Module RelayModel.Relay

Expand source code
from RelayModel import ModuleConfig
from RelayModel.RelayId import RelayId, RelayLayerId


class OutReference:
    """Holds the information needed for an outgoing connection to another Relay.

    Attributes:
        keys (set): Stores all keys in a set used in the outgoing connection
        out_id (RelayId): Stores the RelayId defining the Relay to which the OutReference is connected to
    """

    def __init__(self, keys=None, out_id=None):
        """
        Creates an Object for an outgoing connection stored in an OutReference

        Args:
            keys (set, optional): The set can be passed to the creation of the object. If nothing gets passed the key set gets
                initialized with an empty set.
            out_id (RelayId, optional): The outgoing id can be passed as a RelayId. If nothing gets passed the out id is None which means
                that the OutReference has not outgoing connection. Normally the Relay holding the OutReference with the out_id
                set to None is a sink Relay.
        """
        if keys is None:
            self.__keys = set([])
        else:
            self.__keys = keys
        self._out_id = out_id

    def _set_keys(self, keys: set):
        if type(keys) is set:
            self.__keys = keys

    def _get_keys(self):
        """Handles the keys attribute.
        When setting the value the attribute is only set if it is an object of type set.
        """
        return self.__keys

    def add_key(self, key):
        """Adds the given key to the set of keys.

        Args:
            key (str): The key that should be added.
        """
        self.__keys.add(key)

    def remove_key(self, key):
        """Removes the given key from the set.

        Args:
            key (str): The key string that should be removed
        """
        self.__keys.discard(key)

    def _set_id(self, out_id):
        if isinstance(out_id, RelayId) or out_id is None:
            self._out_id = out_id

    def _get_id(self):
        """Handles the outgoing relay id.
        If setting this value it is only set if the given id is an instance of RelayId or None for a sink relay.
        """
        return self._out_id

    keys = property(_get_keys, _set_keys)
    out_id = property(_get_id, _set_id)

    def __str__(self):
        return "Out Reference: \n\t\tkeys: {} \n\t\tout_id: {}".format(str(self.__keys), str(self._out_id))

    def __eq__(self, other):
        return self.__class__ == other.__class__ and self._out_id == other.out_id and self.__keys == other.keys


class InReference:
    """
    Holds the information needed for an outgoing connection to another Relay.

    Attributes:
        key (string): Stores the key of the incoming connection
        rid (RelayLayerId): Stores the RelayLayerId defining the RelayLayer which is allowed to send messages over this incoming connection
        relay (Relay): Stores the Relay which forwarded the reference. This incoming connection is not validated yet if the relay is
            set but the rid is not.
    """

    def __init__(self, key="", rid=None, relay=None):
        """Creates an object of the InReference class.

        Args:
            key (str, optional): The key of the incoming connection. Normally it is set to an empty string.
            rid (RelayLayerId, optional): Defines the RelayLayer from which an incoming connection is allowed. Normally
                this is set to None if nothing was passed.
            relay (Relay, optional): The Relay that passed the incoming connection for an indirect connection.
                Normally this is net to None if nothing was passed.
        """
        self.__key = key
        self.__rid = rid
        self.__relay = relay

    def __get_key(self):
        """Handles the connection key.
        """
        return self.__key

    def __set_key(self, key):
        self.__key = key

    def __get_rid(self):
        """Handles the rid of the incoming connection

        When setting this attribute, the value is only set to the given value if it is an instance of RelayLayerId.
        Otherwise it is set to None.
        """
        return self.__rid

    def __set_rid(self, rid):
        if isinstance(rid, RelayLayerId):
            self.__rid = rid
        else:
            self.__rid = None

    def __get_relay(self):
        """Handles the relay of the incoming connection.

        Sets the value only if the given value is an instance of Relay. Otherwise it is set to None.
        """
        return self.__relay

    def __set_relay(self, relay):
        if isinstance(relay, Relay):
            self.__relay = relay
        else:
            self.__relay = None

    def check_valid(self):
        """Checks if the incoming Reference is filled correctly.

        Returns true if key is set and relay is set to a Relay object and rid is None or relay is none and rid is set
        to a RelayLayerId object.

        Returns:
            bool: True if key is set and relay is set to a Relay object and rid is None or relay is none and rid is set
                to a RelayLayerId object. False otherwise.
        """
        if self.__key != "" and \
                (self.__relay is not None and self.__rid is None and isinstance(self.__relay, Relay) or
                 self.__relay is None and self.__rid is not None and isinstance(self.__rid, RelayLayerId)):
            return True
        else:
            return False

    key = property(__get_key, __set_key)
    rid = property(__get_rid, __set_rid)
    relay = property(__get_relay, __set_relay)

    def __str__(self):
        relay = self.__relay
        third = None if relay is None else str(relay.relay_id) + '->' + str(relay.sink_rid)
        return "In Reference: \n\t\t\tkey: {} \n\t\t\trid: {} \n\t\t\trelay:" \
               " {}" \
            .format(str(self.__key), str(self.__rid), third)

    def __eq__(self, other):
        return self.__class__ == other.__class__ and self.__key == other.key and self.__rid == other.rid and \
               self.__relay == other.relay


