<commit_before>"""
OpenNSA NSI Service -> Backend adaptor (router).

Author: <NAME> <<EMAIL>>
Copyright: NORDUnet (2011)
"""

import uuid

from zope.interface import implements

from twisted.python import log
from twisted.internet import reactor, defer, task

from opennsa.interface import NSIServiceInterface
from opennsa import nsa, error, registry, subscription, connection



LOG_SYSTEM = 'NSIService'



class NSIService:

    implements(NSIServiceInterface)

    def __init__(self, network, backend, service_registry, topology):
        self.network = network
        self.backend = backend
        self.service_registry = service_registry

        self.topology = topology

        # get own nsa from topology
        self.nsa = self.topology.getNetwork(self.network).nsa

        self.connections = {} # persistence, ha!

        self.service_registry.registerEventHandler(registry.RESERVE,   self.reserve,   registry.SYSTEM_SERVICE)
        self.service_registry.registerEventHandler(registry.PROVISION, self.provision, registry.SYSTEM_SERVICE)
        self.service_registry.registerEventHandler(registry.RELEASE,   self.release,   registry.SYSTEM_SERVICE)
        self.service_registry.registerEventHandler(registry.TERMINATE, self.terminate, registry.SYSTEM_SERVICE)
        self.service_registry.registerEventHandler(registry.QUERY,     self.query,     registry.SYSTEM_SERVICE)


    # utility functionality

    def getConnection(self, requester_nsa, connection_id):

        conn = self.connections.get(requester_nsa, {}).get(connection_id, None)
        if conn is None:
            raise error.ConnectionNonExistentError('No connection with id %s for NSA with address %s' % (connection_id, requester_nsa))
        else:
            return conn


    def setupSubConnection(self, link, conn, service_parameters):

        sub_sps = service_parameters.subConnectionClone(link.sourceSTP(), link.destSTP())

        # should check for local network
        if link.network == self.network:
            # nsi2 hack
            src_port = link.src_port + str(link.src_labels[0].values[0][0]) if link.src_labels else link.src_port
            dst_port = link.dst_port + str(link.dst_labels[0].values[0][0]) if link.dst_labels else link.dst_port
            # resolve nrm ports from the topology
            nrm_src_port = self.topology.getEndpoint(self.network, src_port).nrmPort()
            nrm_dst_port = self.topology.getEndpoint(self.network, dst_port).nrmPort()
            sub_conn = self.backend.createConnection(nrm_src_port, nrm_dst_port, sub_sps)
        else:
            sub_conn_id = 'urn:uuid:' + str(uuid.uuid1())
            remote_nsa = self.topology.getNetwork(link.network).nsa
            sub_conn = connection.SubConnection(self.service_registry, self.nsa, remote_nsa, conn, sub_conn_id, link.sourceSTP(), link.destSTP(), sub_sps)

        conn.sub_connections.append(sub_conn)

        return conn


    # command functionality

    def reserve(self, requester_nsa, provider_nsa, session_security_attr, global_reservation_id, description, connection_id, service_parameters, sub):

        # --

        log.msg('', system=LOG_SYSTEM)
        log.msg('Connection %s. Reserve request from %s.' % (connection_id, requester_nsa), system=LOG_SYSTEM)

        if connection_id in self.connections.get(requester_nsa, {}):
            return defer.fail(error.ConnectionExistsError('Connection with id %s already exists' % connection_id))

        source_stp = service_parameters.source_stp
        dest_stp   = service_parameters.dest_stp

        if source_stp == dest_stp:
            return defer.fail(error.TopologyError('Cannot connect %s to itself.' % source_stp))

        conn = connection.Connection(self.service_registry, requester_nsa, connection_id, source_stp, dest_stp, service_parameters, global_reservation_id, description)

        self.connections.setdefault(requester_nsa, {})[conn.connection_id] = conn

        # figure out nature of request

        path_info = ( connection_id, source_stp.network, source_stp.endpoint, dest_stp.network, dest_stp.endpoint, self.network)

        if source_stp.network == self.network and dest_stp.network == self.network:
            local_path_info = ( connection_id, self.network, source_stp.endpoint, dest_stp.endpoint)
            log.msg('Connection %s: Local link creation: %s %s -> %s' % local_path_info, system=LOG_SYSTEM)
            link = nsa.Link(source_stp.network, source_stp.endpoint, dest_stp.endpoint)
            self.setupSubConnection(link, conn, service_parameters)

        # This code is for chaining requests and is currently not used, but might be needed sometime in the future
        # Once we get proper a topology service, some chaining will be necessary.

        #elif source_stp.network == self.network:
        #    # make path and chain on - common chaining
        #    log.msg('Reserve %s: Common chain creation: %s:%s -> %s:%s (%s)' % path_info, system=LOG_SYSTEM)
        #    paths = self.topology.findPaths(source_stp, dest_stp)
        #    # check for no paths
        #    paths.sort(key=lambda e : len(e.endpoint_pairs))
        #    selected_path = paths[0] # shortest path
        #    log.msg('Attempting to create path %s' % selected_path, system=LOG_SYSTEM)
        #    assert selected_path.source_stp.network == self.network
        #   # setup connection data - does this work with more than one hop?
        #    setupSubConnection(selected_path.source_stp, selected_path.endpoint_pairs[0].sourceSTP(), conn)
        #    setupSubConnection(selected_path.endpoint_pairs[0].destSTP(), dest_stp, conn)<commit_msg>remove old comment from nsiservice<commit_after>"""
OpenNSA NSI Service -> Backend adaptor (router).

