grpc merged multiple event request/handlers into a singular event request for a session, which will return all events
This commit is contained in:
parent
2ba8669c5c
commit
df3a8980ed
4 changed files with 152 additions and 257 deletions
|
@ -263,33 +263,7 @@ class CoreGrpcClient(object):
|
|||
request = core_pb2.SetSessionStateRequest(session_id=session_id, state=state)
|
||||
return self.stub.SetSessionState(request)
|
||||
|
||||
def node_events(self, session_id, handler):
|
||||
"""
|
||||
Listen for session node events.
|
||||
|
||||
:param int session_id: id of session
|
||||
:param handler: handler for every event
|
||||
:return: nothing
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
request = core_pb2.NodeEventsRequest(session_id=session_id)
|
||||
stream = self.stub.NodeEvents(request)
|
||||
start_streamer(stream, handler)
|
||||
|
||||
def link_events(self, session_id, handler):
|
||||
"""
|
||||
Listen for session link events.
|
||||
|
||||
:param int session_id: id of session
|
||||
:param handler: handler for every event
|
||||
:return: nothing
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
request = core_pb2.LinkEventsRequest(session_id=session_id)
|
||||
stream = self.stub.LinkEvents(request)
|
||||
start_streamer(stream, handler)
|
||||
|
||||
def session_events(self, session_id, handler):
|
||||
def events(self, session_id, handler):
|
||||
"""
|
||||
Listen for session events.
|
||||
|
||||
|
@ -298,47 +272,8 @@ class CoreGrpcClient(object):
|
|||
:return: nothing
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
request = core_pb2.SessionEventsRequest(session_id=session_id)
|
||||
stream = self.stub.SessionEvents(request)
|
||||
start_streamer(stream, handler)
|
||||
|
||||
def config_events(self, session_id, handler):
|
||||
"""
|
||||
Listen for session config events.
|
||||
|
||||
:param int session_id: id of session
|
||||
:param handler: handler for every event
|
||||
:return: nothing
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
request = core_pb2.ConfigEventsRequest(session_id=session_id)
|
||||
stream = self.stub.ConfigEvents(request)
|
||||
start_streamer(stream, handler)
|
||||
|
||||
def exception_events(self, session_id, handler):
|
||||
"""
|
||||
Listen for session exception events.
|
||||
|
||||
:param int session_id: id of session
|
||||
:param handler: handler for every event
|
||||
:return: nothing
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
request = core_pb2.ExceptionEventsRequest(session_id=session_id)
|
||||
stream = self.stub.ExceptionEvents(request)
|
||||
start_streamer(stream, handler)
|
||||
|
||||
def file_events(self, session_id, handler):
|
||||
"""
|
||||
Listen for session file events.
|
||||
|
||||
:param int session_id: id of session
|
||||
:param handler: handler for every event
|
||||
:return: nothing
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
request = core_pb2.FileEventsRequest(session_id=session_id)
|
||||
stream = self.stub.FileEvents(request)
|
||||
request = core_pb2.EventsRequest(session_id=session_id)
|
||||
stream = self.stub.Events(request)
|
||||
start_streamer(stream, handler)
|
||||
|
||||
def add_node(self, session_id, node):
|
||||
|
|
|
@ -4,6 +4,7 @@ import os
|
|||
import tempfile
|
||||
import time
|
||||
from Queue import Queue, Empty
|
||||
from core.data import NodeData, LinkData, EventData, ConfigData, ExceptionData, FileData
|
||||
|
||||
import grpc
|
||||
from concurrent import futures
|
||||
|
@ -262,177 +263,149 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
session_proto = core_pb2.Session(state=session.state, nodes=nodes, links=links)
|
||||
return core_pb2.GetSessionResponse(session=session_proto)
|
||||
|
||||
def NodeEvents(self, request, context):
|
||||
def Events(self, request, context):
|
||||
session = self.get_session(request.session_id, context)
|
||||
queue = Queue()
|
||||
session.node_handlers.append(queue.put)
|
||||
|
||||
while self._is_running(context):
|
||||
try:
|
||||
node = queue.get(timeout=1)
|
||||
position = core_pb2.Position(x=node.x_position, y=node.y_position)
|
||||
services = node.services or ""
|
||||
services = services.split("|")
|
||||
node_proto = core_pb2.Node(
|
||||
id=node.id, name=node.name, model=node.model, position=position, services=services)
|
||||
node_event = core_pb2.NodeEvent(node=node_proto)
|
||||
yield node_event
|
||||
except Empty:
|
||||
continue
|
||||
|
||||
self._cancel_stream(context)
|
||||
|
||||
def LinkEvents(self, request, context):
|
||||
session = self.get_session(request.session_id, context)
|
||||
queue = Queue()
|
||||
session.link_handlers.append(queue.put)
|
||||
|
||||
while self._is_running(context):
|
||||
try:
|
||||
event = queue.get(timeout=1)
|
||||
interface_one = None
|
||||
if event.interface1_id is not None:
|
||||
interface_one = core_pb2.Interface(
|
||||
id=event.interface1_id, name=event.interface1_name, mac=convert_value(event.interface1_mac),
|
||||
ip4=convert_value(event.interface1_ip4), ip4mask=event.interface1_ip4_mask,
|
||||
ip6=convert_value(event.interface1_ip6), ip6mask=event.interface1_ip6_mask)
|
||||
|
||||
interface_two = None
|
||||
if event.interface2_id is not None:
|
||||
interface_two = core_pb2.Interface(
|
||||
id=event.interface2_id, name=event.interface2_name, mac=convert_value(event.interface2_mac),
|
||||
ip4=convert_value(event.interface2_ip4), ip4mask=event.interface2_ip4_mask,
|
||||
ip6=convert_value(event.interface2_ip6), ip6mask=event.interface2_ip6_mask)
|
||||
|
||||
options = core_pb2.LinkOptions(
|
||||
opaque=event.opaque,
|
||||
jitter=event.jitter,
|
||||
key=event.key,
|
||||
mburst=event.mburst,
|
||||
mer=event.mer,
|
||||
per=event.per,
|
||||
bandwidth=event.bandwidth,
|
||||
burst=event.burst,
|
||||
delay=event.delay,
|
||||
dup=event.dup,
|
||||
unidirectional=event.unidirectional
|
||||
)
|
||||
link = core_pb2.Link(
|
||||
type=event.link_type, node_one_id=event.node1_id, node_two_id=event.node2_id,
|
||||
interface_one=interface_one, interface_two=interface_two, options=options)
|
||||
link_event = core_pb2.LinkEvent(message_type=event.message_type, link=link)
|
||||
yield link_event
|
||||
except Empty:
|
||||
continue
|
||||
|
||||
self._cancel_stream(context)
|
||||
|
||||
def SessionEvents(self, request, context):
|
||||
session = self.get_session(request.session_id, context)
|
||||
queue = Queue()
|
||||
session.config_handlers.append(queue.put)
|
||||
session.file_handlers.append(queue.put)
|
||||
session.exception_handlers.append(queue.put)
|
||||
session.event_handlers.append(queue.put)
|
||||
|
||||
while self._is_running(context):
|
||||
event = core_pb2.Event()
|
||||
try:
|
||||
event = queue.get(timeout=1)
|
||||
event_time = event.time
|
||||
if event_time is not None:
|
||||
event_time = float(event_time)
|
||||
session_event = core_pb2.SessionEvent(
|
||||
node_id=event.node,
|
||||
event=event.event_type,
|
||||
name=event.name,
|
||||
data=event.data,
|
||||
time=event_time,
|
||||
session_id=session.id
|
||||
)
|
||||
yield session_event
|
||||
data = queue.get(timeout=1)
|
||||
if isinstance(data, NodeData):
|
||||
event.node_event.CopyFrom(self._handle_node_event(data))
|
||||
elif isinstance(data, LinkData):
|
||||
event.link_event.CopyFrom(self._handle_link_event(data))
|
||||
elif isinstance(data, EventData):
|
||||
event.session_event.CopyFrom(self._handle_session_event(data))
|
||||
elif isinstance(data, ConfigData):
|
||||
event.config_event.CopyFrom(self._handle_config_event(data))
|
||||
# TODO: remove when config events are fixed
|
||||
event.config_event.session_id = session.id
|
||||
elif isinstance(data, ExceptionData):
|
||||
event.exception_event.CopyFrom(self._handle_exception_event(data))
|
||||
elif isinstance(data, FileData):
|
||||
event.file_event.CopyFrom(self._handle_file_event(data))
|
||||
else:
|
||||
logging.error("unknown event: %s", data)
|
||||
continue
|
||||
|
||||
yield event
|
||||
except Empty:
|
||||
continue
|
||||
|
||||
session.node_handlers.remove(queue.put)
|
||||
session.link_handlers.remove(queue.put)
|
||||
session.config_handlers.remove(queue.put)
|
||||
session.file_handlers.remove(queue.put)
|
||||
session.exception_handlers.remove(queue.put)
|
||||
session.event_handlers.remove(queue.put)
|
||||
self._cancel_stream(context)
|
||||
|
||||
def ConfigEvents(self, request, context):
|
||||
session = self.get_session(request.session_id, context)
|
||||
queue = Queue()
|
||||
session.config_handlers.append(queue.put)
|
||||
def _handle_node_event(self, event):
|
||||
position = core_pb2.Position(x=event.x_position, y=event.y_position)
|
||||
services = event.services or ""
|
||||
services = services.split("|")
|
||||
node_proto = core_pb2.Node(
|
||||
id=event.id, name=event.name, model=event.model, position=position, services=services)
|
||||
return core_pb2.NodeEvent(node=node_proto)
|
||||
|
||||
while self._is_running(context):
|
||||
try:
|
||||
event = queue.get(timeout=1)
|
||||
session_id = None
|
||||
if event.session is not None:
|
||||
session_id = int(event.session)
|
||||
config_event = core_pb2.ConfigEvent(
|
||||
message_type=event.message_type,
|
||||
node_id=event.node,
|
||||
object=event.object,
|
||||
type=event.type,
|
||||
captions=event.captions,
|
||||
bitmap=event.bitmap,
|
||||
data_values=event.data_values,
|
||||
possible_values=event.possible_values,
|
||||
groups=event.groups,
|
||||
session_id=session_id,
|
||||
interface=event.interface_number,
|
||||
network_id=event.network_id,
|
||||
opaque=event.opaque,
|
||||
data_types=event.data_types
|
||||
)
|
||||
yield config_event
|
||||
except Empty:
|
||||
continue
|
||||
def _handle_link_event(self, event):
|
||||
interface_one = None
|
||||
if event.interface1_id is not None:
|
||||
interface_one = core_pb2.Interface(
|
||||
id=event.interface1_id, name=event.interface1_name, mac=convert_value(event.interface1_mac),
|
||||
ip4=convert_value(event.interface1_ip4), ip4mask=event.interface1_ip4_mask,
|
||||
ip6=convert_value(event.interface1_ip6), ip6mask=event.interface1_ip6_mask)
|
||||
|
||||
self._cancel_stream(context)
|
||||
interface_two = None
|
||||
if event.interface2_id is not None:
|
||||
interface_two = core_pb2.Interface(
|
||||
id=event.interface2_id, name=event.interface2_name, mac=convert_value(event.interface2_mac),
|
||||
ip4=convert_value(event.interface2_ip4), ip4mask=event.interface2_ip4_mask,
|
||||
ip6=convert_value(event.interface2_ip6), ip6mask=event.interface2_ip6_mask)
|
||||
|
||||
def ExceptionEvents(self, request, context):
|
||||
session = self.get_session(request.session_id, context)
|
||||
queue = Queue()
|
||||
session.exception_handlers.append(queue.put)
|
||||
options = core_pb2.LinkOptions(
|
||||
opaque=event.opaque,
|
||||
jitter=event.jitter,
|
||||
key=event.key,
|
||||
mburst=event.mburst,
|
||||
mer=event.mer,
|
||||
per=event.per,
|
||||
bandwidth=event.bandwidth,
|
||||
burst=event.burst,
|
||||
delay=event.delay,
|
||||
dup=event.dup,
|
||||
unidirectional=event.unidirectional
|
||||
)
|
||||
link = core_pb2.Link(
|
||||
type=event.link_type, node_one_id=event.node1_id, node_two_id=event.node2_id,
|
||||
interface_one=interface_one, interface_two=interface_two, options=options)
|
||||
return core_pb2.LinkEvent(message_type=event.message_type, link=link)
|
||||
|
||||
while self._is_running(context):
|
||||
try:
|
||||
event = queue.get(timeout=1)
|
||||
exception_event = core_pb2.ExceptionEvent(
|
||||
node_id=event.node,
|
||||
session_id=int(event.session),
|
||||
level=event.level.value,
|
||||
source=event.source,
|
||||
date=event.date,
|
||||
text=event.text,
|
||||
opaque=event.opaque
|
||||
)
|
||||
yield exception_event
|
||||
except Empty:
|
||||
continue
|
||||
def _handle_session_event(self, event):
|
||||
event_time = event.time
|
||||
if event_time is not None:
|
||||
event_time = float(event_time)
|
||||
return core_pb2.SessionEvent(
|
||||
node_id=event.node,
|
||||
event=event.event_type,
|
||||
name=event.name,
|
||||
data=event.data,
|
||||
time=event_time,
|
||||
session_id=event.session
|
||||
)
|
||||
|
||||
self._cancel_stream(context)
|
||||
def _handle_config_event(self, event):
|
||||
session_id = None
|
||||
if event.session is not None:
|
||||
session_id = int(event.session)
|
||||
return core_pb2.ConfigEvent(
|
||||
message_type=event.message_type,
|
||||
node_id=event.node,
|
||||
object=event.object,
|
||||
type=event.type,
|
||||
captions=event.captions,
|
||||
bitmap=event.bitmap,
|
||||
data_values=event.data_values,
|
||||
possible_values=event.possible_values,
|
||||
groups=event.groups,
|
||||
session_id=session_id,
|
||||
interface=event.interface_number,
|
||||
network_id=event.network_id,
|
||||
opaque=event.opaque,
|
||||
data_types=event.data_types
|
||||
)
|
||||
|
||||
def FileEvents(self, request, context):
|
||||
session = self.get_session(request.session_id, context)
|
||||
queue = Queue()
|
||||
session.file_handlers.append(queue.put)
|
||||
def _handle_exception_event(self, event):
|
||||
return core_pb2.ExceptionEvent(
|
||||
node_id=event.node,
|
||||
session_id=int(event.session),
|
||||
level=event.level.value,
|
||||
source=event.source,
|
||||
date=event.date,
|
||||
text=event.text,
|
||||
opaque=event.opaque
|
||||
)
|
||||
|
||||
while self._is_running(context):
|
||||
try:
|
||||
event = queue.get(timeout=1)
|
||||
file_event = core_pb2.FileEvent(
|
||||
message_type=event.message_type,
|
||||
node_id=event.node,
|
||||
name=event.name,
|
||||
mode=event.mode,
|
||||
number=event.number,
|
||||
type=event.type,
|
||||
source=event.source,
|
||||
session_id=event.session,
|
||||
data=event.data,
|
||||
compressed_data=event.compressed_data
|
||||
)
|
||||
yield file_event
|
||||
except Empty:
|
||||
continue
|
||||
|
||||
self._cancel_stream(context)
|
||||
def _handle_file_event(self, event):
|
||||
return core_pb2.FileEvent(
|
||||
message_type=event.message_type,
|
||||
node_id=event.node,
|
||||
name=event.name,
|
||||
mode=event.mode,
|
||||
number=event.number,
|
||||
type=event.type,
|
||||
source=event.source,
|
||||
session_id=event.session,
|
||||
data=event.data,
|
||||
compressed_data=event.compressed_data
|
||||
)
|
||||
|
||||
def AddNode(self, request, context):
|
||||
logging.debug("add node: %s", request)
|
||||
|
|
|
@ -27,17 +27,7 @@ service CoreApi {
|
|||
}
|
||||
|
||||
// event streams
|
||||
rpc NodeEvents (NodeEventsRequest) returns (stream NodeEvent) {
|
||||
}
|
||||
rpc LinkEvents (LinkEventsRequest) returns (stream LinkEvent) {
|
||||
}
|
||||
rpc SessionEvents (SessionEventsRequest) returns (stream SessionEvent) {
|
||||
}
|
||||
rpc ConfigEvents (ConfigEventsRequest) returns (stream ConfigEvent) {
|
||||
}
|
||||
rpc ExceptionEvents (ExceptionEventsRequest) returns (stream ExceptionEvent) {
|
||||
}
|
||||
rpc FileEvents (FileEventsRequest) returns (stream FileEvent) {
|
||||
rpc Events (EventsRequest) returns (stream Event) {
|
||||
}
|
||||
|
||||
// node rpc
|
||||
|
@ -199,27 +189,30 @@ message SetSessionStateResponse {
|
|||
bool result = 1;
|
||||
}
|
||||
|
||||
message NodeEventsRequest {
|
||||
message EventsRequest {
|
||||
int32 session_id = 1;
|
||||
}
|
||||
|
||||
message Event {
|
||||
oneof event_type {
|
||||
SessionEvent session_event = 1;
|
||||
NodeEvent node_event = 2;
|
||||
LinkEvent link_event = 3;
|
||||
ConfigEvent config_event = 4;
|
||||
ExceptionEvent exception_event = 5;
|
||||
FileEvent file_event = 6;
|
||||
}
|
||||
}
|
||||
|
||||
message NodeEvent {
|
||||
Node node = 1;
|
||||
}
|
||||
|
||||
message LinkEventsRequest {
|
||||
int32 session_id = 1;
|
||||
}
|
||||
|
||||
message LinkEvent {
|
||||
MessageType.Enum message_type = 1;
|
||||
Link link = 2;
|
||||
}
|
||||
|
||||
message SessionEventsRequest {
|
||||
int32 session_id = 1;
|
||||
}
|
||||
|
||||
message SessionEvent {
|
||||
int32 node_id = 1;
|
||||
int32 event = 2;
|
||||
|
@ -229,10 +222,6 @@ message SessionEvent {
|
|||
int32 session_id = 6;
|
||||
}
|
||||
|
||||
message ConfigEventsRequest {
|
||||
int32 session_id = 1;
|
||||
}
|
||||
|
||||
message ConfigEvent {
|
||||
MessageType.Enum message_type = 1;
|
||||
int32 node_id = 2;
|
||||
|
@ -250,10 +239,6 @@ message ConfigEvent {
|
|||
string opaque = 14;
|
||||
}
|
||||
|
||||
message ExceptionEventsRequest {
|
||||
int32 session_id = 1;
|
||||
}
|
||||
|
||||
message ExceptionEvent {
|
||||
int32 node_id = 1;
|
||||
int32 session_id = 2;
|
||||
|
@ -264,10 +249,6 @@ message ExceptionEvent {
|
|||
string opaque = 7;
|
||||
}
|
||||
|
||||
message FileEventsRequest {
|
||||
int32 session_id = 1;
|
||||
}
|
||||
|
||||
message FileEvent {
|
||||
MessageType.Enum message_type = 1;
|
||||
int32 node_id = 2;
|
||||
|
|
|
@ -718,11 +718,12 @@ class TestGrpc:
|
|||
queue = Queue()
|
||||
|
||||
def handle_event(event_data):
|
||||
assert event_data.HasField("node_event")
|
||||
queue.put(event_data)
|
||||
|
||||
# then
|
||||
with client.context_connect():
|
||||
client.node_events(session.id, handle_event)
|
||||
client.events(session.id, handle_event)
|
||||
time.sleep(0.1)
|
||||
session.broadcast_node(node_data)
|
||||
|
||||
|
@ -741,11 +742,12 @@ class TestGrpc:
|
|||
queue = Queue()
|
||||
|
||||
def handle_event(event_data):
|
||||
assert event_data.HasField("link_event")
|
||||
queue.put(event_data)
|
||||
|
||||
# then
|
||||
with client.context_connect():
|
||||
client.link_events(session.id, handle_event)
|
||||
client.events(session.id, handle_event)
|
||||
time.sleep(0.1)
|
||||
session.broadcast_link(link_data)
|
||||
|
||||
|
@ -759,11 +761,12 @@ class TestGrpc:
|
|||
queue = Queue()
|
||||
|
||||
def handle_event(event_data):
|
||||
assert event_data.HasField("session_event")
|
||||
queue.put(event_data)
|
||||
|
||||
# then
|
||||
with client.context_connect():
|
||||
client.session_events(session.id, handle_event)
|
||||
client.events(session.id, handle_event)
|
||||
time.sleep(0.1)
|
||||
event = EventData(event_type=EventTypes.RUNTIME_STATE.value, time="%s" % time.time())
|
||||
session.broadcast_event(event)
|
||||
|
@ -778,11 +781,12 @@ class TestGrpc:
|
|||
queue = Queue()
|
||||
|
||||
def handle_event(event_data):
|
||||
assert event_data.HasField("config_event")
|
||||
queue.put(event_data)
|
||||
|
||||
# then
|
||||
with client.context_connect():
|
||||
client.config_events(session.id, handle_event)
|
||||
client.events(session.id, handle_event)
|
||||
time.sleep(0.1)
|
||||
session_config = session.options.get_configs()
|
||||
config_data = ConfigShim.config_data(0, None, ConfigFlags.UPDATE.value, session.options, session_config)
|
||||
|
@ -798,11 +802,12 @@ class TestGrpc:
|
|||
queue = Queue()
|
||||
|
||||
def handle_event(event_data):
|
||||
assert event_data.HasField("exception_event")
|
||||
queue.put(event_data)
|
||||
|
||||
# then
|
||||
with client.context_connect():
|
||||
client.exception_events(session.id, handle_event)
|
||||
client.events(session.id, handle_event)
|
||||
time.sleep(0.1)
|
||||
session.exception(ExceptionLevels.FATAL, "test", None, "exception message")
|
||||
|
||||
|
@ -817,11 +822,12 @@ class TestGrpc:
|
|||
queue = Queue()
|
||||
|
||||
def handle_event(event_data):
|
||||
assert event_data.HasField("file_event")
|
||||
queue.put(event_data)
|
||||
|
||||
# then
|
||||
with client.context_connect():
|
||||
client.file_events(session.id, handle_event)
|
||||
client.events(session.id, handle_event)
|
||||
time.sleep(0.1)
|
||||
file_data = session.services.get_service_file(node, "IPForward", "ipforward.sh")
|
||||
session.broadcast_file(file_data)
|
||||
|
|
Loading…
Reference in a new issue