class Relay:
    """The Relay class holds every information used to define a Relay for the RelayLayer.

    Attributes:
        relay_id (RelayId): Stores the RelayId of the specific relay. Can be set via the constructor.
        alive (bool): Stores the state of the relay if it is dead or alive. By default this is set to True.
        out_relay (OutReference): Stores the outgoing connection of the Relay. This is by default an empty OutReference.
            Which means the created Relay is a sink relay.
        level (int): Stores the level of the Relay which describes the amount of hops needed to arrive at a sink
            relay. By default is this set to 0.
        sink_rid (RelayLayerId): Stores the RelayLayerId managing the sink relay of this relay. By default this is set
            to the RelayLayerId holding this exact relay.
        in_relays (list): Stores the incoming connections of the relay as a list of InReference objects. By default this
             is set to an empty list.
        validated (bool): Stores the validated flag of a relay. Needed for deletion issues in Node class.
        dos_threshold (int): Stores the threshold of this relay object for dos detection. By default this is set to the
            threshold set in the module config.
    """

    def __init__(self, relay_id: RelayId):
        """Creates a Relay object for a specific RelayId.

        It creates an empty Relay object with all attributes set to the default value.

        Args:
            relay_id (RelayId): Defines the RelayId of the Relay that should be created.
        """
        self.relay_id = relay_id
        self.alive = True
        self.out_relay = OutReference()
        self.level = 0
        self.sink_rid = relay_id.layer_id
        self.in_relays = []
        self.validated = True
        self.dos_threshold = ModuleConfig.CHANGE_ALPHA

    def __eq__(self, other):
        return self.__class__ == other.__class__ and self.relay_id == other.relay_id and self.alive == other.alive and \
               self.out_relay == other.out_relay and self.level == other.level and self.sink_rid == other.sink_rid

    def add_in_reference(self, in_ref):
        """Adds a given incoming reference to the list of incoming references.

        The given incoming reference gets only added if it is an object of the InReference class.

        Args:
            in_ref (InReference): InReference object that should be added as a incoming connection.
        """
        if isinstance(in_ref, InReference):
            self.in_relays += [in_ref]

    def remove_in_reference(self, in_ref):
        """Removes the given incoming reference from the incoming reference list.

        If the given in reference is not in the list nothing happens.

        Args:
            in_ref: The reference that should be removed as InReference object.
        """
        if in_ref in self.in_relays:
            self.in_relays.remove(in_ref)

    def has_incoming(self):
        """Return the amount of incoming connections of the relay.

        Returns:
            int: The amount of incoming connections.
        """
        return len(self.in_relays) > 0

    def is_sink(self):
        """Returns true if the relay level is zero and false otherwise.

        Returns:
            bool: True if the relay is a sink relay, False otherwise.
        """
        return self.level == 0

    def is_direct(self):
        """Returns true if level is lower or equal than one. Otherwise it returns false.

        Returns:
            bool: True if the relay is a direct relay, False otherwise.
        """
        return self.level <= 1

    def is_dead(self):
        """Returns true if the Relay is not alive. Otherwise it returns false.

        The relay is not alive if the alive state is false.

        Returns:
            bool: True if the alive state is False, False otherwise.
        """
        return not self.alive

    def clear_in_relays(self):
        """Removes all incoming references from the relay.
        """
        self.in_relays.clear()

    def same_target(self, other):
        """Compares the outgoing connection of this relay to another relay.

        Args:
            other (Relay): The Relay which should be compared.

        Return:
            bool: True if both have same target, False otherwise.
        """
        return self.__class__ == other.__class__ and self.out_relay.out_id == other.out_relay.out_id

    def remove_in_reference_by_relay(self, relay):
        """Removes all incoming references of this relay when the relay of the InReference is set to the given relay.

        Args:
            relay (Relay): The relay that needs to be set for deleting the InReference.
        """
        for in_ref in self.in_relays.copy():
            if in_ref.relay == relay and in_ref.rid is None:
                if in_ref in self.in_relays:
                    self.in_relays.remove(in_ref)

    def remove_in_reference_by_relay_and_key(self, key, relay):
        """Removes all incoming reference if the key and relay is set to the given key and relay.

        Args:
            key (str): The key that should be compared to remove the InReferences
            relay (Relay): The relay that should be compared to remove the InReferences
        """
        for in_ref in self.in_relays.copy():
            if in_ref.relay == relay and in_ref.rid is None and in_ref.key == key:
                if in_ref in self.in_relays:
                    self.in_relays.remove(in_ref)

    def remove_in_reference_by_rid(self, rid):
        """Removes all incoming references of this relay when the rid of the InReference is set to the given rid.

        Args:
            rid (RelayLayerId): The relay for which all InReferences should be removed.
        """
        for in_ref in self.in_relays:
            if in_ref.rid == rid and in_ref.relay is None:
                if in_ref in self.in_relays:
                    self.in_relays.remove(in_ref)

    def remove_in_reference_by_key_and_rid(self, key, rid):
        """Removes all incoming references of this relay if the InReference key and rid equals to the given key and rid.

        Args:
            key (str): The key that should be compared to remove the InReferences
            rid (RelayLayerId): The RelayLayerId that should be compared to remove the InReferences
        """
        for in_ref in self.in_relays.copy():
            if in_ref.key == key and in_ref.rid == rid and in_ref.relay is None:
                if in_ref in self.in_relays:
                    self.in_relays.remove(in_ref)

    def get_valid_keys(self, sender_rid):
        """Gets all keys that are set in incoming references where the rid is set to the given rid.

        Args:
            sender_rid (RelayLayerId): The RelayLayerId for which all keys are fetched.

        Returns:
            list: A list of keys that are set in incoming references.
        """

        valid_in_ref_keys = [in_ref.key for in_ref in self.in_relays if in_ref.rid is None or in_ref.rid == sender_rid
                             and in_ref.relay is None]

        return valid_in_ref_keys

    def has_key_in_in_ref(self, key):
        """Checks if the given key is in one of the incoming references.

        Args:
            key (str): The key that should be checked.

        Returns:
            bool: True if the key is set in one incoming reference, False otherwise.
        """
        for in_ref in self.in_relays:
            if key == in_ref.key:
                return True
        return False

    def replace_relay_in_references(self, previous_relay, new_relay):
        """Replaces the relay in all in references to the given new relay if the relay is set to the given previous relay.

        Args:
            previous_relay (Relay): The relay that should be replaced
            new_relay (Relay): The relay that should be in the incoming connections after replacement.
        """
        for in_ref in self.in_relays.copy():
            if in_ref.relay == previous_relay:
                in_ref.relay = new_relay

    def __str__(self):
        in_relay_string = '\n\t\t'.join('%s' % str(relay) for relay in self.in_relays)
        return "Relay with id {} has following attributes: \n\t alive: {}" \
               "\n\t out: {} \n\t in: {}\n\t level:{} \n\t " \
               "sink: {} \n\t validated: {}".format(self.relay_id, self.alive, self.out_relay,
                                                    in_relay_string, self.level, self.sink_rid,
                                                    self.validated)

