diff --git a/coretk/coretk/coregrpc.py b/coretk/coretk/coregrpc.py index 8596366c..bcd04c96 100644 --- a/coretk/coretk/coregrpc.py +++ b/coretk/coretk/coregrpc.py @@ -55,6 +55,10 @@ class CoreGrpc: # self.core.events(self.session_id, self.log_event) logging.info("Entering session_id %s.... Result: %s", usr_input, response) + def delete_session(self): + response = self.core.delete_session(self.session_id) + logging.info("Deleted session result: %s", response) + def set_up(self): """ Query sessions, if there exist any, promt whether to join one @@ -75,25 +79,59 @@ class CoreGrpc: # self.create_new_session() self.query_existing_sessions(sessions) - def set_configuration_state(self): - response = self.core.set_session_state( - self.session_id, core_pb2.SessionState.CONFIGURATION - ) - logging.info("set session state: %s", response) + def get_session_state(self): + response = self.core.get_session(self.session_id) + logging.info("get sessio: %s", response) + return response.session.state + + def set_session_state(self, state): + """ + Set session state + + :param str state: session state to set + :return: nothing + """ + response = None + if state == "configuration": + response = self.core.set_session_state( + self.session_id, core_pb2.SessionState.CONFIGURATION + ) + elif state == "instantiation": + response = self.core.set_session_state( + self.session_id, core_pb2.SessionState.INSTANTIATION + ) + elif state == "datacollect": + response = self.core.set_session_state( + self.session_id, core_pb2.SessionState.DATACOLLECT + ) + elif state == "shutdown": + response = self.core.set_session_state( + self.session_id, core_pb2.SessionState.SHUTDOWN + ) + elif state == "runtime": + response = self.core.set_session_state( + self.session_id, core_pb2.SessionState.RUNTIME + ) + elif state == "definition": + response = self.core.set_session_state( + self.session_id, core_pb2.SessionState.DEFINITION + ) + elif state == "none": + response = self.core.set_session_state( + self.session_id, core_pb2.SessionState.NONE + ) + else: + logging.error("coregrpc.py: set_session_state: INVALID STATE") - def set_instantiate_state(self): - response = self.core.set_session_state( - self.session_id, core_pb2.SessionState.INSTANTIATION - ) logging.info("set session state: %s", response) def get_session_id(self): return self.session_id - def add_node(self, node_type, model, x, y, name): - logging.info("ADD NODE %s", name) + def add_node(self, node_type, model, x, y, name, node_id): + logging.info("coregrpc.py ADD NODE %s", name) position = core_pb2.Position(x=x, y=y) - node = core_pb2.Node(type=node_type, position=position, model=model, image=name) + node = core_pb2.Node(id=node_id, type=node_type, position=position, model=model) response = self.core.add_node(self.session_id, node) logging.info("created node: %s", response) return response.node_id @@ -103,10 +141,25 @@ class CoreGrpc: response = self.core.edit_node(session_id, node_id, position) logging.info("updated node id %s: %s", node_id, response) + def delete_nodes(self): + for node in self.core.get_session(self.session_id).session.nodes: + response = self.core.delete_node(self.session_id, node.id) + logging.info("delete node %s", response) + # def create_interface_helper(self): # self.interface_helper = self.core.InterfaceHelper(ip4_prefix="10.83.0.0/16") - # TODO case for other core_pb2.NodeType + def delete_links(self): + for link in self.core.get_session(self.session_id).session.links: + response = self.core.delete_link( + self.session_id, + link.node_one_id, + link.node_two_id, + link.interface_one.id, + link.interface_two.id, + ) + logging.info("delete link %s", response) + def add_link(self, id1, id2, type1, type2): """ Grpc client request add link diff --git a/coretk/coretk/coretoolbar.py b/coretk/coretk/coretoolbar.py index 8af43240..c59c4222 100644 --- a/coretk/coretk/coretoolbar.py +++ b/coretk/coretk/coretoolbar.py @@ -1,6 +1,7 @@ import logging import tkinter as tk +from core.api.grpc import core_pb2 from coretk.graph import GraphMode from coretk.images import Images from coretk.tooltip import CreateToolTip @@ -155,20 +156,19 @@ class CoreToolbar(object): self.create_runtime_toolbar() # set configuration state - self.canvas.core_grpc.set_configuration_state() + if self.canvas.core_grpc.get_session_state() == core_pb2.SessionState.SHUTDOWN: + self.canvas.core_grpc.set_session_state("definition") + self.canvas.core_grpc.set_session_state("configuration") - # grpc client requests creating nodes - for node in self.canvas.grpc_manager.nodes_to_create.values(): + for node in self.canvas.grpc_manager.nodes.values(): self.canvas.core_grpc.add_node( - node.type, node.model, int(node.x), int(node.y), node.name + node.type, node.model, int(node.x), int(node.y), node.name, node.node_id ) - self.canvas.grpc_manager.nodes_to_create.clear() - for edge in self.canvas.grpc_manager.edges_to_create.values(): + for edge in self.canvas.grpc_manager.edges.values(): self.canvas.core_grpc.add_link(edge.id1, edge.id2, edge.type1, edge.type2) - self.canvas.grpc_manager.edges_to_create.clear() - self.canvas.core_grpc.set_instantiate_state() + self.canvas.core_grpc.set_session_state("instantiation") def click_link_tool(self): logging.debug("Click LINK button") @@ -551,6 +551,9 @@ class CoreToolbar(object): logging.debug("Click on STOP button ") self.destroy_children_widgets(self.edit_frame) self.create_toolbar() + self.canvas.core_grpc.set_session_state("datacollect") + self.canvas.core_grpc.delete_links() + self.canvas.core_grpc.delete_nodes() def click_run_button(self): logging.debug("Click on RUN button") diff --git a/coretk/coretk/graph.py b/coretk/coretk/graph.py index 5a25188b..3c984557 100644 --- a/coretk/coretk/graph.py +++ b/coretk/coretk/graph.py @@ -2,6 +2,7 @@ import enum import logging import tkinter as tk +from core.api.grpc import core_pb2 from coretk.grpcmanagement import GrpcManager from coretk.images import Images @@ -33,7 +34,7 @@ class CanvasGraph(tk.Canvas): self.draw_grid() self.core_grpc = grpc self.grpc_manager = GrpcManager() - self.draw_existing_node() + self.draw_existing_component() def setup_menus(self): self.node_context = tk.Menu(self.master) @@ -80,20 +81,40 @@ class CanvasGraph(tk.Canvas): for i in range(0, height, 27): self.create_line(0, i, width, i, dash=(2, 4), tags="grid line") - def draw_existing_node(self): + def draw_existing_component(self): """ - Draw existing node while updating the grpc manager based on that + Draw existing node and update the information in grpc manager to match :return: nothing """ + core_id_to_canvas_id = {} + session_id = self.core_grpc.session_id - response = self.core_grpc.core.get_session(session_id) - nodes = response.session.nodes - if len(nodes) > 0: - for node in nodes: - image = Images.convert_type_and_model_to_image(node.type, node.model) - return image - # n = CanvasNode(node.position.x, node.position.y, image, self, node.id) + session = self.core_grpc.core.get_session(session_id).session + # nodes = response.session.nodes + # if len(nodes) > 0: + for node in session.nodes: + # peer to peer node is not drawn on the GUI + if node.type != core_pb2.NodeType.PEER_TO_PEER: + image, name = Images.convert_type_and_model_to_image( + node.type, node.model + ) + n = CanvasNode(node.position.x, node.position.y, image, self, node.id) + self.nodes[n.id] = n + core_id_to_canvas_id[node.id] = n.id + self.grpc_manager.add_preexisting_node(n, session_id, node, name) + self.grpc_manager.update_reusable_id() + # draw existing links + # links = response.session.links + for link in session.links: + n1 = self.nodes[core_id_to_canvas_id[link.node_one_id]] + n2 = self.nodes[core_id_to_canvas_id[link.node_two_id]] + e = CanvasEdge(n1.x_coord, n1.y_coord, n2.x_coord, n2.y_coord, n1.id, self) + self.edges[e.token] = e + self.grpc_manager.add_edge(session_id, e.token, n1.id, n2.id) + # lift the nodes so they on top of the links + for i in core_id_to_canvas_id.values(): + self.lift(i) def canvas_xy(self, event): """ @@ -289,8 +310,9 @@ class CanvasNode: self.edges = set() self.moving = None - def get_coords(self): - return self.x_coord, self.y_coord + # + # def get_coords(self): + # return self.x_coord, self.y_coord def update_coords(self): self.x_coord, self.y_coord = self.canvas.coords(self.id) diff --git a/coretk/coretk/grpcmanagement.py b/coretk/coretk/grpcmanagement.py index d090f6d6..afbf8175 100644 --- a/coretk/coretk/grpcmanagement.py +++ b/coretk/coretk/grpcmanagement.py @@ -11,19 +11,20 @@ network_layer_nodes = ["router", "host", "PC", "mdr", "prouter", "OVS"] class Node: - def __init__(self, session_id, node_id, type, model, x, y, name): + def __init__(self, session_id, node_id, node_type, model, x, y, name): """ Create an instance of a node :param int session_id: session id :param int node_id: node id - :param core_pb2.NodeType type: node type + :param core_pb2.NodeType node_type: node type :param int x: x coordinate :param int y: coordinate + :param str name: node name """ self.session_id = session_id self.node_id = node_id - self.type = type + self.type = node_type self.x = x self.y = y self.model = model @@ -54,8 +55,8 @@ class GrpcManager: self.id = 1 # A list of id for re-use, keep in increasing order self.reusable = [] - self.nodes_to_create = {} - self.edges_to_create = {} + + self.preexisting = [] def peek_id(self): """ @@ -82,7 +83,6 @@ class GrpcManager: else: return self.reusable.pop(0) - # TODO figure out the name of ovs node def add_node(self, session_id, canvas_id, x, y, name): """ Add node, with information filled in, to grpc manager @@ -109,13 +109,11 @@ class GrpcManager: node_type = core_pb2.NodeType.TUNNEL elif name in network_layer_nodes: node_type = core_pb2.NodeType.DEFAULT - # TODO what is the model name for ovs node_model = name else: logging.error("grpcmanagemeny.py INVALID node name") create_node = Node(session_id, self.get_id(), node_type, node_model, x, y, name) self.nodes[canvas_id] = create_node - self.nodes_to_create[canvas_id] = create_node logging.debug( "Adding node to GrpcManager.. Session id: %s, Coords: (%s, %s), Name: %s", session_id, @@ -124,8 +122,42 @@ class GrpcManager: name, ) - def add_preexisting_node(self): - return + def add_preexisting_node(self, canvas_node, session_id, core_node, name): + """ + Add preexisting nodes to grpc manager + + :param core_pb2.Node core_node: core node grpc message + :param coretk.graph.CanvasNode canvas_node: canvas node + :param int session_id: session id + :return: nothing + """ + core_id = core_node.id + if core_id >= self.id: + self.id = core_id + 1 + self.preexisting.append(core_id) + n = Node( + session_id, + core_id, + core_node.type, + core_node.model, + canvas_node.x_coord, + canvas_node.y_coord, + name, + ) + self.nodes[canvas_node.id] = n + + def update_reusable_id(self): + """ + Update available id for reuse + + :return: nothing + """ + for i in range(1, self.id): + if i not in self.preexisting: + self.reusable.append(i) + + self.preexisting.clear() + logging.debug("Next id: %s, Reusable: %s", self.id, self.reusable) def delete_node(self, canvas_id): """ @@ -151,7 +183,6 @@ class GrpcManager: self.nodes[canvas_id_2].type, ) self.edges[token] = edge - self.edges_to_create[token] = edge logging.debug("Adding edge to grpc manager...") else: logging.error("grpcmanagement.py INVALID CANVAS NODE ID") diff --git a/coretk/coretk/images.py b/coretk/coretk/images.py index 4911efac..fc04c7cc 100644 --- a/coretk/coretk/images.py +++ b/coretk/coretk/images.py @@ -25,35 +25,36 @@ class Images: @classmethod def convert_type_and_model_to_image(cls, node_type, node_model): """ - Retrieve image based on type and model - :param core_pb2.NodeType node_type: core node type - :param string node_model: the node model + Retrieve image based on type and model + :param core_pb2.NodeType node_type: core node type + :param string node_model: the node model - :return: the matching image - """ + :rtype: tuple(PhotoImage, str) + :return: the matching image and its name + """ if node_type == core_pb2.NodeType.SWITCH: - return Images.get("switch") + return Images.get("switch"), "switch" if node_type == core_pb2.NodeType.HUB: - return Images.get("hub") + return Images.get("hub"), "hub" if node_type == core_pb2.NodeType.WIRELESS_LAN: - return Images.get("wlan") + return Images.get("wlan"), "wlan" if node_type == core_pb2.NodeType.RJ45: - return Images.get("rj45") + return Images.get("rj45"), "rj45" if node_type == core_pb2.NodeType.TUNNEL: - return Images.get("tunnel") + return Images.get("tunnel"), "tunnel" if node_type == core_pb2.NodeType.DEFAULT: if node_model == "router": - return Images.get("router") + return Images.get("router"), "router" if node_model == "host": - return Images.get(("host")) + return Images.get(("host")), "host" if node_model == "PC": - return Images.get("pc") + return Images.get("pc"), "PC" if node_model == "mdr": - return Images.get("mdr") + return Images.get("mdr"), "mdr" if node_model == "prouter": - return Images.get("prouter") + return Images.get("prouter"), "prouter" if node_model == "OVS": - return Images.get("ovs") + return Images.get("ovs"), "ovs" else: logging.debug("INVALID INPUT OR NOT CONSIDERED YET")