hwvtep federation support 10/53910/3
authorShlomi <shlomi.alfasi@hpe.com>
Mon, 27 Mar 2017 16:15:22 +0000 (19:15 +0300)
committerSam Hague <shague@redhat.com>
Wed, 29 Mar 2017 15:34:00 +0000 (15:34 +0000)
Change-Id: I1e3ef68ca45c9ab3998d2e0402989098c1aca137
Signed-off-by: Shlomi <shlomi.alfasi@hpe.com>
26 files changed:
vpnservice/features/src/main/features/features.xml
vpnservice/federation-plugin/api/pom.xml
vpnservice/federation-plugin/api/src/main/yang/federation-plugin.yang
vpnservice/federation-plugin/impl/pom.xml
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/FederatedMappings.java
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/FederationPluginCleaner.java
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/FederationPluginConstants.java
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/FederationPluginCounters.java
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/FederationPluginEgress.java
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/FederationPluginIngress.java
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/FederationPluginUtils.java
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/creators/FederationL2GatewayConnectionModificationCreator.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/creators/FederationL2GatewayModificationCreator.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/creators/FederationTopologyHwvtepNodeModificationCreator.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/filters/FederationL2GatewayConnectionFilter.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/filters/FederationL2GatewayFilter.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/filters/FederationTopologyHwvtepNodeFilter.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationL2GatewayConnectionIdentifier.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationL2GatewayIdentifier.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationTopologyHwvtepNodeIdentifier.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationTopologyNodeIdentifier.java
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationL2GatewayConnectionTransformer.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationL2GatewayTransformer.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationTopologyHwvtepNodeTransformer.java [new file with mode: 0644]
vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationTopologyNodeTransformer.java
vpnservice/federation-plugin/impl/src/test/java/org/opendaylight/netvirt/federation/plugin/end2end/AbstractEnd2EndTest.java

index cdfd453bbd9f5057c885e6e331c9fc4629c832ec..5fc686e1eecc2346e5323cfcd8f82416a65e3c30 100644 (file)
@@ -97,6 +97,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <feature name='odl-netvirt-federation' version='${project.version}' description='OpenDaylight :: NetVirt :: Federation'>
     <feature version="${project.version}">odl-netvirt-openstack</feature>
     <feature version="${federation.version}">federation-with-rabbit</feature>
+    <feature version='${infrautils.version}'>odl-infrautils-inject</feature>
     <bundle>mvn:org.opendaylight.netvirt/federation-plugin-api/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.netvirt/federation-plugin-impl/{{VERSION}}</bundle>
   </feature>
