<commit_before>'''
Created on 2016/4/13

:author: hubo
'''
from vlcp.service.sdn.flowbase import FlowBase
from vlcp.server.module import depend, ModuleNotification, callAPI
import vlcp.service.sdn.ofpportmanager as ofpportmanager
import vlcp.service.sdn.ovsdbportmanager as ovsdbportmanager
import vlcp.service.kvdb.objectdb as objectdb
from vlcp.event.event import Event, withIndices
from vlcp.event.runnable import RoutineContainer, RoutineException
from vlcp.config.config import defaultconfig
from vlcp.service.sdn.ofpmanager import FlowInitialize
from vlcp.utils.networkmodel import PhysicalPort, LogicalPort, PhysicalPortSet, LogicalPortSet, LogicalNetwork, PhysicalNetwork
from vlcp.utils.flowupdater import FlowUpdater
from vlcp.event.connection import ConnectionResetException
from vlcp.protocol.openflow.openflow import OpenflowConnectionStateEvent,\
    OpenflowErrorResultException
from pprint import pformat
from namedstruct import dump

@withIndices('datapathid', 'vhost', 'connection', 'logicalportchanged', 'physicalportchanged',
                                                    'logicalnetworkchanged', 'physicalnetworkchanged')
class DataObjectChanged(Event):
    pass

class IDAssigner(object):
    def __init__(self):
        self._indices = {}
        self._revindices = {}
        # Reserve 0 and 0xffff
        self._revindices[0] = '<reserve0>'
        self._revindices[0xffff] = '<reserve65535>'
        self._lastindex = 1
    def assign(self, key):
        if key in self._indices:
            return self._indices[key]
        else:
            ind = self._lastindex
            while ind in self._revindices:
                ind += 1
                ind &= 0xffff
            self._revindices[ind] = key
            self._indices[key] = ind
            self._lastindex = ind + 1
            return ind
    def unassign(self, keys):
        for k in keys:
            ind = self._indices.pop(k, None)
            if ind is not None:
                del self._revindices[ind]
    def frozen(self):
        return dict(self._indices)

def _to32bitport(portno):
    if portno >= 0xff00:
        portno = 0xffff0000 | portno
    return portno

