Bug 5061: Introduce BGP deployer 63/42063/10
authorMilos Fabian <milfabia@cisco.com>
Tue, 19 Jul 2016 12:55:09 +0000 (14:55 +0200)
committerRobert Varga <nite@hq.sk>
Wed, 3 Aug 2016 09:05:40 +0000 (09:05 +0000)
The goal is to migrate RIBImpl configuration from
CSS to BP. The RIBs instances creation needs to be dynamic
and simple - application's compoments wiring should be hidden
from user facing configuration.

The BGP OpenConfig API is an entry point for user's BGP
configuration. The deployer listens to the changes
in a configuration subtree and based on it deploys (starts/restarts/stops) RIB instances.
Instances are registred as OSGi services, where each service is identified by service property.
The service can be used for internal (BGPPeer, ApplicationPeer) and external wiring (topology provider).

Change-Id: I68752ead5b7468c0aada603f52b18e574d4e2cb0
Signed-off-by: Milos Fabian <milfabia@cisco.com>
bgp/rib-impl/pom.xml
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerImpl.java [new file with mode: 0644]
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtil.java [new file with mode: 0644]
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java [new file with mode: 0644]
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/BgpDeployer.java [new file with mode: 0644]
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/InstanceType.java [new file with mode: 0644]
bgp/rib-impl/src/main/resources/org/opendaylight/blueprint/bgp-rib.xml

index e14025fa4b0cf67b80dec1f7e7aea3b8635ce68f..aa39ed652a668743c35ee5d3f6d27082bfa5007a 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-openconfig-spi</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>bgp-openconfig-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-path-selection-mode</artifactId>
             <artifactId>org.osgi.core</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
         <!-- Testing dependencies -->
         <dependency>
             <groupId>${project.groupId}</groupId>
index 5736274237f04f90976eda1e06af126d2bcea60c..dfe63a89d1cf2f58ac931c4c85ed8c43bd4c4cba 100755 (executable)
@@ -19,7 +19,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.ThreadSafe;
@@ -259,10 +258,14 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
     }
 
     @Override
