itm and mdsal porting 17/36717/6
authorANURADHA RAJU <anuradha.raju@ericsson.com>
Thu, 24 Mar 2016 07:12:13 +0000 (12:42 +0530)
committerANURADHA RAJU <anuradha.raju@ericsson.com>
Thu, 31 Mar 2016 10:28:50 +0000 (15:58 +0530)
Change-Id: I9c2b3afa0d19608356e57704f0c85a3eaa3ed6d0
Signed-off-by: ANURADHA RAJU <anuradha.raju@ericsson.com>
52 files changed:
features/src/main/features/features.xml
itm/itm-api/src/main/java/org/opendaylight/vpnservice/itm/api/IITMProvider.java
itm/itm-api/src/main/java/org/opendaylight/vpnservice/itm/globals/ITMConstants.java
itm/itm-api/src/main/yang/itm-config.yang [new file with mode: 0644]
itm/itm-api/src/main/yang/itm-rpc.yang
itm/itm-api/src/main/yang/itm-state.yang
itm/itm-api/src/main/yang/itm.yang
itm/itm-impl/pom.xml
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/ItmCliUtils.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/SubnetObject.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepAdd.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepCommandHelper.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepCommit.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepConfigureTunnelType.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepDelete.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepDeleteDatastore.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepEnableTunnelMonitor.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepMonitor.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepShow.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepShowState.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepStateShow.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaAdd.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaDelete.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaShow.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaUpdate.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/confighelpers/HwVtep.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/confighelpers/ItmExternalTunnelAddWorker.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/confighelpers/ItmExternalTunnelDeleteWorker.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/confighelpers/ItmInternalTunnelAddWorker.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/confighelpers/ItmInternalTunnelDeleteWorker.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/confighelpers/ItmTepAddWorker.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/confighelpers/ItmTepRemoveWorker.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/impl/ITMManager.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/impl/ItmProvider.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/impl/ItmUtils.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/listeners/TransportZoneListener.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/listeners/VtepConfigSchemaListener.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/rpc/ItmManagerRpcService.java
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/snd/ITMStatusMonitor.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/snd/ITMStatusMonitorMBean.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/pom.xml
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/ActionType.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MDSALUtil.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MatchFieldType.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MetaDataUtil.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/NwConstants.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/cache/CacheUtil.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/clustering/ClusteringUtils.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/hwvtep/HwvtepSouthboundConstants.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/hwvtep/HwvtepSouthboundUtils.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/hwvtep/HwvtepUtils.java [new file with mode: 0644]
mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java

index 513ae57ea545ae649fa16674b35d029b0d6bae75..dfd0ca06fae5fd067ac7a1114e3d26b9e89036f7 100644 (file)
@@ -26,6 +26,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <feature version='${openflowplugin.version}'>odl-openflowplugin-nsf-model</feature>
     <feature version="${openflowplugin.version}">odl-openflowplugin-nxm-extensions</feature>
     <feature version="${ovsdb.version}">odl-ovsdb-southbound-impl-rest</feature>
+    <feature version='${ovsdb.version}'>odl-ovsdb-hwvtepsouthbound-api</feature>
     <bundle>mvn:org.opendaylight.controller/liblldp/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.neutron/model/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/model-bgp/{{VERSION}}</bundle>
index 5610422dde90b940e5ab50e2f3fc797a354aea87..c45b982d920eb76ef8df39e9358f606ae7996edd 100644 (file)
@@ -6,7 +6,76 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 package org.opendaylight.vpnservice.itm.api;
+import java.math.BigInteger;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.interfacemgr.exceptions.InterfaceNotFoundException;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema; 
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.TunnelsState;
 
 public interface IITMProvider {
+       // APIs used by i
+    public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask, String gatewayIp, String transportZone);
+
+    public void commitTeps();
+
+    public DataBroker getDataBroker();
+
+    public void showTeps();
+
+    public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
+                    String gatewayIp, String transportZone);
+   // public void showState(TunnelsState tunnelsState);
+    public void configureTunnelType(String transportZone, String tunnelType);
+
+    
+    /**
+     * Adds the vtep config schema.
+     *
+     * @param vtepConfigSchema
+     *            the vtep config schema
+     */
+    public void addVtepConfigSchema(VtepConfigSchema vtepConfigSchema);
+
+    /**
+     * Gets the vtep config schema.
+     *
+     * @param schemaName
+     *            the schema name
+     * @return the vtep config schema
+     */
+    public VtepConfigSchema getVtepConfigSchema(String schemaName);
+
+    /**
+     * Gets the all vtep config schemas.
+     *
+     * @return the all vtep config schemas
+     */
+    public List<VtepConfigSchema> getAllVtepConfigSchemas();
+
+    /**
+     * Update VTEP schema.
+     *
+     * @param schemaName
+     *            the schema name
+     * @param lstDpnsForAdd
+     *            the lst dpns for add
+     * @param lstDpnsForDelete
+     *            the lst dpns for delete
+     */
+    public void updateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd, List<BigInteger> lstDpnsForDelete);
+
+    /**
+     * Delete all vtep schemas.
+     */
+    public void deleteAllVtepSchemas();
+
+    public void configureTunnelMonitorEnabled(boolean monitorEnabled);
 
+    public void configureTunnelMonitorInterval(int interval);
 }
index 1cb20a09e931a260315944ada7094655b2f669f7..b6f6673b838978042183dd57617e9f781354bced 100644 (file)
@@ -9,12 +9,19 @@ package org.opendaylight.vpnservice.itm.globals;
 
 import java.math.BigInteger;
 
-
-
 public class ITMConstants{
   public static final BigInteger COOKIE_ITM = new BigInteger("9000000", 16);
+  public static final BigInteger COOKIE_ITM_EXTERNAL = new BigInteger("9050000", 16);
+
   public static final String ITM_IDPOOL_NAME = "Itmservices";
   public static final long ITM_IDPOOL_START = 1L;
   public static final String ITM_IDPOOL_SIZE = "100000";
   public static int LLDP_SERVICE_ID = 0;
+  //Tunnel Monitoring
+  public static final boolean DEFAULT_MONITOR_ENABLED = true;
+  public static final int DEFAULT_MONITOR_INTERVAL = 10;
+  public static final String DUMMY_IP_ADDRESS = "0.0.0.0";
+  public static final String TUNNEL_TYPE_VXLAN = "VXLAN";
+  public static final String TUNNEL_TYPE_GRE = "GRE";
 }