Classes

class InReference (key='', rid=None, relay=None)

Holds the information needed for an outgoing connection to another Relay.

Attributes

key : string
Stores the key of the incoming connection
rid : RelayLayerId
Stores the RelayLayerId defining the RelayLayer which is allowed to send messages over this incoming connection
relay : Relay
Stores the Relay which forwarded the reference. This incoming connection is not validated yet if the relay is set but the rid is not.

Creates an object of the InReference class.

Args

key : str, optional
The key of the incoming connection. Normally it is set to an empty string.
rid : RelayLayerId, optional
Defines the RelayLayer from which an incoming connection is allowed. Normally this is set to None if nothing was passed.
relay : Relay, optional
The Relay that passed the incoming connection for an indirect connection. Normally this is net to None if nothing was passed.
Expand source code
class InReference:
    """
    Holds the information needed for an outgoing connection to another Relay.

    Attributes:
        key (string): Stores the key of the incoming connection
        rid (RelayLayerId): Stores the RelayLayerId defining the RelayLayer which is allowed to send messages over this incoming connection
        relay (Relay): Stores the Relay which forwarded the reference. This incoming connection is not validated yet if the relay is
            set but the rid is not.
    """

    def __init__(self, key="", rid=None, relay=None):
        """Creates an object of the InReference class.

        Args:
            key (str, optional): The key of the incoming connection. Normally it is set to an empty string.
            rid (RelayLayerId, optional): Defines the RelayLayer from which an incoming connection is allowed. Normally
                this is set to None if nothing was passed.
            relay (Relay, optional): The Relay that passed the incoming connection for an indirect connection.
                Normally this is net to None if nothing was passed.
        """
        self.__key = key
        self.__rid = rid
        self.__relay = relay

    def __get_key(self):
        """Handles the connection key.
        """
        return self.__key

    def __set_key(self, key):
        self.__key = key

    def __get_rid(self):
        """Handles the rid of the incoming connection

        When setting this attribute, the value is only set to the given value if it is an instance of RelayLayerId.
        Otherwise it is set to None.
        """
        return self.__rid

    def __set_rid(self, rid):
        if isinstance(rid, RelayLayerId):
            self.__rid = rid
        else:
            self.__rid = None

    def __get_relay(self):
        """Handles the relay of the incoming connection.

        Sets the value only if the given value is an instance of Relay. Otherwise it is set to None.
        """
        return self.__relay

    def __set_relay(self, relay):
        if isinstance(relay, Relay):
            self.__relay = relay
        else:
            self.__relay = None

    def check_valid(self):
        """Checks if the incoming Reference is filled correctly.

        Returns true if key is set and relay is set to a Relay object and rid is None or relay is none and rid is set
        to a RelayLayerId object.

        Returns:
            bool: True if key is set and relay is set to a Relay object and rid is None or relay is none and rid is set
                to a RelayLayerId object. False otherwise.
        """
        if self.__key != "" and \
                (self.__relay is not None and self.__rid is None and isinstance(self.__relay, Relay) or
                 self.__relay is None and self.__rid is not None and isinstance(self.__rid, RelayLayerId)):
            return True
        else:
            return False

    key = property(__get_key, __set_key)
    rid = property(__get_rid, __set_rid)
    relay = property(__get_relay, __set_relay)

    def __str__(self):
        relay = self.__relay
        third = None if relay is None else str(relay.relay_id) + '->' + str(relay.sink_rid)
        return "In Reference: \n\t\t\tkey: {} \n\t\t\trid: {} \n\t\t\trelay:" \
               " {}" \
            .format(str(self.__key), str(self.__rid), third)

    def __eq__(self, other):
        return self.__class__ == other.__class__ and self.__key == other.key and self.__rid == other.rid and \
               self.__relay == other.relay

