LOG = logging.getLogger(__name__)
_RESOURCE_MAPPING = {
    resources.SECURITY_GROUP: ODLResource(odl_const.ODL_SG, odl_const.ODL_SGS),
    resources.SECURITY_GROUP_RULE: ODLResource(odl_const.ODL_SG_RULE,
                                               odl_const.ODL_SG_RULES),
}
_OPERATION_MAPPING = {
    events.PRECOMMIT_CREATE: odl_const.ODL_CREATE,
    events.PRECOMMIT_UPDATE: odl_const.ODL_UPDATE,
    events.PRECOMMIT_DELETE: odl_const.ODL_DELETE,
    events.AFTER_CREATE: odl_const.ODL_CREATE,
    events.AFTER_UPDATE: odl_const.ODL_UPDATE,
    events.AFTER_DELETE: odl_const.ODL_DELETE,
}
LOG_TEMPLATE = ("(%(msg)s) with ODL_OPS (%(op)s) ODL_RES_TYPE (%(res_type)s) "
                "ODL_RES_ID (%(res_id)s)) ODL_RES_DICT (%(res_dict)s) "
                "DATA (%(data)s)")
def _log_on_callback(lvl, msg, op, res_type, res_id, res_dict, data):
    def __init__(self, precommit, postcommit):
    def _subscribe(self):
    def _sg_callback(self, callback, resource, event, trigger, **kwargs):
    def sg_callback_precommit(self, resource, event, trigger, **kwargs):
    def sg_callback_postcommit(self, resource, event, trigger, **kwargs):
class OdlSecurityGroupsHandler(object): def list_opts(): ODL_NETWORK = 'network'
ODL_NETWORKS = 'networks'
ODL_SUBNET = 'subnet'
ODL_SUBNETS = 'subnets'
ODL_PORT = 'port'
ODL_PORTS = 'ports'
ODL_SG = 'security_group'
ODL_SGS = 'security_groups'
ODL_SG_RULE = 'security_group_rule'
ODL_SG_RULES = 'security_group_rules'
ODL_ROUTER = 'router'
ODL_ROUTERS = 'routers'
ODL_FLOATINGIP = 'floatingip'
ODL_FLOATINGIPS = 'floatingips'
ODL_QOS = 'qos'
ODL_QOS_POLICY = 'policy'
ODL_QOS_POLICIES = 'policies'
ODL_SFC = 'sfc'
ODL_SFC_FLOW_CLASSIFIER = 'flowclassifier'
ODL_SFC_FLOW_CLASSIFIERS = 'flowclassifiers'
ODL_SFC_PORT_PAIR = 'portpair'
ODL_SFC_PORT_PAIRS = 'portpairs'
ODL_SFC_PORT_PAIR_GROUP = 'portpairgroup'
ODL_SFC_PORT_PAIR_GROUPS = 'portpairgroups'
ODL_SFC_PORT_CHAIN = 'portchain'
ODL_SFC_PORT_CHAINS = 'portchains'
NETWORKING_SFC_FLOW_CLASSIFIER = 'flow_classifier'
NETWORKING_SFC_FLOW_CLASSIFIERS = 'flow_classifiers'
NETWORKING_SFC_PORT_PAIR = 'port_pair'
NETWORKING_SFC_PORT_PAIRS = 'port_pairs'
NETWORKING_SFC_PORT_PAIR_GROUP = 'port_pair_group'
NETWORKING_SFC_PORT_PAIR_GROUPS = 'port_pair_groups'
NETWORKING_SFC_PORT_CHAIN = 'port_chain'
NETWORKING_SFC_PORT_CHAINS = 'port_chains'
ODL_TRUNK = 'trunk'
ODL_TRUNKS = 'trunks'
ODL_L2GATEWAY = 'l2_gateway'
ODL_L2GATEWAYS = 'l2_gateways'
ODL_L2GATEWAY_CONNECTION = 'l2gateway_connection'
ODL_L2GATEWAY_CONNECTIONS = 'l2_gateway_connections'
ODL_BGPVPN = 'bgpvpn'
ODL_BGPVPNS = 'bgpvpns'
ODL_BGPVPN_NETWORK_ASSOCIATION = 'bgpvpn_network_association'
ODL_BGPVPN_NETWORK_ASSOCIATIONS = 'bgpvpn_network_associations'
ODL_BGPVPN_ROUTER_ASSOCIATION = 'bgpvpn_router_association'
ODL_BGPVPN_ROUTER_ASSOCIATIONS = 'bgpvpn_router_associations'
ODL_ML2_MECH_DRIVER_V2 = "opendaylight_v2"
ODL_DEVICE_ID_START = 'OpenDaylight'
ODL_CREATE = 'create'
ODL_UPDATE = 'update'
ODL_DELETE = 'delete'
PENDING = 'pending'
PROCESSING = 'processing'
FAILED = 'failed'
COMPLETED = 'completed'
BEFORE_COMPLETE = 'before_complete'
AFTER_DELETE = 'after_delete'
RESOURCE_URL_MAPPINGS = {
    ODL_QOS_POLICY: "%s/%s" % (ODL_QOS, ODL_QOS_POLICIES),
    ODL_SFC_FLOW_CLASSIFIER: "%s/%s" % (ODL_SFC, ODL_SFC_FLOW_CLASSIFIERS),
    ODL_SFC_PORT_CHAIN: "%s/%s" % (ODL_SFC, ODL_SFC_PORT_CHAINS),
    ODL_SFC_PORT_PAIR: "%s/%s" % (ODL_SFC, ODL_SFC_PORT_PAIRS),
    ODL_SFC_PORT_PAIR_GROUP: "%s/%s" % (ODL_SFC, ODL_SFC_PORT_PAIR_GROUPS)
} LOG = log.getLogger(__name__)
OPERATIONAL_PORT_STATUS = 'operational-port-status'
EMPTY_FEATURES = {}
def init():
def has(feature):
def get_config(feature):
def deinit():
def _load_features(json):
def _fetch_features(): def postcommit(cls):
    _build_methods(cls, *args)
    return cls LOG = logging.getLogger(__name__)