+
diff --git a/itm/itm-api/src/main/yang/itm-config.yang b/itm/itm-api/src/main/yang/itm-config.yang
new file mode 100644 (file)
index 0000000..858d0a1
--- /dev/null
@@ -0,0 +1,114 @@
+module itm-config {
+
+    namespace "urn:opendaylight:vpnservice:itm:config";
+
+    prefix itm-config;
+
+    import ietf-interfaces {
+        prefix if;
+    }
+    import ietf-yang-types {
+        prefix yang;
+    }
+    import ietf-inet-types {
+        prefix inet;
+        revision-date "2010-09-24";
+    }
+    import odl-interface {
+            prefix odlif;
+    }
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description "This YANG module defines automatic tunnel configuration.";
+    revision "2015-11-02";
+
+    /* Tunnel Monitoring Knob */
+
+    container tunnel-monitor-enabled {
+      leaf enabled {
+         type boolean;
+         default true;
+      }
+    }
+
+    container tunnel-monitor-interval {
+      leaf interval {
+         type uint16 {
+             range "5..30";
+         }
+         default 10;
+      }
+    }
+
+    /* Configuration data */
+
+    container vtep-config-schemas {
+      list vtep-config-schema {
+        key schema-name;
+        leaf schema-name {
+            type string;
+            mandatory true;
+            description "Schema name";
+        }
+        leaf transport-zone-name {
+            type string;
+            mandatory true;
+            description "Transport zone";
+        }
+        leaf tunnel-type {
+            type identityref {
+            base odlif:tunnel-type-base;
+            }
+        }
+        leaf port-name {
+            type string;
+            mandatory true;
+            description "Port name";
+        }
+        leaf vlan-id {
+            type uint16 {
+                range "0..4094";
+            }
+            mandatory true;
+            description "VLAN ID";
+        }
+        leaf gateway-ip {
+            type inet:ip-address;
+            description "Gateway IP address";
+        }
+        leaf subnet {
+            type inet:ip-prefix;
+            mandatory true;
+            description "Subnet Mask in CIDR-notation string, e.g. 10.0.0.0/24";
+        }
+        leaf exclude-ip-filter {
+            type string;
+            description "IP Addresses which needs to be excluded from the specified subnet. IP address range or comma separated IP addresses can to be specified. e.g: 10.0.0.1-10.0.0.20,10.0.0.30,10.0.0.35";
+        }
+        list dpn-ids {
+            key "DPN";
+            leaf DPN {
+               type uint64;
+               description "DPN ID";
+            }
+        }
+      }
+    }
+
+    /* Ip Address book keeping */
+    container vtep-ip-pools {
+       config true;
+       list vtep-ip-pool {
+          key subnet-cidr;
+          leaf subnet-cidr{
+             type string;
+          }
+          leaf-list available-ipaddress {
+             type inet:ip-address;
+          }
+          leaf-list allocated-ipaddress {
+             type inet:ip-address;
+          }
+       }
+    }
+}
index 2347e6eb055a472dedc967c4e85e9a7a82f73598..866c6e635b413a04c207d54332c337c50c9c6eca 100644 (file)
@@ -23,7 +23,7 @@ module itm-rpc {
     import opendaylight-action-types {prefix action;revision-date "2013-11-12";}
     import opendaylight-flow-types {prefix offlow;revision-date "2013-10-26";}
 
-        
+
     revision "2015-12-17" {
         description "ODL Specific Itm Manager Rpcs Module";
     }
@@ -65,13 +65,13 @@ module itm-rpc {
     }
 
     rpc get-external-tunnel-interface-name {
-        description "used to retrieve tunnel interface id between Dpns";
+        description "used to retrieve external tunnel interface id between Dpns/TORs";
         input {
-            leaf source-dpid {
-            type uint64;
+            leaf source-node {
+            type string;
             }
-            leaf destination-ip {
-            type inet:ip-address;
+            leaf destination-node {
+            type string;
             }
         }
         output {
@@ -98,7 +98,7 @@ module itm-rpc {
         }
      }
 
-     rpc add-external-tunnel-endpoint { 
+    rpc add-external-tunnel-endpoint {
         description "used for building tunnels between teps on all Dpns and external node";
         input {
             leaf destination-ip {
@@ -110,7 +110,7 @@ module itm-rpc {
             }
             }
         }
-     }
+    }
     rpc remove-external-tunnel-from-dpns {
         description "used for building tunnels between a Dpn and external node";
         input {
@@ -155,16 +155,46 @@ module itm-rpc {
          }
      }
 
-     rpc remove-terminating-service-actions {
-              description  "used for removing the terminating service actions";
-              input {
-                  leaf dpn-id {
+    rpc remove-terminating-service-actions {
+        description  "used for removing the terminating service actions";
+        input {
+            leaf dpn-id {
                     type uint64;
-                  }
-                  leaf service-id {
-                     type uint16;
-                  }
-              }
-     }
+            }
+            leaf service-id {
+                type uint16;
+            }
+        }
+    }
+
+    rpc add-l2-gw-device {
+        description "used for building tunnels between teps on all Dpns and hwVtep";
+        input {
+            leaf topology-id {
+                type string;
+            }
+            leaf node-id {
+                type string;
+            }
+            leaf ip-address {
+                type inet:ip-address;
+            }
+        }
+    }
+
+    rpc delete-l2-gw-device {
+        description "used for deleting tunnels between teps on all Dpns and hwVtep";
+        input {
+            leaf topology-id {
+                type string;
+            }
+            leaf node-id {
+                type string;
+            }
+            leaf ip-address {
+                type inet:ip-address;
+            }
+        }
+    }
 
 }
\ No newline at end of file
index ca39c03eda5c66365aa14b392680a80a069cee92..aa30269193a46690f4bb224ba8df161544c9a6f5 100644 (file)
@@ -102,14 +102,14 @@ module itm-state {
       container external-tunnel-list {
              list external-tunnel {
 
-               key  "source-DPN destination-IP";
+               key  "source-device destination-device";
 
-               leaf source-DPN {
-                   type uint64;
+               leaf source-device {
+                   type string; //dpnid or node-id
                }
 
-               leaf destination-IP {
-                   type inet:ip-address;
+               leaf destination-device {
+                   type string; //dpn-id or node-id or ip
                }
 
                /* logical-group interface id */
@@ -121,6 +121,7 @@ module itm-state {
              }
           }
 
+
           notification itm-tunnel-build-complete{
           }
 
index 8785d0a6ca3c66e176849976264718f1ed3c329b..3d3ccbe533c62a2915a48484a787cbd036601c7d 100644 (file)
@@ -48,7 +48,9 @@ module itm {
                 type inet:ip-address;
             }
             leaf vlan-id {
-                type uint16;
+                type uint16{
+                range "0..4094";
+            }
             }
             list vteps {
                 key "dpn-id portname";
@@ -62,6 +64,19 @@ module itm {
                     type inet:ip-address;
                 }
             }
+             list device-vteps {
+              key "node-id ip-address";
+                     leaf topology-id {
+                        type string;
+                     }
+                     leaf node-id {
+                       type string;
+                     }
+                     leaf ip-address {
+                     type inet:ip-address;
+                   }
+           }
+
         }
       }
     }
index d555a771b5d0e263eb3a6134f904ffe2f76d85e3..cc05784947da7d1c27f66b5933087604fddb3d7e 100644 (file)
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+        <groupId>org.osgi</groupId>
+        <artifactId>org.osgi.core</artifactId>
+        <scope>provided</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.karaf.shell</groupId>
+        <artifactId>org.apache.karaf.shell.console</artifactId>
+        <version>${karaf.shell.console.version}</version>
+    </dependency>
     <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava</artifactId>
             <version>0.3.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            org.apache.felix.service.command,
+                            org.apache.felix.gogo.commands,
+                            org.apache.karaf.shell.console,
+                            *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
   </project>
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/ItmCliUtils.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/ItmCliUtils.java
new file mode 100644 (file)
index 0000000..798ee90
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * The Utility class for ITM CLI.
+ */
+public final class ItmCliUtils {
+
+    /**
+     * Construct dpn id list.
+     *
+     * @param dpnIds
+     *            the dpn ids
+     * @return the list
+     */
+    public static List<BigInteger> constructDpnIdList(final String dpnIds) {
+        final List<BigInteger> lstDpnIds = new ArrayList<>();
+        if (StringUtils.isNotBlank(dpnIds)) {
+            final String[] arrDpnIds = StringUtils.split(dpnIds, ',');
+            for (String dpn : arrDpnIds) {
+                if (StringUtils.isNumeric(StringUtils.trim(dpn))) {
+                    lstDpnIds.add(new BigInteger(StringUtils.trim(dpn)));
+                } else {
+                    Preconditions.checkArgument(false, String.format("DPN ID [%s] is not a numeric value.", dpn));
+                }
+            }
+        }
+        return lstDpnIds;
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/SubnetObject.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/SubnetObject.java
new file mode 100644 (file)
index 0000000..f5baf25
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import java.util.Map;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.SubnetsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.SubnetsKey;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public class SubnetObject {
+    private IpAddress _gatewayIp;
+    private SubnetsKey _key;
+    private IpPrefix _prefix;
+    private java.lang.Integer _vlanId;
+
+    public SubnetObject(IpAddress gWIP, SubnetsKey key, IpPrefix mask, Integer vlanId) {
+        _gatewayIp = gWIP;
+        _key = key;
+        _prefix = mask;
+        try {
+            if (vlanId != null) {
+                checkVlanIdRange(vlanId);
+            }
+        } catch (IllegalArgumentException e) {
+            System.out.println("Invalid VlanID. expected: 0 to 4095");
+        }
+        _vlanId = vlanId;
+    }
+
+    public IpAddress get_gatewayIp() {
+        return _gatewayIp;
+    }
+
+    public SubnetsKey get_key() {
+        return _key;
+    }
+
+    public IpPrefix get_prefix() {
+        return _prefix;
+    }
+
+    public java.lang.Integer get_vlanId() {
+        return _vlanId;
+    }
+
+    private int hash = 0;
+    private volatile boolean hashValid = false;
+
+    @Override
+    public int hashCode() {
+        if (hashValid) {
+            return hash;
+        }
+
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((_gatewayIp == null) ? 0 : _gatewayIp.hashCode());
+        result = prime * result + ((_key == null) ? 0 : _key.hashCode());
+        result = prime * result + ((_prefix == null) ? 0 : _prefix.hashCode());
+        result = prime * result + ((_vlanId == null) ? 0 : _vlanId.hashCode());
+        hash = result;
+        hashValid = true;
+        return result;
+    }
+
+    @Override
+    public boolean equals(java.lang.Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof SubnetObject)) {
+            return false;
+        }
+        SubnetObject other = (SubnetObject) obj;
+        if (_gatewayIp == null) {
+            if (other.get_gatewayIp() != null) {
+                return false;
+            }
+        } else if (!_gatewayIp.equals(other.get_gatewayIp())) {
+            return false;
+        }
+        if (_key == null) {
+            if (other.get_key() != null) {
+                return false;
+            }
+        } else if (!_key.equals(other.get_key())) {
+            return false;
+        }
+        if (_prefix == null) {
+            if (other.get_prefix() != null) {
+                return false;
+            }
+        } else if (!_prefix.equals(other.get_prefix())) {
+            return false;
+        }
+        if (_vlanId == null) {
+            if (other.get_vlanId() != null) {
+                return false;
+            }
+        } else if (!_vlanId.equals(other.get_vlanId())) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public java.lang.String toString() {
+        java.lang.StringBuilder builder = new java.lang.StringBuilder("Subnets [");
+        boolean first = true;
+
+        if (_gatewayIp != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(", ");
+            }
+            builder.append("_gatewayIp=");
+            builder.append(_gatewayIp);
+        }
+        if (_key != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(", ");
+            }
+            builder.append("_key=");
+            builder.append(_key);
+        }
+        if (_prefix != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(", ");
+            }
+            builder.append("_prefix=");
+            builder.append(_prefix);
+        }
+        if (_vlanId != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(", ");
+            }
+            builder.append("_vlanId=");
+            builder.append(_vlanId);
+        }
+        return builder.append(']').toString();
+    }
+
+    private static void checkVlanIdRange(final int value) {
+        if (value >= 0 && value <= 4095) {
+            return;
+        }
+        throw new IllegalArgumentException(String.format("Invalid range: %s, expected: [[0?4095]].", value));
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepAdd.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepAdd.java
new file mode 100644 (file)
index 0000000..d4e0c85
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import java.math.BigInteger;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "tep", name = "add", description = "adding a tunnel end point")
+public class TepAdd extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "dpnId", description = "DPN-ID", required = false, multiValued = false)
+    private BigInteger dpnId;
+    @Argument(index = 1, name = "portNo", description = "port-name", required = false, multiValued = false)
+    private String portName;
+    @Argument(index = 2, name = "vlanId", description = "vlan-id", required = false, multiValued = false)
+    private Integer vlanId;
+    @Argument(index = 3, name = "ipAddress", description = "ip-address", required = false, multiValued = false)
+    private String ipAddress;
+    @Argument(index = 4, name = "subnetMask", description = "subnet-Mask", required = false, multiValued = false)
+    private String subnetMask;
+    @Argument(index = 5, name = "gatewayIp", description = "gateway-ip", required = false, multiValued = false)
+    private String gatewayIp;
+    @Argument(index = 6, name = "transportZone", description = "transport_zone", required = false, multiValued = false)
+    private String transportZone;
+    private static final Logger LOG = LoggerFactory.getLogger(TepAdd.class);
+    private IITMProvider itmProvider;
+
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            if (dpnId == null || portName == null || vlanId == null || ipAddress == null || subnetMask == null
+                            || transportZone == null) {
+                System.out.println("Insufficient Arguments");
+                System.out.println("Correct Usage : exec tep-add dpnId portName vlanId ipAddress subnetMask gatewayIp transportZone");
+                return null;
+            }
+            LOG.debug("Executing create TEP command" + "\t" + dpnId + "\t" + portName + "\t" + vlanId + "\t"
+                            + ipAddress + "\t" + subnetMask + "\t" + gatewayIp + "\t" + transportZone);
+            itmProvider.createLocalCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone);
+        } catch (IllegalArgumentException e) {
+            System.out.println(e.getMessage());
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            LOG.error("Exception occurred during execution of command \"tep-add\": ", e);
+        }
+        return null;
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepCommandHelper.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepCommandHelper.java
new file mode 100644 (file)
index 0000000..7f417d3
--- /dev/null
@@ -0,0 +1,810 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.net.util.SubnetUtils;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.exceptions.InterfaceNotFoundException;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+//import org.opendaylight.vpnservice.interfacemgr.util.OperationalIfmUtil;
+import org.opendaylight.vpnservice.itm.globals.ITMConstants;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.vpnservice.mdsalutil.MDSALDataStoreUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorEnabled;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorEnabledBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorInterval;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorIntervalBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZonesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZoneBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZoneKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.SubnetsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.SubnetsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.Vteps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.VtepsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.VtepsKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+
+public class TepCommandHelper {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TepCommandHelper.class);
+    private DataBroker dataBroker;
+    static int check = 0;
+    static short flag = 0;
+    /*
+     * boolean flag add_or_delete --- can be set to true if the last called tep
+     * command is Tep-add else set to false when Tep-delete is called
+     * tepCommandHelper object is created only once in session initiated
+     */
+    final Map<String, Map<SubnetObject, List<Vteps>>> tZones = new HashMap<String, Map<SubnetObject, List<Vteps>>>();
+    private List<Subnets> subnetList = new ArrayList<Subnets>();
+    private List<TransportZone> tZoneList = new ArrayList<TransportZone>();
+    private List<Vteps> vtepDelCommitList = new ArrayList<Vteps>();
+    private IInterfaceManager interfaceManager;
+
+    // private List<InstanceIdentifier<? extends DataObject>> vtepPaths = new
+    // ArrayList<>();
+
+
+    public TepCommandHelper(final DataBroker broker) {
+        this.dataBroker = broker;
+    }
+
+
+    public void setInterfaceManager(IInterfaceManager interfaceManager) {
+        this.interfaceManager = interfaceManager;
+    }
+
+    public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress,
+                    String subnetMask, String gatewayIp, String transportZone) {
+
+        check++;
+        IpAddress ipAddressObj = null;
+        IpAddress gatewayIpObj = null;
+        IpPrefix subnetMaskObj = null;
+        VtepsKey vtepkey = new VtepsKey(dpnId, portName);
+        try {
+            ipAddressObj = new IpAddress(ipAddress.toCharArray());
+            gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
+            if (gatewayIp != null) {
+                gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
+            } else {
+                LOG.debug("gateway is null");
+            }
+        } catch (Exception e) {
+            System.out.println("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255");
+            return;
+        }
+        try {
+            subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
+        } catch (Exception e) {
+            System.out.println("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32");
+            return;
+        }
+
+        if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
+            System.out.println("IpAddress and gateWayIp should belong to the subnet provided");
+            return;
+        }
+
+        if (checkTepPerTzPerDpn(transportZone, dpnId)) {
+            System.out.println("Only one end point per transport Zone per Dpn is allowed");
+            return;
+        }
+        Vteps vtepCli = new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
+                .setPortname(portName).build();
+        validateForDuplicates(vtepCli, transportZone);
+
+        SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
+        SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
+        if (tZones.containsKey(transportZone)) {
+            Map<SubnetObject, List<Vteps>> subVtepMapTemp = (Map<SubnetObject, List<Vteps>>) tZones.get(transportZone);
+            if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
+                List<Vteps> vtepListTemp = (List<Vteps>) subVtepMapTemp.get(subObCli);
+                if (vtepListTemp.contains(vtepCli)) {
+                    // do nothing
+                } else {
+                    vtepListTemp.add(vtepCli);
+                }
+            } else { // subnet doesnt exist
+                if (checkExistingSubnet(subVtepMapTemp, subObCli)) {
+                    System.out.println("subnet with subnet mask " + subObCli.get_key() + "already exists");
+                    return;
+                }
+                List<Vteps> vtepListTemp = new ArrayList<Vteps>();
+                vtepListTemp.add(vtepCli);
+                subVtepMapTemp.put(subObCli, vtepListTemp);
+            }
+        } else {
+            List<Vteps> vtepListTemp = new ArrayList<Vteps>();
+            vtepListTemp.add(vtepCli);
+            Map<SubnetObject, List<Vteps>> subVtepMapTemp = new HashMap<SubnetObject, List<Vteps>>();
+            subVtepMapTemp.put(subObCli, vtepListTemp);
+            tZones.put(transportZone, subVtepMapTemp);
+        }
+    }
+
+    private boolean validateIPs(String ipAddress, String subnetMask, String gatewayIp) {
+        SubnetUtils utils = new SubnetUtils(subnetMask);
+        if ((utils.getInfo().isInRange(ipAddress)) && ((gatewayIp == null) || (utils.getInfo().isInRange(gatewayIp)))) {
+            return true;
+        } else {
+            LOG.trace("InValid IP");
+            return false;
+        }
+    }
+
+    /**
+     * Validate for duplicates.
+     *
+     * @param inputVtep
+     *            the input vtep
+     * @param transportZone
+     *            the transport zone
+     */
+    public void validateForDuplicates(Vteps inputVtep, String transportZone) {
+        Map<String, TransportZone> tZoneMap = getAllTransportZonesAsMap();
+
+        boolean isConfiguredTepGreType = isGreTunnelType(transportZone, tZoneMap);
+        // Checking for duplicates in local cache
+        for (String tZ : tZones.keySet()) {
+            boolean isGreType = isGreTunnelType(tZ, tZoneMap);
+            Map<SubnetObject, List<Vteps>> subVtepMapTemp = (Map<SubnetObject, List<Vteps>>) tZones.get(tZ);
+            for (SubnetObject subOb : subVtepMapTemp.keySet()) {
+                List<Vteps> vtepList = subVtepMapTemp.get(subOb);
+                validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
+            }
+        }
+        // Checking for duplicates in config DS
+        for (TransportZone tZ : tZoneMap.values()) {
+            boolean isGreType = false;
+            if (tZ.getTunnelType().equals(TunnelTypeGre.class)) {
+                isGreType = true;
+            }
+            for (Subnets sub : ItmUtils.emptyIfNull(tZ.getSubnets())) {
+                List<Vteps> vtepList = sub.getVteps();
+                validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
+            }
+        }
+    }
+
+    private void validateForDuplicateAndSingleGreTep(Vteps inputVtep, boolean isConfiguredTepGreType, boolean isGreType,
+            List<Vteps> vtepList) {
+        if (ItmUtils.isEmpty(vtepList)) {
+            return;
+        }
+        if (vtepList.contains(inputVtep)) {
+            Preconditions.checkArgument(false, "VTEP already exists");
+        }
+        BigInteger dpnId = inputVtep.getDpnId();
+        if (isConfiguredTepGreType && isGreType) {
+            for (Vteps vtep : vtepList) {
+                if (vtep.getDpnId().equals(dpnId)) {
+                    String errMsg = new StringBuilder("DPN [").append(dpnId)
+                            .append("] already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.")
+                            .toString();
+                    Preconditions.checkArgument(false, errMsg);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets all transport zones as map.
+     *
+     * @return all transport zones as map
+     */
+    private Map<String, TransportZone> getAllTransportZonesAsMap() {
+        TransportZones tZones = getAllTransportZones();
+        Map<String, TransportZone> tZoneMap = new HashMap<>();
+        if( null != tZones) {
+           for (TransportZone tzone : ItmUtils.emptyIfNull(tZones.getTransportZone())) {
+             tZoneMap.put(tzone.getZoneName(), tzone);
+           }
+        }
+        return tZoneMap;
+    }
+
+    /**
+     * Checks if is gre tunnel type.
+     *
+     * @param tZoneName
+     *            the zone name
+     * @param tZoneMap
+     *            the zone map
+     * @return true, if is gre tunnel type
+     */
+    private boolean isGreTunnelType(String tZoneName, Map<String, TransportZone> tZoneMap) {
+        TransportZone tzone = tZoneMap.get(tZoneName);
+        /*
+        if (tzone != null && StringUtils.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_GRE, tzone.getTunnelType())) {
+            return true;
+        }
+        */
+        if( (tzone != null) && (tzone.getTunnelType()).equals(TunnelTypeGre.class) ) {
+           return true;
+        }
+        return false;
+    }
+
+    /**
+     * Gets the transport zone.
+     *
+     * @param tzone
+     *            the tzone
+     * @return the transport zone
+     */
+    public TransportZone getTransportZone(String tzone) {
+        InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
+                .child(TransportZone.class, new TransportZoneKey(tzone)).build();
+        Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
+                dataBroker);
+        if (tZoneOptional.isPresent()) {
+            return tZoneOptional.get();
+        }
+        return null;
+    }
+
+    /**
+     * Gets the transport zone from config ds.
+     *
+     * @param tzone
+     *            the tzone
+     * @return the transport zone
+     */
+    public TransportZone getTransportZoneFromConfigDS(String tzone) {
+        InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
+                .child(TransportZone.class, new TransportZoneKey(tzone)).build();
+        Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
+                dataBroker);
+        if (tZoneOptional.isPresent()) {
+            return tZoneOptional.get();
+        }
+        return null;
+    }
+
+    /**
+     * Gets all transport zones.
+     *
+     * @return all transport zones
+     */
+    public TransportZones getAllTransportZones() {
+        InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
+        Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
+        if (tZonesOptional.isPresent()) {
+            return tZonesOptional.get();
+        }
+        return null;
+    }
+
+    public boolean checkExistingSubnet(Map<SubnetObject, List<Vteps>> subVtepMapTemp, SubnetObject subObCli) {
+        for (SubnetObject subOb : subVtepMapTemp.keySet()) {
+            if (subOb.get_key().equals(subObCli.get_key())) {
+                if (!(subOb.get_vlanId().equals(subObCli.get_vlanId())))
+                    return true;
+                if (!(subOb.get_gatewayIp().equals(subObCli.get_gatewayIp())))
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean checkTepPerTzPerDpn(String tzone, BigInteger dpnId) {
+        // check in local cache
+        if (tZones.containsKey(tzone)) {
+            Map<SubnetObject, List<Vteps>> subVtepMapTemp = (Map<SubnetObject, List<Vteps>>) tZones.get(tzone);
+            for (SubnetObject subOb : subVtepMapTemp.keySet()) {
+                List<Vteps> vtepList = subVtepMapTemp.get(subOb);
+                for (Vteps vtep : vtepList)
+                    if (vtep.getDpnId().equals(dpnId))
+                        return true;
+            }
+        }
+
+        // check in DS
+        InstanceIdentifier<TransportZone> tzonePath =
+                        InstanceIdentifier.builder(TransportZones.class)
+                                        .child(TransportZone.class, new TransportZoneKey(tzone)).build();
+        Optional<TransportZone> tZoneOptional =
+                        ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
+        if (tZoneOptional.isPresent()) {
+            TransportZone tz = tZoneOptional.get();
+            if (tz.getSubnets() == null || tz.getSubnets().isEmpty())
+                return false;
+            for (Subnets sub : tz.getSubnets()) {
+                if (sub.getVteps() == null || sub.getVteps().isEmpty())
+                    continue;
+                for (Vteps vtep : sub.getVteps()) {
+                    if (vtep.getDpnId().equals(dpnId)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    public void buildTeps() {
+        TransportZones tZonesBuilt = null;
+        TransportZone tZone = null;
+        try {
+            LOG.debug("no of teps added" + check);
+            if (tZones != null || !tZones.isEmpty()) {
+                tZoneList = new ArrayList<TransportZone>();
+                for (String tZ : tZones.keySet()) {
+                    LOG.debug("tZones" + tZ);
+                    subnetList = new ArrayList<Subnets>();
+                    Map<SubnetObject, List<Vteps>> subVtepMapTemp = (Map<SubnetObject, List<Vteps>>) tZones.get(tZ);
+                    for (SubnetObject subOb : subVtepMapTemp.keySet()) {
+                        LOG.debug("subnets" + subOb.get_prefix());
+                        List<Vteps> vtepList = subVtepMapTemp.get(subOb);
+                        Subnets subnet =
+                                        new SubnetsBuilder().setGatewayIp(subOb.get_gatewayIp())
+                                                        .setKey(subOb.get_key()).setPrefix(subOb.get_prefix())
+                                                        .setVlanId(subOb.get_vlanId()).setVteps(vtepList).build();
+                        subnetList.add(subnet);
+                        LOG.debug("vteps" + vtepList);
+                    }
+                    InstanceIdentifier<TransportZone> tZonepath =
+                                    InstanceIdentifier.builder(TransportZones.class)
+                                                    .child(TransportZone.class, new TransportZoneKey(tZ)).build();
+                    Optional<TransportZone> tZoneOptional =
+                                    ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tZonepath, dataBroker);
+                    LOG.debug("read container from DS");
+                    if (tZoneOptional.isPresent()) {
+                        TransportZone tzoneFromDs = tZoneOptional.get();
+                        LOG.debug("read tzone container" + tzoneFromDs.toString());
+                        if (tzoneFromDs.getTunnelType() == null
+                                        || (tzoneFromDs.getTunnelType()).equals(TunnelTypeVxlan.class)) {
+                            tZone =
+                                            new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
+                                                            .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList)
+                                                            .setZoneName(tZ).build();
+                        } else if ((tzoneFromDs.getTunnelType()).equals(TunnelTypeGre.class)) {
+                            tZone =
+                                            new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
+                                                            .setTunnelType(TunnelTypeGre.class).setSubnets(subnetList)
+                                                            .setZoneName(tZ).build();
+                        }
+                    } else {
+                        tZone =
+                                        new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
+                                                        .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList).setZoneName(tZ)
+                                                        .build();
+                    }
+                    LOG.debug("tzone object" + tZone);
+                    tZoneList.add(tZone);
+                }
+                tZonesBuilt = new TransportZonesBuilder().setTransportZone(tZoneList).build();
+                InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
+                LOG.debug("InstanceIdentifier" + path);
+                ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tZonesBuilt, dataBroker,
+                                ItmUtils.DEFAULT_CALLBACK);
+                LOG.debug("wrote to Config DS" + tZonesBuilt);
+                tZones.clear();
+                tZoneList.clear();
+                subnetList.clear();
+                LOG.debug("Everything cleared");
+            } else {
+                LOG.debug("NO vteps were configured");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void showTeps(boolean monitorEnabled, int monitorInterval) {
+        boolean flag = false;
+        InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
+        Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
+        if (tZonesOptional.isPresent()) {
+            TransportZones tZones = tZonesOptional.get();
+            if(tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty())
+            {
+                System.out.println("No teps configured");
+                return;
+            }
+            List<String> result = new ArrayList<String>();
+            result.add(String.format("Tunnel Monitoring (for VXLAN tunnels): %s", (monitorEnabled ? "On" : "Off")));
+            result.add(String.format("Tunnel Monitoring Interval (for VXLAN tunnels): %d", monitorInterval));
+            result.add(System.lineSeparator());
+            result.add(String.format("%-16s  %-16s  %-16s  %-12s  %-12s %-12s %-12s %-12s", "TransportZone", "TunnelType", "SubnetMask",
+                            "GatewayIP", "VlanID", "DpnID", "IPAddress", "PortName"));
+            result.add("--------------------------------------------------------------------------------------------------------------");
+            for (TransportZone tZ : tZones.getTransportZone()) {
+                if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty()) {
+                    LOG.error("Transport Zone " + tZ.getZoneName() + "has no subnets");
+                    continue;
+                }
+                for (Subnets sub : tZ.getSubnets()) {
+                    if (sub.getVteps() == null || sub.getVteps().isEmpty()) {
+                        LOG.error("Transport Zone " + tZ.getZoneName() + "subnet " + sub.getPrefix() + "has no vteps");
+                        continue;
+                    }
+                    for (Vteps vtep : sub.getVteps()) {
+                        flag = true;
+                        String strTunnelType ;
+                        if( (tZ.getTunnelType()).equals(TunnelTypeGre.class) )
+                          strTunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
+                        else
+                          strTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
+                        result.add(String.format("%-16s  %-16s  %-16s  %-12s  %-12s %-12s %-12s %-12s", tZ.getZoneName(), strTunnelType, sub
+                                        .getPrefix().getIpv4Prefix().getValue(), sub.getGatewayIp().getIpv4Address()
+                                        .getValue(), sub.getVlanId().toString(), vtep.getDpnId().toString(), vtep
+                                        .getIpAddress().getIpv4Address().getValue(), vtep.getPortname().toString()));
+                    }
+                }
+            }
+            if (flag == true) {
+                for (String p : result) {
+                    System.out.println(p);
+                }
+            } else
+                System.out.println("No teps to display");
+        } else
+            System.out.println("No teps configured");
+    }
+
+
+    public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
+                    String gatewayIp, String transportZone) {
+
+        IpAddress ipAddressObj = null;
+        IpAddress gatewayIpObj = null;
+        IpPrefix subnetMaskObj = null;
+        VtepsKey vtepkey = new VtepsKey(dpnId, portName);
+        try {
+            ipAddressObj = new IpAddress(ipAddress.toCharArray());
+            gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
+            if (gatewayIp != null) {
+                gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
+            } else {
+                LOG.debug("gateway is null");
+            }
+        } catch (Exception e) {
+            System.out.println("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255");
+            return;
+        }
+        try {
+            subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
+        } catch (Exception e) {
+            System.out.println("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32");
+            return;
+        }
+
+        if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
+            System.out.println("IpAddress and gateWayIp should belong to the subnet provided");
+            return;
+        }
+        SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
+        Vteps vtepCli = null;
+        Subnets subCli = null;
+
+        InstanceIdentifier<Vteps> vpath =
+                        InstanceIdentifier.builder(TransportZones.class)
+                                        .child(TransportZone.class, new TransportZoneKey(transportZone))
+                                        .child(Subnets.class, subnetsKey).child(Vteps.class, vtepkey).build();
+        // check if present in tzones and delete from cache
+        boolean existsInCache = isInCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone);
+        if (!existsInCache) {
+            Optional<Vteps> vtepOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, vpath, dataBroker);
+            if (vtepOptional.isPresent()) {
+                vtepCli = vtepOptional.get();
+                if(vtepCli.getIpAddress().equals(ipAddressObj)){
+                    InstanceIdentifier<Subnets> spath =
+                                    InstanceIdentifier
+                                                    .builder(TransportZones.class)
+                                                    .child(TransportZone.class, new TransportZoneKey(transportZone))
+                                                    .child(Subnets.class, subnetsKey).build();
+                    Optional<Subnets> subOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, spath, dataBroker);
+                    if (subOptional.isPresent()) {
+                        subCli = subOptional.get();
+                        if(subCli.getGatewayIp().equals(gatewayIpObj) && subCli.getVlanId().equals(vlanId)){
+                    vtepDelCommitList.add(vtepCli);
+                      }
+                        else
+                            System.out.println(String.format("vtep with this vlan or gateway doesnt exist"));
+                        }
+                }
+                else 
+                    System.out.println(String.format("Vtep with this ipaddress doesnt exist"));
+                } else {
+                System.out.println(String.format("Vtep Doesnt exist"));
+            }
+        }
+    }
+
+    public <T extends DataObject> void deleteOnCommit() {
+        List<InstanceIdentifier<T>> vtepPaths = new ArrayList<>();
+        List<InstanceIdentifier<T>> subnetPaths = new ArrayList<>();
+        List<InstanceIdentifier<T>> tzPaths = new ArrayList<>();
+        List<Subnets> subDelList = new ArrayList<Subnets>();
+        List<TransportZone> tzDelList = new ArrayList<TransportZone>();
+        List<Vteps> vtepDelList = new ArrayList<Vteps>();
+        List<InstanceIdentifier<T>> allPaths = new ArrayList<>();
+        try {
+            if (vtepDelCommitList != null && !vtepDelCommitList.isEmpty()) {
+                InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
+                Optional<TransportZones> tZonesOptional =
+                                ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
+                if (tZonesOptional.isPresent()) {
+                    TransportZones tZones = tZonesOptional.get();
+                    for (TransportZone tZ : tZones.getTransportZone()) {
+                        if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
+                            continue;
+                        for (Subnets sub : tZ.getSubnets()) {
+                            vtepDelList.addAll(vtepDelCommitList);
+                            for (Vteps vtep : vtepDelList) {
+                                InstanceIdentifier<T> vpath =
+                                                (InstanceIdentifier<T>) InstanceIdentifier
+                                                                .builder(TransportZones.class)
+                                                                .child(TransportZone.class, tZ.getKey())
+                                                                .child(Subnets.class, sub.getKey())
+                                                                .child(Vteps.class, vtep.getKey()).build();
+                                if (sub.getVteps().remove(vtep)) {
+                                    vtepPaths.add(vpath);
+                                    if (sub.getVteps().size() == 0 || sub.getVteps() == null) {
+                                        subDelList.add(sub);
+                                    }
+
+                                }
+                            }
+                        }
+                    }
+
+                    for (TransportZone tZ : tZones.getTransportZone()) {
+                        if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
+                            continue;
+                        for (Subnets sub : subDelList) {
+                            if (tZ.getSubnets().remove(sub)) {
+                                InstanceIdentifier<T> spath =
+                                                (InstanceIdentifier<T>) InstanceIdentifier
+                                                                .builder(TransportZones.class)
+                                                                .child(TransportZone.class, tZ.getKey())
+                                                                .child(Subnets.class, sub.getKey()).build();
+                                subnetPaths.add(spath);
+                                if (tZ.getSubnets() == null || tZ.getSubnets().size() == 0) {
+                                    tzDelList.add(tZ);
+                                }
+                            }
+                        }
+                    }
+
+                    for (TransportZone tZ : tzDelList) {
+                        if (tZones.getTransportZone().remove(tZ)) {
+                            InstanceIdentifier<T> tpath =
+                                            (InstanceIdentifier<T>) InstanceIdentifier.builder(TransportZones.class)
+                                                            .child(TransportZone.class, tZ.getKey()).build();
+                            tzPaths.add(tpath);
+                            if (tZones.getTransportZone() == null || tZones.getTransportZone().size() == 0) {
+                                MDSALDataStoreUtils.asyncRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, path,
+                                                ItmUtils.DEFAULT_CALLBACK);
+                                return;
+                            }
+                        }
+                    }
+                    allPaths.addAll(vtepPaths);
+                    allPaths.addAll(subnetPaths);
+                    allPaths.addAll(tzPaths);
+                    ItmUtils.asyncBulkRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, allPaths,
+                                    ItmUtils.DEFAULT_CALLBACK);
+                }
+                vtepPaths.clear();
+                subnetPaths.clear();
+                tzPaths.clear();
+                allPaths.clear();
+                vtepDelCommitList.clear();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+/*
+    public void showState(TunnelsState tunnelsState, boolean tunnelMonitorEnabled) {
+        List<StateTunnelList> tunnelLists = tunnelsState.getStateTunnelList();
+        if (tunnelLists == null || tunnelLists.isEmpty()) {
+            System.out.println("No Logical Tunnels Exist");
+            return;
+        }
+        if (!tunnelMonitorEnabled) {
+            System.out.println("Tunnel Monitoring is Off");
+        }
+        System.out.println(String.format("%-16s  %-16s  %-16s  %-10s  %-16s %-8s  %-10s  %-10s", "Source-DPN",
+                        "Destination-DPN", "SourcePortName", "Source-IP", "Destination-IP", "VLan-ID", "Trunk-State",
+                        "Logical-Tunnel-State"));
+        System.out.println("----------------------------------------------------------------------------------------------------------------------");
+
+        for (StateTunnelList tunnel : tunnelLists) {
+            String logicaltunnelState = (tunnel.isLogicalTunnelState()) ? "UP" : "DOWN";
+            try {
+                List<String> trunks =
+                                interfaceManager.getTunnelInterfacesOfLogicalGroup(tunnel.getLogicalTunnelGroupName());
+                if (trunks != null && !trunks.isEmpty()) {
+                    for (String trunk : trunks) {
+                        List<String> params = Arrays.asList(trunk.split(":"));
+                        LOG.trace("trunk {} for LogicalIf {} ", trunk, tunnel.getLogicalTunnelGroupName());
+                        String trunkState = (OperationalIfmUtil.isInterfaceUp(dataBroker, trunk)) ? "UP" : "DOWN";
+                        System.out.println(String.format("%-16s  %-16s  %-16s  %-10s  %-16s %-8s  %-10s  %-10s", tunnel
+                                        .getSourceDPN().toString(), tunnel.getDestinationDPN().toString(), params
+                                        .get(1), params.get(3), params.get(4), params.get(2), trunkState,
+                                        logicaltunnelState));
+                    }
+                } else {
+                    LOG.error("No trunks for " + tunnel.getLogicalTunnelGroupName());
+                }
+
+            } catch (InterfaceNotFoundException e) {
+                LOG.error("if not found " + tunnel.getLogicalTunnelGroupName());
+            }
+        }
+    }
+*/
+    // deletes from ADD-cache if it exists.
+    public boolean isInCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
+                    String gatewayIp, String transportZone) {
+        boolean exists = false;
+        VtepsKey vtepkey = new VtepsKey(dpnId, portName);
+        IpAddress ipAddressObj = new IpAddress(ipAddress.toCharArray());
+        IpPrefix subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
+        IpAddress gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
+        if (gatewayIp != null) {
+            gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
+        } else {
+            LOG.debug("gateway is null");
+        }
+        SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
+        Vteps vtepCli =
+                        new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
+                                        .setPortname(portName).build();
+        SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
+
+        if (tZones.containsKey(transportZone)) {
+            Map<SubnetObject, List<Vteps>> subVtepMapTemp = (Map<SubnetObject, List<Vteps>>) tZones.get(transportZone);
+            if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
+                List<Vteps> vtepListTemp = (List<Vteps>) subVtepMapTemp.get(subObCli);
+                if (vtepListTemp.contains(vtepCli)) {
+                    exists = true; // return true if tzones has vtep
+                    vtepListTemp.remove(vtepCli);
+                    if (vtepListTemp.size() == 0) {
+                        subVtepMapTemp.remove(subObCli);
+                        if (subVtepMapTemp.size() == 0) {
+                            tZones.remove(transportZone);
+                        }
+                    }
+                } else {
+                    System.out.println("Vtep " + "has not been configured");
+                }
+            }
+        }
+        return exists;
+    }
+
+    public void configureTunnelType(String tZoneName, String tunnelType) {
+        LOG.debug("configureTunnelType {} for transportZone {}", tunnelType, tZoneName);
+
+        TransportZone tZoneFromConfigDS = getTransportZoneFromConfigDS(tZoneName);
+        validateTunnelType(tZoneName, tunnelType,tZoneFromConfigDS);
+
+        if (tZoneFromConfigDS != null) {
+            LOG.debug("Transport zone {} with tunnel type {} already exists. No action required.", tZoneName,
+                    tunnelType);
+            return;
+        }
+        TransportZones transportZones = null;
+        List<TransportZone> tZoneList = null;
+        InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
+        Optional<TransportZones> tZones = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
+        Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
+        if( tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN))
+            tunType = TunnelTypeVxlan.class ;
+        else if( tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE) )
+            tunType = TunnelTypeGre.class ;
+
+        TransportZone tZone = new TransportZoneBuilder().setKey(new TransportZoneKey(tZoneName))
+                .setTunnelType(tunType).build();
+        if (tZones.isPresent()) {
+            tZoneList = tZones.get().getTransportZone();
+            if(tZoneList == null || tZoneList.isEmpty()) {
+                tZoneList = new ArrayList<TransportZone>();
+            }
+        } else {
+            tZoneList = new ArrayList<TransportZone>();
+        }
+        tZoneList.add(tZone);
+        transportZones = new TransportZonesBuilder().setTransportZone(tZoneList).build();
+        ItmUtils.syncWrite(LogicalDatastoreType.CONFIGURATION, path, transportZones, dataBroker);
+
+    }
+
+    /**
+     * Validate tunnel type.
+     *
+     * @param tZoneName
+     *            the t zone name
+     * @param tunnelType
+     *            the tunnel type
+     */
+    private void validateTunnelType(String tZoneName, String tunnelType,TransportZone tZoneFromConfigDS) {
+        /*
+        String strTunnelType = ItmUtils.validateTunnelType(tunnelType);
+
+        TransportZone tZone = getTransportZone(tZoneName);
+        if (tZone != null) {
+            if (!StringUtils.equalsIgnoreCase(strTunnelType, tZone.getTunnelType())
+                    && ItmUtils.isNotEmpty(tZone.getSubnets())) {
+                String errorMsg = new StringBuilder("Changing the tunnel type from ").append(tZone.getTunnelType())
+                        .append(" to ").append(strTunnelType)
+                        .append(" is not allowed for already configured transport zone [").append(tZoneName)
+                        .append("].").toString();
+                Preconditions.checkArgument(false, errorMsg);
+            }
+        }
+        */
+        String strTunnelType = ItmUtils.validateTunnelType(tunnelType);
+        Class<? extends TunnelTypeBase> tunType ;
+        if( strTunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN))
+            tunType = TunnelTypeVxlan.class ;
+        else 
+            tunType = TunnelTypeGre.class ;
+        //TransportZone tZone = getTransportZone(tZoneName);
+       // if (tZone != null) {
+        if (tZoneFromConfigDS != null) {  
+        if( (!tZoneFromConfigDS.getTunnelType().equals(tunType))  && ItmUtils.isNotEmpty(tZoneFromConfigDS.getSubnets())) {
+              String errorMsg = new StringBuilder("Changing the tunnel type from ").append(tZoneFromConfigDS.getTunnelType())
+                       .append(" to ").append(strTunnelType)
+                       .append(" is not allowed for already configured transport zone [").append(tZoneName)
+                       .append("].").toString();
+               Preconditions.checkArgument(false, errorMsg);
+           }
+        }
+    }
+
+    public void configureTunnelMonitorEnabled(boolean monitorEnabled) {
+        InstanceIdentifier<TunnelMonitorEnabled> path = InstanceIdentifier.builder(TunnelMonitorEnabled.class).build();
+        Optional<TunnelMonitorEnabled> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
+        if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().isEnabled() != monitorEnabled) {
+            TunnelMonitorEnabled tunnelMonitor = new TunnelMonitorEnabledBuilder().setEnabled(monitorEnabled).build();
+            ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
+                                            ItmUtils.DEFAULT_CALLBACK);
+        }
+    }
+
+    public void configureTunnelMonitorInterval(int interval) {
+        InstanceIdentifier<TunnelMonitorInterval> path = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
+        Optional<TunnelMonitorInterval> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
+        if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().getInterval() != interval) {
+            TunnelMonitorInterval tunnelMonitor = new TunnelMonitorIntervalBuilder().setInterval(interval).build();
+            ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
+                                            ItmUtils.DEFAULT_CALLBACK);
+        }
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepCommit.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepCommit.java
new file mode 100644 (file)
index 0000000..3d46c31
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+@Command(scope = "tep", name = "commit",
+    description = "commits the configuration so that actual tunnel-building happens")
+public class TepCommit extends OsgiCommandSupport {
+  private static final Logger logger = LoggerFactory.getLogger(TepCommit.class);
+
+  private IITMProvider itmProvider;
+
+  public void setItmProvider(IITMProvider itmProvider) {
+    this.itmProvider = itmProvider;
+  }
+
+  @Override
+  protected Object doExecute() throws Exception {
+
+    try {
+      itmProvider.commitTeps();
+      logger.debug("Executing commit TEP command");
+    } catch (NullPointerException e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepConfigureTunnelType.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepConfigureTunnelType.java
new file mode 100644 (file)
index 0000000..aabab22
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+@Command(scope = "tep", name = "configure-tunnelType",
+        description = "configuring the tunnel type for a transport zone")
+public class TepConfigureTunnelType extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "TransportZoneName", description = "TransportZoneName", required = true, multiValued = false)
+    private String tZoneName;
+    @Argument(index = 1, name = "TunnelType", description = "Tunnel-Type", required = true, multiValued = false)
+    private String tunnelType;
+
+
+    private static final Logger LOG = LoggerFactory.getLogger(TepConfigureTunnelType.class);
+
+    private IITMProvider itmProvider;
+
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            LOG.debug("TepConfigureTunnelType: configureTunnelType {} for transportZone {}", tunnelType, tZoneName);
+            itmProvider.configureTunnelType(tZoneName, tunnelType);
+        } catch (IllegalArgumentException e) {
+            System.out.println(e.getMessage());
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            LOG.error("Exception occurred during execution of command \"tep:configure-tunnelType\": ", e);
+        }
+        return null;
+    }
+
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepDelete.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepDelete.java
new file mode 100644 (file)
index 0000000..0ecba0b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import java.math.BigInteger;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "tep", name = "delete", description = "deleting a tunnel end point")
+public class TepDelete extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "dpnId", description = "DPN-ID", required = false, multiValued = false)
+    private BigInteger dpnId;
+    @Argument(index = 1, name = "portName", description = "port-number", required = false, multiValued = false)
+    private String portName;
+    @Argument(index = 2, name = "vlanId", description = "vlan-id", required = false, multiValued = false)
+    private Integer vlanId;
+    @Argument(index = 3, name = "ipAddress", description = "ip-address", required = false, multiValued = false)
+    private String ipAddress;
+    @Argument(index = 4, name = "subnetMask", description = "subnet-Mask", required = false, multiValued = false)
+    private String subnetMask;
+    @Argument(index = 5, name = "gatewayIp", description = "gateway-ip", required = false, multiValued = false)
+    private String gatewayIp;
+    @Argument(index = 6, name = "transportZone", description = "transport_zone", required = false, multiValued = false)
+    private String transportZone;
+
+    private static final Logger logger = LoggerFactory.getLogger(TepDelete.class);
+    private IITMProvider itmProvider;
+
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+    @Override
+    protected Object doExecute() throws Exception {
+
+        if (dpnId == null || portName == null || vlanId == null || ipAddress == null || subnetMask == null
+                        || transportZone == null) {
+            System.out.println("Insufficient Arguments");
+            System.out.println("Correct Usage : exec tep-delete dpnId portName vlanId ipAddress subnetMask gatewayIp transportZone");
+            return null;
+        }
+        itmProvider.deleteVtep(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone);        
+        logger.trace("Executing delete TEP command");
+
+        return null;
+
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepDeleteDatastore.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepDeleteDatastore.java
new file mode 100644 (file)
index 0000000..1960a51
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+//import org.opendaylight.vpnservice.interfacemgr.util.ConfigIfmUtil;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.vpnservice.mdsalutil.MDSALDataStoreUtils;
+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.opendaylight.inventory.rev130819.Nodes;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.Tunnels;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.TunnelsState;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels_state.StateTunnelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones;
+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.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+
+@Command(scope = "tep", name = "deleteDatastore", description = "view the configured tunnel endpoints")
+public class TepDeleteDatastore <T extends DataObject>  extends OsgiCommandSupport {
+    private static final Logger logger = LoggerFactory.getLogger(TepDeleteDatastore.class);
+    private IITMProvider itmProvider;
+
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+            DataBroker dataBroker =  itmProvider.getDataBroker();
+            InstanceIdentifier < TransportZones > itmConfigPath = InstanceIdentifier.builder(TransportZones.class).build();
+           // InstanceIdentifier<Tunnels> tunnelsConfigPath = InstanceIdentifier.builder(Tunnels.class).build();
+            InstanceIdentifier<Interfaces> InterfacesConfigPath = InstanceIdentifier.builder(Interfaces.class).build();
+           // InstanceIdentifier<TunnelsState> tnStateOpPath = InstanceIdentifier.builder(TunnelsState.class).build();
+            InstanceIdentifier<InterfacesState> ifStateOpPath = InstanceIdentifier.builder(InterfacesState.class).build();
+            InstanceIdentifier<Nodes> frmConfigPath = InstanceIdentifier.builder(Nodes.class).build();
+            List<InstanceIdentifier<T>> allConfigPaths =
+                            new ArrayList<>();
+            allConfigPaths.add((InstanceIdentifier<T>) itmConfigPath);
+            allConfigPaths.add((InstanceIdentifier<T>) InterfacesConfigPath);
+            allConfigPaths.add((InstanceIdentifier<T>) frmConfigPath);
+            //allConfigPaths.add((InstanceIdentifier<T>) tunnelsConfigPath);
+            ItmUtils.asyncBulkRemove(dataBroker, LogicalDatastoreType.CONFIGURATION,allConfigPaths,
+                            ItmUtils.DEFAULT_CALLBACK);
+            List<InstanceIdentifier<T>> allOperationalPaths =
+                            new ArrayList<>();
+           // allOperationalPaths.add((InstanceIdentifier<T>) tnStateOpPath);
+            allOperationalPaths.add((InstanceIdentifier<T>) ifStateOpPath);
+            ItmUtils.asyncBulkRemove(dataBroker, LogicalDatastoreType.OPERATIONAL, allOperationalPaths,
+                            ItmUtils.DEFAULT_CALLBACK);
+            
+        return null;
+    }
+
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepEnableTunnelMonitor.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepEnableTunnelMonitor.java
new file mode 100644 (file)
index 0000000..622d3d9
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "tep", name = "enable-tunnel-monitor", description = "switch ON/OFF supervision of VxLAN tunnels")
+public class TepEnableTunnelMonitor extends OsgiCommandSupport {
+
+    private static final Logger logger = LoggerFactory.getLogger(TepEnableTunnelMonitor.class);
+
+    @Argument(index = 0, name = "true|false", description = "true|false to enable/disable Tunnel Monitoring", required = true, multiValued = false)
+    private Boolean enableTunnelMonitor;
+
+    private IITMProvider itmProvider;
+
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing Enable Tunnel Monitor command");
+            itmProvider.configureTunnelMonitorEnabled(enableTunnelMonitor);
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepMonitor.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepMonitor.java
new file mode 100644 (file)
index 0000000..a693919
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "tep", name = "monitor-interval", description = "configuring tunnel monitoring time interval")
+public class TepMonitor extends OsgiCommandSupport {
+
+  @Argument(index = 0, name = "interval", description = "monitoring interval", required = true,
+      multiValued = false)
+  private Integer interval;
+
+  private static final Logger logger = LoggerFactory.getLogger(TepMonitor.class);
+  private IITMProvider itmProvider;
+
+  public void setItmProvider(IITMProvider itmProvider) {
+    this.itmProvider = itmProvider;
+  }
+
+  @Override
+  protected Object doExecute() {
+    try {
+      logger.debug("Executing TEP monitor command with interval: " + "\t" + interval);
+      if(!(interval >= 5 && interval <=30)){
+          System.out.println("Monitoring Interval must be in the range 5 - 30");
+      }
+      else {
+          itmProvider.configureTunnelMonitorInterval(interval);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepShow.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepShow.java
new file mode 100644 (file)
index 0000000..cb44ded
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones;
+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.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+
+@Command(scope = "tep", name = "show", description = "view the configured tunnel endpoints")
+public class TepShow extends OsgiCommandSupport {
+    private static final Logger logger = LoggerFactory.getLogger(TepShow.class);
+    private IITMProvider itmProvider;
+
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        logger.debug("Executing show TEP command");
+            itmProvider.showTeps();
+        return null;
+    }
+
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepShowState.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepShowState.java
new file mode 100644 (file)
index 0000000..a2a254d
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import com.google.common.base.Optional;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.TunnelsState;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Command(scope = "tep", name = "show-state", description="Monitors tunnel state")
+
+    public class TepShowState extends OsgiCommandSupport {
+
+    private IITMProvider itmProvider;
+
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        /*
+        DataBroker broker = itmProvider.getDataBroker();
+        List<String> result = new ArrayList<String>();
+        InstanceIdentifier<TunnelsState> path = InstanceIdentifier.builder(TunnelsState.class).build();
+        Optional<TunnelsState> tunnels = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, path, broker);
+        if (tunnels.isPresent()) {
+            itmProvider.showState(tunnels.get());
+        }
+        else
+            System.out.println("No Logical Tunnels Exist");
+            */
+        System.out.println( "Logical Tunnels state is not currently supported");
+        return null;
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepStateShow.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/TepStateShow.java
new file mode 100644 (file)
index 0000000..6d7d8d3
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+@Command(scope = "tep", name = "state-show", description="Monitors tunnel state")
+
+    public class TepStateShow extends OsgiCommandSupport {
+
+       @Override
+
+       protected Object doExecute() throws Exception {
+
+              System.out.println("Executing show TEP states command");
+
+       return null;
+
+       }
+    }
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaAdd.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaAdd.java
new file mode 100644 (file)
index 0000000..5e74bb1
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.itm.globals.ITMConstants;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.vpnservice.itm.cli.ItmCliUtils;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Class which implements karaf command "vtep:schema-add".
+ */
+@Command(scope = "vtep", name = "schema-add", description = "Adding a VTEP schema.")
+public class VtepSchemaAdd extends OsgiCommandSupport {
+
+    private static final String SCHEMA_NAME = "--schema-name";
+    private static final String PORT_NAME = "--port-name";
+    private static final String VLAN_ID = "--vlan-id";
+    private static final String SUBNET_CIDR = "--subnet-cidr";
+    private static final String TRANSPORT_ZONE = "--transport-zone";
+    private static final String DPN_IDS = "--dpn-ids";
+    private static final String GATEWAY_IP = "--gateway-ip";
+    private static final String TUNNEL_TYPE = "--tunnel-type";
+    private static final String EXCLUDE_IP_FILTER = "--exclude-ip-filter";
+
+    /** The schema name. */
+    @Option(name = SCHEMA_NAME, aliases = { "-s" }, description = "Schema name", required = true, multiValued = false)
+    private String schemaName;
+
+    /** The port name. */
+    @Option(name = PORT_NAME, aliases = { "-p" }, description = "Port name", required = true, multiValued = false)
+    private String portName;
+
+    /** The vlan id. */
+    @Option(name = VLAN_ID, aliases = { "-v" }, description = "VLAN ID", required = true, multiValued = false)
+    private Integer vlanId;
+
+    /** The subnet mask. */
+    @Option(name = SUBNET_CIDR, aliases = {
+            "-sc" }, description = "Subnet Mask in CIDR-notation string, e.g. 10.0.0.0/24", required = true, multiValued = false)
+    private String subnetCIDR;
+
+    /** The transport zone. */
+    @Option(name = TRANSPORT_ZONE, aliases = {
+            "-tz" }, description = "Transport zone", required = true, multiValued = false)
+    private String transportZone;
+
+    /** The dpn ids. */
+    @Option(name = DPN_IDS, aliases = {
+            "-d" }, description = "DPN ID's in comma separated values. e.g: 2,3,10", required = false, multiValued = false)
+    private String dpnIds;
+
+    /** The gateway ip. */
+    @Option(name = GATEWAY_IP, aliases = {
+            "-g" }, description = "Gateway IP address", required = false, multiValued = false)
+    private String gatewayIp;
+
+    /** The tunnel type. */
+    @Option(name = TUNNEL_TYPE, aliases = {
+            "-t" }, description = "Tunnel type. Value: VXLAN | GRE. Default: VXLAN", required = false, multiValued = false)
+    private String tunnelType;
+
+    /** The exclude ip filter. */
+    @Option(name = EXCLUDE_IP_FILTER, aliases = {
+            "-ex" }, description = "IP Addresses which needs to be excluded from the specified subnet. IP address range or comma separated IP addresses can to be specified. e.g: 10.0.0.1-10.0.0.20,10.0.0.30,10.0.0.35", required = false, multiValued = false)
+    private String excludeIpFilter;
+
+    /** The Constant logger. */
+    private static final Logger LOG = LoggerFactory.getLogger(VtepSchemaAdd.class);
+
+    /** The itm provider. */
+    private IITMProvider itmProvider;
+
+    /**
+     * Sets the itm provider.
+     *
+     * @param itmProvider
+     *            the new itm provider
+     */
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    /**
+     * Command Usage.
+     */
+    private void usage() {
+        System.out.println(String.format(
+                "usage: vtep:schema-add [%s schema-name] [%s port-name] [%s vlan-id] [%s subnet-cidr] [%s transport-zone] [%s dpn-ids] [%s gateway-ip] [%s tunnel-type] [%s exclude-ip-filter]",
+                SCHEMA_NAME, PORT_NAME, VLAN_ID, SUBNET_CIDR, TRANSPORT_ZONE, DPN_IDS, GATEWAY_IP, TUNNEL_TYPE,
+                EXCLUDE_IP_FILTER));
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.karaf.shell.console.AbstractAction#doExecute()
+     */
+    @Override
+    protected Object doExecute() {
+        try {
+            if (this.schemaName == null || this.portName == null || this.vlanId == null || this.subnetCIDR == null
+                    || this.transportZone == null) {
+                usage();
+                return null;
+            }
+            LOG.debug("Executing vtep:schema-add command\t {} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \t {}", schemaName,
+                    portName, vlanId, subnetCIDR, gatewayIp, transportZone, tunnelType, dpnIds, excludeIpFilter);
+
+            if( null == tunnelType) {
+                tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
+            }
+            VtepConfigSchema schema = ItmUtils.constructVtepConfigSchema(schemaName, portName, vlanId, subnetCIDR,
+                    gatewayIp, transportZone, tunnelType, ItmCliUtils.constructDpnIdList(dpnIds), excludeIpFilter);
+            this.itmProvider.addVtepConfigSchema(schema);
+
+        } catch (IllegalArgumentException e) {
+            System.out.println(e.getMessage());
+        } catch (Exception e) {
+            LOG.error("Exception occurred during execution of command \"vtep:schema-add\": ", e);
+        }
+        return null;
+    }
+
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaDelete.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaDelete.java
new file mode 100644 (file)
index 0000000..5b7a22a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Class which implements karaf command "vtep:schema-delete".
+ */
+@Command(scope = "vtep", name = "schema-delete", description = "Delete VTEP schema.")
+public class VtepSchemaDelete extends OsgiCommandSupport {
+
+    private static final String ALL = "all";
+
+    @Argument(index = 0, name = ALL, description = "Delete all VTEP schemas", required = true, multiValued = false)
+    String deleteAll = null;
+
+    /** The Constant logger. */
+    private static final Logger LOG = LoggerFactory.getLogger(VtepSchemaDelete.class);
+
+    /** The itm provider. */
+    private IITMProvider itmProvider;
+
+    /**
+     * Sets the itm provider.
+     *
+     * @param itmProvider
+     *            the new itm provider
+     */
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    private void usage() {
+        System.out.println("usage: vtep:schema-delete all");
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.karaf.shell.console.AbstractAction#doExecute()
+     */
+    @Override
+    protected Object doExecute() {
+        try {
+            if (this.deleteAll == null || !StringUtils.equalsIgnoreCase(ALL, this.deleteAll)) {
+                usage();
+                return null;
+            }
+            LOG.debug("Executing vtep:schema-delete command\t {} ", this.deleteAll);
+            this.itmProvider.deleteAllVtepSchemas();
+
+        } catch (IllegalArgumentException e) {
+            System.out.println(e.getMessage());
+        } catch (Exception e) {
+            LOG.error("Exception occurred during execution of command \"vtep:schema-delete all\": ", e);
+        }
+        return null;
+    }
+
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaShow.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaShow.java
new file mode 100644 (file)
index 0000000..139b82a
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.itm.globals.ITMConstants;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Class which implements karaf command "vtep:schema-show".
+ */
+@Command(scope = "vtep", name = "schema-show", description = "Show all VTEP schemas.")
+public class VtepSchemaShow extends OsgiCommandSupport {
+
+    /** The schema name. */
+    @Argument(index = 0, name = "schemaName", description = "Schema name", required = false, multiValued = false)
+    private String schemaName;
+
+    private static String VTEP_CONFIG_SCHEMA_CLI_FORMAT = "%-14s %-12s %-8s %-16s %-13s %-14s %-11s %-20s %-32s";
+    public static final String HEADER_UNDERLINE = "---------------------------------------------------------------------------------------------------------------------------------------";
+
+    /** The Constant logger. */
+    private static final Logger LOG = LoggerFactory.getLogger(VtepSchemaShow.class);
+
+    /** The itm provider. */
+    private IITMProvider itmProvider;
+
+    /**
+     * Sets the itm provider.
+     *
+     * @param itmProvider
+     *            the new itm provider
+     */
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.karaf.shell.console.AbstractAction#doExecute()
+     */
+    @Override
+    protected Object doExecute() {
+        LOG.debug("Executing command: schema-show {} ", this.schemaName);
+        try {
+            if (this.schemaName != null) {
+                VtepConfigSchema schema = this.itmProvider.getVtepConfigSchema(this.schemaName);
+                if (schema == null) {
+                    System.out.println("No VTEP schema present with name: " + this.schemaName);
+                } else {
+                    System.out.println(getHeaderOutput());
+                    printSchema(schema);
+                }
+            } else {
+                printAllVtepSchemas();
+            }
+        } catch (Exception e) {
+            LOG.error("Exception occurred during execution of command \"vtep:schema-show\": ", e);
+        }
+        return null;
+    }
+
+    /**
+     * Prints all vtep schemas.
+     */
+    private void printAllVtepSchemas() {
+        List<VtepConfigSchema> schemas = this.itmProvider.getAllVtepConfigSchemas();
+        if (schemas == null || schemas.isEmpty()) {
+            System.out.println("No VTEP schemas present.");
+            return;
+        }
+        System.out.println(getHeaderOutput());
+        for (VtepConfigSchema schema : schemas) {
+            printSchema(schema);
+        }
+    }
+
+    /**
+     * Prints the schema.
+     *
+     * @param schema
+     *            the schema
+     */
+    private void printSchema(VtepConfigSchema schema) {
+        List<BigInteger> lstDpnIds = (schema.getDpnIds() == null) ? Collections.<BigInteger> emptyList()
+                : ItmUtils.getDpnIdList(schema.getDpnIds());
+        List<String> lstIpFilter = getExcludeIpFilterAsList(schema.getExcludeIpFilter());
+
+        Iterator<BigInteger> dpnIterator = lstDpnIds.iterator();
+        Iterator<String> ipFilterIterator = lstIpFilter.iterator();
+
+        String portName = StringUtils.defaultString(schema.getPortName());
+        String vlanId = String.valueOf(schema.getVlanId());
+        String subnetCIDR = (schema.getSubnet() == null) ? StringUtils.EMPTY
+                : String.valueOf(schema.getSubnet().getValue());
+        String gatewayIp = (schema.getGatewayIp() == null) ? StringUtils.EMPTY
+                : String.valueOf(schema.getGatewayIp().getValue());
+        String transportZone = StringUtils.defaultString(schema.getTransportZoneName());
+        String strTunnelType ;
+
+        Class<? extends TunnelTypeBase> tunType = schema.getTunnelType();
+
+        if( tunType.equals(TunnelTypeGre.class) )
+            strTunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
+        else
+            strTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
+        String dpnId = (dpnIterator.hasNext() ? String.valueOf(dpnIterator.next()) : StringUtils.EMPTY);
+        String excludeIpFilter = (ipFilterIterator.hasNext() ? String.valueOf(ipFilterIterator.next())
+                : StringUtils.EMPTY);
+
+        // Print first row
+        System.out.println(String.format(VTEP_CONFIG_SCHEMA_CLI_FORMAT, schema.getSchemaName(), portName, vlanId,
+                subnetCIDR, gatewayIp, transportZone, strTunnelType, dpnId, excludeIpFilter));
+        while (dpnIterator.hasNext() || ipFilterIterator.hasNext()) {
+            dpnId = (dpnIterator.hasNext() ? String.valueOf(dpnIterator.next()) : StringUtils.EMPTY);
+            excludeIpFilter = (ipFilterIterator.hasNext() ? String.valueOf(ipFilterIterator.next())
+                    : StringUtils.EMPTY);
+            System.out.println(String.format(VTEP_CONFIG_SCHEMA_CLI_FORMAT, StringUtils.EMPTY, StringUtils.EMPTY,
+                    StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY,
+                    dpnId, excludeIpFilter));
+        }
+        System.out.println(System.lineSeparator());
+    }
+
+    /**
+     * Gets the exclude ip filter as list.
+     *
+     * @param excludeIpFilter
+     *            the exclude ip filter
+     * @return the exclude ip filter as list
+     */
+    private List<String> getExcludeIpFilterAsList(String excludeIpFilter) {
+        if (StringUtils.isBlank(excludeIpFilter)) {
+            return Collections.emptyList();
+        }
+        final String[] arrIpsOrRange = StringUtils.split(excludeIpFilter, ',');
+        return Arrays.asList(arrIpsOrRange);
+    }
+
+    /**
+     * Gets the vtep config schema header output.
+     *
+     * @return the vtep config schema header output
+     */
+    private String getHeaderOutput() {
+        StringBuilder headerBuilder = new StringBuilder();
+        headerBuilder.append(String.format(VTEP_CONFIG_SCHEMA_CLI_FORMAT, "SchemaName", "PortName", "VlanID", "Subnet",
+                "GatewayIP", "TransportZone", "TunnelType", "DPN-IDS", "ExcludeIpFilter"));
+        headerBuilder.append('\n');
+        headerBuilder.append(HEADER_UNDERLINE);
+        return headerBuilder.toString();
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaUpdate.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/cli/VtepSchemaUpdate.java
new file mode 100644 (file)
index 0000000..008214b
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016 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.itm.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Class which implements karaf command "vtep:schema-update".
+ */
+@Command(scope = "vtep", name = "schema-update", description = "Update VTEP schema.")
+public class VtepSchemaUpdate extends OsgiCommandSupport {
+
+    private static final String SCHEMA_NAME = "--schema-name";
+    private static final String AD = "--add-dpn-ids";
+    private static final String DD = "--del-dpn-ids";
+
+    /** The schema name. */
+    @Option(name = SCHEMA_NAME, aliases = { "-s" }, description = "Schema name", required = true, multiValued = false)
+    private String schemaName;
+
+    /** The dpn ids for add. */
+    @Option(name = AD, aliases = {
+            "-ad" }, description = "DPN ID's to be added to schema in a comma separated value format. e.g: 2,3,10", required = false, multiValued = false)
+    private String dpnIdsForAdd;
+
+    /** The dpn ids for delete. */
+    @Option(name = DD, aliases = {
+            "-dd" }, description = "DPN ID's to be deleted from schema in a comma separated value format. e.g: 2,3,10", required = false, multiValued = false)
+    private String dpnIdsForDelete;
+
+    /** The Constant logger. */
+    private static final Logger LOG = LoggerFactory.getLogger(VtepSchemaUpdate.class);
+
+    /** The itm provider. */
+    private IITMProvider itmProvider;
+
+    /**
+     * Sets the itm provider.
+     *
+     * @param itmProvider
+     *            the new itm provider
+     */
+    public void setItmProvider(IITMProvider itmProvider) {
+        this.itmProvider = itmProvider;
+    }
+
+    /**
+     * Command Usage.
+     */
+    private void usage() {
+        System.out.println(
+                String.format("usage: vtep:schema-update [%s schema-name] [%s dpn-ids-for-add] [%s dpn-ids-for-delete]",
+                        SCHEMA_NAME, AD, DD));
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.karaf.shell.console.AbstractAction#doExecute()
+     */
+    @Override
+    protected Object doExecute() {
+        try {
+            if (this.dpnIdsForAdd == null && this.dpnIdsForDelete == null) {
+                System.out.println(String.format("Atleast one of the parameters [%s or %s] is mandatory", AD, DD));
+                usage();
+                return null;
+            }
+            LOG.debug("Executing vtep:schema-update command\t {} \t {} \t {} ", this.schemaName, this.dpnIdsForAdd,
+                    this.dpnIdsForDelete);
+
+            this.itmProvider.updateVtepSchema(this.schemaName, ItmCliUtils.constructDpnIdList(this.dpnIdsForAdd),
+                    ItmCliUtils.constructDpnIdList(this.dpnIdsForDelete));
+
+        } catch (IllegalArgumentException e) {
+            System.out.println(e.getMessage());
+        } catch (Exception e) {
+            LOG.error("Exception occurred during execution of command \"vtep:schema-update\": ", e);
+        }
+        return null;
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/confighelpers/HwVtep.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/confighelpers/HwVtep.java
new file mode 100644 (file)
index 0000000..800ea62
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016 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.itm.confighelpers;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+
+/**
+ * Created by eanraju on 02-Feb-16.
+ */
+public class HwVtep {
+
+    private String transportZone;
+    private Class<? extends TunnelTypeBase> tunnel_type;
+    private IpPrefix ipPrefix;
+    private IpAddress gatewayIP;
+    private int vlanID;
+    private String topo_id;
+    private String node_id;
+    IpAddress hwIp;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        HwVtep HwVtep = (HwVtep) o;
+
+        if (vlanID != HwVtep.vlanID) return false;
+        if (!transportZone.equals(HwVtep.transportZone)) return false;
+        if (tunnel_type != null ? !tunnel_type.equals(HwVtep.tunnel_type) : HwVtep.tunnel_type != null) return false;
+        if (!ipPrefix.equals(HwVtep.ipPrefix)) return false;
+        if (gatewayIP != null ? !gatewayIP.equals(HwVtep.gatewayIP) : HwVtep.gatewayIP != null) return false;
+        if (!topo_id.equals(HwVtep.topo_id)) return false;
+        if (!node_id.equals(HwVtep.node_id)) return false;
+        return hwIp.equals(HwVtep.hwIp);
+
+    }
+
+    @Override
+    public String toString() {
+        return "HwVtep{" +
+                "transportZone='" + transportZone + '\'' +
+                ", tunnel_type=" + tunnel_type +
+                ", ipPrefix=" + ipPrefix +
+                ", gatewayIP=" + gatewayIP +
+                ", vlanID=" + vlanID +
+                ", topo_id='" + topo_id + '\'' +
+                ", node_id='" + node_id + '\'' +
+                ", hwIp=" + hwIp +
+                '}';
+    }
+
+    @Override
+    public int hashCode() {
+        int result = transportZone.hashCode();
+        result = 31 * result + (tunnel_type != null ? tunnel_type.hashCode() : 0);
+        result = 31 * result + ipPrefix.hashCode();
+        result = 31 * result + (gatewayIP != null ? gatewayIP.hashCode() : 0);
+        result = 31 * result + vlanID;
+        result = 31 * result + topo_id.hashCode();
+        result = 31 * result + node_id.hashCode();
+        result = 31 * result + hwIp.hashCode();
+        return result;
+    }
+
+    public String getTransportZone() {
+        return transportZone;
+    }
+
+    public void setTransportZone(String transportZone) {
+        this.transportZone = transportZone;
+    }
+
+    public Class<? extends TunnelTypeBase> getTunnel_type() {
+        return tunnel_type;
+    }
+
+    public void setTunnel_type(Class<? extends TunnelTypeBase> tunnel_type) {
+        this.tunnel_type = tunnel_type;
+    }
+
+    public IpPrefix getIpPrefix() {
+        return ipPrefix;
+    }
+
+    public void setIpPrefix(IpPrefix ipPrefix) {
+        this.ipPrefix = ipPrefix;
+    }
+
+    public IpAddress getGatewayIP() {
+        return gatewayIP;
+    }
+
+    public void setGatewayIP(IpAddress gatewayIP) {
+        this.gatewayIP = gatewayIP;
+    }
+
+    public int getVlanID() {
+        return vlanID;
+    }
+
+    public void setVlanID(int vlanID) {
+        this.vlanID = vlanID;
+    }
+
+    public String getTopo_id() {
+        return topo_id;
+    }
+
+    public void setTopo_id(String topo_id) {
+        this.topo_id = topo_id;
+    }
+
+    public String getNode_id() {
+        return node_id;
+    }
+
+    public void setNode_id(String node_id) {
+        this.node_id = node_id;
+    }
+
+    public IpAddress getHwIp() {
+        return hwIp;
+    }
+
+    public void setHwIp(IpAddress hwIp) {
+        this.hwIp = hwIp;
+    }
+}
index 54277d4a6b5a8a7b7bea1a780d5a891b926fcf41..6a0ed5be2bd9c4a032c3a2ceef8ea17a0cc8a75e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -11,23 +11,38 @@ import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.google.common.base.Optional;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.vpnservice.itm.impl.ItmUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+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.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.ExternalTunnelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.TunnelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.DPNTEPsInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnelBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZoneKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.DeviceVteps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.Vteps;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.*;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.commons.net.util.SubnetUtils;
@@ -36,7 +51,7 @@ import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.ListenableFuture;
 
 public class ItmExternalTunnelAddWorker {
-    private static final Logger logger = LoggerFactory.getLogger(ItmExternalTunnelAddWorker.class ) ;
+    private static final Logger logger = LoggerFactory.getLogger(ItmExternalTunnelAddWorker.class);
 
     private static final FutureCallback<Void> DEFAULT_CALLBACK =
             new FutureCallback<Void>() {
@@ -46,49 +61,200 @@ public class ItmExternalTunnelAddWorker {
 
                 public void onFailure(Throwable error) {
                     logger.error("Error in Datastore operation", error);
-                };
+                }
+
+                ;
             };
 
     public static List<ListenableFuture<Void>> buildTunnelsToExternalEndPoint(DataBroker dataBroker, IdManagerService idManagerService,
                                                                               List<DPNTEPsInfo> cfgDpnList, IpAddress extIp, Class<? extends TunnelTypeBase> tunType) {
         List<ListenableFuture<Void>> futures = new ArrayList<>();
         WriteTransaction t = dataBroker.newWriteOnlyTransaction();
-       if( null != cfgDpnList) {
-          for( DPNTEPsInfo teps : cfgDpnList ) {
-             // CHECK -- Assumption -- Only one End Point / Dpn for GRE/Vxlan Tunnels
-              TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0) ;
-              String interfaceName = firstEndPt.getInterfaceName() ;
-              String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(idManagerService, interfaceName, firstEndPt.getIpAddress().getIpv4Address().getValue(), extIp.getIpv4Address().getValue()) ;
-              char[] subnetMaskArray = firstEndPt.getSubnetMask().getValue() ;
-              String subnetMaskStr = String.valueOf(subnetMaskArray) ;
-              SubnetUtils utils = new SubnetUtils(subnetMaskStr);
-              String dcGwyIpStr = String.valueOf(extIp.getValue());
-              IpAddress gwyIpAddress = (utils.getInfo().isInRange(dcGwyIpStr) ) ? null : firstEndPt.getGwIpAddress() ;
-              String ifDescription = tunType.getName();
-              logger.debug(  " Creating Trunk Interface with parameters trunk I/f Name - {}, parent I/f name - {}, source IP - {}, DC Gateway IP - {} gateway IP - {}",trunkInterfaceName, interfaceName, firstEndPt.getIpAddress(), extIp, gwyIpAddress ) ;
-              Interface iface = ItmUtils.buildTunnelInterface(teps.getDPNID(), trunkInterfaceName, String.format( "%s %s",ifDescription, "Trunk Interface"), true, tunType, firstEndPt.getIpAddress(), extIp, gwyIpAddress, false) ;
-              logger.debug(  " Trunk Interface builder - {} ", iface ) ;
-              InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
-              logger.debug(  " Trunk Interface Identifier - {} ", trunkIdentifier ) ;
-              logger.trace(  " Writing Trunk Interface to Config DS {}, {} ", trunkIdentifier, iface ) ;
-              t.merge(LogicalDatastoreType.CONFIGURATION, trunkIdentifier, iface, true);
-              // update external_tunnel_list ds  
-              InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
-                      ExternalTunnelList.class)
-                          .child(ExternalTunnel.class, new ExternalTunnelKey(extIp, teps.getDPNID()));
-              ExternalTunnel tnl = ItmUtils.buildExternalTunnel(teps.getDPNID(), extIp, trunkInterfaceName);
-              t.merge(LogicalDatastoreType.CONFIGURATION,path, tnl, true) ;
-          }
-          futures.add( t.submit()) ;
-       }
-        return futures ;
+        if (null != cfgDpnList) {
+            for (DPNTEPsInfo teps : cfgDpnList) {
+                // CHECK -- Assumption -- Only one End Point / Dpn for GRE/Vxlan Tunnels
+                TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
+                String interfaceName = firstEndPt.getInterfaceName();
+                String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(idManagerService, interfaceName, firstEndPt.getIpAddress().getIpv4Address().getValue(), extIp.getIpv4Address().getValue());
+                char[] subnetMaskArray = firstEndPt.getSubnetMask().getValue();
+                String subnetMaskStr = String.valueOf(subnetMaskArray);
+                SubnetUtils utils = new SubnetUtils(subnetMaskStr);
+                String dcGwyIpStr = String.valueOf(extIp.getValue());
+                IpAddress gwyIpAddress = (utils.getInfo().isInRange(dcGwyIpStr)) ? null : firstEndPt.getGwIpAddress();
+                String ifDescription = tunType.getName();
+                logger.debug(" Creating Trunk Interface with parameters trunk I/f Name - {}, parent I/f name - {}, source IP - {}, DC Gateway IP - {} gateway IP - {}", trunkInterfaceName, interfaceName, firstEndPt.getIpAddress(), extIp, gwyIpAddress);
+                Interface iface = ItmUtils.buildTunnelInterface(teps.getDPNID(), trunkInterfaceName, String.format("%s %s", ifDescription, "Trunk Interface"), true, tunType, firstEndPt.getIpAddress(), extIp, gwyIpAddress, firstEndPt.getVLANID(), false,false,null);
+                logger.debug(" Trunk Interface builder - {} ", iface);
+                InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
+                logger.debug(" Trunk Interface Identifier - {} ", trunkIdentifier);
+                logger.trace(" Writing Trunk Interface to Config DS {}, {} ", trunkIdentifier, iface);
+                t.merge(LogicalDatastoreType.CONFIGURATION, trunkIdentifier, iface, true);
+                // update external_tunnel_list ds
+                InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
+                        ExternalTunnelList.class)
+                        .child(ExternalTunnel.class, new ExternalTunnelKey(extIp.toString(), teps.getDPNID().toString()));
+                ExternalTunnel tnl = ItmUtils.buildExternalTunnel(teps.getDPNID().toString(), extIp.toString(), trunkInterfaceName);
+                t.merge(LogicalDatastoreType.CONFIGURATION, path, tnl, true);
+            }
+            futures.add(t.submit());
+        }
+        return futures;
     }
 
     public static List<ListenableFuture<Void>> buildTunnelsFromDpnToExternalEndPoint(DataBroker dataBroker, IdManagerService idManagerService,
                                                                                      List<BigInteger> dpnId, IpAddress extIp, Class<? extends TunnelTypeBase> tunType) {
         List<ListenableFuture<Void>> futures = new ArrayList<>();
-        List<DPNTEPsInfo> cfgDpnList =( dpnId == null ) ? ItmUtils.getTunnelMeshInfo(dataBroker) :ItmUtils.getDPNTEPListFromDPNId(dataBroker, dpnId) ;
-          futures = buildTunnelsToExternalEndPoint( dataBroker, idManagerService, cfgDpnList, extIp, tunType) ;
-        return futures ;
+        List<DPNTEPsInfo> cfgDpnList = (dpnId == null) ? ItmUtils.getTunnelMeshInfo(dataBroker) : ItmUtils.getDPNTEPListFromDPNId(dataBroker, dpnId);
+        futures = buildTunnelsToExternalEndPoint(dataBroker, idManagerService, cfgDpnList, extIp, tunType);
+        return futures;
+    }
+
+    public static List<ListenableFuture<Void>> buildHwVtepsTunnels(DataBroker dataBroker, IdManagerService idManagerService, List<DPNTEPsInfo> cfgdDpnList, List<HwVtep> cfgdHwVteps) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+        if (null != cfgdDpnList && !cfgdDpnList.isEmpty()) {
+            logger.trace("calling tunnels from css {}",cfgdDpnList);
+            tunnelsFromCSS(cfgdDpnList, idManagerService , futures, t , dataBroker);
+
+        }
+        if (null != cfgdHwVteps && !cfgdHwVteps.isEmpty() ) {
+            logger.trace("calling tunnels from hwTep {}",cfgdHwVteps);
+            tunnelsFromhWVtep(cfgdHwVteps, idManagerService, futures, t, dataBroker);
+        }
+
+        if ((cfgdDpnList != null && !cfgdDpnList.isEmpty()) || (cfgdHwVteps != null && !cfgdHwVteps.isEmpty()))
+            futures.add(t.submit());
+        return futures;
+    }
+
+    private static void tunnelsFromCSS(List<DPNTEPsInfo> cfgdDpnList, IdManagerService idManagerService, List<ListenableFuture<Void>> futures, WriteTransaction t, DataBroker dataBroker) {
+        for (DPNTEPsInfo dpn : cfgdDpnList) {
+            logger.trace("processing dpn {}" , dpn);
+            if (dpn.getTunnelEndPoints() != null && !dpn.getTunnelEndPoints().isEmpty())
+                for (TunnelEndPoints tep : dpn.getTunnelEndPoints()) {
+                    InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class).child(TransportZone.class, new TransportZoneKey((tep.getTransportZone()))).build();
+                    Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
+                    if (tZoneOptional.isPresent()) {
+                        TransportZone tZone = tZoneOptional.get();
+                        //do we need to check tunnel type?
+                        if (tZone.getSubnets() != null && !tZone.getSubnets().isEmpty()) {
+                            for (Subnets sub : tZone.getSubnets()) {
+                                if (sub.getDeviceVteps() != null && !sub.getDeviceVteps().isEmpty()) {
+                                    for (DeviceVteps hwVtepDS : sub.getDeviceVteps()) {
+                                        String cssID = dpn.getDPNID().toString();
+                                        String nodeId = hwVtepDS.getNodeId();
+                                        //CSS-TOR
+                                        logger.trace("wire up {} and {}",tep, hwVtepDS);
+                                        if (!wireUp(dpn.getDPNID(), tep.getPortname(), sub.getVlanId(), tep.getIpAddress(), nodeId, hwVtepDS.getIpAddress(), tep.getSubnetMask(),
+                                                sub.getGatewayIp(), sub.getPrefix(), tZone.getTunnelType(), idManagerService, dataBroker, futures, t))
+                                            logger.error("Unable to build tunnel {} -- {}", tep.getIpAddress(), hwVtepDS.getIpAddress());
+                                        //TOR-CSS
+                                        logger.trace("wire up {} and {}", hwVtepDS,tep);
+                                        if (!wireUp(hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(), hwVtepDS.getIpAddress(), cssID, tep.getIpAddress(), sub.getPrefix(),
+                                                sub.getGatewayIp(), tep.getSubnetMask(), tZone.getTunnelType(), idManagerService, dataBroker, futures, t))
+                                            logger.error("Unable to build tunnel {} -- {}", hwVtepDS.getIpAddress(), tep.getIpAddress());
+
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+        }
+    }
+
+    private static void tunnelsFromhWVtep(List<HwVtep> cfgdHwVteps, IdManagerService idManagerService, List<ListenableFuture<Void>> futures, WriteTransaction t, DataBroker dataBroker) {
+        for (HwVtep hwTep : cfgdHwVteps) {
+            InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class).child(TransportZone.class, new TransportZoneKey((hwTep.getTransportZone()))).build();
+            Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
+            if (tZoneOptional.isPresent()) {
+                TransportZone tZone = tZoneOptional.get();
+                //do we need to check tunnel type?
+                if (tZone.getSubnets() != null && !tZone.getSubnets().isEmpty()) {
+                    for (Subnets sub : tZone.getSubnets()) {
+                        if (sub.getDeviceVteps() != null && !sub.getDeviceVteps().isEmpty()) {
+                            for (DeviceVteps hwVtepDS : sub.getDeviceVteps()) {
+                                if (hwVtepDS.getIpAddress().equals(hwTep.getHwIp()))
+                                    continue;//dont mesh with self
+                                //TOR1-TOR2
+                                logger.trace("wire up {} and {}",hwTep, hwVtepDS);
+                                if (!wireUp(hwTep.getTopo_id(), hwTep.getNode_id(), hwTep.getHwIp(), hwVtepDS.getNodeId(), hwVtepDS.getIpAddress(),
+                                        hwTep.getIpPrefix(), hwTep.getGatewayIP(), sub.getPrefix(), tZone.getTunnelType(), idManagerService, dataBroker, futures, t))
+                                    logger.error("Unable to build tunnel {} -- {}", hwTep.getHwIp(), hwVtepDS.getIpAddress());
+                                //TOR2-TOR1
+                                logger.trace("wire up {} and {}", hwVtepDS,hwTep);
+                                if (!wireUp(hwTep.getTopo_id(), hwVtepDS.getNodeId(), hwVtepDS.getIpAddress(), hwTep.getNode_id(), hwTep.getHwIp(),
+                                        sub.getPrefix(), sub.getGatewayIp(), hwTep.getIpPrefix(), tZone.getTunnelType(), idManagerService, dataBroker, futures, t))
+                                    logger.error("Unable to build tunnel {} -- {}", hwVtepDS.getIpAddress(), hwTep.getHwIp());
+                            }
+                        }
+                        if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
+                            for (Vteps vtep : sub.getVteps()) {
+                                //TOR-CSS
+                                String cssID = vtep.getDpnId().toString();
+                                logger.trace("wire up {} and {}",hwTep, vtep);
+                                if(!wireUp(hwTep.getTopo_id(), hwTep.getNode_id(), hwTep.getHwIp(), cssID, vtep.getIpAddress(), hwTep.getIpPrefix(),
+                                        hwTep.getGatewayIP(), sub.getPrefix(), tZone.getTunnelType(),idManagerService, dataBroker, futures, t ))
+                                    logger.error("Unable to build tunnel {} -- {}", hwTep.getHwIp(), vtep.getIpAddress());
+                                    //CSS-TOR
+                                logger.trace("wire up {} and {}", vtep,hwTep);
+                                if(!wireUp(vtep.getDpnId(), vtep.getPortname(), sub.getVlanId(), vtep.getIpAddress(),
+                                                hwTep.getNode_id(),hwTep.getHwIp(),sub.getPrefix(), sub.getGatewayIp(),hwTep.getIpPrefix(),tZone.getTunnelType(),idManagerService, dataBroker, futures, t ));
+
+                            }
+
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    //for tunnels from TOR device
+    private static boolean wireUp(String topo_id, String srcNodeid, IpAddress srcIp, String dstNodeId, IpAddress dstIp, IpPrefix srcSubnet,
+                                  IpAddress gWIp, IpPrefix dstSubnet, Class<? extends TunnelTypeBase> tunType, IdManagerService idManagerService, DataBroker dataBroker, List<ListenableFuture<Void>> futures, WriteTransaction t) {
+        IpAddress gwyIpAddress = (srcSubnet.equals(dstSubnet)) ? null : gWIp;
+        String parentIf =  ItmUtils.getHwParentIf(topo_id, srcNodeid);
+        String tunnelIfName = ItmUtils.getTrunkInterfaceName(idManagerService, parentIf, srcIp.getIpv4Address().getValue(), dstIp.getIpv4Address().getValue());
+        logger.debug(" Creating ExternalTrunk Interface with parameters Name - {}, parent I/f name - {}, source IP - {}, destination IP - {} gateway IP - {}", tunnelIfName, parentIf, srcIp, dstIp, gwyIpAddress);
+        Interface hwTunnelIf = ItmUtils.buildHwTunnelInterface(tunnelIfName, String.format("%s %s", tunType.getName(), "Trunk Interface"),
+                true, topo_id, srcNodeid, tunType, srcIp, dstIp, gwyIpAddress, true);
+        InstanceIdentifier<Interface> ifIID = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(tunnelIfName)).build();
+        logger.trace(" Writing Trunk Interface to Config DS {}, {} ", ifIID, hwTunnelIf);
+        t.merge(LogicalDatastoreType.CONFIGURATION, ifIID, hwTunnelIf, true);
+        // also update itm-state ds?
+        InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
+                ExternalTunnelList.class)
+                .child(ExternalTunnel.class, new ExternalTunnelKey(getExternalTunnelKey(dstNodeId), getExternalTunnelKey(srcNodeid)));
+        ExternalTunnel tnl = ItmUtils.buildExternalTunnel(getExternalTunnelKey(srcNodeid), getExternalTunnelKey(dstNodeId), tunnelIfName);
+        t.merge(LogicalDatastoreType.CONFIGURATION, path, tnl, true);
+        return true;
+    }
+
+    //for tunnels from CSS
+    private static boolean wireUp(BigInteger dpnId,String portname, Integer vlanId, IpAddress srcIp, String dstNodeId, IpAddress dstIp, IpPrefix srcSubnet,
+                                  IpAddress gWIp, IpPrefix dstSubnet, Class<? extends TunnelTypeBase> tunType, IdManagerService idManagerService, DataBroker dataBroker, List<ListenableFuture<Void>> futures, WriteTransaction t) {
+        IpAddress gwyIpAddress = (srcSubnet.equals(dstSubnet)) ? null : gWIp;
+        String parentIf = ItmUtils.getInterfaceName(dpnId, portname, vlanId);
+        String tunnelIfName = ItmUtils.getTrunkInterfaceName(idManagerService, parentIf, srcIp.getIpv4Address().getValue(), dstIp.getIpv4Address().getValue());
+        logger.debug(" Creating ExternalTrunk Interface with parameters Name - {}, parent I/f name - {}, source IP - {}, destination IP - {} gateway IP - {}", tunnelIfName, parentIf, srcIp, dstIp, gwyIpAddress);
+        Interface extTunnelIf = ItmUtils.buildTunnelInterface(dpnId, tunnelIfName, String.format("%s %s", tunType.getName(), "Trunk Interface"), true, tunType, srcIp, dstIp, gwyIpAddress, vlanId, false, true, 5L);
+        InstanceIdentifier<Interface> ifIID = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(tunnelIfName)).build();
+        logger.trace(" Writing Trunk Interface to Config DS {}, {} ", ifIID, extTunnelIf);
+        t.merge(LogicalDatastoreType.CONFIGURATION, ifIID, extTunnelIf, true);
+        InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
+                ExternalTunnelList.class)
+                .child(ExternalTunnel.class, new ExternalTunnelKey(getExternalTunnelKey(dstNodeId), dpnId.toString()));
+        ExternalTunnel tnl = ItmUtils.buildExternalTunnel(dpnId.toString(), getExternalTunnelKey(dstNodeId), tunnelIfName);
+        t.merge(LogicalDatastoreType.CONFIGURATION, path, tnl, true);
+        return true;
+    }
+    
+    static String getExternalTunnelKey(String nodeid) {
+        if (nodeid.indexOf("physicalswitch") > 0) {
+            nodeid = nodeid.substring(0, nodeid.indexOf("physicalswitch") - 1);
+        }
+        return nodeid;
     }
 }
+
index 5cef68f26bf98a59928ed2c348a6198be3d451a9..c1d8f863e52ea89d9861f7d5696f486fa30d59f9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -7,9 +7,12 @@
  */
 package org.opendaylight.vpnservice.itm.confighelpers;
 
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.google.common.base.Optional;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -23,6 +26,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnelKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZoneKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.DeviceVteps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.Vteps;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,7 +60,7 @@ public class ItmExternalTunnelDeleteWorker {
 
                     InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
                             ExternalTunnelList.class)
-                                .child(ExternalTunnel.class, new ExternalTunnelKey(extIp, teps.getDPNID()));
+                                .child(ExternalTunnel.class, getExternalTunnelKey(extIp.toString(), teps.getDPNID().toString()));
                     t.delete(LogicalDatastoreType.CONFIGURATION, path);
                     // Release the Ids for the trunk interface Name
                     ItmUtils.releaseIdForTrunkInterfaceName(idManagerService,interfaceName,firstEndPt.getIpAddress().getIpv4Address().getValue(), extIp.getIpv4Address().getValue() );
@@ -61,4 +70,198 @@ public class ItmExternalTunnelDeleteWorker {
         return futures ;
     }
 
+    public static List<ListenableFuture<Void>> deleteHwVtepsTunnels(DataBroker dataBroker, IdManagerService idManagerService, List<DPNTEPsInfo> delDpnList ,List<HwVtep> cfgdHwVteps) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+        if (null != delDpnList) {
+            tunnelsFromCSS(delDpnList, idManagerService , futures, t , dataBroker);
+        }
+        if (null != cfgdHwVteps) {
+            tunnelsFromhWVtep(cfgdHwVteps, idManagerService, futures, t, dataBroker);
+        }
+
+        if (delDpnList != null || cfgdHwVteps != null)
+            futures.add(t.submit());
+        return futures;
+    }
+
+    private static void tunnelsFromCSS(List<DPNTEPsInfo> cfgdDpnList, IdManagerService idManagerService, List<ListenableFuture<Void>> futures, WriteTransaction t, DataBroker dataBroker) {
+        for (DPNTEPsInfo dpn : cfgdDpnList) {
+            if (dpn.getTunnelEndPoints() != null && !dpn.getTunnelEndPoints().isEmpty())
+                for (TunnelEndPoints srcTep : dpn.getTunnelEndPoints()) {
+                    InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class).child(TransportZone.class, new TransportZoneKey((srcTep.getTransportZone()))).build();
+                    Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
+                    if (tZoneOptional.isPresent()) {
+                        TransportZone tZone = tZoneOptional.get();
+                        //do we need to check tunnel type?
+                        if (tZone.getSubnets() != null && !tZone.getSubnets().isEmpty()) {
+                            for (Subnets sub : tZone.getSubnets()) {
+                                if (sub.getDeviceVteps() != null && !sub.getDeviceVteps().isEmpty()) {
+                                    for (DeviceVteps hwVtepDS : sub.getDeviceVteps()) {
+                                        String cssID = dpn.getDPNID().toString();
+                                        //CSS-TOR-CSS
+                                        deleteTrunksCSSTOR(dataBroker, idManagerService, dpn.getDPNID(),
+                                                        srcTep.getInterfaceName(), srcTep.getIpAddress(),
+                                                        hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(),
+                                                        hwVtepDS.getIpAddress(), t, futures);
+
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+        }
+    }
+
+
+
+
+
+    private static void tunnelsFromhWVtep(List<HwVtep> cfgdHwVteps, IdManagerService idManagerService, List<ListenableFuture<Void>> futures, WriteTransaction t, DataBroker dataBroker) {
+        for (HwVtep hwTep : cfgdHwVteps) {
+            logger.trace("processing hwTep from list {}",hwTep);
+            InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class).child(TransportZone.class, new TransportZoneKey((hwTep.getTransportZone()))).build();
+            Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
+            if (tZoneOptional.isPresent()) {
+                TransportZone tZone = tZoneOptional.get();
+                //do we need to check tunnel type?
+                logger.trace("subnets under tz {} are {}",tZone.getZoneName(),tZone.getSubnets());
+                if (tZone.getSubnets() != null && !tZone.getSubnets().isEmpty()) {
+
+                    for (Subnets sub : tZone.getSubnets()) {
+                        if (sub.getDeviceVteps() != null && !sub.getDeviceVteps().isEmpty()) {
+                            for (DeviceVteps hwVtepDS : sub.getDeviceVteps()) {
+                                logger.trace("hwtepDS exists {}",hwVtepDS);
+                                //do i need to check node-id?
+                                //for mlag case and non-m-lag case, isnt it enough to just check ipaddress?
+                                if (hwVtepDS.getIpAddress().equals(hwTep.getHwIp()))
+                                    continue;//dont delete tunnels with self
+                                //TOR-TOR
+                                logger.trace("deleting tor-tor {} and {}",hwTep,hwVtepDS);
+                                deleteTrunksTORTOR(dataBroker, idManagerService, hwTep.getTopo_id(), hwTep.getNode_id(),
+                                                hwTep.getHwIp(), hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(),
+                                                hwVtepDS.getIpAddress(), t, futures);
+
+                            }
+                        }
+                        if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
+                            for (Vteps vtep : sub.getVteps()) {
+                                //TOR-CSS
+                                logger.trace("deleting tor-css-tor {} and {}",hwTep,vtep);
+                                String parentIf = ItmUtils.getInterfaceName(vtep.getDpnId(),vtep.getPortname(),sub.getVlanId());
+                                deleteTrunksCSSTOR(dataBroker,idManagerService,vtep.getDpnId(),parentIf,vtep.getIpAddress(),
+                                                hwTep.getTopo_id(),hwTep.getNode_id(),hwTep.getHwIp(),t,futures );
+                            }
+
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    private static void deleteTrunksCSSTOR(DataBroker dataBroker, IdManagerService idManagerService, BigInteger dpnid,
+                    String interfaceName, IpAddress cssIpAddress, String topologyId, String nodeId, IpAddress hWIpAddress,
+                    WriteTransaction t, List<ListenableFuture<Void>> futures) {
+        //CSS-TOR
+        if (trunkExists(dpnid.toString(), nodeId,dataBroker)) {
+            logger.trace("deleting tunnel from {} to {} ", dpnid.toString(), nodeId);
+            String parentIf = interfaceName;
+            String fwdTrunkIf = ItmUtils.getTrunkInterfaceName(idManagerService,parentIf,cssIpAddress.getIpv4Address().getValue(),
+                            hWIpAddress.getIpv4Address().getValue());
+            InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(fwdTrunkIf);
+            t.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
+
+            InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
+                            ExternalTunnelList.class)
+                            .child(ExternalTunnel.class, getExternalTunnelKey(nodeId, dpnid.toString()));
+            t.delete(LogicalDatastoreType.CONFIGURATION, path);
+        }
+        else {
+            logger.trace(" trunk from {} to {} already deleted",dpnid.toString(), nodeId);
+        }
+        //TOR-CSS
+        if (trunkExists( nodeId, dpnid.toString(),dataBroker)) {
+            logger.trace("deleting tunnel from {} to {} ",nodeId, dpnid.toString());
+
+            String parentIf = ItmUtils.getHwParentIf(topologyId,nodeId);
+            String revTrunkIf = ItmUtils.getTrunkInterfaceName(idManagerService,parentIf, hWIpAddress.getIpv4Address().getValue(),
+                            cssIpAddress.getIpv4Address().getValue());
+            InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(revTrunkIf);
+            t.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
+
+            InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
+                            ExternalTunnelList.class)
+                            .child(ExternalTunnel.class, getExternalTunnelKey( dpnid.toString(),nodeId));
+            t.delete(LogicalDatastoreType.CONFIGURATION, path);
+        }
+        else {
+            logger.trace(" trunk from {} to {} already deleted",  nodeId, dpnid.toString());
+        }
+    }
+
+    private static void deleteTrunksTORTOR(DataBroker dataBroker, IdManagerService idManagerService,
+                    String topologyId1, String nodeId1, IpAddress hWIpAddress1, String topologyId2, String nodeId2, IpAddress hWIpAddress2,
+                    WriteTransaction t, List<ListenableFuture<Void>> futures) {
+        //TOR1-TOR2
+        if (trunkExists(nodeId1, nodeId2,dataBroker)) {
+            logger.trace("deleting tunnel from {} to {} ", nodeId1, nodeId2);
+            String parentIf = ItmUtils.getHwParentIf(topologyId1,nodeId1);
+            String fwdTrunkIf = ItmUtils.getTrunkInterfaceName(idManagerService, parentIf,
+                            hWIpAddress1.getIpv4Address().getValue(), hWIpAddress2.getIpv4Address().getValue());
+            InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(fwdTrunkIf);
+            t.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
+
+            InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
+                            ExternalTunnelList.class)
+                            .child(ExternalTunnel.class, getExternalTunnelKey(nodeId2, nodeId1));
+            t.delete(LogicalDatastoreType.CONFIGURATION, path);
+        }
+        else {
+            logger.trace(" trunk from {} to {} already deleted",nodeId1, nodeId2);
+        }
+        //TOR2-TOR1
+        if (trunkExists( nodeId2, nodeId1,dataBroker)) {
+            logger.trace("deleting tunnel from {} to {} ",nodeId2, nodeId1);
+
+            String parentIf = ItmUtils.getHwParentIf(topologyId2,nodeId2);
+            String revTrunkIf = ItmUtils.getTrunkInterfaceName(idManagerService,parentIf, hWIpAddress2.getIpv4Address().getValue(),
+                            hWIpAddress1.getIpv4Address().getValue());
+            InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(revTrunkIf);
+            t.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
+
+            InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
+                            ExternalTunnelList.class)
+                            .child(ExternalTunnel.class, getExternalTunnelKey( nodeId1,nodeId2));
+            t.delete(LogicalDatastoreType.CONFIGURATION, path);
+        }
+        else {
+            logger.trace(" trunk from {} to {} already deleted",nodeId2, nodeId1);
+        }
+    }
+
+    private static boolean trunkExists( String srcDpnOrNode,  String dstDpnOrNode, DataBroker dataBroker) {
+        boolean existsFlag = false ;
+        InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
+                        ExternalTunnelList.class)
+                        .child(ExternalTunnel.class, getExternalTunnelKey(dstDpnOrNode, srcDpnOrNode));
+        Optional<ExternalTunnel> exTunnels = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,path, dataBroker) ;
+        if( exTunnels.isPresent())
+            existsFlag = true ;
+        return existsFlag ;
+    }
+
+    static ExternalTunnelKey getExternalTunnelKey(String dst , String src) {
+        if (src.indexOf("physicalswitch") > 0) {
+            src = src.substring(0, src.indexOf("physicalswitch") - 1);
+        }
+        if (dst.indexOf("physicalswitch") > 0) {
+            dst = dst.substring(0, dst.indexOf("physicalswitch") - 1);
+        }
+        return new ExternalTunnelKey(dst, src);
+    }
+
+
 }
index c7c5ae726bc7b3c9e6eefe17c3935605593ab4e8..c1850200f8c5e9bd5a5463fbc8ad0911d450ad92 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -64,7 +64,7 @@ public class ItmInternalTunnelAddWorker {
         WriteTransaction t = dataBroker.newWriteOnlyTransaction();
         if( null == cfgdDpnList || cfgdDpnList.isEmpty()) {
             logger.error(" Build Tunnels was invoked with empty list");
-            return null;
+            return futures;
          }
 
         for( DPNTEPsInfo dpn : cfgdDpnList) {
@@ -152,7 +152,9 @@ public class ItmInternalTunnelAddWorker {
         String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(idManagerService, interfaceName,srcte.getIpAddress().getIpv4Address().getValue(), dstte.getIpAddress().getIpv4Address().getValue()) ;
         IpAddress gwyIpAddress = ( srcte.getSubnetMask().equals(dstte.getSubnetMask()) ) ? null : srcte.getGwIpAddress() ;
         logger.debug(  " Creating Trunk Interface with parameters trunk I/f Name - {}, parent I/f name - {}, source IP - {}, destination IP - {} gateway IP - {}",trunkInterfaceName, interfaceName, srcte.getIpAddress(), dstte.getIpAddress(), gwyIpAddress ) ;
-        Interface iface = ItmUtils.buildTunnelInterface(srcDpnId, trunkInterfaceName, String.format( "%s %s",ifDescription, "Trunk Interface"), true, tunType, srcte.getIpAddress(), dstte.getIpAddress(), gwyIpAddress, true) ;
+        Interface iface = ItmUtils.buildTunnelInterface(srcDpnId, trunkInterfaceName,
+                        String.format("%s %s", ifDescription, "Trunk Interface"), true, tunType, srcte.getIpAddress(),
+                        dstte.getIpAddress(), gwyIpAddress, srcte.getVLANID(), true, false, null);
         logger.debug(  " Trunk Interface builder - {} ", iface ) ;
         InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
         logger.debug(  " Trunk Interface Identifier - {} ", trunkIdentifier ) ;
@@ -161,7 +163,7 @@ public class ItmInternalTunnelAddWorker {
         // also update itm-state ds?
         InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
                 TunnelList.class)
-                    .child(InternalTunnel.class, new InternalTunnelKey( srcDpnId, dstDpnId));   
+                    .child(InternalTunnel.class, new InternalTunnelKey( dstDpnId,srcDpnId ));
         InternalTunnel tnl = ItmUtils.buildInternalTunnel(srcDpnId, dstDpnId, trunkInterfaceName);
         //ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tnl, dataBroker, DEFAULT_CALLBACK);
         t.merge(LogicalDatastoreType.CONFIGURATION,path, tnl, true) ;
index 9e113f25b04887fddeb07d938ac43c7afd66dc19..ed065b6eaa40fab4701461ba087b36d7970cd720 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -38,20 +38,22 @@ public class ItmInternalTunnelDeleteWorker {
     public static List<ListenableFuture<Void>> deleteTunnels(DataBroker dataBroker, IdManagerService idManagerService,IMdsalApiManager mdsalManager,
                                                              List<DPNTEPsInfo> dpnTepsList, List<DPNTEPsInfo> meshedDpnList)
     {
+        logger.trace( "TEPs to be deleted {} " , dpnTepsList );
         List<ListenableFuture<Void>> futures = new ArrayList<>();
         WriteTransaction t = dataBroker.newWriteOnlyTransaction();
         try {
             if (dpnTepsList == null || dpnTepsList.size() == 0) {
                 logger.debug("no vtep to delete");
-                return null ;
+                return futures ;
             }
 
             if (meshedDpnList == null || meshedDpnList.size() == 0) {
                 logger.debug("No Meshed Vteps");
-                return null ;
+                return futures ;
             }
             for (DPNTEPsInfo srcDpn : dpnTepsList) {
                 logger.trace("Processing srcDpn " + srcDpn);
+                List<TunnelEndPoints> meshedEndPtCache = new ArrayList<TunnelEndPoints>(srcDpn.getTunnelEndPoints()) ;
                 for (TunnelEndPoints srcTep : srcDpn.getTunnelEndPoints()) {
                     logger.trace("Processing srcTep " + srcTep);
                     String srcTZone = srcTep.getTransportZone();
@@ -79,18 +81,24 @@ public class ItmInternalTunnelDeleteWorker {
 
                     logger.trace("Tep Removal from DPNTEPSINFO CONFIG DS " + srcTep);
                     t.delete(LogicalDatastoreType.CONFIGURATION, tepPath);
+                    // remove the tep from the cache
+                    meshedEndPtCache.remove(srcTep) ;
+                    
                     InstanceIdentifier<DPNTEPsInfo> dpnPath =
                                     InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, srcDpn.getKey())
                                                     .build();
+                    /*
                     Optional<DPNTEPsInfo> dpnOptional =
                                     ItmUtils.read(LogicalDatastoreType.CONFIGURATION, dpnPath, dataBroker);
                     if (dpnOptional.isPresent()) {
-                        DPNTEPsInfo dpnRead = dpnOptional.get();
+                    */
+                    if( meshedEndPtCache.isEmpty()) {
+                        //DPNTEPsInfo dpnRead = dpnOptional.get();
                         // remove dpn if no vteps exist on dpn
-                        if (dpnRead.getTunnelEndPoints() == null || dpnRead.getTunnelEndPoints().size() == 0) {
+                      //  if (dpnRead.getTunnelEndPoints() == null || dpnRead.getTunnelEndPoints().size() == 0) {
                             logger.debug( "Removing Terminating Service Table Flow ") ;
-                           ItmUtils.setUpOrRemoveTerminatingServiceTable(dpnRead.getDPNID(), mdsalManager,false);
-                            logger.trace("DPN Removal from DPNTEPSINFO CONFIG DS " + dpnRead);
+                           ItmUtils.setUpOrRemoveTerminatingServiceTable(srcDpn.getDPNID(), mdsalManager,false);
+                            logger.trace("DPN Removal from DPNTEPSINFO CONFIG DS " + srcDpn.getDPNID());
                             t.delete(LogicalDatastoreType.CONFIGURATION, dpnPath);
                             InstanceIdentifier<DpnEndpoints> tnlContainerPath =
                                             InstanceIdentifier.builder(DpnEndpoints.class).build();
@@ -105,7 +113,7 @@ public class ItmInternalTunnelDeleteWorker {
                                     t.delete(LogicalDatastoreType.CONFIGURATION, tnlContainerPath);
                                 }
                             }
-                        }
+                        //}
                     }
                 }
             }
index 40a5314ec1eb9b718e7ecc9fac6f32436fd2b921..ed6282d3ea40862023b34d2b6ed62d781f4a0bcb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -28,13 +28,16 @@ public class ItmTepAddWorker implements Callable<List<ListenableFuture<Void>>> {
     private List<DPNTEPsInfo> meshedDpnList;
     private List<DPNTEPsInfo> cfgdDpnList ;
     private IMdsalApiManager mdsalManager;
+    private List<HwVtep> cfgdHwVteps;
 
-    public ItmTepAddWorker( List<DPNTEPsInfo> cfgdDpnList,  DataBroker broker, IdManagerService idManagerService, IMdsalApiManager mdsalManager) {
+    public ItmTepAddWorker( List<DPNTEPsInfo> cfgdDpnList, List<HwVtep> hwVtepList, DataBroker broker, IdManagerService idManagerService, IMdsalApiManager mdsalManager) {
         this.cfgdDpnList = cfgdDpnList ;
         this.dataBroker = broker ;
         this.idManagerService = idManagerService;
         this.mdsalManager = mdsalManager;
+        this.cfgdHwVteps = hwVtepList;
         logger.trace("ItmTepAddWorker initialized with  DpnList {}",cfgdDpnList );
+        logger.trace("ItmTepAddWorker initialized with  hwvteplist {}",hwVtepList);
     }
 
     @Override
@@ -45,6 +48,8 @@ public class ItmTepAddWorker implements Callable<List<ListenableFuture<Void>>> {
         futures.addAll( ItmInternalTunnelAddWorker.build_all_tunnels(dataBroker, idManagerService,mdsalManager, cfgdDpnList, meshedDpnList) ) ;
         // IF EXTERNAL TUNNELS NEEDS TO BE BUILT, DO IT HERE. IT COULD BE TO DC GATEWAY OR TOR SWITCH
         //futures.addAll(ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker,meshedDpnList, extIp) ;
+        logger.debug("invoking build hwVtepTunnels with hwVteplist {}", cfgdHwVteps );
+        futures.addAll(ItmExternalTunnelAddWorker.buildHwVtepsTunnels(dataBroker, idManagerService,cfgdDpnList,cfgdHwVteps));
         return futures ;
     }
 
index dfc6afdfac3d67f2e60d8c6d3419838f895a4ef8..f320a11d732b15f15fd575dc08eb5e181cc8e10c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -28,13 +28,16 @@ public class ItmTepRemoveWorker implements Callable<List<ListenableFuture<Void>>
     private List<DPNTEPsInfo> meshedDpnList ;
     private IdManagerService idManagerService;
     private IMdsalApiManager mdsalManager;
+    private List<HwVtep> cfgdHwVteps;
 
-    public ItmTepRemoveWorker( List<DPNTEPsInfo> delDpnList,  DataBroker broker, IdManagerService idManagerService, IMdsalApiManager mdsalManager) {
+    public ItmTepRemoveWorker( List<DPNTEPsInfo> delDpnList, List<HwVtep> delHwList,  DataBroker broker, IdManagerService idManagerService, IMdsalApiManager mdsalManager) {
         this.delDpnList = delDpnList ;
         this.dataBroker = broker ;
         this.idManagerService = idManagerService;
         this.mdsalManager = mdsalManager;
+        this.cfgdHwVteps = delHwList;
         logger.trace("ItmTepRemoveWorker initialized with  DpnList {}",delDpnList );
+        logger.trace("ItmTepRemoveWorker initialized with  cfgdHwTeps {}",delHwList );
     }
 
     @Override
@@ -44,6 +47,7 @@ public class ItmTepRemoveWorker implements Callable<List<ListenableFuture<Void>>
         futures.addAll( ItmInternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService, mdsalManager, delDpnList, meshedDpnList));
         logger.debug("Invoking Internal Tunnel delete method with DpnList to be deleted {} ; Meshed DpnList {} ",delDpnList, meshedDpnList );
         // IF EXTERNAL TUNNELS NEEDS TO BE DELETED, DO IT HERE, IT COULD BE TO DC GATEWAY OR TOR SWITCH
+        futures.addAll(ItmExternalTunnelDeleteWorker.deleteHwVtepsTunnels(dataBroker, idManagerService,delDpnList,cfgdHwVteps));
         return futures ;
     }
 
index 87f8a8b1960053098b97466cda4df65ae808129c..0c784b08556b12ae96973e3faa6a52e0cdca3397 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -37,7 +37,10 @@ import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.DPNTEPsInfo;
 
 import com.google.common.base.Optional;
-
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorEnabled;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorInterval;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorEnabledBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.TunnelMonitorIntervalBuilder;
 
 public class ITMManager implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(ITMManager.class);
@@ -64,5 +67,56 @@ public class ITMManager implements AutoCloseable {
     public void setNotificationPublishService(NotificationPublishService notificationPublishService) {
         this.notificationPublishService = notificationPublishService;
     }
+    protected void initTunnelMonitorDataInConfigDS() {
+        new Thread() {
+            public void run() {
+                boolean readSucceeded = false;
+                InstanceIdentifier<TunnelMonitorEnabled> monitorPath = InstanceIdentifier.builder(TunnelMonitorEnabled.class).build();
+                while (!readSucceeded) {
+                    try {
+                        Optional<TunnelMonitorEnabled> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, monitorPath, broker);
+                        // Store default values only when tunnel monitor data is not initialized
+                        if (!storedTunnelMonitor.isPresent()) {
+                            TunnelMonitorEnabled monitorEnabled =
+                                    new TunnelMonitorEnabledBuilder().setEnabled(ITMConstants.DEFAULT_MONITOR_ENABLED).build();
+                            ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, monitorPath, monitorEnabled, broker, ItmUtils.DEFAULT_CALLBACK);
+
+                            InstanceIdentifier<TunnelMonitorInterval> intervalPath = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
+                            TunnelMonitorInterval monitorInteval =
+                                    new TunnelMonitorIntervalBuilder().setInterval(ITMConstants.DEFAULT_MONITOR_INTERVAL).build();
+                            ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, intervalPath, monitorInteval, broker, ItmUtils.DEFAULT_CALLBACK);
+                        }
+                        readSucceeded = true;
+                    } catch (Exception e) {
+                        LOG.warn("Unable to read monitor enabled info; retrying after some delay");
+                        try {
+                            Thread.sleep(1000);
+                        } catch (InterruptedException ie) {
+                            return;
+                        }
+                    }
+                }
+            }
+        }.start();
+    }
 
+    protected boolean getTunnelMonitorEnabledFromConfigDS() {
+        boolean tunnelMonitorEnabled = true;
+        InstanceIdentifier<TunnelMonitorEnabled> path = InstanceIdentifier.builder(TunnelMonitorEnabled.class).build();
+        Optional<TunnelMonitorEnabled> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, broker);
+        if (storedTunnelMonitor.isPresent()) {
+            tunnelMonitorEnabled = storedTunnelMonitor.get().isEnabled();
+        }
+        return tunnelMonitorEnabled;
+    }
+
+    protected int getTunnelMonitorIntervalFromConfigDS() {
+        int tunnelMonitorInterval = ITMConstants.DEFAULT_MONITOR_INTERVAL;
+        InstanceIdentifier<TunnelMonitorInterval> path = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
+        Optional<TunnelMonitorInterval> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, broker);
+        if (storedTunnelMonitor.isPresent()) {
+            tunnelMonitorInterval = storedTunnelMonitor.get().getInterval();
+        }
+        return tunnelMonitorInterval;
+    }
 }
index 2c2126e95cc6f428f9e1117d07cdc387cb32882f..57ed05ae157e49b0227347410e8bf0acb466cca7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -22,20 +22,33 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
 import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.itm.cli.TepCommandHelper;
 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
 import org.opendaylight.vpnservice.itm.listeners.TransportZoneListener;
+import org.opendaylight.vpnservice.itm.listeners.VtepConfigSchemaListener;
 import org.opendaylight.vpnservice.itm.rpc.ItmManagerRpcService;
+import org.opendaylight.vpnservice.itm.snd.ITMStatusMonitor;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.VtepConfigSchemas;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchemaBuilder;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.VtepConfigSchemas;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.vtep.config.schemas.VtepConfigSchemaBuilder;
 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.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
-
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
 public class ItmProvider implements BindingAwareProvider, AutoCloseable, IITMProvider /*,ItmStateService */{
 
     private static final Logger LOG = LoggerFactory.getLogger(ItmProvider.class);
@@ -47,8 +60,17 @@ public class ItmProvider implements BindingAwareProvider, AutoCloseable, IITMPro
     private ItmManagerRpcService itmRpcService ;
     private IdManagerService idManager;
     private NotificationService notificationService;
+    private TepCommandHelper tepCommandHelper;
     private TransportZoneListener tzChangeListener;
+    private VtepConfigSchemaListener vtepConfigSchemaListener;
     private RpcProviderRegistry rpcProviderRegistry;
+    private static final ITMStatusMonitor itmStatusMonitor = ITMStatusMonitor.getInstance();
+    static short flag = 0;
+
+    public ItmProvider() {
+        LOG.info("ItmProvider Before register MBean");
+        itmStatusMonitor.registerMbean();
+    }
 
     public void setRpcProviderRegistry(RpcProviderRegistry rpcProviderRegistry) {
         this.rpcProviderRegistry = rpcProviderRegistry;
@@ -61,6 +83,7 @@ public class ItmProvider implements BindingAwareProvider, AutoCloseable, IITMPro
     @Override
     public void onSessionInitiated(ProviderContext session) {
         LOG.info("ItmProvider Session Initiated");
+        itmStatusMonitor.reportStatus("STARTING");
         try {
             dataBroker = session.getSALService(DataBroker.class);
             idManager = getRpcProviderRegistry().getRpcService(IdManagerService.class);
@@ -68,6 +91,8 @@ public class ItmProvider implements BindingAwareProvider, AutoCloseable, IITMPro
             itmManager = new ITMManager(dataBroker);
             tzChangeListener = new TransportZoneListener(dataBroker, idManager) ;
             itmRpcService = new ItmManagerRpcService(dataBroker, idManager);
+            vtepConfigSchemaListener = new VtepConfigSchemaListener(dataBroker);
+            tepCommandHelper = new TepCommandHelper(dataBroker);
             final BindingAwareBroker.RpcRegistration<ItmRpcService> rpcRegistration = getRpcProviderRegistry().addRpcImplementation(ItmRpcService.class, itmRpcService);
             itmRpcService.setMdsalManager(mdsalManager);
             itmManager.setMdsalManager(mdsalManager);
@@ -76,9 +101,13 @@ public class ItmProvider implements BindingAwareProvider, AutoCloseable, IITMPro
             tzChangeListener.setMdsalManager(mdsalManager);
             tzChangeListener.setItmManager(itmManager);
             tzChangeListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+            tepCommandHelper = new TepCommandHelper(dataBroker);
+            tepCommandHelper.setInterfaceManager(interfaceManager);
             createIdPool();
+            itmStatusMonitor.reportStatus("OPERATIONAL");
         } catch (Exception e) {
             LOG.error("Error initializing services", e);
+            itmStatusMonitor.reportStatus("ERROR");
         }
     }
 
@@ -124,4 +153,163 @@ public class ItmProvider implements BindingAwareProvider, AutoCloseable, IITMPro
             LOG.error("Failed to create idPool for ITM Service",e);
         }
     }
+
+    @Override
+    public DataBroker getDataBroker() {
+        return dataBroker;
+    }
+    @Override
+    public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
+                    String gatewayIp, String transportZone) {
+        if (tepCommandHelper != null) {
+            tepCommandHelper.createLocalCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone);
+        } else {
+            LOG.trace("tepCommandHelper doesnt exist");
+        }
+    }
+
+    @Override
+    public void commitTeps() {
+        try {
+                tepCommandHelper.deleteOnCommit();
+                tepCommandHelper.buildTeps();
+        } catch (Exception e) {
+            LOG.debug("unable to configure teps" + e.toString());
+        }
+    }
+
+    @Override
+    public void showTeps() {
+        tepCommandHelper.showTeps(itmManager.getTunnelMonitorEnabledFromConfigDS(),
+                itmManager.getTunnelMonitorIntervalFromConfigDS());
+    }
+
+    public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
+            String gatewayIp, String transportZone) {
+        try {
+           tepCommandHelper.deleteVtep(dpnId,  portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void configureTunnelType(String transportZone, String tunnelType) {
+        LOG .debug("ItmProvider: configureTunnelType {} for transportZone {}", tunnelType, transportZone);
+        tepCommandHelper.configureTunnelType(transportZone,tunnelType);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.opendaylight.vpnservice.itm.api.IITMProvider#addVtepConfigSchema(org.
+     * opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.
+     * rev151102.vtep.config.schemas.VtepConfigSchema)
+     */
+    @Override
+    public void addVtepConfigSchema(VtepConfigSchema vtepConfigSchema) {
+        VtepConfigSchema validatedSchema = ItmUtils.validateForAddVtepConfigSchema(vtepConfigSchema,
+                getAllVtepConfigSchemas());
+
+        String schemaName = validatedSchema.getSchemaName();
+        VtepConfigSchema existingSchema = getVtepConfigSchema(schemaName);
+        if (existingSchema != null) {
+            Preconditions.checkArgument(false, String.format("VtepConfigSchema [%s] already exists!", schemaName));
+        }
+        MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
+                ItmUtils.getVtepConfigSchemaIdentifier(schemaName), validatedSchema);
+        LOG.debug("Vtep config schema {} added to config DS", schemaName);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.opendaylight.vpnservice.itm.api.IITMProvider#getVtepConfigSchema(java
+     * .lang.String)
+     */
+    @Override
+    public VtepConfigSchema getVtepConfigSchema(String schemaName) {
+        Optional<VtepConfigSchema> schema = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
+                ItmUtils.getVtepConfigSchemaIdentifier(schemaName), this.dataBroker);
+        if (schema.isPresent()) {
+            return schema.get();
+        }
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.opendaylight.vpnservice.itm.api.IITMProvider#getAllVtepConfigSchemas(
+     * )
+     */
+    @Override
+    public List<VtepConfigSchema> getAllVtepConfigSchemas() {
+        Optional<VtepConfigSchemas> schemas = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
+                ItmUtils.getVtepConfigSchemasIdentifier(), this.dataBroker);
+        if (schemas.isPresent()) {
+            return schemas.get().getVtepConfigSchema();
+        }
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.opendaylight.vpnservice.itm.api.IITMProvider#updateVtepSchema(java.
+     * lang.String, java.util.List, java.util.List)
+     */
+    @Override
+    public void updateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd, List<BigInteger> lstDpnsForDelete) {
+        LOG.trace("Updating VTEP schema {} by adding DPN's {} and deleting DPN's {}.", schemaName, lstDpnsForAdd,
+                lstDpnsForDelete);
+
+        VtepConfigSchema schema = ItmUtils.validateForUpdateVtepSchema(schemaName, lstDpnsForAdd, lstDpnsForDelete,
+                this);
+        if (ItmUtils.getDpnIdList(schema.getDpnIds()) == null) {
+            VtepConfigSchemaBuilder builder = new VtepConfigSchemaBuilder(schema);
+            builder.setDpnIds(schema.getDpnIds());
+            schema = builder.build();
+        } else {
+            if (lstDpnsForAdd != null && !lstDpnsForAdd.isEmpty()) {
+                ItmUtils.getDpnIdList(schema.getDpnIds()).addAll(lstDpnsForAdd);
+            }
+            if (lstDpnsForDelete != null && !lstDpnsForDelete.isEmpty()) {
+                 ItmUtils.getDpnIdList(schema.getDpnIds()).removeAll(lstDpnsForDelete);
+            }
+        }
+        MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
+                ItmUtils.getVtepConfigSchemaIdentifier(schemaName), schema);
+        LOG.debug("Vtep config schema {} updated to config DS with DPN's {}", schemaName, ItmUtils.getDpnIdList(schema.getDpnIds()));
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.opendaylight.vpnservice.itm.api.IITMProvider#deleteAllVtepSchemas()
+     */
+    @Override
+    public void deleteAllVtepSchemas() {
+        List<VtepConfigSchema> lstSchemas = getAllVtepConfigSchemas();
+        if (lstSchemas != null && !lstSchemas.isEmpty()) {
+            for (VtepConfigSchema schema : lstSchemas) {
+                MDSALUtil.syncDelete(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
+                        ItmUtils.getVtepConfigSchemaIdentifier(schema.getSchemaName()));
+            }
+        }
+        LOG.debug("Deleted all Vtep schemas from config DS");
+    }
+
+    public void configureTunnelMonitorEnabled(boolean monitorEnabled) {
+        tepCommandHelper.configureTunnelMonitorEnabled(monitorEnabled);
+    }
+
+    public void configureTunnelMonitorInterval(int interval) {
+        tepCommandHelper.configureTunnelMonitorInterval(interval);
+    }
 }
index f597e9f32dd48650db6490540fa0e9454de78752..7aa7fa99649c04880bbfe13a1c0b250cd2deed00 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -11,10 +11,13 @@ import java.math.BigInteger;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
+import com.google.common.util.concurrent.CheckedFuture;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.net.util.SubnetUtils;
 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
@@ -22,9 +25,19 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 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.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.itm.confighelpers.HwVtep;
 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.iana._if.type.rev140508.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.VtepConfigSchemas;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.VtepIpPools;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchemaBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchemaKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.ip.pools.VtepIpPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.ip.pools.VtepIpPoolKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdOutput;
@@ -32,6 +45,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.interfaces._interface.NodeIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.interfaces._interface.NodeIdentifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.interfaces._interface.NodeIdentifierKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.DpnEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.DpnEndpointsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.DPNTEPsInfo;
@@ -46,6 +62,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnelBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
@@ -54,7 +71,13 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 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.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.vtep.config.schema.DpnIds ;
 //import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice._interface.service.rev150602._interface.service.info.ServiceInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.vtep.config.schema.DpnIdsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.vtep.config.schema.DpnIdsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.vtep.config.schema.DpnIds;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
@@ -62,7 +85,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
 import org.opendaylight.vpnservice.mdsalutil.ActionType;
 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
@@ -72,6 +94,7 @@ import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
 import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
+
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.net.InetAddresses;
@@ -132,6 +155,16 @@ public class ItmUtils {
         tx.delete(datastoreType, path);
         Futures.addCallback(tx.submit(), callback);
     }
+    public static <T extends DataObject> void asyncBulkRemove(final DataBroker broker,final LogicalDatastoreType datastoreType,
+            List<InstanceIdentifier<T>> pathList, FutureCallback<Void> callback) {
+    if (!pathList.isEmpty()) {
+      WriteTransaction tx = broker.newWriteOnlyTransaction();
+      for (InstanceIdentifier<T> path : pathList) {
+         tx.delete(datastoreType, path);
+      }
+      Futures.addCallback(tx.submit(), callback);
+    }
+    }
 
     public static String getInterfaceName(final BigInteger datapathid, final String portName, final Integer vlanId) {
         return String.format("%s:%s:%s", datapathid, portName, vlanId);
@@ -191,27 +224,56 @@ public class ItmUtils {
     }
 
     public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled, Class<? extends TunnelTypeBase> tunType,
-       IpAddress localIp, IpAddress remoteIp, IpAddress gatewayIp, boolean internal) {
+       IpAddress localIp, IpAddress remoteIp, IpAddress gatewayIp,Integer vlanId, boolean internal, boolean monitorEnabled, Long monitorInterval) {
        InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
        .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
        ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
        builder.addAugmentation(ParentRefs.class, parentRefs);
+       if( vlanId > 0) {
+           IfL2vlan l2vlan = new IfL2vlanBuilder().setVlanId(new VlanId(vlanId)).build();
+           builder.addAugmentation(IfL2vlan.class, l2vlan);
+        }
+               //use default monitoring value from Global Constants
+        Long monitoringInterval = 10000L;
+        if(monitorInterval!= null)
+            monitoringInterval = monitorInterval;
        IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp).setTunnelGateway(gatewayIp).setTunnelSource(localIp)
-       .setTunnelInterfaceType( tunType).setInternal(internal).build();
+       .setTunnelInterfaceType(tunType).setInternal(internal).setMonitorEnabled(monitorEnabled).setMonitorInterval(monitoringInterval).build();
        builder.addAugmentation(IfTunnel.class, tunnel);
        return builder.build();
     }
 
+    public static Interface buildHwTunnelInterface(String tunnelIfName, String desc , boolean enabled, String topo_id, String node_id,
+                                                   Class<? extends TunnelTypeBase> tunType, IpAddress srcIp , IpAddress destIp, IpAddress gWIp,
+                                                   boolean monitor_enabled
+    ){
+        InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(tunnelIfName)).setName(tunnelIfName).setDescription(desc).
+                setEnabled(enabled).setType(Tunnel.class);
+        List<NodeIdentifier> nodeIds = new ArrayList<NodeIdentifier>();
+        NodeIdentifier hWnode = new NodeIdentifierBuilder().setKey(new NodeIdentifierKey(topo_id)).setTopologyId(
+                        topo_id).
+                setNodeId(node_id).build();
+        nodeIds.add(hWnode);
+        ParentRefs parent = new ParentRefsBuilder().setNodeIdentifier(nodeIds).build();
+        builder.addAugmentation(ParentRefs.class , parent);
+        IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gWIp).setTunnelSource(
+                        srcIp).setMonitorEnabled(monitor_enabled).setTunnelInterfaceType(tunType).setInternal(false).build();
+        builder.addAugmentation(IfTunnel.class, tunnel);
+        LOG.trace("iftunnel {} built from hwvtep {} ",tunnel,node_id);
+        return builder.build();
+    }
+
+
     public static InternalTunnel buildInternalTunnel( BigInteger srcDpnId, BigInteger dstDpnId, String trunkInterfaceName) {
-        InternalTunnel tnl = new InternalTunnelBuilder().setKey(new InternalTunnelKey(srcDpnId, dstDpnId))
-            .setDestinationDPN(dstDpnId)
-            .setSourceDPN(srcDpnId)
+        InternalTunnel tnl = new InternalTunnelBuilder().setKey(new InternalTunnelKey(dstDpnId,srcDpnId)).setDestinationDPN(dstDpnId)
+                        .setSourceDPN(srcDpnId)
             .setTunnelInterfaceName(trunkInterfaceName).build();
         return tnl ;
     }
 
-    public static ExternalTunnel buildExternalTunnel( BigInteger srcDpnId, IpAddress dstIp, String trunkInterfaceName) {
-        ExternalTunnel extTnl = new ExternalTunnelBuilder().setKey(new ExternalTunnelKey(dstIp, srcDpnId)).setSourceDPN(srcDpnId).setDestinationIP(dstIp).setTunnelInterfaceName(trunkInterfaceName).build();
+    public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode, String trunkInterfaceName) {
+        ExternalTunnel extTnl = new ExternalTunnelBuilder().setKey(
+                        new ExternalTunnelKey(dstNode, srcNode)).setSourceDevice(srcNode).setDestinationDevice(dstNode).setTunnelInterfaceName(trunkInterfaceName).build();
         return extTnl ;
     }
 
@@ -220,12 +282,12 @@ public class ItmUtils {
 
         // Read the EndPoint Info from the operational database
         InstanceIdentifierBuilder<DpnEndpoints> depBuilder = InstanceIdentifier.builder( DpnEndpoints.class) ;
-        InstanceIdentifier<DpnEndpoints> deps = depBuilder.build() ;
+        InstanceIdentifier<DpnEndpoints> deps = depBuilder.build();
         Optional<DpnEndpoints> dpnEps = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, deps, dataBroker);
-        ifdpnEps.isPresent()) {
+        if (dpnEps.isPresent()) {
            DpnEndpoints tn= dpnEps.get() ;
-           dpnTEPs = tn.getDPNTEPsInfo() ;
-           LOG.debug( "Read from CONFIGURATION datastore - No. of Dpns " , dpnTEPs.size() );
+           dpnTEPs = tn.getDPNTEPsInfo();
+            LOG.debug( "Read from CONFIGURATION datastore - No. of Dpns " , dpnTEPs.size() );
         }else
             LOG.debug( "No Dpn information in CONFIGURATION datastore "  );
          return dpnTEPs ;
@@ -251,7 +313,8 @@ public class ItmUtils {
     }
 
     public static void releaseId(IdManagerService idManager, String idKey) {
-        ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(ITMConstants.ITM_IDPOOL_NAME).setIdKey(idKey).build();
+        ReleaseIdInput idInput =
+                        new ReleaseIdInputBuilder().setPoolName(ITMConstants.ITM_IDPOOL_NAME).setIdKey(idKey).build();
         try {
             Future<RpcResult<Void>> result = idManager.releaseId(idInput);
             RpcResult<Void> rpcResult = result.get();
@@ -316,4 +379,297 @@ public class ItmUtils {
     private static String getFlowRef(long termSvcTable, int svcId) {
         return new StringBuffer().append(termSvcTable).append(svcId).toString();
     }
+    public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier(String schemaName) {
+        return InstanceIdentifier.builder(VtepConfigSchemas.class)
+                        .child(VtepConfigSchema.class, new VtepConfigSchemaKey(schemaName)).build();
+    }
+
+    public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier() {
+        return InstanceIdentifier.builder(VtepConfigSchemas.class).child(VtepConfigSchema.class).build();
+    }
+    public static InstanceIdentifier<VtepConfigSchemas> getVtepConfigSchemasIdentifier() {
+        return InstanceIdentifier.builder(VtepConfigSchemas.class).build();
+    }
+    public static InstanceIdentifier<VtepIpPool> getVtepIpPoolIdentifier(String subnetCidr) {
+        return InstanceIdentifier.builder(VtepIpPools.class).child(VtepIpPool.class, new VtepIpPoolKey(subnetCidr))
+                .build();
+    }
+    public static VtepConfigSchema validateForAddVtepConfigSchema(VtepConfigSchema schema,
+            List<VtepConfigSchema> existingSchemas) {
+        VtepConfigSchema validSchema = validateVtepConfigSchema(schema);
+        for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
+            if (!StringUtils.equalsIgnoreCase(schema.getSchemaName(), existingSchema.getSchemaName())
+                    && schema.getSubnet().equals(existingSchema.getSubnet())) {
+                String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
+                Preconditions.checkArgument(false, new StringBuilder("VTEP schema with subnet [").append(subnetCidr)
+                        .append("] already exists. Multiple VTEP schemas with same subnet is not allowed.").toString());
+            }
+        }
+        if (isNotEmpty(getDpnIdList(validSchema.getDpnIds()))) {
+            String tzone = validSchema.getTransportZoneName();
+            List<BigInteger> lstDpns = getConflictingDpnsAlreadyConfiguredWithTz(validSchema.getSchemaName(), tzone,
+                       getDpnIdList(validSchema.getDpnIds()), existingSchemas);
+            if (!lstDpns.isEmpty()) {
+                Preconditions.checkArgument(false,
+                        new StringBuilder("DPN's ").append(lstDpns).append(" already configured for transport zone ")
+                                .append(tzone).append(". Only one end point per transport Zone per Dpn is allowed.")
+                                .toString());
+            }
+            if (schema.getTunnelType().equals(TunnelTypeGre.class)){
+                validateForSingleGreTep(validSchema.getSchemaName(), getDpnIdList(validSchema.getDpnIds()), existingSchemas);
+            }
+        }
+        return validSchema;
+    }
+    private static void validateForSingleGreTep(String schemaName, List<BigInteger> lstDpnsForAdd,
+            List<VtepConfigSchema> existingSchemas) {
+        for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
+            if ((TunnelTypeGre.class).equals(existingSchema.getTunnelType())
+                    && !StringUtils.equalsIgnoreCase(schemaName, existingSchema.getSchemaName())) {
+                List<BigInteger> lstConflictingDpns = new ArrayList<>(getDpnIdList(existingSchema.getDpnIds()));
+                lstConflictingDpns.retainAll(emptyIfNull(lstDpnsForAdd));
+                if (!lstConflictingDpns.isEmpty()) {
+                    String errMsg = new StringBuilder("DPN's ").append(lstConflictingDpns)
+                            .append(" already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.")
+                            .toString();
+                    Preconditions.checkArgument(false, errMsg);
+                }
+            }
+        }
+    }
+    public static VtepConfigSchema validateVtepConfigSchema(VtepConfigSchema schema) {
+        Preconditions.checkNotNull(schema);
+        Preconditions.checkArgument(StringUtils.isNotBlank(schema.getSchemaName()));
+        Preconditions.checkArgument(StringUtils.isNotBlank(schema.getPortName()));
+        Preconditions.checkArgument((schema.getVlanId() >= 0 && schema.getVlanId() < 4095),
+                "Invalid VLAN ID, range (0-4094)");
+        Preconditions.checkArgument(StringUtils.isNotBlank(schema.getTransportZoneName()));
+        Preconditions.checkNotNull(schema.getSubnet());
+        String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
+        SubnetUtils subnetUtils = new SubnetUtils(subnetCidr);
+        IpAddress gatewayIp = schema.getGatewayIp();
+        if (gatewayIp != null) {
+            String strGatewayIp = String.valueOf(gatewayIp.getValue());
+            if (!strGatewayIp.equals(ITMConstants.DUMMY_IP_ADDRESS) && !subnetUtils.getInfo().isInRange(strGatewayIp)) {
+                Preconditions.checkArgument(false, new StringBuilder("Gateway IP address ").append(strGatewayIp)
+                        .append(" is not in subnet range ").append(subnetCidr).toString());
+            }
+        }
+        ItmUtils.getExcludeIpAddresses(schema.getExcludeIpFilter(), subnetUtils.getInfo());
+        return new VtepConfigSchemaBuilder(schema).setTunnelType(schema.getTunnelType()).build();
+    }
+    public static String validateTunnelType(String tunnelType) {
+        if (tunnelType == null) {
+            tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
+        } else {
+            tunnelType = StringUtils.upperCase(tunnelType);
+            String error = new StringBuilder("Invalid tunnel type. Valid values: ")
+                    .append(ITMConstants.TUNNEL_TYPE_VXLAN).append(" | ").append(ITMConstants.TUNNEL_TYPE_GRE)
+                    .toString();
+            Preconditions.checkArgument(ITMConstants.TUNNEL_TYPE_VXLAN.equals(tunnelType)
+                    || ITMConstants.TUNNEL_TYPE_GRE.equals(tunnelType), error);
+        }
+        return tunnelType;
+    }
+    private static List<BigInteger> getConflictingDpnsAlreadyConfiguredWithTz(String schemaName, String tzone,
+            List<BigInteger> lstDpns, List<VtepConfigSchema> existingSchemas) {
+        List<BigInteger> lstConflictingDpns = new ArrayList<>();
+        for (VtepConfigSchema schema : emptyIfNull(existingSchemas)) {
+            if (!StringUtils.equalsIgnoreCase(schemaName, schema.getSchemaName())
+                    && StringUtils.equals(schema.getTransportZoneName(), tzone)) {
+                lstConflictingDpns = new ArrayList<>(getDpnIdList(schema.getDpnIds()));
+                lstConflictingDpns.retainAll(lstDpns);
+                if (!lstConflictingDpns.isEmpty()) {
+                    break;
+                }
+            }
+        }
+        return lstConflictingDpns;
+    }
+    public static VtepConfigSchema constructVtepConfigSchema(String schemaName, String portName, Integer vlanId,
+            String subnetMask, String gatewayIp, String transportZone,String tunnelType, List<BigInteger> dpnIds,
+            String excludeIpFilter) {
+        IpAddress gatewayIpObj = StringUtils.isBlank(gatewayIp) ? null : new IpAddress(gatewayIp.toCharArray());
+        IpPrefix subnet = StringUtils.isBlank(subnetMask) ? null : new IpPrefix(subnetMask.toCharArray());
+        Class<? extends TunnelTypeBase> tunType ;
+        if( tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN))
+            tunType = TunnelTypeVxlan.class ;
+        else
+            tunType = TunnelTypeGre.class ;
+        VtepConfigSchemaBuilder schemaBuilder = new VtepConfigSchemaBuilder().setSchemaName(schemaName)
+                .setPortName(portName).setVlanId(vlanId).setSubnet(subnet).setGatewayIp(gatewayIpObj)
+                .setTransportZoneName(transportZone).setTunnelType(tunType).setDpnIds(getDpnIdsListFromBigInt(dpnIds))
+                .setExcludeIpFilter(excludeIpFilter);
+        return schemaBuilder.build();
+    }
+    public static List<IpAddress> getExcludeIpAddresses(String excludeIpFilter, SubnetInfo subnetInfo) {
+        final List<IpAddress> lstIpAddress = new ArrayList<>();
+        if (StringUtils.isBlank(excludeIpFilter)) {
+            return lstIpAddress;
+        }
+        final String[] arrIps = StringUtils.split(excludeIpFilter, ',');
+        for (String ip : arrIps) {
+            if (StringUtils.countMatches(ip, "-") == 1) {
+                final String[] arrIpRange = StringUtils.split(ip, '-');
+                String strStartIp = StringUtils.trim(arrIpRange[0]);
+                String strEndIp = StringUtils.trim(arrIpRange[1]);
+                Preconditions.checkArgument(InetAddresses.isInetAddress(strStartIp),
+                        new StringBuilder("Invalid exclude IP filter: invalid IP address value ").append(strStartIp)
+                                .toString());
+                Preconditions.checkArgument(InetAddresses.isInetAddress(strEndIp),
+                        new StringBuilder("Invalid exclude IP filter: invalid IP address value ").append(strEndIp)
+                                .toString());
+                Preconditions.checkArgument(subnetInfo.isInRange(strStartIp),
+                        new StringBuilder("Invalid exclude IP filter: IP address [").append(strStartIp)
+                                .append("] not in subnet range ").append(subnetInfo.getCidrSignature()).toString());
+                Preconditions.checkArgument(subnetInfo.isInRange(strEndIp),
+                        new StringBuilder("Invalid exclude IP filter: IP address [").append(strEndIp)
+                                .append("] not in subnet range ").append(subnetInfo.getCidrSignature()).toString());
+                int startIp = subnetInfo.asInteger(strStartIp);
+                int endIp = subnetInfo.asInteger(strEndIp);
+
+                Preconditions.checkArgument(startIp < endIp,
+                        new StringBuilder("Invalid exclude IP filter: Invalid range [").append(ip).append("] ")
+                                .toString());
+                for (int i = startIp; i <= endIp; i++) {
+                    String ipAddress = ipFormat(toIpArray(i));
+                    validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ipAddress);
+                }
+            } else {
+                validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ip);
+            }
+        }
+        return lstIpAddress;
+    }
+    private static void validateAndAddIpAddressToList(SubnetInfo subnetInfo, final List<IpAddress> lstIpAddress,
+            String ipAddress) {
+        String ip = StringUtils.trim(ipAddress);
+        Preconditions.checkArgument(InetAddresses.isInetAddress(ip),
+                new StringBuilder("Invalid exclude IP filter: invalid IP address value ").append(ip).toString());
+        Preconditions.checkArgument(subnetInfo.isInRange(ip),
+                new StringBuilder("Invalid exclude IP filter: IP address [").append(ip).append("] not in subnet range ")
+                        .append(subnetInfo.getCidrSignature()).toString());
+        lstIpAddress.add(new IpAddress(ip.toCharArray()));
+    }
+    private static int[] toIpArray(int val) {
+        int[] ret = new int[4];
+        for (int j = 3; j >= 0; --j) {
+            ret[j] |= ((val >>> 8 * (3 - j)) & (0xff));
+        }
+        return ret;
+    }
+    private static String ipFormat(int[] octets) {
+        StringBuilder str = new StringBuilder();
+        for (int i = 0; i < octets.length; ++i) {
+            str.append(octets[i]);
+            if (i != octets.length - 1) {
+                str.append(".");
+            }
+        }
+        return str.toString();
+    }
+    public static VtepConfigSchema validateForUpdateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd,
+            List<BigInteger> lstDpnsForDelete, IITMProvider itmProvider) {
+        Preconditions.checkArgument(StringUtils.isNotBlank(schemaName));
+        if ((lstDpnsForAdd == null || lstDpnsForAdd.isEmpty())
+                && (lstDpnsForDelete == null || lstDpnsForDelete.isEmpty())) {
+            Preconditions.checkArgument(false,
+                    new StringBuilder("DPN ID list for add | delete is null or empty in schema ").append(schemaName)
+                            .toString());
+        }
+        VtepConfigSchema schema = itmProvider.getVtepConfigSchema(schemaName);
+        if (schema == null) {
+            Preconditions.checkArgument(false, new StringBuilder("Specified VTEP Schema [").append(schemaName)
+                    .append("] doesn't exists!").toString());
+        }
+        List<BigInteger> existingDpnIds = getDpnIdList(schema.getDpnIds());
+        if (isNotEmpty(lstDpnsForAdd)) {
+            if (isNotEmpty(existingDpnIds)) {
+                List<BigInteger> lstAlreadyExistingDpns = new ArrayList<>(existingDpnIds);
+                lstAlreadyExistingDpns.retainAll(lstDpnsForAdd);
+                Preconditions.checkArgument(lstAlreadyExistingDpns.isEmpty(),
+                        new StringBuilder("DPN ID's ").append(lstAlreadyExistingDpns)
+                                .append(" already exists in VTEP schema [").append(schemaName).append("]").toString());
+            }
+            if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
+                validateForSingleGreTep(schema.getSchemaName(), lstDpnsForAdd, itmProvider.getAllVtepConfigSchemas());
+            }
+        }
+        if (isNotEmpty(lstDpnsForDelete)) {
+            if (existingDpnIds == null || existingDpnIds.isEmpty()) {
+                StringBuilder builder = new StringBuilder("DPN ID's ").append(lstDpnsForDelete)
+                        .append(" specified for delete from VTEP schema [").append(schemaName)
+                        .append("] are not configured in the schema.");
+                Preconditions.checkArgument(false, builder.toString());
+            } else if (!existingDpnIds.containsAll(lstDpnsForDelete)) {
+                List<BigInteger> lstConflictingDpns = new ArrayList<>(lstDpnsForDelete);
+                lstConflictingDpns.removeAll(existingDpnIds);
+                StringBuilder builder = new StringBuilder("DPN ID's ").append(lstConflictingDpns)
+                        .append(" specified for delete from VTEP schema [").append(schemaName)
+                        .append("] are not configured in the schema.");
+                Preconditions.checkArgument(false, builder.toString());
+            }
+        }
+        return schema;
+    }
+    public static String getSubnetCidrAsString(IpPrefix subnet) {
+        return (subnet == null) ? StringUtils.EMPTY : String.valueOf(subnet.getValue());
+    }
+    public static <T> List<T> emptyIfNull(List<T> list) {
+        return (list == null) ? Collections.<T> emptyList() : list;
+    }
+    public static <T> boolean isEmpty(Collection<T> collection) {
+        return (collection == null || collection.isEmpty()) ? true : false;
+    }
+    public static <T> boolean isNotEmpty(Collection<T> collection) {
+        return !isEmpty(collection);
+    }
+    public static HwVtep createHwVtepObject(String topo_id, String node_id, IpAddress ipAddress, IpPrefix ipPrefix, IpAddress gatewayIP, int vlanID, Class<? extends TunnelTypeBase> tunnel_type, TransportZone transportZone) {
+        HwVtep hwVtep = new HwVtep();
+        hwVtep.setGatewayIP(gatewayIP);
+        hwVtep.setHwIp(ipAddress);
+        hwVtep.setIpPrefix(ipPrefix);
+        hwVtep.setNode_id(node_id);
+        hwVtep.setTopo_id(topo_id);
+        hwVtep.setTransportZone(transportZone.getZoneName());
+        hwVtep.setTunnel_type(tunnel_type);
+        hwVtep.setVlanID(vlanID);
+        return hwVtep;
+    }
+
+    public static String getHwParentIf(String topo_id, String srcNodeid) {
+        return String.format("%s:%s", topo_id, srcNodeid);
+    }
+
+    public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
+                    InstanceIdentifier<T> path, T data, DataBroker broker) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.put(datastoreType, path, data, true);
+        CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
+        try {
+            futures.get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    public static List<BigInteger> getDpnIdList( List<DpnIds> dpnIds ) {
+        List<BigInteger> dpnList = new ArrayList<BigInteger>() ;
+        for( DpnIds dpn : dpnIds) {
+           dpnList.add(dpn.getDPN()) ;
+        }
+        return dpnList ;
+    }
+
+    public static List<DpnIds> getDpnIdsListFromBigInt( List<BigInteger> dpnIds) {
+        List<DpnIds> dpnIdList = new ArrayList<DpnIds>() ;
+        DpnIdsBuilder builder = new DpnIdsBuilder() ;
+        for( BigInteger dpnId : dpnIds) {
+              dpnIdList.add(builder.setKey(new DpnIdsKey(dpnId)).setDPN(dpnId).build() );
+        }
+        return dpnIdList;
+    }
+
 }
+
index f15bd19b0fa0e3126a362635407a68f909aefd2a..fae12dc6454223ca69eaa989c086c9446ceb6c9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -9,10 +9,7 @@
 package org.opendaylight.vpnservice.itm.listeners;
 
 import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 import com.google.common.base.Optional;
@@ -22,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.itm.confighelpers.HwVtep;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
@@ -32,6 +30,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.Tr
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZonesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZone;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.DeviceVteps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.Vteps;
 import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
@@ -107,34 +106,99 @@ public class TransportZoneListener extends AsyncDataTreeChangeListenerBase<Trans
     protected void remove(InstanceIdentifier<TransportZone> key, TransportZone tzOld) {
         LOG.debug("Received Transport Zone Remove Event: {}, {}", key, tzOld);
         List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzOld);
+        List<HwVtep> hwVtepList = createhWVteps(tzOld);
         LOG.trace("Delete: Invoking deleteTunnels in ItmManager with DpnList {}", opDpnList);
-        if(opDpnList.size()>0) {
+        if(opDpnList.size()>0 || hwVtepList.size()>0) {
             LOG.trace("Delete: Invoking ItmManager");
-           // itmManager.deleteTunnels(opDpnList);
+            LOG.trace("Add: Invoking ItmManager with hwVtep List {} " , hwVtepList);
+            // itmManager.deleteTunnels(opDpnList);
             DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-            ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(opDpnList, dataBroker, idManagerService, mdsalManager);
+            ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(opDpnList,hwVtepList, dataBroker, idManagerService, mdsalManager);
             coordinator.enqueueJob(tzOld.getZoneName(), removeWorker);
         }
     }
 
     @Override
     protected void update(InstanceIdentifier<TransportZone> key, TransportZone tzOld, TransportZone tzNew) {
-        LOG.debug("Received Transport Zone Update Event: {}, {}, {}", key, tzOld, tzNew);
-        if( !(tzOld.equals(tzNew))) {
-           add(key, tzNew);
+        LOG.debug("Received Transport Zone Update Event: Key - {}, Old - {}, Updated - {}", key, tzOld, tzNew);
+        //if( !(tzOld.equals(tzNew))) {
+        //add(key, tzNew);
+        List<DPNTEPsInfo> oldDpnTepsList = new ArrayList<DPNTEPsInfo>();
+        oldDpnTepsList = createDPNTepInfo(tzOld);
+        List<DPNTEPsInfo> newDpnTepsList = new ArrayList<DPNTEPsInfo>();
+        newDpnTepsList = createDPNTepInfo(tzNew);
+        List<DPNTEPsInfo> oldDpnTepsListcopy = new ArrayList<DPNTEPsInfo>();
+        oldDpnTepsListcopy.addAll(oldDpnTepsList);
+        LOG.trace("oldcopy0" + oldDpnTepsListcopy);
+        List<DPNTEPsInfo> newDpnTepsListcopy = new ArrayList<DPNTEPsInfo>();
+        newDpnTepsListcopy.addAll(newDpnTepsList);
+        LOG.trace("newcopy0" + newDpnTepsListcopy);
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+
+        oldDpnTepsList.removeAll(newDpnTepsListcopy);
+        newDpnTepsList.removeAll(oldDpnTepsListcopy);
+
+        LOG.trace("oldDpnTepsList" + oldDpnTepsList);
+        LOG.trace("newDpnTepsList" + newDpnTepsList);
+        LOG.trace("oldcopy"+oldDpnTepsListcopy);
+        LOG.trace("newcopy"+newDpnTepsListcopy);
+        LOG.trace("oldcopy Size "+oldDpnTepsList.size());
+        LOG.trace("newcopy Size "+newDpnTepsList.size());
+        if(newDpnTepsList.size() > 0) {
+            LOG.trace( "Adding TEPs " );
+            ItmTepAddWorker addWorker = new ItmTepAddWorker(newDpnTepsList, Collections.<HwVtep>emptyList(), dataBroker, idManagerService, mdsalManager);
+            coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
+        }
+        if(oldDpnTepsList.size() > 0) {
+            LOG.trace( "Removing TEPs " );
+            ItmTepRemoveWorker removeWorker =
+                            new ItmTepRemoveWorker(oldDpnTepsList, Collections.<HwVtep>emptyList(), dataBroker, idManagerService, mdsalManager);
+            coordinator.enqueueJob(tzNew.getZoneName(), removeWorker);
+        }
+        List<HwVtep> oldHwList = new ArrayList<HwVtep>();
+        oldHwList = createhWVteps(tzOld);
+        List<HwVtep> newHwList = new ArrayList<HwVtep>();
+        newHwList =  createhWVteps(tzNew);
+        List<HwVtep> oldHwListcopy = new ArrayList<HwVtep>();
+        oldHwListcopy.addAll(oldHwList);
+        LOG.trace("oldHwListcopy0" + oldHwListcopy);
+        List<HwVtep> newHwListcopy = new ArrayList<HwVtep>();
+        newHwListcopy.addAll(newHwList);
+        LOG.trace("newHwListcopy0" + newHwListcopy);
+
+        oldHwList.removeAll(newHwListcopy);
+        newHwList.removeAll(oldHwListcopy);
+        LOG.trace("oldHwList" + oldHwList);
+        LOG.trace("newHwList" + newHwList);
+        LOG.trace("oldHwListcopy" + oldHwListcopy);
+        LOG.trace("newHwListcopy" + newHwListcopy);
+        if(newHwList.size() > 0) {
+            LOG.trace( "Adding HW TEPs " );
+            ItmTepAddWorker addWorker = new ItmTepAddWorker(Collections.<DPNTEPsInfo>emptyList(), newHwList, dataBroker, idManagerService, mdsalManager);
+            coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
         }
+        if(oldHwList.size() > 0) {
+             LOG.trace( "Removing HW TEPs " );
+            ItmTepRemoveWorker removeWorker =
+                            new ItmTepRemoveWorker(Collections.<DPNTEPsInfo>emptyList(), oldHwList, dataBroker,
+                                            idManagerService, mdsalManager);
+            coordinator.enqueueJob(tzNew.getZoneName(), removeWorker);
+        }
+
     }
 
     @Override
     protected void add(InstanceIdentifier<TransportZone> key, TransportZone tzNew) {
         LOG.debug("Received Transport Zone Add Event: {}, {}", key, tzNew);
         List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzNew);
+        List<HwVtep> hwVtepList = createhWVteps(tzNew);
         LOG.trace("Add: Operational dpnTepInfo - Before invoking ItmManager {}", opDpnList);
-        if(opDpnList.size()>0) {
-          LOG.trace("Add: Invoking ItmManager with DPN List {} " , opDpnList);
+        if(opDpnList.size()>0 || hwVtepList.size()>0) {
+            LOG.trace("Add: Invoking ItmManager with DPN List {} " , opDpnList);
+            LOG.trace("Add: Invoking ItmManager with hwVtep List {} " , hwVtepList);
           //itmManager.build_all_tunnels(opDpnList);
           DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-          ItmTepAddWorker addWorker = new ItmTepAddWorker(opDpnList,dataBroker, idManagerService, mdsalManager);
+            ItmTepAddWorker addWorker = new ItmTepAddWorker(opDpnList, hwVtepList, dataBroker, idManagerService, mdsalManager);
           coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
       }
     }
@@ -186,4 +250,45 @@ public class TransportZoneListener extends AsyncDataTreeChangeListenerBase<Trans
         }
         return dpnTepInfo;
     }
-}
\ No newline at end of file
+    private List<HwVtep> createhWVteps(TransportZone transportZone) {
+        //creating hwVtepsList to pass
+        //Inventory model would deprecate Eventually, so not creating hWvtepslist under createDpnTepInfo();
+        List<HwVtep> hwVtepsList = new ArrayList<HwVtep>();
+        //currently the list has only one object always since we are adding L2Gws one by one and only to One TransportZone.
+        //Map<BigInteger, List<TunnelEndPoints>> mapDPNToTunnelEndpt = new ConcurrentHashMap<>();
+
+        String zone_name = transportZone.getZoneName();
+        Class<? extends TunnelTypeBase> tunnel_type = transportZone.getTunnelType();
+        LOG.trace("Transport Zone_name: {}", zone_name);
+        List<Subnets> subnetsList = transportZone.getSubnets();
+        if (subnetsList != null) {
+            for (Subnets subnet : subnetsList) {
+                IpPrefix ipPrefix = subnet.getPrefix();
+                IpAddress gatewayIP = subnet.getGatewayIp();
+                int vlanID = subnet.getVlanId();
+                LOG.trace("IpPrefix: {}, gatewayIP: {}, vlanID: {} ", ipPrefix, gatewayIP, vlanID);
+                List<DeviceVteps> deviceVtepsList = subnet.getDeviceVteps();
+                if (deviceVtepsList != null) {
+                    for (DeviceVteps vteps : deviceVtepsList) {
+                        String topo_id = vteps.getTopologyId();
+                        String node_id = vteps.getNodeId();
+                        IpAddress ipAddress = vteps.getIpAddress();
+                        LOG.trace("topo-id: {}, node-id: {}, ipAddress: {}", topo_id, node_id, ipAddress);
+                        //TunnelEndPoints tunnelEndPoints = ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port, vlanID, ipPrefix, gatewayIP, zone_name, tunnel_type);
+                        HwVtep hwVtep = ItmUtils.createHwVtepObject(topo_id, node_id, ipAddress, ipPrefix, gatewayIP, vlanID, tunnel_type, transportZone);
+
+                        if (hwVtepsList != null) {
+                            LOG.trace("Existing hwVteps");
+                            hwVtepsList.add(hwVtep);
+                        } else {
+                            LOG.trace("Adding new HwVtep {} info ", hwVtep.getHwIp());
+                            hwVtepsList.add(hwVtep);
+                        }
+                    }
+                }
+            }
+        }
+        LOG.trace("returning hwvteplist {}", hwVtepsList);
+        return hwVtepsList;
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/listeners/VtepConfigSchemaListener.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/listeners/VtepConfigSchemaListener.java
new file mode 100644 (file)
index 0000000..9b8b138
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ * Copyright (c) 2016 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.itm.listeners;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.net.util.SubnetUtils;
+import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
+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;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.itm.cli.TepCommandHelper;
+import org.opendaylight.vpnservice.itm.globals.ITMConstants;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.VtepConfigSchemas;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.VtepConfigSchemaBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.ip.pools.VtepIpPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.ip.pools.VtepIpPoolBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.vtep.config.schema.DpnIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.config.rev151102.vtep.config.schemas.vtep.config.schema.DpnIdsKey;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.VtepConfigSchemas;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.vtep.config.schemas.VtepConfigSchema;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.vtep.config.schemas.VtepConfigSchemaBuilder;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.vtep.ip.pools.VtepIpPool;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.config.rev151102.vtep.ip.pools.VtepIpPoolBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZoneKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.SubnetsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.Vteps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.VtepsKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+/**
+ * The listener class interested in processing data change on
+ * {@code VtepConfigSchema} objects.
+ *
+ * @see VtepConfigSchema
+ */
+public class VtepConfigSchemaListener extends AbstractDataChangeListener<VtepConfigSchema> implements AutoCloseable {
+
+    /** The Constant LOG. */
+    private static final Logger LOG = LoggerFactory.getLogger(VtepConfigSchemaListener.class);
+
+    /** The listener registration. */
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+    /** The data broker. */
+    private final DataBroker dataBroker;
+
+    /**
+     * Instantiates a new vtep config schema listener.
+     *
+     * @param db
+     *            the db
+     */
+    public VtepConfigSchemaListener(final DataBroker db) {
+        super(VtepConfigSchema.class);
+        this.dataBroker = db;
+        registerListener(db);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.AutoCloseable#close()
+     */
+    @Override
+    public void close() throws Exception {
+        if (this.listenerRegistration != null) {
+            try {
+                this.listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up DataChangeListener.", e);
+            }
+            this.listenerRegistration = null;
+        }
+        LOG.info("VtepConfigSchemaListener Closed");
+    }
+
+    /**
+     * Register listener.
+     *
+     * @param db
+     *            the db
+     */
+    private void registerListener(final DataBroker db) {
+        try {
+            this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    getWildCardPath(), VtepConfigSchemaListener.this, AsyncDataBroker.DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            LOG.error("VtepConfigSchemaListener DataChange listener registration fail!", e);
+            throw new IllegalStateException("VtepConfigSchemaListener registration Listener failed.", e);
+        }
+    }
+
+    /**
+     * Gets the wild card path.
+     *
+     * @return the wild card path
+     */
+    private InstanceIdentifier<VtepConfigSchema> getWildCardPath() {
+        return ItmUtils.getVtepConfigSchemaIdentifier();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener#remove(
+     * org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
+     * org.opendaylight.yangtools.yang.binding.DataObject)
+     */
+    @Override
+    protected void remove(InstanceIdentifier<VtepConfigSchema> identifier, VtepConfigSchema schema) {
+        LOG.trace("Received notification for VTEP config schema [{}] deleted.", schema.getSchemaName());
+        try {
+            List<BigInteger> lstDpnIds = ItmUtils.getDpnIdList(schema.getDpnIds());
+            if (lstDpnIds != null && !lstDpnIds.isEmpty()) {
+                deleteVteps(schema, lstDpnIds);
+            }
+
+            // Delete IP pool corresponding to schema
+            // TODO: Ensure no schema exists with same subnet before deleting
+            String subnetCidr = ItmUtils.getSubnetCidrAsString(schema.getSubnet());
+            deleteVtepIpPool(subnetCidr);
+        } catch (Exception e) {
+            String error = new StringBuilder("Failed to handle DCN for delete VtepConfigSchema: ").append(schema)
+                    .toString();
+            LOG.error(error, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener#update(
+     * org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
+     * org.opendaylight.yangtools.yang.binding.DataObject,
+     * org.opendaylight.yangtools.yang.binding.DataObject)
+     */
+    @Override
+    protected void update(InstanceIdentifier<VtepConfigSchema> identifier, VtepConfigSchema original,
+            VtepConfigSchema updated) {
+        LOG.error("Receivedn DCN for updating VTEP Original schema: {}. Updated schema: {}",
+                original, updated);
+        //LOG.trace("Received notification for VTEP config schema [{}] updated.", original.getSchemaName());
+
+        try {
+            VtepConfigSchema orignalSchema = ItmUtils.validateVtepConfigSchema(original);
+            VtepConfigSchema updatedSchema = ItmUtils.validateVtepConfigSchema(updated);
+
+            if (doesDeleteAndAddSchemaRequired(original, updated)) {
+                LOG.error("Failed to handle DCN for updating VTEP schema {}. Original schema: {}. Updated schema: {}",
+                        original, updated);
+                // TODO: handle updates
+                return;
+            }
+
+            handleUpdateOfDpnIds(orignalSchema, updatedSchema);
+
+        } catch (Exception e) {
+            String error = new StringBuilder("Failed to handle DCN for update VtepConfigSchema original:")
+                    .append(original).append(", updated: ").append(updated).toString();
+            LOG.error(error, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener#add(org.
+     * opendaylight.yangtools.yang.binding.InstanceIdentifier,
+     * org.opendaylight.yangtools.yang.binding.DataObject)
+     */
+    @Override
+    protected void add(InstanceIdentifier<VtepConfigSchema> identifier, VtepConfigSchema schema) {
+        // Construct the transport zones from the provided schemas and push it
+        // to config DS.
+        LOG.trace("Add VtepConfigSchema: key: {} , value: {}", identifier, schema);
+
+        try {
+            VtepConfigSchema validatedSchema = ItmUtils.validateForAddVtepConfigSchema(schema,
+                    getAllVtepConfigSchemas());
+
+            VtepIpPool vtepIpPool = processAvailableIps(validatedSchema);
+            addVteps(validatedSchema, vtepIpPool);
+        } catch (Exception e) {
+            LOG.error("Failed to handle DCN for add VtepConfigSchema: {}", e);
+        }
+    }
+
+    /**
+     * Handle update of dpn ids.
+     *
+     * @param original
+     *            the original
+     * @param updated
+     *            the updated
+     */
+    private void handleUpdateOfDpnIds(VtepConfigSchema original, VtepConfigSchema updated) {
+        // Handling add/delete DPNs from schema
+        List<DpnIds> originalDpnIds = (original.getDpnIds() == null) ? new ArrayList<DpnIds>()
+                : original.getDpnIds();
+        List<DpnIds> updatedDpnIds = (updated.getDpnIds() == null) ? new ArrayList<DpnIds>()
+                : updated.getDpnIds();
+
+        handleDeletedDpnsFromSchema(original, originalDpnIds, updatedDpnIds);
+        handleNewlyAddedDpnsToSchema(original, originalDpnIds, updatedDpnIds);
+    }
+
+    /**
+     * Does delete and add schema required.
+     *
+     * @param original
+     *            the original
+     * @param updated
+     *            the updated
+     * @return true, if successful
+     */
+    private boolean doesDeleteAndAddSchemaRequired(VtepConfigSchema original, VtepConfigSchema updated) {
+        boolean delnAddRequired = false;
+        if (!StringUtils.equalsIgnoreCase(original.getPortName(), updated.getPortName())) {
+            delnAddRequired = true;
+        } else if (original.getVlanId() != updated.getVlanId()) {
+            delnAddRequired = true;
+        } else if (original.getSubnet() != null && !original.getSubnet().equals(updated.getSubnet())) {
+            delnAddRequired = true;
+        } else if (original.getGatewayIp() != null && !original.getGatewayIp().equals(updated.getGatewayIp())) {
+            delnAddRequired = true;
+        } else if (!StringUtils.equalsIgnoreCase(original.getTransportZoneName(), updated.getTransportZoneName())) {
+            delnAddRequired = true;
+        } else if (!(original.getTunnelType().equals(updated.getTunnelType()) )) {
+            delnAddRequired = true;
+        }
+        return delnAddRequired;
+    }
+
+    /**
+     * Handle newly added dpns to schema.
+     *
+     * @param original
+     *            the original
+     * @param originalDpnIds
+     *            the original dpn ids
+     * @param updatedDpnIds
+     *            the updated dpn ids
+     */
+    private void handleNewlyAddedDpnsToSchema(VtepConfigSchema original, List<DpnIds> originalDpnIds,
+            List<DpnIds> updatedDpnIds) {
+        LOG.trace("Handle Addition of DPNs from VTEP Original Dpn: {}. Updated Dpn: {}", originalDpnIds, updatedDpnIds) ;
+        ArrayList<DpnIds> newlyAddedDpns = new ArrayList<>(updatedDpnIds);
+        newlyAddedDpns.removeAll(originalDpnIds);
+        LOG.debug("Newly added DPNs {} to VTEP config schema [{}].", newlyAddedDpns, original.getSchemaName());
+        if (!newlyAddedDpns.isEmpty()) {
+            VtepConfigSchema diffSchema = new VtepConfigSchemaBuilder(original).setDpnIds(newlyAddedDpns).build();
+            String subnetCidr = ItmUtils.getSubnetCidrAsString(original.getSubnet());
+            VtepIpPool vtepIpPool = getVtepIpPool(subnetCidr);
+            LOG.debug("Adding of DPNs in Diff Schema: {}", diffSchema) ;
+            addVteps(diffSchema, vtepIpPool);
+        }
+    }
+
+    /**
+     * Handle deleted dpns from schema.
+     *
+     * @param original
+     *            the original
+     * @param originalDpnIds
+     *            the original dpn ids
+     * @param updatedDpnIds
+     *            the updated dpn ids
+     */
+    private void handleDeletedDpnsFromSchema(VtepConfigSchema original, List<DpnIds> originalDpnIds,
+            List<DpnIds> updatedDpnIds) {
+        ArrayList<DpnIds> deletedDpns = new ArrayList<>(originalDpnIds);
+        deletedDpns.removeAll(updatedDpnIds);
+        LOG.debug("DPNs to be removed DPNs {} from VTEP config schema [{}].", deletedDpns, original.getSchemaName());
+        if (!deletedDpns.isEmpty()) {
+            LOG.debug("Deleting of DPNs from VTEP Schema: {}. To be deleted Dpns: {}", original, deletedDpns) ;
+            deleteVteps(original, ItmUtils.getDpnIdList(deletedDpns));
+        }
+    }
+
+    /**
+     * Gets all vtep config schemas.
+     *
+     * @return the all vtep config schemas
+     */
+    private List<VtepConfigSchema> getAllVtepConfigSchemas() {
+        Optional<VtepConfigSchemas> schemas = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
+                ItmUtils.getVtepConfigSchemasIdentifier(), this.dataBroker);
+        if (schemas.isPresent()) {
+            return schemas.get().getVtepConfigSchema();
+        }
+        return null;
+    }
+
+    /**
+     * Adds the vteps.
+     *
+     * @param schema
+     *            the schema
+     * @param vtepIpPool
+     *            the vtep ip pool
+     */
+    private void addVteps(VtepConfigSchema schema, VtepIpPool vtepIpPool) {
+        if (schema.getDpnIds() == null || schema.getDpnIds().isEmpty()) {
+            LOG.debug("DPN list is empty, skipping addVteps for schema: {}", schema);
+            return;
+        }
+
+        String subnetCidr = ItmUtils.getSubnetCidrAsString(schema.getSubnet());
+        if (vtepIpPool == null) {
+            LOG.error("VTEP config pool not found for subnetCidr {}. Failed to add VTEPs for schema {}", subnetCidr,
+                    schema);
+            return;
+        }
+        TepCommandHelper tepCommandHelper = new TepCommandHelper(this.dataBroker);
+        // Check this later
+        String tunType ;
+        Class<? extends TunnelTypeBase> tunnelType = schema.getTunnelType() ;
+        if( tunnelType.equals(TunnelTypeVxlan.class))
+            tunType = ITMConstants.TUNNEL_TYPE_VXLAN ;
+        else
+            tunType =  ITMConstants.TUNNEL_TYPE_GRE;
+        tepCommandHelper.configureTunnelType(schema.getTransportZoneName(),
+                StringUtils.upperCase(tunType));
+
+        List<IpAddress> availableIps = vtepIpPool.getAvailableIpaddress();
+        List<IpAddress> newlyAllocatedIps = new ArrayList<>();
+        List<BigInteger> skippedDpnIds = new ArrayList<>();
+
+        String gatewayIp = handleGatewayIp(schema.getGatewayIp());
+        for (BigInteger dpnId : ItmUtils.getDpnIdList(schema.getDpnIds())) {
+            IpAddress ipAddress = getAnAvailableIP(availableIps);
+            if (ipAddress == null) {
+                skippedDpnIds.add(dpnId);
+                continue;
+            }
+            tepCommandHelper.createLocalCache(dpnId, schema.getPortName(), schema.getVlanId(),
+                    String.valueOf(ipAddress.getValue()), subnetCidr, gatewayIp, schema.getTransportZoneName());
+            newlyAllocatedIps.add(ipAddress);
+        }
+        if (!skippedDpnIds.isEmpty()) {
+            LOG.error("No available IP addresses in the VTEP config pool {}, skipping VTEP configurations for DPN's {}",
+                    subnetCidr, skippedDpnIds);
+        }
+
+        if (!newlyAllocatedIps.isEmpty()) {
+            LOG.debug( "Delete OnCommit and buildTeps in NewlyAddedDpns");
+            tepCommandHelper.deleteOnCommit();
+            tepCommandHelper.buildTeps();
+            allocateIpAddresses(newlyAllocatedIps, vtepIpPool, subnetCidr);
+        }
+    }
+
+    /**
+     * Handle gateway ip.
+     *
+     * @param gatewayIp
+     *            the gateway ip
+     * @return the string
+     */
+    private String handleGatewayIp(IpAddress gatewayIp) {
+        String strGatewayIp = (gatewayIp == null) ? null : String.valueOf(gatewayIp.getValue());
+        if (StringUtils.isBlank(strGatewayIp) || StringUtils.equals(ITMConstants.DUMMY_IP_ADDRESS, strGatewayIp)) {
+            // To avoid a validation exception in TepCommandHelper
+            strGatewayIp = null;
+        }
+        return strGatewayIp;
+    }
+
+    /**
+     * Delete vteps.
+     *
+     * @param schema
+     *            the schema
+     * @param lstDpnIdsToBeDeleted
+     *            the dpn ids list to be deleted
+     */
+    private void deleteVteps(VtepConfigSchema schema, List<BigInteger> lstDpnIdsToBeDeleted) {
+        TepCommandHelper tepCommandHelper = new TepCommandHelper(this.dataBroker);
+        List<IpAddress> freeIps = new ArrayList<>();
+
+        String subnetCidr = ItmUtils.getSubnetCidrAsString(schema.getSubnet());
+        String gatewayIp = handleGatewayIp(schema.getGatewayIp());
+
+        for (BigInteger dpnId : lstDpnIdsToBeDeleted) {
+            VtepsKey vtepkey = new VtepsKey(dpnId, schema.getPortName());
+
+            InstanceIdentifier<Vteps> vpath = InstanceIdentifier.builder(TransportZones.class)
+                    .child(TransportZone.class, new TransportZoneKey(schema.getTransportZoneName()))
+                    .child(Subnets.class, new SubnetsKey(schema.getSubnet())).child(Vteps.class, vtepkey).build();
+
+            Vteps vtep = null;
+            Optional<Vteps> vtepOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, vpath, dataBroker);
+            if (vtepOptional.isPresent()) {
+                vtep = vtepOptional.get();
+            } else {
+                LOG.warn("VTEP doesn't exist for DPN [{}] and port [{}].", dpnId, schema.getPortName());
+                continue;
+            }
+
+            IpAddress ipAddress = vtep.getIpAddress();
+            tepCommandHelper.deleteVtep(dpnId, vtep.getPortname(), schema.getVlanId(),
+                    String.valueOf(ipAddress.getValue()), subnetCidr, gatewayIp, schema.getTransportZoneName());
+
+            freeIps.add(ipAddress);
+        }
+        LOG.debug( "Delete OnCommit in NewlyAddedDpns");
+        tepCommandHelper.deleteOnCommit();
+        deAllocateIpAddresses(freeIps, subnetCidr);
+    }
+
+    /**
+     * Calculate available IPs from the subnet mask specified in the schema.
+     * Pushes the available and allocated IP address to config DS.
+     *
+     * @param schema
+     *            the schema
+     */
+    private VtepIpPool processAvailableIps(final VtepConfigSchema schema) {
+        String subnetCidr = ItmUtils.getSubnetCidrAsString(schema.getSubnet());
+        SubnetUtils subnetUtils = new SubnetUtils(subnetCidr);
+
+        List<IpAddress> availableIps = calculateAvailableIps(subnetUtils, schema.getExcludeIpFilter(),
+                schema.getGatewayIp());
+        VtepIpPool vtepIpPool = new VtepIpPoolBuilder().setSubnetCidr(subnetCidr).setAvailableIpaddress(availableIps)
+                .setAllocatedIpaddress(new ArrayList<IpAddress>()).build();
+
+        MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
+                ItmUtils.getVtepIpPoolIdentifier(subnetCidr), vtepIpPool);
+        LOG.info("Vtep IP Pool with key:{} added to config DS", subnetCidr);
+        return vtepIpPool;
+    }
+
+    /**
+     * Gets the vtep ip pool.
+     *
+     * @param subnetCidr
+     *            the subnet cidr
+     * @return the vtep ip pool
+     */
+    private VtepIpPool getVtepIpPool(final String subnetCidr) {
+        Optional<VtepIpPool> vtepIpPool = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
+                ItmUtils.getVtepIpPoolIdentifier(subnetCidr), this.dataBroker);
+        if (vtepIpPool.isPresent()) {
+            return vtepIpPool.get();
+        }
+        return null;
+    }
+
+    /**
+     * Delete vtep ip pool.
+     *
+     * @param subnetCidr
+     *            the subnet cidr
+     */
+    private void deleteVtepIpPool(final String subnetCidr) {
+        if (StringUtils.isNotBlank(subnetCidr)) {
+            MDSALUtil.syncDelete(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    ItmUtils.getVtepIpPoolIdentifier(subnetCidr));
+            LOG.debug("Deleted Vtep IP Pool with key:{}", subnetCidr);
+        }
+    }
+
+    /**
+     * Gets the an available ip.
+     *
+     * @param availableIps
+     *
+     * @return the an available ip
+     */
+    private IpAddress getAnAvailableIP(List<IpAddress> availableIps) {
+        // TODO: Sort IP Addresses, get the least value
+        IpAddress ipAddress = null;
+        if (availableIps != null && !availableIps.isEmpty()) {
+            ipAddress = availableIps.remove(0);
+        }
+        return ipAddress;
+    }
+
+    /**
+     * Allocate ip addresses.
+     *
+     * @param allocatedIps
+     *            the allocated ips
+     * @param vtepIpPool
+     *            the vtep ip pool
+     * @param subnetCidr
+     *            the subnet cidr
+     */
+    private void allocateIpAddresses(List<IpAddress> allocatedIps, VtepIpPool vtepIpPool, String subnetCidr) {
+        if (allocatedIps != null && !allocatedIps.isEmpty() && vtepIpPool != null) {
+            // Remove from the available IP address list and add to allocated IP
+            // address list.
+            VtepIpPoolBuilder builder = new VtepIpPoolBuilder(vtepIpPool);
+            if (builder.getAvailableIpaddress() != null) {
+                builder.getAvailableIpaddress().removeAll(allocatedIps);
+            }
+            if (builder.getAllocatedIpaddress() == null) {
+                builder.setAllocatedIpaddress(allocatedIps);
+            } else {
+                builder.getAllocatedIpaddress().addAll(allocatedIps);
+            }
+
+            MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    ItmUtils.getVtepIpPoolIdentifier(subnetCidr), builder.build());
+        }
+    }
+
+    /**
+     * De-allocate ip addresses.
+     *
+     * @param freeIps
+     *            the free ips
+     * @param subnetCidr
+     *            the subnet cidr
+     */
+    private void deAllocateIpAddresses(List<IpAddress> freeIps, String subnetCidr) {
+        VtepIpPool vtepIpPool = getVtepIpPool(subnetCidr);
+        if (freeIps != null && !freeIps.isEmpty() && vtepIpPool != null) {
+            // Remove from the allocated IP address list and add to available IP
+            // address list.
+            VtepIpPoolBuilder builder = new VtepIpPoolBuilder(vtepIpPool);
+            if (builder.getAllocatedIpaddress() != null) {
+                builder.getAllocatedIpaddress().removeAll(freeIps);
+            }
+            if (builder.getAvailableIpaddress() == null) {
+                builder.setAvailableIpaddress(freeIps);
+            } else {
+                builder.getAvailableIpaddress().addAll(freeIps);
+            }
+
+            MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    ItmUtils.getVtepIpPoolIdentifier(subnetCidr), builder.build());
+            LOG.debug("Vtep IP Pool with key:{} updated to config DS", subnetCidr);
+        }
+    }
+
+    /**
+     * Calculate available ips.
+     *
+     * @param subnetCidr
+     *            the subnet cidr
+     * @param excludeIpFilter
+     *            the exclude ip filter
+     * @param gatewayIp
+     *            the gateway IP
+     * @return the list
+     */
+    private List<IpAddress> calculateAvailableIps(SubnetUtils subnetUtils, String excludeIpFilter,
+            IpAddress gatewayIp) {
+        List<IpAddress> lstAvailableIps = new ArrayList<>();
+        SubnetInfo subnetInfo = subnetUtils.getInfo();
+        String[] arrIpAddresses = subnetInfo.getAllAddresses();
+
+        for (String ipAddress : arrIpAddresses) {
+            lstAvailableIps.add(new IpAddress(ipAddress.toCharArray()));
+        }
+        lstAvailableIps.remove(gatewayIp);
+        lstAvailableIps.removeAll(ItmUtils.getExcludeIpAddresses(excludeIpFilter, subnetInfo));
+
+        return lstAvailableIps;
+    }
+}
index 32b4f2a580c114cf1197e7c78d3a81156f6b2e46..a373472b56bbf8f4d98fb977413b0cc68760c6e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015, 2016 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,
@@ -12,20 +12,28 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Future;
 
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.vpnservice.mdsalutil.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZoneKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.SubnetsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.DeviceVteps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.DeviceVtepsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.DeviceVtepsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.vpnservice.itm.confighelpers.ItmExternalTunnelAddWorker;
 import org.opendaylight.vpnservice.itm.confighelpers.ItmExternalTunnelDeleteWorker;
 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.vpnservice.itm.impl.ItmUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.ExternalTunnelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.TunnelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.DPNTEPsInfo;
@@ -34,85 +42,68 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnelKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnelKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.AddExternalTunnelEndpointInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.BuildExternalTunnelFromDpnsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.CreateTerminatingServiceActionsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetInternalOrExternalInterfaceNameInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetInternalOrExternalInterfaceNameOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetInternalOrExternalInterfaceNameOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.RemoveExternalTunnelEndpointInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.RemoveExternalTunnelFromDpnsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.RemoveTerminatingServiceActionsInput;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 
 import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
 
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 
 public class ItmManagerRpcService implements ItmRpcService {
 
-   private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
-        DataBroker dataBroker;
-        private IMdsalApiManager mdsalManager;
+    private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
+    DataBroker dataBroker;
+    private IMdsalApiManager mdsalManager;
 
 
     public void setMdsalManager(IMdsalApiManager mdsalManager) {
-            this.mdsalManager = mdsalManager;
+        this.mdsalManager = mdsalManager;
+    }
+
+    IdManagerService idManagerService;
+
+    public ItmManagerRpcService(DataBroker dataBroker, IdManagerService idManagerService) {
+        this.dataBroker = dataBroker;
+        this.idManagerService = idManagerService;
     }
 
-        IdManagerService idManagerService;
+    @Override
+    public Future<RpcResult<GetTunnelInterfaceNameOutput>> getTunnelInterfaceName(GetTunnelInterfaceNameInput input) {
+        RpcResultBuilder<GetTunnelInterfaceNameOutput> resultBld = null;
+        BigInteger sourceDpn = input.getSourceDpid() ;
+        BigInteger destinationDpn = input.getDestinationDpid() ;
+        InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
+                TunnelList.class)
+                .child(InternalTunnel.class, new InternalTunnelKey( destinationDpn,sourceDpn));
+
+        Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
 
-        public ItmManagerRpcService(DataBroker dataBroker, IdManagerService idManagerService) {
-          this.dataBroker = dataBroker;
-          this.idManagerService = idManagerService;
+        if( tnl != null && tnl.isPresent())
+        {
+            InternalTunnel tunnel = tnl.get();
+            GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
+            output.setInterfaceName(tunnel.getTunnelInterfaceName()) ;
+            resultBld = RpcResultBuilder.success();
+            resultBld.withResult(output.build()) ;
+        }else {
+            resultBld = RpcResultBuilder.failed();
         }
 
-     @Override
-     public Future<RpcResult<GetTunnelInterfaceNameOutput>> getTunnelInterfaceName(GetTunnelInterfaceNameInput input) {
-         RpcResultBuilder<GetTunnelInterfaceNameOutput> resultBld = null;
-         BigInteger sourceDpn = input.getSourceDpid() ;
-         BigInteger destinationDpn = input.getDestinationDpid() ;
-         InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
-                 TunnelList.class)
-                     .child(InternalTunnel.class, new InternalTunnelKey(sourceDpn,destinationDpn));
-
-         Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
-
-         if( tnl != null && tnl.isPresent())
-         {
-              InternalTunnel tunnel = tnl.get();
-              GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
-              output.setInterfaceName(tunnel.getTunnelInterfaceName()) ;
-              resultBld = RpcResultBuilder.success();
-              resultBld.withResult(output.build()) ;
-         }else {
-             resultBld = RpcResultBuilder.failed();
-         }
-         
-         return Futures.immediateFuture(resultBld.build());
-     }
+        return Futures.immediateFuture(resultBld.build());
+    }
 
 
     @Override
     public Future<RpcResult<Void>> removeExternalTunnelEndpoint(
             RemoveExternalTunnelEndpointInput input) {
-         //Ignore the Futures for now
+        //Ignore the Futures for now
         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
         List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
         ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService,meshedDpnList , input.getDestinationIp(), input.getTunnelType());
@@ -175,21 +166,21 @@ public class ItmManagerRpcService implements ItmRpcService {
             GetExternalTunnelInterfaceNameInput input) {
         final SettableFuture<RpcResult<GetExternalTunnelInterfaceNameOutput>> result = SettableFuture.create() ;
         RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
-        BigInteger sourceDpn = input.getSourceDpid() ;
-        IpAddress destinationIp = input.getDestinationIp() ;
+        String sourceNode = input.getSourceNode();
+        String dstNode = input.getDestinationNode();
         InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
                 ExternalTunnelList.class)
-                    .child(ExternalTunnel.class, new ExternalTunnelKey(destinationIp, sourceDpn));
+                .child(ExternalTunnel.class, new ExternalTunnelKey(dstNode, sourceNode));
 
         Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
 
         if( ext != null && ext.isPresent())
         {
-             ExternalTunnel exTunnel = ext.get();
-             GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
-             output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
-             resultBld = RpcResultBuilder.success();
-             resultBld.withResult(output.build()) ;
+            ExternalTunnel exTunnel = ext.get();
+            GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
+            output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
+            resultBld = RpcResultBuilder.success();
+            resultBld.withResult(output.build()) ;
         }else {
             resultBld = RpcResultBuilder.failed();
         }
@@ -199,46 +190,46 @@ public class ItmManagerRpcService implements ItmRpcService {
 
     @Override
     public Future<RpcResult<java.lang.Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
-       LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction());
-       final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
-       int serviceId = input.getServiceId() ;
-       List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
-       byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-    // Flags Byte
-       byte Flags = (byte) 0x08;
-       vxLANHeader[0] = Flags;
-
-       // Extract the serviceId details and imprint on the VxLAN Header
-       vxLANHeader[4] = (byte) (serviceId >> 16);
-       vxLANHeader[5] = (byte) (serviceId >> 8);
-       vxLANHeader[6] = (byte) (serviceId >> 0);
-
-       // Matching metadata
-       mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
-                               new BigInteger(1, vxLANHeader),
-                               MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
-
-       Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
-                       getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId),
-                       0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
-
-       ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
-       Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
-
-           @Override
-           public void onSuccess(Void aVoid) {
-               result.set(RpcResultBuilder.<Void>success().build());
-           }
-
-           @Override
-           public void onFailure(Throwable error) {
-               String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
-               LOG.error("create terminating service actions failed. {}. {}", msg, error);
-               result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
-           }
-       });
-       result.set(RpcResultBuilder.<Void>success().build());
-       return result;
+        LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction());
+        final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+        int serviceId = input.getServiceId() ;
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+        // Flags Byte
+        byte Flags = (byte) 0x08;
+        vxLANHeader[0] = Flags;
+
+        // Extract the serviceId details and imprint on the VxLAN Header
+        vxLANHeader[4] = (byte) (serviceId >> 16);
+        vxLANHeader[5] = (byte) (serviceId >> 8);
+        vxLANHeader[6] = (byte) (serviceId >> 0);
+
+        // Matching metadata
+        mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
+                new BigInteger(1, vxLANHeader),
+                MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
+
+        Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
+                getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId),
+                0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
+
+        ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
+        Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
+
+            @Override
+            public void onSuccess(Void aVoid) {
+                result.set(RpcResultBuilder.<Void>success().build());
+            }
+
+            @Override
+            public void onFailure(Throwable error) {
+                String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
+                LOG.error("create terminating service actions failed. {}. {}", msg, error);
+                result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+            }
+        });
+       // result.set(RpcResultBuilder.<Void>success().build());
+        return result;
     }
 
     @Override
