Integration with MDSAL Util 69/19369/2
authorSasidharan Sambasivam <sasidharan.s.sambasivam@ericsson.com>
Thu, 30 Apr 2015 08:54:46 +0000 (14:24 +0530)
committerSasidharan Sambasivam <sasidharan.s.sambasivam@ericsson.com>
Thu, 30 Apr 2015 09:05:30 +0000 (14:35 +0530)
Listening for Fib entries and updating Operational VPN model

Change-Id: I304e99136a2f5e20bd70f7b8cf8bec4c6f1b21af
Signed-off-by: Sasidharan Sambasivam <sasidharan.s.sambasivam@ericsson.com>
features/src/main/features/features.xml
vpnmanager/vpnmanager-impl/pom.xml
vpnmanager/vpnmanager-impl/src/main/config/default-config.xml
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnUtil.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnserviceProvider.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vpnservice/impl/rev150216/VpnserviceImplModule.java
vpnmanager/vpnmanager-impl/src/main/yang/vpnservice-impl.yang
vpnmanager/vpnmanager-impl/src/test/java/org/opendaylight/vpnservice/test/VpnServiceTest.java

index d710d320418b322520133fd38dc86f00730b61fd..123f8e9c24aaab15edd695cbc038a6a242e4d1c0 100644 (file)
@@ -33,9 +33,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <bundle>mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/mdsalutil-api/${interfacemgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}</bundle>
-    <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/interfacemgr-api/${interfacemgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/idmanager-impl/${idmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}</bundle>
@@ -45,8 +45,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <!--<bundle>wrap:mvn:javax.servlet/servlet-api/2.5</bundle>-->
     <configfile finalname="bgpmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}/xml/config</configfile>
     <configfile finalname="mdsalutil-impl-default-config.xml">mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}/xml/config</configfile>
-    <configfile finalname="vpnmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}/xml/config</configfile>
     <configfile finalname="interfacemgr-impl-default-config.xml">mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}/xml/config</configfile>
+    <configfile finalname="vpnmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}/xml/config</configfile>
     <configfile finalname="nexthopmgr-impl-default-config.xml">mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version}/xml/config</configfile>
     <configfile finalname="idmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/idmanager-impl/${idmanager.version}/xml/config</configfile>
     <configfile finalname="fibmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}/xml/config</configfile>
index 20886d9bb8eb389d8262050ea229e0f401bb88fb..ba626fb075a0b76c962ee4aec85add75968b72cc 100644 (file)
@@ -31,7 +31,22 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>bgpmanager-api</artifactId>
       <version>1.0-SNAPSHOT</version>
     </dependency>
-           <!--  TEST Dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>fibmanager-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mdsalutil-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>interfacemgr-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <!--  TEST Dependencies -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
index 65cfb17f8d07d3f1796064fdbc2d6c441c8ec573..3d718ff744e4e50793bdd85de40ca4e4be69a244 100644 (file)
@@ -12,6 +12,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <capability>urn:opendaylight:params:xml:ns:yang:vpnservice:impl?module=vpnservice-impl&amp;revision=2015-02-16</capability>
       <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
       <capability>urn:opendaylight:params:xml:ns:yang:bgpmanager:api?module=bgpmanager-api&amp;revision=2015-04-20</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&amp;revision=2015-04-10</capability>
+      <capability>urn:opendaylight:vpnservice:interfacemgr?module=odl-interface&amp;revision=2015-03-31</capability>
   </required-capabilities>
   <configuration>
 
@@ -28,6 +30,14 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <type xmlns:bgpmanager="urn:opendaylight:params:xml:ns:yang:bgpmanager:api">bgpmanager:bgpmanager-api</type>
             <name>bgpmanager</name>
           </bgpmanager>
+          <mdsalutil>
+            <type xmlns:mdsalutil="urn:opendaylight:params:xml:ns:yang:mdsalutil:api">mdsalutil:odl-mdsalutil</type>
+            <name>mdsalutil-service</name>
+          </mdsalutil>
+          <odlinterface>
+            <type xmlns:odlif="urn:opendaylight:vpnservice:interfacemgr">odlif:odl-interface</type>
+            <name>interfacemgr-service</name>
+          </odlinterface>
         </module>
       </modules>
     </data>