-    public synchronized void close() throws InterruptedException, ExecutionException {
-        final DOMDataWriteTransaction t = this.domChain.newWriteOnlyTransaction();
-        t.delete(LogicalDatastoreType.OPERATIONAL, getYangRibId());
-        t.submit().get();
+    public synchronized void close() {
+        try {
+            final DOMDataWriteTransaction t = this.domChain.newWriteOnlyTransaction();
+            t.delete(LogicalDatastoreType.OPERATIONAL, getYangRibId());
+            t.submit().checkedGet();
+        } catch (final TransactionCommitFailedException e) {
+            LOG.warn("Failed to remove RIB instance {} from DS.", getYangRibId(), e);
+        }
         this.domChain.close();
         for (final LocRibWriter locRib : this.locRibs) {
             try {
diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerImpl.java
new file mode 100644 (file)
index 0000000..0b53f13
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.rib.impl.config;
+
+import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getRibInstanceName;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer;
+import org.opendaylight.protocol.bgp.rib.impl.spi.InstanceType;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.NetworkInstances;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceKey;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.ProtocolsBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class BgpDeployerImpl implements BgpDeployer, DataTreeChangeListener<Bgp>, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BgpDeployerImpl.class);
+
+    private final InstanceIdentifier<NetworkInstance> networkInstanceIId;
+    private final BlueprintContainer container;
+    private final BundleContext bundleContext;
+    private final BGPOpenConfigMappingService mappingService;
+    private final ListenerRegistration<BgpDeployerImpl>  registration;
+    @GuardedBy("this")
+    private final Map<InstanceIdentifier<Bgp>, RibImpl> ribs = new HashMap<>();
+    @GuardedBy("this")
+    private boolean closed;
+
+    public BgpDeployerImpl(final String networkInstanceName, final BlueprintContainer container, final BundleContext bundleContext, final DataBroker dataBroker,
+            final BGPOpenConfigMappingService mappingService) {
+        this.container = Preconditions.checkNotNull(container);
+        this.bundleContext = Preconditions.checkNotNull(bundleContext);
+        this.mappingService = Preconditions.checkNotNull(mappingService);
+        this.networkInstanceIId = InstanceIdentifier
+                .create(NetworkInstances.class)
+                .child(NetworkInstance.class, new NetworkInstanceKey(networkInstanceName));
+        Futures.addCallback(initializeNetworkInstance(dataBroker, this.networkInstanceIId), new FutureCallback<Void>() {
+            @Override
+            public void onSuccess(final Void result) {
+                LOG.debug("Network Instance {} initialized successfully.", networkInstanceName);
+            }
+            @Override
+            public void onFailure(final Throwable t) {
+                LOG.error("Failed to initialize Network Instance {}.", networkInstanceName, t);
+            }
+        });
+        this.registration = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, this.networkInstanceIId.child(Protocols.class)
+                .child(Protocol.class)
+                .augmentation(Protocol1.class)
+                .child(Bgp.class)), this);
+        LOG.info("BGP Deployer {} started.", networkInstanceName);
+    }
+
+    @Override
+    public synchronized void onDataTreeChanged(final Collection<DataTreeModification<Bgp>> changes) {
+        if (this.closed) {
+            LOG.trace("BGP Deployer was already closed, skipping changes.");
+            return;
+        }
+        for (final DataTreeModification<Bgp> dataTreeModification : changes) {
+            final InstanceIdentifier<Bgp> rootIdentifier = dataTreeModification.getRootPath().getRootIdentifier();
+            final DataObjectModification<Bgp> rootNode = dataTreeModification.getRootNode();
+            LOG.trace("BGP configuration has changed: {}", rootNode);
+            for (final DataObjectModification<? extends DataObject> dataObjectModification : rootNode.getModifiedChildren()) {
+                if (dataObjectModification.getDataType().equals(Global.class)) {
+                    onGlobalChanged((DataObjectModification<Global>) dataObjectModification, rootIdentifier);
+                }
+            }
+        }
+    }
+
+    @Override
+    public InstanceIdentifier<NetworkInstance> getInstanceIdentifier() {
+        return this.networkInstanceIId;
+    }
+
+    @Override
+    public synchronized void close() throws Exception {
+        this.registration.close();
+        this.ribs.values().forEach(rib -> rib.close());
+        this.ribs.clear();
+        this.closed = true;
+    }
+
+    private static CheckedFuture<Void, TransactionCommitFailedException> initializeNetworkInstance(final DataBroker dataBroker,
+            final InstanceIdentifier<NetworkInstance> networkInstance) {
+        final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
+        wTx.merge(LogicalDatastoreType.CONFIGURATION, networkInstance,
+                new NetworkInstanceBuilder().setName(networkInstance.firstKeyOf(NetworkInstance.class).getName()).setProtocols(new ProtocolsBuilder().build()).build());
+        return wTx.submit();
+    }
+
+    private void onGlobalChanged(final DataObjectModification<Global> dataObjectModification,
+            final InstanceIdentifier<Bgp> rootIdentifier) {
+        switch (dataObjectModification.getModificationType()) {
+        case DELETE:
+            onGlobalRemoved(rootIdentifier);
+            break;
+        case SUBTREE_MODIFIED:
+        case WRITE:
+            onGlobalModified(rootIdentifier, dataObjectModification.getDataAfter());
+            break;
+        default:
+            break;
+        }
+    }
+
+    private void onGlobalModified(final InstanceIdentifier<Bgp> rootIdentifier, final Global global) {
+        LOG.debug("Modifing RIB instance with configuration: {}", global);
+        //restart existing rib instance with a new configuration
+        final RibImpl ribImpl = this.ribs.get(rootIdentifier);
+        if (ribImpl != null) {
+            ribImpl.close();
+            initiateRibInstance(rootIdentifier, global, ribImpl);
+        } else {
+            //if not exists, create a new instance
+            onGlobalCreated(rootIdentifier, global);
+        }
+        LOG.debug("RIB instance modified {}", ribImpl);
+    }
+
+    private void onGlobalCreated(final InstanceIdentifier<Bgp> rootIdentifier, final Global global) {
+        //create, start and register rib instance
+        LOG.debug("Creating RIB instance with configuration: {}", global);
+        final RibImpl ribImpl = (RibImpl) this.container.getComponentInstance(InstanceType.RIB.getBeanName());
+        initiateRibInstance(rootIdentifier, global, ribImpl);
+        this.ribs.put(rootIdentifier, ribImpl);
+        LOG.debug("RIB instance created {}", ribImpl);
+    }
+
+    private void onGlobalRemoved(final InstanceIdentifier<Bgp> rootIdentifier) {
+        //destroy rib instance
+        LOG.debug("Removing RIB instance: {}", rootIdentifier);
+        final RibImpl ribImpl = this.ribs.remove(rootIdentifier);
+        if (ribImpl != null) {
+            ribImpl.close();
+            LOG.debug("RIB instance removed {}", ribImpl);
+        }
+    }
+
+    private void registerRibInstance(final RibImpl ribImpl, final String ribInstanceName) {
+        final Dictionary<String, String> properties = new Hashtable<>();
+        properties.put(InstanceType.RIB.getBeanName(), ribInstanceName);
+        final ServiceRegistration<?> serviceRegistration = this.bundleContext.registerService(InstanceType.RIB.getServices(), ribImpl, properties);
+        ribImpl.setServiceRegistration(serviceRegistration);
+    }
+
+    private void initiateRibInstance(final InstanceIdentifier<Bgp> rootIdentifier, final Global global,
+            final RibImpl ribImpl) {
+        final String ribInstanceName = getRibInstanceName(rootIdentifier);
+        ribImpl.start(global, ribInstanceName, this.mappingService);
+        registerRibInstance(ribImpl, ribInstanceName);
+    }
+
+}
diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtil.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtil.java
new file mode 100644 (file)
index 0000000..51151fd
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.rib.impl.config;
+
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+final class OpenConfigMappingUtil {
+
+    private OpenConfigMappingUtil() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static String getRibInstanceName(final InstanceIdentifier<?> rootIdentifier) {
+        return rootIdentifier.firstKeyOf(Protocol.class).getName();
+    }
+
+}
diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java
new file mode 100644 (file)
index 0000000..b40f0be
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.rib.impl.config;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
+import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
+import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigProvider;
+import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
+import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.ImportPolicyPeerTracker;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.BGPRenderStats;
+import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
+import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class RibImpl implements RIB, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
+
+    private final RIBExtensionConsumerContext extensions;
+    private final BGPDispatcher dispatcher;
+    private final BindingCodecTreeFactory codecTreeFactory;
+    private final DOMDataBroker domBroker;
+    private final SchemaService schemaService;
+    private RIBImpl ribImpl;
+    private ServiceRegistration<?> serviceRegistration;
+    private ListenerRegistration<SchemaContextListener> schemaContextRegistration;
+
+    @SuppressWarnings("deprecation")
+    public RibImpl(final RIBExtensionConsumerContext contextProvider, final BGPDispatcher dispatcher,
+            final BindingCodecTreeFactory codecTreeFactory, final DOMDataBroker domBroker, final SchemaService schemaService) {
+        this.extensions = contextProvider;
+        this.dispatcher = dispatcher;
+        this.codecTreeFactory = codecTreeFactory;
+        this.domBroker = domBroker;
+        this.schemaService = schemaService;
+    }
+
+    void start(final Global global, final String instanceName, final BGPOpenConfigMappingService mappingService) {
+        Preconditions.checkState(this.ribImpl == null, "Previous instance %s was not closed.", this);
+        this.ribImpl = createRib(global, instanceName, mappingService);
+        this.schemaContextRegistration = this.schemaService.registerSchemaContextListener(this.ribImpl);
+    }
+
+    @Override
+    public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
+        return this.ribImpl.getInstanceIdentifier();
+    }
+
+    @Override
+    public AsNumber getLocalAs() {
+        return this.ribImpl.getLocalAs();
+    }
+
+    @Override
+    public BgpId getBgpIdentifier() {
+        return this.ribImpl.getBgpIdentifier();
+    }
+
+    @Override
+    public Set<? extends BgpTableType> getLocalTables() {
+        return this.ribImpl.getLocalTables();
+    }
+
+    @Override
+    public BGPDispatcher getDispatcher() {
+        return this.ribImpl.getDispatcher();
+    }
+
+    @Override
+    public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
+        return this.ribImpl.createPeerChain(listener);
+    }
+
+    @Override
+    public RIBExtensionConsumerContext getRibExtensions() {
+        return this.ribImpl.getRibExtensions();
+    }
+
+    @Override
+    public RIBSupportContextRegistry getRibSupportContext() {
+        return this.ribImpl.getRibSupportContext();
+    }
+
+    @Override
+    public YangInstanceIdentifier getYangRibId() {
+        return this.ribImpl.getYangRibId();
+    }
+
+    @Override
+    public CodecsRegistry getCodecsRegistry() {
+        return this.ribImpl.getCodecsRegistry();
+    }
+
+    @Override
+    public Optional<BGPOpenConfigProvider> getOpenConfigProvider() {
+        return this.ribImpl.getOpenConfigProvider();
+    }
+
+    @Override
+    public CacheDisconnectedPeers getCacheDisconnectedPeers() {
+        return this.ribImpl.getCacheDisconnectedPeers();
+    }
+
+    @Override
+    public DOMDataTreeChangeService getService() {
+        return this.ribImpl.getService();
+    }
+
+    @Override
+    public void close() {
+        if (this.ribImpl != null) {
+            this.ribImpl.close();
+            this.ribImpl = null;
+        }
+        if (this.schemaContextRegistration != null) {
+            this.schemaContextRegistration.close();
+            this.schemaContextRegistration = null;
+        }
+        if (this.serviceRegistration != null) {
+            try {
+                this.serviceRegistration.unregister();
+            } catch(final IllegalStateException e) {
+                LOG.warn("Failed to unregister {} service instance", this, e);
+            }
+            this.serviceRegistration = null;
+        }
+    }
+
+    public void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
+        this.serviceRegistration = serviceRegistration;
+    }
+
+    @Override
+    public BGPRenderStats getRenderStats() {
+        return this.ribImpl.getRenderStats();
+    }
+
+    @Override
+    public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
+        return this.ribImpl.getImportPolicyPeerTracker();
+    }
+
+    @Override
+    public Set<TablesKey> getLocalTablesKeys() {
+        return this.ribImpl.getLocalTablesKeys();
+    }
+
+    @Override
+    public String toString() {
+        return this.ribImpl.toString();
+    }
+
+    private RIBImpl createRib(final Global global, final String bgpInstanceName, final BGPOpenConfigMappingService mappingService) {
+        final Map<TablesKey, PathSelectionMode> pathSelectionModes = mappingService.toPathSelectionMode(global.getAfiSafis().getAfiSafi()).entrySet()
+                .stream().collect(Collectors.toMap(entry -> new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), entry -> entry.getValue()));
+        return new RIBImpl(new RibId(bgpInstanceName), new AsNumber(global.getConfig().getAs().getValue()),
+                new BgpId(global.getConfig().getRouterId().getValue()), new ClusterIdentifier(global.getConfig().getRouterId().getValue()),
+                this.extensions, this.dispatcher, this.codecTreeFactory, this.domBroker,
+                mappingService.toTableTypes(global.getAfiSafis().getAfiSafi()), pathSelectionModes,
+                this.extensions.getClassLoadingStrategy());
+    }
+
+}
diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/BgpDeployer.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/BgpDeployer.java
new file mode 100644 (file)
index 0000000..7bfd76f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.rib.impl.spi;
+
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * The BgpDeployer service is managing RIB, Peer, Application Peer instances based on the OpenConfig BGP
+ * configuration status.
+ * BGP configuration is held under the specific OpenConfig's NetworkInstance subtree.
+ *
+ */
+public interface BgpDeployer {
+
+    /**
+     * Get pointer to NetworkInstance instance where this particular BGP deployer is binded.
+     * @return InstanceIdentifier
+     */
+    InstanceIdentifier<NetworkInstance> getInstanceIdentifier();
+
+}
diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/InstanceType.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/InstanceType.java
new file mode 100644 (file)
index 0000000..0006072
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.rib.impl.spi;
+
+import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.opendaylight.protocol.bgp.rib.RibReference;
+
+public enum InstanceType {
+
+    RIB("ribImpl", Lists.newArrayList(RIB.class, RibReference.class));
+
+    private final String beanName;
+    private final String[] services;
+
+    InstanceType(final String beanName, final List<Class<?>> services) {
+        this.beanName = beanName;
+        this.services = new String[services.size()];
+        services.stream().map(clazz -> clazz.getName()).collect(Collectors.toList()).toArray(this.services);
+    }
+
+    public String getBeanName() {
+        return this.beanName;
+    }
+
+    public String[] getServices() {
+        return this.services;
+    }
+
+}
index afa6e24bb74607462f5890dbef9d5a515bc5cdcf..d4103bc0f24d5badc0c8e0ac646d81974e175e4d 100644 (file)
@@ -2,7 +2,6 @@
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0">
 