Instance variables

var key

Handles the connection key.

Expand source code
def __get_key(self):
    """Handles the connection key.
    """
    return self.__key
var relay

Handles the relay of the incoming connection.

Sets the value only if the given value is an instance of Relay. Otherwise it is set to None.

Expand source code
def __get_relay(self):
    """Handles the relay of the incoming connection.

    Sets the value only if the given value is an instance of Relay. Otherwise it is set to None.
    """
    return self.__relay
var rid

Handles the rid of the incoming connection

When setting this attribute, the value is only set to the given value if it is an instance of RelayLayerId. Otherwise it is set to None.

Expand source code
def __get_rid(self):
    """Handles the rid of the incoming connection

    When setting this attribute, the value is only set to the given value if it is an instance of RelayLayerId.
    Otherwise it is set to None.
    """
    return self.__rid

Methods

def check_valid(self)

Checks if the incoming Reference is filled correctly.

Returns true if key is set and relay is set to a Relay object and rid is None or relay is none and rid is set to a RelayLayerId object.

Returns

bool
True if key is set and relay is set to a Relay object and rid is None or relay is none and rid is set to a RelayLayerId object. False otherwise.
Expand source code
def check_valid(self):
    """Checks if the incoming Reference is filled correctly.

    Returns true if key is set and relay is set to a Relay object and rid is None or relay is none and rid is set
    to a RelayLayerId object.

    Returns:
        bool: True if key is set and relay is set to a Relay object and rid is None or relay is none and rid is set
            to a RelayLayerId object. False otherwise.
    """
    if self.__key != "" and \
            (self.__relay is not None and self.__rid is None and isinstance(self.__relay, Relay) or
             self.__relay is None and self.__rid is not None and isinstance(self.__rid, RelayLayerId)):
        return True
    else:
        return False
class OutReference (keys=None, out_id=None)

Holds the information needed for an outgoing connection to another Relay.

Attributes

keys : set
Stores all keys in a set used in the outgoing connection
out_id : RelayId
Stores the RelayId defining the Relay to which the OutReference is connected to

Creates an Object for an outgoing connection stored in an OutReference

Args