@@ -264,11 +255,12 @@ public class ItmManagerRpcService implements ItmRpcService {
                 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
             }
         });
-        result.set(RpcResultBuilder.<Void>success().build());
+        //result.set(RpcResultBuilder.<Void>success().build());
 
-       return result ;
+        return result ;
     }
 
+
     public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
         byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -284,7 +276,7 @@ public class ItmManagerRpcService implements ItmRpcService {
 
         // Matching metadata
         mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[]{
-        BigInteger.valueOf(serviceId)}));
+                BigInteger.valueOf(serviceId)}));
 
         return mkMatches;
     }
@@ -295,49 +287,161 @@ public class ItmManagerRpcService implements ItmRpcService {
 
     @Override
     public Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
-       GetInternalOrExternalInterfaceNameInput input) {
-       RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = RpcResultBuilder.failed();
-       BigInteger srcDpn = input.getSourceDpid() ;
-       IpAddress dstIp = input.getDestinationIp() ;
-      InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(
-          ExternalTunnelList.class)
-          .child(ExternalTunnel.class, new ExternalTunnelKey(dstIp, srcDpn));
-
-      Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
-
-      if( ext != null && ext.isPresent())
-      {
-        ExternalTunnel extTunnel = ext.get();
-        GetInternalOrExternalInterfaceNameOutputBuilder output = new GetInternalOrExternalInterfaceNameOutputBuilder().setInterfaceName(extTunnel.getTunnelInterfaceName() );
-        resultBld = RpcResultBuilder.success();
-        resultBld.withResult(output.build()) ;
-      } else {
-        List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
-        // Look for external tunnels if not look for internal tunnel
-        for (DPNTEPsInfo teps : meshedDpnList) {
-          TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
-          if (dstIp.equals(firstEndPt.getIpAddress())) {
-            InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
-                TunnelList.class)
-                .child(InternalTunnel.class, new InternalTunnelKey(srcDpn, teps.getDPNID()));
-
-            Optional<InternalTunnel>
-                tnl =
-                ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
-            if (tnl != null && tnl.isPresent()) {
-              InternalTunnel tunnel = tnl.get();
-              GetInternalOrExternalInterfaceNameOutputBuilder
-                  output =
-                  new GetInternalOrExternalInterfaceNameOutputBuilder()
-                      .setInterfaceName(tunnel.getTunnelInterfaceName());
-              resultBld = RpcResultBuilder.success();
-              resultBld.withResult(output.build());
-              break;
+            GetInternalOrExternalInterfaceNameInput input) {
+        RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = RpcResultBuilder.failed();
+        BigInteger srcDpn = input.getSourceDpid() ;
+        String srcNode = srcDpn.toString();
+        IpAddress dstIp = input.getDestinationIp() ;
+        InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(
+                ExternalTunnelList.class)
+                .child(ExternalTunnel.class, new ExternalTunnelKey(String.valueOf(dstIp), srcDpn.toString()));
+
+        Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
+
+        if( ext != null && ext.isPresent())
+        {
+            ExternalTunnel extTunnel = ext.get();
+            GetInternalOrExternalInterfaceNameOutputBuilder output = new GetInternalOrExternalInterfaceNameOutputBuilder().setInterfaceName(extTunnel.getTunnelInterfaceName() );
+            resultBld = RpcResultBuilder.success();
+            resultBld.withResult(output.build()) ;
+        } else {
+            List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
+            // Look for external tunnels if not look for internal tunnel
+            for (DPNTEPsInfo teps : meshedDpnList) {
+                TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
+                if (dstIp.equals(firstEndPt.getIpAddress())) {
+                    InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
+                            TunnelList.class)
+                            .child(InternalTunnel.class, new InternalTunnelKey(teps.getDPNID(),srcDpn));
+
+                    Optional<InternalTunnel>
+                            tnl =
+                            ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
+                    if (tnl != null && tnl.isPresent()) {
+                        InternalTunnel tunnel = tnl.get();
+                        GetInternalOrExternalInterfaceNameOutputBuilder
+                                output =
+                                new GetInternalOrExternalInterfaceNameOutputBuilder()
+                                        .setInterfaceName(tunnel.getTunnelInterfaceName());
+                        resultBld = RpcResultBuilder.success();
+                        resultBld.withResult(output.build());
+                        break;
+                    }
+                }
+            }
+        }
+        return Futures.immediateFuture(resultBld.build());
+    }
+
+    @Override
+    public Future<RpcResult<java.lang.Void>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
+        final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+        try {
+            final IpAddress hwIp = input.getIpAddress();
+            final String node_id = input.getNodeId();
+            InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
+            Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
+            if (tZonesOptional.isPresent()) {
+                TransportZones tZones = tZonesOptional.get();
+                if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
+                    LOG.error("No teps configured");
+                    result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
+                    return result;
+                }
+                String transportZone = tZones.getTransportZone().get(0).getZoneName();
+                if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
+                    result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
+                    return result;
+                }
+                SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
+                DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
+                InstanceIdentifier<DeviceVteps> path =
+                                InstanceIdentifier.builder(TransportZones.class)
+                                                .child(TransportZone.class, new TransportZoneKey(transportZone))
+                                                .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build();
+                WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+                //TO DO: add retry if it fails
+                t.delete(LogicalDatastoreType.CONFIGURATION, path);
+
+                ListenableFuture<Void> futureCheck = t.submit();
+                Futures.addCallback(futureCheck, new FutureCallback<Void>() {
+
+                    @Override
+                    public void onSuccess(Void aVoid) {
+                        result.set(RpcResultBuilder.<Void>success().build());
+                    }
+
+                    @Override
+                    public void onFailure(Throwable error) {
+                        String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
+                        LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
+                        result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+                    }
+                });
+            }
+            return result;
+        } catch (Exception e) {
+            RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
+                            withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
+            return Futures.immediateFuture(resultBuilder.build());
+        }
+    }
+
+    @Override
+    public Future<RpcResult<java.lang.Void>> addL2GwDevice(AddL2GwDeviceInput input) {
+
+        final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+        try {
+            final IpAddress hwIp = input.getIpAddress();
+            final String node_id = input.getNodeId();
+            InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
+            Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
+            if (tZonesOptional.isPresent()) {
+                TransportZones tZones = tZonesOptional.get();
+                if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
+                    LOG.error("No teps configured");
+                    result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
+                    return result;
+                }
+                String transportZone = tZones.getTransportZone().get(0).getZoneName();
+                if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
+                    result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
+                    return result;
+                }
+                SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
+                DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
+                InstanceIdentifier<DeviceVteps> path =
+                        InstanceIdentifier.builder(TransportZones.class)
+                                .child(TransportZone.class, new TransportZoneKey(transportZone))
+                                .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build();
+                DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp).setNodeId(
+                                node_id).setTopologyId(input.getTopologyId()).build();
+                WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+                //TO DO: add retry if it fails
+                t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
+
+                ListenableFuture<Void> futureCheck = t.submit();
+                Futures.addCallback(futureCheck, new FutureCallback<Void>() {
+
+                    @Override
+                    public void onSuccess(Void aVoid) {
+                        result.set(RpcResultBuilder.<Void>success().build());
+                    }
+
+                    @Override
+                    public void onFailure(Throwable error) {
+                        String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
+                        LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
+                        result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+                    }
+                });
             }
