Bug 5213 - Missing segmentation-id for physical networks 31/34231/1
authorMartin Sunal <msunal@cisco.com>
Tue, 26 Jan 2016 16:11:49 +0000 (17:11 +0100)
committerTomas Cechvala <tcechval@cisco.com>
Mon, 8 Feb 2016 08:52:20 +0000 (08:52 +0000)
segmentation-id is stored to DS if a neutron network is backed by physical network

Change-Id: Id7334fc0a088a32879396ce7f2e48cdb06d250dc
Signed-off-by: Tomas Cechvala <tcechval@cisco.com>
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactory.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java
neutron-mapper/src/main/yang/neutron-gbp-mapper.yang
neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/NeutronOvsdb.java
neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/ProviderPhysicalNetworkListener.java [new file with mode: 0644]

index 14b8b97fcc4c2203b1a369ec08fadddbb75abff8..e337409c87319fc9d63c8f03c75245952622e4a9 100644 (file)
@@ -11,7 +11,9 @@ package org.opendaylight.groupbasedpolicy.neutron.gbp.util;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.GbpByNeutronMappings;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.NeutronByGbpMappings;
@@ -20,18 +22,21 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gb
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ExternalGatewaysAsL3Endpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.PortsByEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ProviderPhysicalNetworksAsL2FloodDomains;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.l3.endpoints.ExternalGatewayAsL3Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.l3.endpoints.ExternalGatewayAsL3EndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.endpoints.PortByEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.endpoints.PortByEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-
 public class NeutronGbpIidFactory {
 
     public static InstanceIdentifier<EndpointByPort> endpointByPortIid(UniqueId portId) {
-        return InstanceIdentifier.builder(
-                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+        return InstanceIdentifier
+            .builder(
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
             .child(GbpByNeutronMappings.class)
             .child(EndpointsByPorts.class)
             .child(EndpointByPort.class, new EndpointByPortKey(portId))
@@ -39,8 +44,9 @@ public class NeutronGbpIidFactory {
     }
 
     public static InstanceIdentifier<PortByEndpoint> portByEndpointIid(L2BridgeDomainId l2BdId, MacAddress mac) {
-        return InstanceIdentifier.builder(
-                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+        return InstanceIdentifier
+            .builder(
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
             .child(NeutronByGbpMappings.class)
             .child(PortsByEndpoints.class)
             .child(PortByEndpoint.class, new PortByEndpointKey(l2BdId, mac))
@@ -49,12 +55,25 @@ public class NeutronGbpIidFactory {
 
     public static InstanceIdentifier<ExternalGatewayAsL3Endpoint> externalGatewayAsL3Endpoint(L3ContextId l3Context,
             IpAddress ipAddress) {
-        return InstanceIdentifier.builder(
-                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+        return InstanceIdentifier
+            .builder(
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
             .child(NeutronByGbpMappings.class)
             .child(ExternalGatewaysAsL3Endpoints.class)
             .child(ExternalGatewayAsL3Endpoint.class, new ExternalGatewayAsL3EndpointKey(ipAddress, l3Context))
             .build();
     }
 
+    public static InstanceIdentifier<ProviderPhysicalNetworkAsL2FloodDomain> providerPhysicalNetworkAsL2FloodDomainIid(
+            TenantId tenantId, L2FloodDomainId l2FdId) {
+        return InstanceIdentifier
+            .builder(
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+            .child(NeutronByGbpMappings.class)
+            .child(ProviderPhysicalNetworksAsL2FloodDomains.class)
+            .child(ProviderPhysicalNetworkAsL2FloodDomain.class,
+                    new ProviderPhysicalNetworkAsL2FloodDomainKey(l2FdId, tenantId))
+            .build();
+    }
+
 }
index a692884049a53330f7d594147d70b93f7a88a1e4..514dbef866055258874de9344f2b9ad929a3ad86 100644 (file)
@@ -15,7 +15,9 @@ import java.util.UUID;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.NeutronSecurityGroupAware;
@@ -35,6 +37,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMapping;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMappingBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
@@ -50,6 +54,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 
 public class NeutronNetworkAware implements INeutronNetworkAware {
@@ -129,6 +134,10 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
         if (network.getRouterExternal() != null && network.getRouterExternal() == true) {
             addEigEpgExternalWithContracts(tenantId, rwTx);
         }
+        if (!Strings.isNullOrEmpty(network.getProviderPhysicalNetwork())) {
+            String segmentationId = network.getProviderSegmentationID();
+            addProviderPhysicalNetworkMapping(tenantId, l2FdId, segmentationId, rwTx);
+        }
         DataStoreHelper.submitToDs(rwTx);
     }
 
@@ -173,6 +182,14 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
                 IidFactory.externalImplicitGroupIid(tenantId, eig.getId()), eig, true);
     }
 
+    private void addProviderPhysicalNetworkMapping(TenantId tenantId, L2FloodDomainId l2FdId, String segmentationId,
+            WriteTransaction wTx) {
+        ProviderPhysicalNetworkAsL2FloodDomain provNetAsL2Fd = new ProviderPhysicalNetworkAsL2FloodDomainBuilder()
+            .setTenantId(tenantId).setL2FloodDomainId(l2FdId).setSegmentationId(segmentationId).build();
+        wTx.put(LogicalDatastoreType.OPERATIONAL,
+                NeutronGbpIidFactory.providerPhysicalNetworkAsL2FloodDomainIid(tenantId, l2FdId), provNetAsL2Fd);
+    }
+
     /**
      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canUpdateNetwork(org.opendaylight.neutron.spi.NeutronNetwork,
      *      org.opendaylight.neutron.spi.NeutronNetwork)
index 5ba306a8345f1c4cc066993dfb09f3f4cf58b759..8f3adafb2e8c6c4c85fc31e525cdb25d3cd9650a 100644 (file)
@@ -51,6 +51,27 @@ module neutron-gbp-mapper {
                     uses gbp-endpoint:l3-key;
                 }
             }
+
+            container provider-physical-networks-as-l2-flood-domains {
+                list provider-physical-network-as-l2-flood-domain {
+                    key "tenant-id l2-flood-domain-id";
+                    leaf tenant-id {
+                        description "Tenant of L2 Flood Domain";
+                        type gbp-common:tenant-id;
+                    }
+                    leaf l2-flood-domain-id {
+                        description "The L2 Flood Domain ID";
+                        type gbp-common:l2-flood-domain-id;
+                    }
+                    leaf segmentation-id {
+                        mandatory true;
+                        description "An isolated segment on the physical network. The network-type
+                            attribute defines the segmentation model. For example, if network-type
+                            is vlan, this ID is a vlan identifier.";
+                        type string;
+                    }
+                }
+            }
         }
 
         container gbp-by-neutron-mappings {
index 4c6e72372d97dd1eb6466443823f37b0a8f3b85a..24d9c58e0988ce2d02ddb3d1986fb44df372fcf7 100644 (file)
@@ -17,9 +17,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.r
 public class NeutronOvsdb implements AutoCloseable {
 
     private final TerminationPointDataChangeListener tpListener;
-//    private final NodeDataChangeListener nodeListener;
     private final PortByEndpointListener portByEndpointListener;
     private final OvsdbNodeListener ovsdbNodeListener;
+    private final ProviderPhysicalNetworkListener provPhysNetListener;
 
     public NeutronOvsdb(DataBroker dataProvider, RpcProviderRegistry rpcProvider) {
         checkNotNull(dataProvider);
@@ -27,9 +27,9 @@ public class NeutronOvsdb implements AutoCloseable {
 
         EndpointService epService = rpcProvider.getRpcService(EndpointService.class);
         tpListener = new TerminationPointDataChangeListener(dataProvider, epService);
-//        nodeListener = new NodeDataChangeListener(dataProvider);
         ovsdbNodeListener = new OvsdbNodeListener(dataProvider);
         portByEndpointListener = new PortByEndpointListener(dataProvider);
+        provPhysNetListener = new ProviderPhysicalNetworkListener(dataProvider);
     }
 
     /**
@@ -38,9 +38,9 @@ public class NeutronOvsdb implements AutoCloseable {
     @Override
     public void close() throws Exception {
         tpListener.close();
-//        nodeListener.close();
         ovsdbNodeListener.close();
         portByEndpointListener.close();
+        provPhysNetListener.close();
     }
 
 }
diff --git a/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/ProviderPhysicalNetworkListener.java b/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/ProviderPhysicalNetworkListener.java
new file mode 100644 (file)
index 0000000..72233f3
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. 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.groupbasedpolicy.neutron.ovsdb;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.NeutronByGbpMappings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ProviderPhysicalNetworksAsL2FloodDomains;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.Segmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.SegmentationBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+
+public class ProviderPhysicalNetworkListener extends DataTreeChangeHandler<ProviderPhysicalNetworkAsL2FloodDomain> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ProviderPhysicalNetworkListener.class);
+
+    protected ProviderPhysicalNetworkListener(DataBroker dataProvider) {
+        super(dataProvider,
+                new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                        InstanceIdentifier.builder(Mappings.class)
+                            .child(NeutronByGbpMappings.class)
+                            .child(ProviderPhysicalNetworksAsL2FloodDomains.class)
+                            .child(ProviderPhysicalNetworkAsL2FloodDomain.class)
+                            .build()));
+    }
+
+    @Override
+    protected void onWrite(DataObjectModification<ProviderPhysicalNetworkAsL2FloodDomain> rootNode,
+            InstanceIdentifier<ProviderPhysicalNetworkAsL2FloodDomain> rootIdentifier) {
+        L2FloodDomainId l2FdId = rootNode.getDataAfter().getL2FloodDomainId();
+        TenantId tenantId = rootNode.getDataAfter().getTenantId();
+        String segmentationId = rootNode.getDataAfter().getSegmentationId();
+        augmentSegmentationToFloodDomain(tenantId, l2FdId, segmentationId);
+    }
+
+    @Override
+    protected void onDelete(DataObjectModification<ProviderPhysicalNetworkAsL2FloodDomain> rootNode,
+            InstanceIdentifier<ProviderPhysicalNetworkAsL2FloodDomain> rootIdentifier) {
+        L2FloodDomainId l2FdId = rootNode.getDataBefore().getL2FloodDomainId();
+        TenantId tenantId = rootNode.getDataBefore().getTenantId();
+        augmentSegmentationToFloodDomain(tenantId, l2FdId, null);
+    }
+
+    @Override
+    protected void onSubtreeModified(DataObjectModification<ProviderPhysicalNetworkAsL2FloodDomain> rootNode,
+            InstanceIdentifier<ProviderPhysicalNetworkAsL2FloodDomain> rootIdentifier) {
+        L2FloodDomainId l2FdId = rootNode.getDataAfter().getL2FloodDomainId();
+        TenantId tenantId = rootNode.getDataAfter().getTenantId();
+        String segmentationId = rootNode.getDataAfter().getSegmentationId();
+        augmentSegmentationToFloodDomain(tenantId, l2FdId, segmentationId);
+    }
+
+    private void augmentSegmentationToFloodDomain(TenantId tenantId, L2FloodDomainId l2FdId, String segmentationId) {
+        if (Strings.isNullOrEmpty(segmentationId)) {
+            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
+                    IidFactory.l2FloodDomainIid(tenantId, l2FdId).augmentation(Segmentation.class), rwTx);
+            DataStoreHelper.submitToDs(rwTx);
+        } else {
+            try {
+                Segmentation segmentation =
+                        new SegmentationBuilder().setSegmentationId(Integer.valueOf(segmentationId)).build();
+                WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+                wTx.merge(LogicalDatastoreType.CONFIGURATION,
+                        IidFactory.l2FloodDomainIid(tenantId, l2FdId).augmentation(Segmentation.class), segmentation);
+                DataStoreHelper.submitToDs(wTx);
+            } catch (NumberFormatException e) {
+                LOG.info("Segmentation ID of Neutron Provider Physical Network {} is not a number but is {}.",
+                        l2FdId.getValue(), segmentationId);
+            }
+        }
+    }
+
+}