Add possibility of unregistering in events mechanism.
authordrebs <drebs@leap.se>
Sun, 9 Jun 2013 17:16:33 +0000 (14:16 -0300)
committerdrebs <drebs@leap.se>
Thu, 13 Jun 2013 14:46:21 +0000 (11:46 -0300)
changes/feature_add-events-ungerister [new file with mode: 0644]
src/leap/common/events/__init__.py
src/leap/common/events/component.py
src/leap/common/events/events.proto
src/leap/common/events/events_pb2.py
src/leap/common/events/server.py
src/leap/common/tests/test_events.py

diff --git a/changes/feature_add-events-ungerister b/changes/feature_add-events-ungerister
new file mode 100644 (file)
index 0000000..0f17626
--- /dev/null
@@ -0,0 +1 @@
+  o Add possibility of unregistering callbacks for a signal.
index 9fc93ee..12416e4 100644 (file)
@@ -24,7 +24,7 @@ import socket
 
 
 from leap.common.events import (
-    events_pb2,
+    events_pb2 as proto,
     server,
     component,
     daemon,
@@ -61,12 +61,37 @@ def register(signal, callback, uid=None, replace=False, reqcbk=None,
     :type timeout: int
 
     :return: the response from server for synch calls or nothing for asynch
-        calls
+        calls.
     :rtype: leap.common.events.events_pb2.EventsResponse or None
     """
     return component.register(signal, callback, uid, replace, reqcbk, timeout)
 
 
+def unregister(signal, uid=None, reqcbk=None, timeout=1000):
+    """
+    Unregister a callback.
+
+    If C{uid} is specified, unregisters only the callback identified by that
+    unique id. Otherwise, unregisters all callbacks registered for C{signal}.
+
+    :param signal: the signal that causes the callback to be launched
+    :type signal: int (see the `events.proto` file)
+    :param uid: a unique id for the callback
+    :type uid: int
+    :param reqcbk: a callback to be called when a response from server is
+        received
+    :type reqcbk: function
+        callback(leap.common.events.events_pb2.EventResponse)
+    :param timeout: the timeout for synch calls
+    :type timeout: int
+
+    :return: the response from server for synch calls or nothing for asynch
+        calls.
+    :rtype: leap.common.events.events_pb2.EventsResponse or None
+    """
+    return component.unregister(signal, uid, reqcbk, timeout)
+
+
 def signal(signal, content="", mac_method="", mac="", reqcbk=None,
            timeout=1000):
     """
@@ -94,7 +119,7 @@ def signal(signal, content="", mac_method="", mac="", reqcbk=None,
     :type timeout: int
 
     :return: the response from server for synch calls or nothing for asynch
-        calls
+        calls.
     :rtype: leap.common.events.events_pb2.EventsResponse or None
     """
     return component.signal(signal, content, mac_method, mac, reqcbk, timeout)
index 9932190..029d1ac 100644 (file)
@@ -56,6 +56,7 @@ class CallbackAlreadyRegistered(Exception):
     """
     Raised when trying to register an already registered callback.
     """
+    pass
 
 
 def ensure_component_daemon():
@@ -111,7 +112,7 @@ def register(signal, callback, uid=None, replace=False, reqcbk=None,
     callback identified by the given uid and replace is False.
 
     :return: the response from server for synch calls or nothing for asynch
-        calls
+        calls.
     :rtype: leap.common.events.events_pb2.EventsResponse or None
     """
     ensure_component_daemon()  # so we can receive registered signals
@@ -140,6 +141,56 @@ def register(signal, callback, uid=None, replace=False, reqcbk=None,
         str(request)[:40])
     return service.register(request, callback=reqcbk, timeout=timeout)
 
+def unregister(signal, uid=None, reqcbk=None, timeout=1000):
+    """
+    Unregister a callback.
+
+    If C{uid} is specified, unregisters only the callback identified by that
+    unique id. Otherwise, unregisters all callbacks
+
+    :param signal: the signal that causes the callback to be launched
+    :type signal: int (see the `events.proto` file)
+    :param uid: a unique id for the callback
+    :type uid: int
+    :param reqcbk: a callback to be called when a response from server is
+        received
+    :type reqcbk: function
+        callback(leap.common.events.events_pb2.EventResponse)
+    :param timeout: the timeout for synch calls
+    :type timeout: int
+
+    :return: the response from server for synch calls or nothing for asynch
+        calls or None if no callback is registered for that signal or uid.
+    :rtype: leap.common.events.events_pb2.EventsResponse or None
+    """
+    if signal not in registered_callbacks or not registered_callbacks[signal]:
+        logger.warning("No callback registered for signal %d." % signal)
+        return None
+    # unregister callback locally
+    cbklist = registered_callbacks[signal]
+    if uid is not None:
+        if filter(lambda (cbkuid, _): cbkuid == uid, cbklist) == []:
+            logger.warning("No callback registered for uid %d." % st)
+            return None
+        registered_callbacks[signal] = filter(lambda(x, y): x != uid, cbklist)
+    else:
+        # exclude all callbacks for given signal
+        registered_callbacks[signal] = []
+    # unregister port in server if there are no more callbacks for this signal
+    if not registered_callbacks[signal]:
+        request = proto.UnregisterRequest()
+        request.event = signal
+        request.port = EventsComponentDaemon.get_instance().get_port()
+        request.mac_method = mac_auth.MacMethod.MAC_NONE
+        request.mac = ""
+        service = RpcService(proto.EventsServerService_Stub,
+                             server.SERVER_PORT, 'localhost')
+        logger.info(
+            "Sending unregistration request to server on port %s: %s",
+            server.SERVER_PORT,
+            str(request)[:40])
+        return service.unregister(request, callback=reqcbk, timeout=timeout)
+
 
 def signal(signal, content="", mac_method="", mac="", reqcbk=None,
            timeout=1000):
@@ -168,7 +219,7 @@ def signal(signal, content="", mac_method="", mac="", reqcbk=None,
     :type timeout: int
 
     :return: the response from server for synch calls or nothing for asynch
-        calls
+        calls.
     :rtype: leap.common.events.events_pb2.EventsResponse or None
     """
     request = proto.SignalRequest()
index 447b038..a813ed1 100644 (file)
@@ -49,6 +49,13 @@ message RegisterRequest {
   required bytes mac = 4;
 }
 
+message UnregisterRequest {
+  required Event event = 1;
+  required int32 port = 2;
+  required string mac_method = 3;
+  required bytes mac = 4;
+}
+
 message EventResponse {
 
   enum Status {
@@ -63,6 +70,7 @@ message EventResponse {
 
 service EventsServerService {
   rpc register(RegisterRequest) returns (EventResponse);
+  rpc unregister(UnregisterRequest) returns (EventResponse);
   rpc signal(SignalRequest) returns (EventResponse);
 }
 
index a4f1df4..5b1c118 100644 (file)
@@ -1,85 +1,87 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: events.proto
 
-from google.protobuf import descriptor
-from google.protobuf import message
-from google.protobuf import reflection
-from google.protobuf import service
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import service as _service
 from google.protobuf import service_reflection
 from google.protobuf import descriptor_pb2
 # @@protoc_insertion_point(imports)
 
 
-DESCRIPTOR = descriptor.FileDescriptor(
+DESCRIPTOR = _descriptor.FileDescriptor(
     name='events.proto',
     package='leap.common.events',
-    serialized_pb='\n\x0c\x65vents.proto\x12\x12leap.common.events\"\x97\x01\n\rSignalRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0f\n\x07\x63ontent\x18\x02 \x02(\t\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\x12\x12\n\nenc_method\x18\x05 \x01(\t\x12\x16\n\x0e\x65rror_occurred\x18\x06 \x01(\x08\"j\n\x0fRegisterRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0c\n\x04port\x18\x02 \x02(\x05\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\"\x82\x01\n\rEventResponse\x12\x38\n\x06status\x18\x01 \x02(\x0e\x32(.leap.common.events.EventResponse.Status\x12\x0e\n\x06result\x18\x02 \x01(\t\"\'\n\x06Status\x12\x06\n\x02OK\x10\x01\x12\n\n\x06UNAUTH\x10\x02\x12\t\n\x05\x45RROR\x10\x03*\xe7\x02\n\x05\x45vent\x12\x15\n\x11\x43LIENT_SESSION_ID\x10\x01\x12\x0e\n\nCLIENT_UID\x10\x02\x12\x19\n\x15SOLEDAD_CREATING_KEYS\x10\x03\x12\x1e\n\x1aSOLEDAD_DONE_CREATING_KEYS\x10\x04\x12\x1a\n\x16SOLEDAD_UPLOADING_KEYS\x10\x05\x12\x1f\n\x1bSOLEDAD_DONE_UPLOADING_KEYS\x10\x06\x12\x1c\n\x18SOLEDAD_DOWNLOADING_KEYS\x10\x07\x12!\n\x1dSOLEDAD_DONE_DOWNLOADING_KEYS\x10\x08\x12\x1c\n\x18SOLEDAD_NEW_DATA_TO_SYNC\x10\t\x12\x1a\n\x16SOLEDAD_DONE_DATA_SYNC\x10\n\x12\x17\n\x13UPDATER_NEW_UPDATES\x10\x0b\x12\x19\n\x15UPDATER_DONE_UPDATING\x10\x0c\x12\x10\n\x0cRAISE_WINDOW\x10\r2\xb9\x01\n\x13\x45ventsServerService\x12R\n\x08register\x12#.leap.common.events.RegisterRequest\x1a!.leap.common.events.EventResponse\x12N\n\x06signal\x12!.leap.common.events.SignalRequest\x1a!.leap.common.events.EventResponse2h\n\x16\x45ventsComponentService\x12N\n\x06signal\x12!.leap.common.events.SignalRequest\x1a!.leap.common.events.EventResponseB\x03\x90\x01\x01')
+    serialized_pb='\n\x0c\x65vents.proto\x12\x12leap.common.events\"\x97\x01\n\rSignalRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0f\n\x07\x63ontent\x18\x02 \x02(\t\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\x12\x12\n\nenc_method\x18\x05 \x01(\t\x12\x16\n\x0e\x65rror_occurred\x18\x06 \x01(\x08\"j\n\x0fRegisterRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0c\n\x04port\x18\x02 \x02(\x05\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\"l\n\x11UnregisterRequest\x12(\n\x05\x65vent\x18\x01 \x02(\x0e\x32\x19.leap.common.events.Event\x12\x0c\n\x04port\x18\x02 \x02(\x05\x12\x12\n\nmac_method\x18\x03 \x02(\t\x12\x0b\n\x03mac\x18\x04 \x02(\x0c\"\x82\x01\n\rEventResponse\x12\x38\n\x06status\x18\x01 \x02(\x0e\x32(.leap.common.events.EventResponse.Status\x12\x0e\n\x06result\x18\x02 \x01(\t\"\'\n\x06Status\x12\x06\n\x02OK\x10\x01\x12\n\n\x06UNAUTH\x10\x02\x12\t\n\x05\x45RROR\x10\x03*\xe7\x02\n\x05\x45vent\x12\x15\n\x11\x43LIENT_SESSION_ID\x10\x01\x12\x0e\n\nCLIENT_UID\x10\x02\x12\x19\n\x15SOLEDAD_CREATING_KEYS\x10\x03\x12\x1e\n\x1aSOLEDAD_DONE_CREATING_KEYS\x10\x04\x12\x1a\n\x16SOLEDAD_UPLOADING_KEYS\x10\x05\x12\x1f\n\x1bSOLEDAD_DONE_UPLOADING_KEYS\x10\x06\x12\x1c\n\x18SOLEDAD_DOWNLOADING_KEYS\x10\x07\x12!\n\x1dSOLEDAD_DONE_DOWNLOADING_KEYS\x10\x08\x12\x1c\n\x18SOLEDAD_NEW_DATA_TO_SYNC\x10\t\x12\x1a\n\x16SOLEDAD_DONE_DATA_SYNC\x10\n\x12\x17\n\x13UPDATER_NEW_UPDATES\x10\x0b\x12\x19\n\x15UPDATER_DONE_UPDATING\x10\x0c\x12\x10\n\x0cRAISE_WINDOW\x10\r2\x91\x02\n\x13\x45ventsServerService\x12R\n\x08register\x12#.leap.common.events.RegisterRequest\x1a!.leap.common.events.EventResponse\x12V\n\nunregister\x12%.leap.common.events.UnregisterRequest\x1a!.leap.common.events.EventResponse\x12N\n\x06signal\x12!.leap.common.events.SignalRequest\x1a!.leap.common.events.EventResponse2h\n\x16\x45ventsComponentService\x12N\n\x06signal\x12!.leap.common.events.SignalRequest\x1a!.leap.common.events.EventResponseB\x03\x90\x01\x01')
 
-_EVENT = descriptor.EnumDescriptor(
+_EVENT = _descriptor.EnumDescriptor(
     name='Event',
     full_name='leap.common.events.Event',
     filename=None,
     file=DESCRIPTOR,
     values=[
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='CLIENT_SESSION_ID', index=0, number=1,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='CLIENT_UID', index=1, number=2,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='SOLEDAD_CREATING_KEYS', index=2, number=3,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='SOLEDAD_DONE_CREATING_KEYS', index=3, number=4,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='SOLEDAD_UPLOADING_KEYS', index=4, number=5,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='SOLEDAD_DONE_UPLOADING_KEYS', index=5, number=6,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='SOLEDAD_DOWNLOADING_KEYS', index=6, number=7,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='SOLEDAD_DONE_DOWNLOADING_KEYS', index=7, number=8,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='SOLEDAD_NEW_DATA_TO_SYNC', index=8, number=9,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='SOLEDAD_DONE_DATA_SYNC', index=9, number=10,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='UPDATER_NEW_UPDATES', index=10, number=11,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='UPDATER_DONE_UPDATING', index=11, number=12,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='RAISE_WINDOW', index=12, number=13,
             options=None,
             type=None),
     ],
     containing_type=None,
     options=None,
-    serialized_start=432,
-    serialized_end=791,
+    serialized_start=542,
+    serialized_end=901,
 )
 
-
+Event = enum_type_wrapper.EnumTypeWrapper(_EVENT)
 CLIENT_SESSION_ID = 1
 CLIENT_UID = 2
 SOLEDAD_CREATING_KEYS = 3
@@ -95,240 +97,311 @@ UPDATER_DONE_UPDATING = 12
 RAISE_WINDOW = 13
 
 
-_EVENTRESPONSE_STATUS = descriptor.EnumDescriptor(
+_EVENTRESPONSE_STATUS = _descriptor.EnumDescriptor(
     name='Status',
     full_name='leap.common.events.EventResponse.Status',
     filename=None,
     file=DESCRIPTOR,
     values=[
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='OK', index=0, number=1,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='UNAUTH', index=1, number=2,
             options=None,
             type=None),
-        descriptor.EnumValueDescriptor(
+        _descriptor.EnumValueDescriptor(
             name='ERROR', index=2, number=3,
             options=None,
             type=None),
     ],
     containing_type=None,
     options=None,
-    serialized_start=390,
-    serialized_end=429,
+    serialized_start=500,
+    serialized_end=539,
 )
 
 
-_SIGNALREQUEST = descriptor.Descriptor(
+_SIGNALREQUEST = _descriptor.Descriptor(
     name='SignalRequest',
     full_name='leap.common.events.SignalRequest',
     filename=None,
     file=DESCRIPTOR,
     containing_type=None,
     fields=[
-        descriptor.FieldDescriptor(
+        _descriptor.FieldDescriptor(
             name='event', full_name='leap.common.events.SignalRequest.event', index=0,
             number=1, type=14, cpp_type=8, label=2,
             has_default_value=False, default_value=1,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    descriptor.FieldDescriptor(
-      name='content', full_name='leap.common.events.SignalRequest.content', index=1,
-      number=2, type=9, cpp_type=9, label=2,
-      has_default_value=False, default_value=unicode("", "utf-8"),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    descriptor.FieldDescriptor(
-      name='mac_method', full_name='leap.common.events.SignalRequest.mac_method', index=2,
-      number=3, type=9, cpp_type=9, label=2,
-      has_default_value=False, default_value=unicode("", "utf-8"),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    descriptor.FieldDescriptor(
-      name='mac', full_name='leap.common.events.SignalRequest.mac', index=3,
-      number=4, type=12, cpp_type=9, label=2,
-      has_default_value=False, default_value="",
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    descriptor.FieldDescriptor(
-      name='enc_method', full_name='leap.common.events.SignalRequest.enc_method', index=4,
-      number=5, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    descriptor.FieldDescriptor(
-      name='error_occurred', full_name='leap.common.events.SignalRequest.error_occurred', index=5,
-      number=6, type=8, cpp_type=7, label=1,
-      has_default_value=False, default_value=False,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  extension_ranges=[],
-  serialized_start=37,
-  serialized_end=188,
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='content', full_name='leap.common.events.SignalRequest.content', index=1,
+            number=2, type=9, cpp_type=9, label=2,
+            has_default_value=False, default_value=unicode("", "utf-8"),
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='mac_method', full_name='leap.common.events.SignalRequest.mac_method', index=2,
+            number=3, type=9, cpp_type=9, label=2,
+            has_default_value=False, default_value=unicode("", "utf-8"),
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='mac', full_name='leap.common.events.SignalRequest.mac', index=3,
+            number=4, type=12, cpp_type=9, label=2,
+            has_default_value=False, default_value="",
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='enc_method', full_name='leap.common.events.SignalRequest.enc_method', index=4,
+            number=5, type=9, cpp_type=9, label=1,
+            has_default_value=False, default_value=unicode("", "utf-8"),
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='error_occurred', full_name='leap.common.events.SignalRequest.error_occurred', index=5,
+            number=6, type=8, cpp_type=7, label=1,
+            has_default_value=False, default_value=False,
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+    ],
+    extensions=[
+    ],
+    nested_types=[],
+    enum_types=[
+    ],
+    options=None,
+    is_extendable=False,
+    extension_ranges=[],
+    serialized_start=37,
+    serialized_end=188,
+)
+
+
+_REGISTERREQUEST = _descriptor.Descriptor(
+    name='RegisterRequest',
+    full_name='leap.common.events.RegisterRequest',
+    filename=None,
+    file=DESCRIPTOR,
+    containing_type=None,
+    fields=[
+        _descriptor.FieldDescriptor(
+            name='event', full_name='leap.common.events.RegisterRequest.event', index=0,
+            number=1, type=14, cpp_type=8, label=2,
+            has_default_value=False, default_value=1,
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='port', full_name='leap.common.events.RegisterRequest.port', index=1,
+            number=2, type=5, cpp_type=1, label=2,
+            has_default_value=False, default_value=0,
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='mac_method', full_name='leap.common.events.RegisterRequest.mac_method', index=2,
+            number=3, type=9, cpp_type=9, label=2,
+            has_default_value=False, default_value=unicode("", "utf-8"),
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='mac', full_name='leap.common.events.RegisterRequest.mac', index=3,
+            number=4, type=12, cpp_type=9, label=2,
+            has_default_value=False, default_value="",
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+    ],
+    extensions=[
+    ],
+    nested_types=[],
+    enum_types=[
+    ],
+    options=None,
+    is_extendable=False,
+    extension_ranges=[],
+    serialized_start=190,
+    serialized_end=296,
 )
 
 
-_REGISTERREQUEST = descriptor.Descriptor(
-  name='RegisterRequest',
-  full_name='leap.common.events.RegisterRequest',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    descriptor.FieldDescriptor(
-      name='event', full_name='leap.common.events.RegisterRequest.event', index=0,
-      number=1, type=14, cpp_type=8, label=2,
-      has_default_value=False, default_value=1,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    descriptor.FieldDescriptor(
-      name='port', full_name='leap.common.events.RegisterRequest.port', index=1,
-      number=2, type=5, cpp_type=1, label=2,
-      has_default_value=False, default_value=0,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    descriptor.FieldDescriptor(
-      name='mac_method', full_name='leap.common.events.RegisterRequest.mac_method', index=2,
-      number=3, type=9, cpp_type=9, label=2,
-      has_default_value=False, default_value=unicode("", "utf-8"),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    descriptor.FieldDescriptor(
-      name='mac', full_name='leap.common.events.RegisterRequest.mac', index=3,
-      number=4, type=12, cpp_type=9, label=2,
-      has_default_value=False, default_value="",
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  extension_ranges=[],
-  serialized_start=190,
-  serialized_end=296,
+_UNREGISTERREQUEST = _descriptor.Descriptor(
+    name='UnregisterRequest',
+    full_name='leap.common.events.UnregisterRequest',
+    filename=None,
+    file=DESCRIPTOR,
+    containing_type=None,
+    fields=[
+        _descriptor.FieldDescriptor(
+            name='event', full_name='leap.common.events.UnregisterRequest.event', index=0,
+            number=1, type=14, cpp_type=8, label=2,
+            has_default_value=False, default_value=1,
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='port', full_name='leap.common.events.UnregisterRequest.port', index=1,
+            number=2, type=5, cpp_type=1, label=2,
+            has_default_value=False, default_value=0,
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='mac_method', full_name='leap.common.events.UnregisterRequest.mac_method', index=2,
+            number=3, type=9, cpp_type=9, label=2,
+            has_default_value=False, default_value=unicode("", "utf-8"),
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='mac', full_name='leap.common.events.UnregisterRequest.mac', index=3,
+            number=4, type=12, cpp_type=9, label=2,
+            has_default_value=False, default_value="",
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+    ],
+    extensions=[
+    ],
+    nested_types=[],
+    enum_types=[
+    ],
+    options=None,
+    is_extendable=False,
+    extension_ranges=[],
+    serialized_start=298,
+    serialized_end=406,
 )
 
 
-_EVENTRESPONSE = descriptor.Descriptor(
-  name='EventResponse',
-  full_name='leap.common.events.EventResponse',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    descriptor.FieldDescriptor(
-      name='status', full_name='leap.common.events.EventResponse.status', index=0,
-      number=1, type=14, cpp_type=8, label=2,
-      has_default_value=False, default_value=1,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    descriptor.FieldDescriptor(
-      name='result', full_name='leap.common.events.EventResponse.result', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-    _EVENTRESPONSE_STATUS,
-  ],
-  options=None,
-  is_extendable=False,
-  extension_ranges=[],
-  serialized_start=299,
-  serialized_end=429,
+_EVENTRESPONSE = _descriptor.Descriptor(
+    name='EventResponse',
+    full_name='leap.common.events.EventResponse',
+    filename=None,
+    file=DESCRIPTOR,
+    containing_type=None,
+    fields=[
+        _descriptor.FieldDescriptor(
+            name='status', full_name='leap.common.events.EventResponse.status', index=0,
+            number=1, type=14, cpp_type=8, label=2,
+            has_default_value=False, default_value=1,
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='result', full_name='leap.common.events.EventResponse.result', index=1,
+            number=2, type=9, cpp_type=9, label=1,
+            has_default_value=False, default_value=unicode("", "utf-8"),
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None,
+            options=None),
+    ],
+    extensions=[
+    ],
+    nested_types=[],
+    enum_types=[
+        _EVENTRESPONSE_STATUS,
+    ],
+    options=None,
+    is_extendable=False,
+    extension_ranges=[],
+    serialized_start=409,
+    serialized_end=539,
 )
 
 _SIGNALREQUEST.fields_by_name['event'].enum_type = _EVENT
 _REGISTERREQUEST.fields_by_name['event'].enum_type = _EVENT
+_UNREGISTERREQUEST.fields_by_name['event'].enum_type = _EVENT
 _EVENTRESPONSE.fields_by_name['status'].enum_type = _EVENTRESPONSE_STATUS
-_EVENTRESPONSE_STATUS.containing_type = _EVENTRESPONSE;
+_EVENTRESPONSE_STATUS.containing_type = _EVENTRESPONSE
 DESCRIPTOR.message_types_by_name['SignalRequest'] = _SIGNALREQUEST
 DESCRIPTOR.message_types_by_name['RegisterRequest'] = _REGISTERREQUEST
+DESCRIPTOR.message_types_by_name['UnregisterRequest'] = _UNREGISTERREQUEST
 DESCRIPTOR.message_types_by_name['EventResponse'] = _EVENTRESPONSE
 
 
-class SignalRequest(message.Message):
-    __metaclass__ = reflection.GeneratedProtocolMessageType
+class SignalRequest(_message.Message):
+    __metaclass__ = _reflection.GeneratedProtocolMessageType
     DESCRIPTOR = _SIGNALREQUEST
 
     # @@protoc_insertion_point(class_scope:leap.common.events.SignalRequest)
 
 
-class RegisterRequest(message.Message):
-    __metaclass__ = reflection.GeneratedProtocolMessageType
+class RegisterRequest(_message.Message):
+    __metaclass__ = _reflection.GeneratedProtocolMessageType
     DESCRIPTOR = _REGISTERREQUEST
 
     # @@protoc_insertion_point(class_scope:leap.common.events.RegisterRequest)
 
 
-class EventResponse(message.Message):
-    __metaclass__ = reflection.GeneratedProtocolMessageType
+class UnregisterRequest(_message.Message):
+    __metaclass__ = _reflection.GeneratedProtocolMessageType
+    DESCRIPTOR = _UNREGISTERREQUEST
+
+    # @@protoc_insertion_point(class_scope:leap.common.events.UnregisterRequest)
+
+
+class EventResponse(_message.Message):
+    __metaclass__ = _reflection.GeneratedProtocolMessageType
     DESCRIPTOR = _EVENTRESPONSE
 
     # @@protoc_insertion_point(class_scope:leap.common.events.EventResponse)
 
 
-_EVENTSSERVERSERVICE = descriptor.ServiceDescriptor(
-  name='EventsServerService',
-  full_name='leap.common.events.EventsServerService',
-  file=DESCRIPTOR,
-  index=0,
-  options=None,
-  serialized_start=794,
-  serialized_end=979,
-  methods=[
-  descriptor.MethodDescriptor(
-    name='register',
-    full_name='leap.common.events.EventsServerService.register',
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(
+    descriptor_pb2.FileOptions(), '\220\001\001')
+
+_EVENTSSERVERSERVICE = _descriptor.ServiceDescriptor(
+    name='EventsServerService',
+    full_name='leap.common.events.EventsServerService',
+    file=DESCRIPTOR,
     index=0,
-    containing_service=None,
-    input_type=_REGISTERREQUEST,
-    output_type=_EVENTRESPONSE,
     options=None,
-  ),
-  descriptor.MethodDescriptor(
-    name='signal',
-    full_name='leap.common.events.EventsServerService.signal',
-    index=1,
-    containing_service=None,
-    input_type=_SIGNALREQUEST,
-    output_type=_EVENTRESPONSE,
-    options=None,
-  ),
-])
+    serialized_start=904,
+    serialized_end=1177,
+    methods=[
+        _descriptor.MethodDescriptor(
+            name='register',
+            full_name='leap.common.events.EventsServerService.register',
+            index=0,
+            containing_service=None,
+            input_type=_REGISTERREQUEST,
+            output_type=_EVENTRESPONSE,
+            options=None,
+        ),
+        _descriptor.MethodDescriptor(
+            name='unregister',
+            full_name='leap.common.events.EventsServerService.unregister',
+            index=1,
+            containing_service=None,
+            input_type=_UNREGISTERREQUEST,
+            output_type=_EVENTRESPONSE,
+            options=None,
+        ),
+        _descriptor.MethodDescriptor(
+            name='signal',
+            full_name='leap.common.events.EventsServerService.signal',
+            index=2,
+            containing_service=None,
+            input_type=_SIGNALREQUEST,
+            output_type=_EVENTRESPONSE,
+            options=None,
+        ),
+    ])
 
 
-class EventsServerService(service.Service):
+class EventsServerService(_service.Service):
     __metaclass__ = service_reflection.GeneratedServiceType
     DESCRIPTOR = _EVENTSSERVERSERVICE
 
@@ -338,28 +411,28 @@ class EventsServerService_Stub(EventsServerService):
     DESCRIPTOR = _EVENTSSERVERSERVICE
 
 
-_EVENTSCOMPONENTSERVICE = descriptor.ServiceDescriptor(
-  name='EventsComponentService',
-  full_name='leap.common.events.EventsComponentService',
-  file=DESCRIPTOR,
-  index=1,
-  options=None,
-  serialized_start=981,
-  serialized_end=1085,
-  methods=[
-  descriptor.MethodDescriptor(
-    name='signal',
-    full_name='leap.common.events.EventsComponentService.signal',
-    index=0,
-    containing_service=None,
-    input_type=_SIGNALREQUEST,
-    output_type=_EVENTRESPONSE,
+_EVENTSCOMPONENTSERVICE = _descriptor.ServiceDescriptor(
+    name='EventsComponentService',
+    full_name='leap.common.events.EventsComponentService',
+    file=DESCRIPTOR,
+    index=1,
     options=None,
-  ),
-])
+    serialized_start=1179,
+    serialized_end=1283,
+    methods=[
+        _descriptor.MethodDescriptor(
+            name='signal',
+            full_name='leap.common.events.EventsComponentService.signal',
+            index=0,
+            containing_service=None,
+            input_type=_SIGNALREQUEST,
+            output_type=_EVENTRESPONSE,
+            options=None,
+        ),
+    ])
 
 
-class EventsComponentService(service.Service):
+class EventsComponentService(_service.Service):
     __metaclass__ = service_reflection.GeneratedServiceType
     DESCRIPTOR = _EVENTSCOMPONENTSERVICE
 
index 1f3a874..d53c218 100644 (file)
@@ -100,6 +100,33 @@ class EventsServerService(proto.EventsServerService):
         response.status = proto.EventResponse.OK
         done.run(response)
 
+    def unregister(self, controller, request, done):
+        """
+        Unregister a component port so it will not be signaled when specific
+        events come in.
+
+        :param controller: used to mediate a single method call
+        :type controller: protobuf.socketrpc.controller.SocketRpcController
+        :param request: the request received from the component
+        :type request: leap.common.events.events_pb2.RegisterRequest
+        :param done: callback to be called when done
+        :type done: protobuf.socketrpc.server.Callback
+        """
+        logger.info(
+            "Received unregistration request: %s..." % str(request)[:40])
+        # remove component port from signal list
+        response = proto.EventResponse()
+        if request.event in registered_components:
+            try:
+                registered_components[request.event].remove(request.port)
+                response.status = proto.EventResponse.OK
+            except KeyError:
+                response.status = proto.EventsResponse.ERROR
+                response.result = 'Port %d not registered.' % request.port
+        # send response back to component
+        logger.debug('sending response back')
+        done.run(response)
+
     def signal(self, controller, request, done):
         """
         Perform an RPC call to signal all components registered to receive a
index 8c0bd36..7286bdc 100644 (file)
@@ -198,3 +198,36 @@ class EventsTestCase(unittest.TestCase):
         response = events.signal(sig)
         self.assertTrue(response.status == response.OK,
                         'Received wrong response status when signaling.')
+
+    def test_component_unregister_all(self):
+        """
+        Test that the component can unregister all events for one signal.
+        """
+        sig = CLIENT_UID
+        complist = server.registered_components
+        events.register(sig, lambda x: True)
+        events.register(sig, lambda x: True)
+        time.sleep(0.1)
+        events.unregister(sig)
+        time.sleep(0.1)
+        port = component.EventsComponentDaemon.get_instance().get_port()
+        self.assertFalse(bool(complist[sig]))
+        self.assertTrue(port not in complist[sig])
+
+    def test_component_unregister_by_uid(self):
+        """
+        Test that the component can unregister an event by uid.
+        """
+        sig = CLIENT_UID
+        complist = server.registered_components
+        events.register(sig, lambda x: True, uid='cbkuid')
+        events.register(sig, lambda x: True, uid='cbkuid2')
+        time.sleep(0.1)
+        events.unregister(sig, uid='cbkuid')
+        time.sleep(0.1)
+        port = component.EventsComponentDaemon.get_instance().get_port()
+        self.assertTrue(sig in complist)
+        self.assertTrue(len(complist[sig]) == 1)
+        self.assertTrue(
+            component.registered_callbacks[sig].pop()[0] == 'cbkuid2')
+        self.assertTrue(port in complist[sig])