BUG-6857 - Initial configuration file loader for BGP 66/47166/2
authorClaudio D. Gasparini <cgaspari@cisco.com>
Thu, 6 Oct 2016 12:45:08 +0000 (14:45 +0200)
committerClaudio D. Gasparini <cgaspari@cisco.com>
Wed, 19 Oct 2016 18:51:38 +0000 (18:51 +0000)
- Create BGP Config Loader service,
 Takes care of load files under etc/bgp/ and notifies
 ConfigFileProcessors when files matches patter.
 Pattern is created based on schema name
 eg. Procotols Schema requires files protocols-*.xml
- Create ProtocolsConfigFileProcessors
 Serialize Protocols normalized node to BI and notifies
 Deployer, loading new configuration.
- protocols-config.xml
 Contains BGP initial configuration ( Rib + Peer)

Change-Id: Ic350584c84f90653fe970748a6a05e7b30286835
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
16 files changed:
artifacts/pom.xml
bgp/config-loader-impl/pom.xml [new file with mode: 0644]
bgp/config-loader-impl/src/main/java/org/opendaylight/protocol/bgp/config/loader/impl/ConfigLoaderImpl.java [new file with mode: 0644]
bgp/config-loader-impl/src/main/resources/org/opendaylight/blueprint/bgp-config-loader.xml [new file with mode: 0644]
bgp/config-loader-spi/pom.xml [new file with mode: 0644]
bgp/config-loader-spi/src/main/java/org/opendaylight/protocol/bgp/config/loader/spi/ConfigFileProcessor.java [new file with mode: 0644]
bgp/config-loader-spi/src/main/java/org/opendaylight/protocol/bgp/config/loader/spi/ConfigLoader.java [new file with mode: 0644]
bgp/controller-config/pom.xml
bgp/controller-config/src/main/resources/initial/protocols-config.xml [new file with mode: 0644]
bgp/openconfig-impl/src/main/java/org/opendaylight/protocol/bgp/openconfig/impl/BGPOpenConfigMappingServiceImpl.java
bgp/pom.xml
bgp/rib-impl/pom.xml
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ProtocolsConfigFileProcessor.java [new file with mode: 0644]
bgp/rib-impl/src/main/resources/org/opendaylight/blueprint/bgp-rib.xml
features/bgp/pom.xml
features/bgp/src/main/features/features.xml

index cde0e280da0088f12578558a0098081d30cf3877..fe36d75d40b851feb629a92bbfe7cc34ff61ea97 100644 (file)
                 <artifactId>bgp-peer-acceptor</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>bgp-config-loader-spi</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>bgp-config-loader-impl</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>bgp-rib-mock</artifactId>