keys : set, optional
The set can be passed to the creation of the object. If nothing gets passed the key set gets initialized with an empty set.
out_id : RelayId, optional
The outgoing id can be passed as a RelayId. If nothing gets passed the out id is None which means that the OutReference has not outgoing connection. Normally the Relay holding the OutReference with the out_id set to None is a sink Relay.
Expand source code
class OutReference:
    """Holds the information needed for an outgoing connection to another Relay.

    Attributes:
        keys (set): Stores all keys in a set used in the outgoing connection
        out_id (RelayId): Stores the RelayId defining the Relay to which the OutReference is connected to
    """

    def __init__(self, keys=None, out_id=None):
        """
        Creates an Object for an outgoing connection stored in an OutReference

        Args:
            keys (set, optional): The set can be passed to the creation of the object. If nothing gets passed the key set gets
                initialized with an empty set.
            out_id (RelayId, optional): The outgoing id can be passed as a RelayId. If nothing gets passed the out id is None which means
                that the OutReference has not outgoing connection. Normally the Relay holding the OutReference with the out_id
                set to None is a sink Relay.
        """
        if keys is None:
            self.__keys = set([])
        else:
            self.__keys = keys
        self._out_id = out_id

    def _set_keys(self, keys: set):
        if type(keys) is set:
            self.__keys = keys

    def _get_keys(self):
        """Handles the keys attribute.
        When setting the value the attribute is only set if it is an object of type set.
        """
        return self.__keys

    def add_key(self, key):
        """Adds the given key to the set of keys.

        Args:
            key (str): The key that should be added.
        """
        self.__keys.add(key)

    def remove_key(self, key):
        """Removes the given key from the set.

        Args:
            key (str): The key string that should be removed
        """
        self.__keys.discard(key)

    def _set_id(self, out_id):
        if isinstance(out_id, RelayId) or out_id is None:
            self._out_id = out_id

    def _get_id(self):
        """Handles the outgoing relay id.
        If setting this value it is only set if the given id is an instance of RelayId or None for a sink relay.
        """
        return self._out_id

    keys = property(_get_keys, _set_keys)
    out_id = property(_get_id, _set_id)

    def __str__(self):
        return "Out Reference: \n\t\tkeys: {} \n\t\tout_id: {}".format(str(self.__keys), str(self._out_id))

    def __eq__(self, other):
        return self.__class__ == other.__class__ and self._out_id == other.out_id and self.__keys == other.keys

Instance variables

var keys

Handles the keys attribute. When setting the value the attribute is only set if it is an object of type set.

Expand source code
def _get_keys(self):
    """Handles the keys attribute.
    When setting the value the attribute is only set if it is an object of type set.
    """
    return self.__keys
var out_id

Handles the outgoing relay id. If setting this value it is only set if the given id is an instance of RelayId or None for a sink relay.

Expand source code
def _get_id(self):
    """Handles the outgoing relay id.
    If setting this value it is only set if the given id is an instance of RelayId or None for a sink relay.
    """
    return self._out_id

Methods

def add_key(self, key)

Adds the given key to the set of keys.

Args

key : str
The key that should be added.
Expand source code
def add_key(self, key):
    """Adds the given key to the set of keys.

    Args:
        key (str): The key that should be added.
    """
    self.__keys.add(key)
def remove_key(self, key)

Removes the given key from the set.

Args

key : str
The key string that should be removed
Expand source code
def remove_key(self, key):
    """Removes the given key from the set.

    Args:
        key (str): The key string that should be removed
    """
    self.__keys.discard(key)
class Relay (relay_id: RelayId)

The Relay class holds every information used to define a Relay for the RelayLayer.

Attributes

relay_id : RelayId
Stores the RelayId of the specific relay. Can be set via the constructor.
alive : bool
Stores the state of the relay if it is dead or alive. By default this is set to True.
out_relay : OutReference
Stores the outgoing connection of the Relay. This is by default an empty OutReference. Which means the created Relay is a sink relay.
level : int
Stores the level of the Relay which describes the amount of hops needed to arrive at a sink relay. By default is this set to 0.
sink_rid : RelayLayerId
Stores the RelayLayerId managing the sink relay of this relay. By default this is set to the RelayLayerId holding this exact relay.
in_relays : list
Stores the incoming connections of the relay as a list of InReference objects. By default this is set to an empty list.
validated : bool
Stores the validated flag of a relay. Needed for deletion issues in Node class.
dos_threshold : int
Stores the threshold of this relay object for dos detection. By default this is set to the threshold set in the module config.

Creates a Relay object for a specific RelayId.

It creates an empty Relay object with all attributes set to the default value.

Args

