Merge "RpcRegistration and RpcResult for IdManager."
authorVivek Srivastava <vivek.v.srivastava@ericsson.com>
Tue, 5 May 2015 10:47:00 +0000 (10:47 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 5 May 2015 10:47:00 +0000 (10:47 +0000)
43 files changed:
bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpManager.java
bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/implementation/BgpRouter.java
bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/implementation/BgpSyncHandle.java
bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpThriftService.java
bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpUpdateHandler.java
features/src/main/features/features.xml
interfacemgr/interfacemgr-api/pom.xml
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/interfaces/IInterfaceManager.java
interfacemgr/interfacemgr-impl/pom.xml
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmNodeConnectorListener.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java
interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/IfmUtilTest.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/InterfaceManagerTest.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/MockDataChangedEvent.java [new file with mode: 0644]
mdsalutil/mdsalutil-impl/pom.xml
mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java
mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALUtilProvider.java [new file with mode: 0644]
mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/mdsalutil/impl/rev150403/MdsaluttilimplModule.java
mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/AbstractMockForwardingRulesManager.java [new file with mode: 0644]
mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/MdSalUtilTest.java [new file with mode: 0644]
mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/MockFlowForwarder.java [new file with mode: 0644]
mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/MockGroupForwarder.java [new file with mode: 0644]
mdsalutil/pom.xml
nexthopmgr/nexthopmgr-impl/pom.xml
nexthopmgr/nexthopmgr-impl/src/main/config/default-config.xml
nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/NexthopManager.java
nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/NexthopmgrProvider.java
nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/OdlInterfaceChangeListener.java
nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/VpnInterfaceChangeListener.java
nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nexthopmgr/impl/rev150325/NexthopmgrImplModule.java
nexthopmgr/nexthopmgr-impl/src/main/yang/nexthopmgr-impl.yang
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 cbcaa2e5d9e3a2048f9d6b0cba28f7dca0fd1896..35d492471d2e48227a0cafc39bcff876c19c077a 100644 (file)
@@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory;
 
 public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpManager {
 
-    private static final Logger s_logger = LoggerFactory.getLogger(BgpManager.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(BgpManager.class);
     private BgpConfigurationManager bgpConfigurationMgr;
     private FibDSWriter fibDSWriter;
     private BgpConfiguration   bgpConfiguration = new BgpConfiguration();
@@ -88,7 +88,7 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
             try {
                 wait();
             } catch (InterruptedException e) {
-                s_logger.error("InterruptedException while waiting for Bgp connection to initialize");
+                LOGGER.error("InterruptedException while waiting for Bgp connection to initialize");
                 return;
             }
         }
@@ -96,37 +96,37 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
 
     public void startBgpService() throws TException {
         if(bgpThriftClient == null) {
-            s_logger.info("Start Bgp Service - bgpThriftClient is null. Unable to start BGP service.");
+            LOGGER.info("Start Bgp Service - bgpThriftClient is null. Unable to start BGP service.");
             return;
         }
 
         // Now try start bgp - if bgp is already Active, it will tell us, nothing to do then
         try {
             bgpThriftClient.startBgp((int)bgpConfiguration.getAsNum(), bgpConfiguration.getRouterId());
-            s_logger.info("Started BGP with AS number " + (int)bgpConfiguration.getAsNum() + " and router id " + bgpConfiguration.getRouterId());
+            LOGGER.info("Started BGP with AS number " + (int)bgpConfiguration.getAsNum() + " and router id " + bgpConfiguration.getRouterId());
         } catch (BgpRouterException be) {
             if(be.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
-                s_logger.info("bgp server already active");
+                LOGGER.info("bgp server already active");
                 return;
             }
             else if(be.getErrorCode() == BgpRouterException.BGP_ERR_NOT_INITED) {
-                s_logger.error("bgp server connection not initialized.");
+                LOGGER.error("bgp server connection not initialized.");
                 reInitConn();
                 return;
             }
             else {
-                s_logger.error("application error while starting bgp server " + be.getErrorCode());
+                LOGGER.error("application error while starting bgp server " + be.getErrorCode());
                 return;
             }
 
         }  catch (TException t) {
-            s_logger.error("Could not set up thrift connection with bgp server");
-            //s_logger.trace("Transport error while starting bgp server ", t);
+            LOGGER.error("Could not set up thrift connection with bgp server");
+            //LOGGER.trace("Transport error while starting bgp server ", t);
             reInitConn();
             throw t;
         } catch (Exception e) {
-            s_logger.error("Error while starting bgp server");
-            //s_logger.trace("Bgp Service not started due to exception", e);
+            LOGGER.error("Error while starting bgp server");
+            //LOGGER.trace("Bgp Service not started due to exception", e);
             return;
         }
 
@@ -136,13 +136,13 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
 
     @Override
     public void onSessionInitiated(ProviderContext session) {
-        s_logger.info("BgpManager Session Initiated");
+        LOGGER.info("BgpManager Session Initiated");
         try {
             final DataBroker dataBroker = session.getSALService(DataBroker.class);
             bgpConfigurationMgr = new BgpConfigurationManager(dataBroker, bgpConfiguration, this);
             fibDSWriter = new FibDSWriter(dataBroker);
         } catch (Exception e) {
-            s_logger.error("Error initializing services", e);
+            LOGGER.error("Error initializing services", e);
         }
 
         initializeBGPCommunication();
@@ -151,7 +151,7 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
 
    @Override
     public void close() throws Exception {
-        s_logger.info("BgpManager Closed");
+        LOGGER.info("BgpManager Closed");
 
        //close the client and server ends of the thrift communication
        if(bgpThriftClient != null)
@@ -174,42 +174,42 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
 
     protected void addNeighbor(String ipAddress, long asNum) throws TException {
         if(bgpThriftClient == null) {
-            s_logger.info("Add BGP Neighbor - bgpThriftClient is null. Unable to add BGP Neighbor.");
+            LOGGER.info("Add BGP Neighbor - bgpThriftClient is null. Unable to add BGP Neighbor.");
             return;
         }
 
         try {
             bgpThriftClient.addNeighbor(ipAddress, (int) asNum);
         } catch (BgpRouterException b) {
-            s_logger.error("Failed to add BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
-            s_logger.error("BgpRouterException trace ", b);
+            LOGGER.error("Failed to add BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
+            LOGGER.error("BgpRouterException trace ", b);
         } catch (TException t) {
-            s_logger.error(String.format("Failed adding neighbor %s due to Transport error", ipAddress));
+            LOGGER.error(String.format("Failed adding neighbor %s due to Transport error", ipAddress));
             reInitConn();
             throw t;
         } catch (Exception e) {
-            s_logger.error(String.format("Failed adding neighbor %s", ipAddress));
+            LOGGER.error(String.format("Failed adding neighbor %s", ipAddress));
         }
     }
 
 
     protected void deleteNeighbor(String ipAddress) throws TException {
         if(bgpThriftClient == null) {
-            s_logger.info("Delete BGP Neighbor - bgpThriftClient is null. Unable to delete BGP Neighbor.");
+            LOGGER.info("Delete BGP Neighbor - bgpThriftClient is null. Unable to delete BGP Neighbor.");
             return;
         }
 
         try {
             bgpThriftClient.delNeighbor(ipAddress);
         } catch (BgpRouterException b) {
-            s_logger.error("Failed to delete BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
-            s_logger.error("BgpRouterException trace ", b);
+            LOGGER.error("Failed to delete BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
+            LOGGER.error("BgpRouterException trace ", b);
         }catch (TException t) {
-            s_logger.error(String.format("Failed deleting neighbor %s due to Transport error", ipAddress));
+            LOGGER.error(String.format("Failed deleting neighbor %s due to Transport error", ipAddress));
             reInitConn();
             throw t;
         } catch (Exception e) {
-            s_logger.error(String.format("Failed deleting neighbor %s", ipAddress));
+            LOGGER.error(String.format("Failed deleting neighbor %s", ipAddress));
         }
     }
 
@@ -217,21 +217,21 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
     @Override
     public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts) throws Exception {
         if(bgpThriftClient == null) {
-            s_logger.info("Add BGP vrf - bgpThriftClient is null. Unable to add BGP vrf.");
+            LOGGER.info("Add BGP vrf - bgpThriftClient is null. Unable to add BGP vrf.");
             return;
         }
         try {
             bgpThriftClient.addVrf(rd, new ArrayList<>(importRts), new ArrayList<>(exportRts));
         } catch (BgpRouterException b) {
-            s_logger.error("Failed to add BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
-            s_logger.error("BgpRouterException trace ", b);
+            LOGGER.error("Failed to add BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
+            LOGGER.error("BgpRouterException trace ", b);
             throw b;
         } catch (TException t) {
-            s_logger.error(String.format("Failed adding vrf %s due to Transport error", rd));
+            LOGGER.error(String.format("Failed adding vrf %s due to Transport error", rd));
             reInitConn();
             throw t;
         } catch (Exception e) {
-            s_logger.error(String.format("Failed adding vrf %s", rd));
+            LOGGER.error(String.format("Failed adding vrf %s", rd));
             throw e;
         }
     }
@@ -239,21 +239,21 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
     @Override
     public void deleteVrf(String rd) throws Exception {
         if(bgpThriftClient == null) {
-            s_logger.info("Delete BGP vrf - bgpThriftClient is null. Unable to delete BGP vrf.");
+            LOGGER.info("Delete BGP vrf - bgpThriftClient is null. Unable to delete BGP vrf.");
             return;
         }
         try {
             bgpThriftClient.delVrf(rd);
         } catch (BgpRouterException b) {
-            s_logger.error("Failed to delete BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
-            s_logger.error("BgpRouterException trace ", b);
+            LOGGER.error("Failed to delete BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
+            LOGGER.error("BgpRouterException trace ", b);
             throw b;
         } catch (TException t) {
-            s_logger.error(String.format("Failed deleting vrf %s due to Transport error", rd));
+            LOGGER.error(String.format("Failed deleting vrf %s due to Transport error", rd));
             reInitConn();
             throw t;
         } catch (Exception e) {
-            s_logger.error(String.format("Failed deleting vrf %s", rd));
+            LOGGER.error(String.format("Failed deleting vrf %s", rd));
             throw e;
         }
     }
@@ -269,16 +269,16 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
         try {
             bgpThriftClient.addPrefix(rd, prefix, nextHop, vpnLabel);
         } catch (BgpRouterException b) {
-            s_logger.error("Failed to add BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
-            s_logger.error("BgpRouterException trace ", b);
+            LOGGER.error("Failed to add BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
+            LOGGER.error("BgpRouterException trace ", b);
             throw b;
         } catch (TException t) {
-            s_logger.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d due to Transport error",
+            LOGGER.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d due to Transport error",
                 rd, prefix, nextHop, vpnLabel));
             reInitConn();
             throw t;
         } catch (Exception e) {
-            s_logger.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d",
+            LOGGER.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d",
                 rd, prefix, nextHop, vpnLabel));
             throw e;
         }
@@ -295,16 +295,16 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
         try {
             bgpThriftClient.delPrefix(rd, prefix);
         } catch (BgpRouterException b) {
-            s_logger.error("Failed to delete BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
-            s_logger.error("BgpRouterException trace ", b);
+            LOGGER.error("Failed to delete BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
+            LOGGER.error("BgpRouterException trace ", b);
             throw b;
         } catch (TException t) {
-            s_logger.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s due to Transport error",
+            LOGGER.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s due to Transport error",
                 rd, prefix));
             reInitConn();
             throw t;
         } catch (Exception e) {
-            s_logger.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s",
+            LOGGER.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s",
                 rd, prefix));
             throw e;
         }
@@ -316,22 +316,22 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
         bgpPort = port;
 
         if(bgpThriftClient == null) {
-            s_logger.error("Failed to connect to BGP server since Bgp Thrift Client is not initialized yet.");
+            LOGGER.error("Failed to connect to BGP server since Bgp Thrift Client is not initialized yet.");
             return;
         }
         try {
             bgpThriftClient.connect(host, port);
-            s_logger.info("Connected to BGP server " + host + " on port " + port);
+            LOGGER.info("Connected to BGP server " + host + " on port " + port);
         } catch (BgpRouterException b) {
-            s_logger.error("Failed to connect to BGP server " + host + " on port " + port + " due to BgpRouter Exception number " + b.getErrorCode());
+            LOGGER.error("Failed to connect to BGP server " + host + " on port " + port + " due to BgpRouter Exception number " + b.getErrorCode());
             //_logger.error("BgpRouterException trace ", b);
             throw b;
         } catch (TException t) {
-            s_logger.error("Failed to initialize BGP Connection due to Transport error ");
+            LOGGER.error("Failed to initialize BGP Connection due to Transport error ");
             throw t;
         }
         catch (Exception e) {
-            s_logger.error("Failed to initialize BGP Connection ");
+            LOGGER.error("Failed to initialize BGP Connection ");
             throw e;
         }
     }
@@ -340,8 +340,8 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
         try {
             bgpConfiguration.setAsNum(asNum);
             bgpConfiguration.setRouterId(routerId);
-        } catch(Throwable e) {
-            s_logger.error("failed configuring bgp ",e);
+        } catch(Exception e) {
+            LOGGER.error("failed configuring bgp ",e);
         }
     }
 
@@ -349,173 +349,18 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana
 
         try {
             bgpThriftClient.reInit();
-            s_logger.info("Reinitialized connection to BGP Server " + bgpHost);
+            LOGGER.info("Reinitialized connection to BGP Server " + bgpHost);
         } catch (BgpRouterException b) {
-            s_logger.error("Failed to reinitialize connection to BGP server " + bgpHost + " on port " + bgpPort + " due to BgpRouter Exception number " + b.getErrorCode());
-            s_logger.error("BgpRouterException trace ", b);
+            LOGGER.error("Failed to reinitialize connection to BGP server " + bgpHost + " on port " + bgpPort + " due to BgpRouter Exception number " + b.getErrorCode());
+            LOGGER.error("BgpRouterException trace ", b);
         } catch (TException t) {
-            s_logger.error("Failed to reinitialize BGP Connection due to Transport error.");
+            LOGGER.error("Failed to reinitialize BGP Connection due to Transport error.");
         }
         catch (Exception e) {
-            s_logger.error("Failed to reinitialize BGP Connection.", e);
+            LOGGER.error("Failed to reinitialize BGP Connection.", e);
         }
     }
 
-    /*public synchronized void startBgpSync() {
-        boolean getRoutes = true;
-        readBgpConfiguration();
-        try {
-            pushConfigurationToBgp();
-
-        } catch (BgpRouterException b) {
-            s_logger.error("Failed to push configuration to BGP due to BgpRouter Exception number " + b.getErrorCode());
-            s_logger.error("BgpRouterException trace ", b);
-            if(b.getErrorCode() == BgpRouterException.BGP_ERR_INACTIVE)
-                getRoutes = false;
-        } catch (Exception e) {
-            s_logger.error("Failed to push configuration to bgp ", e);
-        }
-        if(getRoutes == true)
-            pullConfigurationFromBgp();
-        //controllerResyncLatch.countDown();
-    }*/
-
-    /*public void waitForControllerBgpResync() {
-        try {
-            controllerResyncLatch.await();
-        } catch (InterruptedException e) {
-        }
-    }*/
-
-    /*private void pullConfigurationFromBgp() {
-        //get routes from bgp server
-        s_logger.info("Starting bgp route sync");
-        try {
-            bgpThriftClient.doRouteSync();
-        } catch (BgpRouterException b) {
-            s_logger.error("Failed BGP Route sync due to BgpRouter Exception number " + b.getErrorCode());
-            s_logger.error("BgpRouterException trace ", b);
-        } catch (Exception e) {
-            s_logger.error("Failed to pull configuration from bgp ", e);
-        }
-    }*/
-
-    /*private BgpConfiguration readBgpConfiguration() {
-        if (cache != null) {
-            bgpConfiguration = cache.get("bgpConfiguration");
-            if (bgpConfiguration == null) {
-                s_logger.info("Created bgp configuration cache");
-                bgpConfiguration = new BgpConfiguration();
-                cache.put("bgpConfiguration", bgpConfiguration);
-            } else {
-                s_logger.info("Using bgp configuration cache");
-            }
-        }
-        return bgpConfiguration;
-    }*/
-
-    /*public synchronized void pushConfigurationToBgp() throws Exception {
-        if (bgpConfiguration.getAsNum() == 0) {
-            s_logger.error("No as num configured, Skipping the push configuration to bgp ");
-            throw new BgpRouterException(BgpRouterException.BGP_ERR_INACTIVE);
-            //return;
-        }
-        if(bgpThriftClient == null) {
-            s_logger.error("bgpThriftClient is null. Skipping the push configuration to bgp.");
-            throw new BgpRouterException(BgpRouterException.BGP_ERR_INACTIVE);
-            //return;
-        }
-
-        try {
-            bgpThriftClient.startBgp((int)bgpConfiguration.getAsNum(), bgpConfiguration.getRouterId());
-            s_logger.info("Started BGP with AS number " + (int)bgpConfiguration.getAsNum() + " and router id " + bgpConfiguration.getRouterId());
-        } catch (BgpRouterException be) {
-            if(be.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
-                s_logger.info("bgp server already active");
-                return;                //the assumption here is that bgp server is configured already with neighbor, vrfs and routes as well
-            } if(be.getErrorCode() == BgpRouterException.BGP_ERR_INACTIVE) {
-                s_logger.info("bgp server inactive");
-                throw be;
-            }
-
-            else {
-                s_logger.error("application error while starting bgp server %d", be.getErrorCode());
-                return;
-            }
-
-        } catch (SocketTimeoutException to) {
-            s_logger.error("Socket Timeout error while starting bgp server", to);
-            return;
-        } catch (TException t) {
-            s_logger.error("Transport error while starting bgp server ", t);
-            return;
-        } catch (Exception e) {
-            s_logger.error("Error while starting bgp server", e);
-        }
-
-        if (bgpConfiguration.getNeighbourIp().trim().length() > 0) {
-            try {
-                bgpThriftClient.addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
-            } catch (TException t) {
-                s_logger.error("Failed to push vrf to bgp due to Transport error" );
-                //retry connection
-                reInitConn();
-                addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
-            } catch (Exception e) {
-                s_logger.error("Error while starting bgp server", e);
-            }
-        }
-
-        Tenant tenant;
-        try {
-            tenant = tenantManager.getTenant("NEUTRON");
-        } catch (TenantNotFoundException e) {
-            s_logger.error("Tenant not found. Skipping push configuration to bgp.");
-            return;
-        }
-        if (tenant != null) {
-            int tenantId = tenant.getTenantId();
-
-            Set<VpnInstanceInfo> vpnInfos = l3Manager.getVpnInstanceManager().getVpnsForTenant(tenantId);
-            s_logger.info("Number of vpns to configure is "+vpnInfos.size());
-            for (VpnInstanceInfo vpnInfo: vpnInfos) {
-                try {
-                    bgpThriftClient.addVrf(vpnInfo.getRouteDistinguisher(),
-                        new ArrayList<>(vpnInfo.getRtImportList()),
-                        new ArrayList<>(vpnInfo.getRtExportList()));
-                } catch (TException t) {
-                    s_logger.error("Failed to push vrf to bgp due to Transport error" );
-                    //retry connection
-                    reInitConn();
-                    addVrf(vpnInfo.getRouteDistinguisher(), new ArrayList<>(vpnInfo.getRtImportList()),
-                        new ArrayList<>(vpnInfo.getRtExportList()));
-                } catch (Exception e) {
-                    s_logger.error("Failed to push vrf to bgp ", e);
-                }
-            }
-            for (VpnInstanceInfo vpnInfo: vpnInfos) {
-                ConcurrentMap<FibInfo, Object>  fibInfos = l3Manager.getVpnInstanceManager().
-                    getLocalFibInfosForRdCache(vpnInfo.getRouteDistinguisher());
-                s_logger.info("Number of fib infos to configure is "+fibInfos.size());
-                for (FibInfo fibInfo : fibInfos.keySet()) {
-                    try {
-                        bgpThriftClient.addPrefix(vpnInfo.getRouteDistinguisher(), fibInfo.getDestinationPrefix(),
-                            fibInfo.getNextHopPrefix(), (int) fibInfo.getLabel());
-                    } catch (TException t) {
-                        s_logger.error("Failed to push route to bgp due to Transport error" );
-                        reInitConn();
-                        addPrefix(vpnInfo.getRouteDistinguisher(), fibInfo.getDestinationPrefix(),
-                            fibInfo.getNextHopPrefix(), (int) fibInfo.getLabel());
-                    } catch (Exception e) {
-                        s_logger.error("Failed to push route to bgp ", e);
-                    }
-                }
-            }
-        }
-
-    }
-    */
-
     public void disconnect() {
         bgpThriftClient.disconnect();
     }
index 181e266427071f85f542d432040d882c8ccc6d45..e5af15acd93e733c946c5d4d08b633a9334102f6 100644 (file)
@@ -17,10 +17,9 @@ import org.slf4j.LoggerFactory;
 
 public class BgpRouter {
     private TTransport transport;
-    private TSocket sock;
     private TProtocol protocol;
     private static BgpConfigurator.Client bgpClient=null;
-    private static final Logger logger = LoggerFactory.getLogger(BgpRouter.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(BgpRouter.class);
 
 
     private final static int ADD_NBR = 1;
@@ -31,10 +30,6 @@ public class BgpRouter {
     private final static int DEL_PFX = 6;
     private final static int START_BGP = 7;
 
-    //public final static int BGP_ERR_INITED = 101;
-    //public final static int BGP_ERR_NOT_INITED = 102;
-
-
     private final static int GET_RTS_INIT = 0;
     private final static int GET_RTS_NEXT = 1;
 
@@ -75,38 +70,42 @@ public class BgpRouter {
         this.bgpPort = bgpPort;
         bop = new BgpOp();
         try {
-            logger.info("Connecting to BGP Server " + bgpHost + " on port " + bgpPort);
+            LOGGER.info("Connecting to BGP Server " + bgpHost + " on port " + bgpPort);
             reInit();
         } catch (Exception e) {
-            logger.error("Failed connecting to BGP server ");
+            LOGGER.error("Failed connecting to BGP server ");
             throw e;
         }
     }
 
     public void disconnect() {
-        if(transport != null)
+        if(transport != null) {
             transport.close();
+        }
     }
 
     public void reInit()
         throws TException, BgpRouterException {
-        if(transport != null)
+        if(transport != null) {
             transport.close();
+        }
         transport = new TSocket(bgpHost, bgpPort);
         ((TSocket)transport).setTimeout(Constants.CL_SKT_TIMEO_MS);
         transport.open();
         protocol = new TBinaryProtocol(transport);
         bgpClient = new BgpConfigurator.Client(protocol);
-        if(bop == null)
+        if(bop == null) {
             bop = new BgpOp();
+        }
     }
 
     private void dispatch(BgpOp op)
         throws TException, BgpRouterException {
         int result = 1;
 
-        if (bgpClient == null)
+        if (bgpClient == null) {
             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+        }
 
         switch (op.type) {
             case START_BGP:
@@ -133,7 +132,9 @@ public class BgpRouter {
                 break;
             default: break;
         }
-        if (result != 0) throw new BgpRouterException(result);
+        if (result != 0) {
+            throw new BgpRouterException(result);
+        }
     }
 
     public void startBgp(int asNum, String rtrId)
@@ -141,7 +142,7 @@ public class BgpRouter {
         bop.type = START_BGP;
         bop.asNum = asNum;
         bop.rtrId = rtrId;
-        logger.info("Starting BGP Server with as number " + asNum + " and router ID " + rtrId);
+        LOGGER.info("Starting BGP Server with as number " + asNum + " and router ID " + rtrId);
         dispatch(bop);
     }
 
@@ -150,7 +151,7 @@ public class BgpRouter {
         bop.type = ADD_NBR;
         bop.nbrIp = nbrIp;
         bop.nbrAsNum = nbrAsNum;
-        logger.info("Adding BGP Neighbor " + nbrIp + " with as number " + nbrAsNum);
+        LOGGER.info("Adding BGP Neighbor " + nbrIp + " with as number " + nbrAsNum);
         dispatch(bop);
     }
 
@@ -158,7 +159,7 @@ public class BgpRouter {
         throws TException, BgpRouterException {
         bop.type = DEL_NBR;
         bop.nbrIp = nbrIp;
-        logger.info("Deleting BGP Neighbor " + nbrIp);
+        LOGGER.info("Deleting BGP Neighbor " + nbrIp);
         dispatch(bop);
     }
 
@@ -168,7 +169,7 @@ public class BgpRouter {
         bop.rd = rd;
         bop.irts = irts;
         bop.erts = erts;
-        logger.info("Adding BGP VRF rd: " + rd);
+        LOGGER.info("Adding BGP VRF rd: " + rd);
         dispatch(bop);
     }
 
@@ -176,7 +177,7 @@ public class BgpRouter {
         throws TException, BgpRouterException {
         bop.type = DEL_VRF;
         bop.rd = rd;
-        logger.info("Deleting BGP VRF rd: " + rd);
+        LOGGER.info("Deleting BGP VRF rd: " + rd);
         dispatch(bop);
     }
 
@@ -187,7 +188,7 @@ public class BgpRouter {
         bop.pfx = prefix;
         bop.nh = nexthop;
         bop.lbl = label;
-        logger.info("Adding BGP route - rd:" + rd + " prefix:" + prefix + " nexthop:" + nexthop + " label:" + label);
+        LOGGER.info("Adding BGP route - rd:" + rd + " prefix:" + prefix + " nexthop:" + nexthop + " label:" + label);
         dispatch(bop);
     }
 
@@ -196,16 +197,18 @@ public class BgpRouter {
         bop.type = DEL_PFX;
         bop.rd = rd;
         bop.pfx = prefix;
-        logger.info("Deleting BGP route - rd:" + rd + " prefix:" + prefix);
+        LOGGER.info("Deleting BGP route - rd:" + rd + " prefix:" + prefix);
         dispatch(bop);
     }
 
     public int initRibSync(BgpSyncHandle handle)
         throws TException, BgpRouterException {
-        if (bgpClient == null)
+        if (bgpClient == null) {
             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
-        if (handle.getState() == BgpSyncHandle.ITERATING)
+        }
+        if (handle.getState() == BgpSyncHandle.ITERATING) {
             return BgpRouterException.BGP_ERR_IN_ITER;
+        }
         handle.setState(BgpSyncHandle.INITED);
         handle.setMore(1);
         return 0;
@@ -213,8 +216,9 @@ public class BgpRouter {
 
     public int endRibSync(BgpSyncHandle handle)
         throws TException, BgpRouterException {
-        if (bgpClient == null)
+        if (bgpClient == null) {
             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+        }
         int state = handle.getState();
         switch (state) {
             case BgpSyncHandle.INITED:
@@ -233,8 +237,9 @@ public class BgpRouter {
 
     public Routes doRibSync(BgpSyncHandle handle)
         throws TException, BgpRouterException {
-        if (bgpClient == null)
+        if (bgpClient == null) {
             throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+        }
         int state = handle.getState();
         if (state != BgpSyncHandle.INITED && state != BgpSyncHandle.ITERATING) {
             Routes r = new Routes();
@@ -246,11 +251,13 @@ public class BgpRouter {
         handle.setState(BgpSyncHandle.ITERATING);
         int winSize = handle.getMaxCount()*handle.getRouteSize();
         Routes outRoutes = bgpClient.getRoutes(op, winSize);
-       if (outRoutes.errcode != 0)
-            return outRoutes;
+       if (outRoutes.errcode != 0) {
+           return outRoutes;
+       }
         handle.setMore(outRoutes.more);
-        if (outRoutes.more == 0)
+        if (outRoutes.more == 0) {
             handle.setState(BgpSyncHandle.DONE);
+        }
         return outRoutes;
     }
 
@@ -260,13 +267,13 @@ public class BgpRouter {
         BgpSyncHandle bsh = BgpSyncHandle.getInstance();
 
         try {
-            logger.info("Starting BGP Route sync.. ");
+            LOGGER.info("Starting BGP Route sync.. ");
             initRibSync(bsh);
             while (bsh.getState() != bsh.DONE) {
                 Routes r = doRibSync(bsh);
                 if(r.getErrcode() == BgpRouterException.BGP_ERR_INACTIVE) {
                     //BGP server is inactive; log and return
-                    logger.error("BGP Server is inactive. Failed BGP Route sync");
+                    LOGGER.error("BGP Server is inactive. Failed BGP Route sync");
                     return;
                 }
                 Iterator<Update> iter = r.getUpdatesIterator();
@@ -281,37 +288,12 @@ public class BgpRouter {
                 }
             }
             endRibSync(bsh);
-            logger.info("Completed BGP Route sync.");
+            LOGGER.info("Completed BGP Route sync.");
         }  catch (Exception e) {
             throw e;
         }
     };
 
 
-    public List<Route> getRoutes()
-        throws TException, BgpRouterException {
-
-        BgpSyncHandle bsh = BgpSyncHandle.getInstance();
-        List<Route> allRoutes = new ArrayList<Route>();
-
-        try {
-            initRibSync(bsh);
-            while (bsh.getState() != bsh.DONE) {
-                Routes r = doRibSync(bsh);
-                Iterator<Update> iter = r.getUpdatesIterator();
-                while (iter.hasNext()) {
-                    Update u = iter.next();
-                    Route route = new Route(u.rd, u.prefix, u.prefixlen, u.nexthop, u.label);
-
-                    allRoutes.add(route);
-                }
-            }
-            endRibSync(bsh);
-        }  catch (Exception e) {
-            throw e;
-        }
-        return allRoutes;
-    };
-
 
 }
index e00515f3fe18631ff0380237f23758b07ff57e18..5c0eb4238c2dc7a6a3e75982706eb239f83bb32e 100644 (file)
@@ -4,9 +4,12 @@ package org.opendaylight.bgpmanager.thrift.client.implementation;
 import java.io.IOException;
 import java.net.Socket;
 import java.net.SocketException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class BgpSyncHandle {
     private static BgpSyncHandle handle = null;
+    private static final Logger LOGGER = LoggerFactory.getLogger(BgpSyncHandle.class);
     private int more;
     private int state;
 
@@ -16,7 +19,7 @@ public class BgpSyncHandle {
     public static final int ABORTED = 4;
     public static final int NEVER_DONE = 5;
 
-    public static final int default_tcp_sock_sz = 87380;    //default receive buffer size on linux > 2.4 (SLES 11)
+    public static final int DEFAULT_TCP_SOCK_SZ = 87380;    //default receive buffer size on linux > 2.4
 
     private BgpSyncHandle() {
         more = 1; 
@@ -24,8 +27,9 @@ public class BgpSyncHandle {
     }
 
     public static synchronized BgpSyncHandle getInstance() {
-       if (handle == null) 
+       if (handle == null) {
            handle = new BgpSyncHandle();
+       }
        return handle;
     }
 
@@ -36,14 +40,16 @@ public class BgpSyncHandle {
     public int getMaxCount() {
         //compute the max count of routes we would like to send
         Socket skt = new Socket();
-        int sockBufSz = default_tcp_sock_sz;
+        int sockBufSz = DEFAULT_TCP_SOCK_SZ;
         try {
             sockBufSz = skt.getReceiveBufferSize();
         } catch (SocketException s) {
+            LOGGER.warn("Socket Exception while retrieving default socket buffer size");
         }
         try {
             skt.close();
         } catch (IOException e) {
+            LOGGER.warn("IO Exception while closing socket for retrieving default socket buffer size");
         }
         return sockBufSz/getRouteSize();
     }
index c6d01195c109050a2331b335a074060502e5f499..dfe4af646d97f2907c2f8b39c1cd6bd5d81ea699 100644 (file)
@@ -14,14 +14,12 @@ import org.slf4j.LoggerFactory;
 
 public class BgpThriftService {
        
-       private static final Logger logger = LoggerFactory.getLogger(BgpThriftService.class);
+       private static final Logger LOGGER = LoggerFactory.getLogger(BgpThriftService.class);
        
        private int port;
-       //private int serverType;
        private int maxWorkerThreads;
        private int minWorkerThreads;
     private TServerTransport serverTransport;
-       //private TNonblockingServerTransport serverTransport;
     private TServer server;
        private BgpUpdateHandler notificationHandler;
        private BgpManager bgpManager;
@@ -29,17 +27,16 @@ public class BgpThriftService {
     public BgpThriftService(BgpManager bgpMgr, FibDSWriter dsWriter) {
        bgpManager = bgpMgr;
                notificationHandler = new BgpUpdateHandler(bgpManager, dsWriter);
-               //fibDSWriter = dsWriter;
     }
 
 
        public void start() {
-               logger.info("BGP Thrift Server starting.");
+               LOGGER.info("BGP Thrift Server starting.");
                startBgpThriftServer();
        }
        
        public void stop() {
-               logger.info("BGP Thrift Server stopping.");
+               LOGGER.info("BGP Thrift Server stopping.");
                stopBgpThriftServer();
        }
 
@@ -47,7 +44,7 @@ public class BgpThriftService {
         * Destroy method called up after the bundle has been stopped
         */
        public void destroy() {
-               logger.debug("BGP Thrift Server destroy ");
+               LOGGER.debug("BGP Thrift Server destroy ");
        }
 
     /**
@@ -71,7 +68,7 @@ public class BgpThriftService {
 
        public void stopBgpThriftServer() {
                try {
-            logger.debug("Server stopping");
+            LOGGER.debug("Server stopping");
 
             if (serverTransport != null) {
                 serverTransport.close();
@@ -79,21 +76,19 @@ public class BgpThriftService {
             
             server.stop();
         } catch (Exception e) {
-            logger.error("Error while stopping the server - {} {}", getClass().getName(), e.getMessage());
+            LOGGER.error("Error while stopping the server - {} {}", getClass().getName(), e.getMessage());
         }
        }
        
        private class ThriftRunnable implements Runnable {
                @Override
                public void run() {
-                       //notificationHandler = new BgpUpdateHandler(bgpManager);
 
                try {
                                serverTransport = new TServerSocket(port);
-                               //serverTransport = new TNonblockingServerSocket(port);
-                   logger.info("Server Socket on Port {} ", port);
-                       } catch (TTransportException e) {                       
-                               e.printStackTrace();
+                   LOGGER.info("Server Socket on Port {} ", port);
+                       } catch (TTransportException e) {
+                               LOGGER.error("Transport Exception while starting bgp thrift server", e);
                                return;
                        }
                        /* This may need to change. Right now, its as good as a blocking server for each client (client would be
@@ -103,11 +98,6 @@ public class BgpThriftService {
                server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport)
                        .maxWorkerThreads(maxWorkerThreads).minWorkerThreads(minWorkerThreads)
                        .processor(new BgpUpdater.Processor<BgpUpdateHandler>(notificationHandler)));
-                       /*
-                       THsHaServer.Args args = new THsHaServer.Args(serverTransport);
-                       args.workerThreads(10);
-                       server = new THsHaServer(args.processor(new BgpUpdater.Processor<BgpUpdateHandler>(notificationHandler)));*/
-
                        server.serve();
                }               
        }
index a9aecccc9fd5edd6ccb423cc858a7c0a2add7ecc..9f3c40a89a65a2d5ae33f791bf1cab1abd3767bf 100644 (file)
@@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory;
 
 class BgpUpdateHandler implements BgpUpdater.Iface {
 
-    private static final Logger logger = LoggerFactory.getLogger(BgpUpdateHandler.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(BgpUpdateHandler.class);
     private BgpManager bgpManager;
     private FibDSWriter fibDSWriter;
 
@@ -20,7 +20,7 @@ class BgpUpdateHandler implements BgpUpdater.Iface {
     public void onUpdatePushRoute(String rd, String prefix, int plen,
                                 String nexthop, int label) {
 
-       logger.info("Route add ** " + rd + " ** " + prefix + "/" + plen
+       LOGGER.info("Route add ** " + rd + " ** " + prefix + "/" + plen
                + " ** " + nexthop + " ** " + label);
         //Write to FIB in Data Store
         fibDSWriter.addFibEntryToDS(rd, prefix + "/" + plen, nexthop, label);
@@ -28,13 +28,13 @@ class BgpUpdateHandler implements BgpUpdater.Iface {
    }
 
    public void onUpdateWithdrawRoute(String rd, String prefix, int plen) {
-       logger.info("Route del ** " + rd + " ** " + prefix + "/" + plen);
+       LOGGER.info("Route del ** " + rd + " ** " + prefix + "/" + plen);
        fibDSWriter.removeFibEntryFromDS(rd, prefix + "/" + plen);
 
    }
 
    public void onStartConfigResyncNotification() {
-       logger.info("BGP (re)started");
+       LOGGER.info("BGP (re)started");
        bgpManager.reInitConn();
    }
 
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 84f0c09cbd06d7d8f6e957f4b0c5d3f50a55a58c..4cfdfcf6919de45a345c3371e1ab999adb0061d0 100644 (file)
@@ -27,6 +27,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <yang.ext.version>2013.09.07.7-SNAPSHOT</yang.ext.version>
     <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
     <mdsal.version>1.2.0-SNAPSHOT</mdsal.version>
+    <vpns.mdsalutil.version>0.0.1-SNAPSHOT</vpns.mdsalutil.version>
   </properties>
   <dependencies>
     <dependency>
@@ -69,5 +70,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>model-inventory</artifactId>
       <version>${mdsal.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>mdsalutil-api</artifactId>
+      <version>${vpns.mdsalutil.version}</version>
+    </dependency>
   </dependencies>
 </project>
\ No newline at end of file
index bda2d8c0c0757b9d088d5c2154b6bf543a324c49..206e6e1170dcbde74b4a68f341757d0521689f34 100644 (file)
@@ -1,7 +1,15 @@
 package org.opendaylight.vpnservice.interfacemgr.interfaces;
 
+import java.util.List;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+
 public interface IInterfaceManager {
 
-    public void testApi();
+    public Long getPortForInterface(String ifName);
+    public long getDpnForInterface(String ifName);
+    public String getEndpointIpForDpn(long dpnId);
+    public List<MatchInfo> getInterfaceIngressRule(String ifName);
+    public List<ActionInfo> getInterfaceEgressActions(String ifName);
 
 }
\ No newline at end of file
index 6fcdf059deb68d621390e542ea6bcad42e850c5a..fec2ca0d00715d4a73dd5b770d0823a35473aaae 100644 (file)
@@ -38,7 +38,22 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <dependency>
       <groupId>org.opendaylight.vpnservice</groupId>
       <artifactId>vpnmanager-impl</artifactId>
-      <version>1.0-SNAPSHOT</version>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>mdsalutil-api</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>idmanager-api</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>idmanager-impl</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
     </dependency>
     <!-- Testing Dependencies -->
     <dependency>
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java
new file mode 100644 (file)
index 0000000..add3af5
--- /dev/null
@@ -0,0 +1,11 @@
+package org.opendaylight.vpnservice.interfacemgr;
+
+public class IfmConstants {
+    public static final String IFM_IDPOOL_NAME = "interfaces";
+    public static final long IFM_IDPOOL_START = 1L;
+    public static final String IFM_IDPOOL_SIZE = "65535";
+    public static final String OF_URI_PREFIX = "openflow:";
+    public static final String OF_URI_SEPARATOR = ":";
+    public static final int DEFAULT_IFINDEX = 65536;
+
+}
index ef3653ea3b9049742fbe65dfd5de4a7a93ed0b8a..1e4fac40fc32279de8955a8e31f9f4d28dfdf885 100644 (file)
@@ -1,20 +1,17 @@
 package org.opendaylight.vpnservice.interfacemgr;
 
+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;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.AbstractDataChangeListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-
-import java.util.Iterator;
-import java.util.List;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.opendaylight.vpnservice.AbstractDataChangeListener;
 
 public class IfmNodeConnectorListener extends AbstractDataChangeListener<NodeConnector> implements AutoCloseable{
     private static final Logger LOG = LoggerFactory.getLogger(IfmNodeConnectorListener.class);
@@ -74,7 +71,6 @@ public class IfmNodeConnectorListener extends AbstractDataChangeListener<NodeCon
 
     @Override
     protected void update(InstanceIdentifier<NodeConnector> identifier, NodeConnector original, NodeConnector update) {
-        LOG.trace("NodeConnectorUpdated: key: " + identifier + ", original=" + original + ", update=" + update );
         ifManager.processPortUpdate(original, update);
     }
 
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java
new file mode 100644 (file)
index 0000000..76f0c1a
--- /dev/null
@@ -0,0 +1,58 @@
+package org.opendaylight.vpnservice.interfacemgr;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.Pools;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPoolKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+
+public class IfmUtil {
+
+    public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
+        /*
+         * NodeConnectorId is of form 'openflow:dpnid:portnum'
+         */
+        String[] split = portId.getValue().split(IfmConstants.OF_URI_SEPARATOR);
+        return split[1];
+    }
+
+
+    public static NodeId buildDpnNodeId(long dpnId) {
+        return new NodeId(IfmConstants.OF_URI_PREFIX + dpnId);
+    }
+
+    public static InstanceIdentifier<Interface> buildId(String interfaceName) {
+        //TODO Make this generic and move to AbstractDataChangeListener or Utils.
+        InstanceIdentifierBuilder<Interface> idBuilder =
+                InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
+        InstanceIdentifier<Interface> id = idBuilder.build();
+        return id;
+    }
+
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
+        InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
+                InstanceIdentifier.builder(InterfacesState.class)
+                .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
+                                new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
+        return id;
+    }
+
+    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName(
+                    String name) {
+        return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name);
+    }
+
+    public static InstanceIdentifier<IdPool> getPoolId(String poolName){
+        InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
+                        InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey(poolName));
+        InstanceIdentifier<IdPool> id = idBuilder.build();
+        return id;
+    }
+}
index 768656d78f008ece4fdb44b046c2d4e24fd964d3..a1cc4972589eee098b9d2b3cb32bca552c571e52 100644 (file)
@@ -7,49 +7,70 @@
  */
 package org.opendaylight.vpnservice.interfacemgr;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
-import java.math.BigInteger;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state._interface.StatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state._interface.Statistics;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
-import com.google.common.util.concurrent.FutureCallback;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionType;
+import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.vpnservice.AbstractDataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.id.pool.GeneratedIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfMpls;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfStackedVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.Mpls;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.StackedVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
 
-public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable{
+public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceManager.class);
     private ListenerRegistration<DataChangeListener> listenerRegistration;
     private final DataBroker broker;
+    private final IdManager idManager;
+    private final Map<NodeConnectorId, String> mapNcToInterfaceName = new ConcurrentHashMap<>();
+    private final Map<NodeId, String> dbDpnEndpoints = new ConcurrentHashMap<>();
 
     private static final FutureCallback<Void> DEFAULT_CALLBACK =
                     new FutureCallback<Void>() {
@@ -59,12 +80,13 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
 
                         public void onFailure(Throwable error) {
                             LOG.error("Error in Datastore write operation", error);
-                        };
+                        }
                     };
 
-    public InterfaceManager(final DataBroker db) {
+    public InterfaceManager(final DataBroker db, final IdManager idmgr) {
         super(Interface.class);
         broker = db;
+        idManager = idmgr;
         registerListener(db);
     }
 
@@ -94,48 +116,41 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
     @Override
     protected void add(final InstanceIdentifier<Interface> identifier,
             final Interface imgrInterface) {
-        LOG.trace("key: " + identifier + ", value=" + imgrInterface );
+        LOG.trace("Adding interface key: " + identifier + ", value=" + imgrInterface );
         addInterface(identifier, imgrInterface);
     }
 
     private InstanceIdentifier<Interface> buildId(final InstanceIdentifier<Interface> identifier) {
         //TODO Make this generic and move to AbstractDataChangeListener or Utils.
         final InterfaceKey key = identifier.firstKeyOf(Interface.class, InterfaceKey.class);
-        String interfaceName = key.getName();
+        return buildId(key.getName());
+    }
+
+    private InstanceIdentifier<Interface> buildId(String interfaceName) {
+        //TODO Make this generic and move to AbstractDataChangeListener or Utils.
         InstanceIdentifierBuilder<Interface> idBuilder =
                 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
         InstanceIdentifier<Interface> id = idBuilder.build();
         return id;
     }
 
-    private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
-        //TODO Make this generic and move to AbstractDataChangeListener or Utils.
-        InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
-                InstanceIdentifier.builder(InterfacesState.class)
-                .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
-                                new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
-        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
-        return id;
-    }
 
     private void addInterface(final InstanceIdentifier<Interface> identifier,
-                              final Interface imgrInterface) {
-        InstanceIdentifier<Interface> id = buildId(identifier);
-        Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
-        if(port.isPresent()) {
-            Interface interf = port.get();
-            NodeConnector nodeConn = getNodeConnectorFromInterface(interf);
-            updateInterfaceState(identifier, interf, nodeConn);
-            /* TODO:
-             *  1. Get interface-id from id manager
-             *  2. Update interface-state with following:
-             *    admin-status = set to enable value
-             *    oper-status = Down [?]
-             *    if-index = interface-id
-             * FIXME:
-             *  1. Get operational data from node-connector-id?
-             *
-             */
+                              final Interface interf) {
+        NodeConnector nodeConn = getNodeConnectorFromDataStore(interf);
+        NodeConnectorId ncId = null;
+        updateInterfaceState(identifier, interf, nodeConn);
+        if (nodeConn == null) {
+            ncId = getNodeConnectorIdFromInterface(interf);
+        } else {
+            ncId = nodeConn.getId();
+        }
+        mapNcToInterfaceName.put(ncId, interf.getName());
+        if(interf.getType().isAssignableFrom(L3tunnel.class)) {
+            NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
+            IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
+            dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
+            LOG.trace("dbDpnEndpoints: {}",dbDpnEndpoints);
         }
     }
 
@@ -151,7 +166,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
          *    if-index = interface-id
         */
         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
-                        buildStateInterfaceId(interf.getName());
+                        IfmUtil.buildStateInterfaceId(interf.getName());
         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
                         read(LogicalDatastoreType.OPERATIONAL, id);
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
@@ -159,12 +174,13 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
                         new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
         if(!stateIf.isPresent()) {
             // TODO: Get interface-id from IdManager
+            String ifName = interf.getName();
             ifaceBuilder.setAdminStatus((interf.isEnabled()) ?  org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Up :
                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Down);
-            ifaceBuilder.setOperStatus(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down);
-            ifaceBuilder.setIfIndex(200).setName(interf.getName()).setType(interf.getType());
-            ifaceBuilder.setKey(getStateInterfaceKeyFromName(interf.getName()));
-            //ifaceBuilder.setStatistics(createStatistics(interf.getName(), nodeConn));
+            ifaceBuilder.setOperStatus(getOperStatus(nodeConn));
+
+            ifaceBuilder.setIfIndex(getIfIndex(ifName)).setName(ifName).setType(interf.getType());
+            ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
             stateIface = ifaceBuilder.build();
             LOG.trace("Adding stateIface {} and id {} to OPERATIONAL DS", stateIface, id);
             asyncWrite(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
@@ -176,48 +192,63 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
             if(interf.getType() != null) {
                 ifaceBuilder.setType(interf.getType());
             }
-
+            ifaceBuilder.setOperStatus(getOperStatus(nodeConn));
             stateIface = ifaceBuilder.build();
             LOG.trace("updating OPERATIONAL data store with stateIface {} and id {}", stateIface, id);
             asyncUpdate(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
         }
     }
 
-    /*
-    private void setAugmentations(
-                    org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder,
-                    InstanceIdentifier<Interface> identifier, Interface interf) {
-        // TODO Add code for all augmentations
-        InstanceIdentifier<IfL3tunnel> ifL3TunnelPath = identifier.augmentation(IfL3tunnel.class);
-        Optional<IfL3tunnel> l3Tunnel = read(LogicalDatastoreType.CONFIGURATION, ifL3TunnelPath);
-        String ifName = interf.getName();
-        if(l3Tunnel.isPresent()) {
-            l3Tunnel.get();
+    private Integer getIfIndex(String ifName) {
+        GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder()
+        .setPoolName(IfmConstants.IFM_IDPOOL_NAME).setIdKey(ifName)
+        .build();
+        //TODO: Proper error handling once IdManager code is complete
+        try {
+            Future<RpcResult<GetUniqueIdOutput>> result = idManager.getUniqueId(getIdInput);
+            RpcResult<GetUniqueIdOutput> rpcResult = result.get();
+            return rpcResult.getResult().getIdValue().intValue();
+        } catch (NullPointerException | InterruptedException | ExecutionException e) {
+            LOG.trace("",e);
         }
-    }
-    */
-
-    private Statistics createStatistics(String name, NodeConnector nodeConn) {
-        Counter64 init64 = new Counter64(new BigInteger("0000000000000000"));
-        Counter32 init32 = new Counter32((long) 0);
-        StatisticsBuilder statBuilder = new StatisticsBuilder();
-        statBuilder.setDiscontinuityTime(new DateAndTime("2015-04-04T00:00:00Z"))
-        .setInBroadcastPkts(init64).setInDiscards(init32).setInErrors(init32).setInMulticastPkts(init64)
-        .setInOctets(init64).setInUnicastPkts(init64).setInUnknownProtos(init32).setOutBroadcastPkts(init64)
-        .setOutDiscards(init32).setOutErrors(init32).setOutMulticastPkts(init64).setOutOctets(init64)
-        .setOutUnicastPkts(init64);
-        return statBuilder.build();
+        /* This currently returns null, so let us get it from IdManager DS
+         * TODO: Start-delete-me
+         */
+
+        InstanceIdentifier<IdPool> id = IfmUtil.getPoolId(IfmConstants.IFM_IDPOOL_NAME);
+        Optional<IdPool> globalPool = read(LogicalDatastoreType.OPERATIONAL, id );
+        Long newIdValue = null;
+        if (globalPool.isPresent()) {
+            IdPool pool = globalPool.get();
+            List<GeneratedIds> generatedIds = pool.getGeneratedIds();
+            if ((generatedIds != null) && !generatedIds.isEmpty()) {
+                for (GeneratedIds gen_id : generatedIds) {
+                    if (gen_id.getIdKey().equals(ifName)) {
+                        newIdValue = gen_id.getIdValue();
+                        LOG.debug("Id {} found for interface %s ", newIdValue, ifName);
+                        return newIdValue.intValue();
+                    }
+                }
+            }
+        }
+        //TODO: End-delete-me
+        LOG.debug("Unable to get valid ifIndex for interface {}", ifName);
+        return IfmConstants.DEFAULT_IFINDEX;
     }
 
-    private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName(
-                    String name) {
-        return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name);
+    private OperStatus getOperStatus(NodeConnector nodeConn) {
+        LOG.trace("nodeConn is {}", nodeConn);
+        if(nodeConn == null) {
+            return OperStatus.Down;
+        }else {
+            return OperStatus.Up;
+        }
     }
 
-    private NodeConnector getNodeConnectorFromInterface(Interface interf) {
+    private NodeConnector getNodeConnectorFromDataStore(Interface interf) {
         NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
         //TODO: Replace with MDSAL Util method
-        NodeId nodeId = new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
+        NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
         InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
                         .child(Node.class, new NodeKey(nodeId))
                         .child(NodeConnector.class, new NodeConnectorKey(ncId)).build();
@@ -231,25 +262,69 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
         return null;
     }
 
+    private NodeConnectorId getNodeConnectorIdFromInterface(Interface interf) {
+        return interf.getAugmentation(BaseIds.class).getOfPortId();
+    }
+
     private void delInterface(final InstanceIdentifier<Interface> identifier,
                               final Interface delInterface) {
         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
-                        buildStateInterfaceId(delInterface.getName());
+                        IfmUtil.buildStateInterfaceId(delInterface.getName());
         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
                         read(LogicalDatastoreType.OPERATIONAL, id);
-        if(!stateIf.isPresent()) {
+        if(stateIf.isPresent()) {
             LOG.trace("deleting interfaces:state OPERATIONAL data store with id {}", id);
             asyncRemove(LogicalDatastoreType.OPERATIONAL, id, DEFAULT_CALLBACK);
+            NodeConnectorId ncId = getNodeConnectorIdFromInterface(delInterface);
+            if(ncId != null) {
+                mapNcToInterfaceName.remove(ncId);
+                if(delInterface.getType().isAssignableFrom(L3tunnel.class)) {
+                    Node node = getNodeFromDataStore(delInterface);
+                    if((node != null) &&(node.getNodeConnector().isEmpty())) {
+                        dbDpnEndpoints.remove(node.getId());
+                    }
+                }
+            }
         }
     }
 
+    private Node getNodeFromDataStore(Interface interf) {
+        NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
+        //TODO: Replace with MDSAL Util method
+        NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
+        InstanceIdentifier<Node> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
+                        .child(Node.class, new NodeKey(nodeId)).build();
+
+        Optional<Node> dpn = read(LogicalDatastoreType.OPERATIONAL, ncIdentifier);
+        if(dpn.isPresent()) {
+            Node node = dpn.get();
+            LOG.trace("node: {}",node);
+            return node;
+        }
+        return null;
+    }
+
     private void updateInterface(final InstanceIdentifier<Interface> identifier,
-                              final Interface original, final Interface udpate) {
+                              final Interface original, final Interface update) {
         InstanceIdentifier<Interface> id = buildId(identifier);
         Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
         if(port.isPresent()) {
             Interface interf = port.get();
-            //TODO: Update operational data
+            NodeConnector nc = getNodeConnectorFromDataStore(update);
+            updateInterfaceState(identifier, update, nc);
+            /*
+             * Alternative is to get from interf and update map irrespective if NCID changed or not.
+             */
+            if(nc != null) {
+                // Name doesn't change. Is it present in update?
+                mapNcToInterfaceName.put(nc.getId(), original.getName());
+                if(interf.getType().isAssignableFrom(L3tunnel.class)) {
+                    NodeId nodeId = getNodeIdFromNodeConnectorId(nc.getId());
+                    IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
+                    dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
+                    LOG.trace("dbEndpoints: {}",dbDpnEndpoints);
+                }
+            }
         }
     }
 
@@ -274,55 +349,194 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
 
     @Override
     protected void remove(InstanceIdentifier<Interface> identifier, Interface del) {
-        LOG.trace("key: " + identifier + ", value=" + del );
+        LOG.trace("remove - key: " + identifier + ", value=" + del );
         delInterface(identifier, del);
     }
 
     @Override
     protected void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
-        LOG.trace("key: " + identifier + ", original=" + original + ", update=" + update );
+        LOG.trace("update - key: " + identifier + ", original=" + original + ", update=" + update );
         updateInterface(identifier, original, update);
     }
 
-    private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+    protected <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);
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.put(datastoreType, path, data, true);
+        Futures.addCallback(tx.submit(), callback);
     }
 
-    private <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
+    protected <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
                     InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
-    WriteTransaction tx = broker.newWriteOnlyTransaction();
-    tx.merge(datastoreType, path, data, true);
-    Futures.addCallback(tx.submit(), callback);
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.merge(datastoreType, path, data, true);
+        Futures.addCallback(tx.submit(), callback);
     }
 
-    private <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
+    protected <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
                     InstanceIdentifier<T> path, FutureCallback<Void> callback) {
-    WriteTransaction tx = broker.newWriteOnlyTransaction();
-    tx.delete(datastoreType, path);
-    Futures.addCallback(tx.submit(), callback);
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.delete(datastoreType, path);
+        Futures.addCallback(tx.submit(), callback);
     }
 
-    public void processPortAdd(NodeConnector port) {
-        String strPortId = port.getId().getValue();
+    void processPortAdd(NodeConnector port) {
+        NodeConnectorId portId = port.getId();
         FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
-        LOG.debug("PortAdd: PortId { "+strPortId+"} PortName {"+ofPort.getName()+"}");
+        LOG.debug("PortAdd: PortId { " + portId.getValue() + "} PortName {" + ofPort.getName() + "}");
+        String ifName = this.mapNcToInterfaceName.get(portId);
+        setInterfaceOperStatus(ifName, OperStatus.Up);
     }
 
-    public void processPortUpdate(NodeConnector oldPort, NodeConnector update) {
-        String oldPortId = oldPort.getId().getValue();
-        FlowCapableNodeConnector oldOfPort = oldPort.getAugmentation(FlowCapableNodeConnector.class);
-        String strPortId = update.getId().getValue();
-        FlowCapableNodeConnector ofPort = update.getAugmentation(FlowCapableNodeConnector.class);
-        LOG.debug("PortUpdate: { "+strPortId+", "+ofPort.getName()+"}");
+    void processPortUpdate(NodeConnector oldPort, NodeConnector update) {
+        //TODO: Currently nothing to do here.
+        LOG.trace("ifMap: {}, dpnMap: {}", mapNcToInterfaceName, dbDpnEndpoints);
     }
 
-    public void processPortDelete(NodeConnector port) {
-        String strPortId = port.getId().getValue();
+    void processPortDelete(NodeConnector port) {
+        NodeConnectorId portId = port.getId();
         FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
-        LOG.debug("PortDelete: PortId { "+strPortId+"} PortName {"+ofPort.getName()+"}");
+        LOG.debug("PortDelete: PortId { "+portId.getValue()+"} PortName {"+ofPort.getName()+"}");
+        String ifName = this.mapNcToInterfaceName.get(portId);
+        setInterfaceOperStatus(ifName, OperStatus.Down);
+    }
+
+    private void setInterfaceOperStatus(String ifName, OperStatus opStatus) {
+        if (ifName != null) {
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
+                            IfmUtil.buildStateInterfaceId(ifName);
+            Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
+                            read(LogicalDatastoreType.OPERATIONAL, id);
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder =
+                            new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
+            if (stateIf.isPresent()) {
+                stateIface = ifaceBuilder.setOperStatus(opStatus).build();
+                LOG.trace("Setting OperStatus for {} to {} in OPERATIONAL DS", ifName, opStatus);
+                asyncUpdate(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
+            }
+        }
+    }
+
+    private Interface getInterfaceByIfName(String ifName) {
+        InstanceIdentifier<Interface> id = buildId(ifName);
+        Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
+        if(port.isPresent()) {
+            return port.get();
+        }
+        return null;
+    }
+
+    Long getPortForInterface(String ifName) {
+        Interface iface = getInterfaceByIfName(ifName);
+        return getPortNumForInterface(iface);
+    }
+
+    long getDpnForInterface(String ifName) {
+        Interface iface = getInterfaceByIfName(ifName);
+        try {
+            NodeConnector port = getNodeConnectorFromDataStore(iface);
+            //TODO: This should be an MDSAL Util method
+            return Long.parseLong(IfmUtil.getDpnFromNodeConnectorId(port.getId()));
+        } catch (NullPointerException e) {
+            LOG.error("OFPort for Interface {} not found", ifName);
+        }
+        return 0L;
+    }
+
+    String getEndpointIpForDpn(long dpnId) {
+        //TODO: This should be MDSAL Util function
+        NodeId dpnNodeId = IfmUtil.buildDpnNodeId(dpnId);
+        return dbDpnEndpoints.get(dpnNodeId);
+    }
+
+    List<MatchInfo> getInterfaceIngressRule(String ifName) {
+        Interface iface = getInterfaceByIfName(ifName);
+        List<MatchInfo> matches = new ArrayList<MatchInfo>();
+        Class<? extends InterfaceType> ifType = iface.getType();
+        long dpn = this.getDpnForInterface(ifName);
+        long portNo = this.getPortNumForInterface(iface).longValue();
+        matches.add(new MatchInfo(MatchFieldType.in_port, new long[] {dpn, portNo}));
+
+        if (ifType.isInstance(L2vlan.class)) {
+            IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
+            long vlanVid = vlanIface.getVlanId().longValue();
+            if (vlanVid != 0) {
+                matches.add(new MatchInfo(MatchFieldType.vlan_vid,
+                            new long[] {vlanVid}));
+                LOG.trace("L2Vlan: {}",vlanIface);
+            }
+        } else if (ifType.isInstance(L3tunnel.class)) {
+            //TODO: Handle different tunnel types
+            IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
+            Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
+            LOG.trace("L3Tunnel: {}",ifL3Tunnel);
+        } else if (ifType.isAssignableFrom(StackedVlan.class)) {
+            IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class);
+            LOG.trace("StackedVlan: {}",ifStackedVlan);
+        } else if (ifType.isAssignableFrom(Mpls.class)) {
+            IfMpls ifMpls = iface.getAugmentation(IfMpls.class);
+            LOG.trace("Mpls: {}",ifMpls);
+        }
+        return matches;
+    }
+
+    public List<ActionInfo> getInterfaceEgressActions(String ifName) {
+        Interface iface = getInterfaceByIfName(ifName);
+
+        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+        Class<? extends InterfaceType> ifType = iface.getType();
+        long dpn = this.getDpnForInterface(ifName);
+        long portNo = this.getPortNumForInterface(iface).longValue();
+
+        if (iface.isEnabled()) {
+
+            if(ifType.isAssignableFrom(L2vlan.class)) {
+                IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
+                long vlanVid = vlanIface.getVlanId();
+                LOG.trace("L2Vlan: {}",vlanIface);
+                if (vlanVid != 0) {
+                    listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
+                    listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
+                            new String[] { Long.toString(vlanVid) }));
+                }
+                listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
+
+            } else if (ifType.isAssignableFrom(L3tunnel.class)) {
+                //TODO: Handle different tunnel types
+                IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
+                Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
+                LOG.trace("L3Tunnel: {}",ifL3Tunnel);
+                //TODO: check switch_type and configure accordingly
+                listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
+
+            } else if (ifType.isAssignableFrom(StackedVlan.class)) {
+                IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class);
+                LOG.trace("StackedVlan: {}",ifStackedVlan);
+                // TODO: TBD
+            } else if (ifType.isAssignableFrom(Mpls.class)) {
+                IfMpls ifMpls = iface.getAugmentation(IfMpls.class);
+                LOG.trace("Mpls: {}",ifMpls);
+                // TODO: TBD
+            }
+        }
+        return listActionInfo;
+
+    }
+
+    private NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
+        return new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
+    }
+
+    private Long getPortNumForInterface(Interface iface) {
+        try {
+            NodeConnector port = getNodeConnectorFromDataStore(iface);
+            FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
+            return ofPort.getPortNumber().getUint32();
+        } catch (Exception e) {
+            LOG.error("OFPort for Interface {} not found", iface.getName());
+        }
+        return null;
     }
 
 }
index 8127e92888450950f1d0e68faf26b49ccfe86400..9a04dae55def58f0854b132e4962ee58b194b285 100644 (file)
@@ -7,12 +7,22 @@
  */
 package org.opendaylight.vpnservice.interfacemgr;
 
+import java.math.BigInteger;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 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.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
 
 public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable, IInterfaceManager {
 
@@ -20,19 +30,37 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
 
     private InterfaceManager interfaceManager;
     private IfmNodeConnectorListener ifmNcListener;
+    private IdManager idManager;
 
     @Override
     public void onSessionInitiated(ProviderContext session) {
         LOG.info("InterfacemgrProvider Session Initiated");
         try {
             final  DataBroker dataBroker = session.getSALService(DataBroker.class);
-            interfaceManager = new InterfaceManager(dataBroker);
+            idManager = new IdManager(dataBroker);
+            interfaceManager = new InterfaceManager(dataBroker, idManager);
             ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager);
+            createIdPool();
         } catch (Exception e) {
             LOG.error("Error initializing services", e);
         }
-        //TODO: Make this debug
-        LOG.info("Interfacemgr services initiated");
+    }
+
+    private void createIdPool() {
+        CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
+            .setPoolName(IfmConstants.IFM_IDPOOL_NAME)
+            .setIdStart(IfmConstants.IFM_IDPOOL_START)
+            .setPoolSize(new BigInteger(IfmConstants.IFM_IDPOOL_SIZE))
+            .build();
+        //TODO: Error handling
+        Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
+        try {
+            if ((result != null) && (result.get().isSuccessful())) {
+                LOG.debug("Created IdPool for InterfaceMgr");
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Failed to create idPool for InterfaceMgr",e);
+        }
     }
 
     @Override
@@ -43,7 +71,27 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
     }
 
     @Override
-    public void testApi() {
-        LOG.debug("Testing interface mgr api");
+    public Long getPortForInterface(String ifName) {
+        return interfaceManager.getPortForInterface(ifName);
+    }
+
+    @Override
+    public long getDpnForInterface(String ifName) {
+        return interfaceManager.getDpnForInterface(ifName);
+    }
+
+    @Override
+    public String getEndpointIpForDpn(long dpnId) {
+        return interfaceManager.getEndpointIpForDpn(dpnId);
+    }
+
+    @Override
+    public List<MatchInfo> getInterfaceIngressRule(String ifName) {
+        return interfaceManager.getInterfaceIngressRule(ifName);
+    }
+
+    @Override
+    public List<ActionInfo> getInterfaceEgressActions(String ifName) {
+        return interfaceManager.getInterfaceEgressActions(ifName);
     }
-}
\ No newline at end of file
+}
diff --git a/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/IfmUtilTest.java b/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/IfmUtilTest.java
new file mode 100644 (file)
index 0000000..74e11df
--- /dev/null
@@ -0,0 +1,31 @@
+package org.opendaylight.vpnservice.interfacemgr.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+
+public class IfmUtilTest {
+
+    @Mock NodeConnectorId ncId;
+    MockDataChangedEvent event;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testDpnConversions() {
+        String NodeId = IfmUtil.buildDpnNodeId(101L).getValue();
+        assertEquals("openflow:101", NodeId);
+        when(ncId.getValue()).thenReturn("openflow:101:11");
+        assertEquals("101",IfmUtil.getDpnFromNodeConnectorId(ncId));
+    }
+
+}
diff --git a/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/InterfaceManagerTest.java b/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/InterfaceManagerTest.java
new file mode 100644 (file)
index 0000000..1cae176
--- /dev/null
@@ -0,0 +1,209 @@
+package org.opendaylight.vpnservice.interfacemgr.test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.InterfaceManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIdsBuilder;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@RunWith(MockitoJUnitRunner.class)
+public class InterfaceManagerTest {
+
+    private String ifName = "dpn1-if0";
+    Map<InstanceIdentifier<?>,DataObject> written = new HashMap<>();
+    Map<InstanceIdentifier<?>,DataObject> updated = new HashMap<>();
+    Set<InstanceIdentifier<?>> removed = new HashSet<>();
+
+    @Mock DataBroker dataBroker;
+    @Mock IdManager idManager;
+    @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
+    @Mock ReadOnlyTransaction mockReadTx;
+    @Mock WriteTransaction mockWriteTx;
+
+    MockDataChangedEvent dataChangeEvent;
+    InterfaceManager imgr;
+
+    NodeConnectorId ncId;
+    NodeConnector nc;
+    Interface interf;
+    InstanceIdentifier<Interface> ifIdent;
+    InstanceIdentifier<NodeConnector> ncIdent;
+    InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifsIdent;
+    org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
+    InstanceIdentifier<IdPool> poolIdent;
+
+    @Before
+    public void setUp() throws Exception {
+        when(dataBroker.registerDataChangeListener(
+                any(LogicalDatastoreType.class),
+                any(InstanceIdentifier.class),
+                any(DataChangeListener.class),
+                any(DataChangeScope.class)))
+                .thenReturn(dataChangeListenerRegistration);
+        dataChangeEvent = new MockDataChangedEvent();
+        imgr = new InterfaceManager(dataBroker, idManager) {
+            protected <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+                            InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+                /*
+                 * Do nothing for now. Ideally we should capture this information
+                 * and use it to verify results.
+                 */
+                written.put(path, data);
+            }
+            protected <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
+                            InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+                updated.put(path, data);
+            }
+
+            protected <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
+                            InstanceIdentifier<T> path, FutureCallback<Void> callback) {
+                removed.add(path);
+            }
+
+        };
+        setupMocks();
+    }
+
+    private void setupMocks() {
+        ncId = new NodeConnectorId("openflow:10:111");
+        nc = buildNodeConnector(ncId);
+        interf = buildInterface(ifName, "Test Interface1", true, L2vlan.class, ncId);
+        ifIdent = IfmUtil.buildId(ifName);
+        ncIdent = getNcIdent("openflow:10",ncId);
+        ifsIdent = IfmUtil.buildStateInterfaceId(interf.getName());
+        stateIface = buildStateInterface(ifName);
+        poolIdent = IfmUtil.getPoolId("interfaces");
+
+        // Setup mocks
+        when(dataBroker.newReadOnlyTransaction()).thenReturn(mockReadTx);
+        when(dataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTx);
+    }
+
+    @Test
+    public void testAdd() {
+        Optional<Interface> expected = Optional.of(interf);
+        Optional<NodeConnector> expectedNc = Optional.of(nc);
+        doReturn(Futures.immediateCheckedFuture(expected)).when(mockReadTx).read(
+                        LogicalDatastoreType.CONFIGURATION, ifIdent);
+        doReturn(Futures.immediateCheckedFuture(expectedNc)).when(mockReadTx).read(
+                        LogicalDatastoreType.OPERATIONAL, ncIdent);
+        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(
+                        LogicalDatastoreType.OPERATIONAL, ifsIdent);
+        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(
+                        LogicalDatastoreType.OPERATIONAL, poolIdent);
+
+        dataChangeEvent.created.put(IfmUtil.buildId(ifName), interf);
+        imgr.onDataChanged(dataChangeEvent);
+        //Add some verifications
+        assertEquals(1,written.size());
+        assertEquals(0,updated.size());
+        assertEquals(0, removed.size());
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface writtenIface =
+                        (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface)written.get(ifsIdent);
+        assertEquals(stateIface.getKey(), writtenIface.getKey());
+        assertEquals(65536, writtenIface.getIfIndex().intValue());
+        assertEquals(OperStatus.Up, writtenIface.getOperStatus());
+    }
+
+    @Test
+    public void testUpdate() {
+        Optional<Interface> expected = Optional.of(interf);
+        Optional<NodeConnector> expectedNc = Optional.of(nc);
+        Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> expectedStateIf = Optional.of(stateIface);
+        doReturn(Futures.immediateCheckedFuture(expected)).when(mockReadTx).read(
+                        LogicalDatastoreType.CONFIGURATION, ifIdent);
+        doReturn(Futures.immediateCheckedFuture(expectedNc)).when(mockReadTx).read(
+                        LogicalDatastoreType.OPERATIONAL, ncIdent);
+        doReturn(Futures.immediateCheckedFuture(expectedStateIf)).when(mockReadTx).read(
+                        LogicalDatastoreType.OPERATIONAL, ifsIdent);
+        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(
+                        LogicalDatastoreType.OPERATIONAL, poolIdent);
+        dataChangeEvent.original.put(IfmUtil.buildId(ifName), interf);
+        dataChangeEvent.updated.put(IfmUtil.buildId(ifName), interf);
+        imgr.onDataChanged(dataChangeEvent);
+        //Add some verifications
+
+        assertEquals(0,written.size());
+        assertEquals(1,updated.size());
+        assertEquals(0, removed.size());
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface updatedIface =
+                        (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface)updated.get(ifsIdent);
+        assertNotEquals(stateIface.getKey(),updatedIface.getKey());
+        assertNull(updatedIface.getIfIndex());
+        assertEquals(OperStatus.Up, updatedIface.getOperStatus());
+    }
+
+    private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface buildStateInterface(
+                    String ifName) {
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder =
+                        new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
+        ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
+        return ifaceBuilder.build();
+    }
+
+    private InstanceIdentifier<NodeConnector> getNcIdent(String nodeKey, NodeConnectorId ncId) {
+        return InstanceIdentifier.builder(Nodes.class)
+                        .child(Node.class, new NodeKey(new NodeId(nodeKey)))
+                        .child(NodeConnector.class, new NodeConnectorKey(ncId))
+                        .build();
+    }
+
+    private Interface buildInterface(String ifName, String desc, boolean enabled, Class<? extends InterfaceType> ifType, NodeConnectorId ncId) {
+        InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
+                        .setDescription(desc).setEnabled(enabled).setType(ifType);
+
+        BaseIds baseId = new BaseIdsBuilder().setOfPortId(ncId).build();
+        builder.addAugmentation(BaseIds.class, baseId);
+        return builder.build();
+    }
+
+    private NodeConnector buildNodeConnector(NodeConnectorId ncId) {
+        NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder()
+                        .setId(ncId)
+                        .setKey(new NodeConnectorKey(ncId));
+        return ncBuilder.build();
+    }
+
+}
diff --git a/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/MockDataChangedEvent.java b/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/MockDataChangedEvent.java
new file mode 100644 (file)
index 0000000..3c95c90
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.vpnservice.interfacemgr.test;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+class MockDataChangedEvent implements AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> {
+  Map<InstanceIdentifier<?>,DataObject> created = new HashMap<>();
+  Map<InstanceIdentifier<?>,DataObject> updated = new HashMap<>();
+  Map<InstanceIdentifier<?>,DataObject> original = new HashMap<>();
+  Set<InstanceIdentifier<?>> removed = new HashSet<>();
+
+  @Override
+  public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
+      return created;
+  }
+
+  @Override
+  public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
+      return updated;
+  }
+
+  @Override
+  public Set<InstanceIdentifier<?>> getRemovedPaths() {
+      return removed;
+  }
+
+  @Override
+  public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
+      return original;
+  }
+
+  @Override
+  public DataObject getOriginalSubtree() {
+      throw new UnsupportedOperationException("Not implemented by mock");
+  }
+
+  @Override
+  public DataObject getUpdatedSubtree() {
+      throw new UnsupportedOperationException("Not implemented by mock");
+  }
+}
index 049d293fa35dc1de584ffd2061c521772324d19a..2101d2ad4d4d58648e75912a822585b01765691c 100644 (file)
             <artifactId>model-flow-service</artifactId>
             <version>0.1.0-SNAPSHOT</version>
         </dependency>
-        <!--<dependency>
-            <groupId>org.opendaylight.controller.model</groupId>
-            <artifactId>model-flow-management</artifactId>
-        </dependency>-->
-        <!-- Commenting due to missing constraint error
-        <dependency>
-            <groupId>org.opendaylight.controller.model</groupId>
-            <artifactId>model-inventory</artifactId>
-        </dependency>
-        -->
-        <!--<dependency>
-            <groupId>org.eclipse.xtend</groupId>
-            <artifactId>org.eclipse.xtend.lib</artifactId>
-            <version>${xtend.version}</version>
-        </dependency>-->
-        <!--<dependency>
-            <groupId>equinoxSDK381</groupId>
-            <artifactId>org.eclipse.osgi</artifactId>
-        </dependency>-->
-        <dependency>
+         <!--  TEST Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+       <dependency>
+       <groupId>org.mockito</groupId>
+       <artifactId>mockito-all</artifactId>
+       <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.powermock</groupId>
+        <artifactId>powermock-module-junit4</artifactId>
+        <version>1.5.2</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.powermock</groupId>
+        <artifactId>powermock-api-mockito</artifactId>
+        <version>1.5.2</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-broker-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-broker-impl</artifactId>
+      <version>${mdsal.version}</version>
+      <scope>test</scope>
+      <type>test-jar</type>
+    </dependency>
+     <dependency>
             <groupId>commons-lang</groupId>
             <artifactId>commons-lang</artifactId>
         </dependency>
@@ -59,7 +74,7 @@
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
-        <dependency>
+     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>mdsalutil-api</artifactId>
       <version>${project.version}</version>
                     <manifestLocation>${project.basedir}/META-INF</manifestLocation>
                 </configuration>
             </plugin>
-            <!--<plugin>
-                <groupId>org.eclipse.xtend</groupId>
-                <artifactId>xtend-maven-plugin</artifactId>
-                <version>${xtend.version}</version>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>compile</goal>
-                        </goals>
-                        <configuration>
-                            <outputDirectory>${basedir}/src/main/xtend-gen</outputDirectory>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>-->
             <plugin>
                 <artifactId>maven-clean-plugin</artifactId>
                 <version>${maven.clean.plugin.version}</version>
                     </filesets>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <argLine>-XX:-UseSplitVerifier</argLine>
+                </configuration>
+            </plugin>
+            
         </plugins>
     </build>
 </project>
index 00119d417cc3edd1fc8f89654cad9bed3203c760..7a3ec91fa8f1eb2db55c143f7b3841686874530e 100644 (file)
@@ -11,38 +11,24 @@ package org.opendaylight.vpnservice.mdsalutil.internal;
 
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-//import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
 import org.opendaylight.vpnservice.mdsalutil.ActionType;
-import org.opendaylight.vpnservice.mdsalutil.BucketInfo;
 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
 import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
-import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
-import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
-import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
-import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
-import org.opendaylight.vpnservice.mdsalutil.InstructionType;
 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
-// Missing constraint
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
@@ -50,7 +36,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
@@ -59,113 +44,126 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 
-public class MDSALManager implements IMdsalApiManager,BindingAwareConsumer, AutoCloseable {
+public class MDSALManager implements IMdsalApiManager, AutoCloseable {
 
     private static final Logger s_logger = LoggerFactory.getLogger(MDSALManager.class);
 
     private DataBroker m_dataBroker;
 
-    private ConsumerContext m_consumerContext = null;
-       
     private PacketProcessingService m_packetProcessingService;
-      
+
     private final AtomicInteger m_atomicInteger = new AtomicInteger();
 
     //TODO : IF ID MANAGER IS RQD
-    
-    @Override
-    public void onSessionInitialized(ConsumerContext session) {
-       
-       s_logger.info( " Session Initiated for MD SAL Manager") ;
-       
-        m_consumerContext = session;
-        
-       m_dataBroker = session.getSALService(DataBroker.class);
-              
-        // TODO - Verify this.
-       m_packetProcessingService = session.getRpcService(PacketProcessingService.class);
-            
+
+    /**
+     * Writes the flows and Groups to the MD SAL DataStore
+     * which will be sent to the openflowplugin for installing flows/groups on the switch.
+     * Other modules of VPN service that wants to install flows / groups on the switch
+     * uses this utility
+     *
+     * @param db - dataBroker reference
+     * @param PacketProcessingService for sending the packet outs
+     */
+    public MDSALManager(final DataBroker db, PacketProcessingService pktProcService) {
+        m_dataBroker = db;
+        m_packetProcessingService = pktProcService;
+
     }
-    
-    
+
+
     @Override
     public void close() throws Exception {
-       s_logger.info("MDSAL Manager Closed");
+        s_logger.info("MDSAL Manager Closed");
     }
-    
+
     @Override
     public void printTest() {
-       
-       s_logger.info(" INTER MODULECOMMUNICATION IS WORKING!!!!");
+
+        s_logger.info(" INTER MODULECOMMUNICATION IS WORKING!!!!");
     }
     @Override
     public void installFlow(FlowEntity flowEntity) {
+
         try {
-            s_logger.info("within installFlowX {}", flowEntity.getDpnId());
-            System.out.println( " Insie installFlow -- ") ;
+            s_logger.info("within installFlow {}", flowEntity.getDpnId());
 
             if (flowEntity.getCookie() == null) {
-                s_logger.info("Helium_sync: Cookie is null");
+              //  s_logger.info("Helium_sync: Cookie is null");
                 flowEntity.setCookie(new BigInteger("0110000", 16));
             }
 
-            Flow flow = flowEntity.getFlowBuilder().build();
+            FlowKey flowKey = new FlowKey( new FlowId(flowEntity.getFlowId()) );
+
+            FlowBuilder flowbld = flowEntity.getFlowBuilder();
+
+            Flow flow = flowbld.build() ;
 
             Node nodeDpn = buildDpnNode(flowEntity.getDpnId());
             InstanceIdentifier<Node> nodeInstanceId = InstanceIdentifier.builder(Nodes.class)
                     .child(Node.class, nodeDpn.getKey()).build();
+
             InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
                     .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
-                    .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class, flow.getKey()).build();
+                    .child(Table.class, new TableKey(flowEntity.getTableId())).child(Flow.class,flowKey).build();
 
             String sTransactionUri = generateTransactionUri();
-            // Helium Way
-                       
+
+            TableKey tableKey = new TableKey(flowEntity.getTableId() );
+            InstanceIdentifier<Table> tableInstanceId = InstanceIdentifier.create(Nodes.class).child(Node.class, nodeDpn.getKey())
+                    .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+            Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+
             WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
-            
-            modification.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, nodeDpn, true);
-            
-            modification.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow);
-            
-            ListenableFuture<RpcResult<TransactionStatus>> commitFuture = modification.commit();
-            
-            Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
+
+            //CHECK IF RQD
+           // modification.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, nodeDpn, true);
+
+
+            modification.put(LogicalDatastoreType.CONFIGURATION, tableInstanceId, table);
+
+            modification.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flowbld.build());
+
+            CheckedFuture<Void,TransactionCommitFailedException> submitFuture  = modification.submit();
+
+            Futures.addCallback(submitFuture, new FutureCallback<Void>() {
+
                 @Override
-                public void onSuccess(RpcResult<TransactionStatus> result) {
-                       if( result.getResult() != TransactionStatus.COMMITED ) {
-                               s_logger.debug("Failed to commit the Flow Data " + result.getErrors());
-                       
-                    }
-                
+                public void onSuccess(final Void result) {
+                    // Commited successfully
+                    s_logger.info( "Install Flow -- Committedsuccessfully ") ;
                 }
 
                 @Override
-                public void onFailure(Throwable throwable) {
-                       s_logger.error(throwable.getMessage(), throwable);
-                    s_logger.debug(String.format("Status of Flow Data Loaded Transaction : failure. Reason : %s", throwable));
-                    
+                public void onFailure(final Throwable t) {
+                    // Transaction failed
+
+                    if(t instanceof OptimisticLockFailedException) {
+                        // Failed because of concurrent transaction modifying same data
+                        s_logger.error( "Install Flow -- Failed because of concurrent transaction modifying same data ") ;
+                    } else {
+                       // Some other type of TransactionCommitFailedException
+                        s_logger.error( "Install Flow -- Some other type of TransactionCommitFailedException " + t) ;
+                    }
                 }
             });
         } catch (Exception e) {
             s_logger.error("Could not install flow: {}, exception: {}", flowEntity, e.getMessage());
         }
-
     }
+
     @Override
     public void installGroup(GroupEntity groupEntity) {
         try {
@@ -178,34 +176,35 @@ public class MDSALManager implements IMdsalApiManager,BindingAwareConsumer, Auto
                     .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
                     .child(Group.class, new GroupKey(new GroupId(groupEntity.getGroupId()))).build();
 
-                       
-         // Helium
             WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
-            
-            modification.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, nodeDpn);
+
+            //CHECK IF RQD
+         //   modification.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, nodeDpn);
             modification.put(LogicalDatastoreType.CONFIGURATION, groupInstanceId, group);
-                              
-            ListenableFuture<RpcResult<TransactionStatus>> commitFuture = modification.commit();
-            
-            Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
+
+            CheckedFuture<Void,TransactionCommitFailedException> submitFuture  = modification.submit();
+
+            Futures.addCallback(submitFuture, new FutureCallback<Void>() {
                 @Override
-                public void onSuccess(RpcResult<TransactionStatus> result) {
-                       if( result.getResult() != TransactionStatus.COMMITED ) {
-                               s_logger.debug("Failed to commit the group Data " + result.getErrors());
-                       
-                    }
-                
+                public void onSuccess(final Void result) {
+                    // Commited successfully
+                    s_logger.info( "Install Group -- Committedsuccessfully ") ;
                 }
 
                 @Override
-                public void onFailure(Throwable throwable) {
-                       s_logger.error(throwable.getMessage(), throwable);
-                    s_logger.debug(String.format("Status of Group Data Loaded Transaction : failure. Reason : %s", throwable));
-                    
+                public void onFailure(final Throwable t) {
+                    // Transaction failed
+
+                    if(t instanceof OptimisticLockFailedException) {
+                        // Failed because of concurrent transaction modifying same data
+                        s_logger.error( "Install Group -- Failed because of concurrent transaction modifying same data ") ;
+                    } else {
+                       // Some other type of TransactionCommitFailedException
+                        s_logger.error( "Install Group -- Some other type of TransactionCommitFailedException " + t) ;
+                    }
                 }
-            });
-                        
-        } catch (Exception e) {
+             });
+           } catch (Exception e) {
             s_logger.error("Could not install Group: {}, exception: {}", groupEntity, e.getMessage());
             throw e;
         }
@@ -224,24 +223,27 @@ public class MDSALManager implements IMdsalApiManager,BindingAwareConsumer, Auto
                 WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
                 modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId );
 
-                ListenableFuture<RpcResult<TransactionStatus>> commitFuture = modification.commit();
-                
-                Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
+                CheckedFuture<Void,TransactionCommitFailedException> submitFuture  = modification.submit();
+
+                Futures.addCallback(submitFuture, new FutureCallback<Void>() {
                     @Override
-                    public void onSuccess(RpcResult<TransactionStatus> result) {
-                       if( result.getResult() != TransactionStatus.COMMITED ) {
-                               s_logger.debug("Failed to remove the Flow Data " + result.getErrors());
-                               
-                        }
-                    
+                    public void onSuccess(final Void result) {
+                        // Commited successfully
+                        s_logger.info( "Delete Flow -- Committedsuccessfully ") ;
                     }
 
                     @Override
-                    public void onFailure(Throwable throwable) {
-                       s_logger.error(throwable.getMessage(), throwable);
-                        s_logger.debug(String.format("Status of Flow Data remove Transaction : failure. Reason : %s", throwable));
-                        
+                    public void onFailure(final Throwable t) {
+                        // Transaction failed
+                        if(t instanceof OptimisticLockFailedException) {
+                            // Failed because of concurrent transaction modifying same data
+                            s_logger.error( "Delete Flow -- Failed because of concurrent transaction modifying same data ") ;
+                        } else {
+                           // Some other type of TransactionCommitFailedException
+                            s_logger.error( "Delete Flow -- Some other type of TransactionCommitFailedException " + t) ;
+                        }
                     }
+
                 });
         } catch (Exception e) {
             s_logger.error("Could not remove Flow: {}, exception: {}", flowEntity, e.getMessage());
@@ -256,33 +258,31 @@ public class MDSALManager implements IMdsalApiManager,BindingAwareConsumer, Auto
                     .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
                     .child(Group.class, new GroupKey(new GroupId(groupEntity.getGroupId()))).build();
 
-
             WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
-            
+
             modification.delete(LogicalDatastoreType.CONFIGURATION,groupInstanceId );
 
-            ListenableFuture<RpcResult<TransactionStatus>> commitFuture = modification.commit();
-            
-            Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
+            CheckedFuture<Void,TransactionCommitFailedException> submitFuture  = modification.submit();
+
+            Futures.addCallback(submitFuture, new FutureCallback<Void>() {
                 @Override
-                public void onSuccess(RpcResult<TransactionStatus> result) {
-                       if( result.getResult() != TransactionStatus.COMMITED ) {
-                               s_logger.debug("Failed to remove the group Data " + result.getErrors());
-                       
-                    }
-                
+                public void onSuccess(final Void result) {
+                    // Commited successfully
+                    s_logger.info( "Install Group -- Committedsuccessfully ") ;
                 }
 
                 @Override
-                public void onFailure(Throwable throwable) {
-                       s_logger.error(throwable.getMessage(), throwable);
-                    s_logger.debug(String.format("Status of group Data remove Transaction : failure. Reason : %s", throwable));
-                    
+                public void onFailure(final Throwable t) {
+                    // Transaction failed
+                    if(t instanceof OptimisticLockFailedException) {
+                        // Failed because of concurrent transaction modifying same data
+                        s_logger.error( "Install Group -- Failed because of concurrent transaction modifying same data ") ;
+                    } else {
+                       // Some other type of TransactionCommitFailedException
+                        s_logger.error( "Install Group -- Some other type of TransactionCommitFailedException " + t) ;
+                    }
                 }
             });
-
-                
-
         } catch (Exception e) {
             s_logger.error("Could not remove Group: {}, exception: {}", groupEntity, e.getMessage());
         }
@@ -308,7 +308,7 @@ public class MDSALManager implements IMdsalApiManager,BindingAwareConsumer, Auto
                 + Long.toString(nTransactionId);
     }
 */
-    
+
     @Override
     public void sendPacketOut(long lDpnId, int groupId, byte[] payload) {
 
@@ -372,4 +372,5 @@ public class MDSALManager implements IMdsalApiManager,BindingAwareConsumer, Auto
 
         return nodeDpn;
     }
+
 }
diff --git a/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALUtilProvider.java b/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALUtilProvider.java
new file mode 100644 (file)
index 0000000..4ef0749
--- /dev/null
@@ -0,0 +1,40 @@
+package org.opendaylight.vpnservice.mdsalutil.internal;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MDSALUtilProvider implements BindingAwareConsumer, AutoCloseable {
+
+    private static final Logger s_logger = LoggerFactory.getLogger(MDSALUtilProvider.class);
+    private MDSALManager mdSalMgr;
+
+    @Override
+    public void onSessionInitialized(ConsumerContext session) {
+
+        s_logger.info( " Session Initiated for MD SAL Util Provider") ;
+
+        try {
+            final DataBroker dataBroker;
+            final PacketProcessingService packetProcessingService;
+            dataBroker = session.getSALService(DataBroker.class);
+             // TODO - Verify this.
+             packetProcessingService = session.getRpcService(PacketProcessingService.class);
+             mdSalMgr = new MDSALManager( dataBroker, packetProcessingService) ;
+        }catch( Exception e) {
+            s_logger.error( "Error initializing MD SAL Util Services " + e );
+        }
+    }
+
+
+    @Override
+    public void close() throws Exception {
+        mdSalMgr.close();
+        s_logger.info("MDSAL Manager Closed");
+    }
+
+}
index ab2776d75fd8ab197250a5197ede492e81234a13..473d96254413bc7305eaaf3a4ec2122ecefd7a13 100644 (file)
@@ -1,6 +1,6 @@
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsalutil.impl.rev150403;
 
-import org.opendaylight.vpnservice.mdsalutil.internal.MDSALManager;
+import org.opendaylight.vpnservice.mdsalutil.internal.MDSALUtilProvider;
 
 public class MdsaluttilimplModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsalutil.impl.rev150403.AbstractMdsaluttilimplModule {
     public MdsaluttilimplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -21,11 +21,11 @@ public class MdsaluttilimplModule extends org.opendaylight.yang.gen.v1.urn.opend
        // TODO:implement
 //      Can use the following to get a handle to data broker
        
-        MDSALManager mdsalUtilMgr = new MDSALManager();
-        getBrokerDependency().registerConsumer(mdsalUtilMgr);
+       MDSALUtilProvider mdsalUtilProvider = new MDSALUtilProvider();
+        getBrokerDependency().registerConsumer(mdsalUtilProvider);
        //DataBroker dataBrokerService = getDataBrokerDependency();
        //mdsalUtilMgr.setDataProvider(dataBrokerService);
-        return mdsalUtilMgr ;
+        return mdsalUtilProvider ;
       }
 
 }
diff --git a/mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/AbstractMockForwardingRulesManager.java b/mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/AbstractMockForwardingRulesManager.java
new file mode 100644 (file)
index 0000000..1bffa91
--- /dev/null
@@ -0,0 +1,25 @@
+package org.opendaylight.vpnservice.test;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractMockForwardingRulesManager<D extends DataObject> implements DataTreeChangeListener<D> {
+
+    public AbstractMockForwardingRulesManager() {
+        // Do Nothing
+    }
+
+
+    public void onDataTreeChanged(Collection<DataTreeModification<D>> changes) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/MdSalUtilTest.java b/mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/MdSalUtilTest.java
new file mode 100644 (file)
index 0000000..8c804b8
--- /dev/null
@@ -0,0 +1,230 @@
+package org.opendaylight.vpnservice.test;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import org.mockito.runners.MockitoJUnitRunner;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionType;
+import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
+import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
+import org.opendaylight.vpnservice.mdsalutil.BucketInfo;
+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.internal.MDSALManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(MockitoJUnitRunner.class)
+//@RunWith(PowerMockRunner.class)
+@PrepareForTest(MDSALUtil.class)
+public class MdSalUtilTest extends AbstractDataBrokerTest {
+     DataBroker dataBroker;
+     @Mock PacketProcessingService ppS ;
+     MDSALManager mdSalMgr = null ;
+     MockFlowForwarder flowFwder = null ;
+     MockGroupForwarder grpFwder = null ;
+
+     @Before
+        public void setUp() throws Exception {
+            dataBroker = getDataBroker() ;
+            mdSalMgr = new MDSALManager( dataBroker, ppS);
+            flowFwder = new MockFlowForwarder( dataBroker );
+            grpFwder = new MockGroupForwarder( dataBroker ) ;
+
+            PowerMockito.mockStatic(MDSALUtil.class) ;
+
+            NodeKey s1Key = new NodeKey(new NodeId("openflow:1"));
+            addFlowCapableNode(s1Key);
+        }
+
+        @Test
+        public void testInstallFlow() {
+            String dpnId = "openflow:1";
+            String tableId1 = "12";
+
+            //Install Flow 1
+            FlowEntity testFlow1 = createFlowEntity(dpnId, tableId1) ;
+            mdSalMgr.installFlow(testFlow1);
+            assertEquals(1, flowFwder.getDataChgCount());
+
+            // Install FLow 2
+            String tableId2 = "13" ;
+             FlowEntity testFlow2 = createFlowEntity(dpnId, tableId2) ;
+             mdSalMgr.installFlow(testFlow2);
+             assertEquals(2, flowFwder.getDataChgCount());
+        }
+
+        @Test
+        public void testRemoveFlow() {
+            String dpnId = "openflow:1";
+            String tableId = "13" ;
+            FlowEntity testFlow = createFlowEntity(dpnId, tableId) ;
+
+            // To test RemoveFlow add and then delete Flows
+            mdSalMgr.installFlow(testFlow) ;
+            assertEquals(1, flowFwder.getDataChgCount());
+            mdSalMgr.removeFlow(testFlow);
+            assertEquals(0, flowFwder.getDataChgCount());
+        }
+
+        @Test
+        public void testInstallGroup() {
+            // Install Group 1
+            String Nodeid = "1";
+            String inport = "2" ;
+            int vlanid = 100 ;
+            GroupEntity grpEntity1 = createGroupEntity(Nodeid, inport, vlanid) ;
+
+             mdSalMgr.installGroup(grpEntity1);
+             assertEquals(1, grpFwder.getDataChgCount());
+
+             // Install Group 2
+               Nodeid = "1";
+                inport = "3" ;
+                vlanid = 100 ;
+                GroupEntity grpEntity2 = createGroupEntity(Nodeid, inport, vlanid) ;
+                mdSalMgr.installGroup(grpEntity2);
+                assertEquals(2, grpFwder.getDataChgCount());
+        }
+
+        @Test
+        public void testRemoveGroup() {
+            String Nodeid = "1";
+            String inport = "2" ;
+            int vlanid = 100 ;
+            GroupEntity grpEntity = createGroupEntity(Nodeid, inport, vlanid) ;
+            // To test RemoveGroup  add and then delete Group
+            mdSalMgr.installGroup(grpEntity);
+            assertEquals(1, grpFwder.getDataChgCount());
+            mdSalMgr.removeGroup(grpEntity);
+            assertEquals(0, grpFwder.getDataChgCount());
+        }
+
+        public void addFlowCapableNode(NodeKey nodeKey) throws ExecutionException, InterruptedException {
+            Nodes nodes = new NodesBuilder().setNode(Collections.<Node>emptyList()).build();
+            InstanceIdentifier<Node> flowNodeIdentifier = InstanceIdentifier.create(Nodes.class)
+                    .child(Node.class, nodeKey);
+
+            FlowCapableNodeBuilder fcnBuilder = new FlowCapableNodeBuilder();
+            NodeBuilder nodeBuilder = new NodeBuilder();
+            nodeBuilder.setKey(nodeKey);
+            nodeBuilder.addAugmentation(FlowCapableNode.class, fcnBuilder.build());
+
+            WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+            writeTx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodes);
+            writeTx.put(LogicalDatastoreType.OPERATIONAL, flowNodeIdentifier, nodeBuilder.build());
+            writeTx.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Nodes.class), nodes);
+            writeTx.put(LogicalDatastoreType.CONFIGURATION, flowNodeIdentifier, nodeBuilder.build());
+            assertCommit(writeTx.submit());
+        }
+
+         // Methods to test the install Flow and Group
+
+        public FlowEntity createFlowEntity(String dpnId, String tableId) {
+
+            long dpId;
+            int SERVICE_ID = 0;
+            FlowEntity terminatingServiceTableFlowEntity = null;
+
+            List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+            listActionInfo.add(new ActionInfo(ActionType.punt_to_controller,
+                    new String[] {}));
+
+            try {
+                dpId = Long.parseLong(dpnId.split(":")[1]);
+
+                List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+                BigInteger COOKIE = new BigInteger("9000000", 16);
+
+                short s_tableId = Short.parseShort(tableId) ;
+
+                mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
+                        new BigInteger("0000000000000000", 16) }));
+
+                List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+                mkInstructions.add(new InstructionInfo(InstructionType.write_actions,
+                        listActionInfo));
+
+                terminatingServiceTableFlowEntity = MDSALUtil
+                        .buildFlowEntity(
+                                dpId,
+                                s_tableId,
+                                getFlowRef(s_tableId,
+                                        SERVICE_ID), 5, "Terminating Service Flow Entry: " + SERVICE_ID,
+                                0, 0, COOKIE
+                                        .add(BigInteger.valueOf(SERVICE_ID)),
+                                        null, null);
+                } catch (Exception e) {
+                    //throw new Exception(e) ;
+              }
+
+            return terminatingServiceTableFlowEntity;
+        }
+
+        private String getFlowRef(short termSvcTable, int svcId) {
+            return new StringBuffer().append(termSvcTable).append(svcId).toString();
+        }
+
+        public GroupEntity createGroupEntity(String Nodeid, String inport, int vlanid) {
+            GroupEntity groupEntity;
+            long id = getUniqueValue(Nodeid, inport);
+            List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+            List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+            if (vlanid > 0) {
+                listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] { null }));
+                listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid, new String[] { String.valueOf(vlanid) }));
+            }
+            listActionInfo.add(new ActionInfo(ActionType.output, new String[] { inport, "65535" }));
+            listBucketInfo.add(new BucketInfo(listActionInfo));
+
+            String groupName = "Test Group";
+            groupEntity = MDSALUtil.buildGroupEntity(Long.valueOf(Nodeid), id, groupName, GroupTypes.GroupIndirect,
+                    listBucketInfo);
+
+            return groupEntity;
+        }
+
+        private static long getUniqueValue(String nodeId, String inport) {
+
+            Long nodeIdL = Long.valueOf(nodeId);
+            Long inportL = Long.valueOf(inport);
+                long sd_set;
+                sd_set = nodeIdL * 10 + inportL;
+
+                return sd_set;
+    }
+
+}
diff --git a/mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/MockFlowForwarder.java b/mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/MockFlowForwarder.java
new file mode 100644 (file)
index 0000000..56ba800
--- /dev/null
@@ -0,0 +1,72 @@
+package org.opendaylight.vpnservice.test;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class MockFlowForwarder extends AbstractMockForwardingRulesManager<Flow> {
+
+    private int nFlowCount = 0;
+
+    private ListenerRegistration<MockFlowForwarder> listenerRegistration;
+
+    public MockFlowForwarder( final DataBroker db) {
+        super() ;
+        registerListener(db) ;
+    }
+
+    private void registerListener(final DataBroker db) {
+        final DataTreeIdentifier<Flow> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getWildCardPath());
+        try {
+            listenerRegistration = db.registerDataTreeChangeListener(treeId, MockFlowForwarder.this);
+        } catch (final Exception e) {
+            throw new IllegalStateException("FlowForwarder registration Listener fail! System needs restart.", e);
+        }
+    }
+
+    private InstanceIdentifier<Flow> getWildCardPath() {
+            return InstanceIdentifier.create(Nodes.class).child(Node.class)
+                    .augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class);
+     }
+
+    @Override
+    public void onDataTreeChanged(Collection<DataTreeModification<Flow>> changes) {
+        for (DataTreeModification<Flow> change : changes) {
+            final InstanceIdentifier<Flow> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<Flow> mod = change.getRootNode();
+
+                switch (mod.getModificationType()) {
+                case DELETE:
+                    nFlowCount -= 1;
+                    break;
+                case SUBTREE_MODIFIED:
+                    // CHECK IF RQD
+                    break;
+                case WRITE:
+                    if (mod.getDataBefore() == null) {
+                        nFlowCount += 1;
+                    } else {
+                        // UPDATE COUNT UNCHANGED
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
+                }
+            }
+     }
+
+    public int getDataChgCount() {
+        return nFlowCount;
+    }
+}
diff --git a/mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/MockGroupForwarder.java b/mdsalutil/mdsalutil-impl/src/test/java/org/opendaylight/vpnservice/test/MockGroupForwarder.java
new file mode 100644 (file)
index 0000000..b47deee
--- /dev/null
@@ -0,0 +1,69 @@
+package org.opendaylight.vpnservice.test;
+
+import java.util.Collection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+
+public class MockGroupForwarder extends AbstractMockForwardingRulesManager<Group>{
+
+    private int nGroupCount = 0;
+    private ListenerRegistration<MockGroupForwarder> listenerRegistration ;
+
+    public MockGroupForwarder( final DataBroker db) {
+        super() ;
+        registerListener(db) ;
+    }
+
+    private void registerListener(final DataBroker db) {
+       final DataTreeIdentifier<Group> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getWildCardPath());
+       try {
+           listenerRegistration = db.registerDataTreeChangeListener(treeId, MockGroupForwarder.this);
+       } catch (final Exception e) {
+           throw new IllegalStateException("GroupForwarder registration Listener fail! System needs restart.", e);
+       }
+    }
+
+    private InstanceIdentifier<Group> getWildCardPath() {
+        return InstanceIdentifier.create(Nodes.class).child(Node.class).
+                augmentation(FlowCapableNode.class).child(Group.class);
+    }
+
+    @Override
+    public void onDataTreeChanged(Collection<DataTreeModification<Group>> changes) {
+        for (DataTreeModification<Group> change : changes) {
+            final InstanceIdentifier<Group> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<Group> mod = change.getRootNode();
+
+                switch (mod.getModificationType()) {
+                case DELETE:
+                    nGroupCount -= 1;
+                    break;
+                case SUBTREE_MODIFIED:
+                    // CHECK IF RQD
+                    break;
+                case WRITE:
+                    if (mod.getDataBefore() == null) {
+                        nGroupCount += 1;
+                    } else {
+                        // UPDATE COUNT UNCHANGED
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
+                }
+            }
+     }
+
+    public int getDataChgCount() {
+        return nGroupCount;
+    }
+}
index 0e362dc937b5319504cccb998af7c126fc0de84c..3d52a99d2fb159371cbdf9bf8bd8bf80bf0ff486 100644 (file)
@@ -11,7 +11,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>odlparent</artifactId>
     <version>1.5.0-SNAPSHOT</version>
-       <relativePath/>
+    <relativePath/>
   </parent>
 
   <groupId>org.opendaylight.vpnservice</groupId>
index c519fe5e887246d970aa86a98d94bed8d7233c36..a6f04dd24895268fea1cb83ddf2b154ba86f0654 100644 (file)
@@ -31,11 +31,26 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>interfacemgr-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>idmanager-api</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>idmanager-impl</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>nexthopmgr-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mdsalutil-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
 
     <!-- Testing Dependencies -->
     <dependency>
index c44c0b3b0fd611eb9cef42179c5a39c19cb11206..18c12e6176a418225d97c27a43dff7b2b516fb4a 100644 (file)
@@ -11,6 +11,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <required-capabilities>
       <capability>urn:opendaylight:params:xml:ns:yang:nexthopmgr:impl?module=nexthopmgr-impl&amp;revision=2015-03-25</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: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>
 
@@ -23,6 +25,14 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
             <name>binding-osgi-broker</name>
           </broker>
+          <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 38b0d6e344dccdddf3f824e8fbcda199d9660a60..8e1a4fc2e37d7cdf0d1eeec7af8d750baa389570 100644 (file)
@@ -8,33 +8,58 @@
 package org.opendaylight.vpnservice.nexthopmgr;
 
 
-import com.google.common.base.Optional;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.Future;
+
+import com.google.common.base.Optional;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.FutureCallback;
+
+//import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.Rpcs;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 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.opendaylight.group.types.rev131018.GroupTypes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.tunnelnexthops.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.vpnnexthops.*;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionType;
+import org.opendaylight.vpnservice.mdsalutil.BucketInfo;
+import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.idmanager.IdManager;
+
+import java.util.concurrent.ExecutionException;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class NexthopManager implements L3nexthopService, AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(NexthopManager.class);
     private final DataBroker broker;
+    private IMdsalApiManager mdsalManager;
+    private IInterfaceManager interfaceManager;
+    private IdManager idManager;
 
     private static final FutureCallback<Void> DEFAULT_CALLBACK =
         new FutureCallback<Void>() {
@@ -53,44 +78,45 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
     * @param db - dataBroker reference
     */
     public NexthopManager(final DataBroker db) {
-        // create nexhhop ID pool
-      //  getIdManager.createIdPool("nextHopGroupIdPool", 10000, 100000);
         broker = db;
+        createNexthopPointerPool();
     }
 
-
     @Override
     public void close() throws Exception {
         LOG.info("NextHop Manager Closed");
     }
 
+    public void setInterfaceManager(IInterfaceManager ifManager) {
+        this.interfaceManager = ifManager;
+    }
 
-    public void createLocalNextHop(String ifName, String vpnName, String ipAddress)
-    {
-        String nhKey = new String("nexthop." + vpnName + ipAddress);
-        int groupId = 1;//getIdManager().getUniqueId("nextHopGroupIdPool", nhKey);
+    public void setMdsalManager(IMdsalApiManager mdsalManager) {
+        this.mdsalManager = mdsalManager;
+    }
 
-        long vpnId = getVpnId(vpnName);
-        VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
-        if (nexthop == null) {
+    public void setIdManager(IdManager idManager) {
+        this.idManager = idManager;
+    }
 
-         /*   List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
-            List<ActionInfo> listActionInfo = interfacemgr.getEgressGroupActions(ifName);
-            BucketInfo bucket = new BucketInfo(listActionInfo);
-            // MAC re-write??
-            listBucketInfo.add(bucket);
-            GroupEntity groupEntity = MDSALUtil.buildGroupEntity
-                (dpId, groupId, IPAddress, GroupTypes.GroupIndirect, listBucketInfo);
-            getMdsalApiManager().installGroup(groupEntity, objTransaction???);
-            */
+    private void createNexthopPointerPool() {
+        CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
+            .setPoolName("nextHopPointerPool")
+            .setIdStart(1L)
+            .setPoolSize(new BigInteger("65535"))
+            .build();
+        //TODO: Error handling
+        Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
+//            try {
+//                LOG.info("Result2: {}",result.get());
+//            } catch (InterruptedException | ExecutionException e) {
+//                // TODO Auto-generated catch block
+//                LOG.error("Error in result.get");
+//            }
 
-            //update MD-SAL DS
-            addVpnNexthopToDS(vpnId, ipAddress, groupId);
-        } else {
-            //check update
-        }
     }
 
+
     private long getVpnId(String vpnName) {
         InstanceIdentifierBuilder<VpnInstance> idBuilder = InstanceIdentifier.builder(VpnInstances.class)
                 .child(VpnInstance.class, new VpnInstanceKey(vpnName));
@@ -99,32 +125,81 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
         InstanceIdentifier<VpnInstance1> idx = id.augmentation(VpnInstance1.class);
         Optional<VpnInstance1> vpn = read(LogicalDatastoreType.CONFIGURATION, idx);
 
-        if (vpn.isPresent()) return vpn.get().getVpnId();
-        else return 0;
+        if (vpn.isPresent()) {
+            return vpn.get().getVpnId();
+        } else {
+            return 0;
+        }
     }
 
     private long getDpnId(String ifName) {
-        return 1;
+        String[] fields = ifName.split(":");
+        long dpn = Integer.parseInt(fields[1]);
+        return dpn;
     }
 
-    public void createRemoteNextHop(String ifName, String ipAddress)
-    {
+    private int createNextHopPointer(String nexthopKey) {
+        GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder()
+            .setPoolName("nextHopPointerPool").setIdKey(nexthopKey)
+            .build();
+        //TODO: Proper error handling once IdManager code is complete
+        try {
+            Future<RpcResult<GetUniqueIdOutput>> result = idManager.getUniqueId(getIdInput);
+            RpcResult<GetUniqueIdOutput> rpcResult = result.get();
+            return rpcResult.getResult().getIdValue().intValue();
+        } catch (NullPointerException | InterruptedException | ExecutionException e) {
+            LOG.trace("",e);
+        }
+        return 0;
+    }
+
+    public void createLocalNextHop(String ifName, String vpnName, String ipAddress, String macAddress) {
+        String nhKey = new String("nexthop." + vpnName + ipAddress);
+        int groupId = createNextHopPointer(nhKey);
+
+        long vpnId = getVpnId(vpnName);
+        long dpnId = interfaceManager.getDpnForInterface(ifName);
+        VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
+        if (nexthop == null) {
+            List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+            List<ActionInfo> listActionInfo = interfaceManager.getInterfaceEgressActions(ifName);
+            BucketInfo bucket = new BucketInfo(listActionInfo);
+            // MAC re-write
+            if (macAddress != null) {
+                listActionInfo.add(new ActionInfo(ActionType.set_field_eth_dest, new String[]{macAddress}));
+            } else {
+                //FIXME: Log message here.
+            }
+            listBucketInfo.add(bucket);
+            GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
+                dpnId, groupId, ipAddress, GroupTypes.GroupIndirect, listBucketInfo);
+
+            // install Group
+            mdsalManager.installGroup(groupEntity);
+
+            //update MD-SAL DS
+            addVpnNexthopToDS(vpnId, ipAddress, groupId);
+        } else {
+            //check update
+        }
+    }
+
+    public void createRemoteNextHop(String ifName, String ofPortId, String ipAddress) {
         String nhKey = new String("nexthop." + ifName + ipAddress);
-        int groupId = 1;//getIdManager().getUniqueId("nextHopGroupIdPool", nhKey);
+        int groupId = createNextHopPointer(nhKey);
 
-        long dpnId = getDpnId(ifName);
+        long dpnId = getDpnId(ofPortId);
         TunnelNexthop nexthop = getTunnelNexthop(dpnId, ipAddress);
         if (nexthop == null) {
 
-         /*   List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
-            List<ActionInfo> listActionInfo = interfacemgr.getEgressGroupActions(ifName);
+            List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+            List<ActionInfo> listActionInfo = interfaceManager.getInterfaceEgressActions(ifName);
             BucketInfo bucket = new BucketInfo(listActionInfo);
-            // MAC re-write??
+            // MAC re-write??           
             listBucketInfo.add(bucket);
-            GroupEntity groupEntity = MDSALUtil.buildGroupEntity
-                (dpId, groupId, IPAddress, GroupTypes.GroupIndirect, listBucketInfo);
-            getMdsalApiManager().installGroup(groupEntity, objTransaction???);
-            */
+            GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
+                dpnId, groupId, ipAddress, GroupTypes.GroupIndirect, listBucketInfo);
+            mdsalManager.installGroup(groupEntity);
 
             //update MD-SAL DS
             addTunnelNexthopToDS(dpnId, ipAddress, groupId);
@@ -133,8 +208,7 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
         }
     }
 
-    private void addVpnNexthopToDS(long vpnId, String ipPrefix, long egressPointer){
-
+    private void addVpnNexthopToDS(long vpnId, String ipPrefix, long egressPointer) {
 
         InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
                 .child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
@@ -161,7 +235,7 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
 
     }
 
-    private void addTunnelNexthopToDS(long dpnId, String ipPrefix, long egressPointer){
+    private void addTunnelNexthopToDS(long dpnId, String ipPrefix, long egressPointer) {
         InstanceIdentifierBuilder<TunnelNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
                 .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId));
 
@@ -170,7 +244,10 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
         Optional<TunnelNexthops> nexthops = read(LogicalDatastoreType.CONFIGURATION, id);
         if (!nexthops.isPresent()) {
             // create a new node
-            TunnelNexthops node = new TunnelNexthopsBuilder().setKey(new TunnelNexthopsKey(dpnId)).setDpnId(dpnId).build();
+            TunnelNexthops node = new TunnelNexthopsBuilder()
+                .setKey(new TunnelNexthopsKey(dpnId))
+                .setDpnId(dpnId)
+                .build();
             asyncWrite(LogicalDatastoreType.OPERATIONAL, id, node, DEFAULT_CALLBACK);
         }
 
@@ -189,29 +266,47 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
 
     private VpnNexthop getVpnNexthop(long vpnId, String ipAddress) {
 
-        InstanceIdentifierBuilder<VpnNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
-                .child(VpnNexthops.class, new VpnNexthopsKey(vpnId))
-                .child(VpnNexthop.class, new VpnNexthopKey(ipAddress));
-        InstanceIdentifier<VpnNexthop> id = idBuilder.build();
-        Optional<VpnNexthop> nextHop = read(LogicalDatastoreType.CONFIGURATION, id);
-
-        if(nextHop.isPresent()) return nextHop.get();
-        else return null;
+        // check if vpn node is there 
+        InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+                .child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
+        InstanceIdentifier<VpnNexthops> id = idBuilder.build();
+        Optional<VpnNexthops> vpnNexthops = read(LogicalDatastoreType.CONFIGURATION, id);
+        if (!vpnNexthops.isPresent()) {
+
+            // get nexthops list for vpn
+            List<VpnNexthop> nexthops = vpnNexthops.get().getVpnNexthop();
+            for (VpnNexthop nexthop : nexthops) {
+                if (nexthop.getIpAddress().equals(ipAddress)) {
+                    // return nexthop 
+                    return nexthop;
+                }
+            }
+        }
+        //return null if not found
+        return null;
     }
 
     private TunnelNexthop getTunnelNexthop(long dpnId, String ipAddress) {
-        InstanceIdentifierBuilder<TunnelNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
-                .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId))
-                .child(TunnelNexthop.class, new TunnelNexthopKey(ipAddress));
-        InstanceIdentifier<TunnelNexthop> id = idBuilder.build();
-        Optional<TunnelNexthop> nextHop = read(LogicalDatastoreType.CONFIGURATION, id);
+        
+        InstanceIdentifierBuilder<TunnelNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+                .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId));
 
-        if(nextHop.isPresent()) return nextHop.get();
-        else return null;
+        // check if vpn node is there 
+        InstanceIdentifier<TunnelNexthops> id = idBuilder.build();
+        Optional<TunnelNexthops> dpnNexthops = read(LogicalDatastoreType.CONFIGURATION, id);
+        if (!dpnNexthops.isPresent()) {
+            List<TunnelNexthop> nexthops = dpnNexthops.get().getTunnelNexthop();
+            for (TunnelNexthop nexthop : nexthops) {
+                if (nexthop.getIpAddress().equals(ipAddress)) {
+                    return nexthop;
+                }
+            }
+        }
+        return null;
     }
 
     public long getNextHopPointer(long dpnId, long vpnId, String prefixIp, String nextHopIp) {
-        String endpointIp = "10.10.10.1";//interfaceManager.getLocalEndpointIp(dpnId);
+        String endpointIp = interfaceManager.getEndpointIpForDpn(dpnId);
         if (nextHopIp.equals(endpointIp)) {
             VpnNexthop vpnNextHop = getVpnNexthop(vpnId, prefixIp);
             return vpnNextHop.getEgressPointer();
@@ -221,25 +316,74 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
         }
     }
 
-    public void removeRemoteNextHop(String ifname, String IpAddress)
-    {
-        String nhKey = new String("nexthop" + ifname + IpAddress);
-        int groupId = 1;//getIdManager().getUniqueId(L3Constants.L3NEXTHOP_GROUPID_POOL, nhKey);
+    private void removeTunnelNexthopFromDS(long dpnId, String ipPrefix) {
 
-/*        if (getNextHop(groupId) != Null){
-            List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
-            List<ActionInfo> listActionInfo = null;//nextHop.getActions({output to port});
-            BucketInfo bucket = new BucketInfo(listActionInfo);
-            listBucketInfo.add(bucket);
-            //GroupEntity groupEntity = MDSALUtil.buildGroupEntity
-              (dpId, groupId, IPAddress, GroupTypes.GroupIndirect, listBucketInfo);
-            //getMdsalApiManager().removeGroup(groupEntity, objTransaction???);
+        InstanceIdentifierBuilder<TunnelNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+                .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId))
+                .child(TunnelNexthop.class, new TunnelNexthopKey(ipPrefix));
+        InstanceIdentifier<TunnelNexthop> id = idBuilder.build();
+        // remove from DS     
+        delete(LogicalDatastoreType.OPERATIONAL, id);
+    }
+
+    private void removeVpnNexthopFromDS(long vpnId, String ipPrefix) {
+
+        InstanceIdentifierBuilder<VpnNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+                .child(VpnNexthops.class, new VpnNexthopsKey(vpnId))
+                .child(VpnNexthop.class, new VpnNexthopKey(ipPrefix));
+        InstanceIdentifier<VpnNexthop> id = idBuilder.build();
+        // remove from DS
+        delete(LogicalDatastoreType.OPERATIONAL, id);
+    }
+
+    public void removeLocalNextHop(String vpnName, String ipAddress) {
 
+        long vpnId = getVpnId(vpnName);
+
+        VpnNexthop nh = getVpnNexthop(vpnId, ipAddress);
+        if (nh != null) {
+            // how to inform and remove dependent FIB entries??
+            // we need to do it before the group is removed
+            
+            // remove Group ...
+            
             //update MD-SAL DS
-            removeNextHopFromDS(dpId, vpn, ipAddress);
-        }else{
-            //check update
-        }*/
+            removeVpnNexthopFromDS(vpnId, ipAddress);
+        } else {
+            //throw error
+        }
+
+    }
+
+    public void removeRemoteNextHop(long dpnId, String ipAddress) {
+
+        TunnelNexthop nh = getTunnelNexthop(dpnId, ipAddress);
+        if (nh != null) {
+            // how to inform and remove dependent FIB entries??
+            // we need to do it before the group is removed
+
+            // remove Group ...
+            //update MD-SAL DS
+            removeTunnelNexthopFromDS(dpnId, ipAddress);
+        } else {
+            //throw error
+        }
+
+    }
+
+    @Override
+    public Future<RpcResult<GetEgressPointerOutput>> getEgressPointer(
+            GetEgressPointerInput input) {
+        long egressGroupId =
+                getNextHopPointer(input.getDpnId(), input.getVpnId(), input.getIpPrefix(), input.getNexthopIp());
+
+        GetEgressPointerOutputBuilder output = new GetEgressPointerOutputBuilder();
+        output.setEgressPointer(egressGroupId);
+
+        RpcResult<GetEgressPointerOutput> result = null;
+        //Rpcs.<GetEgressPointerOutput> getRpcResult(false, output.build());
+        return Futures.immediateFuture(result); 
     }
 
     private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
@@ -265,18 +409,10 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
     }
 
 