-          }
+            return result;
+        } catch (Exception e) {
+            RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
+                    withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
+            return Futures.immediateFuture(resultBuilder.build());
         }
-      }
-       return Futures.immediateFuture(resultBld.build());
     }
 
 }
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/snd/ITMStatusMonitor.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/snd/ITMStatusMonitor.java
new file mode 100644 (file)
index 0000000..03a4b87
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 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.itm.snd;
+
+import java.lang.management.ManagementFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ITMStatusMonitor implements ITMStatusMonitorMBean {
+
+
+    private String serviceStatus;
+    private static ITMStatusMonitor itmStatusMonitor = new ITMStatusMonitor();
+    private static final String JMX_ITM_OBJ_NAME = "com.ericsson.sdncp.services.status:type=SvcItmService";
+    private static final Logger log = LoggerFactory.getLogger(ITMStatusMonitor.class);
+
+    private ITMStatusMonitor () {
+    }
+
+    public void registerMbean() {
+        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+        try {
+            ObjectName objName = new ObjectName(JMX_ITM_OBJ_NAME);
+            mbs.registerMBean(itmStatusMonitor, objName);
+            log.info("itm MXBean registration SUCCESSFUL!!! {}", JMX_ITM_OBJ_NAME);
+        } catch (InstanceAlreadyExistsException iaeEx) {
+            log.error("itm MXBean registration FAILED with InstanceAlreadyExistsException", iaeEx);
+        } catch (MBeanRegistrationException mbrEx) {
+            log.error("itm MXBean registration FAILED with MBeanRegistrationException", mbrEx);
+        } catch (NotCompliantMBeanException ncmbEx) {
+            log.error("itm MXBean registration FAILED with NotCompliantMBeanException", ncmbEx);
+        } catch (MalformedObjectNameException monEx) {
+            log.error("itm MXBean registration failed with MalformedObjectNameException", monEx);
+        }
+    }
+
+    public static ITMStatusMonitor getInstance() {
+        return itmStatusMonitor;
+    }
+
+    @Override
+    public String acquireServiceStatus() {
+        return serviceStatus;
+    }
+
+    public void reportStatus (String serviceStatus) {
+        this.serviceStatus = serviceStatus;
+    }
+
+
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/snd/ITMStatusMonitorMBean.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/snd/ITMStatusMonitorMBean.java
new file mode 100644 (file)
index 0000000..e1557af
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2016 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.itm.snd;
+
+public interface ITMStatusMonitorMBean {
+
+    public String acquireServiceStatus();
+
+}
index d3f560fdb008aad1a04047c23a536be40d70808f..f42e3e9ae05010a01bfb873dd12eab4a63031b93 100644 (file)
             <artifactId>openflowjava-extension-nicira</artifactId>
             <version>${openflowplugin.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.ovsdb</groupId>
+            <artifactId>hwvtepsouthbound-api</artifactId>
+            <version>${vpns.ovsdb.version}</version>
+        </dependency>
 
     </dependencies>
 </project>
index 8678917f33ccf028dc1cd95b71f4413a5805379d..985806a1fb934c85ef3411c74a183ea4efc1c3d8 100755 (executable)
@@ -47,6 +47,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
@@ -263,7 +264,7 @@ public enum ActionType {
         }
 
     },
-    set_destination_port_field {
+    set_udp_destination_port {
 
         @Override
         public Action buildAction(ActionInfo actionInfo) {
@@ -280,7 +281,7 @@ public enum ActionType {
         }
 
     },
-    set_source_port_field {
+    set_udp_source_port {
 
         @Override
         public Action buildAction(ActionInfo actionInfo) {
@@ -296,6 +297,40 @@ public enum ActionType {
 
         }
 
+    },
+    set_tcp_destination_port {
+
+        @Override
+        public Action buildAction(ActionInfo actionInfo) {
+            String[] actionValues = actionInfo.getActionValues();
+            Integer portNumber = new Integer(actionValues[0]);
+
+            return new ActionBuilder().setAction(
+                    new SetFieldCaseBuilder().setSetField(
+                            new SetFieldBuilder().setLayer4Match(
+                                    new TcpMatchBuilder().setTcpDestinationPort(
+                                            new PortNumber(portNumber)).build())
+                            .build()).build()).setKey(new ActionKey(actionInfo.getActionKey())).build();
+
+        }
+
+    },
+    set_tcp_source_port {
+
+        @Override
+        public Action buildAction(ActionInfo actionInfo) {
+            String[] actionValues = actionInfo.getActionValues();
+            Integer portNumber = new Integer(actionValues[0]);
+
+            return new ActionBuilder().setAction(
+                    new SetFieldCaseBuilder().setSetField(
+                            new SetFieldBuilder().setLayer4Match(
+                                    new TcpMatchBuilder().setTcpSourcePort(
+                                            new PortNumber(portNumber)).build())
+                            .build()).build()).setKey(new ActionKey(actionInfo.getActionKey())).build();
+
+        }
+
     },
     set_source_ip {
 
@@ -312,7 +347,7 @@ public enum ActionType {
                     new SetFieldCaseBuilder().setSetField(
                             new SetFieldBuilder().setLayer3Match(
                                     new Ipv4MatchBuilder().setIpv4Source(
-                                            new Ipv4Prefix(sourceIp.getHostAddress())).build()).
+                                            new Ipv4Prefix(sourceIp.getHostAddress() + "/" + actionValues[1])).build()).
                                             build()).build()).setKey(new ActionKey(actionInfo.getActionKey())).build();
 
         }
@@ -333,7 +368,7 @@ public enum ActionType {
                     new SetFieldCaseBuilder().setSetField(
                             new SetFieldBuilder().setLayer3Match(
                                     new Ipv4MatchBuilder().setIpv4Destination(
-                                            new Ipv4Prefix(sourceIp.getHostAddress())).build()).
+                                            new Ipv4Prefix(sourceIp.getHostAddress() + "/" + actionValues[1])).build()).
                                             build()).build()).setKey(new ActionKey(actionInfo.getActionKey())).build();
 
         }