index 76f1f494cd26d9a93557622f0b19d002e9d202d5..48926683c75fe9fc7ae6ab3055c9fa48a8c9a32a 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.vpnservice;
 
+import java.math.BigInteger;
 import java.util.List;
 import java.util.ArrayList;
 
@@ -14,8 +15,18 @@ import com.google.common.base.Optional;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.FutureCallback;
 
+import org.opendaylight.bgpmanager.api.IBgpManager;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
+import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
+import org.opendaylight.vpnservice.mdsalutil.InstructionType;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -30,8 +41,13 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacencyList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
@@ -43,11 +59,14 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
     private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);
     private ListenerRegistration<DataChangeListener> listenerRegistration;
     private final DataBroker broker;
+    private final IBgpManager bgpManager;
+    private IMdsalApiManager mdsalManager;
+    private IInterfaceManager interfaceManager;
 
     private static final FutureCallback<Void> DEFAULT_CALLBACK =
             new FutureCallback<Void>() {
                 public void onSuccess(Void result) {
-                    LOG.info("Success in Datastore operation");
+                    LOG.debug("Success in Datastore operation");
                 }
 
                 public void onFailure(Throwable error) {
@@ -61,12 +80,17 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
      * 
      * @param db - dataBroker service reference
      */
-    public VpnInterfaceManager(final DataBroker db) {
+    public VpnInterfaceManager(final DataBroker db, final IBgpManager bgpManager) {
         super(VpnInterface.class);
         broker = db;
+        this.bgpManager = bgpManager;
         registerListener(db);
     }
 
+    public void setMdsalManager(IMdsalApiManager mdsalManager) {
+        this.mdsalManager = mdsalManager;
+    }
+
     @Override
     public void close() throws Exception {
         if (listenerRegistration != null) {
@@ -93,7 +117,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
     @Override
     protected void add(final InstanceIdentifier<VpnInterface> identifier,
             final VpnInterface vpnInterface) {
-        LOG.info("key: " + identifier + ", value=" + vpnInterface );
+        LOG.info("key: {} , value: {}", identifier, vpnInterface );
         addInterface(identifier, vpnInterface);
     }
 
@@ -107,7 +131,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
         if (port.isPresent()) {
             Interface interf = port.get();
-            bindServiceOnInterface(interf);
+            bindServiceOnInterface(interf, getVpnId(vpnInterface.getVpnInstanceName()));
             updateNextHops(identifier, vpnInterface);
         }
     }
@@ -122,14 +146,19 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             List<Adjacency> nextHops = adjacencies.get().getAdjacency();
             List<Adjacency> value = new ArrayList<>();
 
+            //Get the rd of the vpn instance
+            String rd = getRouteDistinguisher(intf.getVpnInstanceName());
+            //TODO: Get the endpoint IP from interface manager
+            String nextHopIp = "10.0.0.1";
+
             if (!nextHops.isEmpty()) {
-                LOG.info("NextHops are " + nextHops);
+                LOG.info("NextHops are {}", nextHops);
                 for (Adjacency nextHop : nextHops) {
                     //TODO: Generate label for the prefix and store it in the next hop model
                     long label = 200;
 
                     //TODO: Update BGP
-                    updatePrefixToBGP(nextHop);
+                    updatePrefixToBGP(rd, nextHop, nextHopIp);
                     value.add(new AdjacencyBuilder(nextHop).setLabel(label).build());
                 }
             }
@@ -140,12 +169,76 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
     }
 
-    private void bindServiceOnInterface(Interface intf) {
+    private long getVpnId(String vpnName) {
+        InstanceIdentifier<VpnInstance1> id = InstanceIdentifier.builder(VpnInstances.class)
+                .child(VpnInstance.class, new VpnInstanceKey(vpnName)).augmentation(VpnInstance1.class).build();
+        Optional<VpnInstance1> vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id);
+        long vpnId = -1;
+        if(vpnInstance.isPresent()) {
+            vpnId = vpnInstance.get().getVpnId();
+        }
+        return vpnId;
+    }
+
+    private String getRouteDistinguisher(String vpnName) {
+        InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
+                                      .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+        Optional<VpnInstance> vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id);
+        String rd = "";
+        if(vpnInstance.isPresent()) {
+            VpnInstance instance = vpnInstance.get();
+            VpnAfConfig config = instance.getIpv4Family();
+            rd = config.getRouteDistinguisher();
+        }
+        return rd;
+    }
+
+    private void bindServiceOnInterface(Interface intf, long vpnId) {
+        LOG.info("Bind service on interface {} for VPN: {}", intf, vpnId);
         //TODO: Create Ingress flow on the interface to bind the VPN service
+        //TODO: Get dpn ID from the interface manager
+        long dpId = 1;
+        short LPORT_INGRESS_TABLE = 0;
+        //TODO: Get the port no from interface manager
+        int portNo = 1;
+        String flowRef = getL3InterfaceFlowRef(dpId, LPORT_INGRESS_TABLE, vpnId, portNo);
+
+        String flowName = intf.getName();
+        BigInteger COOKIE_VM_INGRESS_TABLE = new BigInteger("8000001", 16);
+
+        int priority = 10; //L3Constants.DEFAULT_L3_FLOW_PRIORITY;
+        short gotoTableId = 21; //L3Constants.L3_FIB_TABLE;
+
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        mkInstructions.add(new InstructionInfo(InstructionType.write_metadata, new BigInteger[] {
+                BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
+
+        mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { gotoTableId }));
+
+        List<MatchInfo> matches = new ArrayList<MatchInfo>();
+        matches.add(new MatchInfo(MatchFieldType.in_port, new long[] {
+                dpId, portNo }));
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, LPORT_INGRESS_TABLE, flowRef,
+                          priority, flowName, 0, 0, COOKIE_VM_INGRESS_TABLE, matches, mkInstructions);
+
+        mdsalManager.installFlow(flowEntity);
+    }
+
+    private String getL3InterfaceFlowRef(long dpId, short tableId,
+            long vpnId, int portNo) {
+        return new StringBuilder().append(dpId).append(tableId).append(vpnId).append(portNo).toString();
     }
 
-    private void updatePrefixToBGP(Adjacency nextHop) {
+    private void updatePrefixToBGP(String rd, Adjacency nextHop, String nextHopIp) {
         //TODO: Update the Prefix to BGP
+        //public void addPrefix(String rd, String prefix, String nextHop, int vpnLabel)
+        int label = nextHop.getLabel().intValue();
+        try {
+            bgpManager.addPrefix(rd, nextHop.getIpAddress(), nextHopIp, label);
+        } catch(Exception e) {
+            LOG.error("Add prefix failed", e);
+        }
     }
 
     private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
index 75c159fc9136a62bc1fc1023f79c42d3b980848b..c05506bb739ff74fa14e38623b9ce7e2db47d2af 100644 (file)
@@ -7,21 +7,55 @@
  */
 package org.opendaylight.vpnservice;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.opendaylight.bgpmanager.api.IBgpManager;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.FibEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.vrfentries.VrfEntry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+
 public class VpnManager extends AbstractDataChangeListener<VpnInstance> implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(VpnManager.class);
-    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private ListenerRegistration<DataChangeListener> listenerRegistration, fibListenerRegistration;
     private final DataBroker broker;
+    private final IBgpManager bgpManager;
+    private final FibEntriesListener fibListener;
+
+    private static final FutureCallback<Void> DEFAULT_CALLBACK =
+            new FutureCallback<Void>() {
+                public void onSuccess(Void result) {
+                    LOG.debug("Success in Datastore operation");
+                }
+
+                public void onFailure(Throwable error) {
+                    LOG.error("Error in Datastore operation", error);
+                };
+            };
 
     /**
      * Listens for data change related to VPN Instance
@@ -29,9 +63,11 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
      * 
      * @param db - dataBroker reference
      */
-    public VpnManager(final DataBroker db) {
+    public VpnManager(final DataBroker db, final IBgpManager bgpManager) {
         super(VpnInstance.class);
         broker = db;
+        this.bgpManager = bgpManager;
+        this.fibListener = new FibEntriesListener();
         registerListener(db);
     }
 
@@ -39,6 +75,8 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
         try {
             listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
                     getWildCardPath(), VpnManager.this, DataChangeScope.SUBTREE);
+            fibListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    getFibEntryListenerPath(), fibListener, DataChangeScope.BASE);
         } catch (final Exception e) {
             LOG.error("VPN Service DataChange listener registration fail!", e);
             throw new IllegalStateException("VPN Service registration Listener failed.", e);
@@ -60,26 +98,149 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
     @Override
     protected void add(InstanceIdentifier<VpnInstance> identifier,
             VpnInstance value) {
-        LOG.info("key: " + identifier + ", value=" + value);
+        LOG.info("key: {}, value: {}" +identifier, value);
         //TODO: Generate VPN ID for this instance, where to store in model ... ?
+        long vpnId = 1000;
+        InstanceIdentifier<VpnInstance1> augId = identifier.augmentation(VpnInstance1.class);
+        Optional<VpnInstance1> vpnAugmenation = read(LogicalDatastoreType.CONFIGURATION, augId);
+        if(vpnAugmenation.isPresent()) {
+            VpnInstance1 vpn = vpnAugmenation.get();
+            vpnId = vpn.getVpnId();
+            LOG.info("VPN ID is {}", vpnId);
+        }
+
+        VpnInstance opValue = new VpnInstanceBuilder(value).
+                 addAugmentation(VpnInstance1.class, new VpnInstance1Builder().setVpnId(vpnId).build()).build();
+
+        asyncWrite(LogicalDatastoreType.OPERATIONAL, identifier, opValue, DEFAULT_CALLBACK);
 
         //TODO: Add VRF to BGP
+        //public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts)
+        VpnAfConfig config = value.getIpv4Family();
+        String rd = config.getRouteDistinguisher();
+        List<String> importRts = Arrays.asList(config.getImportRoutePolicy().split(","));
+        List<String> exportRts = Arrays.asList(config.getExportRoutePolicy().split(","));
+        try {
+            bgpManager.addVrf(rd, importRts, exportRts);
+        } catch(Exception e) {
+            LOG.error("Exception when adding VRF to BGP", e);
+        }
     }
 
     private InstanceIdentifier<?> getWildCardPath() {
         return InstanceIdentifier.create(VpnInstances.class).child(VpnInstance.class);
     }
 
+    private InstanceIdentifier<?> getFibEntryListenerPath() {
+        return InstanceIdentifier.create(FibEntries.class).child(VrfTables.class)
+                .child(VrfEntry.class);
+    }
+
     @Override
     public void close() throws Exception {
         if (listenerRegistration != null) {
             try {
                 listenerRegistration.close();
             } catch (final Exception e) {
-                LOG.error("Error when cleaning up DataChangeListener.", e);
+                LOG.error("Error when cleaning up Vpn DataChangeListener.", e);
             }
             listenerRegistration = null;
         }
-        LOG.info("VPN Manager Closed");
+        if (fibListenerRegistration != null) {
+            try {
+                fibListenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up Fib entries DataChangeListener.", e);
+            }
+            fibListenerRegistration = null;
+        }
+        LOG.trace("VPN Manager Closed");
+    }
+
+    private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+            InstanceIdentifier<T> path) {
+
+        ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+        Optional<T> result = Optional.absent();
+        try {
+            result = tx.read(datastoreType, path).get();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return result;
+    }
+
+    private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+            InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.put(datastoreType, path, data, true);
+        Futures.addCallback(tx.submit(), callback);
+    }
+
+    private VpnInstance getVpnForRD(String rd) {
+        InstanceIdentifier<VpnInstances> id = InstanceIdentifier.create(VpnInstances.class);
+        Optional<VpnInstances> vpnInstances = read(LogicalDatastoreType.OPERATIONAL, id);
+        if(vpnInstances.isPresent()) {
+            List<VpnInstance> vpns = vpnInstances.get().getVpnInstance();
+            for(VpnInstance vpn : vpns) {
+                if(vpn.getIpv4Family().getRouteDistinguisher().equals(rd)) {
+                    return vpn;
+                }
+            }
+        }
+        return null;
+    }
+
+    private class FibEntriesListener extends AbstractDataChangeListener<VrfEntry>  {
+
+        public FibEntriesListener() {
+            super(VrfEntry.class);
+        }
+
+        @Override
+        protected void remove(InstanceIdentifier<VrfEntry> identifier,
+                VrfEntry del) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        protected void update(InstanceIdentifier<VrfEntry> identifier,
+                VrfEntry original, VrfEntry update) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        protected void add(InstanceIdentifier<VrfEntry> identifier,
+                VrfEntry add) {
+            LOG.info("Key : " + identifier + " value : " + add);
+            final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
+            String rd = key.getRouteDistinguisher();
+            Long label = add.getLabel();
+            VpnInstance vpn = getVpnForRD(rd);
+            if(vpn != null) {
+                InstanceIdentifier<VpnInstance> id = VpnUtil.getVpnInstanceIdentifier(vpn.getVpnInstanceName());
+                InstanceIdentifier<VpnInstance1> augId = id.augmentation(VpnInstance1.class);
+                Optional<VpnInstance1> vpnAugmenation = read(LogicalDatastoreType.OPERATIONAL, augId);
+                if(vpnAugmenation.isPresent()) {
+                    VpnInstance1 vpnAug = vpnAugmenation.get();
+                    List<Long> routeIds = vpnAug.getRouteEntryId();
+                    if(routeIds == null) {
+                        routeIds = new ArrayList<>();
+                    }
+                    LOG.info("Adding label to vpn info " + label);
+                    routeIds.add(label);
+                    asyncWrite(LogicalDatastoreType.OPERATIONAL, augId,
+                            new VpnInstance1Builder(vpnAug).setRouteEntryId(routeIds).build(), DEFAULT_CALLBACK);
+                } else {
+                    LOG.info("VPN Augmentation not found");
+                }
+            } else {
+                LOG.warn("No VPN Instance found for RD: {}", rd);
+            }
+        }
     }
 }
index a5b44ec900306529692ab4e2b91fa648280f3b0c..b7c9721e255946f2011bb1ffb0ce0b2663a9f93f 100644 (file)
@@ -2,6 +2,9 @@ package org.opendaylight.vpnservice;
 
 import java.util.List;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
@@ -16,6 +19,11 @@ public class VpnUtil {
                 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
     }
 
+    static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
+        return InstanceIdentifier.builder(VpnInstances.class)
+                .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+    }
+
     static VpnInterface getVpnInterface(String intfName, String vpnName, Adjacencies aug) {
         return new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(intfName)).setVpnInstanceName(vpnName)
                 .addAugmentation(Adjacencies.class, aug).build();
