from nepi.execution.resource import ResourceManager, clsinit_copy, \
ResourceState, reschedule_delay
-
-from nepi.execute.attributes import Flags
-from nepi.resources.ns3.ns3simulator import NS3Simulator
-from nepi.resources.ns3.ns3node import NS3BaseNode
+from nepi.execution.attribute import Flags
+from nepi.execution.trace import TraceAttr
@clsinit_copy
class NS3Base(ResourceManager):
- _rtype = "ns3::Object"
+ _rtype = "abstract::ns3::Object"
+ _backend_type = "ns3"
- def __init__(self):
- super(NS3Base, self).__init__()
+ def __init__(self, ec, guid):
+ super(NS3Base, self).__init__(ec, guid)
self._uuid = None
self._connected = set()
+ self._trace_filename = dict()
@property
def connected(self):
return self._uuid
@property
- def simulator(self):
- simulators = self.get_connected(NS3Simulator.get_rtype())
- if simulators: return simulators[0]
- # if the object is not directly connected to the simulator,
- # it should be connected to a node
- node = self.node
- if node: return node.simulator
- return None
-
+ def simulation(self):
+ return self.node.simulation
+
@property
def node(self):
+ from nepi.resources.ns3.ns3node import NS3BaseNode
nodes = self.get_connected(NS3BaseNode.get_rtype())
if nodes: return nodes[0]
return None
+ def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0):
+ filename = self._trace_filename.get(name)
+ if not filename:
+ self.error("Can resolve trace %s. Did you enabled it?" % name)
+ return ""
+
+ return self.simulation.trace(filename, attr, block, offset)
+
@property
- def others_to_wait(self):
- others = set()
+ def _rms_to_wait(self):
+ """ Returns the collection of ns-3 RMs that this RM needs to
+ wait for before start
+
+ This method should be overriden to wait for other ns-3
+ objects to be deployed before proceeding with the deployment
+
+ """
+ rms = set()
node = self.node
- if node: others.add(node)
- return others
+ if node: rms.add(node)
+ return rms
def _instantiate_object(self):
if self.uuid:
return
kwargs = dict()
- for attr in self._attrs:
- if not attr.value or attr.has_flag(Flags.ReadOnly):
+ for attr in self._attrs.values():
+ if not ( attr.has_flag(Flags.Construct) and attr.has_changed() ):
continue
- kwargs[attr.name] = attr.value
+ kwargs[attr.name] = attr._value
- self.uuid = self.simulator.factory(self.get_rtype(), **kwargs)
+ self._uuid = self.simulation.factory(self.get_rtype(), **kwargs)
def _configure_object(self):
pass
def _connect_object(self):
node = self.node
if node and node.uuid not in self.connected:
- self.simulator.invoke(node.uuid, "AggregateObject", self.uuid)
+ self.simulation.invoke(node.uuid, "AggregateObject", self.uuid)
self._connected.add(node.uuid)
- def _wait_others(self):
- """ Returns the collection of ns-3 RMs that this RM needs to
- wait for before start
-
- This method should be overriden to wait for other ns-3
- objects to be deployed before proceeding with the deployment
-
- """
- for other in self.others_to_wait:
- if other and other.state < ResourceState.READY:
+ def _wait_rms(self):
+ """ Returns True if dependent RMs are not yer READY, False otherwise"""
+ for rm in self._rms_to_wait:
+ if rm and rm.state < ResourceState.READY:
return True
return False
def do_provision(self):
- # create run dir for ns3 object
- # self.simulator.node.mkdir(self.run_home)
+ # TODO: create run dir for ns3 object !!!!
+ # self.simulation.node.mkdir(self.run_home)
self._instantiate_object()
- self._configure_object()
self._connect_object()
+ self._configure_object()
self.info("Provisioning finished")
super(NS3Base, self).do_provision()
def do_deploy(self):
- if not self.simulator or self.simulator.state < ResourceState.READY or \
- self._wait_others():
+ if self._wait_rms():
self.debug("---- RESCHEDULING DEPLOY ----" )
-
- # ccnd needs to wait until node is deployed and running
self.ec.schedule(reschedule_delay, self.deploy)
else:
- # TODO: CREATE AND CONFIGURE NS-3 C++ OBJECT
self.do_discover()
self.do_provision()
- self.debug("----- READY ---- ")
self.set_ready()
def do_start(self):
if self.state == ResourceState.READY:
- # No need to do anything, simulator.Run() will start every object
+ # No need to do anything, simulation.Run() will start every object
self.info("Starting")
self.set_started()
else:
def do_stop(self):
if self.state == ResourceState.STARTED:
- # No need to do anything, simulator.Destroy() will stop every object
+ # No need to do anything, simulation.Destroy() will stop every object
self.info("Stopping command '%s'" % command)
self.set_stopped()
def state(self):
return self._state
+ def get(self, name):
+ if self.state in [ResourceState.READY, ResourceState.STARTED] and \
+ self.has_flag(name, Flags.Reserved) and \
+ not self.has_flag(name, Flags.NoRead):
+ return self.simulation.ns3_get(self.uuid, name)
+ else:
+ value = super(NS3Base, self).get(name)
+
+ return value
+
+ def set(self, name, value):
+ if self.state in [ResourceState.READY, ResourceState.STARTED] and \
+ self.has_flag(name, Flags.Reserved) and \
+ not (self.has_flag(Flags.NoWrite) or self.has_flag(name, Flags.Design)):
+ self.simulation.ns3_set(self.uuid, name, value)
+
+ value = super(NS3Base, self).set(name, value)
+
+ return value
+