relay_id : RelayId
Defines the RelayId of the Relay that should be created.
Expand source code
class Relay:
    """The Relay class holds every information used to define a Relay for the RelayLayer.

    Attributes:
        relay_id (RelayId): Stores the RelayId of the specific relay. Can be set via the constructor.
        alive (bool): Stores the state of the relay if it is dead or alive. By default this is set to True.
        out_relay (OutReference): Stores the outgoing connection of the Relay. This is by default an empty OutReference.
            Which means the created Relay is a sink relay.
        level (int): Stores the level of the Relay which describes the amount of hops needed to arrive at a sink
            relay. By default is this set to 0.
        sink_rid (RelayLayerId): Stores the RelayLayerId managing the sink relay of this relay. By default this is set
            to the RelayLayerId holding this exact relay.
        in_relays (list): Stores the incoming connections of the relay as a list of InReference objects. By default this
             is set to an empty list.
        validated (bool): Stores the validated flag of a relay. Needed for deletion issues in Node class.
        dos_threshold (int): Stores the threshold of this relay object for dos detection. By default this is set to the
            threshold set in the module config.
    """

    def __init__(self, relay_id: RelayId):
        """Creates a Relay object for a specific RelayId.

        It creates an empty Relay object with all attributes set to the default value.

        Args:
            relay_id (RelayId): Defines the RelayId of the Relay that should be created.
        """
        self.relay_id = relay_id
        self.alive = True
        self.out_relay = OutReference()
        self.level = 0
        self.sink_rid = relay_id.layer_id
        self.in_relays = []
        self.validated = True
        self.dos_threshold = ModuleConfig.CHANGE_ALPHA

    def __eq__(self, other):
        return self.__class__ == other.__class__ and self.relay_id == other.relay_id and self.alive == other.alive and \
               self.out_relay == other.out_relay and self.level == other.level and self.sink_rid == other.sink_rid

    def add_in_reference(self, in_ref):
        """Adds a given incoming reference to the list of incoming references.

        The given incoming reference gets only added if it is an object of the InReference class.

        Args:
            in_ref (InReference): InReference object that should be added as a incoming connection.
        """
        if isinstance(in_ref, InReference):
            self.in_relays += [in_ref]

    def remove_in_reference(self, in_ref):
        """Removes the given incoming reference from the incoming reference list.

        If the given in reference is not in the list nothing happens.

        Args:
            in_ref: The reference that should be removed as InReference object.
        """
        if in_ref in self.in_relays:
            self.in_relays.remove(in_ref)

    def has_incoming(self):
        """Return the amount of incoming connections of the relay.

        Returns:
            int: The amount of incoming connections.
        """
        return len(self.in_relays) > 0

    def is_sink(self):
        """Returns true if the relay level is zero and false otherwise.

        Returns:
            bool: True if the relay is a sink relay, False otherwise.
        """
        return self.level == 0

    def is_direct(self):
        """Returns true if level is lower or equal than one. Otherwise it returns false.

        Returns:
            bool: True if the relay is a direct relay, False otherwise.
        """
        return self.level <= 1

    def is_dead(self):
        """Returns true if the Relay is not alive. Otherwise it returns false.

        The relay is not alive if the alive state is false.

        Returns:
            bool: True if the alive state is False, False otherwise.
        """
        return not self.alive

    def clear_in_relays(self):
        """Removes all incoming references from the relay.
        """
        self.in_relays.clear()

    def same_target(self, other):
        """Compares the outgoing connection of this relay to another relay.

        Args:
            other (Relay): The Relay which should be compared.

        Return:
            bool: True if both have same target, False otherwise.
        """
        return self.__class__ == other.__class__ and self.out_relay.out_id == other.out_relay.out_id

    def remove_in_reference_by_relay(self, relay):
        """Removes all incoming references of this relay when the relay of the InReference is set to the given relay.

        Args:
            relay (Relay): The relay that needs to be set for deleting the InReference.
        """
        for in_ref in self.in_relays.copy():
            if in_ref.relay == relay and in_ref.rid is None:
                if in_ref in self.in_relays:
                    self.in_relays.remove(in_ref)

    def remove_in_reference_by_relay_and_key(self, key, relay):
        """Removes all incoming reference if the key and relay is set to the given key and relay.

        Args:
            key (str): The key that should be compared to remove the InReferences
            relay (Relay): The relay that should be compared to remove the InReferences
        """
        for in_ref in self.in_relays.copy():
            if in_ref.relay == relay and in_ref.rid is None and in_ref.key == key:
                if in_ref in self.in_relays:
                    self.in_relays.remove(in_ref)

    def remove_in_reference_by_rid(self, rid):
        """Removes all incoming references of this relay when the rid of the InReference is set to the given rid.

        Args:
            rid (RelayLayerId): The relay for which all InReferences should be removed.
        """
        for in_ref in self.in_relays:
            if in_ref.rid == rid and in_ref.relay is None:
                if in_ref in self.in_relays:
                    self.in_relays.remove(in_ref)

    def remove_in_reference_by_key_and_rid(self, key, rid):
        """Removes all incoming references of this relay if the InReference key and rid equals to the given key and rid.

        Args:
            key (str): The key that should be compared to remove the InReferences
            rid (RelayLayerId): The RelayLayerId that should be compared to remove the InReferences
        """
        for in_ref in self.in_relays.copy():
            if in_ref.key == key and in_ref.rid == rid and in_ref.relay is None:
                if in_ref in self.in_relays:
                    self.in_relays.remove(in_ref)

    def get_valid_keys(self, sender_rid):
        """Gets all keys that are set in incoming references where the rid is set to the given rid.

        Args:
            sender_rid (RelayLayerId): The RelayLayerId for which all keys are fetched.

        Returns:
            list: A list of keys that are set in incoming references.
        """

        valid_in_ref_keys = [in_ref.key for in_ref in self.in_relays if in_ref.rid is None or in_ref.rid == sender_rid
                             and in_ref.relay is None]

        return valid_in_ref_keys

    def has_key_in_in_ref(self, key):
        """Checks if the given key is in one of the incoming references.

        Args:
            key (str): The key that should be checked.

        Returns:
            bool: True if the key is set in one incoming reference, False otherwise.
        """
        for in_ref in self.in_relays:
            if key == in_ref.key:
                return True
        return False

    def replace_relay_in_references(self, previous_relay, new_relay):
        """Replaces the relay in all in references to the given new relay if the relay is set to the given previous relay.

        Args:
            previous_relay (Relay): The relay that should be replaced
            new_relay (Relay): The relay that should be in the incoming connections after replacement.
        """
        for in_ref in self.in_relays.copy():
            if in_ref.relay == previous_relay:
                in_ref.relay = new_relay

    def __str__(self):
        in_relay_string = '\n\t\t'.join('%s' % str(relay) for relay in self.in_relays)
        return "Relay with id {} has following attributes: \n\t alive: {}" \
               "\n\t out: {} \n\t in: {}\n\t level:{} \n\t " \
               "sink: {} \n\t validated: {}".format(self.relay_id, self.alive, self.out_relay,
                                                    in_relay_string, self.level, self.sink_rid,
                                                    self.validated)