-    @Override
-    public Future<RpcResult<GetEgressPointerOutput>> getEgressPointer(
-            GetEgressPointerInput input) {
-        long egressGroupId =
-                getNextHopPointer(input.getDpnId(), input.getVpnId(), input.getIpPrefix(), input.getNexthopIp());
-
-        GetEgressPointerOutputBuilder output = new GetEgressPointerOutputBuilder();
-        output.setEgressPointer(egressGroupId);
-
-        /*RpcResult<GetEgressPointerOutput> result = Rpcs.<GetEgressPointerOutput> getRpcResult(false, output.build());
-        return Futures.immediateFuture(result);*/
-        return null;
+    private <T extends DataObject> void delete(LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.delete(datastoreType, path);
+        Futures.addCallback(tx.submit(), DEFAULT_CALLBACK);
     }
 
 }
\ No newline at end of file
index 68758b6d079de4c3420fb75f228ea4249a996e97..57b7a766746b63f4fa92f96a3d7479a0e4d62a35 100644 (file)
@@ -11,6 +11,9 @@ 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.nexthopmgr.NexthopManager;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.idmanager.IdManager;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -21,16 +24,31 @@ public class NexthopmgrProvider implements BindingAwareProvider, AutoCloseable {
     private VpnInterfaceChangeListener vpnIfListener;
     private OdlInterfaceChangeListener odlIfListener;
     private NexthopManager nhManager;
+    private IMdsalApiManager mdsalManager;
+    private IInterfaceManager interfaceManager;
+    private IdManager idManager;
 
     @Override
     public void onSessionInitiated(ProviderContext session) {
         final  DataBroker dbx = session.getSALService(DataBroker.class);
         nhManager = new NexthopManager(dbx);
         vpnIfListener = new VpnInterfaceChangeListener(dbx, nhManager);
-        odlIfListener = new OdlInterfaceChangeListener(dbx, nhManager);
+        odlIfListener = new OdlInterfaceChangeListener(dbx, nhManager, interfaceManager);
+        idManager = new IdManager(dbx);
+        nhManager.setMdsalManager(mdsalManager);
+        nhManager.setInterfaceManager(interfaceManager);
+        nhManager.setIdManager(idManager);
         LOG.info("NexthopmgrProvider Session Initiated");
     }
 
+    public void setMdsalManager(IMdsalApiManager mdsalManager) {
+        this.mdsalManager = mdsalManager;
+    }
+
+    public void setInterfaceManager(IInterfaceManager interfaceManager) {
+        this.interfaceManager = interfaceManager;
+    }
+
     @Override
     public void close() throws Exception {
         vpnIfListener.close();
index d97fc88efb5996640fb4bd2a9e082bfa7071f68c..e8a5bc2e1561fd58698a297990b7e99d40047a02 100644 (file)
@@ -16,11 +16,12 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
-
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
 import org.opendaylight.vpnservice.nexthopmgr.AbstractDataChangeListener;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -31,11 +32,14 @@ public class OdlInterfaceChangeListener extends AbstractDataChangeListener<Inter
     private ListenerRegistration<DataChangeListener> listenerRegistration;
     private final DataBroker broker;
     private NexthopManager nexthopManager;
+    private IInterfaceManager interfaceManager;
+
 
-    public OdlInterfaceChangeListener(final DataBroker db, NexthopManager nhm) {
+    public OdlInterfaceChangeListener(final DataBroker db, NexthopManager nhm, IInterfaceManager ifManager) {
         super(Interface.class);
         broker = db;
         nexthopManager = nhm;
+        interfaceManager = ifManager;
         registerListener(db);
     }
 
@@ -62,24 +66,24 @@ public class OdlInterfaceChangeListener extends AbstractDataChangeListener<Inter
             throw new IllegalStateException("Nexthop Manager registration Listener failed.", e);
         }
     }
-    
+
     @Override
-    
-       protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
+    protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
         LOG.info("key: " + identifier + ", value=" + intrf );
 
         if (intrf.getType().equals(L3tunnel.class)) {
-               IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
+            IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
             String gwIp = intfData.getGatewayIp().toString();
             String remoteIp = intfData.getRemoteIp().toString();
             if (gwIp != null) {
                 remoteIp = gwIp;
             }
-            nexthopManager.createRemoteNextHop(intrf.getName(), remoteIp);
+            NodeConnectorId ofPort = intrf.getAugmentation(BaseIds.class).getOfPortId();
+            nexthopManager.createRemoteNextHop(intrf.getName(), ofPort.toString(), remoteIp);
         }
     }
 
