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:
Blake Harnden 2021-04-27 10:49:52 -07:00
parent f891974e3a
commit e0fe86bcb2
7 changed files with 64 additions and 69 deletions

View file

@ -248,7 +248,10 @@ class CoreGrpcClient:
self.proxy: bool = proxy
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]]:
"""
Start a session.
@ -331,6 +334,7 @@ class CoreGrpcClient:
config_service_configs=config_service_configs,
options=options,
user=session.user,
definition=definition,
)
response = self.stub.StartSession(request)
return response.result, list(response.exceptions)

View file

@ -223,8 +223,12 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
# clear previous state and setup for creation
session.clear()
session.directory.mkdir(exist_ok=True)
session.set_state(EventTypes.CONFIGURATION_STATE)
if request.definition:
state = EventTypes.DEFINITION_STATE
else:
state = EventTypes.CONFIGURATION_STATE
session.directory.mkdir(exist_ok=True)
session.set_state(state)
session.user = request.user
# session options
@ -298,16 +302,18 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
return core_pb2.StartSessionResponse(result=False, exceptions=exceptions)
# set to instantiation and start
session.set_state(EventTypes.INSTANTIATION_STATE)
# boot services
boot_exceptions = session.instantiate()
if boot_exceptions:
exceptions = []
for boot_exception in boot_exceptions:
for service_exception in boot_exception.args:
exceptions.append(str(service_exception))
return core_pb2.StartSessionResponse(result=False, exceptions=exceptions)
if not request.definition:
session.set_state(EventTypes.INSTANTIATION_STATE)
# boot services
boot_exceptions = session.instantiate()
if boot_exceptions:
exceptions = []
for boot_exception in boot_exceptions:
for service_exception in boot_exception.args:
exceptions.append(str(service_exception))
return core_pb2.StartSessionResponse(
result=False, exceptions=exceptions
)
return core_pb2.StartSessionResponse(result=True)
def StopSession(

View file

@ -437,28 +437,38 @@ class CoreClient:
for server in self.servers.values():
self.client.add_session_server(self.session.id, server.name, server.address)
def start_session(self) -> Tuple[bool, List[str]]:
self.ifaces_manager.set_macs([x.link for x in self.links.values()])
links = []
asymmetric_links = []
def get_links(self, definition: bool = False) -> Tuple[List[Link], List[Link]]:
if not definition:
self.ifaces_manager.set_macs([x.link for x in self.links.values()])
links, asym_links = [], []
for edge in self.links.values():
link = edge.link
if link.iface1 and not link.iface1.mac:
link.iface1.mac = self.ifaces_manager.next_mac()
if link.iface2 and not link.iface2.mac:
link.iface2.mac = self.ifaces_manager.next_mac()
if not definition:
if link.iface1 and not link.iface1.mac:
link.iface1.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)
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
result = False
exceptions = []
try:
self.send_servers()
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:
self.set_metadata()
except grpc.RpcError as e:
@ -548,8 +558,15 @@ class CoreClient:
file_path = str(self.session.file)
try:
if not self.is_runtime():
logger.debug("Send session data to the daemon")
self.send_data()
logger.debug("sending session data to the daemon")
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)
logger.info("saved xml file %s", file_path)
except grpc.RpcError as e:
@ -595,45 +612,6 @@ class CoreClient:
)
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:
"""
Clean ups when done using grpc

View file

@ -75,7 +75,7 @@ class ConfigServiceConfigDialog(Dialog):
def load(self) -> None:
try:
self.core.create_nodes_and_links()
self.core.start_session(definition=True)
service = self.core.config_services[self.service_name]
self.dependencies = service.dependencies[:]
self.executables = service.executables[:]

View file

@ -78,7 +78,7 @@ class ServiceConfigDialog(Dialog):
def load(self) -> None:
try:
self.app.core.create_nodes_and_links()
self.core.start_session(definition=True)
default_config = self.app.core.get_node_service(
self.node.id, self.service_name
)

View file

@ -180,6 +180,7 @@ message StartSessionRequest {
repeated configservices.ConfigServiceConfig config_service_configs = 13;
map<string, string> options = 14;
string user = 15;
bool definition = 16;
}
message StartSessionResponse {

View file

@ -47,7 +47,8 @@ from core.xml.corexml import CoreXmlWriter
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
client = CoreGrpcClient()
with client.context_connect():
@ -164,10 +165,15 @@ class TestGrpcw:
# when
with patch.object(CoreXmlWriter, "write"):
with client.context_connect():
client.start_session(session)
client.start_session(session, definition=definition)
# then
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 node2.id in real_session.nodes
assert wlan_node.id in real_session.nodes