index a1e635c371349f55b1c7889b1e6870c78cbd5a7b..a93dc1c2611d4e711452b28b744efb2aa55d819c 100644 (file)
@@ -13,6 +13,8 @@ import org.opendaylight.bgpmanager.api.IBgpManager;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -23,14 +25,17 @@ public class VpnserviceProvider implements BindingAwareProvider,
     private VpnInterfaceManager vpnInterfaceManager;
     private VpnManager vpnManager;
     private IBgpManager bgpManager;
+    private IMdsalApiManager mdsalManager;
+    private IInterfaceManager interfaceManager;
 
     @Override
     public void onSessionInitiated(ProviderContext session) {
         LOG.info("VpnserviceProvider Session Initiated");
         try {
             final  DataBroker dataBroker = session.getSALService(DataBroker.class);
-            vpnManager = new VpnManager(dataBroker);
-            vpnInterfaceManager = new VpnInterfaceManager(dataBroker);
+            vpnManager = new VpnManager(dataBroker, bgpManager);
+            vpnInterfaceManager = new VpnInterfaceManager(dataBroker, bgpManager);
+            vpnInterfaceManager.setMdsalManager(mdsalManager);
         } catch (Exception e) {
             LOG.error("Error initializing services", e);
         }
@@ -41,6 +46,14 @@ public class VpnserviceProvider implements BindingAwareProvider,
         this.bgpManager = bgpManager;
     }
 