Methods

def add_in_reference(self, in_ref)

Adds a given incoming reference to the list of incoming references.

The given incoming reference gets only added if it is an object of the InReference class.

Args

in_ref : InReference
InReference object that should be added as a incoming connection.
Expand source code
def add_in_reference(self, in_ref):
    """Adds a given incoming reference to the list of incoming references.

    The given incoming reference gets only added if it is an object of the InReference class.

    Args:
        in_ref (InReference): InReference object that should be added as a incoming connection.
    """
    if isinstance(in_ref, InReference):
        self.in_relays += [in_ref]
def clear_in_relays(self)

Removes all incoming references from the relay.

Expand source code
def clear_in_relays(self):
    """Removes all incoming references from the relay.
    """
    self.in_relays.clear()
def get_valid_keys(self, sender_rid)

Gets all keys that are set in incoming references where the rid is set to the given rid.

Args

sender_rid : RelayLayerId
The RelayLayerId for which all keys are fetched.

Returns

list
A list of keys that are set in incoming references.
Expand source code
def get_valid_keys(self, sender_rid):
    """Gets all keys that are set in incoming references where the rid is set to the given rid.

    Args:
        sender_rid (RelayLayerId): The RelayLayerId for which all keys are fetched.

    Returns:
        list: A list of keys that are set in incoming references.
    """

    valid_in_ref_keys = [in_ref.key for in_ref in self.in_relays if in_ref.rid is None or in_ref.rid == sender_rid
                         and in_ref.relay is None]

    return valid_in_ref_keys
def has_incoming(self)

Return the amount of incoming connections of the relay.

Returns

int
The amount of incoming connections.
Expand source code
def has_incoming(self):
    """Return the amount of incoming connections of the relay.

    Returns:
        int: The amount of incoming connections.
    """
    return len(self.in_relays) > 0
def has_key_in_in_ref(self, key)

Checks if the given key is in one of the incoming references.

Args

key : str
The key that should be checked.

Returns

bool
True if the key is set in one incoming reference, False otherwise.
Expand source code
def has_key_in_in_ref(self, key):
    """Checks if the given key is in one of the incoming references.

    Args:
        key (str): The key that should be checked.

    Returns:
        bool: True if the key is set in one incoming reference, False otherwise.
    """
    for in_ref in self.in_relays:
        if key == in_ref.key:
            return True
    return False
def is_dead(self)

Returns true if the Relay is not alive. Otherwise it returns false.

The relay is not alive if the alive state is false.

Returns

bool
True if the alive state is False, False otherwise.
Expand source code
def is_dead(self):
    """Returns true if the Relay is not alive. Otherwise it returns false.

    The relay is not alive if the alive state is false.

    Returns:
        bool: True if the alive state is False, False otherwise.
    """
    return not self.alive
def is_direct(self)

Returns true if level is lower or equal than one. Otherwise it returns false.

Returns

bool
True if the relay is a direct relay, False otherwise.
Expand source code
def is_direct(self):
    """Returns true if level is lower or equal than one. Otherwise it returns false.

    Returns:
        bool: True if the relay is a direct relay, False otherwise.
    """
    return self.level <= 1
def is_sink(self)

Returns true if the relay level is zero and false otherwise.

