grpc: updated start_session to have a definition option, to allow saving xml files and getting service configurations, without fully starting a session
This commit is contained in:
parent
f891974e3a
commit
e0fe86bcb2
7 changed files with 64 additions and 69 deletions
|
@ -248,7 +248,10 @@ class CoreGrpcClient:
|
||||||
self.proxy: bool = proxy
|
self.proxy: bool = proxy
|
||||||
|
|
||||||
def start_session(
|
def start_session(
|
||||||
self, session: wrappers.Session, asymmetric_links: List[wrappers.Link] = None
|
self,
|
||||||
|
session: wrappers.Session,
|
||||||
|
asymmetric_links: List[wrappers.Link] = None,
|
||||||
|
definition: bool = False,
|
||||||
) -> Tuple[bool, List[str]]:
|
) -> Tuple[bool, List[str]]:
|
||||||
"""
|
"""
|
||||||
Start a session.
|
Start a session.
|
||||||
|
@ -331,6 +334,7 @@ class CoreGrpcClient:
|
||||||
config_service_configs=config_service_configs,
|
config_service_configs=config_service_configs,
|
||||||
options=options,
|
options=options,
|
||||||
user=session.user,
|
user=session.user,
|
||||||
|
definition=definition,
|
||||||
)
|
)
|
||||||
response = self.stub.StartSession(request)
|
response = self.stub.StartSession(request)
|
||||||
return response.result, list(response.exceptions)
|
return response.result, list(response.exceptions)
|
||||||
|
|
|
@ -223,8 +223,12 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
|
|
||||||
# clear previous state and setup for creation
|
# clear previous state and setup for creation
|
||||||
session.clear()
|
session.clear()
|
||||||
session.directory.mkdir(exist_ok=True)
|
if request.definition:
|
||||||
session.set_state(EventTypes.CONFIGURATION_STATE)
|
state = EventTypes.DEFINITION_STATE
|
||||||
|
else:
|
||||||
|
state = EventTypes.CONFIGURATION_STATE
|
||||||
|
session.directory.mkdir(exist_ok=True)
|
||||||
|
session.set_state(state)
|
||||||
session.user = request.user
|
session.user = request.user
|
||||||
|
|
||||||
# session options
|
# session options
|
||||||
|
@ -298,16 +302,18 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
return core_pb2.StartSessionResponse(result=False, exceptions=exceptions)
|
return core_pb2.StartSessionResponse(result=False, exceptions=exceptions)
|
||||||
|
|
||||||
# set to instantiation and start
|
# set to instantiation and start
|
||||||
session.set_state(EventTypes.INSTANTIATION_STATE)
|
if not request.definition:
|
||||||
|
session.set_state(EventTypes.INSTANTIATION_STATE)
|
||||||
# boot services
|
# boot services
|
||||||
boot_exceptions = session.instantiate()
|
boot_exceptions = session.instantiate()
|
||||||
if boot_exceptions:
|
if boot_exceptions:
|
||||||
exceptions = []
|
exceptions = []
|
||||||
for boot_exception in boot_exceptions:
|
for boot_exception in boot_exceptions:
|
||||||
for service_exception in boot_exception.args:
|
for service_exception in boot_exception.args:
|
||||||
exceptions.append(str(service_exception))
|
exceptions.append(str(service_exception))
|
||||||
return core_pb2.StartSessionResponse(result=False, exceptions=exceptions)
|
return core_pb2.StartSessionResponse(
|
||||||
|
result=False, exceptions=exceptions
|
||||||
|
)
|
||||||
return core_pb2.StartSessionResponse(result=True)
|
return core_pb2.StartSessionResponse(result=True)
|
||||||
|
|
||||||
def StopSession(
|
def StopSession(
|
||||||
|
|
|
@ -437,28 +437,38 @@ class CoreClient:
|
||||||
for server in self.servers.values():
|
for server in self.servers.values():
|
||||||
self.client.add_session_server(self.session.id, server.name, server.address)
|
self.client.add_session_server(self.session.id, server.name, server.address)
|
||||||
|
|
||||||
def start_session(self) -> Tuple[bool, List[str]]:
|
def get_links(self, definition: bool = False) -> Tuple[List[Link], List[Link]]:
|
||||||
self.ifaces_manager.set_macs([x.link for x in self.links.values()])
|
if not definition:
|
||||||
links = []
|
self.ifaces_manager.set_macs([x.link for x in self.links.values()])
|
||||||
asymmetric_links = []
|
links, asym_links = [], []
|
||||||
for edge in self.links.values():
|
for edge in self.links.values():
|
||||||
link = edge.link
|
link = edge.link
|
||||||
if link.iface1 and not link.iface1.mac:
|
if not definition:
|
||||||
link.iface1.mac = self.ifaces_manager.next_mac()
|
if link.iface1 and not link.iface1.mac:
|
||||||
if link.iface2 and not link.iface2.mac:
|
link.iface1.mac = self.ifaces_manager.next_mac()
|
||||||
link.iface2.mac = self.ifaces_manager.next_mac()
|
if link.iface2 and not link.iface2.mac:
|
||||||
|
link.iface2.mac = self.ifaces_manager.next_mac()
|
||||||
links.append(link)
|
links.append(link)
|
||||||
if edge.asymmetric_link:
|
if edge.asymmetric_link:
|
||||||
asymmetric_links.append(edge.asymmetric_link)
|
asym_links.append(edge.asymmetric_link)
|
||||||
|
return links, asym_links
|
||||||
|
|
||||||
|
def start_session(self, definition: bool = False) -> Tuple[bool, List[str]]:
|
||||||
|
links, asym_links = self.get_links(definition)
|
||||||
self.session.links = links
|
self.session.links = links
|
||||||
result = False
|
result = False
|
||||||
exceptions = []
|
exceptions = []
|
||||||
try:
|
try:
|
||||||
self.send_servers()
|
self.send_servers()
|
||||||
result, exceptions = self.client.start_session(
|
result, exceptions = self.client.start_session(
|
||||||
self.session, asymmetric_links
|
self.session, asym_links, definition
|
||||||
|
)
|
||||||
|
logger.info(
|
||||||
|
"start session(%s) definition(%s), result: %s",
|
||||||
|
self.session.id,
|
||||||
|
definition,
|
||||||
|
result,
|
||||||
)
|
)
|
||||||
logger.info("start session(%s), result: %s", self.session.id, result)
|
|
||||||
if result:
|
if result:
|
||||||
self.set_metadata()
|
self.set_metadata()
|
||||||
except grpc.RpcError as e:
|
except grpc.RpcError as e:
|
||||||
|
@ -548,8 +558,15 @@ class CoreClient:
|
||||||
file_path = str(self.session.file)
|
file_path = str(self.session.file)
|
||||||
try:
|
try:
|
||||||
if not self.is_runtime():
|
if not self.is_runtime():
|
||||||
logger.debug("Send session data to the daemon")
|
logger.debug("sending session data to the daemon")
|
||||||
self.send_data()
|
result, exceptions = self.start_session(definition=True)
|
||||||
|
if not result:
|
||||||
|
message = "\n".join(exceptions)
|
||||||
|
self.app.show_exception_data(
|
||||||
|
"Session Definition Exception",
|
||||||
|
"Failed to define session",
|
||||||
|
message,
|
||||||
|
)
|
||||||
self.client.save_xml(self.session.id, file_path)
|
self.client.save_xml(self.session.id, file_path)
|
||||||
logger.info("saved xml file %s", file_path)
|
logger.info("saved xml file %s", file_path)
|
||||||
except grpc.RpcError as e:
|
except grpc.RpcError as e:
|
||||||
|
@ -595,45 +612,6 @@ class CoreClient:
|
||||||
)
|
)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def create_nodes_and_links(self) -> None:
|
|
||||||
"""
|
|
||||||
create nodes and links that have not been created yet
|
|
||||||
"""
|
|
||||||
self.client.set_session_state(self.session.id, SessionState.DEFINITION)
|
|
||||||
for node in self.session.nodes.values():
|
|
||||||
node_id = self.client.add_node(self.session.id, node, source=GUI_SOURCE)
|
|
||||||
logger.debug("created node: %s", node_id)
|
|
||||||
asymmetric_links = []
|
|
||||||
for edge in self.links.values():
|
|
||||||
self.add_link(edge.link)
|
|
||||||
if edge.asymmetric_link:
|
|
||||||
asymmetric_links.append(edge.asymmetric_link)
|
|
||||||
for link in asymmetric_links:
|
|
||||||
self.add_link(link)
|
|
||||||
|
|
||||||
def send_data(self) -> None:
|
|
||||||
"""
|
|
||||||
Send to daemon all session info, but don't start the session
|
|
||||||
"""
|
|
||||||
self.send_servers()
|
|
||||||
self.create_nodes_and_links()
|
|
||||||
for node_id, config in self.get_wlan_configs():
|
|
||||||
self.client.set_wlan_config(self.session.id, node_id, config)
|
|
||||||
for node_id, config in self.get_mobility_configs():
|
|
||||||
self.client.set_mobility_config(self.session.id, node_id, config)
|
|
||||||
for config in self.get_service_configs():
|
|
||||||
self.client.set_node_service(self.session.id, config)
|
|
||||||
for config in self.get_service_file_configs():
|
|
||||||
self.client.set_node_service_file(self.session.id, config)
|
|
||||||
for hook in self.session.hooks.values():
|
|
||||||
self.client.add_hook(self.session.id, hook)
|
|
||||||
for config in self.get_emane_model_configs():
|
|
||||||
self.client.set_emane_model_config(self.session.id, config)
|
|
||||||
config = to_dict(self.session.emane_config)
|
|
||||||
self.client.set_emane_config(self.session.id, config)
|
|
||||||
self.client.set_session_location(self.session.id, self.session.location)
|
|
||||||
self.set_metadata()
|
|
||||||
|
|
||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
"""
|
"""
|
||||||
Clean ups when done using grpc
|
Clean ups when done using grpc
|
||||||
|
|
|
@ -75,7 +75,7 @@ class ConfigServiceConfigDialog(Dialog):
|
||||||
|
|
||||||
def load(self) -> None:
|
def load(self) -> None:
|
||||||
try:
|
try:
|
||||||
self.core.create_nodes_and_links()
|
self.core.start_session(definition=True)
|
||||||
service = self.core.config_services[self.service_name]
|
service = self.core.config_services[self.service_name]
|
||||||
self.dependencies = service.dependencies[:]
|
self.dependencies = service.dependencies[:]
|
||||||
self.executables = service.executables[:]
|
self.executables = service.executables[:]
|
||||||
|
|
|
@ -78,7 +78,7 @@ class ServiceConfigDialog(Dialog):
|
||||||
|
|
||||||
def load(self) -> None:
|
def load(self) -> None:
|
||||||
try:
|
try:
|
||||||
self.app.core.create_nodes_and_links()
|
self.core.start_session(definition=True)
|
||||||
default_config = self.app.core.get_node_service(
|
default_config = self.app.core.get_node_service(
|
||||||
self.node.id, self.service_name
|
self.node.id, self.service_name
|
||||||
)
|
)
|
||||||
|
|
|
@ -180,6 +180,7 @@ message StartSessionRequest {
|
||||||
repeated configservices.ConfigServiceConfig config_service_configs = 13;
|
repeated configservices.ConfigServiceConfig config_service_configs = 13;
|
||||||
map<string, string> options = 14;
|
map<string, string> options = 14;
|
||||||
string user = 15;
|
string user = 15;
|
||||||
|
bool definition = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StartSessionResponse {
|
message StartSessionResponse {
|
||||||
|
|
|
@ -47,7 +47,8 @@ from core.xml.corexml import CoreXmlWriter
|
||||||
|
|
||||||
|
|
||||||
class TestGrpcw:
|
class TestGrpcw:
|
||||||
def test_start_session(self, grpc_server: CoreGrpcServer):
|
@pytest.mark.parametrize("definition", [False, True])
|
||||||
|
def test_start_session(self, grpc_server: CoreGrpcServer, definition):
|
||||||
# given
|
# given
|
||||||
client = CoreGrpcClient()
|
client = CoreGrpcClient()
|
||||||
with client.context_connect():
|
with client.context_connect():
|
||||||
|
@ -164,10 +165,15 @@ class TestGrpcw:
|
||||||
# when
|
# when
|
||||||
with patch.object(CoreXmlWriter, "write"):
|
with patch.object(CoreXmlWriter, "write"):
|
||||||
with client.context_connect():
|
with client.context_connect():
|
||||||
client.start_session(session)
|
client.start_session(session, definition=definition)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
real_session = grpc_server.coreemu.sessions[session.id]
|
real_session = grpc_server.coreemu.sessions[session.id]
|
||||||
|
if definition:
|
||||||
|
state = EventTypes.DEFINITION_STATE
|
||||||
|
else:
|
||||||
|
state = EventTypes.RUNTIME_STATE
|
||||||
|
assert real_session.state == state
|
||||||
assert node1.id in real_session.nodes
|
assert node1.id in real_session.nodes
|
||||||
assert node2.id in real_session.nodes
|
assert node2.id in real_session.nodes
|
||||||
assert wlan_node.id in real_session.nodes
|
assert wlan_node.id in real_session.nodes
|
||||||
|
|
Loading…
Add table
Reference in a new issue