+    public void setMdsalManager(IMdsalApiManager mdsalManager) {
+        this.mdsalManager = mdsalManager;
+    }
+
+    public void setInterfaceManager(IInterfaceManager interfaceManager) {
+        this.interfaceManager = interfaceManager;
+    }
+
     @Override
     public void close() throws Exception {
         vpnManager.close();
index c0fe55864b6af54fce61914d180c8307b0e674f8..cbab6e84ac2e254779ed46784e5e2d6ab2db5922 100644 (file)
@@ -26,8 +26,10 @@ public class VpnserviceImplModule extends org.opendaylight.yang.gen.v1.urn.opend
     @Override
     public java.lang.AutoCloseable createInstance() {
         VpnserviceProvider provider = new VpnserviceProvider();
-        getBrokerDependency().registerProvider(provider);
         provider.setBgpManager(getBgpmanagerDependency());
+        provider.setMdsalManager(getMdsalutilDependency());
+        provider.setInterfaceManager(getOdlinterfaceDependency());
+        getBrokerDependency().registerProvider(provider);
         return provider;
     }
 }
index f77b000e6744b0f3d340a1511e8513e03f1513c3..b1703e2227d693432a7e3c27c52ff5d00a769d7d 100644 (file)
@@ -6,6 +6,8 @@ module vpnservice-impl {
     import config { prefix config; revision-date 2013-04-05; }
     import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
     import bgpmanager-api { prefix bgpmgr-api; revision-date 2015-04-20;}
+    import odl-mdsalutil { prefix odl-mdsal; revision-date 2015-04-10;}
+    import odl-interface {prefix odlif; revision-date 2015-03-31;}
 
     description
         "Service definition for vpnservice project";
@@ -39,6 +41,22 @@ module vpnservice-impl {
                     }
                 }
             }