diff --git a/bgp/config-loader-impl/pom.xml b/bgp/config-loader-impl/pom.xml
new file mode 100644 (file)
index 0000000..5de9b6e
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main</url>
+        <tag>HEAD</tag>
+    </scm>
+    <parent>
+        <artifactId>bgp-parent</artifactId>
+        <groupId>org.opendaylight.bgpcep</groupId>
+        <version>0.7.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>bgp-config-loader-impl</artifactId>
+    <description>BGP Initial configuration Loader</description>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+    <prerequisites>
+        <maven>3.0.4</maven>
+    </prerequisites>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>bgp-config-loader-spi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-codec-xml</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+</project>
\ No newline at end of file
diff --git a/bgp/config-loader-impl/src/main/java/org/opendaylight/protocol/bgp/config/loader/impl/ConfigLoaderImpl.java b/bgp/config-loader-impl/src/main/java/org/opendaylight/protocol/bgp/config/loader/impl/ConfigLoaderImpl.java
new file mode 100644 (file)
index 0000000..677ec5f
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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.config.loader.impl;
+
+import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
+import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
+
+import com.google.common.base.Preconditions;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.GuardedBy;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+import org.opendaylight.protocol.bgp.config.loader.spi.ConfigFileProcessor;
+import org.opendaylight.protocol.bgp.config.loader.spi.ConfigLoader;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.concepts.AbstractRegistration;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class ConfigLoaderImpl implements ConfigLoader, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(ConfigLoaderImpl.class);
+    private static final String DEFAULT_APP_CONFIG_FILE_PATH = "etc" + File.separator + "opendaylight" + File.separator + "bgp";
+    private static final String INTERRUPTED = "InterruptedException";
+    private static final String EXTENSION = "-.*\\.xml";
+    private static final String INITIAL = "^";
+    private static final Path PATH = Paths.get(DEFAULT_APP_CONFIG_FILE_PATH);
+    @GuardedBy("this")
+    private final Map<String, ConfigFileProcessor> configServices = new HashMap<>();
+    private final SchemaContext schemaContext;
+    private final Thread watcherThread;
+    private final BindingNormalizedNodeSerializer bindingSerializer;
+
+    public ConfigLoaderImpl(final SchemaContext schemaContext, final BindingNormalizedNodeSerializer bindingSerializer) {
+        this.schemaContext = Preconditions.checkNotNull(schemaContext);
+        this.bindingSerializer = Preconditions.checkNotNull(bindingSerializer);
+        this.watcherThread = new Thread(new Watcher());
+        this.watcherThread.start();
+        LOG.info("Config Loader service initiated");
+    }
+
+    private class Watcher implements Runnable {
+        @Override
+        public void run() {
+            WatchKey key;
+            try {
+                while (!Thread.currentThread().isInterrupted()) {
+                    final WatchService watcher = FileSystems.getDefault().newWatchService();
+                    Runtime.getRuntime().addShutdownHook(new Thread() {
+                        @Override
+                        public void run() {
+                            try {
+                                watcher.close();
+                            } catch (final IOException e) {
+                                LOG.warn(INTERRUPTED, e);
+                            }
+                        }
+                    });
+
+                    PATH.register(watcher, OVERFLOW, ENTRY_CREATE);
+                    key = watcher.take();
+                    key.pollEvents().forEach(event -> handleEvent(event.context().toString()));
+
+                    final boolean reset = key.reset();
+                    if (!reset) {
+                        LOG.warn("Could not reset the watch key.");
+                        break;
+                    }
+                }
+            } catch (final Exception e) {
+                LOG.warn(INTERRUPTED, e);
+            }
+        }
+    }
+
+    private void handleConfigFile(final ConfigFileProcessor config, final String filename) {
+        final NormalizedNode<?, ?> dto;
+        try {
+            dto = parseDefaultConfigFile(config, filename);
+        } catch (final Exception e) {
+            LOG.warn("Failed to parse config file {}", filename, e);
+            return;
+        }
+        LOG.info("Loading initial config {}", filename);
+        config.loadConfiguration(dto);
+    }
+
+    private NormalizedNode<?, ?> parseDefaultConfigFile(final ConfigFileProcessor config, final String filename) throws Exception {
+        final NormalizedNodeResult result = new NormalizedNodeResult();
+        final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+
+        final InputStream resourceAsStream = new FileInputStream(new File(DEFAULT_APP_CONFIG_FILE_PATH, filename));
+        final XMLInputFactory factory = XMLInputFactory.newInstance();
+        final XMLStreamReader reader = factory.createXMLStreamReader(resourceAsStream);
+
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, this.schemaContext,
+            SchemaContextUtil.findDataSchemaNode(this.schemaContext, config.getSchemaPath()));
+        xmlParser.parse(reader);
+
+        return result.getResult();
+    }
+
+    public synchronized AbstractRegistration registerConfigFile(@Nonnull final ConfigFileProcessor config) {
+        final String pattern = INITIAL + config.getSchemaPath().getLastComponent().getLocalName() + EXTENSION;
+        configServices.put(pattern, config);
+
+        final File[] fList = new File(DEFAULT_APP_CONFIG_FILE_PATH).listFiles();
+        if (fList != null) {
+            for (final File file : fList) {
+                if (file.isFile()) {
+                    final String filename = file.getName();
+                    if (Pattern.matches(pattern, filename)) {
+                        handleConfigFile(config, filename);
+                    }
+                }
+            }
+        }
+
+        return new AbstractRegistration() {
+            @Override
+            protected void removeRegistration() {
+                synchronized (ConfigLoaderImpl.this) {
+                    ConfigLoaderImpl.this.configServices.remove(pattern);
+                }
+            }
+        };
+    }
+
+    @Override
+    public BindingNormalizedNodeSerializer getBindingNormalizedNodeSerializer() {
+        return this.bindingSerializer;
+    }
+
+    private synchronized void handleEvent(final String filename) {
+        configServices.entrySet().stream().filter(entry -> Pattern.matches(entry.getKey(), filename)).
+            forEach(entry -> handleConfigFile(entry.getValue(), filename));
+    }
+
+    @Override
+    public void close() throws Exception {
+        this.watcherThread.interrupt();
+    }
+}
diff --git a/bgp/config-loader-impl/src/main/resources/org/opendaylight/blueprint/bgp-config-loader.xml b/bgp/config-loader-impl/src/main/resources/org/opendaylight/blueprint/bgp-config-loader.xml
new file mode 100644 (file)
index 0000000..8c456a6
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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
+  -->
+
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0">
+    <odl:static-reference id="schemaService" interface="org.opendaylight.controller.sal.core.api.model.SchemaService" />
+    <odl:static-reference id="binding-codec" interface="org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer" />
+
+    <bean id="bgpConfigLoader" class="org.opendaylight.protocol.bgp.config.loader.impl.ConfigLoaderImpl"  destroy-method="close">
+        <argument>
+            <bean factory-ref="schemaService" factory-method="getGlobalContext"/>
+        </argument>
+        <argument ref="binding-codec"/>
+    </bean>
+
+    <service ref="bgpConfigLoader" interface="org.opendaylight.protocol.bgp.config.loader.spi.ConfigLoader" odl:type="default"/>
+</blueprint>
\ No newline at end of file
diff --git a/bgp/config-loader-spi/pom.xml b/bgp/config-loader-spi/pom.xml
new file mode 100644 (file)
index 0000000..e2eaf8d
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main</url>
+        <tag>HEAD</tag>
+    </scm>
+    <parent>
+        <artifactId>bgp-parent</artifactId>
+        <groupId>org.opendaylight.bgpcep</groupId>
+        <version>0.7.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>bgp-config-loader-spi</artifactId>
+    <description>BGP Initial configuration Loader SPI</description>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+    <prerequisites>
+        <maven>3.0.4</maven>
+    </prerequisites>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-binding-dom-codec</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+</project>
\ No newline at end of file
diff --git a/bgp/config-loader-spi/src/main/java/org/opendaylight/protocol/bgp/config/loader/spi/ConfigFileProcessor.java b/bgp/config-loader-spi/src/main/java/org/opendaylight/protocol/bgp/config/loader/spi/ConfigFileProcessor.java
new file mode 100644 (file)
index 0000000..a764c1a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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.config.loader.spi;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * Takes care of obtain object schema, schema Qname is used as base to create a pattern
+ * (Qname + "-" + * + ".xml") to recognize which files needs to be processed by each
+ * e.g. ProtocolsConfigFileProcessor will process any file containing the naming protocols-*.xml
+ */
+public interface ConfigFileProcessor {
+
+    /**
+     * Schema Path to search for
+     *
+     * @return SchemaPath
+     */
+    SchemaPath getSchemaPath();
+
+    /**
+     * Load the information contained on the normalized node
+     *
+     * @param dto normalizedNode
+     */
+    void loadConfiguration(@Nonnull NormalizedNode<?, ?> dto);
+}
diff --git a/bgp/config-loader-spi/src/main/java/org/opendaylight/protocol/bgp/config/loader/spi/ConfigLoader.java b/bgp/config-loader-spi/src/main/java/org/opendaylight/protocol/bgp/config/loader/spi/ConfigLoader.java
new file mode 100644 (file)
index 0000000..c88091a
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.config.loader.spi;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.concepts.AbstractRegistration;
+
+public interface ConfigLoader {
+    /**
+     * Register object model handler
+     * @param config Config File Processor
+     */
+    AbstractRegistration registerConfigFile(@Nonnull ConfigFileProcessor config);
+
+    /**
+     *
+     * @return Binding Normalized node serializer
+     */
+    BindingNormalizedNodeSerializer getBindingNormalizedNodeSerializer();
+}
index 8acfc1a1c8fb62cfc098a35b4514e5f4ec41fd71..c8d33a2b2037f006eb9384cad1a681a2a7278a0e 100644 (file)
                                     <type>xml</type>
                                     <classifier>bmp-config-example</classifier>
                                 </artifact>