class OdlDhcpDriver(driver_base.OdlDhcpDriverBase):
    def handle_subnet_event(self, resource, event, trigger, payload):
    def handle_subnet_delete_event(self, resource, event, trigger,
                                   payload):
    def _delete_port_if_dhcp(self, plugin, context, port):
    def handle_port_update_event(self, resource, event, trigger,
                                 payload):
    def _get_subnet_context(self, context, network_id, subnet_id):
    def _delete_if_dhcp_port(self, context, row): LOG = logging.getLogger(__name__)
ALL_RESOURCES = {}
    RESOURCES = {}
def get_driver(resource_type):
    def __init__(self, *args, **kwargs):
    def _get_resource_getter(self, method_suffix):
    def get_resources_for_full_sync(self, context, resource_type):
    def plugin(self):
    def get_resource_for_recovery(self, context, obj):
class ResourceBaseDriver(object): @db_api.retry_if_session_inactive()
@db_api.CONTEXT_WRITER.savepoint
def full_sync(context):
    if not _full_sync_needed(context):
        return

    db.delete_pending_rows(context, _OPS_TO_DELETE_ON_SYNC)

    for resource_type in _ORDERED_ODL_RESOURCES:
        handler = FULL_SYNC_RESOURCES.get(resource_type)
        if handler:
            _sync_resources(context, resource_type, handler)

    journal.record(context, odl_const.ODL_NETWORK, _CANARY_NETWORK_ID,
                   odl_const.ODL_CREATE, _CANARY_NETWORK_DATA) LOG = logging.getLogger(__name__)
MAKE_URL = {}
LOG_ENTRY_TEMPLATE = ("%(log_type)s (Entry ID: %(entry_id)s) - %(op)s "
                      "%(obj_type)s %(obj_id)s (Time stamp: %(timestamp)s)")