Returns

bool
True if the relay is a sink relay, False otherwise.
Expand source code
def is_sink(self):
    """Returns true if the relay level is zero and false otherwise.

    Returns:
        bool: True if the relay is a sink relay, False otherwise.
    """
    return self.level == 0
def remove_in_reference(self, in_ref)

Removes the given incoming reference from the incoming reference list.

If the given in reference is not in the list nothing happens.

Args

in_ref
The reference that should be removed as InReference object.
Expand source code
def remove_in_reference(self, in_ref):
    """Removes the given incoming reference from the incoming reference list.

    If the given in reference is not in the list nothing happens.

    Args:
        in_ref: The reference that should be removed as InReference object.
    """
    if in_ref in self.in_relays:
        self.in_relays.remove(in_ref)
def remove_in_reference_by_key_and_rid(self, key, rid)

Removes all incoming references of this relay if the InReference key and rid equals to the given key and rid.

Args

key : str
The key that should be compared to remove the InReferences
rid : RelayLayerId
The RelayLayerId that should be compared to remove the InReferences
Expand source code
def remove_in_reference_by_key_and_rid(self, key, rid):
    """Removes all incoming references of this relay if the InReference key and rid equals to the given key and rid.

    Args:
        key (str): The key that should be compared to remove the InReferences
        rid (RelayLayerId): The RelayLayerId that should be compared to remove the InReferences
    """
    for in_ref in self.in_relays.copy():
        if in_ref.key == key and in_ref.rid == rid and in_ref.relay is None:
            if in_ref in self.in_relays:
                self.in_relays.remove(in_ref)
def remove_in_reference_by_relay(self, relay)

Removes all incoming references of this relay when the relay of the InReference is set to the given relay.

Args

relay : Relay
The relay that needs to be set for deleting the InReference.
Expand source code
def remove_in_reference_by_relay(self, relay):
    """Removes all incoming references of this relay when the relay of the InReference is set to the given relay.

    Args:
        relay (Relay): The relay that needs to be set for deleting the InReference.
    """
    for in_ref in self.in_relays.copy():
        if in_ref.relay == relay and in_ref.rid is None:
            if in_ref in self.in_relays:
                self.in_relays.remove(in_ref)
def remove_in_reference_by_relay_and_key(self, key, relay)

Removes all incoming reference if the key and relay is set to the given key and relay.

Args

key : str
The key that should be compared to remove the InReferences
relay : Relay
The relay that should be compared to remove the InReferences
Expand source code
def remove_in_reference_by_relay_and_key(self, key, relay):
    """Removes all incoming reference if the key and relay is set to the given key and relay.

    Args:
        key (str): The key that should be compared to remove the InReferences
        relay (Relay): The relay that should be compared to remove the InReferences
    """
    for in_ref in self.in_relays.copy():
        if in_ref.relay == relay and in_ref.rid is None and in_ref.key == key:
            if in_ref in self.in_relays:
                self.in_relays.remove(in_ref)
def remove_in_reference_by_rid(self, rid)

Removes all incoming references of this relay when the rid of the InReference is set to the given rid.

Args

rid : RelayLayerId
The relay for which all InReferences should be removed.
Expand source code
def remove_in_reference_by_rid(self, rid):
    """Removes all incoming references of this relay when the rid of the InReference is set to the given rid.

    Args:
        rid (RelayLayerId): The relay for which all InReferences should be removed.
    """
    for in_ref in self.in_relays:
        if in_ref.rid == rid and in_ref.relay is None:
            if in_ref in self.in_relays:
                self.in_relays.remove(in_ref)
def replace_relay_in_references(self, previous_relay, new_relay)

Replaces the relay in all in references to the given new relay if the relay is set to the given previous relay.

Args

previous_relay : Relay
The relay that should be replaced
new_relay : Relay
The relay that should be in the incoming connections after replacement.
Expand source code
def replace_relay_in_references(self, previous_relay, new_relay):
    """Replaces the relay in all in references to the given new relay if the relay is set to the given previous relay.

    Args:
        previous_relay (Relay): The relay that should be replaced
        new_relay (Relay): The relay that should be in the incoming connections after replacement.
    """
    for in_ref in self.in_relays.copy():
        if in_ref.relay == previous_relay:
            in_ref.relay = new_relay
def same_target(self, other)

Compares the outgoing connection of this relay to another relay.

Args

other : Relay
The Relay which should be compared.

Return

bool: True if both have same target, False otherwise.

Expand source code
def same_target(self, other):
    """Compares the outgoing connection of this relay to another relay.

    Args:
        other (Relay): The Relay which should be compared.

    Return:
        bool: True if both have same target, False otherwise.
    """
    return self.__class__ == other.__class__ and self.out_relay.out_id == other.out_relay.out_id