+                                <artifact>
+                                    <file>${project.build.directory}/classes/initial/protocols-config.xml</file>
+                                    <type>xml</type>
+                                    <classifier>bgp-initial-config</classifier>
+                                </artifact>
                             </artifacts>
                         </configuration>
                     </execution>
diff --git a/bgp/controller-config/src/main/resources/initial/protocols-config.xml b/bgp/controller-config/src/main/resources/initial/protocols-config.xml
new file mode 100644 (file)
index 0000000..5cf47e7
--- /dev/null
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+    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
+-->
+<protocols xmlns="http://openconfig.net/yang/network-instance">
+    <protocol xmlns="http://openconfig.net/yang/network-instance">
+        <name>bgp-example</name>
+        <identifier xmlns:x="http://openconfig.net/yang/policy-types">x:BGP</identifier>
+        <bgp xmlns="urn:opendaylight:params:xml:ns:yang:bgp:openconfig-extensions">
+            <global>
+                <config>
+                    <router-id>192.0.2.2</router-id>
+                    <as>64496</as>
+                    <!-- if cluster-id is not present, it's value is the same as bgp-id -->
+                    <!-- <route-reflector-cluster-id>192.0.2.3</route-reflector-cluster-id> -->
+                </config>
+                <afi-safis>
+                    <afi-safi>
+                        <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV4-UNICAST</afi-safi-name>
+                        <!--Advertise N Paths
+                        <receive>true</receive>
+                        <send-max>2</send-max>-->
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV6-UNICAST</afi-safi-name>
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV4-LABELLED-UNICAST</afi-safi-name>
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV6-LABELLED-UNICAST</afi-safi-name>
+                    </afi-safi>
+
+                    <afi-safi>
+                        <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV4-UNICAST</afi-safi-name>
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV6-UNICAST</afi-safi-name>
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L2VPN-EVPN</afi-safi-name>
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name>LINKSTATE</afi-safi-name>
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name>IPV4-FLOW</afi-safi-name>
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name>IPV6-FLOW</afi-safi-name>
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name>IPV4-L3VPN-FLOW</afi-safi-name>
+                    </afi-safi>
+                    <afi-safi>
+                        <afi-safi-name>IPV6-L3VPN-FLOW</afi-safi-name>
+                    </afi-safi>
+                </afi-safis>
+            </global>
+            <neighbors xmlns="urn:opendaylight:params:xml:ns:yang:bgp:openconfig-extensions">
+                <neighbor xmlns="urn:opendaylight:params:xml:ns:yang:bgp:openconfig-extensions">
+                    <neighbor-address>192.0.2.1</neighbor-address>
+                    <config>
+                        <peer-type>INTERNAL</peer-type>
+                        <peer-as>64496</peer-as>
+                    </config>
+                    <transport>
+                        <config>
+                            <remote-port>179</remote-port>
+                            <passive-mode>true</passive-mode>
+                        </config>
+                    </transport>
+                    <timers>
+                        <config>
+                            <hold-time>180</hold-time>
+                            <connect-retry>10</connect-retry>
+                        </config>
+                    </timers>
+                    <route-reflector>
+                        <config>
+                            <route-reflector-client>false</route-reflector-client>
+                        </config>
+                    </route-reflector>
+                    <afi-safis>
+                        <afi-safi>
+                            <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV4-UNICAST</afi-safi-name>
+                            <!--Advertise N Paths
+                            <receive>true</receive>
+                            <send-max>0</send-max>-->
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV6-UNICAST</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV4-LABELLED-UNICAST</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:IPV6-LABELLED-UNICAST</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV4-UNICAST</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV6-UNICAST</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L2VPN-EVPN</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name>LINKSTATE</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name>IPV4-FLOW</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name>IPV6-FLOW</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name>IPV4-L3VPN-FLOW</afi-safi-name>
+                        </afi-safi>
+                        <afi-safi>
+                            <afi-safi-name>IPV6-L3VPN-FLOW</afi-safi-name>
+                        </afi-safi>
+                    </afi-safis>
+                </neighbor>
+                <neighbor xmlns="urn:opendaylight:params:xml:ns:yang:bgp:openconfig-extensions">
+                    <neighbor-address>192.0.2.6</neighbor-address>
+                    <config>
+                        <peer-group>application-peers</peer-group>
+                    </config>
+                </neighbor>
+            </neighbors>
+        </bgp>
+    </protocol>
+</protocols>
\ No newline at end of file
index b4e271817a453ed85a6a497f6c31d647755cf9b6..071a75f3657c303a7deac13d6be25b7722dc4a94 100644 (file)
@@ -81,16 +81,18 @@ public final class BGPOpenConfigMappingServiceImpl implements BGPOpenConfigMappi
         final Map<BgpTableType, PathSelectionMode> pathSelectionModes = new HashMap<>();
         for (final AfiSafi afiSafi : afiSafis) {
             final BgpNeighborAddPathsConfig afiSafi2 = afiSafi.getAugmentation(AfiSafi2.class);
-            final Optional<BgpTableType> bgpTableType = OpenConfigUtil.toBgpTableType(afiSafi.getAfiSafiName());
-            if (afiSafi2 != null && bgpTableType.isPresent()) {
-                final Short sendMax = afiSafi2.getSendMax();
-                final PathSelectionMode selectionMode;
-                if (sendMax > 1) {
-                    selectionMode = new AddPathBestNPathSelection(sendMax.longValue());
-                } else {
-                    selectionMode = new AllPathSelection();
+            if (afiSafi2 != null) {
+                final Optional<BgpTableType> bgpTableType = OpenConfigUtil.toBgpTableType(afiSafi.getAfiSafiName());
+                if (bgpTableType.isPresent()) {
+                    final Short sendMax = afiSafi2.getSendMax();
+                    final PathSelectionMode selectionMode;
+                    if (sendMax > 1) {
+                        selectionMode = new AddPathBestNPathSelection(sendMax.longValue());
+                    } else {
+                        selectionMode = new AllPathSelection();
+                    }
+                    pathSelectionModes.put(bgpTableType.get(), selectionMode);
                 }
-                pathSelectionModes.put(bgpTableType.get(), selectionMode);
             }
         }
         return pathSelectionModes;
index 7934324c012708cf419e42c5895b1ec1dd2feb8f..2ebdc21237a1e77fd9284528b5e804356152093e 100644 (file)
@@ -61,6 +61,8 @@
         <module>evpn</module>
         <module>cli</module>
         <module>peer-acceptor</module>
+        <module>config-loader-spi</module>
+        <module>config-loader-impl</module>
     </modules>
 
   <!--
index be022c1c6020de98ef8f879e154438b69e5b6191..9eb64bcd41b0401028a74e59c6b553330c6013ee 100644 (file)
     </properties>
 
     <dependencies>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>concepts</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>util</artifactId>
-        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-concepts</artifactId>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>bgp-parser-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>bgp-parser-spi</artifactId>
+            <artifactId>bgp-rib-spi</artifactId>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>bgp-rib-api</artifactId>
+            <artifactId>bgp-config-loader-spi</artifactId>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>bgp-rib-spi</artifactId>
+            <artifactId>bgp-openconfig-spi</artifactId>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>bgp-rib-spi</artifactId>
-            <type>test-jar</type>
-            <scope>test</scope>
+            <artifactId>bgp-path-selection-mode</artifactId>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>testtool-util</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>jsr305</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-codec</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-buffer</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-common</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-transport-native-epoll</artifactId>
-            <classifier>${os.detected.classifier}</classifier>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-binding-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.mdsal</groupId>
-            <artifactId>yang-binding</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>concepts</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>yang-common</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>yang-data-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>yang-model-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>yang-data-impl</artifactId>
+            <artifactId>bgp-inet</artifactId>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-parser-impl</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>config-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-common-api</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-config</artifactId>
             <artifactId>mdsal-binding-generator-impl</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>netty-config-api</artifactId>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+
+        <!--Netty -->
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netty-timer-config</artifactId>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>bgp-openconfig-spi</artifactId>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-codec</artifactId>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>bgp-openconfig-api</artifactId>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-transport-native-epoll</artifactId>
+            <classifier>${os.detected.classifier}</classifier>
         </dependency>
+        <!-- Testing dependencies -->
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>bgp-path-selection-mode</artifactId>
+            <artifactId>bgp-rib-spi</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>bgp-inet</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
+            <artifactId>testtool-util</artifactId>
+            <scope>test</scope>
         </dependency>
-        <!-- Testing dependencies -->
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-path-selection-mode</artifactId>
diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ProtocolsConfigFileProcessor.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ProtocolsConfigFileProcessor.java
new file mode 100644 (file)
index 0000000..87c43e6
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.opendaylight.protocol.bgp.config.loader.spi.ConfigFileProcessor;
+import org.opendaylight.protocol.bgp.config.loader.spi.ConfigLoader;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
+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.bgp.rev151009.bgp.top.bgp.Neighbors;
+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.network.instance.Protocols;
+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.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolKey;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.BGP;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.concepts.AbstractRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public final class ProtocolsConfigFileProcessor implements ConfigFileProcessor, AutoCloseable {
+    private final BindingNormalizedNodeSerializer bindingSerializer;
+    private final BgpDeployer bgpDeployer;
+    private final AbstractRegistration registration;
+    private final InstanceIdentifier<Protocols> protocolsIID;
+    private final YangInstanceIdentifier protocolYIId;
+    private static final SchemaPath PROTOCOLS_SCHEMA_PATH = SchemaPath.create(true, NetworkInstances.QNAME, NetworkInstance.QNAME,Protocols.QNAME);
+
+    public ProtocolsConfigFileProcessor(final ConfigLoader configLoader, final BgpDeployer bgpDeployer) {
+        Preconditions.checkNotNull(configLoader);
+        this.bgpDeployer = Preconditions.checkNotNull(bgpDeployer);
+        this.protocolsIID = this.bgpDeployer.getInstanceIdentifier().child(Protocols.class);
+        this.bindingSerializer = configLoader.getBindingNormalizedNodeSerializer();
+        this.registration = configLoader.registerConfigFile(this);
+        this.protocolYIId = this.bindingSerializer.toYangInstanceIdentifier(this.protocolsIID.child(Protocol.class));
+    }
+
+    @Override
+    public SchemaPath getSchemaPath() {
+        return PROTOCOLS_SCHEMA_PATH;
+    }
+
+    @Override
+    public void loadConfiguration(@Nonnull final NormalizedNode<?, ?> dto) {
+        final Collection<MapEntryNode> protocolsCollection = ((MapNode) dto).getValue();
+        for (final MapEntryNode protocolEntry : protocolsCollection) {
+            final Map.Entry<InstanceIdentifier<?>, DataObject> bi = this.bindingSerializer.fromNormalizedNode(this.protocolYIId, protocolEntry);
+            if (bi != null) {
+                notifyDeployer((Protocol) bi.getValue());
+            }
+        }
+    }
+
+    private void notifyDeployer(final Protocol protocol) {
+        final Protocol1 bgp = protocol.getAugmentation(Protocol1.class);
+        if (bgp != null) {
+            final InstanceIdentifier<Bgp> bgpIID = this.protocolsIID.child(Protocol.class, new ProtocolKey(BGP.class, protocol.getName()))
+                .augmentation(Protocol1.class).child(Bgp.class);
+
+            final Global global = bgp.getBgp().getGlobal();
+            if (global != null) {
+                this.bgpDeployer.onGlobalModified(bgpIID, global, () -> this.bgpDeployer.writeConfiguration(global, bgpIID.child(Global.class)));
+            }
+
+            final Neighbors neighbors = bgp.getBgp().getNeighbors();
+            if (neighbors != null) {
+                final List<Neighbor> neighborsList = neighbors.getNeighbor();
+                final InstanceIdentifier<Neighbors> neighborsIID = bgpIID.child(Neighbors.class);
+                neighborsList.forEach(neighbor -> this.bgpDeployer.onNeighborModified(bgpIID, neighbor,
+                    () -> this.bgpDeployer.writeConfiguration(neighbor, neighborsIID.child(Neighbor.class, neighbor.getKey()))));
+            }
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        this.registration.close();
+    }
+}
index e770314730719bf89263f7d4d536154ba4efc413..06144c6c198577ff17014a70ffcc6c7b80df38fa 100644 (file)
@@ -7,7 +7,7 @@
   <reference id="globalWorkerGroup" interface="io.netty.channel.EventLoopGroup" odl:type="global-worker-group"/>
   <reference id="clusterSingletonServiceProvider" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
-  <bean id="BGPDispatcher" class="org.opendaylight.protocol.bgp.rib.impl.BGPDispatcherImpl">
+  <bean id="BGPDispatcher" class="org.opendaylight.protocol.bgp.rib.impl.BGPDispatcherImpl"  destroy-method="close">
     <argument>
       <bean factory-ref="BGPExtensionContext" factory-method="getMessageRegistry"/>
     </argument>
@@ -27,7 +27,7 @@
   </service>
 
   <bean id="BGPPeerRegistry" class="org.opendaylight.protocol.bgp.rib.impl.StrictBGPPeerRegistry"
-          factory-method="instance"/>
+          factory-method="instance" destroy-method="close"/>
 
   <service ref="BGPPeerRegistry" interface="org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry"
           odl:type="default">
@@ -49,7 +49,7 @@
   <reference id="schemaService" interface="org.opendaylight.controller.sal.core.api.model.SchemaService"/>
   <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
 
-  <bean id="bgpDeployer" class="org.opendaylight.protocol.bgp.rib.impl.config.BgpDeployerImpl">
+  <bean id="bgpDeployer" class="org.opendaylight.protocol.bgp.rib.impl.config.BgpDeployerImpl"  destroy-method="close">
     <argument value="global-bgp"/>
     <argument ref="blueprintContainer"/>
     <argument ref="blueprintBundleContext"/>
 
   <bean id="appPeer" class="org.opendaylight.protocol.bgp.rib.impl.config.AppPeer" scope="prototype"/>
 
+  <reference id="bgpConfigLoader" interface="org.opendaylight.protocol.bgp.config.loader.spi.ConfigLoader"/>
+
+  <bean id="protocolsInitialConfig" class="org.opendaylight.protocol.bgp.rib.impl.ProtocolsConfigFileProcessor" destroy-method="close">
+      <argument ref="bgpConfigLoader"/>
+      <argument ref="bgpDeployer"/>
+  </bean>
 </blueprint>
\ No newline at end of file
index d7b4b1618f107b2fdec8635d987b3f75ea127a97..dd760419fa2e18983e3b2bb920d87ca7df45bbf2 100644 (file)
@@ -26,6 +26,7 @@
         <yangtools.version>1.1.0-SNAPSHOT</yangtools.version>
         <mdsal.version>1.5.0-SNAPSHOT</mdsal.version>
         <mdsal.model.version>0.10.0-SNAPSHOT</mdsal.model.version>
+        <mdsal.common.version>2.2.0-SNAPSHOT</mdsal.common.version>
         <config.version>0.6.0-SNAPSHOT</config.version>
         <odlparent.version>1.8.0-SNAPSHOT</odlparent.version>
     </properties>
@@ -96,7 +97,7 @@
         <dependency>
             <groupId>org.opendaylight.mdsal</groupId>
             <artifactId>features-mdsal</artifactId>
-            <version>2.2.0-SNAPSHOT</version>
+            <version>${mdsal.common.version}</version>
             <classifier>features</classifier>
             <type>xml</type>
             <scope>runtime</scope>
             <version>${mdsal.model.version}</version>
             <classifier>features</classifier>
             <type>xml</type>
-              <scope>runtime</scope>
+            <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
           <groupId>${project.groupId}</groupId>
           <artifactId>bgp-peer-acceptor</artifactId>
       </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>bgp-config-loader-spi</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>bgp-config-loader-impl</artifactId>
+      </dependency>
       <dependency>
           <groupId>${project.groupId}</groupId>
           <artifactId>bgp-controller-config</artifactId>
index d908a6dad3517e83ed73f79eba7c828a7a056a07..ab54eb5eedb98114794bb844a0fae0e90edc8ef8 100644 (file)
@@ -40,6 +40,7 @@
         <feature version='${project.version}'>odl-bgpcep-bgp-cli</feature>
         <configfile finalname="etc/opendaylight/karaf/31-bgp.xml">mvn:org.opendaylight.bgpcep/bgp-controller-config/{{VERSION}}/xml/config</configfile>
         <configfile finalname="etc/opendaylight/karaf/41-bgp-example.xml">mvn:org.opendaylight.bgpcep/bgp-controller-config/{{VERSION}}/xml/config-example</configfile>
+        <configfile finalname="etc/opendaylight/bgp/protocols-config.xml">mvn:org.opendaylight.bgpcep/bgp-controller-config/{{VERSION}}/xml/bgp-initial-config</configfile>
     </feature>
 
     <feature name="odl-bgpcep-bgp-openconfig" version='${project.version}'>
         <feature version='${project.version}'>odl-bgpcep-bgp-rib-api</feature>
         <feature version='${project.version}'>odl-bgpcep-bgp-inet</feature>
         <feature version='${project.version}'>odl-bgpcep-bgp-path-selection-mode</feature>
+        <feature version='${project.version}'>odl-bgpcep-bgp-config-loader</feature>
         <bundle>mvn:org.opendaylight.bgpcep/bgp-openconfig-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.bgpcep/bgp-openconfig-spi/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.bgpcep/bgp-rib-impl/{{VERSION}}</bundle>
         <feature version='${project.version}'>odl-bgpcep-bgp-rib-impl</feature>
         <bundle>mvn:org.opendaylight.bgpcep/bgp-cli/{{VERSION}}</bundle>
     </feature>
+
+    <feature name="odl-bgpcep-bgp-config-loader" version='${project.version}'>
+        <feature version='${mdsal.common.version}'>odl-mdsal-binding-runtime</feature>
+        <bundle>mvn:org.opendaylight.bgpcep/bgp-config-loader-spi/{{VERSION}}</bundle>
+      <bundle>mvn:org.opendaylight.bgpcep/bgp-config-loader-impl/{{VERSION}}</bundle>
+   </feature>
 </features>