index f31a9675ad23a9475e644f476f743b7a7519065a..a6e469d44913374b90a7e29f04d892248f4fec73 100644 (file)
@@ -22,7 +22,9 @@ 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.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
@@ -39,10 +41,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.M
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.actions._case.WriteActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.actions._case.WriteActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
@@ -67,21 +73,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.No
 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.model.match.types.rev131026.match.TunnelBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder;
 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.binding.DataObject;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.controller.liblldp.HexEncode;
+
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
 import com.google.common.primitives.Bytes;
@@ -90,6 +94,8 @@ import com.google.common.util.concurrent.CheckedFuture;
 
 public class MDSALUtil {
 
+    public enum MdsalOp {  CREATION_OP, UPDATE_OP, REMOVAL_OP };
+
     public static final String NODE_PREFIX = "openflow";
     public static final int GROUP_WEIGHT = 0;
     public static final long WATCH_PORT = 0xffffffffL;
@@ -138,6 +144,10 @@ public class MDSALUtil {
                 .setCookie(new FlowCookie(cookie)).build();
     }
 
+    public static Flow buildFlow(short tableId, String flowId) {
+        return new FlowBuilder().setTableId(tableId).setId(new FlowId(flowId)).build();
+    }
+
     public static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
                                  int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo, List<Instruction> listInstructionInfo) {
         return MDSALUtil.buildFlowNew(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie,
@@ -195,6 +205,13 @@ public class MDSALUtil {
                 .setIngress(ingress).setEgress(ingress).build();
     }
 
+    public static Action retrieveSetTunnelIdAction(BigInteger tunnelId, int actionKey) {
+        return new ActionBuilder().setAction(
+                new SetFieldCaseBuilder().setSetField(new SetFieldBuilder().setTunnel(new TunnelBuilder()
+                .setTunnelId(tunnelId).build()).build())
+                .build()).setKey(new ActionKey(actionKey)).build();
+    }
+
     public static List<Action> buildActions(List<ActionInfo> actions) {
         List<Action> actionsList = new ArrayList<Action>();
         for (ActionInfo actionInfo : actions) {
@@ -251,7 +268,7 @@ public class MDSALUtil {
         return EMPTY_Buckets;
     }
 
-    protected static Instructions buildInstructions(List<InstructionInfo> listInstructionInfo) {
+    public static Instructions buildInstructions(List<InstructionInfo> listInstructionInfo) {
         if (listInstructionInfo != null) {
             List<Instruction> instructions = new ArrayList<Instruction>();
             int instructionKey = 0;
@@ -345,7 +362,7 @@ public class MDSALUtil {
 
     public static long getDpnIdFromPortName(NodeConnectorId nodeConnectorId) {
         String ofPortName = nodeConnectorId.getValue();
-        return Long.parseLong(ofPortName.substring(ofPortName.indexOf(":")+1, 
+        return Long.parseLong(ofPortName.substring(ofPortName.indexOf(":")+1,
                 ofPortName.lastIndexOf(":")));
     }
 
@@ -366,6 +383,14 @@ public class MDSALUtil {
                 .setKey(new ActionKey(actionKey)).build();
         List<Action> listAction = new ArrayList<Action> ();
         listAction.add(popVlanAction);
+        return buildApplyActionsInstruction(listAction, instructionKey);
+    }
+
+    public static Instruction buildApplyActionsInstruction(List<Action> actions) {
+        return buildApplyActionsInstruction(actions, 0);
+    }
+
+    public static Instruction buildApplyActionsInstruction(List<Action> listAction, int instructionKey) {
         ApplyActions applyActions = new ApplyActionsBuilder().setAction(listAction).build();
         ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();
         InstructionBuilder instructionBuilder = new InstructionBuilder();
@@ -375,6 +400,29 @@ public class MDSALUtil {
         return instructionBuilder.build();
     }
 
+    public static List<Instruction> buildInstructionsDrop() {
+        return buildInstructionsDrop(0);
+    }
+
+    public static List<Instruction> buildInstructionsDrop(int instructionKey) {
+        List<Instruction> mkInstructions = new ArrayList<Instruction>();
+        List <Action> actionsInfos = new ArrayList <Action> ();
+        actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}).buildAction());
+        mkInstructions.add(getWriteActionsInstruction(actionsInfos, instructionKey));
+        return mkInstructions;
+    }
+
+
+    public static Instruction getWriteActionsInstruction(List<Action> listAction, int instructionKey) {
+        WriteActions writeActions = new WriteActionsBuilder().setAction(listAction).build();
+        WriteActionsCase writeActionsCase = new WriteActionsCaseBuilder().setWriteActions(writeActions).build();
+        InstructionBuilder instructionBuilder = new InstructionBuilder();
+
+        instructionBuilder.setInstruction(writeActionsCase);
+        instructionBuilder.setKey(new InstructionKey(instructionKey));
+        return instructionBuilder.build();
+    }
+
     public static Action buildAction(int actionKey, int instruction) {
         return new ActionBuilder().setAction(
                 new PopVlanActionCaseBuilder().setPopVlanAction(new PopVlanActionBuilder().build()).build())
@@ -529,3 +577,4 @@ public class MDSALUtil {
     }
 
 }
+
index 7e4cfa290a0f8ebce907ede79a2480d75ef22f2f..24cdb3da6bf73ed95955b914d1cfa2b9f4cdadd7 100755 (executable)
@@ -251,6 +251,64 @@ public enum MatchFieldType {
             }
         }
     },
+    
+    ipv4_destination {
+        @Override
+        protected Class<? extends MatchField> getMatchType() {
+            return Ipv4Dst.class;
+        }
+
+        @Override
+        public void createInnerMatchBuilder(MatchInfo matchInfo, Map<Class<?>, Object> mapMatchBuilder) {
+            Ipv4MatchBuilder ipv4MatchBuilder = (Ipv4MatchBuilder) mapMatchBuilder.get(Ipv4MatchBuilder.class);
+
+            if (ipv4MatchBuilder == null) {
+                ipv4MatchBuilder = new Ipv4MatchBuilder();
+                mapMatchBuilder.put(Ipv4MatchBuilder.class, ipv4MatchBuilder);
+            }
+
+            String[] prefix = matchInfo.getStringMatchValues();
+            ipv4MatchBuilder.setIpv4Destination(new Ipv4Prefix(prefix[0] + "/" + prefix[1])).build();
+        }
+
+        @Override
+        public void setMatch(MatchBuilder matchBuilderInOut, MatchInfo matchInfo, Map<Class<?>, Object> mapMatchBuilder) {
+            Ipv4MatchBuilder ipv4MatchBuilder = (Ipv4MatchBuilder) mapMatchBuilder.remove(Ipv4MatchBuilder.class);
+
+            if (ipv4MatchBuilder != null) {
+                matchBuilderInOut.setLayer3Match(ipv4MatchBuilder.build());
+            }
+        }
+    },
+
+    ipv4_source {
+        @Override
+        protected Class<? extends MatchField> getMatchType() {
+            return Ipv4Src.class;
+        }
+
+        @Override
+        public void createInnerMatchBuilder(MatchInfo matchInfo, Map<Class<?>, Object> mapMatchBuilder) {
+            Ipv4MatchBuilder ipv4MatchBuilder = (Ipv4MatchBuilder) mapMatchBuilder.get(Ipv4MatchBuilder.class);
+
+            if (ipv4MatchBuilder == null) {
+                ipv4MatchBuilder = new Ipv4MatchBuilder();
+                mapMatchBuilder.put(Ipv4MatchBuilder.class, ipv4MatchBuilder);
+            }
+
+            String[] prefix = matchInfo.getStringMatchValues();
+            ipv4MatchBuilder.setIpv4Source(new Ipv4Prefix(prefix[0] + "/" + prefix[1])).build();
+        }
+
+        @Override
+        public void setMatch(MatchBuilder matchBuilderInOut, MatchInfo matchInfo, Map<Class<?>, Object> mapMatchBuilder) {
+            Ipv4MatchBuilder ipv4MatchBuilder = (Ipv4MatchBuilder) mapMatchBuilder.remove(Ipv4MatchBuilder.class);
+
+            if (ipv4MatchBuilder != null) {
+                matchBuilderInOut.setLayer3Match(ipv4MatchBuilder.build());
+            }
+        }
+    },
 
     arp_op {
         @Override
index 568ad4f457483ccb5486ef2ba93fc1e0c756df32..06f794bd032fd323624e2b83784b28d9cb1566fd 100644 (file)
@@ -10,14 +10,16 @@ package org.opendaylight.vpnservice.mdsalutil;
 import java.math.BigInteger;
 
 public class MetaDataUtil {
-    public static final BigInteger METADATA_MASK_VRFID = new BigInteger("00000000FFFFFFFF", 16);
-    public static final BigInteger METADATA_MASK_LPORT_TAG = new BigInteger("1FFFFF0000000000", 16);
-    public static final BigInteger METADATA_MASK_SERVICE = new BigInteger("000000FFFF000000", 16);
+    public static final BigInteger METADATA_MASK_VRFID =         new BigInteger("00000000FFFFFFFF", 16);
+    public static final BigInteger METADATA_MASK_LPORT_TAG =     new BigInteger("1FFFFF0000000000", 16);
+    public static final BigInteger METADATA_MASK_SERVICE =       new BigInteger("000000FFFF000000", 16);
     public static final BigInteger METADATA_MASK_SERVICE_INDEX = new BigInteger("E000000000000000", 16);
-    public static final BigInteger METADATA_MASK_LPORT_WRITE = new BigInteger("00FFFF0000000000", 16);
+    public static final BigInteger METADATA_MASK_LPORT_WRITE =   new BigInteger("00FFFF0000000000", 16);
     public static final BigInteger METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID = new BigInteger("08000000FFFFFF00", 16);
-    public static final BigInteger METADATA_MASK_LABEL_ITM = new BigInteger("40FFFFFF000000FF", 16);
-    public static final BigInteger METADA_MASK_TUNNEL_ID = new BigInteger("00000000FFFFFF00", 16);
+    public static final BigInteger METADATA_MASK_LABEL_ITM =     new BigInteger("40FFFFFF000000FF", 16);
+    public static final BigInteger METADA_MASK_TUNNEL_ID =       new BigInteger("00000000FFFFFF00", 16);
+    public static final BigInteger METADATA_MASK_SERVICE_SH_FLAG = new BigInteger("000000FFFF000001", 16);
+    public static final BigInteger METADATA_MASK_LPORT_TAG_SH_FLAG =     new BigInteger("1FFFFF0000000001", 16);
 
     public static BigInteger getMetaDataForLPortDispatcher(int lportTag, short serviceIndex) {
         return getServiceIndexMetaData(serviceIndex).or(getLportTagMetaData(lportTag));
@@ -66,4 +68,8 @@ public class MetaDataUtil {
     public static BigInteger getTunnelIdWithValidVniBitAndVniSet(int vni) {
         return BigInteger.valueOf(0X08).shiftLeft(56).or(BigInteger.valueOf(vni).shiftLeft(8));
     }
+
+    public static long getNatRouterIdFromMetadata(BigInteger metadata){
+        return (metadata.and(METADATA_MASK_VRFID)).longValue();
+    }
 }
index 9133de482765b11ce3d102684e48765b17eb2dbb..55472e297497c3d236e7e88c22a0c22fe85828e6 100644 (file)
@@ -16,7 +16,7 @@ public class NwConstants {
 
     public static final int ETHTYPE_MPLS_UC           = 0X8847;
     public static final int ETHTYPE_PBB               = 0X88E7;
-    
+
     //Protocol Type
     public static final int IP_PROT_UDP = 17;
     public static final int IP_PROT_GRE = 47;
@@ -28,7 +28,7 @@ public class NwConstants {
     //Default Port
     public static final int UDP_DEFAULT_PORT = 4789;
 
-    
+
     // Flow Actions
     public static final int ADD_FLOW = 0;
     public static final int DEL_FLOW = 1;
@@ -44,13 +44,14 @@ public class NwConstants {
     //Table IDs
     public static final short L3_FIB_TABLE = 21;
     public static final short L3_LFIB_TABLE = 20;
+    public static final short L3_SUBNET_ROUTE_TABLE=22;
 
     public static final short L3_PROTOCOL_TABLE = 36;
     public static final short L3_INTERFACE_TABLE = 80;
     public static final short LPORT_DISPATCHER_TABLE = 17;
     public static final short VLAN_INTERFACE_INGRESS_TABLE = 0;
     public static final short INTERNAL_TUNNEL_TABLE = 36;
-    public static final short EXTERNAL_TUNNEL_TABLE = 36;
+    public static final short EXTERNAL_TUNNEL_TABLE = 38;
     public static final short DHCP_TABLE = 16;
-
+    public static final short DHCP_TABLE_EXTERNAL_TUNNEL = 18;
  }
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/cache/CacheUtil.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/cache/CacheUtil.java
new file mode 100644 (file)
index 0000000..0f45a83
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 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.utils.cache;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public class CacheUtil {
+    private static final ConcurrentMap<String, ConcurrentMap<?, ?>> m_mapCache = 
+            new ConcurrentHashMap<String, ConcurrentMap<?, ?>>();
+
+    public static ConcurrentMap<?, ?> getCache(String sCacheName) {
+        return m_mapCache.get(sCacheName);
+    }
+
+    public static void createCache(String sCacheName) {
+        if (m_mapCache.get(sCacheName) == null)
+            m_mapCache.put(sCacheName, new ConcurrentHashMap<Object, Object>());
+    }
+
+    public static void destroyCache(String sCacheName) {
+        m_mapCache.remove(sCacheName);
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/clustering/ClusteringUtils.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/clustering/ClusteringUtils.java
new file mode 100644 (file)
index 0000000..ec90e2c
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 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.utils.clustering;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
+import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class ClusteringUtils {
+
+    public static boolean isNodeEntityOwner(EntityOwnershipService entityOwnershipService, String entityType,
+            String nodeId) {
+        Entity entity = new Entity(entityType, nodeId);
+        Optional<EntityOwnershipState> entityState = entityOwnershipService.getOwnershipState(entity);
+        if (entityState.isPresent()) {
+            return entityState.get().isOwner();
+        }
+        return false;
+    }
+
+    public static boolean isNodeEntityOwner(EntityOwnershipService entityOwnershipService, String entityType,
+            YangInstanceIdentifier nodeId) {
+        Entity entity = new Entity(entityType, nodeId);
+        Optional<EntityOwnershipState> entityState = entityOwnershipService.getOwnershipState(entity);
+        if (entityState.isPresent()) {
+            return entityState.get().isOwner();
+        }
+        return false;
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/hwvtep/HwvtepSouthboundConstants.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/hwvtep/HwvtepSouthboundConstants.java
new file mode 100644 (file)
index 0000000..33eecd9
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.utils.hwvtep;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeVxlanOverIpv4;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+
+import com.google.common.collect.ImmutableBiMap;
+
+// TODO (eperefr) Remove this class once it's been added to hwvtep-southbound
+public class HwvtepSouthboundConstants {
+
+    public static final TopologyId HWVTEP_TOPOLOGY_ID = new TopologyId("hwvtep:1");
+    public static final String HWVTEP_ENTITY_TYPE = "hwvtep";
+    public static final Object PSWITCH_URI_PREFIX = "physicalswitch";
+    public static final ImmutableBiMap<Class<? extends EncapsulationTypeBase>, String> ENCAPS_TYPE_MAP = new ImmutableBiMap.Builder<Class<? extends EncapsulationTypeBase>, String>()
+            .put(EncapsulationTypeVxlanOverIpv4.class, "vxlan_over_ipv4").build();
+
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/hwvtep/HwvtepSouthboundUtils.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/hwvtep/HwvtepSouthboundUtils.java
new file mode 100644 (file)
index 0000000..72bb09d
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2016 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.utils.hwvtep;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeVxlanOverIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindingsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindingsKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableBiMap;
+
+/**
+ * TODO: Move these API's to ovsdb's utils.hwvtepsouthbound-utils module.
+ */
+public class HwvtepSouthboundUtils {
+
+    /**
+     * Creates the hwvtep topology instance identifier.
+     *
+     * @return the instance identifier
+     */
+    public static InstanceIdentifier<Topology> createHwvtepTopologyInstanceIdentifier() {
+        return InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
+                new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID));
+    }
+
+    /**
+     * Creates the instance identifier.
+     *
+     * @param nodeId
+     *            the node id
+     * @return the instance identifier
+     */
+    public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
+        return InstanceIdentifier.create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
+                .child(Node.class, new NodeKey(nodeId));
+    }
+
+    /**
+     * Creates the logical switches instance identifier.
+     *
+     * @param nodeId
+     *            the node id
+     * @param hwvtepNodeName
+     *            the hwvtep node name
+     * @return the instance identifier
+     */
+    public static InstanceIdentifier<LogicalSwitches> createLogicalSwitchesInstanceIdentifier(NodeId nodeId,
+            HwvtepNodeName hwvtepNodeName) {
+        return createInstanceIdentifier(nodeId).augmentation(HwvtepGlobalAugmentation.class)
+                .child(LogicalSwitches.class, new LogicalSwitchesKey(hwvtepNodeName));
+    }
+
+    /**
+     * Creates the remote ucast macs instance identifier.
+     *
+     * @param nodeId
+     *            the node id
+     * @param mac
+     *            the mac
+     * @return the instance identifier
+     */
+    public static InstanceIdentifier<RemoteUcastMacs> createRemoteUcastMacsInstanceIdentifier(NodeId nodeId,
+            String logicalSwitchName,
+            MacAddress mac) {
+        InstanceIdentifier<LogicalSwitches> logicalSwitch = createLogicalSwitchesInstanceIdentifier(nodeId, 
+                new HwvtepNodeName(logicalSwitchName));
+        return createInstanceIdentifier(nodeId).augmentation(HwvtepGlobalAugmentation.class)
+                .child(RemoteUcastMacs.class, new RemoteUcastMacsKey(new HwvtepLogicalSwitchRef(logicalSwitch), mac));
+    }
+    
+    /**
+     * Creates the local ucast macs instance identifier.
+     *
+     * @param nodeId
+     *            the node id
+     * @param mac
+     *            the mac
+     * @return the instance identifier
+     */
+    public static InstanceIdentifier<LocalUcastMacs> createLocalUcastMacsInstanceIdentifier(NodeId nodeId,
+            String logicalSwitchName,
+            MacAddress mac) {
+        InstanceIdentifier<LogicalSwitches> logicalSwitch = createLogicalSwitchesInstanceIdentifier(nodeId, 
+                new HwvtepNodeName(logicalSwitchName));
+        return createInstanceIdentifier(nodeId).augmentation(HwvtepGlobalAugmentation.class).child(LocalUcastMacs.class,
+                new LocalUcastMacsKey(new HwvtepLogicalSwitchRef(logicalSwitch), mac));
+    }
+
+    public static InstanceIdentifier<RemoteMcastMacs> createRemoteMcastMacsInstanceIdentifier(NodeId nodeId,
+            String logicalSwitchName,
+            MacAddress mac) {
+        InstanceIdentifier<LogicalSwitches> logicalSwitch = createLogicalSwitchesInstanceIdentifier(nodeId, 
+                new HwvtepNodeName(logicalSwitchName));
+        return createInstanceIdentifier(nodeId).augmentation(HwvtepGlobalAugmentation.class).child(RemoteMcastMacs.class,
+                new RemoteMcastMacsKey(new HwvtepLogicalSwitchRef(logicalSwitch), mac));
+    }
+
+    /**
+     * Creates the remote mcast macs instance identifier.
+     *
+     * @param nodeId
+     *            the node id
+     * @param remoteMcastMacsKey
+     *            the remote mcast macs key
+     * @return the instance identifier
+     */
+    public static InstanceIdentifier<RemoteMcastMacs> createRemoteMcastMacsInstanceIdentifier(NodeId nodeId,
+            RemoteMcastMacsKey remoteMcastMacsKey) {
+        return createInstanceIdentifier(nodeId).augmentation(HwvtepGlobalAugmentation.class)
+                .child(RemoteMcastMacs.class, remoteMcastMacsKey);
+    }
+
+    /**
+     * Creates the physical locator instance identifier.
+     *
+     * @param nodeId
+     *            the node id
+     * @param physicalLocatorAug
+     *            the physical locator aug
+     * @return the instance identifier
+     */
+    public static InstanceIdentifier<TerminationPoint> createPhysicalLocatorInstanceIdentifier(NodeId nodeId,
+            HwvtepPhysicalLocatorAugmentation physicalLocatorAug) {
+        return createInstanceIdentifier(nodeId).child(TerminationPoint.class,
+                getTerminationPointKey(physicalLocatorAug));
+    }
+
+    /**
+     * Creates the physical port instance identifier.
+     *
+     * @param physicalSwitchNodeId
+     *            the physical switch node id
+     * @param phyPortName
+     *            the phy port name
+     * @return the instance identifier
+     */
+    public static InstanceIdentifier<HwvtepPhysicalPortAugmentation> createPhysicalPortInstanceIdentifier(
+            NodeId physicalSwitchNodeId, String phyPortName) {
+        return createInstanceIdentifier(physicalSwitchNodeId)
+                .child(TerminationPoint.class, new TerminationPointKey(new TpId(phyPortName)))
+                .augmentation(HwvtepPhysicalPortAugmentation.class);
+    }
+
+    /**
+     * Creates the vlan binding instance identifier.
+     *
+     * @param physicalSwitchNodeId
+     *            the physical switch node id
+     * @param phyPortName
+     *            the phy port name
+     * @param vlanId
+     *            the vlan id
+     * @return the instance identifier
+     */
+    public static InstanceIdentifier<VlanBindings> createVlanBindingInstanceIdentifier(NodeId physicalSwitchNodeId,
+            String phyPortName, Integer vlanId) {
+        return createPhysicalPortInstanceIdentifier(physicalSwitchNodeId, phyPortName).child(VlanBindings.class,
+                new VlanBindingsKey(new VlanId(vlanId)));
+    }
+
+    /**
+     * Gets the termination point key.
+     *
+     * @param phyLocator
+     *            the phy locator
+     * @return the termination point key
+     */
+    public static TerminationPointKey getTerminationPointKey(HwvtepPhysicalLocatorAugmentation phyLocator) {
+        TerminationPointKey tpKey = null;
+        if (phyLocator.getEncapsulationType() != null && phyLocator.getDstIp() != null) {
+            String encapType = HwvtepSouthboundConstants.ENCAPS_TYPE_MAP.get(phyLocator.getEncapsulationType());
+            String tpKeyStr = encapType + ":" + String.valueOf(phyLocator.getDstIp().getValue());
+            tpKey = new TerminationPointKey(new TpId(tpKeyStr));
+        }
+        return tpKey;
+    }
+
+    /**
+     * Creates the managed node id.
+     *
+     * @param nodeId
+     *            the node id
+     * @param physicalSwitchName
+     *            the physical switch name
+     * @return the node id
+     */
+    public static NodeId createManagedNodeId(NodeId nodeId, String physicalSwitchName) {
+        String phySwitchNodeId = nodeId.getValue() + "/" + HwvtepSouthboundConstants.PSWITCH_URI_PREFIX + "/"
+                + physicalSwitchName;
+        return new NodeId(phySwitchNodeId);
+    }
+
+    /**
+     * Create logical switch.
+     *
+     * @param name
+     *            the name
+     * @param desc
+     *            the desc
+     * @param tunnelKey
+     *            the tunnel key
+     * @return the logical switches
+     */
+    public static LogicalSwitches createLogicalSwitch(String name, String desc, String tunnelKey) {
+        HwvtepNodeName hwvtepName = new HwvtepNodeName(name);
+        LogicalSwitchesBuilder lsBuilder = new LogicalSwitchesBuilder().setHwvtepNodeDescription(desc)
+                .setHwvtepNodeName(hwvtepName).setKey(new LogicalSwitchesKey(hwvtepName)).setTunnelKey(tunnelKey);
+        return lsBuilder.build();
+    }
+
+    /**
+     * Create hwvtep physical locator augmentation.
+     *
+     * @param ipAddress
+     *            the ip address
+     * @return the hwvtep physical locator augmentation
+     */
+    public static HwvtepPhysicalLocatorAugmentation createHwvtepPhysicalLocatorAugmentation(String ipAddress) {
+        // FIXME: Get encapsulation type dynamically
+        Class<? extends EncapsulationTypeBase> encapTypeClass = createEncapsulationType(StringUtils.EMPTY);
+        HwvtepPhysicalLocatorAugmentationBuilder phyLocBuilder = new HwvtepPhysicalLocatorAugmentationBuilder()
+                .setEncapsulationType(encapTypeClass).setDstIp(new IpAddress(ipAddress.toCharArray()));
+        return phyLocBuilder.build();
+    }
+
+    public static Class<? extends EncapsulationTypeBase> createEncapsulationType(String type) {
+        Preconditions.checkNotNull(type);
+        if (type.isEmpty()) {
+            return EncapsulationTypeVxlanOverIpv4.class;
+        } else {
+            ImmutableBiMap<String, Class<? extends EncapsulationTypeBase>> mapper = HwvtepSouthboundConstants.ENCAPS_TYPE_MAP
+                    .inverse();
+            return mapper.get(type);
+        }
+    }
+
+    /**
+     * Create remote ucast mac.
+     *
+     * @param nodeId
+     *            the node id
+     * @param mac
+     *            the mac
+     * @param ipAddress
+     *            the ip address
+     * @param logicalSwitchName
+     *            the logical switch name
+     * @param physicalLocatorAug
+     *            the physical locator aug
+     * @return the remote ucast macs
+     */
+    public static RemoteUcastMacs createRemoteUcastMac(NodeId nodeId, String mac, IpAddress ipAddress,
+            String logicalSwitchName, HwvtepPhysicalLocatorAugmentation physicalLocatorAug) {
+        HwvtepLogicalSwitchRef lsRef = new HwvtepLogicalSwitchRef(
+                createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(logicalSwitchName)));
+        HwvtepPhysicalLocatorRef phyLocRef = new HwvtepPhysicalLocatorRef(
+                createPhysicalLocatorInstanceIdentifier(nodeId, physicalLocatorAug));
+
+        RemoteUcastMacs remoteUcastMacs = new RemoteUcastMacsBuilder().setMacEntryKey(new MacAddress(mac))
+                .setIpaddr(ipAddress).setLogicalSwitchRef(lsRef).setLocatorRef(phyLocRef).build();
+        return remoteUcastMacs;
+    }
+
+    /**
+     * Creates the remote mcast mac.
+     *
+     * @param nodeId
+     *            the node id
+     * @param mac
+     *            the mac
+     * @param ipAddress
+     *            the ip address
+     * @param logicalSwitchName
+     *            the logical switch name
+     * @param lstPhysicalLocatorAug
+     *            the lst physical locator aug
+     * @return the remote mcast macs
+     */
+    public static RemoteMcastMacs createRemoteMcastMac(NodeId nodeId, String mac, IpAddress ipAddress,
+            String logicalSwitchName, List<HwvtepPhysicalLocatorAugmentation> lstPhysicalLocatorAug) {
+        HwvtepLogicalSwitchRef lsRef = new HwvtepLogicalSwitchRef(
+                createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(logicalSwitchName)));
+
+        List<LocatorSet> lstLocatorSet = new ArrayList<>();
+        for (HwvtepPhysicalLocatorAugmentation phyLocatorAug : lstPhysicalLocatorAug) {
+            HwvtepPhysicalLocatorRef phyLocRef = new HwvtepPhysicalLocatorRef(
+                    createPhysicalLocatorInstanceIdentifier(nodeId, phyLocatorAug));
+            lstLocatorSet.add(new LocatorSetBuilder().setLocatorRef(phyLocRef).build());
+        }
+
+        RemoteMcastMacs remoteMcastMacs = new RemoteMcastMacsBuilder().setMacEntryKey(new MacAddress(mac))
+                .setIpaddr(ipAddress).setLogicalSwitchRef(lsRef).setLocatorSet(lstLocatorSet).build();
+        return remoteMcastMacs;
+    }
+
+    /**
+     * Create vlan binding.
+     *
+     * @param nodeId
+     *            the node id
+     * @param vlanId
+     *            the vlan id
+     * @param logicalSwitchName
+     *            the logical switch name
+     * @return the vlan bindings
+     */
+    public static VlanBindings createVlanBinding(NodeId nodeId, int vlanId, String logicalSwitchName) {
+        VlanBindingsBuilder vbBuilder = new VlanBindingsBuilder();
+        VlanBindingsKey vbKey = new VlanBindingsKey(new VlanId(vlanId));
+        vbBuilder.setKey(vbKey);
+        vbBuilder.setVlanIdKey(vbKey.getVlanIdKey());
+
+        final InstanceIdentifier<LogicalSwitches> lSwitchIid = createLogicalSwitchesInstanceIdentifier(nodeId,
+                new HwvtepNodeName(logicalSwitchName));
+        HwvtepLogicalSwitchRef lsRef = new HwvtepLogicalSwitchRef(lSwitchIid);
+        vbBuilder.setLogicalSwitchRef(lsRef);
+        return vbBuilder.build();
+    }
+
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/hwvtep/HwvtepUtils.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/utils/hwvtep/HwvtepUtils.java
new file mode 100644 (file)
index 0000000..f913f62
--- /dev/null
@@ -0,0 +1,556 @@
+/*
+ * Copyright (c) 2016 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.utils.hwvtep;
+
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * Utility class to related to Hardware VTEP devices.
+ */
+public final class HwvtepUtils {
+
+    // TODO: (eperefr) Move this to HwvtepSouthboundUtils when in place.
+    public static InstanceIdentifier<LocalUcastMacs> getWildCardPathForLocalUcastMacs() {
+        return InstanceIdentifier.create(NetworkTopology.class).child(Topology.class).child(Node.class)
+                .augmentation(HwvtepGlobalAugmentation.class).child(LocalUcastMacs.class);
+    }
+
+    /**
+     * Adds the logical switch into config DS.
+     *
+     * @param broker
+     *            the broker
+     * @param nodeId
+     *            the node id
+     * @param logicalSwitch
+     *            the logical switch
+     * @return the listenable future
+     */
+    public static ListenableFuture<Void> addLogicalSwitch(DataBroker broker, NodeId nodeId,
+            LogicalSwitches logicalSwitch) {
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+        putLogicalSwitch(transaction, nodeId, logicalSwitch);
+        return transaction.submit();
+    }
+
+    /**
+     * Put the logical switches in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param lstSwitches
+     *            the lst switches
+     */
+    public static void putLogicalSwitches(final WriteTransaction transaction, final NodeId nodeId,
+            final List<LogicalSwitches> lstSwitches) {
+        if (lstSwitches != null) {
+            for (LogicalSwitches logicalSwitch : lstSwitches) {
+                putLogicalSwitch(transaction, nodeId, logicalSwitch);
+            }
+        }
+    }
+
+    /**
+     * Put logical switch in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param logicalSwitch
+     *            the logical switch
+     */
+    public static void putLogicalSwitch(final WriteTransaction transaction, final NodeId nodeId,
+            final LogicalSwitches logicalSwitch) {
+        InstanceIdentifier<LogicalSwitches> iid = HwvtepSouthboundUtils.createLogicalSwitchesInstanceIdentifier(nodeId,
+                logicalSwitch.getHwvtepNodeName());
+        transaction.put(LogicalDatastoreType.CONFIGURATION, iid, logicalSwitch, true);
+    }
+
+    /**
+     * Delete logical switch from config DS.
+     *
+     * @param broker
+     *            the broker
+     * @param nodeId
+     *            the node id
+     * @param logicalSwitchName
+     *            the logical switch name
+     * @return the listenable future
+     */
+    public static ListenableFuture<Void> deleteLogicalSwitch(DataBroker broker, NodeId nodeId,
+            String logicalSwitchName) {
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+        deleteLogicalSwitch(transaction, nodeId, logicalSwitchName);
+        return transaction.submit();
+    }
+
+    /**
+     * Delete logical switch from the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param logicalSwitchName
+     *            the logical switch name
+     */
+    public static void deleteLogicalSwitch(final WriteTransaction transaction, final NodeId nodeId,
+            final String logicalSwitchName) {
+        transaction.delete(LogicalDatastoreType.CONFIGURATION, HwvtepSouthboundUtils
+                .createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(logicalSwitchName)));
+    }
+
+    /**
+     * Gets the logical switch.
+     *
+     * @param nodeId
+     *            the node id
+     * @param logicalSwitchName
+     *            the logical switch name
+     * @return the logical switch
+     */
+    public static LogicalSwitches getLogicalSwitch(DataBroker broker, LogicalDatastoreType datastoreType, NodeId nodeId,
+            String logicalSwitchName) {
+        final InstanceIdentifier<LogicalSwitches> iid = HwvtepSouthboundUtils
+                .createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(logicalSwitchName));
+        Optional<LogicalSwitches> optLogicalSwitch = MDSALUtil.read(broker, datastoreType, iid);
+        if (optLogicalSwitch.isPresent()) {
+            return optLogicalSwitch.get();
+        }
+        return null;
+    }
+
+    /**
+     * Get LogicalSwitches for a given hwVtepNodeId.
+     *
+     * @param broker
+     *            the broker
+     * @param hwVtepNodeId
+     *            Hardware VTEP Node Id
+     * @param vni
+     *            virtual network id
+     * @return the logical switches
+     */
+    public static LogicalSwitches getLogicalSwitches(DataBroker broker, String hwVtepNodeId, String vni) {
+        NodeId nodeId = new NodeId(hwVtepNodeId);
+        InstanceIdentifier<LogicalSwitches> logicalSwitchesIdentifier = HwvtepSouthboundUtils
+                .createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(vni));
+
+        Optional<LogicalSwitches> logicalSwitches = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
+                logicalSwitchesIdentifier);
+        if (!logicalSwitches.isPresent()) {
+            return null;
+        }
+
+        return logicalSwitches.get();
+    }
+
+    /**
+     * Put physical locators in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param lstPhysicalLocator
+     *            the lst physical locator
+     */
+    public static void putPhysicalLocators(WriteTransaction transaction, NodeId nodeId,
+            List<HwvtepPhysicalLocatorAugmentation> lstPhysicalLocator) {
+        if (lstPhysicalLocator != null) {
+            for (HwvtepPhysicalLocatorAugmentation phyLocator : lstPhysicalLocator) {
+                putPhysicalLocator(transaction, nodeId, phyLocator);
+            }
+        }
+    }
+
+    /**
+     * Put physical locator in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param phyLocator
+     *            the phy locator
+     */
+    public static void putPhysicalLocator(final WriteTransaction transaction, final NodeId nodeId,
+            final HwvtepPhysicalLocatorAugmentation phyLocator) {
+        InstanceIdentifier<TerminationPoint> iid = HwvtepSouthboundUtils.createPhysicalLocatorInstanceIdentifier(nodeId,
+                phyLocator);
+        TerminationPoint terminationPoint = new TerminationPointBuilder()
+                .setKey(HwvtepSouthboundUtils.getTerminationPointKey(phyLocator))
+                .addAugmentation(HwvtepPhysicalLocatorAugmentation.class, phyLocator).build();
+
+        transaction.put(LogicalDatastoreType.CONFIGURATION, iid, terminationPoint, true);
+    }
+
+    /**
+     * Adds the remote ucast macs into config DS.
+     *
+     * @param broker
+     *            the broker
+     * @param nodeId
+     *            the node id
+     * @param lstRemoteUcastMacs
+     *            the lst remote ucast macs
+     * @return the listenable future
+     */
+    public static ListenableFuture<Void> addRemoteUcastMacs(DataBroker broker, NodeId nodeId,
+            List<RemoteUcastMacs> lstRemoteUcastMacs) {
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+        putRemoteUcastMacs(transaction, nodeId, lstRemoteUcastMacs);
+        return transaction.submit();
+    }
+
+    /**
+     * Put remote ucast macs in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param lstRemoteUcastMacs
+     *            the lst remote ucast macs
+     */
+    public static void putRemoteUcastMacs(final WriteTransaction transaction, final NodeId nodeId,
+            final List<RemoteUcastMacs> lstRemoteUcastMacs) {
+        if (lstRemoteUcastMacs != null && !lstRemoteUcastMacs.isEmpty()) {
+            for (RemoteUcastMacs remoteUcastMac : lstRemoteUcastMacs) {
+                putRemoteUcastMac(transaction, nodeId, remoteUcastMac);
+            }
+        }
+    }
+
+    /**
+     * Put remote ucast mac in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param remoteUcastMac
+     *            the remote ucast mac
+     */
+    public static void putRemoteUcastMac(final WriteTransaction transaction, final NodeId nodeId,
+            RemoteUcastMacs remoteUcastMac) {
+        InstanceIdentifier<RemoteUcastMacs> iid = HwvtepSouthboundUtils.createInstanceIdentifier(nodeId).augmentation(HwvtepGlobalAugmentation.class)
+        .child(RemoteUcastMacs.class, new RemoteUcastMacsKey(remoteUcastMac.getLogicalSwitchRef(), remoteUcastMac.getMacEntryKey()));
+        transaction.put(LogicalDatastoreType.CONFIGURATION, iid, remoteUcastMac, true);
+    }
+
+    /**
+     * Delete remote ucast mac from the config DS.
+     *
+     * @param broker
+     *            the broker
+     * @param nodeId
+     *            the node id
+     * @param mac
+     *            the mac
+     * @return the listenable future
+     */
+    public static ListenableFuture<Void> deleteRemoteUcastMac(DataBroker broker, NodeId nodeId,
+            String logicalSwitchName, MacAddress mac) {
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+        deleteRemoteUcastMac(transaction, nodeId, logicalSwitchName, mac);
+        return transaction.submit();
+    }
+
+    /**
+     * Delete remote ucast macs from the config DS.
+     *
+     * @param broker
+     *            the broker
+     * @param nodeId
+     *            the node id
+     * @param lstMac
+     *            the lst mac
+     * @return the listenable future
+     */
+    public static ListenableFuture<Void> deleteRemoteUcastMacs(DataBroker broker, NodeId nodeId,
+            String logicalSwitchName, List<MacAddress> lstMac) {
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+        deleteRemoteUcastMacs(transaction, nodeId, logicalSwitchName, lstMac);
+        return transaction.submit();
+    }
+
+    /**
+     * Delete remote ucast macs from the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param lstMac
+     *            the lst mac
+     */
+    public static void deleteRemoteUcastMacs(final WriteTransaction transaction, final NodeId nodeId,
+            String logicalSwitchName, final List<MacAddress> lstMac) {
+        if (lstMac != null && !lstMac.isEmpty()) {
+            for (MacAddress mac : lstMac) {
+                deleteRemoteUcastMac(transaction, nodeId, logicalSwitchName, mac);
+            }
+        }
+    }
+
+    /**
+     * Delete remote ucast mac from the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param mac
+     *            the mac
+     */
+    public static void deleteRemoteUcastMac(final WriteTransaction transaction, final NodeId nodeId,
+            String logialSwitchName,
+            final MacAddress mac) {
+        transaction.delete(LogicalDatastoreType.CONFIGURATION,
+                HwvtepSouthboundUtils.createRemoteUcastMacsInstanceIdentifier(nodeId, logialSwitchName, mac));
+    }
+
+    /**
+     * Adds the remote mcast macs into config DS.
+     *
+     * @param broker
+     *            the broker
+     * @param nodeId
+     *            the node id
+     * @param lstRemoteMcastMacs
+     *            the lst remote mcast macs
+     * @return the listenable future
+     */
+    public static ListenableFuture<Void> addRemoteMcastMacs(DataBroker broker, NodeId nodeId,
+            List<RemoteMcastMacs> lstRemoteMcastMacs) {
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+        putRemoteMcastMacs(transaction, nodeId, lstRemoteMcastMacs);
+        return transaction.submit();
+    }
+
+    /**
+     * Put remote mcast macs in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param lstRemoteMcastMacs
+     *            the lst remote mcast macs
+     */
+    public static void putRemoteMcastMacs(final WriteTransaction transaction, final NodeId nodeId,
+            final List<RemoteMcastMacs> lstRemoteMcastMacs) {
+        if (lstRemoteMcastMacs != null && !lstRemoteMcastMacs.isEmpty()) {
+            for (RemoteMcastMacs remoteMcastMac : lstRemoteMcastMacs) {
+                putRemoteMcastMac(transaction, nodeId, remoteMcastMac);
+            }
+        }
+    }
+
+    /**
+     * Put remote mcast mac in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param remoteMcastMac
+     *            the remote mcast mac
+     */
+    public static void putRemoteMcastMac(final WriteTransaction transaction, final NodeId nodeId,
+            RemoteMcastMacs remoteMcastMac) {
+        InstanceIdentifier<RemoteMcastMacs> iid = HwvtepSouthboundUtils.createRemoteMcastMacsInstanceIdentifier(nodeId,
+                remoteMcastMac.getKey());
+        transaction.put(LogicalDatastoreType.CONFIGURATION, iid, remoteMcastMac, true);
+    }
+
+    /**
+     * Delete remote mcast mac from config DS.
+     *
+     * @param broker
+     *            the broker
+     * @param nodeId
+     *            the node id
+     * @param remoteMcastMacsKey
+     *            the remote mcast macs key
+     * @return the listenable future
+     */
+    public static ListenableFuture<Void> deleteRemoteMcastMac(DataBroker broker, NodeId nodeId,
+            RemoteMcastMacsKey remoteMcastMacsKey) {
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+        deleteRemoteMcastMac(transaction, nodeId, remoteMcastMacsKey);
+        return transaction.submit();
+    }
+
+    /**
+     * Delete remote mcast macs from config DS.
+     *
+     * @param broker
+     *            the broker
+     * @param nodeId
+     *            the node id
+     * @param lstRemoteMcastMacsKey
+     *            the lst remote mcast macs key
+     * @return the listenable future
+     */
+    public static ListenableFuture<Void> deleteRemoteMcastMacs(DataBroker broker, NodeId nodeId,
+            List<RemoteMcastMacsKey> lstRemoteMcastMacsKey) {
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+        deleteRemoteMcastMacs(transaction, nodeId, lstRemoteMcastMacsKey);
+        return transaction.submit();
+    }
+
+    /**
+     * Delete remote mcast macs from the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param lstRemoteMcastMacsKey
+     *            the lst remote mcast macs key
+     */
+    public static void deleteRemoteMcastMacs(final WriteTransaction transaction, final NodeId nodeId,
+            final List<RemoteMcastMacsKey> lstRemoteMcastMacsKey) {
+        if (lstRemoteMcastMacsKey != null && !lstRemoteMcastMacsKey.isEmpty()) {
+            for (RemoteMcastMacsKey mac : lstRemoteMcastMacsKey) {
+                deleteRemoteMcastMac(transaction, nodeId, mac);
+            }
+        }
+    }
+
+    /**
+     * Delete remote mcast mac from the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param remoteMcastMacsKey
+     *            the remote mcast macs key
+     */
+    public static void deleteRemoteMcastMac(final WriteTransaction transaction, final NodeId nodeId,
+            final RemoteMcastMacsKey remoteMcastMacsKey) {
+        transaction.delete(LogicalDatastoreType.CONFIGURATION,
+                HwvtepSouthboundUtils.createRemoteMcastMacsInstanceIdentifier(nodeId, remoteMcastMacsKey));
+    }
+
+    /**
+     * Merge vlan bindings in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param nodeId
+     *            the node id
+     * @param phySwitchName
+     *            the phy switch name
+     * @param phyPortName
+     *            the phy port name
+     * @param vlanBindings
+     *            the vlan bindings
+     */
+    public static void mergeVlanBindings(final WriteTransaction transaction, final NodeId nodeId,
+            final String phySwitchName, final String phyPortName, final List<VlanBindings> vlanBindings) {
+        NodeId physicalSwitchNodeId = HwvtepSouthboundUtils.createManagedNodeId(nodeId, phySwitchName);
+        mergeVlanBindings(transaction, physicalSwitchNodeId, phyPortName, vlanBindings);
+    }
+
+    /**
+     * Merge vlan bindings in the transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param physicalSwitchNodeId
+     *            the physical switch node id
+     * @param phyPortName
+     *            the phy port name
+     * @param vlanBindings
+     *            the vlan bindings
+     */
+    public static void mergeVlanBindings(final WriteTransaction transaction, final NodeId physicalSwitchNodeId,
+            final String phyPortName, final List<VlanBindings> vlanBindings) {
+        HwvtepPhysicalPortAugmentation phyPortAug = new HwvtepPhysicalPortAugmentationBuilder()
+                .setHwvtepNodeName(new HwvtepNodeName(phyPortName)).setVlanBindings(vlanBindings).build();
+
+        final InstanceIdentifier<HwvtepPhysicalPortAugmentation> iid = HwvtepSouthboundUtils
+                .createPhysicalPortInstanceIdentifier(physicalSwitchNodeId, phyPortName);
+        transaction.merge(LogicalDatastoreType.CONFIGURATION, iid, phyPortAug, true);
+    }
+
+    /**
+     * Delete vlan binding from transaction.
+     *
+     * @param transaction
+     *            the transaction
+     * @param physicalSwitchNodeId
+     *            the physical switch node id
+     * @param phyPortName
+     *            the phy port name
+     * @param vlanId
+     *            the vlan id
+     */
+    public static void deleteVlanBinding(WriteTransaction transaction, NodeId physicalSwitchNodeId, String phyPortName,
+            Integer vlanId) {
+        InstanceIdentifier<VlanBindings> iid = HwvtepSouthboundUtils
+                .createVlanBindingInstanceIdentifier(physicalSwitchNodeId, phyPortName, vlanId);
+        transaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
+    }
+
+    /**
+     * Gets the hw vtep node.
+     *
+     * @param dataBroker
+     *            the data broker
+     * @param datastoreType
+     *            the datastore type
+     * @param nodeId
+     *            the node id
+     * @return the hw vtep node
+     */
+    public static Node getHwVtepNode(DataBroker dataBroker, LogicalDatastoreType datastoreType, NodeId nodeId) {
+        Optional<Node> optNode = MDSALUtil.read(dataBroker, datastoreType,
+                HwvtepSouthboundUtils.createInstanceIdentifier(nodeId));
+        if (optNode.isPresent()) {
+            return optNode.get();
+        }
+        return null;
+    }
+}
index 1192208f6bce6cbea7e9669d3c5c4e4c3bbf1f74..08a1e657334ac684750cdb0917ebb5307f55a455 100644 (file)
@@ -264,7 +264,8 @@ public class MDSALManager implements AutoCloseable {
     public CheckedFuture<Void,TransactionCommitFailedException> removeFlowNew(BigInteger dpnId, Flow flowEntity) {
         s_logger.debug("Remove flow {}",flowEntity);
         Node nodeDpn = buildDpnNode(dpnId);
-        FlowKey flowKey = new FlowKey(new FlowId(flowEntity.getId()));
+               //FlowKey flowKey = new FlowKey(new FlowId(flowEntity.getId()));
+        FlowKey flowKey = new FlowKey(flowEntity.getId());
         InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
                     .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
                     .child(Table.class, new TableKey(flowEntity.getTableId())).child(Flow.class, flowKey).build();