# Path: opennsa/nsa.py
# LOG_SYSTEM = 'opennsa.nsa'
# URN_UUID_PREFIX = 'urn:uuid:'
# BIDIRECTIONAL   = 'Bidirectional'
# class NSIHeader(object):
# class SecurityAttribute(object):
# class EmptyLabelSet(Exception):
# class Label(object):
# class STP(object): # Service Termination Point
# class Link(object):
# class Path(object):
# class NetworkServiceAgent(object):
# class ConnectionInfo(object):
# class Criteria(object):
# class QueryCriteria(Criteria):
# class Schedule(object):
# class Point2PointService(object):
#     def __init__(self, requester_nsa, provider_nsa, correlation_id=None, reply_to=None, security_attributes=None, connection_trace=None):
#     def _createCorrelationId(self):
#     def newCorrelationId(self):
#     def __repr__(self):
#     def __init__(self, type_, value):
#     def __repr__(self):
#     def __init__(self, type_, values=None):
#     def _parseLabelValues(self, values):
#         def createValue(value):
#     def intersect(self, other):
#     def labelValue(self):
#     def singleValue(self):
#     def enumerateValues(self):
#     def randomLabel(self):
#     def canMatch(l1, l2):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, network, port, label=None):
#     def shortName(self):
#     def baseURN(self):
#     def urn(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, src_stp, dst_stp):
#     def sourceSTP(self):
#     def destSTP(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, network_links):
#     def links(self):
#     def sourceEndpoint(self):
#     def destEndpoint(self):
#     def __str__(self):
#     def __init__(self, identity, endpoint, service_type=None):
#     def getHostPort(self):
#     def urn(self):
#     def getServiceType(self):
#     def __str__(self):
#     def __init__(self, connection_id, global_reservation_id, description, service_type, criterias, provider_nsa, requester_nsa, states, notification_id, result_id):
#     def __init__(self, revision, schedule, service_def):
#     def __init__(self, revision, schedule, service_def, children=None):
#     def __init__(self, start_time, end_time):
#     def __str__(self):
#     def __init__(self, source_stp, dest_stp, capacity, directionality=BIDIRECTIONAL, symmetric=False, ero=None, parameters=None):
# 
# Path: opennsa/plugin.py
# class BasePlugin:
# 
#     """
#     Default plugin.
# 
#     Can be used to inherint from so only relevant methods have to be defined in custom
#     plugins. Also used as default, so we don't have to check to see if a plugin exists
#     before calling.
#     """
# 
#     def init(self, cfg, ctx_factory):
#         self.cfg         = cfg
#         self.ctx_factory = ctx_factory
# 
#         self.conn_prefix = cfg[config.DOMAIN][:2].upper() + '-'
# 
# 
#     def connectionRequest(self, header, connection_id, global_reservation_id, description, criteria):
#         return defer.succeed(None)
# 
# 
#     def createConnectionId(self):
#         connection_id = self.conn_prefix + ''.join( [ random.choice(string.hexdigits[:16]) for _ in range(10) ] )
#         return defer.succeed(connection_id)
# 
# 
#     def prunePaths(self, paths):
#         return defer.succeed(paths)
# 
# 
#     def connectionCreated(self, connection):
#         return defer.succeed(None)
# 
# 
#     def connectionTerminated(self, connection):
#         return defer.succeed(None)


from zope.interface import implementer
from twisted.internet import defer
from opennsa import nsa
from opennsa.interface import IPlugin
from opennsa.plugin import BasePlugin
"""
Plugin to prune paths in order to help the probabilty that a path setup will succeed.

Mostly to work around limitations on certain network equipment, NRM,
and NSI agent implementations.

Author: Henrik Thostrup Jensen < htj at nordu dot net >

Copyright: NORDUnet A/S (2014)
"""





NETWORKS = []


def pruneLabels(path):
    """
    Some networks does not support underspecified STPs and VLAN rewrites so we help them out a bit.
    """
    for idx, link in enumerate(path):

        if any( [ n in link.src_stp.network for n in NETWORKS ] ):
            liv = link.src_stp.label.intersect(link.dst_stp.label)