-    
+
     private InstanceIdentifier<Interface> getWildCardPath() {
         return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
     }
@@ -88,13 +92,14 @@ public class OdlInterfaceChangeListener extends AbstractDataChangeListener<Inter
     protected void remove(InstanceIdentifier<Interface> identifier,
             Interface intrf) {
         if (intrf.getType().equals(L3tunnel.class)) {
+            long dpnId = interfaceManager.getDpnForInterface(intrf.getName());
             IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
             String gwIp = intfData.getGatewayIp().toString();
             String remoteIp = intfData.getRemoteIp().toString();
             if (gwIp != null) {
                 remoteIp = gwIp;
             }
-            nexthopManager.removeRemoteNextHop(intrf.getName(), remoteIp);
+            nexthopManager.removeRemoteNextHop(dpnId, remoteIp);
         }
     }
 
index 855f387d3b8f7e4511977808291fd0adb61a4392..1245a12ad9da2699894aaa6dcf375946c75342fc 100644 (file)
@@ -8,16 +8,12 @@
 package org.opendaylight.vpnservice.nexthopmgr;
 
 import java.util.List;
-import java.util.ArrayList;
-
 import com.google.common.base.Optional;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
@@ -25,17 +21,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.l
 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.VpnInterfaces;
 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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 import org.opendaylight.vpnservice.nexthopmgr.AbstractDataChangeListener;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