index 06dd190cae58afa92abaf47b0783af0b64becfb9..ffbcc3c96fd913b6091680925472a4112e84c2de 100644 (file)
@@ -37,6 +37,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>vpnmanager-api</artifactId>
       <version>${vpnservices.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.neutron</groupId>
+      <artifactId>model</artifactId>
+      <version>${neutron.version}</version>
+    </dependency>
   </dependencies>
 
   <build>
index 7cec4ac40b414e7f39d5674371be0d992da8a395..2f54a8765e962aba49e36ef3469736655aa88ed2 100644 (file)
@@ -33,7 +33,11 @@ module federation-plugin {
     }
 
     import neutronvpn {
-         prefix nvpn;
+        prefix nvpn;
+    }
+
+    import neutron {
+        prefix neutron;
     }
 
     revision "2017-02-19" {
@@ -79,4 +83,14 @@ module federation-plugin {
         ext:augment-identifier "vpn-shadow-properties";
         uses shadow-properties;
     }
+
+    augment "/neutron:neutron/neutron:l2gateways/neutron:l2gateway" {
+        ext:augment-identifier "l2gw-shadow-properties";
+        uses shadow-properties;
+    }
+
+    augment "/neutron:neutron/neutron:l2gatewayConnections/neutron:l2gatewayConnection" {
+        ext:augment-identifier "l2gw-connection-shadow-properties";
+        uses shadow-properties;
+    }
 }
index 42327db78f6fb5ac14607289dd33b4185c4f5fa9..443f5f634706a0437d64d196918ef91a8fc4f54c 100644 (file)
@@ -47,8 +47,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <version>${vpnservices.version}</version>
     </dependency>
     <dependency>
-        <groupId>javax.inject</groupId>
-        <artifactId>javax.inject</artifactId>
+        <groupId>org.opendaylight.infrautils</groupId>
+        <artifactId>inject</artifactId>
+        <version>${infrautils.version}</version>
     </dependency>
     <dependency>
         <groupId>org.opendaylight.netvirt</groupId>
index f8b4bd111e664e7d433ee5ad10e49ca6a75d2b14..83eef6ee0b302d8dbac2ef03e7b40bf65e6dbd63 100644 (file)
@@ -17,12 +17,15 @@ public class FederatedMappings {
 
     private final Map<String, String> producerToConsumerNetworkMap = Maps.newConcurrentMap();
     private final Map<String, String> producerToConsumerSubnetMap = Maps.newConcurrentMap();
+    private final Map<String, String> producerToConsumerTenantMap = Maps.newConcurrentMap();
 
     public FederatedMappings(List<FederatedNetworkPair> federatedNetworkPairs) {
         federatedNetworkPairs.stream()
                 .forEach((pair) -> producerToConsumerNetworkMap.put(pair.producerNetworkId, pair.consumerNetworkId));
         federatedNetworkPairs.stream()
                 .forEach((pair) -> producerToConsumerSubnetMap.put(pair.producerSubnetId, pair.consumerSubnetId));
+        federatedNetworkPairs.stream()
+                .forEach((pair) -> producerToConsumerTenantMap.put(pair.producerTenantId, pair.consumerTenantId));
     }
 
     public String getConsumerNetworkId(String producerNetworkId) {
@@ -49,10 +52,24 @@ public class FederatedMappings {
         return producerToConsumerSubnetMap.containsValue(consumerSubnetId);
     }
 
+    public String getConsumerTenantId(String producerTenantId) {
+        return producerToConsumerTenantMap.get(producerTenantId);
+    }
+
+    public boolean containsProducerTenantId(String producerTenantId) {
+        return producerToConsumerTenantMap.containsKey(producerTenantId);
+    }
+
+    public boolean containsConsumerTenantId(String consumerTenantId) {
+        return producerToConsumerTenantMap.containsValue(consumerTenantId);
+    }
+
     @Override
     public String toString() {
-        return "FederatedMappings [federatedNetworkMap=" + producerToConsumerNetworkMap + ", federatedSubnetMap="
-                + producerToConsumerSubnetMap + "]";
+        return "FederatedMappings [producerToConsumerNetworkMap=" + producerToConsumerNetworkMap
+                + ", producerToConsumerSubnetMap=" + producerToConsumerSubnetMap + ", producerToConsumerTenantMap="
+                + producerToConsumerTenantMap + "]";
     }
 
+
 }
index 57e32a802babbf92559c96c30f8787e41fa47342..5960bc8b7bea6ab043e1b3b05dc476e15a23bf37 100644 (file)
@@ -9,12 +9,10 @@ package org.opendaylight.netvirt.federation.plugin;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
-
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
@@ -24,21 +22,27 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 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.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.ElanShadowProperties;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.IfShadowProperties;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.InventoryNodeShadowProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwConnectionShadowProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwShadowProperties;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.TopologyNodeShadowProperties;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.VpnShadowProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnectionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.L2gateways;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gateway;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gatewayKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 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.TopologyId;
 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.yangtools.yang.binding.InstanceIdentifier;
@@ -75,10 +79,33 @@ public class FederationPluginCleaner {
 
         if (deleteElanInterfacesShadows(db, LogicalDatastoreType.CONFIGURATION, MAX_TRANSACTION_DELETE_RETRIES,
             elanInterface -> {
-                ElanShadowProperties elanShadowProperties = elanInterface.getAugmentation(ElanShadowProperties.class);
+                ElanShadowProperties elanShadowProperties = elanInterface
+                        .getAugmentation(ElanShadowProperties.class);
                 return elanShadowProperties != null && Boolean.TRUE.equals(elanShadowProperties.isShadow())
-                    && generationNumber != elanShadowProperties.getGenerationNumber()
-                    && remoteIp.equals(elanShadowProperties.getRemoteIp());
+                        && generationNumber != elanShadowProperties.getGenerationNumber()
+                        && remoteIp.equals(elanShadowProperties.getRemoteIp());
+            })) {
+            somethingDeleted = true;
+        }
+
+        if (deleteL2GatewayShadows(db, LogicalDatastoreType.CONFIGURATION, MAX_TRANSACTION_DELETE_RETRIES,
+            l2Gateway -> {
+                L2gwShadowProperties l2GwShadowProperties = l2Gateway.getAugmentation(L2gwShadowProperties.class);
+                return l2GwShadowProperties != null && Boolean.TRUE.equals(l2GwShadowProperties.isShadow())
+                        && generationNumber != l2GwShadowProperties.getGenerationNumber()
+                        && remoteIp.equals(l2GwShadowProperties.getRemoteIp());
+            })) {
+            somethingDeleted = true;
+        }
+
+        if (deleteL2GatewayConnectionShadows(db, LogicalDatastoreType.CONFIGURATION, MAX_TRANSACTION_DELETE_RETRIES,
+            l2GatewayConnection -> {
+                L2gwConnectionShadowProperties l2GwConnectionShadowProperties = l2GatewayConnection
+                        .getAugmentation(L2gwConnectionShadowProperties.class);
+                return l2GwConnectionShadowProperties != null
+                        && Boolean.TRUE.equals(l2GwConnectionShadowProperties.isShadow())
+                        && generationNumber != l2GwConnectionShadowProperties.getGenerationNumber()
+                        && remoteIp.equals(l2GwConnectionShadowProperties.getRemoteIp());
             })) {
             somethingDeleted = true;
         }
@@ -92,62 +119,60 @@ public class FederationPluginCleaner {
                 && remoteIp.equals(ifShadowProperties.getRemoteIp());
         });
 
+
         EXECUTOR.schedule(() -> {
 
-            deleteInventoryNodes(db, LogicalDatastoreType.OPERATIONAL, MAX_TRANSACTION_DELETE_RETRIES,
-                    new IEntityDeleteDecision<Node>() {
-                        @Override
-                        public boolean shouldDelete(Node node) {
-                            InventoryNodeShadowProperties nodeShadowProperties = node
-                                    .getAugmentation(InventoryNodeShadowProperties.class);
-                            return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
-                                    && (generationNumber != nodeShadowProperties.getGenerationNumber())
-                                    && (remoteIp.equals(nodeShadowProperties.getRemoteIp()));
-                        }
-                    });
-
-            deleteInventoryNodes(db, LogicalDatastoreType.CONFIGURATION, MAX_TRANSACTION_DELETE_RETRIES,
-                    new IEntityDeleteDecision<Node>() {
-                        @Override
-                        public boolean shouldDelete(Node node) {
-                            InventoryNodeShadowProperties nodeShadowProperties = node
-                                    .getAugmentation(InventoryNodeShadowProperties.class);
-                            return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
-                                    && (generationNumber != nodeShadowProperties.getGenerationNumber())
-                                    && (remoteIp.equals(nodeShadowProperties.getRemoteIp()));
-                        }
-                    });
-
-            deleteTopologyShadowNodes(db, LogicalDatastoreType.OPERATIONAL, MAX_TRANSACTION_DELETE_RETRIES,
-                    new IEntityDeleteDecision<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
-                    .rev131021.network.topology.topology.Node>() {
-                        @Override
-                        public boolean shouldDelete(
-                                org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
-                                .network.topology.topology.Node node) {
-                            TopologyNodeShadowProperties nodeShadowProperties = node
-                                    .getAugmentation(TopologyNodeShadowProperties.class);
-                            return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
-                                    && (generationNumber != nodeShadowProperties.getGenerationNumber())
-                                    && (remoteIp.equals(nodeShadowProperties.getRemoteIp()));
-                        }
-                    });
-
-            deleteTopologyShadowNodes(db, LogicalDatastoreType.CONFIGURATION, MAX_TRANSACTION_DELETE_RETRIES,
-                    new IEntityDeleteDecision<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
-                    .rev131021.network.topology.topology.Node>() {
-                        @Override
-                        public boolean shouldDelete(
-                                org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
-                                .network.topology.topology.Node node) {
-                            TopologyNodeShadowProperties nodeShadowProperties = node
-                                    .getAugmentation(TopologyNodeShadowProperties.class);
-                            return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
-                                    && (generationNumber > nodeShadowProperties.getGenerationNumber())
-                                    && (remoteIp.equals(nodeShadowProperties.getRemoteIp()));
-                        }
-                    });
-        } , 120, TimeUnit.SECONDS);
+            deleteInventoryNodes(db, LogicalDatastoreType.OPERATIONAL, MAX_TRANSACTION_DELETE_RETRIES, node -> {
+                InventoryNodeShadowProperties nodeShadowProperties = node
+                        .getAugmentation(InventoryNodeShadowProperties.class);
+                return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
+                        && generationNumber != nodeShadowProperties.getGenerationNumber()
+                        && remoteIp.equals(nodeShadowProperties.getRemoteIp());
+            });
+
+            deleteInventoryNodes(db, LogicalDatastoreType.CONFIGURATION, MAX_TRANSACTION_DELETE_RETRIES, node -> {
+                InventoryNodeShadowProperties nodeShadowProperties = node
+                        .getAugmentation(InventoryNodeShadowProperties.class);
+                return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
+                        && generationNumber != nodeShadowProperties.getGenerationNumber()
+                        && remoteIp.equals(nodeShadowProperties.getRemoteIp());
+            });
+
+            deleteTopologyShadowNodes(db, LogicalDatastoreType.OPERATIONAL,
+                    FederationPluginConstants.OVSDB_TOPOLOGY_KEY, MAX_TRANSACTION_DELETE_RETRIES, node -> {
+                    TopologyNodeShadowProperties nodeShadowProperties = node
+                                .getAugmentation(TopologyNodeShadowProperties.class);
+                    return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
+                                && generationNumber != nodeShadowProperties.getGenerationNumber()
+                                && remoteIp.equals(nodeShadowProperties.getRemoteIp());
+                });
+
+            deleteTopologyShadowNodes(db, LogicalDatastoreType.CONFIGURATION,
+                    FederationPluginConstants.OVSDB_TOPOLOGY_KEY, MAX_TRANSACTION_DELETE_RETRIES, node -> {
+                    TopologyNodeShadowProperties nodeShadowProperties = node
+                                .getAugmentation(TopologyNodeShadowProperties.class);
+                    return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
+                                && generationNumber > nodeShadowProperties.getGenerationNumber()
+                                && remoteIp.equals(nodeShadowProperties.getRemoteIp());
+                });
+            deleteTopologyShadowNodes(db, LogicalDatastoreType.OPERATIONAL,
+                    FederationPluginConstants.HWVTEP_TOPOLOGY_KEY, MAX_TRANSACTION_DELETE_RETRIES, node -> {
+                    TopologyNodeShadowProperties nodeShadowProperties = node
+                                .getAugmentation(TopologyNodeShadowProperties.class);
+                    return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
+                                && generationNumber != nodeShadowProperties.getGenerationNumber()
+                                && remoteIp.equals(nodeShadowProperties.getRemoteIp());
+                });
+
+            deleteTopologyShadowNodes(db, LogicalDatastoreType.CONFIGURATION,
+                    FederationPluginConstants.HWVTEP_TOPOLOGY_KEY, MAX_TRANSACTION_DELETE_RETRIES, node -> {
+                    TopologyNodeShadowProperties nodeShadowProperties = node
+                                .getAugmentation(TopologyNodeShadowProperties.class);
+                    return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow())
+                                && generationNumber > nodeShadowProperties.getGenerationNumber()
+                                && remoteIp.equals(nodeShadowProperties.getRemoteIp());
+                });
+        }, 120, TimeUnit.SECONDS);
     }
 
     private static void sleepIfSomethingWasDeleted(boolean somethingRemoved) {
@@ -204,7 +229,7 @@ public class FederationPluginCleaner {
     }
 
     private static boolean deleteInterfacesShadows(DataBroker db, LogicalDatastoreType type, int remainingRetries,
-        IEntityDeleteDecision<Interface> entityDeleteDecision) {
+            IEntityDeleteDecision<Interface> entityDeleteDecision) {
         InstanceIdentifier<Interfaces> path = InstanceIdentifier.create(Interfaces.class);
         ReadTransaction readTx = db.newReadOnlyTransaction();
         CheckedFuture<Optional<Interfaces>, ReadFailedException> future = readTx.read(type, path);
@@ -224,7 +249,7 @@ public class FederationPluginCleaner {
                     LOG.debug("Delete shadow interfaces: DataStoreType {}, interface {}", type, iface);
                     FederationPluginCounters.removed_shadow_ietf_interface.inc();
                     InstanceIdentifier<Interface> iid = InstanceIdentifier.create(Interfaces.class)
-                        .child(Interface.class, new InterfaceKey(iface.getKey()));
+                            .child(Interface.class, new InterfaceKey(iface.getKey()));
                     deleteTx.delete(type, iid);
                 }
             }
@@ -237,7 +262,99 @@ public class FederationPluginCleaner {
                     deleteInterfacesShadows(db, type, --remainingRetries, entityDeleteDecision);
                 } else {
                     LOG.error("deleteInterfacesShadows - Failed to delete - no more retries! {} {}" + e.getMessage(),
-                        e);
+                            e);
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private static boolean deleteL2GatewayShadows(DataBroker db, LogicalDatastoreType type, int remainingRetries,
+            IEntityDeleteDecision<L2gateway> entityDeleteDecision) {
+
+        InstanceIdentifier<L2gateways> path = InstanceIdentifier.create(Neutron.class)
+                .child(L2gateways.class);
+        ReadTransaction readTx = db.newReadOnlyTransaction();
+        CheckedFuture<Optional<L2gateways>, ReadFailedException> future = readTx.read(type, path);
+
+        Optional<L2gateways> optional = null;
+
+        try {
+            optional = future.get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("deleteL2GatewayShadows failed to get data");
+            return false;
+        }
+        if (optional.isPresent()) {
+            WriteTransaction deleteTx = db.newWriteOnlyTransaction();
+            L2gateways l2gws = optional.get();
+            for (L2gateway iface : l2gws.getL2gateway()) {
+                if (entityDeleteDecision.shouldDelete(iface)) {
+                    LOG.debug("Delete shadow l2 gateway: DataStoreType {}, interface {}", type, iface);
+                    FederationPluginCounters.removed_shadow_l2_gateway.inc();
+                    InstanceIdentifier<L2gateway> iid = InstanceIdentifier.create(Neutron.class)
+                            .child(L2gateways.class).child(L2gateway.class, new L2gatewayKey(iface.getKey()));
+                    deleteTx.delete(type, iid);
+                }
+            }
+            CheckedFuture<Void, TransactionCommitFailedException> future1 = deleteTx.submit();
+            try {
+                future1.checkedGet();
+            } catch (TransactionCommitFailedException e) {
+                if (remainingRetries > 0) {
+                    LOG.warn("deleteL2GatewayShadows - Failed to delete! {} {}" + e.getMessage(), e);
+                    deleteL2GatewayShadows(db, type, --remainingRetries, entityDeleteDecision);
+                } else {
+                    LOG.error("deleteL2GatewayShadows - Failed to delete - no more retries! {} {}" + e.getMessage(), e);
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private static boolean deleteL2GatewayConnectionShadows(DataBroker db, LogicalDatastoreType type,
+            int remainingRetries, IEntityDeleteDecision<L2gatewayConnection> entityDeleteDecision) {
+
+        InstanceIdentifier<L2gatewayConnections> path = InstanceIdentifier.create(Neutron.class)
+                .child(L2gatewayConnections.class);
+        ReadTransaction readTx = db.newReadOnlyTransaction();
+        CheckedFuture<Optional<L2gatewayConnections>, ReadFailedException> future = readTx.read(type, path);
+
+        Optional<L2gatewayConnections> optional = null;
+
+        try {
+            optional = future.get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("deleteL2GatewayConnectionShadows failed to get data");
+            return false;
+        }
+        if (optional.isPresent()) {
+            WriteTransaction deleteTx = db.newWriteOnlyTransaction();
+            L2gatewayConnections l2gws = optional.get();
+            for (L2gatewayConnection iface : l2gws.getL2gatewayConnection()) {
+                if (entityDeleteDecision.shouldDelete(iface)) {
+                    LOG.debug("Delete shadow l2 gateway: DataStoreType {}, interface {}", type, iface);
+                    FederationPluginCounters.removed_shadow_l2_gateway.inc();
+                    InstanceIdentifier<L2gatewayConnection> iid = InstanceIdentifier.create(
+                            Neutron.class).child(L2gatewayConnections.class)
+                            .child(L2gatewayConnection.class, new L2gatewayConnectionKey(iface.getKey()));
+                    deleteTx.delete(type, iid);
+                }
+            }
+            CheckedFuture<Void, TransactionCommitFailedException> future1 = deleteTx.submit();
+            try {
+                future1.checkedGet();
+            } catch (TransactionCommitFailedException e) {
+                if (remainingRetries > 0) {
+                    LOG.warn("deleteL2GatewayShadows - Failed to delete! {} {}" + e.getMessage(), e);
+                    deleteL2GatewayConnectionShadows(db, type, --remainingRetries, entityDeleteDecision);
+                } else {
+                    LOG.error(
+                            "deleteL2GatewayShadows - Failed to delete - no more retries! {} {}" + e.getMessage(), e);
                 }
             }
             return true;
@@ -291,11 +408,12 @@ public class FederationPluginCleaner {
         }
     }
 
-    private static boolean deleteTopologyShadowNodes(DataBroker db, LogicalDatastoreType type, int remainingRetries,
+    private static boolean deleteTopologyShadowNodes(DataBroker db, LogicalDatastoreType type, TopologyKey topologyKey,
+            int remainingRetries,
         IEntityDeleteDecision<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network
         .topology.topology.Node> entityDeleteDecision) {
         InstanceIdentifier<Topology> path = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
-            new TopologyKey(new TopologyId(new Uri("ovsdb:1"))));
+                topologyKey);
         ReadTransaction readTx = db.newReadOnlyTransaction();
         CheckedFuture<Optional<Topology>, ReadFailedException> future = readTx.read(type, path);
 
@@ -318,7 +436,7 @@ public class FederationPluginCleaner {
                     InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
                         .rev131021.network.topology.topology.Node> iid = InstanceIdentifier
                             .create(NetworkTopology.class)
-                            .child(Topology.class, new TopologyKey(new TopologyId(new Uri("ovsdb:1"))))
+                            .child(Topology.class, FederationPluginConstants.OVSDB_TOPOLOGY_KEY)
                             .child(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
                                     .network.topology.topology.Node.class, node.getKey());
                     deleteTx.delete(type, iid);
@@ -330,7 +448,7 @@ public class FederationPluginCleaner {
             } catch (org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException e) {
                 if (remainingRetries > 0) {
                     LOG.warn("deleteTopologyShadowNodes - Failed to delete! {} {}" + e.getMessage(), e);
-                    deleteTopologyShadowNodes(db, type, --remainingRetries, entityDeleteDecision);
+                    deleteTopologyShadowNodes(db, type, topologyKey, --remainingRetries, entityDeleteDecision);
                 } else {
                     LOG.error("deleteTopologyShadowNodes - Failed to delete - no more retries! {} {}" + e.getMessage(),
                         e);
index fe20e0467e0dad673ac91be460f86b2f13662762..e31d9afd73b3b93e73154f32f35ef9c968b4b4ed 100644 (file)
@@ -9,6 +9,10 @@
 package org.opendaylight.netvirt.federation.plugin;
 
 import org.opendaylight.genius.itm.globals.ITMConstants;
+import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
 
 public class FederationPluginConstants {
 
@@ -18,6 +22,10 @@ public class FederationPluginConstants {
 
     public static final String INVENTORY_NODE_OPER_KEY = "INVENTORY_NODE_OPER";
 
+    public static final String TOPOLOGY_HWVTEP_NODE_CONFIG_KEY = "TOPOLOGY_HWVTEP_NODE_CONFIG";
+
+    public static final String TOPOLOGY_HWVTEP_NODE_OPER_KEY = "TOPOLOGY_HWVTEP_NODE_OPER";
+
     public static final String TOPOLOGY_NODE_CONFIG_KEY = "TOPOLOGY_NODE_CONFIG";
 
     public static final String TOPOLOGY_NODE_OPER_KEY = "TOPOLOGY_NODE_OPER";
@@ -28,10 +36,20 @@ public class FederationPluginConstants {
 
     public static final String VPN_INTERFACE_KEY = "VPN_INTERFACE";
 
+    public static final String L2_GATEWAY_KEY = "L2_GATEWAY";
+
+    public static final String L2_GATEWAY_CONNECTION_KEY = "L2_GATEWAY_CONNECTIONS";
+
     public static final String RPC_ROUTE_KEY = "FEDERATION_ROUTE_KEY";
 
     public static final String INTEGRATION_BRIDGE_PREFIX = ITMConstants.BRIDGE_URI_PREFIX + "/"
             + ITMConstants.DEFAULT_BRIDGE_NAME;
 
     public static final String TUNNEL_PREFIX = "tun";
+
+    public static final TopologyKey OVSDB_TOPOLOGY_KEY = new TopologyKey(new TopologyId(new Uri("ovsdb:1")));
+
+    public static final TopologyKey HWVTEP_TOPOLOGY_KEY = new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID);
+
+    public static final String HWVTEP_PHYSICAL_SWITCH = "physicalswitch";
 }
index 388d2786546461933ac07fe2046438e05c1f4cc9..6fa26f5032237f60554d6fc9f24e3fcce742ad17 100644 (file)
@@ -40,14 +40,17 @@ public enum FederationPluginCounters {
     ingress_consume_msg_aborted, //
     ingress_full_sync_aborted, //
     egress_node_filtered_after_transform, //
+    egress_hwvtep_node_filtered_after_transform, //
     egress_no_existing_data, //
     removed_shadow_elan_interface, //
+    removed_shadow_l2_gateway, //
     removed_shadow_ietf_interface, //
     removed_shadow_inventory_node, //
     removed_shadow_topology_node, //
     removed_shadow_vpn_interface, //
     removed_shadow_vpn_port_ip_to_port, //
-    ;
+    hwvtep_egress_apply_transformation, //
+    hwvtep_ingress_apply_transformation;
 
     private OccurenceCounter counter;
 
index f3861bad65f8669fe51683c4dc82a5010d8b9659..f3b50ce27296bb94dbfd26e1d7c959f558303bda 100644 (file)
@@ -271,7 +271,7 @@ public class FederationPluginEgress implements IFederationPluginEgress {
                 .getSubtreeInstanceIdentifier(listenerKey);
         LogicalDatastoreType datastoreType = FederationPluginUtils.getListenerDatastoreType(listenerKey);
         EntityFederationMessage<T> msg = createMsgWithRetriesMechanism(dataObject, modificationType, instanceIdentifier,
-                datastoreType, 2);
+                datastoreType, listenerKey, 2);
         return msg;
     }
 
@@ -282,10 +282,10 @@ public class FederationPluginEgress implements IFederationPluginEgress {
     @SuppressWarnings({ "rawtypes", "unchecked", "checkstyle:emptyblock" })
     private <T extends DataObject, S extends DataObject> EntityFederationMessage<T> createMsgWithRetriesMechanism(
             T dataObject, ModificationType modificationType, InstanceIdentifier<T> instanceIdentifier,
-            LogicalDatastoreType datastoreType, int remainingRetries) {
+            LogicalDatastoreType datastoreType, String metadata, int remainingRetries) {
         try {
             EntityFederationMessage msg = new EntityFederationMessage(datastoreType.toString(),
-                    modificationType.toString(), null, queueName, instanceIdentifier, dataObject);
+                    modificationType.toString(), metadata, queueName, instanceIdentifier, dataObject);
             return msg;
         } catch (UncheckedExecutionException t) {
             if (remainingRetries > 0) {
@@ -296,7 +296,7 @@ public class FederationPluginEgress implements IFederationPluginEgress {
                 } catch (InterruptedException e) {
                 }
                 createMsgWithRetriesMechanism(dataObject, modificationType, instanceIdentifier, datastoreType,
-                        --remainingRetries);
+                        metadata, --remainingRetries);
             }
         }
 
index e3d73e00de210a90090ffc62428ef3213ff353c7..9b00eb785c9d84787cd42db879e921fba82f61a9 100644 (file)
@@ -15,7 +15,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
-
 import org.apache.commons.lang3.tuple.Pair;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
@@ -130,7 +129,7 @@ public class FederationPluginIngress implements IFederationPluginIngress {
             return;
         }
 
-        String listenerKey = FederationPluginUtils.getClassListener(msg.getInputClassType(), datastoreType);
+        String listenerKey = msg.getMetadata();
         if (listenerKey == null) {
             logger.error("Failed to get listener key for {}", msg.getInputClassType());
             return;
index 961371a45d6a7c0a175721b860487f899a8e61e9..cc6e6a74eb4c9ca3d7b5d34cc64ef705539df2e2 100644 (file)
@@ -45,7 +45,6 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 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.InterfacesBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
@@ -107,6 +106,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.IfShadowPropertiesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.InventoryNodeShadowProperties;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.InventoryNodeShadowPropertiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwConnectionShadowProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwShadowProperties;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.TopologyNodeShadowProperties;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.TopologyNodeShadowPropertiesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.VpnShadowProperties;
@@ -119,6 +120,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.OpS
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.L2gateways;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gateway;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
@@ -130,10 +135,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.F
 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.NetworkTopologyBuilder;
 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.TopologyId;
 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.TopologyBuilder;
-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.NodeBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -149,6 +152,10 @@ public class FederationPluginUtils {
 
             ImmutableList.of(FederationPluginConstants.TOPOLOGY_NODE_CONFIG_KEY, //
                     FederationPluginConstants.TOPOLOGY_NODE_OPER_KEY, //
+                    FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_CONFIG_KEY, //
+                    FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_OPER_KEY, //
+                    FederationPluginConstants.L2_GATEWAY_KEY, //
+                    FederationPluginConstants.L2_GATEWAY_CONNECTION_KEY, //
                     FederationPluginConstants.INVENTORY_NODE_CONFIG_KEY, //
                     FederationPluginConstants.INVENTORY_NODE_OPER_KEY, //
                     FederationPluginConstants.IETF_INTERFACE_KEY, //
@@ -196,6 +203,14 @@ public class FederationPluginUtils {
             moduleInfos.add(BindingReflections.getModuleInfo(IfShadowProperties.class));
             moduleInfos.add(BindingReflections.getModuleInfo(InventoryNodeShadowProperties.class));
             moduleInfos.add(BindingReflections.getModuleInfo(VpnShadowProperties.class));
+            moduleInfos.add(BindingReflections.getModuleInfo(Neutron.class));
+            moduleInfos.add(BindingReflections.getModuleInfo(L2gateways.class));
+            moduleInfos.add(BindingReflections.getModuleInfo(L2gateway.class));
+            moduleInfos.add(BindingReflections.getModuleInfo(L2gatewayConnections.class));
+            moduleInfos.add(BindingReflections.getModuleInfo(L2gatewayConnection.class));
+            moduleInfos.add(BindingReflections.getModuleInfo(L2gwConnectionShadowProperties.class));
+            moduleInfos.add(BindingReflections.getModuleInfo(L2gwShadowProperties.class));
+
             BindingAwareJsonConverter.init(moduleInfos);
             bug7420Workaround(5);
             yangModulesInitialized = true;
@@ -470,7 +485,7 @@ public class FederationPluginUtils {
         try {
 
             TopologyBuilder topologyBuilder = new TopologyBuilder();
-            topologyBuilder.setKey(new TopologyKey(new TopologyId(new Uri("ovsdb:1"))));
+            topologyBuilder.setKey(FederationPluginConstants.OVSDB_TOPOLOGY_KEY);
             String nodeName = "aaa";
             NodeBuilder nodeBuilder = new NodeBuilder();
             nodeBuilder.setNodeId(new NodeId(nodeName));
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/creators/FederationL2GatewayConnectionModificationCreator.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/creators/FederationL2GatewayConnectionModificationCreator.java
new file mode 100644 (file)
index 0000000..80b89a6
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.creators;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationL2GatewayConnectionModificationCreator
+        implements FederationPluginModificationCreator<L2gatewayConnection, L2gatewayConnections> {
+    private static final Logger LOG = LoggerFactory.getLogger(FederationL2GatewayConnectionModificationCreator.class);
+
+    @Inject
+    public FederationL2GatewayConnectionModificationCreator() {
+        FederationPluginCreatorRegistry.registerCreator(FederationPluginConstants.L2_GATEWAY_CONNECTION_KEY, this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public Collection<DataTreeModification<L2gatewayConnection>> createDataTreeModifications(
+            L2gatewayConnections l2gatewayConnections) {
+        if (l2gatewayConnections == null || l2gatewayConnections.getL2gatewayConnection() == null) {
+            LOG.debug("No L2 Gateway connection found");
+            return Collections.emptyList();
+        }
+
+        Collection<DataTreeModification<L2gatewayConnection>> modifications = new ArrayList<>();
+        for (L2gatewayConnection l2gateway : l2gatewayConnections.getL2gatewayConnection()) {
+            modifications.add(new FullSyncDataTreeModification<>(l2gateway));
+        }
+
+        return modifications;
+    }
+
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/creators/FederationL2GatewayModificationCreator.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/creators/FederationL2GatewayModificationCreator.java
new file mode 100644 (file)
index 0000000..578ae41
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.creators;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.L2gateways;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gateway;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationL2GatewayModificationCreator
+        implements FederationPluginModificationCreator<L2gateway, L2gateways> {
+    private static final Logger LOG = LoggerFactory.getLogger(FederationL2GatewayModificationCreator.class);
+
+    @Inject
+    public FederationL2GatewayModificationCreator() {
+        FederationPluginCreatorRegistry.registerCreator(FederationPluginConstants.L2_GATEWAY_KEY, this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public Collection<DataTreeModification<L2gateway>> createDataTreeModifications(L2gateways l2gateways) {
+        if (l2gateways == null || l2gateways.getL2gateway() == null) {
+            LOG.debug("No L2 Gateway found");
+            return Collections.emptyList();
+        }
+
+        Collection<DataTreeModification<L2gateway>> modifications = new ArrayList<>();
+        for (L2gateway l2gateway : l2gateways.getL2gateway()) {
+            modifications.add(new FullSyncDataTreeModification<>(l2gateway));
+        }
+
+        return modifications;
+    }
+
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/creators/FederationTopologyHwvtepNodeModificationCreator.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/creators/FederationTopologyHwvtepNodeModificationCreator.java
new file mode 100644 (file)
index 0000000..d908b1f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.creators;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationTopologyHwvtepNodeModificationCreator
+        implements FederationPluginModificationCreator<Node, Topology> {
+    private static final Logger LOG = LoggerFactory.getLogger(FederationTopologyHwvtepNodeModificationCreator.class);
+
+    @Inject
+    public FederationTopologyHwvtepNodeModificationCreator() {
+        FederationPluginCreatorRegistry.registerCreator(FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_CONFIG_KEY,
+                this);
+        FederationPluginCreatorRegistry.registerCreator(FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_OPER_KEY, this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public Collection<DataTreeModification<Node>> createDataTreeModifications(Topology topology) {
+        if (topology == null || topology.getNode() == null) {
+            LOG.debug("No topology nodes found");
+            return Collections.emptyList();
+        }
+
+        Collection<DataTreeModification<Node>> modifications = new ArrayList<>();
+        for (Node node : topology.getNode()) {
+            modifications.add(new FullSyncDataTreeModification<>(node));
+        }
+
+        return modifications;
+    }
+
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/filters/FederationL2GatewayConnectionFilter.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/filters/FederationL2GatewayConnectionFilter.java
new file mode 100644 (file)
index 0000000..070af7b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.filters;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.netvirt.federation.plugin.FederatedMappings;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.netvirt.federation.plugin.PendingModificationCache;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwConnectionShadowProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationL2GatewayConnectionFilter implements FederationPluginFilter<L2gatewayConnection,
+        Neutron> {
+    private static final Logger LOG = LoggerFactory.getLogger(FederationL2GatewayConnectionFilter.class);
+
+    @Inject
+    public FederationL2GatewayConnectionFilter(final DataBroker dataBroker) {
+        FederationPluginFilterRegistry.registerFilter(FederationPluginConstants.L2_GATEWAY_CONNECTION_KEY, this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public FilterResult applyEgressFilter(L2gatewayConnection l2Gateway, FederatedMappings federatedMappings,
+            PendingModificationCache<DataTreeModification<?>> pendingModifications,
+            DataTreeModification<L2gatewayConnection> dataTreeModification) {
+        if (isShadow(l2Gateway)) {
+            LOG.trace("Interface {} filtered out. Reason: shadow interface", l2Gateway.getName());
+            return FilterResult.DENY;
+        }
+
+        String networkName = l2Gateway.getNetworkId().getValue();
+        if (!federatedMappings.containsProducerNetworkId(networkName)) {
+            LOG.trace("Interface {} filtered out. Reason: network {} not federated", l2Gateway.getName(), networkName);
+            return FilterResult.DENY;
+        }
+
+        return FilterResult.ACCEPT;
+    }
+
+    @Override
+    public FilterResult applyIngressFilter(String listenerKey, Neutron neutron) {
+        return FilterResult.ACCEPT;
+    }
+
+    private boolean isShadow(L2gatewayConnection l2Gateway) {
+        L2gwConnectionShadowProperties l2ShadowProperties = l2Gateway
+                .getAugmentation(L2gwConnectionShadowProperties.class);
+        return l2ShadowProperties != null && Boolean.TRUE.equals(l2ShadowProperties.isShadow());
+    }
+
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/filters/FederationL2GatewayFilter.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/filters/FederationL2GatewayFilter.java
new file mode 100644 (file)
index 0000000..d698d64
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.filters;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.netvirt.federation.plugin.FederatedMappings;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.netvirt.federation.plugin.PendingModificationCache;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwShadowProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gateway;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationL2GatewayFilter implements FederationPluginFilter<L2gateway, Neutron> {
+    private static final Logger LOG = LoggerFactory.getLogger(FederationL2GatewayFilter.class);
+
+    @Inject
+    public FederationL2GatewayFilter(final DataBroker dataBroker) {
+        FederationPluginFilterRegistry.registerFilter(FederationPluginConstants.L2_GATEWAY_KEY, this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public FilterResult applyEgressFilter(L2gateway l2Gateway, FederatedMappings federatedMappings,
+            PendingModificationCache<DataTreeModification<?>> pendingModifications,
+            DataTreeModification<L2gateway> dataTreeModification) {
+        if (isShadow(l2Gateway)) {
+            LOG.trace("Interface {} filtered out. Reason: shadow interface", l2Gateway.getName());
+            return FilterResult.DENY;
+        }
+
+        String tenantName = l2Gateway.getTenantId().getValue();
+        if (!federatedMappings.containsProducerTenantId(tenantName)) {
+            LOG.trace("Interface {} filtered out. Reason: tenant {} not federated", l2Gateway.getName(),
+                    tenantName);
+            return FilterResult.DENY;
+        }
+
+        return FilterResult.ACCEPT;
+    }
+
+    @Override
+    public FilterResult applyIngressFilter(String listenerKey, Neutron neutron) {
+        return FilterResult.ACCEPT;
+    }
+
+    private boolean isShadow(L2gateway l2Gateway) {
+        L2gwShadowProperties l2ShadowProperties = l2Gateway.getAugmentation(L2gwShadowProperties.class);
+        return l2ShadowProperties != null && Boolean.TRUE.equals(l2ShadowProperties.isShadow());
+    }
+
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/filters/FederationTopologyHwvtepNodeFilter.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/filters/FederationTopologyHwvtepNodeFilter.java
new file mode 100644 (file)
index 0000000..abe85b5
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.filters;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.netvirt.federation.plugin.FederatedMappings;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.netvirt.federation.plugin.PendingModificationCache;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.TopologyNodeShadowProperties;
+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.network.topology.topology.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationTopologyHwvtepNodeFilter implements FederationPluginFilter<Node, NetworkTopology> {
+    private static final Logger LOG = LoggerFactory.getLogger(FederationTopologyHwvtepNodeFilter.class);
+
+    @Inject
+    public FederationTopologyHwvtepNodeFilter() {
+        FederationPluginFilterRegistry.registerFilter(FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_CONFIG_KEY,
+                this);
+        FederationPluginFilterRegistry.registerFilter(FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_OPER_KEY,
+                this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public FilterResult applyEgressFilter(Node node, FederatedMappings federatedMappings,
+            PendingModificationCache<DataTreeModification<?>> pendingModifications,
+            DataTreeModification<Node> dataTreeModification) {
+        String nodeName = node.getNodeId().getValue();
+        if (isShadow(node)) {
+            LOG.trace("Node {} filtered out. Reason: shadow node", nodeName);
+            return FilterResult.DENY;
+        }
+
+//        if (nodeName.contains(ITMConstants.BRIDGE_URI_PREFIX)
+//                && !nodeName.contains(FederationPluginConstants.INTEGRATION_BRIDGE_PREFIX)) {
+//            LOG.trace("Node {} filtered out. Reason: bridge that is not integration bridge", nodeName);
+//            return FilterResult.DENY;
+//        }
+
+        return FilterResult.ACCEPT;
+    }
+
+    @Override
+    public FilterResult applyIngressFilter(String listenerKey, NetworkTopology topology) {
+        return FilterResult.ACCEPT;
+    }
+
+    private boolean isShadow(Node node) {
+        TopologyNodeShadowProperties nodeShadowProperties = node.getAugmentation(TopologyNodeShadowProperties.class);
+        return nodeShadowProperties != null && Boolean.TRUE.equals(nodeShadowProperties.isShadow());
+    }
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationL2GatewayConnectionIdentifier.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationL2GatewayConnectionIdentifier.java
new file mode 100644 (file)
index 0000000..0633f19
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.identifiers;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@Singleton
+public class FederationL2GatewayConnectionIdentifier
+        implements FederationPluginIdentifier<L2gatewayConnection, L2gatewayConnections, Neutron> {
+
+    @Inject
+    public FederationL2GatewayConnectionIdentifier() {
+        FederationPluginIdentifierRegistry.registerIdentifier(FederationPluginConstants.L2_GATEWAY_CONNECTION_KEY,
+                LogicalDatastoreType.CONFIGURATION, this);
+    }
+
+    @Override
+    public InstanceIdentifier<L2gatewayConnection> getInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class).child(L2gatewayConnections.class)
+                .child(L2gatewayConnection.class);
+    }
+
+    @Override
+    public InstanceIdentifier<L2gatewayConnections> getParentInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class).child(L2gatewayConnections.class);
+    }
+
+    @Override
+    public InstanceIdentifier<Neutron> getSubtreeInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class);
+    }
+
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationL2GatewayIdentifier.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationL2GatewayIdentifier.java
new file mode 100644 (file)
index 0000000..488817e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.identifiers;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.L2gateways;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gateway;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationL2GatewayIdentifier
+        implements FederationPluginIdentifier<L2gateway, L2gateways, Neutron> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FederationL2GatewayIdentifier.class);
+
+    @Inject
+    public FederationL2GatewayIdentifier() {
+        FederationPluginIdentifierRegistry.registerIdentifier(FederationPluginConstants.L2_GATEWAY_KEY,
+                LogicalDatastoreType.CONFIGURATION, this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public InstanceIdentifier<L2gateway> getInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class).child(L2gateways.class).child(L2gateway.class);
+    }
+
+    @Override
+    public InstanceIdentifier<L2gateways> getParentInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class).child(L2gateways.class);
+    }
+
+    @Override
+    public InstanceIdentifier<Neutron> getSubtreeInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class);
+    }
+
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationTopologyHwvtepNodeIdentifier.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/identifiers/FederationTopologyHwvtepNodeIdentifier.java
new file mode 100644 (file)
index 0000000..fcada65
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.identifiers;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+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.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.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationTopologyHwvtepNodeIdentifier
+        implements FederationPluginIdentifier<Node, Topology, NetworkTopology> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FederationTopologyHwvtepNodeIdentifier.class);
+
+    @Inject
+    public FederationTopologyHwvtepNodeIdentifier() {
+        FederationPluginIdentifierRegistry.registerIdentifier(
+                FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_CONFIG_KEY, LogicalDatastoreType.CONFIGURATION, this);
+        FederationPluginIdentifierRegistry.registerIdentifier(
+                FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_OPER_KEY, LogicalDatastoreType.OPERATIONAL, this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public InstanceIdentifier<Node> getInstanceIdentifier() {
+        InstanceIdentifier<Node> nodeId = InstanceIdentifier.create(NetworkTopology.class)
+                .child(Topology.class, FederationPluginConstants.HWVTEP_TOPOLOGY_KEY).child(Node.class);
+        LOG.info("InstanceId: {}", nodeId);
+        return nodeId;
+    }
+
+    @Override
+    public InstanceIdentifier<Topology> getParentInstanceIdentifier() {
+        return InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
+                FederationPluginConstants.HWVTEP_TOPOLOGY_KEY);
+    }
+
+    @Override
+    public InstanceIdentifier<NetworkTopology> getSubtreeInstanceIdentifier() {
+        return InstanceIdentifier.create(NetworkTopology.class);
+    }
+}
index 49c23f68bbfd6d00220a4e358ae5b687f777b247..7d2bd00e3f165313294f3a2b2886ffc57215d40a 100644 (file)
@@ -12,11 +12,8 @@ import javax.inject.Singleton;
 
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 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.TopologyId;
 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.yangtools.yang.binding.InstanceIdentifier;
 
@@ -34,13 +31,13 @@ public class FederationTopologyNodeIdentifier implements FederationPluginIdentif
     @Override
     public InstanceIdentifier<Node> getInstanceIdentifier() {
         return InstanceIdentifier.create(NetworkTopology.class)
-                .child(Topology.class, new TopologyKey(new TopologyId(new Uri("ovsdb:1")))).child(Node.class);
+                .child(Topology.class, FederationPluginConstants.OVSDB_TOPOLOGY_KEY).child(Node.class);
     }
 
     @Override
     public InstanceIdentifier<Topology> getParentInstanceIdentifier() {
         return InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
-                new TopologyKey(new TopologyId(new Uri("ovsdb:1"))));
+                FederationPluginConstants.OVSDB_TOPOLOGY_KEY);
     }
 
     @Override
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationL2GatewayConnectionTransformer.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationL2GatewayConnectionTransformer.java
new file mode 100644 (file)
index 0000000..8facb7b
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.transformers;
+
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.netvirt.federation.plugin.FederatedMappings;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.netvirt.federation.plugin.PendingModificationCache;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwConnectionShadowProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwConnectionShadowPropertiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnectionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnectionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.NeutronBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationL2GatewayConnectionTransformer
+        implements FederationPluginTransformer<L2gatewayConnection, Neutron> {
+    private static final Logger LOG = LoggerFactory.getLogger(FederationL2GatewayConnectionTransformer.class);
+
+    @Inject
+    public FederationL2GatewayConnectionTransformer() {
+        FederationPluginTransformerRegistry.registerTransformer(FederationPluginConstants.L2_GATEWAY_CONNECTION_KEY,
+                this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public Neutron applyEgressTransformation(L2gatewayConnection l2Gateway, FederatedMappings federatedMappings,
+            PendingModificationCache<DataTreeModification<?>> pendingModifications) {
+        String l2gwNetworkId = l2Gateway.getNetworkId().getValue();
+        String consumerL2gwNetworkName = federatedMappings.getConsumerNetworkId(l2gwNetworkId);
+        if (consumerL2gwNetworkName == null) {
+            LOG.debug("Failed to transform l2Gateway {}. No transformation found for l2Gateway instance {}",
+                    l2Gateway.getName(), consumerL2gwNetworkName);
+            return null;
+        }
+
+        String l2gwTenantId = l2Gateway.getTenantId().getValue();
+        String consumerL2gwTenantName = federatedMappings.getConsumerTenantId(l2gwTenantId);
+        L2gatewayConnectionBuilder l2gwBuilder = new L2gatewayConnectionBuilder(l2Gateway);
+        l2gwBuilder.setTenantId(new Uuid(consumerL2gwTenantName));
+        l2gwBuilder.setNetworkId(new Uuid(consumerL2gwNetworkName));
+        l2gwBuilder.addAugmentation(L2gwConnectionShadowProperties.class,
+                new L2gwConnectionShadowPropertiesBuilder().setShadow(true).build());
+        L2gatewayConnections l2gatewayConnections = new L2gatewayConnectionsBuilder()
+                .setL2gatewayConnection(Collections.singletonList(l2gwBuilder.build())).build();
+        NeutronBuilder nb = new NeutronBuilder();
+        nb.setL2gatewayConnections(l2gatewayConnections);
+        return nb.build();
+    }
+
+    @Override
+    public Pair<InstanceIdentifier<L2gatewayConnection>, L2gatewayConnection> applyIngressTransformation(
+            Neutron neutron, ModificationType modificationType, int generationNumber,
+            String remoteIp) {
+        L2gatewayConnections l2Gws = neutron.getL2gatewayConnections();
+        if (l2Gws == null) {
+            LOG.error("L2 gateway connections is null");
+            return null;
+        }
+
+        List<L2gatewayConnection> l2GwsList = l2Gws.getL2gatewayConnection();
+        if (l2GwsList == null || l2GwsList.isEmpty()) {
+            LOG.error("L2 gateway connections is null");
+            return null;
+        }
+
+        L2gatewayConnection l2gw = l2GwsList.get(0);
+        L2gatewayConnectionBuilder l2gwBuilder = new L2gatewayConnectionBuilder(l2gw);
+        l2gwBuilder.addAugmentation(L2gwConnectionShadowProperties.class,
+                new L2gwConnectionShadowPropertiesBuilder(
+                        l2gwBuilder.getAugmentation(L2gwConnectionShadowProperties.class)).setShadow(true)
+                                .setGenerationNumber(generationNumber).setRemoteIp(remoteIp).build());
+        l2gw = l2gwBuilder.build();
+        return Pair.of(
+                InstanceIdentifier.create(Neutron.class).child(L2gatewayConnections.class)
+                .child(L2gatewayConnection.class, l2gw.getKey()), l2gw);
+    }
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationL2GatewayTransformer.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationL2GatewayTransformer.java
new file mode 100644 (file)
index 0000000..b22085f
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.transformers;
+
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.netvirt.federation.plugin.FederatedMappings;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.netvirt.federation.plugin.PendingModificationCache;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwShadowProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.L2gwShadowPropertiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.L2gateways;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.L2gatewaysBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gateway;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gatewayBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.NeutronBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationL2GatewayTransformer implements FederationPluginTransformer<L2gateway, Neutron> {
+    private static final Logger LOG = LoggerFactory.getLogger(FederationL2GatewayTransformer.class);
+
+    @Inject
+    public FederationL2GatewayTransformer() {
+        FederationPluginTransformerRegistry.registerTransformer(FederationPluginConstants.L2_GATEWAY_KEY, this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public Neutron applyEgressTransformation(L2gateway l2Gateway, FederatedMappings federatedMappings,
+            PendingModificationCache<DataTreeModification<?>> pendingModifications) {
+        String l2gwTenantName = l2Gateway.getTenantId().getValue();
+        String consumerL2gwTenantName = federatedMappings.getConsumerTenantId(l2gwTenantName);
+        if (consumerL2gwTenantName == null) {
+            LOG.debug("Failed to transform l2Gateway {}. No transformation found for l2Gateway instance {}",
+                    l2Gateway.getName(), consumerL2gwTenantName);
+            return null;
+        }
+
+        L2gatewayBuilder l2gwBuilder = new L2gatewayBuilder(l2Gateway);
+        l2gwBuilder.setTenantId(new Uuid(consumerL2gwTenantName));
+        l2gwBuilder.addAugmentation(L2gwShadowProperties.class,
+                new L2gwShadowPropertiesBuilder().setShadow(true).build());
+        return new NeutronBuilder()
+                .setL2gateways(
+                        new L2gatewaysBuilder().setL2gateway(Collections.singletonList(l2gwBuilder.build())).build())
+                .build();
+    }
+
+    @Override
+    public Pair<InstanceIdentifier<L2gateway>, L2gateway> applyIngressTransformation(Neutron neutron,
+            ModificationType modificationType, int generationNumber, String remoteIp) {
+        L2gateways l2Gws = neutron.getL2gateways();
+        if (l2Gws == null) {
+            LOG.error("no L2 gateways");
+            return null;
+        }
+
+        List<L2gateway> l2GwsList = l2Gws.getL2gateway();
+        if (l2GwsList == null || l2GwsList.isEmpty()) {
+            LOG.error("L2 gateway is empty");
+            return null;
+        }
+
+        L2gateway l2gw = l2GwsList.get(0);
+        L2gatewayBuilder l2gwBuilder = new L2gatewayBuilder(l2gw);
+        l2gwBuilder.addAugmentation(L2gwShadowProperties.class,
+                new L2gwShadowPropertiesBuilder(l2gwBuilder.getAugmentation(L2gwShadowProperties.class)).setShadow(true)
+                        .setGenerationNumber(generationNumber).setRemoteIp(remoteIp).build());
+        l2gw = l2gwBuilder.build();
+        return Pair.of(
+                InstanceIdentifier.create(Neutron.class).child(L2gateways.class).child(L2gateway.class, l2gw.getKey()),
+                l2gw);
+    }
+}
diff --git a/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationTopologyHwvtepNodeTransformer.java b/vpnservice/federation-plugin/impl/src/main/java/org/opendaylight/netvirt/federation/plugin/transformers/FederationTopologyHwvtepNodeTransformer.java
new file mode 100644 (file)
index 0000000..363b377
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.federation.plugin.transformers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.netvirt.federation.plugin.FederatedMappings;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
+import org.opendaylight.netvirt.federation.plugin.FederationPluginCounters;
+import org.opendaylight.netvirt.federation.plugin.PendingModificationCache;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.TopologyNodeShadowProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.TopologyNodeShadowPropertiesBuilder;
+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.HwvtepGlobalAugmentationBuilder;
+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.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.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacsBuilder;
+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.LocalUcastMacsBuilder;
+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.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.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.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
+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.TopologyBuilder;
+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.NodeBuilder;
+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.TerminationPointBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class FederationTopologyHwvtepNodeTransformer implements FederationPluginTransformer<Node, NetworkTopology> {
+    private static final Logger LOG = LoggerFactory.getLogger(FederationTopologyHwvtepNodeTransformer.class);
+
+    @Inject
+    public FederationTopologyHwvtepNodeTransformer() {
+        FederationPluginTransformerRegistry
+                .registerTransformer(FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_CONFIG_KEY, this);
+        FederationPluginTransformerRegistry.registerTransformer(FederationPluginConstants.TOPOLOGY_HWVTEP_NODE_OPER_KEY,
+                this);
+    }
+
+    @PostConstruct
+    public void init() {
+        LOG.info("{} start", getClass().getSimpleName());
+    }
+
+    @Override
+    public NetworkTopology applyEgressTransformation(Node node, FederatedMappings federatedMappings,
+            PendingModificationCache<DataTreeModification<?>> pendingModifications) {
+        TopologyBuilder topologyBuilder = new TopologyBuilder();
+        topologyBuilder.setKey(FederationPluginConstants.HWVTEP_TOPOLOGY_KEY);
+        String nodeName = node.getNodeId().getValue();
+        NodeBuilder nodeBuilder;
+        FederationPluginCounters.hwvtep_egress_apply_transformation.inc();
+        LOG.debug("applying egress transformation to node {}", nodeName);
+
+        if (nodeName.contains(FederationPluginConstants.HWVTEP_PHYSICAL_SWITCH)) {
+            nodeBuilder = getNodeBuilderForEgressTransformationOnPhysicalSwitchNode(node, federatedMappings);
+        } else {
+            nodeBuilder = getNodeBuilderForEgressTransformationOnPhysicalSwitchParentNode(node, federatedMappings);
+        }
+
+        nodeBuilder.addAugmentation(TopologyNodeShadowProperties.class,
+                new TopologyNodeShadowPropertiesBuilder().setShadow(true).build());
+        topologyBuilder.setNode(Collections.singletonList(nodeBuilder.build()));
+        return new NetworkTopologyBuilder().setTopology(Collections.singletonList(topologyBuilder.build())).build();
+    }
+
+    @Override
+    public Pair<InstanceIdentifier<Node>, Node> applyIngressTransformation(NetworkTopology networkTopology,
+            ModificationType modificationType, int generationNumber, String remoteIp) {
+        List<Topology> topologyList = networkTopology.getTopology();
+        FederationPluginCounters.hwvtep_ingress_apply_transformation.inc();
+        if (topologyList == null || topologyList.isEmpty()) {
+            LOG.error("Topology network is empty");
+            return null;
+        }
+
+        Topology topology = topologyList.get(0);
+        List<Node> nodeList = topology.getNode();
+        if (nodeList == null || nodeList.isEmpty()) {
+            LOG.error("Topology node is empty");
+            return null;
+        }
+
+        Node node = nodeList.get(0);
+        LOG.debug("applying ingress transformation to node {}", node);
+        NodeBuilder nodeBuilder = new NodeBuilder(node);
+        nodeBuilder.addAugmentation(TopologyNodeShadowProperties.class,
+                new TopologyNodeShadowPropertiesBuilder(nodeBuilder.getAugmentation(TopologyNodeShadowProperties.class))
+                        .setShadow(true).setGenerationNumber(generationNumber).setRemoteIp(remoteIp).build());
+        return Pair.of(InstanceIdentifier.create(NetworkTopology.class)
+                .child(Topology.class, FederationPluginConstants.HWVTEP_TOPOLOGY_KEY).child(Node.class, node.getKey()),
+                nodeBuilder.build());
+    }
+
+    private NodeBuilder getNodeBuilderForEgressTransformationOnPhysicalSwitchParentNode(Node node,
+            FederatedMappings federatedMappings) {
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setKey(node.getKey());
+        nodeBuilder.setNodeId(node.getNodeId());
+        // TODO - replace logical switch id in:
+        // hwvtep:logical-switches - done
+        // hwvtep:remote-mcast-macs/logical-switch-ref  - done
+        // hwvtep:local-mcast-macs/logical-switch-ref  - done
+        // hwvtep:remote-ucast-macs  - done
+        HwvtepGlobalAugmentation originalGlobalAug = node.getAugmentation(HwvtepGlobalAugmentation.class);
+        if (originalGlobalAug != null) {
+            List<LogicalSwitches> federatedLogicalSwitches = copyFederatedLogicalSwitches(originalGlobalAug,
+                    federatedMappings);
+            HwvtepGlobalAugmentationBuilder hgab = new HwvtepGlobalAugmentationBuilder();
+            List<RemoteUcastMacs> federatedRemoteUcastMacs = copyRemoteUcastMacs(originalGlobalAug, federatedMappings);
+            hgab.setRemoteUcastMacs(federatedRemoteUcastMacs);
+            List<RemoteMcastMacs> federatedRemoteMcastMacs = copyRemoteMcastMacs(originalGlobalAug, federatedMappings);
+            hgab.setRemoteMcastMacs(federatedRemoteMcastMacs);
+            List<LocalUcastMacs> federatedLocalUcastMacs = copyLocalUcastMacs(originalGlobalAug, federatedMappings);
+            hgab.setLocalUcastMacs(federatedLocalUcastMacs);
+            List<LocalMcastMacs> federatedLocalMcastMacs = copyLocalMcastMacs(originalGlobalAug, federatedMappings);
+            hgab.setLocalMcastMacs(federatedLocalMcastMacs);
+
+            hgab.setConnectionInfo(originalGlobalAug.getConnectionInfo());
+            hgab.setLogicalSwitches(federatedLogicalSwitches);
+            nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, hgab.build());
+        }
+
+        PhysicalSwitchAugmentation originalPhysicalAug = node.getAugmentation(PhysicalSwitchAugmentation.class);
+        if (originalPhysicalAug != null) {
+            PhysicalSwitchAugmentationBuilder psa = new PhysicalSwitchAugmentationBuilder(originalPhysicalAug);
+            nodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, psa.build());
+        }
+
+        nodeBuilder.setTerminationPoint(node.getTerminationPoint());
+        return nodeBuilder;
+    }
+
+    private List<LocalUcastMacs> copyLocalUcastMacs(HwvtepGlobalAugmentation originalGlobalAug,
+            FederatedMappings federatedMappings) {
+        List<LocalUcastMacs> ret = new ArrayList<>();
+        if (originalGlobalAug.getLocalUcastMacs() != null) {
+            for (LocalUcastMacs localMac : originalGlobalAug.getLocalUcastMacs()) {
+                LogicalSwitchesKey lsKey = localMac.getLogicalSwitchRef().getValue().firstKeyOf(LogicalSwitches.class);
+                String consumerNetworkId = federatedMappings.getConsumerNetworkId(lsKey.getHwvtepNodeName().getValue());
+                if (consumerNetworkId != null) {
+                    LocalUcastMacsBuilder lumb = new LocalUcastMacsBuilder(localMac);
+                    InstanceIdentifier<LogicalSwitches> federatedLogicalSwitchRef =
+                            federateLogicalSwitchRef(localMac.getLogicalSwitchRef(), consumerNetworkId);
+                    lumb.setLogicalSwitchRef(new HwvtepLogicalSwitchRef(federatedLogicalSwitchRef));
+                    ret.add(lumb.build());
+                }
+            }
+        }
+        return ret;
+    }
+
+    private List<LocalMcastMacs> copyLocalMcastMacs(HwvtepGlobalAugmentation originalGlobalAug,
+            FederatedMappings federatedMappings) {
+        List<LocalMcastMacs> ret = new ArrayList<>();
+        if (originalGlobalAug.getLocalUcastMacs() != null) {
+            for (LocalMcastMacs localMac : originalGlobalAug.getLocalMcastMacs()) {
+                LogicalSwitchesKey lsKey = localMac.getLogicalSwitchRef().getValue().firstKeyOf(LogicalSwitches.class);
+                String consumerNetworkId = federatedMappings.getConsumerNetworkId(lsKey.getHwvtepNodeName().getValue());
+                if (consumerNetworkId != null) {
+                    LocalMcastMacsBuilder lumb = new LocalMcastMacsBuilder(localMac);
+                    InstanceIdentifier<LogicalSwitches> federatedLogicalSwitchRef =
+                            federateLogicalSwitchRef(localMac.getLogicalSwitchRef(), consumerNetworkId);
+                    lumb.setLogicalSwitchRef(new HwvtepLogicalSwitchRef(federatedLogicalSwitchRef));
+                    ret.add(lumb.build());
+                }
+            }
+        }
+        return ret;
+    }
+
+    private List<RemoteUcastMacs> copyRemoteUcastMacs(HwvtepGlobalAugmentation originalGlobalAug,
+            FederatedMappings federatedMappings) {
+        List<RemoteUcastMacs> ret = new ArrayList<>();
+        if (originalGlobalAug.getRemoteUcastMacs() != null) {
+            for (RemoteUcastMacs localMac : originalGlobalAug.getRemoteUcastMacs()) {
+                LogicalSwitchesKey lsKey = localMac.getLogicalSwitchRef().getValue().firstKeyOf(LogicalSwitches.class);
+                String consumerNetworkId = federatedMappings.getConsumerNetworkId(lsKey.getHwvtepNodeName().getValue());
+                if (consumerNetworkId != null) {
+                    RemoteUcastMacsBuilder rumb = new RemoteUcastMacsBuilder(localMac);
+                    InstanceIdentifier<LogicalSwitches> federatedLogicalSwitchRef =
+                            federateLogicalSwitchRef(localMac.getLogicalSwitchRef(), consumerNetworkId);
+                    rumb.setLogicalSwitchRef(new HwvtepLogicalSwitchRef(federatedLogicalSwitchRef));
+                    ret.add(rumb.build());
+                }
+            }
+        }
+        return ret;
+    }
+
+    private List<RemoteMcastMacs> copyRemoteMcastMacs(HwvtepGlobalAugmentation originalGlobalAug,
+            FederatedMappings federatedMappings) {
+        List<RemoteMcastMacs> ret = new ArrayList<>();
+        if (originalGlobalAug.getRemoteMcastMacs() != null) {
+            for (RemoteMcastMacs remoteMac : originalGlobalAug.getRemoteMcastMacs()) {
+                LogicalSwitchesKey lsKey = remoteMac.getLogicalSwitchRef().getValue().firstKeyOf(LogicalSwitches.class);
+                String consumerNetworkId = federatedMappings.getConsumerNetworkId(lsKey.getHwvtepNodeName().getValue());
+                if (consumerNetworkId != null) {
+                    RemoteMcastMacsBuilder rumb = new RemoteMcastMacsBuilder(remoteMac);
+                    InstanceIdentifier<LogicalSwitches> federatedLogicalSwitchRef =
+                            federateLogicalSwitchRef(remoteMac.getLogicalSwitchRef(), consumerNetworkId);
+                    rumb.setLogicalSwitchRef(new HwvtepLogicalSwitchRef(federatedLogicalSwitchRef));
+                    ret.add(rumb.build());
+                }
+            }
+        }
+        return ret;
+    }
+
+    private List<LogicalSwitches> copyFederatedLogicalSwitches(HwvtepGlobalAugmentation hwvtepNodeAugmentation,
+            FederatedMappings federatedMappings) {
+        List<LogicalSwitches> logicalSwitches = hwvtepNodeAugmentation.getLogicalSwitches();
+        List<LogicalSwitches> federatedLogicalSwitches = new ArrayList<>();
+        if (logicalSwitches != null) {
+            for (LogicalSwitches ls : logicalSwitches) {
+                HwvtepNodeName hwvtepNodeName = ls.getKey().getHwvtepNodeName();
+                String consumerNetworkId = federatedMappings.getConsumerNetworkId(hwvtepNodeName.getValue());
+                if (consumerNetworkId != null) {
+                    LogicalSwitchesBuilder lsb = new LogicalSwitchesBuilder(ls);
+                    lsb.setKey(new LogicalSwitchesKey(new HwvtepNodeName(consumerNetworkId)));
+                    federatedLogicalSwitches.add(lsb.build());
+                }
+            }
+        }
+        return federatedLogicalSwitches;
+    }
+
+    private NodeBuilder getNodeBuilderForEgressTransformationOnPhysicalSwitchNode(Node node,
+            FederatedMappings federatedMappings) {
+        NodeBuilder nodeBuilder = new NodeBuilder(node);
+        List<TerminationPoint> tps = node.getTerminationPoint();
+        List<TerminationPoint> federatedTps = new ArrayList<>();
+
+        // TODO - need to replace logical-switch-ref to use the name of the
+        // network of the remote site
+        // termination-point/hwvtep:vlan-bindings/logical-switch-ref
+        if (tps != null) {
+            for (TerminationPoint tp : tps) {
+                HwvtepPhysicalPortAugmentation portAug = tp.getAugmentation(HwvtepPhysicalPortAugmentation.class);
+                if (portAug != null) {
+                    List<VlanBindings> origVlanBindings = portAug.getVlanBindings();
+                    List<VlanBindings> federatedVlanBindings = new ArrayList<>();
+                    if (origVlanBindings != null) {
+                        for (VlanBindings vb : origVlanBindings) {
+                            LogicalSwitchesKey lsKey = vb.getLogicalSwitchRef().getValue()
+                                    .firstKeyOf(LogicalSwitches.class);
+                            String consumerNetworkId = federatedMappings
+                                    .getConsumerNetworkId(lsKey.getHwvtepNodeName().getValue());
+                            if (consumerNetworkId != null) {
+                                VlanBindingsBuilder vbb = new VlanBindingsBuilder(vb);
+                                InstanceIdentifier<LogicalSwitches> federatedLogicalSwitchRef =
+                                        federateLogicalSwitchRef(vb.getLogicalSwitchRef(), consumerNetworkId);
+                                vbb.setLogicalSwitchRef(new HwvtepLogicalSwitchRef(federatedLogicalSwitchRef));
+                                federatedVlanBindings.add(vbb.build());
+                            }
+                        }
+                        if (!federatedVlanBindings.isEmpty()) {
+                            TerminationPointBuilder tpb = new TerminationPointBuilder(tp);
+                            HwvtepPhysicalPortAugmentationBuilder hppab = new HwvtepPhysicalPortAugmentationBuilder(
+                                    portAug);
+                            hppab.setVlanBindings(federatedVlanBindings);
+                            tpb.addAugmentation(HwvtepPhysicalPortAugmentation.class, hppab.build());
+                            federatedTps.add(tpb.build());
+                        }
+                    }
+                }
+            }
+            nodeBuilder.setTerminationPoint(federatedTps);
+        }
+
+        return nodeBuilder;
+    }
+
+    private InstanceIdentifier<LogicalSwitches> federateLogicalSwitchRef(HwvtepLogicalSwitchRef logicalSwitchRef,
+            String consumerNetworkId) {
+        NodeKey nodeKey = logicalSwitchRef.getValue().firstKeyOf(Node.class);
+        InstanceIdentifier<LogicalSwitches> federatedLogicalSwitchRef =
+                InstanceIdentifier.create(NetworkTopology.class)
+                .child(Topology.class, FederationPluginConstants.HWVTEP_TOPOLOGY_KEY)
+                .child(Node.class, nodeKey).augmentation(HwvtepGlobalAugmentation.class)
+                .child(LogicalSwitches.class,
+                        new LogicalSwitchesKey(new HwvtepNodeName(consumerNetworkId)));
+
+        return federatedLogicalSwitchRef;
+
+    }
+
+}
index a940baf0af5155583de3d070aaf34dfbbc3fe20a..b1129cfec88ec80a5f4e01937e1a0f0f77af678f 100644 (file)
@@ -22,17 +22,14 @@ import org.opendaylight.netvirt.federation.plugin.FederatedMappings;
 import org.opendaylight.netvirt.federation.plugin.FederationPluginConstants;
 import org.opendaylight.netvirt.federation.plugin.FederationPluginUtils;
 import org.opendaylight.netvirt.federation.plugin.PendingModificationCache;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.TopologyNodeShadowProperties;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.rev170219.TopologyNodeShadowPropertiesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
 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.NetworkTopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
 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.TopologyBuilder;
-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.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
@@ -55,7 +52,7 @@ public class FederationTopologyNodeTransformer implements FederationPluginTransf
     public NetworkTopology applyEgressTransformation(Node node, FederatedMappings federatedMappings,
             PendingModificationCache<DataTreeModification<?>> pendingModifications) {
         TopologyBuilder topologyBuilder = new TopologyBuilder();
-        topologyBuilder.setKey(new TopologyKey(new TopologyId(new Uri("ovsdb:1"))));
+        topologyBuilder.setKey(FederationPluginConstants.OVSDB_TOPOLOGY_KEY);
         String nodeName = node.getNodeId().getValue();
         NodeBuilder nodeBuilder;
         if (nodeName.contains(FederationPluginConstants.INTEGRATION_BRIDGE_PREFIX)) {
@@ -94,7 +91,7 @@ public class FederationTopologyNodeTransformer implements FederationPluginTransf
                                 nodeBuilder.getAugmentation(TopologyNodeShadowProperties.class)).setShadow(true)
                                         .setGenerationNumber(generationNumber).setRemoteIp(remoteIp).build());
         return Pair.of(InstanceIdentifier.create(NetworkTopology.class)
-                .child(Topology.class, new TopologyKey(new TopologyId(new Uri("ovsdb:1"))))
+                .child(Topology.class, FederationPluginConstants.OVSDB_TOPOLOGY_KEY)
                 .child(Node.class, node.getKey()), nodeBuilder.build());
     }
 
index 9f42acfa4ef3756b74bb64e5857a6070dd4baa66..f97421ffdb2ce4d8d0c8b2222de7ffa69f1dc8bc 100644 (file)
@@ -17,14 +17,12 @@ import static org.mockito.Mockito.when;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.Futures;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
-
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -52,21 +50,33 @@ import org.opendaylight.netvirt.federation.plugin.SubnetVpnAssociationManager;
 import org.opendaylight.netvirt.federation.plugin.creators.FederationElanInterfaceModificationCreator;
 import org.opendaylight.netvirt.federation.plugin.creators.FederationIetfInterfaceModificationCreator;
 import org.opendaylight.netvirt.federation.plugin.creators.FederationInventoryNodeModificationCreator;
+import org.opendaylight.netvirt.federation.plugin.creators.FederationL2GatewayConnectionModificationCreator;
+import org.opendaylight.netvirt.federation.plugin.creators.FederationL2GatewayModificationCreator;
+import org.opendaylight.netvirt.federation.plugin.creators.FederationTopologyHwvtepNodeModificationCreator;
 import org.opendaylight.netvirt.federation.plugin.creators.FederationTopologyNodeModificationCreator;
 import org.opendaylight.netvirt.federation.plugin.creators.FederationVpnInterfaceModificationCreator;
 import org.opendaylight.netvirt.federation.plugin.filters.FederationElanInterfaceFilter;
 import org.opendaylight.netvirt.federation.plugin.filters.FederationIetfInterfaceFilter;
 import org.opendaylight.netvirt.federation.plugin.filters.FederationInventoryNodeFilter;
+import org.opendaylight.netvirt.federation.plugin.filters.FederationL2GatewayConnectionFilter;
+import org.opendaylight.netvirt.federation.plugin.filters.FederationL2GatewayFilter;
+import org.opendaylight.netvirt.federation.plugin.filters.FederationTopologyHwvtepNodeFilter;
 import org.opendaylight.netvirt.federation.plugin.filters.FederationTopologyNodeFilter;
 import org.opendaylight.netvirt.federation.plugin.filters.FederationVpnInterfaceFilter;
 import org.opendaylight.netvirt.federation.plugin.identifiers.FederationElanInterfaceIdentifier;
 import org.opendaylight.netvirt.federation.plugin.identifiers.FederationIetfInterfaceIdentifier;
 import org.opendaylight.netvirt.federation.plugin.identifiers.FederationInventoryNodeIdentifier;
+import org.opendaylight.netvirt.federation.plugin.identifiers.FederationL2GatewayConnectionIdentifier;
+import org.opendaylight.netvirt.federation.plugin.identifiers.FederationL2GatewayIdentifier;
+import org.opendaylight.netvirt.federation.plugin.identifiers.FederationTopologyHwvtepNodeIdentifier;
 import org.opendaylight.netvirt.federation.plugin.identifiers.FederationTopologyNodeIdentifier;
 import org.opendaylight.netvirt.federation.plugin.identifiers.FederationVpnInterfaceIdentifier;
 import org.opendaylight.netvirt.federation.plugin.transformers.FederationElanInterfaceTransformer;
 import org.opendaylight.netvirt.federation.plugin.transformers.FederationIetfInterfaceTransformer;
 import org.opendaylight.netvirt.federation.plugin.transformers.FederationInventoryNodeTransformer;
+import org.opendaylight.netvirt.federation.plugin.transformers.FederationL2GatewayConnectionTransformer;
+import org.opendaylight.netvirt.federation.plugin.transformers.FederationL2GatewayTransformer;
+import org.opendaylight.netvirt.federation.plugin.transformers.FederationTopologyHwvtepNodeTransformer;
 import org.opendaylight.netvirt.federation.plugin.transformers.FederationTopologyNodeTransformer;
 import org.opendaylight.netvirt.federation.plugin.transformers.FederationVpnInterfaceTransformer;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.federation.plugin.manager.rev170219.FederationGenerations;
@@ -140,6 +150,10 @@ public class AbstractEnd2EndTest {
         new FederationTopologyNodeFilter();
         new FederationTopologyNodeModificationCreator();
         new FederationTopologyNodeIdentifier();
+        new FederationTopologyHwvtepNodeTransformer();
+        new FederationTopologyHwvtepNodeFilter();
+        new FederationTopologyHwvtepNodeModificationCreator();
+        new FederationTopologyHwvtepNodeIdentifier();
         new FederationIetfInterfaceTransformer();
         new FederationIetfInterfaceFilter(dataBroker, elanService);
         new FederationIetfInterfaceModificationCreator();
@@ -148,6 +162,14 @@ public class AbstractEnd2EndTest {
         new FederationElanInterfaceFilter(dataBroker, elanService);
         new FederationElanInterfaceModificationCreator();
         new FederationElanInterfaceIdentifier();
+        new FederationL2GatewayTransformer();
+        new FederationL2GatewayFilter(dataBroker);
+        new FederationL2GatewayModificationCreator();
+        new FederationL2GatewayIdentifier();
+        new FederationL2GatewayConnectionTransformer();
+        new FederationL2GatewayConnectionFilter(dataBroker);
+        new FederationL2GatewayConnectionModificationCreator();
+        new FederationL2GatewayConnectionIdentifier();
         new FederationVpnInterfaceFilter(dataBroker, associationMgr);
         new FederationVpnInterfaceTransformer(associationMgr);
         new FederationVpnInterfaceModificationCreator();