LOG_RECORDED = 'Recorded'
LOG_PROCESSING = 'Processing'
LOG_COMPLETED = 'Completed'
LOG_ERROR_PROCESSING = 'Error while processing'
    _RETRY_SLEEP_MIN = 0.1
    _RETRY_SLEEP_MAX = 60
def call_thread_on_end(func):
    def new_func(obj, *args, **kwargs):
def _enrich_port(plugin_context, ml2_context, object_type, operation, data):
def _log_entry(log_type, entry, log_level=logging.INFO, **kwargs):
def record(plugin_context, object_type, object_uuid, operation, data,
           ml2_context=None):
def entry_complete(context, entry):
def entry_reset(context, entry):
def entry_update_state_by_retry_count(context, entry, retry_count):
def _make_url(row):
def register_url_builder(object_type, method):
def _build_url(row):
    def __init__(self, start_thread=True):
    def _create_odl_sync_thread(self):
    def start(self):
    def stop(self, timeout=None):
    def set_sync_event(self):
    def _json_data(row):
    def run_sync_thread(self):
    def sync_pending_entries(self):
    def _retry_sleep(self):
    def _retry_reset(self):
    def _sync_entry(self, context, entry):
class OpenDaylightJournalThread(object): LOG = logging.getLogger(__name__)
class JournalPeriodicProcessor(worker.BaseWorker):
    def __init__(self):
    def _create_pidfile(self):
    def _delete_pidfile(self):
    def start(self):
    def stop(self):
    def wait(self):
    def reset(self):
    def _call_journal(self):
    def _start_maintenance_task(self): LOG = log.getLogger(__name__)
class PortBindingController(object, metaclass=abc.ABCMeta):
class PortBindingManager(PortBindingController):
    def get_workers(self):
    def bind_port(self, port_context):
    def __init__(self, name, controller):
    def create(
            cls, namespace='networking_odl.ml2.port_binding_controllers',
            name=None):
    def get_workers(self):
    def bind_port(self, port_context): LOG = log.getLogger(__name__)
    PORT_PATH = "restconf/operational/neutron:neutron/ports/port"
class OdlPortStatusUpdate(worker.BaseWorker):
    def __init__(self):
    def start(self):
    def stop(self):
    def wait(self):
    def reset():
    def run_websocket(self):
    def _process_websocket_recv(self, payload, reconnect):
    def _process_websocket_reconnect(self, status):
    def _pull_missed_statuses(self): LOG = logging.getLogger(__name__)
VIF_TYPES = [portbindings.VIF_TYPE_OVS, portbindings.VIF_TYPE_VHOST_USER]
VNIC_TYPES = [portbindings.VNIC_NORMAL]
QOS_RESOURCES = {
    odl_const.ODL_QOS_POLICY: odl_const.ODL_QOS_POLICIES
}
DEFAULT_QOS_RULES = {
    qos_consts.RULE_TYPE_BANDWIDTH_LIMIT: {
        qos_consts.MAX_KBPS: {
            'type:range': [0, db_const.DB_INTEGER_MAX_VALUE]},
        qos_consts.MAX_BURST: {
            'type:range': [0, db_const.DB_INTEGER_MAX_VALUE]},
        qos_consts.DIRECTION: {
            'type:values': [constants.EGRESS_DIRECTION]}
    }
}
QOS_RULES = 'qos-rules'
class OpenDaylightQosDriver(base.DriverBase):
    def create():
    def __init__(self, supported_rules,
                 name='OpenDaylightQosDriver',
                 vif_types=VIF_TYPES,
                 vnic_types=VNIC_TYPES,
                 requires_rpc_notifications=False):
    def _record_in_journal(self, context, op_const, qos_policy):
    def create_policy_precommit(self, context, qos_policy):
    def update_policy_precommit(self, context, qos_policy):
    def delete_policy_precommit(self, context, qos_policy):
    def create_policy(self, context, policy):
    def update_policy(self, context, policy):
    def delete_policy(self, context, policy): LOG = logging.getLogger(__name__)
