daemon: refactored NodeData to reference a node instead of replicating fields as an intermediate passthrough, removed data() functions from nodes due to this change

This commit is contained in:
Blake Harnden 2020-06-18 09:06:31 -07:00
parent 1702fe256f
commit ecc3eb1c89
10 changed files with 52 additions and 129 deletions

View file

@ -15,24 +15,28 @@ from core.emulator.data import (
from core.emulator.session import Session
def handle_node_event(event: NodeData) -> core_pb2.NodeEvent:
def handle_node_event(node_data: NodeData) -> core_pb2.NodeEvent:
"""
Handle node event when there is a node event
:param event: node data
:param node_data: node data
:return: node event that contains node id, name, model, position, and services
"""
position = core_pb2.Position(x=event.x_position, y=event.y_position)
geo = core_pb2.Geo(lat=event.latitude, lon=event.longitude, alt=event.altitude)
node = node_data.node
x, y, _ = node.position.get()
position = core_pb2.Position(x=x, y=y)
lon, lat, alt = node.position.get_geo()
geo = core_pb2.Geo(lon=lon, lat=lat, alt=alt)
services = [x.name for x in node.services]
node_proto = core_pb2.Node(
id=event.id,
name=event.name,
model=event.model,
id=node.id,
name=node.name,
model=node.type,
position=position,
geo=geo,
services=event.services,
services=services,
)
return core_pb2.NodeEvent(node=node_proto, source=event.source)
return core_pb2.NodeEvent(node=node_proto, source=node_data.source)
def handle_link_event(event: LinkData) -> core_pb2.LinkEvent:

View file

@ -329,7 +329,6 @@ class CoreHandler(socketserver.BaseRequestHandler):
"""
logging.debug("handling broadcast node: %s", node_data)
message = dataconversion.convert_node(node_data)
try:
self.sendall(message)
except IOError:

View file

@ -8,35 +8,39 @@ from typing import Dict, List
from core.api.tlv import coreapi, structutils
from core.api.tlv.enumerations import ConfigTlvs, NodeTlvs
from core.config import ConfigGroup, ConfigurableOptions
from core.emulator.data import ConfigData
from core.emulator.data import ConfigData, NodeData
def convert_node(node_data):
def convert_node(node_data: NodeData):
"""
Convenience method for converting NodeData to a packed TLV message.
:param core.emulator.data.NodeData node_data: node data to convert
:return: packed node message
"""
node = node_data.node
services = None
if node_data.services is not None:
services = "|".join([x for x in node_data.services])
if node.services is not None:
services = "|".join([x.name for x in node.services])
server = None
if node.server is not None:
server = node.server.name
tlv_data = structutils.pack_values(
coreapi.CoreNodeTlv,
[
(NodeTlvs.NUMBER, node_data.id),
(NodeTlvs.TYPE, node_data.type.value),
(NodeTlvs.NAME, node_data.name),
(NodeTlvs.MODEL, node_data.model),
(NodeTlvs.EMULATION_SERVER, node_data.server),
(NodeTlvs.X_POSITION, int(node_data.x_position)),
(NodeTlvs.Y_POSITION, int(node_data.y_position)),
(NodeTlvs.CANVAS, node_data.canvas),
(NodeTlvs.NUMBER, node.id),
(NodeTlvs.TYPE, node.apitype.value),
(NodeTlvs.NAME, node.name),
(NodeTlvs.MODEL, node.type),
(NodeTlvs.EMULATION_SERVER, server),
(NodeTlvs.X_POSITION, int(node.position.x)),
(NodeTlvs.Y_POSITION, int(node.position.y)),
(NodeTlvs.CANVAS, node.canvas),
(NodeTlvs.SERVICES, services),
(NodeTlvs.LATITUDE, str(node_data.latitude)),
(NodeTlvs.LONGITUDE, str(node_data.longitude)),
(NodeTlvs.ALTITUDE, str(node_data.altitude)),
(NodeTlvs.ICON, node_data.icon),
(NodeTlvs.LATITUDE, str(node.position.lat)),
(NodeTlvs.LONGITUDE, str(node.position.lon)),
(NodeTlvs.ALTITUDE, str(node.position.alt)),
(NodeTlvs.ICON, node.icon),
],
)
return coreapi.CoreNodeMessage.pack(node_data.message_type.value, tlv_data)

View file

@ -12,11 +12,10 @@ from core.emulator.enumerations import (
ExceptionLevels,
LinkTypes,
MessageFlags,
NodeTypes,
)
if TYPE_CHECKING:
from core.nodes.base import CoreNode
from core.nodes.base import CoreNode, NodeBase
@dataclass
@ -121,23 +120,11 @@ class NodeOptions:
@dataclass
class NodeData:
"""
Used to represent nodes being broadcasted.
Node to broadcast.
"""
node: "NodeBase"
message_type: MessageFlags = None
type: NodeTypes = None
id: int = None
name: str = None
model: str = None
server: str = None
icon: str = None
canvas: int = None
services: List[str] = None
x_position: float = None
y_position: float = None
latitude: float = None
longitude: float = None
altitude: float = None
source: str = None

View file

@ -807,9 +807,9 @@ class Session:
:param source: source of broadcast, None by default
:return: nothing
"""
node_data = node.data(message_type, source)
if not node_data:
if not node.apitype:
return
node_data = NodeData(node=node, message_type=message_type, source=source)
for handler in self.node_handlers:
handler(node_data)

View file

@ -14,7 +14,7 @@ import netaddr
from core import utils
from core.configservice.dependencies import ConfigServiceDependencies
from core.constants import MOUNT_BIN, VNODED_BIN
from core.emulator.data import InterfaceData, LinkData, LinkOptions, NodeData
from core.emulator.data import InterfaceData, LinkData, LinkOptions
from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes
from core.errors import CoreCommandError, CoreError
from core.nodes.client import VnodeClient
@ -182,42 +182,6 @@ class NodeBase(abc.ABC):
self.iface_id += 1
return iface_id
def data(
self, message_type: MessageFlags = MessageFlags.NONE, source: str = None
) -> Optional[NodeData]:
"""
Build a data object for this node.
:param message_type: purpose for the data object we are creating
:param source: source of node data
:return: node data object
"""
if self.apitype is None:
return None
x, y, _ = self.getposition()
model = self.type
server = None
if self.server is not None:
server = self.server.name
services = [x.name for x in self.services]
return NodeData(
message_type=message_type,
type=self.apitype,
id=self.id,
name=self.name,
model=model,
server=server,
canvas=self.canvas,
icon=self.icon,
x_position=x,
y_position=y,
latitude=self.position.lat,
longitude=self.position.lon,
altitude=self.position.alt,
services=services,
source=source,
)
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
"""
Build link data for this node.

View file

@ -8,7 +8,7 @@ from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple
from core import utils
from core.emulator.data import LinkOptions
from core.emulator.enumerations import MessageFlags, TransportType
from core.emulator.enumerations import TransportType
from core.errors import CoreCommandError
from core.nodes.netclient import LinuxNetClient, get_net_client
@ -561,23 +561,4 @@ class GreTap(CoreInterface):
self.net_client.delete_device(self.localname)
except CoreCommandError:
logging.exception("error during shutdown")
self.localname = None
def data(self, message_type: int) -> None:
"""
Data for a gre tap.
:param message_type: message type for data
:return: None
"""
return None
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List:
"""
Retrieve link data.
:param flags: link flags
:return: link data
"""
return []

View file

@ -11,7 +11,7 @@ import netaddr
from core import utils
from core.constants import EBTABLES_BIN, TC_BIN
from core.emulator.data import InterfaceData, LinkData, LinkOptions, NodeData
from core.emulator.data import InterfaceData, LinkData, LinkOptions
from core.emulator.enumerations import (
LinkTypes,
MessageFlags,
@ -862,19 +862,6 @@ class PtpNet(CoreNetwork):
)
super().attach(iface)
def data(
self, message_type: MessageFlags = MessageFlags.NONE, source: str = None
) -> Optional[NodeData]:
"""
Do not generate a Node Message for point-to-point links. They are
built using a link message instead.
:param message_type: purpose for the data object we are creating
:param source: source of node data
:return: node data object
"""
return None
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
"""
Build CORE API TLVs for a point-to-point link. One Link message

View file

@ -314,26 +314,22 @@ class Sdt:
:param node_data: node data being updated
:return: nothing
"""
logging.debug("sdt handle node update: %s - %s", node_data.id, node_data.name)
if not self.connect():
return
# delete node
node = node_data.node
logging.debug("sdt handle node update: %s - %s", node.id, node.name)
if node_data.message_type == MessageFlags.DELETE:
self.cmd(f"delete node,{node_data.id}")
self.cmd(f"delete node,{node.id}")
else:
x = node_data.x_position
y = node_data.y_position
lat = node_data.latitude
lon = node_data.longitude
alt = node_data.altitude
x, y, _ = node.position.get()
lon, lat, alt = node.position.get_geo()
if all([lat is not None, lon is not None, alt is not None]):
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
self.cmd(f"node {node_data.id} {pos}")
self.cmd(f"node {node.id} {pos}")
elif node_data.message_type == 0:
lat, lon, alt = self.session.location.getgeo(x, y, 0)
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
self.cmd(f"node {node_data.id} {pos}")
self.cmd(f"node {node.id} {pos}")
def wireless_net_check(self, node_id: int) -> bool:
"""

View file

@ -1198,9 +1198,10 @@ class TestGrpc:
queue = Queue()
def node_handler(node_data: NodeData):
assert node_data.longitude == lon
assert node_data.latitude == lat
assert node_data.altitude == alt
n = node_data.node
assert n.position.lon == lon
assert n.position.lat == lat
assert n.position.alt == alt
queue.put(node_data)
session.node_handlers.append(node_handler)