-
   <reference id="BGPExtensionContext" interface="org.opendaylight.protocol.bgp.parser.spi.BGPExtensionConsumerContext"/>
   <reference id="globalBossGroup" interface="io.netty.channel.EventLoopGroup" odl:type="global-boss-group"/>
   <reference id="globalWorkerGroup" interface="io.netty.channel.EventLoopGroup" odl:type="global-worker-group"/>
       <entry key="config-instance-name" value="global-bgp-peer-registry"/>
     </service-properties>
   </service>
+
+  <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" odl:type="pingpong"/>
+  <reference id="globalBgpExtensions" interface="org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext"/>
+  <reference id="codecTreeFactory" interface="org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory"/>
+  <reference id="domDataBroker" interface="org.opendaylight.controller.md.sal.dom.api.DOMDataBroker"/>
+  <reference id="bgpOpenConfigMappingService" interface="org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService"/>
+  <reference id="schemaService" interface="org.opendaylight.controller.sal.core.api.model.SchemaService"/>
+
+  <bean id="bgpDeployer" class="org.opendaylight.protocol.bgp.rib.impl.config.BgpDeployerImpl">
+    <argument value="global-bgp"/>
+    <argument ref="blueprintContainer"/>
+    <argument ref="blueprintBundleContext"/>
+    <argument ref="dataBroker"/>
+    <argument ref="bgpOpenConfigMappingService"/>
+  </bean>
+
+  <service ref="bgpDeployer" interface="org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer"/>
+
+  <bean id="ribImpl" class="org.opendaylight.protocol.bgp.rib.impl.config.RibImpl" scope="prototype">
+    <argument ref="globalBgpExtensions"/>
+    <argument ref="BGPDispatcher"/>
+    <argument ref="codecTreeFactory"/>
+    <argument ref="domDataBroker"/>
+    <argument ref="schemaService"/>
+  </bean>
+
 </blueprint>
\ No newline at end of file