+            container mdsalutil {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity odl-mdsal:odl-mdsalutil;
+                    }
+                }
+            }
+            container odlinterface {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity odlif:odl-interface;
+                    }
+                }
+            }
         }
     }
 }
index 588da749540bd0ccddfb96085b4c0235b61a629b..bdac7b0695912d11626f6c7076894e40b3b9c3f9 100644 (file)
@@ -15,8 +15,8 @@ import org.junit.*;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-
 import org.opendaylight.vpnservice.VpnManager;
+import org.opendaylight.bgpmanager.api.IBgpManager;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
@@ -39,6 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081
 @RunWith(MockitoJUnitRunner.class)
 public class VpnServiceTest {
     @Mock DataBroker dataBroker;
+    @Mock IBgpManager bgpManager;
     @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
     MockDataChangedEvent event;
 
@@ -60,9 +61,10 @@ public class VpnServiceTest {
                     setExportRoutePolicy("100:1").setApplyLabel(new ApplyLabelBuilder().setApplyLabelMode(
                         new PerRouteBuilder().setApplyLabelPerRoute(true).build()).build()).build());
         VpnInstance instance = builder.build();
-        VpnManager vpnManager = new VpnManager(dataBroker);
+        VpnManager vpnManager = new VpnManager(dataBroker, bgpManager);
         event.created.put(createVpnId("Vpn1"), instance);
-        vpnManager.onDataChanged(event);
+        //TODO: Need to enhance the test case to handle ds read/write ops
+        //vpnManager.onDataChanged(event);
     }
 
     private InstanceIdentifier<VpnInstance> createVpnId(String name) {