[ONOS-6224] L3VPN service delete

Change-Id: I2eabb231def39dba6613dc5b95f2b16594133ad4
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpModelIdLevel.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpModelIdLevel.java
index 334f2fe..05ee2bb 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpModelIdLevel.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpModelIdLevel.java
@@ -35,5 +35,10 @@
     /**
      * Requested model id level is device list.
      */
-    DEVICE
+    DEVICE,
+
+    /**
+     * Requested model id level is VPN list.
+     */
+    VPN
 }
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java
index 648d556..a45cc68 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java
@@ -17,7 +17,7 @@
 package org.onosproject.l3vpn.netl3vpn;
 
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.behaviour.L3vpnConfig;
+import org.onosproject.net.behaviour.L3VpnConfig;
 import org.onosproject.net.driver.DriverHandler;
 import org.onosproject.net.driver.DriverService;
 import org.onosproject.yang.model.ModelObjectData;
@@ -158,7 +158,7 @@
      */
     public ModelObjectData processCreateInstance(DriverService driverSvc,
                                                  ModelObjectData modelData) {
-        L3vpnConfig config = getL3VpnConfig(driverSvc);
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
         return (ModelObjectData) config.createInstance(modelData);
     }
 
@@ -173,7 +173,7 @@
      */
     public ModelObjectData processCreateInterface(DriverService driverSvc,
                                                   ModelObjectData modData) {
-        L3vpnConfig config = getL3VpnConfig(driverSvc);
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
         return (ModelObjectData) config.bindInterface(modData);
     }
 
@@ -190,7 +190,7 @@
     public ModelObjectData processCreateBgpInfo(DriverService driverSvc,
                                                 BgpInfo bgpInfo,
                                                 BgpDriverInfo driverInfo) {
-        L3vpnConfig config = getL3VpnConfig(driverSvc);
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
         return (ModelObjectData) config.createBgpInfo(bgpInfo, driverInfo);
     }
 
@@ -205,7 +205,7 @@
      */
     public ModelObjectData processDeleteInstance(DriverService driverSvc,
                                                  ModelObjectData modData) {
-        L3vpnConfig config = getL3VpnConfig(driverSvc);
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
         return (ModelObjectData) config.deleteInstance(modData);
     }
 
@@ -237,8 +237,8 @@
     public ModelObjectData processDeleteBgpInfo(DriverService driverSvc,
                                                 BgpInfo bgpInfo,
                                                 BgpDriverInfo driverInfo) {
-        // TODO: Need to call the behaviour.
-        return null;
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
+        return (ModelObjectData) config.deleteBgpInfo(bgpInfo, driverInfo);
     }
 
     /**
@@ -247,8 +247,8 @@
      * @param driverSvc driver service
      * @return L3VPN config
      */
-    private L3vpnConfig getL3VpnConfig(DriverService driverSvc) {
+    private L3VpnConfig getL3VpnConfig(DriverService driverSvc) {
         DriverHandler handler = driverSvc.createHandler(deviceId);
-        return handler.behaviour(L3vpnConfig.class);
+        return handler.behaviour(L3VpnConfig.class);
     }
 }
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/DistributedNetL3VpnStore.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/DistributedNetL3VpnStore.java
index 6debaf4..09c2f6a 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/DistributedNetL3VpnStore.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/DistributedNetL3VpnStore.java
@@ -198,7 +198,7 @@
     public void addInterfaceInfo(AccessInfo accessInfo, InterfaceInfo intInfo) {
         checkNotNull(accessInfo, ACCESS_INFO_NULL);
         checkNotNull(intInfo, INT_INFO_NULL);
-        intInfoMap.putIfAbsent(accessInfo, intInfo);
+        intInfoMap.put(accessInfo, intInfo);
     }
 
     @Override
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3vpnManager.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnManager.java
similarity index 94%
rename from apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3vpnManager.java
rename to apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnManager.java
index 4dc9165..67c6237 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3vpnManager.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnManager.java
@@ -142,14 +142,16 @@
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForSites;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getResourceData;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getRole;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnBgpDelModObj;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnCreateModObj;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnDelModObj;
 import static org.onosproject.yang.runtime.helperutils.YangApacheUtils.getYangModel;
 
 /**
  * The IETF net l3vpn manager implementation.
  */
 @Component(immediate = true)