-public class VpnInterfaceChangeListener extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {
+public class VpnInterfaceChangeListener extends AbstractDataChangeListener<Adjacencies> implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceChangeListener.class);
 
     private ListenerRegistration<DataChangeListener> listenerRegistration;
@@ -43,7 +35,7 @@ public class VpnInterfaceChangeListener extends AbstractDataChangeListener<VpnIn
     private NexthopManager nexthopManager;
 
     public VpnInterfaceChangeListener(final DataBroker db, NexthopManager nhm) {
-        super(VpnInterface.class);
+        super(Adjacencies.class);
         broker = db;
         nexthopManager = nhm;
         registerListener(db);
@@ -74,39 +66,45 @@ public class VpnInterfaceChangeListener extends AbstractDataChangeListener<VpnIn
     }
 
     @Override
-    protected void add(InstanceIdentifier<VpnInterface> identifier,
-            VpnInterface vpnIf) {
-        LOG.info("key: " + identifier + ", value=" + vpnIf );
-
-        String vpnName = vpnIf.getVpnInstanceName();
-        final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
-        String interfaceName = key.getName();
-        InstanceIdentifierBuilder<Interface> idBuilder =
-                InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
-        InstanceIdentifier<Interface> id = idBuilder.build();
-        Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
-        if (port.isPresent()) {
-            //Interface interf = port.get();
-
-            //Read NextHops
-            InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
-            Optional<Adjacencies> adjacencies = read(LogicalDatastoreType.CONFIGURATION, path);
-
-            if (adjacencies.isPresent()) {
-                List<Adjacency> nextHops = adjacencies.get().getAdjacency();
-                List<Adjacency> value = new ArrayList<>();
-
-                if (!nextHops.isEmpty()) {
-                    LOG.info("NextHops are " + nextHops);
-                    for (Adjacency nextHop : nextHops) {
-                        nexthopManager.createLocalNextHop(interfaceName, vpnName, nextHop.getIpAddress());
-                    }
-                }
-            }
+    protected void add(InstanceIdentifier<Adjacencies> identifier,
+            Adjacencies adjs) {
+
+        InstanceIdentifier<VpnInterface> vpnIfId = identifier.firstIdentifierOf(VpnInterface.class);
+        Optional<VpnInterface> vpnIf = read(LogicalDatastoreType.CONFIGURATION, vpnIfId);
+        VpnInterface vpnIfData = vpnIf.get();
+
+        List<Adjacency> adjList = adjs.getAdjacency();
+        for (Adjacency adjacency : adjList) {
+            nexthopManager.createLocalNextHop(
+                    vpnIfData.getName(),
+                    vpnIfData.getVpnInstanceName(),
+                    adjacency.getIpAddress(),
+                    adjacency.getMacAddress());
         }
+    }
+
+
+    @Override
+    protected void remove(InstanceIdentifier<Adjacencies> identifier,
+            Adjacencies adjs) {
+        InstanceIdentifier<VpnInterface> vpnIfId = identifier.firstIdentifierOf(VpnInterface.class);
+        Optional<VpnInterface> vpnIf = read(LogicalDatastoreType.CONFIGURATION, vpnIfId);
+        VpnInterface vpnIfData = vpnIf.get();
+
+        List<Adjacency> adjList = adjs.getAdjacency();
+        for (Adjacency adjacency : adjList) {
+            nexthopManager.removeLocalNextHop(vpnIfData.getVpnInstanceName(), adjacency.getIpAddress());
+        }
+
+    }
 
+    @Override
+    protected void update(InstanceIdentifier<Adjacencies> identifier,
+            Adjacencies original, Adjacencies update) {
+        // TODO Auto-generated method stub
     }
 
+
     private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
             InstanceIdentifier<T> path) {
 
@@ -122,21 +120,9 @@ public class VpnInterfaceChangeListener extends AbstractDataChangeListener<VpnIn
         return result;
     }
 
-    private InstanceIdentifier<VpnInterface> getWildCardPath() {
-        return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class);
+    private InstanceIdentifier<Adjacencies> getWildCardPath() {
+        return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class).augmentation(Adjacencies.class);
     }
 