class IOFlowUpdater(FlowUpdater):
    def __init__(self, connection, systemid, bridgename, parent):
        FlowUpdater.__init__(self, connection, (LogicalPortSet.default_key(),
                                                PhysicalPortSet.default_key()),
                                            ('ioprocessing', connection),
                                            parent._logger)
        self._walkerdict = {LogicalPortSet.default_key(): self._logicalport_walker,
                            PhysicalPortSet.default_key(): self._physicalport_walker
                            }
        self._systemid = systemid
        self._bridgename = bridgename
        self._portnames = {}
        self._portids = {}
        self._currentportids = {}
        self._currentportnames = {}
        self._lastportids = {}
        self._lastportnames = {}
        self._lastnetworkids = {}
        self._networkids = IDAssigner()
        self._phynetworkids = IDAssigner()
        self._physicalnetworkids = {}
        self._logicalportkeys = set()
        self._physicalportkeys = set()
        self._logicalnetworkkeys = set()
        self._physicalnetworkkeys = set()
        self._parent = parent
    def update_ports(self, ports, ovsdb_ports):
        self._portnames.clear()
        self._portnames.update((p['name'], _to32bitport(p['ofport'])) for p in ovsdb_ports)
        self._portids.clear()
        self._portids.update((p['id'], _to32bitport(p['ofport'])) for p in ovsdb_ports if p['id'])
        for m in self.restart_walk():
            yield m
    def _logicalport_walker(self, key, value, walk, save):
        save(key)
        if value is None:
            return
        logset = value.set
        for id in self._portids:
            logports = logset.find(LogicalPort, id)
            for p in logports:
                try:
                    logp = walk(p.getkey())
                except KeyError:
                    pass
                else:
                    save(logp.getkey())
                    try:
                        lognet = walk(logp.network.getkey())
                    except KeyError:
                        pass
                    else:
                        save(lognet.getkey())
                        try:
                            phynet = walk(lognet.physicalnetwork.getkey())
                        except KeyError:
                            pass
                        else:
                            save(phynet.getkey())
                    if hasattr(logp,"subnet"):
                        try:
                            subnet = walk(logp.subnet.getkey())
                        except KeyError:
                            pass
                        else:
                            if hasattr(subnet,"router"):
                                try:
                                    routerport = walk(subnet.router.getkey())
                                except KeyError:
                                    pass
                                else:
                                    if hasattr(routerport,"router"):
                                        try:
                                            router = walk(routerport.router.getkey())
                                        except KeyError:
                                            pass
                                        else:
                                            if router.interfaces.dataset():
                                                for weakobj in router.interfaces.dataset():
                                                    try:
                                                        weakrouterport = walk(weakobj.getkey())
                                                    except KeyError:
                                                        pass
                                                    else:
                                                        try:
                                                            s = walk(weakrouterport.subnet.getkey())
                                                        except KeyError:
                                                            pass
                                                        else:
                                                            try:
                                                                lgnet = walk(s.network.getkey())
                                                            except KeyError:
                                                                pass
                                                            else:
                                                                save(lgnet.getkey())
    def _physicalport_walker(self, key, value, walk, save):
        save(key)
        if value is None:
            return
        physet = value.set
        for name in self._portnames:
            phyports = physet.find(PhysicalPort, self._connection.protocol.vhost, self._systemid, self._bridgename, name)
            # There might be more than one match physical port rule for one port, pick the most specified one
            namedict = {}
            for p in phyports:
                _, inds = PhysicalPort._getIndices(p.getkey())
                name = inds[-1]
                ind_key = [i != '%' for i in inds]
                if name != '%':
                    if name in namedict:
                        if namedict[name][0] < ind_key:
                            namedict[name] = (ind_key, p)
                    else:
                        namedict[name] = (ind_key, p)
            phyports = [v[1] for v in namedict.values()]
            for p in phyports:
                try:
                    phyp = walk(p.getkey())
                except KeyError:
                    pass
                else:
                    save(phyp.getkey())
                    try:
                        phynet = walk(phyp.physicalnetwork.getkey())
                    except KeyError:
                        pass
                    else:
                        save(phynet.getkey())
    def walkcomplete(self, keys, values):
        conn = self._connection
        dpid = conn.openflow_datapathid<commit_msg>修改 ioprocessing 通知 router 相关logicalnetwork的问题<commit_after>'''
Created on 2016/4/13

:author: hubo
'''
from vlcp.service.sdn.flowbase import FlowBase
from vlcp.server.module import depend, ModuleNotification, callAPI
import vlcp.service.sdn.ofpportmanager as ofpportmanager
import vlcp.service.sdn.ovsdbportmanager as ovsdbportmanager
import vlcp.service.kvdb.objectdb as objectdb
from vlcp.event.event import Event, withIndices
from vlcp.event.runnable import RoutineContainer, RoutineException
from vlcp.config.config import defaultconfig
from vlcp.service.sdn.ofpmanager import FlowInitialize
from vlcp.utils.networkmodel import PhysicalPort, LogicalPort, PhysicalPortSet, LogicalPortSet, LogicalNetwork, PhysicalNetwork,SubNet,RouterPort,VRouter
from vlcp.utils.flowupdater import FlowUpdater
from vlcp.event.connection import ConnectionResetException
from vlcp.protocol.openflow.openflow import OpenflowConnectionStateEvent,\
    OpenflowErrorResultException
from pprint import pformat
from namedstruct import dump

import itertools

@withIndices('datapathid', 'vhost', 'connection', 'logicalportchanged', 'physicalportchanged',
                                                    'logicalnetworkchanged', 'physicalnetworkchanged')
class DataObjectChanged(Event):
    pass

class IDAssigner(object):
    def __init__(self):
        self._indices = {}
        self._revindices = {}
        # Reserve 0 and 0xffff
        self._revindices[0] = '<reserve0>'
        self._revindices[0xffff] = '<reserve65535>'
        self._lastindex = 1
    def assign(self, key):
        if key in self._indices:
            return self._indices[key]
        else:
            ind = self._lastindex
            while ind in self._revindices:
                ind += 1
                ind &= 0xffff
            self._revindices[ind] = key
            self._indices[key] = ind
            self._lastindex = ind + 1
            return ind
    def unassign(self, keys):
        for k in keys:
            ind = self._indices.pop(k, None)
            if ind is not None:
                del self._revindices[ind]
    def frozen(self):
        return dict(self._indices)

def _to32bitport(portno):
    if portno >= 0xff00:
        portno = 0xffff0000 | portno
    return portno