TRUNK_RESOURCES = {
    odl_const.ODL_TRUNK: odl_const.ODL_TRUNKS
}
class OpenDaylightTrunkHandlerV2(object):
class OpenDaylightTrunkDriverV2(trunk_base.DriverBase):
    def __init__(self):
    def _record_in_journal(context, trunk_id, operation, data):
    def trunk_create_precommit(self, resource, event,
                               trunk_plugin, payload=None):
    def trunk_update_precommit(self, resource, event,
                               trunk_plugin, payload=None):
    def trunk_delete_precommit(self, resource, event,
                               trunk_plugin, payload=None):
    def trunk_create_postcommit(self, resource, event,
                                trunk_plugin, payload=None):
    def trunk_update_postcommit(self, resource, event,
                                trunk_plugin, payload=None):
    def trunk_delete_postcommit(self, resource, event,
                                trunk_plugin, payload=None):
    def trunk_subports_set_status(self, resource, event, trunk_plugin,
                                  payload=None):
    def trunk_subports_update_status(self, resource, event, trigger, payload):
    def _set_subport_status(self, plugin, admin_context, port_id, status):
    def _get_subports_ids(self, port_id):
    def is_loaded(self):
    def register(self, resource, event, trigger, payload=None):
    def create(cls):
from neutron_lib.api.definitions import multiprovidernet as mpnet_apidef
from neutron_lib.api.definitions import provider_net as providernet
from neutron_lib import constants as p_const
from neutron_lib.plugins import constants as nlib_const
from neutron_lib.plugins.ml2 import api
from oslo_config import cfg
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
from networking_odl.common import callback
from networking_odl.common import config as odl_conf
from networking_odl.common import constants as odl_const
from networking_odl.common import odl_features
from networking_odl.common import postcommit
from networking_odl.dhcp import odl_dhcp_driver as dhcp_driver
from networking_odl.journal import base_driver
from networking_odl.journal import full_sync
from networking_odl.journal import journal
from networking_odl.journal import worker
from networking_odl.ml2 import port_binding
from networking_odl.ml2 import port_status_update
from networking_odl.qos import qos_driver_v2 as qos_driver
from networking_odl.trunk import trunk_driver_v2 as trunk_driver
# Copyright (c) 2013-2014 OpenStack Foundation
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.



LOG = logging.getLogger(__name__)


@postcommit.add_postcommit('network', 'subnet', 'port')
class OpenDaylightMechanismDriver(api.MechanismDriver,
                                  base_driver.ResourceBaseDriver):
    """OpenDaylight Python Driver for Neutron.

    This code is the backend implementation for the OpenDaylight ML2
    MechanismDriver for OpenStack Neutron.
    """
    RESOURCES = {
        odl_const.ODL_SG: odl_const.ODL_SGS,
        odl_const.ODL_SG_RULE: odl_const.ODL_SG_RULES,
        odl_const.ODL_NETWORK: odl_const.ODL_NETWORKS,
        odl_const.ODL_SUBNET: odl_const.ODL_SUBNETS,
        odl_const.ODL_PORT: odl_const.ODL_PORTS
    }
    plugin_type = nlib_const.CORE

    def initialize(self):
        LOG.debug("Initializing OpenDaylight ML2 driver")
        cfg.CONF.register_opts(odl_conf.odl_opts, "ml2_odl")
        self.sg_handler = callback.OdlSecurityGroupsHandler(
            self.sync_from_callback_precommit,
            self.sync_from_callback_postcommit)
        self.journal = journal.OpenDaylightJournalThread()
        self.port_binding_controller = port_binding.PortBindingManager.create()
        self.trunk_driver = trunk_driver.OpenDaylightTrunkDriverV2.create()
        if cfg.CONF.ml2_odl.enable_dhcp_service:
            self.dhcp_driver = dhcp_driver.OdlDhcpDriver()

        full_sync.register(nlib_const.CORE, self.RESOURCES)
        odl_features.init()

        if odl_const.ODL_QOS in cfg.CONF.ml2.extension_drivers:
            qos_driver.OpenDaylightQosDriver.create()

    def get_workers(self):

        workers = [port_status_update.OdlPortStatusUpdate(),