-    @Override
-    protected void remove(InstanceIdentifier<VpnInterface> identifier,
-            VpnInterface del) {
-            // TODO Auto-generated method stub
-    }
-
-    @Override
-    protected void update(InstanceIdentifier<VpnInterface> identifier,
-                VpnInterface original, VpnInterface update) {
-            // TODO Auto-generated method stub
-
-    }
 
 }
\ No newline at end of file
index 90470f0ce61d73aa3be6d46422202d521098a1d1..4b7d4aeac0b4b6383594d0cf477110b95f8df7fe 100644 (file)
@@ -19,6 +19,9 @@ public class NexthopmgrImplModule extends org.opendaylight.yang.gen.v1.urn.opend
     @Override
     public java.lang.AutoCloseable createInstance() {
         NexthopmgrProvider provider = new NexthopmgrProvider();
+        provider.setMdsalManager(getMdsalutilDependency());
+        provider.setInterfaceManager(getOdlinterfaceDependency());
+
         getBrokerDependency().registerProvider(provider);
         return provider;
     }
index 8c60aba879f5aa43df0d25feef23c1ab28759fec..3b50fdaf2309b1cb021c1babc642d4e3075bdf59 100644 (file)
@@ -5,6 +5,8 @@ module nexthopmgr-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 odl-mdsalutil { prefix odl-mdsal; revision-date 2015-04-10;}
+    import odl-interface {prefix odlif; revision-date 2015-03-31;}
 
     description
         "Service definition for nexthopmgr project";
@@ -30,6 +32,22 @@ module nexthopmgr-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 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) {