<type>xml</type>
<classifier>bgp-initial-config</classifier>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-controller-config</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>network-topology-initial-config</classifier>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bgp-benchmark-app</artifactId>
<type>xml</type>
<classifier>bgp-initial-config</classifier>
</artifact>
+ <artifact>
+ <file>${project.build.directory}/classes/initial/network-topology-config.xml</file>
+ <type>xml</type>
+ <classifier>network-topology-initial-config</classifier>
+ </artifact>
</artifacts>
</configuration>
</execution>
--- /dev/null
+<?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
+ -->
+<network-topology xmlns="urn:TBD:params:xml:ns:yang:network-topology">
+ <topology>
+ <topology-id>example-bgp-rib-ipv4-topology</topology-id>
+ <topology-types>
+ <bgp-ipv4-reachability-topology xmlns="urn:opendaylight:params:xml:ns:yang:odl-bgp-topology-types"/>
+ </topology-types>
+ <rib-id xmlns="urn:opendaylight:params:xml:ns:yang:odl-bgp-topology-config">example-bgp-rib</rib-id>
+ </topology>
+ <topology>
+ <topology-id>example-bgp-rib-ipv6-topology</topology-id>
+ <topology-types>
+ <bgp-ipv6-reachability-topology xmlns="urn:opendaylight:params:xml:ns:yang:odl-bgp-topology-types"/>
+ </topology-types>
+ <rib-id xmlns="urn:opendaylight:params:xml:ns:yang:odl-bgp-topology-config">example-bgp-rib</rib-id>
+ </topology>
+ <topology>
+ <topology-id>example-bgp-rib-linkstate-topology</topology-id>
+ <topology-types>
+ <bgp-linkstate-topology xmlns="urn:opendaylight:params:xml:ns:yang:odl-bgp-topology-types"/>
+ </topology-types>
+ <rib-id xmlns="urn:opendaylight:params:xml:ns:yang:odl-bgp-topology-config">example-bgp-rib</rib-id>
+ </topology>
+</network-topology>
\ No newline at end of file
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-config-loader-spi</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>ietf-ted</artifactId>
</dependency>
<!-- Test dependencies -->
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-manager</artifactId>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-util</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
+
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bgp-rib-impl</artifactId>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-broker-impl</artifactId>
<scope>test</scope>
+ <type>test-jar</type>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>netty-event-executor-config</artifactId>
+ <artifactId>sal-dom-broker-config</artifactId>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-broker-impl</artifactId>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-controller-config</artifactId>
<scope>test</scope>
- <type>test-jar</type>
</dependency>
+ <!-- junit/mockito default -->
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>mockito-configuration</artifactId>
+ </dependency>
+ <!-- netty -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>netty-threadgroup-config</artifactId>
+ <artifactId>netty-event-executor-config</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-dom-broker-config</artifactId>
+ <artifactId>netty-threadgroup-config</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
--- /dev/null
+/*
+ * 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.bgpcep.bgp.topology.provider;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.opendaylight.bgpcep.bgp.topology.provider.spi.BgpTopologyDeployer;
+import org.opendaylight.protocol.bgp.config.loader.spi.ConfigFileProcessor;
+import org.opendaylight.protocol.bgp.config.loader.spi.ConfigLoader;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+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 NetworkTopologyConfigFileProcessor implements ConfigFileProcessor, AutoCloseable {
+ private static final SchemaPath TOPOLOGY_SCHEMA_PATH = SchemaPath.create(true, NetworkTopology.QNAME);
+ private final BindingNormalizedNodeSerializer bindingSerializer;
+ private final BgpTopologyDeployer deployer;
+ private final AbstractRegistration registration;
+ private final YangInstanceIdentifier topologyYii;
+
+ public NetworkTopologyConfigFileProcessor(final ConfigLoader configLoader, final BgpTopologyDeployer deployer) {
+ Preconditions.checkNotNull(configLoader);
+ this.deployer = Preconditions.checkNotNull(deployer);
+ this.bindingSerializer = configLoader.getBindingNormalizedNodeSerializer();
+ this.topologyYii = this.bindingSerializer.toYangInstanceIdentifier(deployer.getInstanceIdentifier());
+ this.registration = configLoader.registerConfigFile(this);
+ }
+
+ @Override
+ public void close() throws Exception {
+ this.registration.close();
+ }
+
+ @Nonnull
+ @Override
+ public SchemaPath getSchemaPath() {
+ return TOPOLOGY_SCHEMA_PATH;
+ }
+
+ @Override
+ public void loadConfiguration(@Nonnull final NormalizedNode<?, ?> dto) {
+ final Collection<MapEntryNode> networkTopology = ((MapNode) dto).getValue();
+ for (final MapEntryNode topology : networkTopology) {
+ final Map.Entry<InstanceIdentifier<?>, DataObject> bi = this.bindingSerializer.fromNormalizedNode(this.topologyYii , topology);
+ if (bi != null) {
+ this.deployer.createInstance((Topology) bi.getValue());
+ }
+ }
+ }
+}
import com.google.common.reflect.AbstractInvocationHandler;
import com.google.common.reflect.Reflection;
import java.lang.reflect.Method;
-import java.util.function.Function;
import org.opendaylight.bgpcep.bgp.topology.provider.spi.BgpTopologyDeployer;
import org.opendaylight.bgpcep.bgp.topology.provider.spi.TopologyReferenceSingletonService;
import org.opendaylight.bgpcep.topology.TopologyReference;
import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
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.odl.bgp.topology.config.rev160726.Topology1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.config.rev160726.Topology1Builder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.osgi.framework.BundleContext;
//create instance
final WaitingServiceTracker<BgpTopologyDeployer> deployerTracker = WaitingServiceTracker.create(BgpTopologyDeployer.class, bundleContext);
final BgpTopologyDeployer topologyDeployer = deployerTracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
- topologyDeployer.createInstance(topology, new Function<Topology, Void>() {
- @Override
- public Void apply(final Topology topology) {
- writeConfiguration(dataBroker, topology);
- return null;
- }
- });
+ topologyDeployer.createInstance(topology);
//get topology service, use filter
final WaitingServiceTracker<TopologyReference> topologyTracker = WaitingServiceTracker.create(TopologyReference.class,
bundleContext, "(" + "topology-id" + "=" + topology.getTopologyId().getValue() + ")");
});
}
- private static void writeConfiguration(final DataBroker dataBroker, final Topology topology) {
- final KeyedInstanceIdentifier<Topology, TopologyKey> topologyIId = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
- topology.getKey());
- final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
- wTx.put(LogicalDatastoreType.CONFIGURATION, topologyIId, topology, true);
- wTx.submit();
- }
-
private static Topology createConfiguration(final TopologyTypes topologyTypes, final TopologyId topologyId, final RibId ribId) {
final TopologyBuilder topologyBuilder = new TopologyBuilder();
topologyBuilder.setTopologyId(topologyId);
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
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.mdsal.singleton.common.api.ClusterSingletonService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.protocol.bgp.rib.spi.util.ClusterSingletonServiceRegistrationHelper;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yangtools.concepts.AbstractRegistration;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
public final class BgpTopologyDeployerImpl implements AutoCloseable, ClusteredDataTreeChangeListener<Topology>, BgpTopologyDeployer {
private static final Logger LOG = LoggerFactory.getLogger(BgpTopologyDeployerImpl.class);
-
+ private static final InstanceIdentifier<Topology> TOPOLOGY_IID = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class);
private static final int MAX_REGISTRATION_ATTEMPTS = 10;
private static final int SLEEP_TIME = MAX_REGISTRATION_ATTEMPTS;
this.dataBroker = Preconditions.checkNotNull(dataBroker);
this.singletonProvider = Preconditions.checkNotNull(singletonProvider);
this.registration =
- this.dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(NetworkTopology.class).child(Topology.class)), this);
+ this.dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(NetworkTopology.class).child(Topology.class)), this);
LOG.info("BGP topology deployer started.");
}
};
}
- @Override
- public synchronized void close() throws Exception {
- this.registration.close();
- LOG.info("BGP topology deployer stopped.");
- this.closed = true;
- }
-
@Override
public DataBroker getDataBroker() {
return this.dataBroker;
}
- private Iterable<BgpTopologyProvider> filterTopologyBuilders(final Topology topology) {
- return Iterables.filter(this.topologyProviders, input -> input.topologyTypeFilter(topology));
- }
-
@Override
public AbstractRegistration registerService(final TopologyReferenceSingletonService topologyProviderService) {
final Dictionary<String, String> properties = new Hashtable<>();
properties.put("topology-id", topologyProviderService.getInstanceIdentifier().firstKeyOf(Topology.class).getTopologyId().getValue());
- final ServiceRegistration<?> registerService = this.context.registerService(new String[] {TopologyReference.class.getName()}, topologyProviderService, properties);
+ final ServiceRegistration<?> registerService = this.context.registerService(new String[]{TopologyReference.class.getName()}, topologyProviderService, properties);
final ClusterSingletonServiceRegistration registerClusterSingletonService = registerSingletonService(topologyProviderService);
return new AbstractRegistration() {
@Override
registerClusterSingletonService.close();
} catch (final Exception e) {
LOG.warn("Failed to close ClusterSingletonServiceRegistration {} for TopologyBuilder {}",
- registerClusterSingletonService, topologyProviderService.getInstanceIdentifier(), e);
+ registerClusterSingletonService, topologyProviderService.getInstanceIdentifier(), e);
}
registerService.unregister();
}
}
@Override
- public void createInstance(final Topology topology, final Function<Topology, Void> writeFunction) {
+ public void createInstance(final Topology topology) {
+ final Function<Topology, Void> writeFunction = topology1 -> {
+ final WriteTransaction wTx = this.dataBroker.newWriteOnlyTransaction();
+ final KeyedInstanceIdentifier<Topology, TopologyKey> topologyIIdKeyed =
+ InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, topology1.getKey());
+ wTx.put(LogicalDatastoreType.CONFIGURATION, topologyIIdKeyed, topology1, true);
+ wTx.submit();
+ return null;
+ };
+
filterTopologyBuilders(topology).forEach(provider -> provider.onTopologyBuilderCreated(topology, writeFunction));
}
filterTopologyBuilders(topology).forEach(provider -> provider.onTopologyBuilderRemoved(topology));
}
+ @Override
+ public InstanceIdentifier<Topology> getInstanceIdentifier() {
+ return TOPOLOGY_IID;
+ }
+
+ @Override
+ public synchronized void close() throws Exception {
+ this.registration.close();
+ LOG.info("BGP topology deployer stopped.");
+ this.closed = true;
+ }
+
+ private Iterable<BgpTopologyProvider> filterTopologyBuilders(final Topology topology) {
+ return Iterables.filter(this.topologyProviders, input -> input.topologyTypeFilter(topology));
+ }
+
private ClusterSingletonServiceRegistration registerSingletonService(final ClusterSingletonService clusterSingletonService) {
return ClusterSingletonServiceRegistrationHelper.registerSingletonService(this.singletonProvider, clusterSingletonService, MAX_REGISTRATION_ATTEMPTS, SLEEP_TIME);
}
package org.opendaylight.bgpcep.bgp.topology.provider.spi;
-import java.util.function.Function;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yangtools.concepts.AbstractRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public interface BgpTopologyDeployer {
AbstractRegistration registerService(TopologyReferenceSingletonService topologyProviderService);
- void createInstance(Topology topology, Function<Topology, Void> writeFunction);
+ void createInstance(Topology topology);
void removeInstance(Topology topology);
+ InstanceIdentifier<Topology> getInstanceIdentifier();
}
<argument ref="bgpTopologyDeployer"/>
</bean>
+ <reference id="bgpConfigLoader" interface="org.opendaylight.protocol.bgp.config.loader.spi.ConfigLoader"/>
+
+ <bean id="topologyInitialConfig" class="org.opendaylight.bgpcep.bgp.topology.provider.NetworkTopologyConfigFileProcessor" destroy-method="close">
+ <argument ref="bgpConfigLoader"/>
+ <argument ref="bgpTopologyDeployer"/>
+ </bean>
</blueprint>
\ No newline at end of file
import static org.junit.Assert.fail;
import java.util.List;
-import java.util.function.Function;
import javax.management.ObjectName;
import org.junit.Test;
import org.opendaylight.bgpcep.bgp.topology.provider.spi.BgpTopologyDeployer;
public AbstractRegistration registerService(final TopologyReferenceSingletonService topologyProviderService) {
return null;
}
+
@Override
- public void createInstance(final Topology topology, final Function<Topology, Void> writeFunction) {
- return;
+ public void createInstance(final Topology topology) {
+
}
@Override
public void removeInstance(final Topology topology) {
return;
}
+
+ @Override
+ public InstanceIdentifier<Topology> getInstanceIdentifier() {
+ return null;
+ }
});
}
import static org.junit.Assert.fail;
import java.util.List;
-import java.util.function.Function;
import javax.management.ObjectName;
import org.junit.Test;
import org.opendaylight.bgpcep.bgp.topology.provider.spi.BgpTopologyDeployer;
public AbstractRegistration registerService(final TopologyReferenceSingletonService topologyProviderService) {
return null;
}
+
@Override
- public void createInstance(final Topology topology, final Function<Topology, Void> writeFunction) {
- return;
+ public void createInstance(final Topology topology) {
+
}
@Override
public void removeInstance(final Topology topology) {
return;
}
+
+ @Override
+ public InstanceIdentifier<Topology> getInstanceIdentifier() {
+ return null;
+ }
});
}
public AbstractRegistration registerService(final TopologyReferenceSingletonService topologyProviderService) {
return null;
}
+
@Override
- public void createInstance(final Topology topology, final Function<Topology, Void> writeFunction) {
+ public void createInstance(final Topology topology) {
+
+ }
+
+ void createInstance(final Topology topology, final Function<Topology, Void> writeFunction) {
return;
}
public void removeInstance(final Topology topology) {
return;
}
+
+ @Override
+ public InstanceIdentifier<Topology> getInstanceIdentifier() {
+ return null;
+ }
});
}
<artifactId>bgp-controller-config</artifactId>
<type>xml</type>
<classifier>bgp-initial-config</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-controller-config</artifactId>
+ <type>xml</type>
+ <classifier>network-topology-initial-config</classifier>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<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>
+ <configfile finalname="etc/opendaylight/bgp/network-topology-config.xml">mvn:org.opendaylight.bgpcep/bgp-controller-config/{{VERSION}}/xml/network-topology-initial-config</configfile>
</feature>
<feature name="odl-bgpcep-bgp-openconfig" version='${project.version}'>
<feature version='${project.version}'>odl-bgpcep-bgp-linkstate</feature>
<bundle>mvn:org.opendaylight.bgpcep/topology-api/{{VERSION}}</bundle>
<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+ <feature version='${project.version}'>odl-bgpcep-bgp-config-loader</feature>
<bundle>mvn:org.opendaylight.bgpcep/bgp-topology-provider/{{VERSION}}</bundle>
</feature>