<name>${project.artifactId}</name>
<modules>
- <module>api</module>
+ <module>api</module>
+ <module>provider-bgp</module>
<module>tunnel-api</module>
<module>tunnel-pcep</module>
<module>segment-routing</module>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>topology-provider-bgp</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<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">
+
+ <parent>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>topology-parent</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>topology-provider-bgp</artifactId>
+ <description>BGP Topology Provider</description>
+ <packaging>bundle</packaging>
+ <name>${project.artifactId}</name>
+ <prerequisites>
+ <maven>3.0.4</maven>
+ </prerequisites>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-rib-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-linkstate</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>topology-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>mockito-configuration</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${maven.bundle.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ <Export-Package>
+ org.opendaylight.bgpcep.topology.provider.bgp
+ </Export-Package>
+ <Private-Package>
+ org.opendaylight.bgpcep.topology.provider.bgp.impl
+ </Private-Package>
+ <Bundle-Activator>org.opendaylight.bgpcep.topology.provider.bgp.impl.Activator</Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <distributionManagement>
+ <site>
+ <id>${project.artifactId}</id>
+ <name>TOPOLOGY-PROVIDER-BGP Module site</name>
+ <url>${basedir}/target/site/${project.artifactId}</url>
+ </site>
+ </distributionManagement>
+
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2013 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.topology.provider.bgp;
+
+import java.util.EventListener;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+
+public interface LocRIBListener extends EventListener {
+ /**
+ * @param trans Modification transaction. The implementation must explicitly commit
+ * it if it wishes to have its modifications propagated. The transaction
+ * is not shared with any other entity and will be cleaned up by the
+ * caller if it is not committed before this method returns.
+ * @param event Data change event
+ * @throws Exception throw it if you must. If you can handle it, please do so.
+ */
+ public void onLocRIBChange(DataModification<?, ?> trans, DataChangeEvent<?, ?> event) throws Exception;
+}
--- /dev/null
+package org.opendaylight.bgpcep.topology.provider.bgp;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public final class LocRIBListeners {
+ public interface Subscribtion {
+ public Class<? extends AddressFamily> getAfi();
+ public Class<? extends SubsequentAddressFamily> getSafi();
+ public LocRIBListener getLocRIBListener();
+ }
+
+ private LocRIBListeners() {
+
+ }
+
+ public static ServiceRegistration<Subscribtion> subscribe(final BundleContext context,
+ final Class<? extends AddressFamily> afi, final Class<? extends SubsequentAddressFamily> safi, final LocRIBListener listener) {
+ return context.registerService(Subscribtion.class,
+ new Subscribtion() {
+ @Override
+ public Class<? extends AddressFamily> getAfi() {
+ return afi;
+ }
+
+ @Override
+ public Class<? extends SubsequentAddressFamily> getSafi() {
+ return safi;
+ }
+
+ @Override
+ public LocRIBListener getLocRIBListener() {
+ return listener;
+ }
+ }, null);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.topology.provider.bgp.impl;
+
+import org.opendaylight.bgpcep.topology.provider.bgp.LocRIBListeners;
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import com.google.common.base.Preconditions;
+
+public class Activator extends AbstractBindingAwareProvider {
+// private ServiceRegistration<LocRIBListeners.Subscribtion> ipv4, ipv6, linkstate;
+ private BundleContext context;
+
+ @Override
+ public void onSessionInitiated(final ProviderContext session) {
+ final LocRIBListenerSubscriptionTracker reg = new LocRIBListenerSubscriptionTracker(context, session.getSALService(DataProviderService.class));
+ reg.open();
+
+// ipv4 = LocRIBListeners.subscribe(context, Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, new Ipv4ReachabilityTopologyBuilder());
+// ipv6 = LocRIBListeners.subscribe(context, Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class, new Ipv6ReachabilityTopologyBuilder());
+// linkstate = LocRIBListeners.subscribe(context, LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class, new LinkstateTopologyBuilder());
+ }
+
+ @Override
+ protected void startImpl(final BundleContext context) {
+ this.context = Preconditions.checkNotNull(context);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.topology.provider.bgp.impl;
+
+import org.opendaylight.bgpcep.topology.provider.bgp.LocRIBListener;
+import org.opendaylight.bgpcep.topology.provider.bgp.LocRIBListeners;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.protocol.concepts.ListenerRegistration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.LocRib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+final class LocRIBListenerSubscriptionTracker extends ServiceTracker<LocRIBListeners.Subscribtion, ListenerRegistration<LocRIBListener>> {
+ private static final InstanceIdentifier<LocRib> locRIBPath = InstanceIdentifier.builder().node(LocRib.class).toInstance();
+ private static final Logger logger = LoggerFactory.getLogger(LocRIBListenerSubscriptionTracker.class);
+ private final DataProviderService dps;
+
+ LocRIBListenerSubscriptionTracker(final BundleContext context, final DataProviderService dps) {
+ super(context, LocRIBListeners.Subscribtion.class, null);
+ this.dps = Preconditions.checkNotNull(dps);
+ }
+
+ @Override
+ public ListenerRegistration<LocRIBListener> addingService(final ServiceReference<LocRIBListeners.Subscribtion> reference) {
+ final LocRIBListeners.Subscribtion service = context.getService(reference);
+ if (service == null) {
+ logger.trace("Service for reference {} disappeared", reference);
+ return null;
+ }
+
+ final InstanceIdentifier<Tables> path = InstanceIdentifier.builder(locRIBPath).
+ node(Tables.class, new TablesKey(service.getAfi(), service.getSafi())).toInstance();
+ final LocRIBListener listener = service.getLocRIBListener();
+
+ final DataChangeListener dcl = new DataChangeListener() {
+
+ @Override
+ public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ final DataModification trans = dps.beginTransaction();
+
+ try {
+ listener.onLocRIBChange(trans, change);
+ } catch (Exception e) {
+ logger.info("Data change {} was not completely propagated to listener {}", change, listener, e);
+ }
+
+ // FIXME: abort the transaction if it's not committing
+ }
+ };
+
+ dps.registerChangeListener(path, dcl);
+
+ return new ListenerRegistration<LocRIBListener>(listener) {
+ @Override
+ protected void removeRegistration() {
+ dps.unregisterChangeListener(path, dcl);
+ }
+ };
+ }
+
+ @Override
+ public void removedService(final ServiceReference<LocRIBListeners.Subscribtion> reference, final ListenerRegistration<LocRIBListener> service) {
+ service.close();
+ context.ungetService(reference);
+ }
+}