Author: <NAME> <<EMAIL>>
Copyright: NORDUnet (2011)
"""

import uuid

from zope.interface import implements

from twisted.python import log
from twisted.internet import reactor, defer, task

from opennsa.interface import NSIServiceInterface
from opennsa import nsa, error, registry, subscription, connection



LOG_SYSTEM = 'NSIService'



class NSIService:

    implements(NSIServiceInterface)

    def __init__(self, network, backend, service_registry, topology):
        self.network = network
        self.backend = backend
        self.service_registry = service_registry

        self.topology = topology

        # get own nsa from topology
        self.nsa = self.topology.getNetwork(self.network).nsa

        self.connections = {} # persistence, ha!

        self.service_registry.registerEventHandler(registry.RESERVE,   self.reserve,   registry.SYSTEM_SERVICE)
        self.service_registry.registerEventHandler(registry.PROVISION, self.provision, registry.SYSTEM_SERVICE)
        self.service_registry.registerEventHandler(registry.RELEASE,   self.release,   registry.SYSTEM_SERVICE)
        self.service_registry.registerEventHandler(registry.TERMINATE, self.terminate, registry.SYSTEM_SERVICE)
        self.service_registry.registerEventHandler(registry.QUERY,     self.query,     registry.SYSTEM_SERVICE)


    # utility functionality

    def getConnection(self, requester_nsa, connection_id):

        conn = self.connections.get(requester_nsa, {}).get(connection_id, None)
        if conn is None:
            raise error.ConnectionNonExistentError('No connection with id %s for NSA with address %s' % (connection_id, requester_nsa))
        else:
            return conn


    def setupSubConnection(self, link, conn, service_parameters):

        sub_sps = service_parameters.subConnectionClone(link.sourceSTP(), link.destSTP())

        # should check for local network
        if link.network == self.network:
            # nsi2 hack
            src_port = link.src_port + str(link.src_labels[0].values[0][0]) if link.src_labels else link.src_port
            dst_port = link.dst_port + str(link.dst_labels[0].values[0][0]) if link.dst_labels else link.dst_port
            # resolve nrm ports from the topology
            nrm_src_port = self.topology.getEndpoint(self.network, src_port).nrmPort()
            nrm_dst_port = self.topology.getEndpoint(self.network, dst_port).nrmPort()
            sub_conn = self.backend.createConnection(nrm_src_port, nrm_dst_port, sub_sps)
        else:
            sub_conn_id = 'urn:uuid:' + str(uuid.uuid1())
            remote_nsa = self.topology.getNetwork(link.network).nsa
            sub_conn = connection.SubConnection(self.service_registry, self.nsa, remote_nsa, conn, sub_conn_id, link.sourceSTP(), link.destSTP(), sub_sps)

        conn.sub_connections.append(sub_conn)

        return conn


    # command functionality

    def reserve(self, requester_nsa, provider_nsa, session_security_attr, global_reservation_id, description, connection_id, service_parameters, sub):

        # --

        log.msg('', system=LOG_SYSTEM)
        log.msg('Connection %s. Reserve request from %s.' % (connection_id, requester_nsa), system=LOG_SYSTEM)

        if connection_id in self.connections.get(requester_nsa, {}):
            return defer.fail(error.ConnectionExistsError('Connection with id %s already exists' % connection_id))

        source_stp = service_parameters.source_stp
        dest_stp   = service_parameters.dest_stp

        if source_stp == dest_stp:
            return defer.fail(error.TopologyError('Cannot connect %s to itself.' % source_stp))

        # since STPs are candidates here, we need to change these later on
        conn = connection.Connection(self.service_registry, requester_nsa, connection_id, source_stp, dest_stp, service_parameters, global_reservation_id, description)

        self.connections.setdefault(requester_nsa, {})[conn.connection_id] = conn

        # figure out nature of request

        path_info = ( connection_id, source_stp.network, source_stp.endpoint, dest_stp.network, dest_stp.endpoint, self.network)

        if source_stp.network == self.network and dest_stp.network == self.network:
            local_path_info = ( connection_id, self.network, source_stp.endpoint, dest_stp.endpoint)
            log.msg('Connection %s: Local link creation: %s %s -> %s' % local_path_info, system=LOG_SYSTEM)
            link = nsa.Link(source_stp.network, source_stp.endpoint, dest_stp.endpoint)
            self.setupSubConnection(link, conn, service_parameters)

        # This code is for chaining requests and is currently not used, but might be needed sometime in the future
        # Once we get proper a topology service, some chaining will be necessary.

        #elif source_stp.network == self.network:
        #    # make path and chain on - common chaining
        #    log.msg('Reserve %s: Common chain creation: %s:%s -> %s:%s (%s)' % path_info, system=LOG_SYSTEM)
        #    paths = self.topology.findPaths(source_stp, dest_stp)
        #    # check for no paths
        #    paths.sort(key=lambda e : len(e.endpoint_pairs))
        #    selected_path = paths[0] # shortest path
        #    log.msg('Attempting to create path %s' % selected_path, system=LOG_SYSTEM)
        #    assert selected_path.source_stp.network == self.network
        #   # setup connection data - does this work with more than one hop?
        #    setupSubConnection(selected_path.source_stp, selected_path.endpoint_pairs[0].sourceSTP(), conn)
        #    setupSubConnection(selected_path.endpoint_pairs[0].destSTP(), dest_stp, conn)
{'fraction_non_alphanumeric': 0.09362374846302476, 'fraction_numerical': 0.0026348146847005095, 'mean_word_length': 3.316527672479151, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1318760', 'n_tokens_mistral': 3381, 'n_tokens_neox': 3290, 'n_words': 763}