# Path: opennsa/nsa.py
# LOG_SYSTEM = 'opennsa.nsa'
# URN_UUID_PREFIX = 'urn:uuid:'
# BIDIRECTIONAL   = 'Bidirectional'
# class NSIHeader(object):
# class SecurityAttribute(object):
# class EmptyLabelSet(Exception):
# class Label(object):
# class STP(object): # Service Termination Point
# class Link(object):
# class Path(object):
# class NetworkServiceAgent(object):
# class ConnectionInfo(object):
# class Criteria(object):
# class QueryCriteria(Criteria):
# class Schedule(object):
# class Point2PointService(object):
#     def __init__(self, requester_nsa, provider_nsa, correlation_id=None, reply_to=None, security_attributes=None, connection_trace=None):
#     def _createCorrelationId(self):
#     def newCorrelationId(self):
#     def __repr__(self):
#     def __init__(self, type_, value):
#     def __repr__(self):
#     def __init__(self, type_, values=None):
#     def _parseLabelValues(self, values):
#         def createValue(value):
#     def intersect(self, other):
#     def labelValue(self):
#     def singleValue(self):
#     def enumerateValues(self):
#     def randomLabel(self):
#     def canMatch(l1, l2):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, network, port, label=None):
#     def shortName(self):
#     def baseURN(self):
#     def urn(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, src_stp, dst_stp):
#     def sourceSTP(self):
#     def destSTP(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __init__(self, network_links):
#     def links(self):
#     def sourceEndpoint(self):
#     def destEndpoint(self):
#     def __str__(self):
#     def __init__(self, identity, endpoint, service_type=None):
#     def getHostPort(self):
#     def urn(self):
#     def getServiceType(self):
#     def __str__(self):
#     def __init__(self, connection_id, global_reservation_id, description, service_type, criterias, provider_nsa, requester_nsa, states, notification_id, result_id):
#     def __init__(self, revision, schedule, service_def):
#     def __init__(self, revision, schedule, service_def, children=None):
#     def __init__(self, start_time, end_time):
#     def __str__(self):
#     def __init__(self, source_stp, dest_stp, capacity, directionality=BIDIRECTIONAL, symmetric=False, ero=None, parameters=None):
# 
# Path: opennsa/plugin.py
# class BasePlugin:
# 
#     """
#     Default plugin.
# 
#     Can be used to inherint from so only relevant methods have to be defined in custom
#     plugins. Also used as default, so we don't have to check to see if a plugin exists
#     before calling.
#     """
# 
#     def init(self, cfg, ctx_factory):
#         self.cfg         = cfg
#         self.ctx_factory = ctx_factory
# 
#         self.conn_prefix = cfg[config.DOMAIN][:2].upper() + '-'
# 
# 
#     def connectionRequest(self, header, connection_id, global_reservation_id, description, criteria):
#         return defer.succeed(None)
# 
# 
#     def createConnectionId(self):
#         connection_id = self.conn_prefix + ''.join( [ random.choice(string.hexdigits[:16]) for _ in range(10) ] )
#         return defer.succeed(connection_id)
# 
# 
#     def prunePaths(self, paths):
#         return defer.succeed(paths)
# 
# 
#     def connectionCreated(self, connection):
#         return defer.succeed(None)
# 
# 
#     def connectionTerminated(self, connection):
#         return defer.succeed(None)


# Path: opennsa/plugins/pruner.py
from zope.interface import implementer
from twisted.internet import defer
from opennsa import nsa
from opennsa.interface import IPlugin
from opennsa.plugin import BasePlugin

"""
Plugin to prune paths in order to help the probabilty that a path setup will succeed.

Mostly to work around limitations on certain network equipment, NRM,
and NSI agent implementations.

Author: Henrik Thostrup Jensen < htj at nordu dot net >

Copyright: NORDUnet A/S (2014)
"""





NETWORKS = []


def pruneLabels(path):
    """
    Some networks does not support underspecified STPs and VLAN rewrites so we help them out a bit.
    """
    for idx, link in enumerate(path):

        if any( [ n in link.src_stp.network for n in NETWORKS ] ):
            liv = link.src_stp.label.intersect(link.dst_stp.label)

            lnv = nsa.Label(liv.type_, liv.labelValue())