class IOFlowUpdater(FlowUpdater):
    def __init__(self, connection, systemid, bridgename, parent):
        FlowUpdater.__init__(self, connection, (LogicalPortSet.default_key(),
                                                PhysicalPortSet.default_key()),
                                            ('ioprocessing', connection),
                                            parent._logger)
        self._walkerdict = {LogicalPortSet.default_key(): self._logicalport_walker,
                            PhysicalPortSet.default_key(): self._physicalport_walker
                            }
        self._systemid = systemid
        self._bridgename = bridgename
        self._portnames = {}
        self._portids = {}
        self._currentportids = {}
        self._currentportnames = {}
        self._lastportids = {}
        self._lastportnames = {}
        self._lastnetworkids = {}
        self._networkids = IDAssigner()
        self._phynetworkids = IDAssigner()
        self._physicalnetworkids = {}
        self._logicalportkeys = set()
        self._physicalportkeys = set()
        self._logicalnetworkkeys = set()
        self._physicalnetworkkeys = set()
        self._parent = parent
    def update_ports(self, ports, ovsdb_ports):
        self._portnames.clear()
        self._portnames.update((p['name'], _to32bitport(p['ofport'])) for p in ovsdb_ports)
        self._portids.clear()
        self._portids.update((p['id'], _to32bitport(p['ofport'])) for p in ovsdb_ports if p['id'])
        for m in self.restart_walk():
            yield m
    def _logicalport_walker(self, key, value, walk, save):
        save(key)
        if value is None:
            return
        logset = value.set
        for id in self._portids:
            logports = logset.find(LogicalPort, id)
            for p in logports:
                try:
                    logp = walk(p.getkey())
                except KeyError:
                    pass
                else:
                    save(logp.getkey())
                    try:
                        lognet = walk(logp.network.getkey())
                    except KeyError:
                        pass
                    else:
                        save(lognet.getkey())
                        try:
                            phynet = walk(lognet.physicalnetwork.getkey())
                        except KeyError:
                            pass
                        else:
                            save(phynet.getkey())
                    if hasattr(logp,"subnet"):
                        try:
                            subnet = walk(logp.subnet.getkey())
                        except KeyError:
                            pass
                        else:
                            save(subnet.getkey())
                            if hasattr(subnet,"router"):
                                try:
                                    routerport = walk(subnet.router.getkey())
                                except KeyError:
                                    pass
                                else:
                                    save(routerport.getkey())
                                    if hasattr(routerport,"router"):
                                        try:
                                            router = walk(routerport.router.getkey())
                                        except KeyError:
                                            pass
                                        else:
                                            save(router.getkey())
                                            if router.interfaces.dataset():
                                                for weakobj in router.interfaces.dataset():
                                                    try:
                                                        weakrouterport = walk(weakobj.getkey())
                                                    except KeyError:
                                                        pass
                                                    else:
                                                        save(weakrouterport.getkey())
                                                        try:
                                                            s = walk(weakrouterport.subnet.getkey())
                                                        except KeyError:
                                                            pass
                                                        else:
                                                            save(s.getkey())
                                                            try:
                                                                lgnet = walk(s.network.getkey())
                                                            except KeyError:
                                                                pass
                                                            else:
                                                                save(lgnet.getkey())
    def _physicalport_walker(self, key, value, walk, save):
        save(key)
        if value is None:
            return
        physet = value.set
        for name in self._portnames:
            phyports = physet.find(PhysicalPort, self._connection.protocol.vhost, self._systemid, self._bridgename, name)
            # There might be more than one match physical port rule for one port, pick the most specified one
            namedict = {}
            for p in phyports:
                _, inds = PhysicalPort._getIndices(p.getkey())
                name = inds[-1]
                ind_key = [i != '%' for i in inds]
                if name != '%':
                    if name in namedict:
                        if namedict[name][0] < ind_key:
                            namedict[name] = (ind_key, p)
                    else:
                        namedict[name] = (ind_key, p)
            phyports = [v[1] for v in namedict.values()]
            for p in phyports:
                try:
                    phyp = walk(p.getkey())
                except KeyError:
                    pass
                else:
                    save(phyp.getkey())
                    try:
                        phynet = walk(phyp.physicalnetwork.getkey())
                    except KeyError:
                        pass
                    else:
                        save(phynet.getkey())

    def reset_initialkeys(self,keys,values):

        subnetkeys = [k for k,v in zip(keys,values) if v.isinstance(SubNet)]
        routerportkeys = [k for k,v in zip(keys,values) if v.isinstance(RouterPort)]
        portkeys = [k for k,v in zip(keys,values) if v.isinstance(VRouter)]
        
        self._initialkeys = tuple(itertools.chain(subnetkeys,routerportkeys,
                                    portkeys,[LogicalPortSet.default_key(),PhysicalPortSet.default_key()]))

    def walkcomplete(self, keys, values):
        conn = self._connection
        dpid = conn.openflow_datapathid
{'fraction_non_alphanumeric': 0.07454678940531993, 'fraction_numerical': 0.0042920878748517535, 'mean_word_length': 1.1025884587983852, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 116, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5878873', 'n_tokens_mistral': 4084, 'n_tokens_neox': 3955, 'n_words': 929}