-public class NetL3vpnManager {
+public class NetL3VpnManager {
 
     private static final String APP_ID = "org.onosproject.app.l3vpn";
     private static final String L3_VPN_ID_TOPIC = "l3vpn-id";
@@ -569,6 +571,7 @@
         InterfaceInfo interInfo = new InterfaceInfo(info, portName,
                                                     instance.vpnName());
         l3VpnStore.addInterfaceInfo(accInfo, interInfo);
+        l3VpnStore.addVpnIns(instance.vpnName(), instance);
     }
 
     /**
@@ -645,7 +648,6 @@
         Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
         generateRdRt(inst, role);
         DeviceInfo info = new DeviceInfo(id);
-        inst.addDevInfo(id, info);
 
         NetworkInstances instances = createInstance(inst, role, ip);
         ModelObjectData devMod = getVpnCreateModObj(intMap, instances,
@@ -655,6 +657,7 @@
         ResourceData resData = modelConverter.createDataNode(driMod);
         addToStore(resData);
         l3VpnStore.addVpnIns(inst.vpnName(), inst);
+        inst.addDevInfo(id, info);
         return info;
     }
 
@@ -871,7 +874,7 @@
         Interfaces interfaces = createInterface(pName, ins.vpnName(),
                                                 connect);
         ModelObjectData devMod = getIntCreateModObj(
-                intMap, interfaces, info.deviceId().toString());
+                info.ifNames(), interfaces, info.deviceId().toString());
         ModelObjectData driMod = info.processCreateInterface(driverService,
                                                              devMod);
         ResourceData resData = modelConverter.createDataNode(driMod);
@@ -896,7 +899,7 @@
         if (intBgp != null) {
             intBgp.vpnName(name);
             BgpDriverInfo config = getBgpCreateConfigObj(
-                    bgpMap, info.deviceId().toString());
+                    bgpMap, info.deviceId().toString(), info.bgpInfo(), intBgp);
             ModelObjectData driData = info.processCreateBgpInfo(
                     driverService, intBgp, config);
             l3VpnStore.addBgpInfo(info.bgpInfo(), info.deviceId());
@@ -965,24 +968,47 @@
      */
     private void deleteVpnInstance(VpnInstance instance, boolean isIntDeleted) {
         Map<DeviceId, DeviceInfo> devices = instance.devInfo();
-        for (Map.Entry<DeviceId, DeviceInfo> device : devices.entrySet()) {
-            Map<AccessInfo, InterfaceInfo> intMap =
-                    l3VpnStore.getInterfaceInfo();
-            NetworkInstances ins = deleteInstance(instance.vpnName());
-            DeviceInfo dev = device.getValue();
-
-            ModelObjectData devMod = getVpnCreateModObj(
-                    intMap, ins, dev.deviceId().toString());
-            ModelObjectData driMod = dev.processDeleteInstance(driverService,
-                                                               devMod);
-            ResourceData resData = modelConverter.createDataNode(driMod);
-            deleteFromStore(resData);
-            if (!isIntDeleted) {
-                //TODO: Remove from store.
-                remInterfaceFromMap(dev);
+        if (devices != null) {
+            for (Map.Entry<DeviceId, DeviceInfo> device : devices.entrySet()) {
+                NetworkInstances ins = deleteInstance(instance.vpnName());
+                DeviceInfo dev = device.getValue();
+                if (!isIntDeleted) {
+                    remVpnBgp(dev);
+                    remInterfaceFromMap(dev);
+                }
+                Map<AccessInfo, InterfaceInfo> intMap =
+                        l3VpnStore.getInterfaceInfo();
+                String id = dev.deviceId().toString();
+                ModelObjectData devMod = getVpnDelModObj(intMap, ins, id);
+                ModelObjectData driMod = dev.processDeleteInstance(
+                        driverService, devMod);
+                ResourceData resData = modelConverter.createDataNode(driMod);
+                deleteFromStore(resData);
             }
+            l3VpnStore.removeVpnInstance(instance.vpnName());
         }
-        l3VpnStore.removeVpnInstance(instance.vpnName());
+    }
+
+    /**
+     * Removes the BGP information for that complete VPN instance.
+     *
+     * @param dev device info
+     */
+    private void remVpnBgp(DeviceInfo dev) {
+        BgpInfo devBgp = dev.bgpInfo();
+        if (devBgp != null) {
+            l3VpnStore.removeBgpInfo(devBgp);
+            BgpInfo delInfo = new BgpInfo();
+            delInfo.vpnName(devBgp.vpnName());
+            String id = dev.deviceId().toString();
+            Map<BgpInfo, DeviceId> bgpMap = l3VpnStore.getBgpInfo();
+            BgpDriverInfo driConfig = getVpnBgpDelModObj(bgpMap, id);
+            ModelObjectData driData = dev.processDeleteBgpInfo(
+                    driverService, delInfo, driConfig);
+            ResourceData resData = modelConverter.createDataNode(driData);
+            deleteFromStore(resData);
+            l3VpnStore.removeBgpInfo(devBgp);
+        }
     }
 
     /**
@@ -993,7 +1019,7 @@
      */
     private void deleteFromStore(ResourceData resData) {
         if (resData != null) {
-            configService.deleteNode(resData.resourceId());
+            configService.deleteNodeRecursive(resData.resourceId());
         }
     }
 
@@ -1005,8 +1031,10 @@
      */
     private void remInterfaceFromMap(DeviceInfo deviceInfo) {
         List<AccessInfo> accesses = deviceInfo.accesses();
-        for (AccessInfo access : accesses) {
-            l3VpnStore.removeInterfaceInfo(access);
+        if (accesses != null) {
+            for (AccessInfo access : accesses) {
+                l3VpnStore.removeInterfaceInfo(access);
+            }
         }
         deviceInfo.ifNames(null);
         deviceInfo.accesses(null);
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java
index a713fc3..5875fe7 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java
@@ -49,6 +49,7 @@
 import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.DEVICE;
 import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.DEVICES;
 import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.ROOT;
+import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.VPN;
 import static org.onosproject.l3vpn.netl3vpn.VpnType.ANY_TO_ANY;
 import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
 import static org.onosproject.l3vpn.netl3vpn.VpnType.SPOKE;
@@ -385,16 +386,15 @@
     /**
      * Returns the interface create model object data.
      *
-     * @param intMap interface map
-     * @param ifs    interface instance
-     * @param id     device id
+     * @param ifNames interfaces
+     * @param ifs     interface instance
+     * @param id      device id
      * @return interface model object data
      */
-    static ModelObjectData getIntCreateModObj(Map<AccessInfo, InterfaceInfo> intMap,
+    static ModelObjectData getIntCreateModObj(List<String> ifNames,
                                               Interfaces ifs, String id) {
         ModelObjectData modData;
-        boolean intAdded = isDevIdPresent(intMap, id);
-        if (intAdded) {
+        if (ifNames.size() > 1) {
             modData = buildIntModDataDevice(id, ifs);
         } else {
             modData = buildIntModDataRoot(id, ifs);
@@ -439,15 +439,20 @@
      *
      * @param bgpMap BGP map
      * @param id     device id
-     * @return driver config info
+     * @param devBgp device BGP info
+     * @param intBgp interface BGP info
+     * @return BGP driver config
      */
     static BgpDriverInfo getBgpCreateConfigObj(Map<BgpInfo, DeviceId> bgpMap,
-                                               String id) {
+                                               String id, BgpInfo devBgp,
+                                               BgpInfo intBgp) {
         boolean isDevIdPresent = isDevIdBgpPresent(bgpMap, id);
         BgpDriverInfo info;
-        if (isDevIdPresent) {
+        if (devBgp != intBgp) {
+            //TODO: With ipv6 BGP it has to be changed
+            info = new BgpDriverInfo(VPN, id);
+        } else if (isDevIdPresent) {
             info = new BgpDriverInfo(DEVICE, id);
-
         } else if (bgpMap.size() != 0) {
             info = new BgpDriverInfo(DEVICES, id);
         } else {
@@ -473,4 +478,48 @@
         }
         return false;
     }
+
+    /**
+     * Returns the model object data for VPN instance deletion.
+     *
+     * @param intMap interface map
+     * @param ins    VPN instance
+     * @param id     device id
+     * @return model object data
+     */
+    static ModelObjectData getVpnDelModObj(Map<AccessInfo, InterfaceInfo> intMap,
+                                           NetworkInstances ins,
+                                           String id) {
+        boolean isDevIdPresent = isDevIdPresent(intMap, id);
+        ModelObjectData modData;
+        if (intMap.size() == 0) {
+            modData = buildInsModDataRoot(id, ins);
+        } else if (isDevIdPresent) {
+            modData = buildInsModDataDevice(id, ins);
+        } else {
+            modData = buildInsModDataDevices(id, ins);
+        }
+        return modData;
+    }
+
+    /**
+     * Returns the BGP driver info for VPN BGP instance deletion.
+     *
+     * @param bgpMap BGP map
+     * @param id     device id
+     * @return BGP driver info
+     */
+    static BgpDriverInfo getVpnBgpDelModObj(Map<BgpInfo, DeviceId> bgpMap,
+                                            String id) {
+        boolean isDevIdPresent = isDevIdBgpPresent(bgpMap, id);
+        BgpDriverInfo driInfo;
+        if (bgpMap.size() == 0) {
+            driInfo = new BgpDriverInfo(ROOT, id);
+        } else if (isDevIdPresent) {
+            driInfo = new BgpDriverInfo(DEVICE, id);
+        } else {
+            driInfo = new BgpDriverInfo(DEVICES, id);
+        }
+        return driInfo;
+    }
 }