Introducing new API in neutron-mapper 88/39388/4
authorTomas Cechvala <tcechval@cisco.com>
Mon, 23 May 2016 18:42:29 +0000 (20:42 +0200)
committerMartin Sunal <msunal@cisco.com>
Thu, 26 May 2016 07:13:39 +0000 (07:13 +0000)
New forwarding and endpoint model incorporated in
Neutron-Mapper component.

Former forwarding and endpoint API still supported.

Change-Id: Iaa851ec8ab0e7cbf1d04a45d2796b0b87f8e2b3e
Signed-off-by: Tomas Cechvala <tcechval@cisco.com>
13 files changed:
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/util/IidFactoryTest.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactory.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/MappingFactory.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/MappingUtils.java
neutron-mapper/src/main/yang/neutron-gbp-mapper.yang
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactoryTest.java

index f8bb98c2e6109b02d4d58e1ee4859d0ee236b26f..9faabd823a0f2539e103561468ee57c9b0985686 100644 (file)
@@ -22,8 +22,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocations;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocation;
@@ -41,6 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 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.NetworkDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
@@ -59,11 +58,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_l
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProviderKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.AddressType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.ContextType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenant;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenantKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomainKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
@@ -74,15 +81,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomainKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractKey;
@@ -122,6 +124,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecord;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 
 public class IidFactory {
 
@@ -255,29 +258,78 @@ public class IidFactory {
             .build();
     }
 
-    public static InstanceIdentifier<L2FloodDomain> l2FloodDomainIid(TenantId tenantId,
+    public static InstanceIdentifier<NetworkDomain> subnetIid(TenantId tenantId, NetworkDomainId id) {
+        NetworkDomainKey domainKey = new NetworkDomainKey(id, Subnet.class);
+        return createForwardingByTenantIidBuilder(tenantId).child(NetworkDomain.class, domainKey).build();
+    }
+
+    public static InstanceIdentifier<ForwardingContext> l2FloodDomainIid(TenantId tenantId, ContextId id) {
+        ForwardingContextKey domainKey = new ForwardingContextKey(id, L2FloodDomain.class);
+        return createForwardingByTenantIidBuilder(tenantId).child(ForwardingContext.class, domainKey).build();
+    }
+
+    public static InstanceIdentifier<ForwardingContext> l2BridgeDomainIid(TenantId tenantId, ContextId id) {
+        ForwardingContextKey domainKey = new ForwardingContextKey(id, L2BridgeDomain.class);
+        return createForwardingByTenantIidBuilder(tenantId).child(ForwardingContext.class, domainKey).build();
+    }
+
+    public static InstanceIdentifier<ForwardingContext> l3ContextIid(TenantId tenantId, ContextId id) {
+        ForwardingContextKey domainKey = new ForwardingContextKey(id, L3Context.class);
+        return createForwardingByTenantIidBuilder(tenantId).child(ForwardingContext.class, domainKey).build();
+    }
+
+    private static InstanceIdentifierBuilder<ForwardingByTenant> createForwardingByTenantIidBuilder(TenantId tenantId) {
+        return InstanceIdentifier.builder(Forwarding.class).child(ForwardingByTenant.class,
+                new ForwardingByTenantKey(tenantId));
+    }
+
+    @Deprecated
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain> l2FloodDomainIid(TenantId tenantId,
             L2FloodDomainId l2FloodDomainId) {
         return InstanceIdentifier.builder(Tenants.class)
             .child(Tenant.class, new TenantKey(tenantId))
-            .child(ForwardingContext.class)
-            .child(L2FloodDomain.class, new L2FloodDomainKey(l2FloodDomainId))
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext.class)
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain.class, new L2FloodDomainKey(l2FloodDomainId))
             .build();
     }
 
-    public static InstanceIdentifier<L2BridgeDomain> l2BridgeDomainIid(TenantId tenantId,
+    @Deprecated
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain> l2BridgeDomainIid(TenantId tenantId,
             L2BridgeDomainId l2BridgeDomainId) {
         return InstanceIdentifier.builder(Tenants.class)
             .child(Tenant.class, new TenantKey(tenantId))
-            .child(ForwardingContext.class)
-            .child(L2BridgeDomain.class, new L2BridgeDomainKey(l2BridgeDomainId))
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext.class)
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain.class, new L2BridgeDomainKey(l2BridgeDomainId))
+            .build();
+    }
+
+    @Deprecated
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context> l3ContextIid(TenantId tenantId, L3ContextId l3ContextId) {
+        return InstanceIdentifier.builder(Tenants.class)
+            .child(Tenant.class, new TenantKey(tenantId))
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext.class)
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context.class, new L3ContextKey(l3ContextId))
             .build();
     }
 
-    public static InstanceIdentifier<L3Context> l3ContextIid(TenantId tenantId, L3ContextId l3ContextId) {
+    @Deprecated
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet> subnetIid(
+            TenantId tenantId, SubnetId subnetId) {
         return InstanceIdentifier.builder(Tenants.class)
             .child(Tenant.class, new TenantKey(tenantId))
-            .child(ForwardingContext.class)
-            .child(L3Context.class, new L3ContextKey(l3ContextId))
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext.class)
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet.class,
+                    new SubnetKey(subnetId))
+            .build();
+    }
+
+    @Deprecated
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet> subnetWildcardIid(
+            TenantId tenantId) {
+        return InstanceIdentifier.builder(Tenants.class)
+            .child(Tenant.class, new TenantKey(tenantId))
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext.class)
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet.class)
             .build();
     }
 
@@ -317,22 +369,6 @@ public class IidFactory {
         return ENDPOINTS_IID;
     }
 
-    public static InstanceIdentifier<Subnet> subnetIid(TenantId tenantId, SubnetId subnetId) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(ForwardingContext.class)
-            .child(Subnet.class, new SubnetKey(subnetId))
-            .build();
-    }
-
-    public static InstanceIdentifier<Subnet> subnetWildcardIid(TenantId tenantId) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(ForwardingContext.class)
-            .child(Subnet.class)
-            .build();
-    }
-
     public static InstanceIdentifier<FollowedEndpointGroup> followedEndpointgroupIid(RendererName rendererName,
             TenantId tenantId, EndpointGroupId epgId) {
         return InstanceIdentifier.builder(Renderers.class)
index a168b8fc2f08c5a3f4f0ce4454a4a99471744f17..8e3a656bb1ee026ab2dc38991a3ec25cad4a36dc 100755 (executable)
@@ -13,6 +13,7 @@ import static org.mockito.Mockito.mock;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mockito;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
@@ -38,11 +39,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 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.NetworkDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
 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.endpoint.rev140421.Endpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
@@ -51,6 +54,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenant;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ActionDefinition;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
@@ -220,6 +226,14 @@ public class IidFactoryTest {
 
     @Test
     public void testL2FloodDomainIid() {
+        ContextId id = mock(ContextId.class);
+        InstanceIdentifier<ForwardingContext> identifier = IidFactory.l2FloodDomainIid(tenantId, id);
+        Assert.assertEquals(id, InstanceIdentifier.keyOf(identifier).getContextId());
+        Assert.assertEquals(tenantId, identifier.firstKeyOf(ForwardingByTenant.class).getTenantId());
+    }
+
+    @Test
+    public void testL2FloodDomainIid_tenantApi() {
         L2FloodDomainId l2FloodDomainId = mock(L2FloodDomainId.class);
         InstanceIdentifier<L2FloodDomain> identifier = IidFactory.l2FloodDomainIid(tenantId, l2FloodDomainId);
         Assert.assertEquals(l2FloodDomainId, InstanceIdentifier.keyOf(identifier).getId());
@@ -228,6 +242,14 @@ public class IidFactoryTest {
 
     @Test
     public void testL2BridgeDomainIid() {
+        ContextId id = mock(ContextId.class);
+        InstanceIdentifier<ForwardingContext> identifier = IidFactory.l2BridgeDomainIid(tenantId, id);
+        Assert.assertEquals(id, InstanceIdentifier.keyOf(identifier).getContextId());
+        Assert.assertEquals(tenantId, identifier.firstKeyOf(ForwardingByTenant.class).getTenantId());
+    }
+
+    @Test
+    public void testL2BridgeDomainIid_tenantApi() {
         L2BridgeDomainId l2BridgeDomainId = mock(L2BridgeDomainId.class);
         InstanceIdentifier<L2BridgeDomain> identifier = IidFactory.l2BridgeDomainIid(tenantId, l2BridgeDomainId);
         Assert.assertEquals(l2BridgeDomainId, InstanceIdentifier.keyOf(identifier).getId());
@@ -236,6 +258,14 @@ public class IidFactoryTest {
 
     @Test
     public void testL3ContextIid() {
+        ContextId id = mock(ContextId.class);
+        InstanceIdentifier<ForwardingContext> identifier = IidFactory.l3ContextIid(tenantId, id);
+        Assert.assertEquals(id, InstanceIdentifier.keyOf(identifier).getContextId());
+        Assert.assertEquals(tenantId, identifier.firstKeyOf(ForwardingByTenant.class).getTenantId());
+    }
+
+    @Test
+    public void testL3ContextIid_tenantApi() {
         L3ContextId l3ContextId = mock(L3ContextId.class);
         InstanceIdentifier<L3Context> identifier = IidFactory.l3ContextIid(tenantId, l3ContextId);
         Assert.assertEquals(l3ContextId, InstanceIdentifier.keyOf(identifier).getId());
@@ -287,6 +317,14 @@ public class IidFactoryTest {
 
     @Test
     public void testSubnetIid() {
+        NetworkDomainId id = mock(NetworkDomainId.class);
+        InstanceIdentifier<NetworkDomain> identifier = IidFactory.subnetIid(tenantId, id);
+        Assert.assertEquals(tenantId, identifier.firstKeyOf(ForwardingByTenant.class).getTenantId());
+        Assert.assertEquals(id, identifier.firstKeyOf(NetworkDomain.class).getNetworkDomainId());
+    }
+
+    @Test
+    public void testSubnetIid_tenantApi() {
         SubnetId subnetId = mock(SubnetId.class);
         InstanceIdentifier<Subnet> identifier = IidFactory.subnetIid(tenantId, subnetId);
         Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId());
index e337409c87319fc9d63c8f03c75245952622e4a9..c8aaaa6df2cb3daaa27a2b05de8de955ac52c23f 100644 (file)
@@ -9,30 +9,54 @@
 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.inet.types.rev100924.IpPrefix;
 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.ContextId;
 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.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.ContextType;
 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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.BaseEndpointsByPorts;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.EndpointsByPorts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPort;
 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.ExternalGatewaysAsEndpoints;
 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.PortsByBaseEndpoints;
 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.ProviderNetworksAsL2FloodDomains;
 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.endpoints.ExternalGatewayAsEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.endpoints.ExternalGatewayAsEndpointKey;
 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.base.endpoints.PortByBaseEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.base.endpoints.PortByBaseEndpointKey;
 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.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.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.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public class NeutronGbpIidFactory {
 
+    public static InstanceIdentifier<BaseEndpointByPort> baseEndpointByPortIid(UniqueId portId) {
+        return InstanceIdentifier.builder(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+            .child(GbpByNeutronMappings.class)
+            .child(BaseEndpointsByPorts.class)
+            .child(BaseEndpointByPort.class, new BaseEndpointByPortKey(portId))
+            .build();
+    }
+
+    @Deprecated
     public static InstanceIdentifier<EndpointByPort> endpointByPortIid(UniqueId portId) {
         return InstanceIdentifier
             .builder(
@@ -43,6 +67,16 @@ public class NeutronGbpIidFactory {
             .build();
     }
 
+    public static InstanceIdentifier<PortByBaseEndpoint> portByBaseEndpointIid(PortByBaseEndpointKey baseEpkey) {
+        return InstanceIdentifier.builder(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+            .child(NeutronByGbpMappings.class)
+            .child(PortsByBaseEndpoints.class)
+            .child(PortByBaseEndpoint.class, baseEpkey)
+            .build();
+    }
+
+    @Deprecated
     public static InstanceIdentifier<PortByEndpoint> portByEndpointIid(L2BridgeDomainId l2BdId, MacAddress mac) {
         return InstanceIdentifier
             .builder(
@@ -53,6 +87,22 @@ public class NeutronGbpIidFactory {
             .build();
     }
 
+    public static InstanceIdentifier<ExternalGatewayAsEndpoint> externalGatewayAsEndpoint(ContextId contextId,
+            IpPrefix ipPrefix, Class<? extends ContextType> contextType) {
+        ExternalGatewayAsEndpointKey key = new ExternalGatewayAsEndpointKey(
+                new String(ipPrefix.getValue()),
+                IpPrefixType.class,
+                contextId,
+                contextType);
+        return InstanceIdentifier.builder(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+            .child(NeutronByGbpMappings.class)
+            .child(ExternalGatewaysAsEndpoints.class)
+            .child(ExternalGatewayAsEndpoint.class, key)
+            .build();
+    }
+
+    @Deprecated
     public static InstanceIdentifier<ExternalGatewayAsL3Endpoint> externalGatewayAsL3Endpoint(L3ContextId l3Context,
             IpAddress ipAddress) {
         return InstanceIdentifier
@@ -65,15 +115,25 @@ public class NeutronGbpIidFactory {
     }
 
     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)
+            TenantId tenantId, ContextId domainId) {
+        return InstanceIdentifier.builder(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
             .child(NeutronByGbpMappings.class)
-            .child(ProviderPhysicalNetworksAsL2FloodDomains.class)
+            .child(ProviderNetworksAsL2FloodDomains.class)
             .child(ProviderPhysicalNetworkAsL2FloodDomain.class,
-                    new ProviderPhysicalNetworkAsL2FloodDomainKey(l2FdId, tenantId))
+                    new ProviderPhysicalNetworkAsL2FloodDomainKey(domainId, tenantId))
             .build();
     }
 
+    @Deprecated
+    public static InstanceIdentifier<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> 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(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.class,
+                    new 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(l2FdId, tenantId))
+            .build();
+    }
 }
index bc15b4045ed43e009efdfda438931a0af4211684..25fe227b0fb9fccb00087cc02a7c3bd0aff37978 100644 (file)
@@ -17,18 +17,30 @@ import javax.annotation.Nullable;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnreg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnregBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterL3PrefixEndpointInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterL3PrefixEndpointInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3Gateways;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3GatewaysBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,12 +52,57 @@ public class EndpointRegistrator {
 
     private static final Logger LOG = LoggerFactory.getLogger(EndpointRegistrator.class);
     private final EndpointService epService;
+    private final BaseEndpointService baseEpService;
 
-    public EndpointRegistrator(EndpointService epService) {
+    public EndpointRegistrator(EndpointService epService, BaseEndpointService baseEpService) {
         this.epService = Preconditions.checkNotNull(epService);
+        this.baseEpService = Preconditions.checkNotNull(baseEpService);
     }
 
-    public boolean registerEndpoint(RegisterEndpointInput regEndpointInput) {
+    public boolean registerEndpoint(AddressEndpointReg regEndpointInput) {
+        RegisterEndpointInput regBaseEpInput = new RegisterEndpointInputBuilder().setAddressEndpointReg(
+                ImmutableList.<AddressEndpointReg>of(regEndpointInput))
+            .build();
+        return registerEndpoint(regBaseEpInput);
+    }
+
+    public boolean registerEndpoint(RegisterEndpointInput regBaseEpInput) {
+        try {
+            RpcResult<Void> rpcResult = baseEpService.registerEndpoint(regBaseEpInput).get();
+            if (!rpcResult.isSuccessful()) {
+                LOG.warn("Illegal state - registerEndpoint was not successful. Input of RPC: {}", regBaseEpInput);
+                return false;
+            }
+            return true;
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Base endpoint registration failed. {}", regBaseEpInput, e);
+            return false;
+        }
+    }
+
+    public boolean unregisterEndpoint(AddressEndpointUnreg addrEpUnreg) {
+        UnregisterEndpointInput input = new UnregisterEndpointInputBuilder().setAddressEndpointUnreg(
+                ImmutableList.<AddressEndpointUnreg>of(new AddressEndpointUnregBuilder().setKey(addrEpUnreg.getKey())
+                    .build())).build();
+        return unregisterEndpoint(input);
+    }
+
+    public boolean unregisterEndpoint(UnregisterEndpointInput input) {
+        try {
+            RpcResult<Void> rpcResult = baseEpService.unregisterEndpoint(input).get();
+            if (!rpcResult.isSuccessful()) {
+                LOG.warn("Illegal state - unregisterEndpoint was not successful. Input of RPC: {}", input);
+                return false;
+            }
+            return true;
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("unregisterEndpoint failed. {}", input, e);
+            return false;
+        }
+    }
+
+    @Deprecated
+    public boolean registerEndpoint(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput regEndpointInput) {
         try {
             RpcResult<Void> rpcResult = epService.registerEndpoint(regEndpointInput).get();
             if (!rpcResult.isSuccessful()) {
@@ -59,7 +116,8 @@ public class EndpointRegistrator {
         }
     }
 
-    public boolean unregisterEndpoint(UnregisterEndpointInput unregEndpointInput) {
+    @Deprecated
+    public boolean unregisterEndpoint(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput unregEndpointInput) {
         try {
             RpcResult<Void> rpcResult = epService.unregisterEndpoint(unregEndpointInput).get();
             if (!rpcResult.isSuccessful()) {
@@ -73,6 +131,7 @@ public class EndpointRegistrator {
         }
     }
 
+    @Deprecated
     public boolean registerExternalL3PrefixEndpoint(IpPrefix ipPrefix, L3ContextId l3Context,
             @Nullable IpAddress gatewayIp, TenantId tenantId) {
         List<EndpointL3Gateways> l3Gateways = new ArrayList<EndpointL3Gateways>();
@@ -103,10 +162,11 @@ public class EndpointRegistrator {
         }
     }
 
-    public boolean registerL3EndpointAsExternalGateway(TenantId tenantId, IpAddress ipAddress, L3ContextId l3Context,
+    @Deprecated
+    public boolean registerL3EpAsExternalGateway(TenantId tenantId, IpAddress ipAddress, L3ContextId l3Context,
             NetworkDomainId networkContainment) {
-        RegisterEndpointInput registerEndpointInput =
-                new RegisterEndpointInputBuilder()
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput registerEndpointInput =
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder()
                     .setL3Address(ImmutableList
                         .of(new L3AddressBuilder().setL3Context(l3Context).setIpAddress(ipAddress).build()))
                     .setTenant(tenantId)
index ece7573cd272c1e04d7555b5294acf9babd63b0d..bfa6523e33a787bc515b3bd209f4a81de05f6145 100644 (file)
@@ -34,6 +34,7 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecu
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils;
 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.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionEgress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionIngress;
@@ -104,7 +105,8 @@ public class NeutronMapper implements DataTreeChangeListener<Neutron>, AutoClose
 
     public NeutronMapper(DataBroker dataProvider, RpcProviderRegistry rpcProvider) {
         EndpointService epService = rpcProvider.getRpcService(EndpointService.class);
-        EndpointRegistrator epRegistrator = new EndpointRegistrator(epService);
+        BaseEndpointService baseEpService = rpcProvider.getRpcService(BaseEndpointService.class);
+        EndpointRegistrator epRegistrator = new EndpointRegistrator(epService, baseEpService);
         networkAware = new NeutronNetworkAware(dataProvider);
         securityGroupAware = new NeutronSecurityGroupAware(dataProvider);
         securityRuleAware = new NeutronSecurityRuleAware(dataProvider);
index 64b5114d2ec31bf6dc29f0e732880f601dc720ff..5be9ff2004a17da77726ffeee5d3be51f24e4844 100644 (file)
@@ -8,23 +8,54 @@
 
 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
 
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPortBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPortBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.endpoints.ExternalGatewayAsEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.endpoints.ExternalGatewayAsEndpointBuilder;
 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.ExternalGatewayAsL3EndpointBuilder;
 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.base.endpoints.PortByBaseEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.base.endpoints.PortByBaseEndpointBuilder;
 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.PortByEndpointBuilder;
 
+
 public class MappingFactory {
 
     private MappingFactory() {
         throw new UnsupportedOperationException("cannot create an instance");
     }
 
+    public static BaseEndpointByPort createBaseEndpointByPort(AddressEndpointKey addrEpKey, UniqueId portId) {
+        return new BaseEndpointByPortBuilder().setPortId(portId)
+            .setAddressType(addrEpKey.getAddressType())
+            .setAddress(addrEpKey.getAddress())
+            .setContextType(addrEpKey.getContextType())
+            .setContextId(addrEpKey.getContextId())
+            .build();
+    }
+
+    public static PortByBaseEndpoint createPortByBaseEndpoint(UniqueId portId, AddressEndpointKey addrEpKey) {
+        return new PortByBaseEndpointBuilder().setPortId(portId)
+            .setAddressType(addrEpKey.getAddressType())
+            .setAddress(addrEpKey.getAddress())
+            .setContextType(addrEpKey.getContextType())
+            .setContextId(addrEpKey.getContextId())
+            .build();
+    }
+
+    @Deprecated
     public static EndpointByPort createEndpointByPort(EndpointKey epKey, UniqueId portId) {
         return new EndpointByPortBuilder().setPortId(portId)
             .setL2Context(epKey.getL2Context())
@@ -32,6 +63,7 @@ public class MappingFactory {
             .build();
     }
 
+    @Deprecated
     public static PortByEndpoint createPortByEndpoint(UniqueId portId, EndpointKey epKey) {
         return new PortByEndpointBuilder().setPortId(portId)
             .setL2Context(epKey.getL2Context())
@@ -39,6 +71,15 @@ public class MappingFactory {
             .build();
     }
 
+    public static ExternalGatewayAsEndpoint createEaxternalGatewayAsEndpoint(ContextId contextId, IpPrefix ipPrefix) {
+        return new ExternalGatewayAsEndpointBuilder().setAddress(new String(ipPrefix.getValue()))
+            .setAddressType(IpPrefixType.class)
+            .setContextId(contextId)
+            .setContextType(MappingUtils.L3_CONTEXT)
+            .build();
+    }
+
+    @Deprecated
     public static ExternalGatewayAsL3Endpoint createExternalGatewayByL3Endpoint(EndpointL3Key epL3Key) {
         return new ExternalGatewayAsL3EndpointBuilder().setKey(
                 new ExternalGatewayAsL3EndpointKey(epL3Key.getIpAddress(), epL3Key.getL3Context()))
index 1c0b349ca2fb012fb29411668673e999fb7119b6..045e9624c648d1982d9cf19eac0468c703482823 100644 (file)
@@ -19,16 +19,20 @@ 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.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 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.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.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.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.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;
@@ -61,12 +65,16 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
     public void onCreated(Network network, Neutron neutron) {
         LOG.trace("created network - {}", network);
         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
-        L2FloodDomainId l2FdId = new L2FloodDomainId(network.getUuid().getValue());
         TenantId tenantId = new TenantId(network.getTenantId().getValue());
         Name name = null;
+        ContextId ctxId = new ContextId(network.getUuid().getValue());
+        ForwardingContextBuilder fwdCtxBuilder = new ForwardingContextBuilder()
+        .setContextId(ctxId)
+        .setContextType(MappingUtils.L3_CONTEXT);
         if (!Strings.isNullOrEmpty(network.getName())) {
             try {
                 name = new Name(network.getName());
+                fwdCtxBuilder.setName(name);
             } catch (Exception e) {
                 name = null;
                 LOG.info("Name of Neutron Network '{}' is ignored.", network.getName());
@@ -74,16 +82,22 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
             }
         }
 
-        L3ContextId l3ContextId = new L3ContextId(l2FdId);
-        L3Context l3Context = new L3ContextBuilder().setId(l3ContextId).setName(name).build();
-        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3Context.getId()), l3Context, true);
+        ForwardingContext l3Context = fwdCtxBuilder.build();
 
-        L2BridgeDomainId l2BdId = new L2BridgeDomainId(l2FdId);
-        L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(l3Context.getId()).setName(name).build();
-        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
+        fwdCtxBuilder.setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
 
-        L2FloodDomain l2Fd = new L2FloodDomainBuilder().setId(l2FdId).setParent(l2BdId).setName(name).build();
-        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
+        .setParent(MappingUtils.createParent(ctxId, MappingUtils.L3_CONTEXT));
+        ForwardingContext l2Bd = fwdCtxBuilder.build();
+
+        fwdCtxBuilder.setContextType(MappingUtils.L2_FLOOD_DOMAIN).setParent(
+                MappingUtils.createParent(ctxId, MappingUtils.L2_BRDIGE_DOMAIN));
+        ForwardingContext l2Fd = fwdCtxBuilder.build();
+
+        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, ctxId), l3Context, true);
+        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, ctxId), l2Bd, true);
+        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, ctxId), l2Fd, true);
+
+        createTenantNetworkDomains(network, tenantId, rwTx);
 
         if (!tenantsWithRouterAndNetworkSeviceEntities.contains(tenantId)) {
             tenantsWithRouterAndNetworkSeviceEntities.add(tenantId);
@@ -97,15 +111,63 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.MGMT_CONTRACT_CONSUMER_SELECTOR, rwTx);
         }
         if (!NetworkUtils.getPhysicalNetwork(network).isEmpty() && !NetworkUtils.getSegmentationId(network).isEmpty()) {
-            addProviderPhysicalNetworkMapping(tenantId, l2FdId, NetworkUtils.getSegmentationId(network), rwTx);
+            addProviderPhysicalNetworkMapping(tenantId, ctxId, NetworkUtils.getSegmentationId(network), rwTx);
+            addProviderPhysicalNetworkMapping(tenantId, new L2FloodDomainId(ctxId.getValue()),
+                    NetworkUtils.getSegmentationId(network), rwTx);
         }
         DataStoreHelper.submitToDs(rwTx);
     }
 
+    @Deprecated
+    private void createTenantNetworkDomains(Network network, TenantId tenantId, ReadWriteTransaction rwTx) {
+        Name name;
+        L3ContextBuilder l3CtxBuilder = new L3ContextBuilder();
+        L2FloodDomainBuilder l2FdBuilder = new L2FloodDomainBuilder();
+        L2BridgeDomainBuilder l2BdBuilder = new L2BridgeDomainBuilder();
+        if (!Strings.isNullOrEmpty(network.getName())) {
+            try {
+                name = new Name(network.getName());
+                l3CtxBuilder.setName(name);
+                l2FdBuilder.setName(name);
+                l2BdBuilder.setName(name);
+            } catch (Exception e) {
+                name = null;
+                LOG.info("Name of Neutron Network '{}' is ignored.", network.getName());
+                LOG.debug("Name exception", e);
+            }
+        }
+        L2FloodDomainId l2FdId = new L2FloodDomainId(network.getUuid().getValue());
+        L3ContextId l3ContextId = new L3ContextId(l2FdId);
+        L3Context l3Context = l3CtxBuilder.setId(l3ContextId).build();
+        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3Context.getId()), l3Context, true);
+
+        L2BridgeDomainId l2BdId = new L2BridgeDomainId(l2FdId);
+        L2BridgeDomain l2Bd = l2BdBuilder.setId(l2BdId).setParent(l3Context.getId()).build();
+        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
+
+        L2FloodDomain l2Fd = l2FdBuilder.setId(l2FdId).setParent(l2BdId).build();
+        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
+    }
+
+    private void addProviderPhysicalNetworkMapping(TenantId tenantId, ContextId ctxId, String segmentationId,
+            WriteTransaction wTx) {
+        ProviderPhysicalNetworkAsL2FloodDomain provNetAsL2Fd = new ProviderPhysicalNetworkAsL2FloodDomainBuilder().setTenantId(
+                tenantId)
+            .setL2FloodDomainId(ctxId)
+            .setSegmentationId(segmentationId)
+            .build();
+        wTx.put(LogicalDatastoreType.OPERATIONAL,
+                NeutronGbpIidFactory.providerPhysicalNetworkAsL2FloodDomainIid(tenantId, ctxId), provNetAsL2Fd);
+    }
+
+    @Deprecated
     private void addProviderPhysicalNetworkMapping(TenantId tenantId, L2FloodDomainId l2FdId, String segmentationId,
             WriteTransaction wTx) {
-        ProviderPhysicalNetworkAsL2FloodDomain provNetAsL2Fd = new ProviderPhysicalNetworkAsL2FloodDomainBuilder()
-            .setTenantId(tenantId).setL2FloodDomainId(l2FdId).setSegmentationId(segmentationId).build();
+        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 provNetAsL2Fd = new 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().setTenantId(
+                tenantId)
+            .setL2FloodDomainId(new L2FloodDomainId(l2FdId.getValue()))
+            .setSegmentationId(segmentationId)
+            .build();
         wTx.put(LogicalDatastoreType.OPERATIONAL,
                 NeutronGbpIidFactory.providerPhysicalNetworkAsL2FloodDomainIid(tenantId, l2FdId), provNetAsL2Fd);
     }
@@ -121,6 +183,31 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
         LOG.trace("deleted network - {}", network);
         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
         TenantId tenantId = new TenantId(network.getTenantId().getValue());
+        ContextId id = new ContextId(network.getUuid().getValue());
+        Optional<ForwardingContext> potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.l2FloodDomainIid(tenantId, id), rwTx);
+        if (!potentialL2Fd.isPresent()) {
+            LOG.warn("Illegal state - l2-flood-domain {} does not exist.", id.getValue());
+            return;
+        }
+        Optional<ForwardingContext> potentialL2Bd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.l2BridgeDomainIid(tenantId, id), rwTx);
+        if (!potentialL2Bd.isPresent()) {
+            LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", id.getValue());
+            return;
+        }
+        Optional<ForwardingContext> potentialL3Ctx = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.l3ContextIid(tenantId, id), rwTx);
+        if (!potentialL3Ctx.isPresent()) {
+            LOG.warn("Illegal state - l3-context {} does not exist.", id.getValue());
+            return;
+        }
+        removeTenantNetworkDomains(network, tenantId, rwTx);
+        DataStoreHelper.submitToDs(rwTx);
+    }
+
+    @Deprecated
+    private void removeTenantNetworkDomains(Network network, TenantId tenantId, ReadWriteTransaction rwTx) {
         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getUuid().getValue());
         Optional<L2FloodDomain> potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
                 IidFactory.l2FloodDomainIid(tenantId, l2FdId), rwTx);
@@ -136,8 +223,12 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
             LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", l2BdId.getValue());
             return;
         }
-
-        DataStoreHelper.submitToDs(rwTx);
+        L3ContextId l3CtxId = new L3ContextId(l2FdId);
+        Optional<L3Context> potentialL3Ctx = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.l3ContextIid(tenantId, l3CtxId), rwTx);
+        if (!potentialL3Ctx.isPresent()) {
+            LOG.warn("Illegal state - l3-context {} does not exist.", l3CtxId.getValue());
+            return;
+        }
     }
-
 }
index e8cede6ee766e6b3018c0d12c55f1e962ea90157..f7a891d9320dcf3b193289eba7ebf8d5998a612a 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -23,23 +22,36 @@ import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.PortUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SubnetUtils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 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.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnreg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnregBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
 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.SubnetId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
 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.endpoint.rev140421.RegisterEndpointInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
@@ -47,7 +59,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.MacAddressType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.base.endpoints.PortByBaseEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.base.endpoints.PortByBaseEndpointKey;
 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.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
@@ -89,9 +110,9 @@ public class NeutronPortAware implements NeutronAware<Port> {
                 return;
             }
             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
-            L3ContextId routerL3Context = new L3ContextId(port.getDeviceId());
+            ContextId routerL3Context = new ContextId(port.getDeviceId());
             // change L3Context for all EPs with same subnet as router port
-            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), neutron.getPorts(), routerL3Context);
+            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), neutron);
             // set L3Context as parent for bridge domain which is parent of subnet
             TenantId tenantId = new TenantId(port.getTenantId().getValue());
             Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(), neutron.getSubnets());
@@ -100,15 +121,22 @@ public class NeutronPortAware implements NeutronAware<Port> {
                         port);
                 return;
             }
-            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             Subnet routerPortSubnet = potentialRouterPortSubnet.get();
-            L2BridgeDomainId l2BdId = new L2BridgeDomainId(routerPortSubnet.getNetworkId().getValue());
-            L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(routerL3Context).build();
+            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+            ContextId l2BdId = new ContextId(routerPortSubnet.getNetworkId().getValue());
+            ForwardingContext l2Bd = new ForwardingContextBuilder().setContextId(l2BdId)
+                .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
+                .setParent(MappingUtils.createParent(routerL3Context, MappingUtils.L3_CONTEXT))
+                .build();
             rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd);
             // set virtual router IP for subnet
-            org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet subnet =
-                    NeutronSubnetAware.createSubnet(routerPortSubnet, portIpWithSubnet.getIpAddress());
-            rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet);
+            NetworkDomain subnetDomain = NeutronSubnetAware.createSubnet(
+                    routerPortSubnet, portIpWithSubnet.getIpAddress());
+            rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain);
+
+            // does the same for tenant forwarding domains
+            processTenantForwarding(routerPortSubnet, routerL3Context, portIpWithSubnet, tenantId, rwTx);
+
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isDhcpPort(port)) {
             // process as normal port but put it to DHCP group
@@ -118,35 +146,58 @@ public class NeutronPortAware implements NeutronAware<Port> {
                 LOG.warn("DHCP port does not have an IP address. {}", port);
                 return;
             }
-            RegisterEndpointInputBuilder epInBuilder = createBasicEndpointInputBuilder(port);
-            // endpoint has only one network containment therefore only first IP is used
             FixedIps ipWithSubnet = firstFixedIps.get();
-            epInBuilder.setNetworkContainment(new SubnetId(ipWithSubnet.getSubnetId().getValue()));
-            L3Address l3Address = new L3AddressBuilder().setL3Context(new L3ContextId(port.getNetworkId().getValue()))
-                .setIpAddress(ipWithSubnet.getIpAddress())
-                .build();
-            epInBuilder.setL3Address(ImmutableList.of(l3Address));
+            NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
             List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
             epgsFromSecGroups.add(NetworkService.EPG_ID);
-            epInBuilder.setEndpointGroups(epgsFromSecGroups);
-            registerEndpointAndStoreMapping(epInBuilder.build(), port);
+
+            // BUILD BASE ENDPOINT
+            AddressEndpointRegBuilder l2BaseEp = createBasicMacAddrEpInputBuilder(port, networkContainment,
+                    epgsFromSecGroups);
+            AddressEndpointRegBuilder l3BaseEp = createBasicL3AddrEpInputBuilder(port, networkContainment,
+                    epgsFromSecGroups, neutron);
+            setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp);
+
+            // BUILD ENDPOINT
+            org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder epInBuilder = createEndpointRegFromPort(
+                    port, ipWithSubnet, networkContainment, epgsFromSecGroups, neutron);
+
+            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+            registerBaseEndpointAndStoreMapping(
+                    ImmutableList.<AddressEndpointReg>of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx);
+            registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
+            DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isNormalPort(port)) {
             LOG.trace("Port is normal port: {}", port.getUuid().getValue());
-            RegisterEndpointInputBuilder epInBuilder = createBasicEndpointInputBuilder(port);
+            org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder epInBuilder = null;
+            AddressEndpointRegBuilder l2BaseEp;
+            AddressEndpointRegBuilder l3BaseEp = null;
             Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(port);
+            List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
+            epgsFromSecGroups.add(NetworkClient.EPG_ID);
             if (firstFixedIps.isPresent()) {
                 // endpoint has only one network containment therefore only first IP is used
                 FixedIps ipWithSubnet = firstFixedIps.get();
-                epInBuilder.setNetworkContainment(new SubnetId(ipWithSubnet.getSubnetId().getValue()));
-                L3Address l3Address = resolveL3AddressFromPort(port, ipWithSubnet, neutron);
-                epInBuilder.setL3Address(ImmutableList.of(l3Address));
+                NetworkDomainId containment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
+                epInBuilder = createEndpointRegFromPort(port, ipWithSubnet, containment, epgsFromSecGroups, neutron);
+                l2BaseEp = createBasicMacAddrEpInputBuilder(port,
+                        containment, epgsFromSecGroups);
+                l3BaseEp = createBasicL3AddrEpInputBuilder(port, containment, epgsFromSecGroups, neutron);
+                setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp);
             } else {
-                epInBuilder.setNetworkContainment(new L2FloodDomainId(port.getNetworkId().getValue()));
+                NetworkDomainId containment = new NetworkDomainId(port.getNetworkId().getValue());
+                epInBuilder = createEndpointRegFromPort(port, null, containment, epgsFromSecGroups, neutron);
+                l2BaseEp = createBasicMacAddrEpInputBuilder(port, containment, epgsFromSecGroups);
             }
-            List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
-            epgsFromSecGroups.add(NetworkClient.EPG_ID);
-            epInBuilder.setEndpointGroups(epgsFromSecGroups);
-            registerEndpointAndStoreMapping(epInBuilder.build(), port);
+            List<AddressEndpointReg> baseEpRegs = new ArrayList<>();
+            baseEpRegs.add(l2BaseEp.build());
+            if (l3BaseEp != null) {
+                baseEpRegs.add(l3BaseEp.build());
+            }
+            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+            registerBaseEndpointAndStoreMapping(baseEpRegs, port, rwTx);
+            registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
+            DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isRouterGatewayPort(port)) {
             // do nothing because actual trigger is attaching of port to router
             LOG.trace("Port is router gateway port: {}", port.getUuid().getValue());
@@ -158,8 +209,45 @@ public class NeutronPortAware implements NeutronAware<Port> {
         }
     }
 
-    private void changeL3ContextForEpsInSubnet(Uuid subnetUuid, Ports ports, L3ContextId newl3Context) {
-        Set<Port> portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, ports);
+    private void setParentChildRelationshipForEndpoints(AddressEndpointRegBuilder parentEp,
+            AddressEndpointRegBuilder childEp) {
+        childEp.setParentEndpointChoice(new ParentEndpointCaseBuilder().setParentEndpoint(
+                ImmutableList.<ParentEndpoint>of(createParentEndpoint(parentEp))).build());
+        parentEp.setChildEndpoint(ImmutableList.<ChildEndpoint>of(createChildEndpoint(childEp)));
+    }
+
+    @Deprecated
+    private void processTenantForwarding(Subnet routerPortSubnet, ContextId routerL3Context, FixedIps portIpWithSubnet,
+            TenantId tenantId, ReadWriteTransaction rwTx) {
+        L2BridgeDomainId l2BdId = new L2BridgeDomainId(routerPortSubnet.getNetworkId().getValue());
+        L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(new L3ContextId(routerL3Context)).build();
+        rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd);
+        // set virtual router IP for subnet
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet subnet = NeutronSubnetAware.createTenantSubnet(
+                routerPortSubnet, portIpWithSubnet.getIpAddress());
+        rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet);
+    }
+
+    /**
+     * Registers endpoint from {@link Port} and method parameters.
+     * Always creates registration input for L2 endpoint.
+     * Creates registration input for L3 endpoint if fixedIps argument is not null.
+     */
+    @Deprecated
+    private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder createEndpointRegFromPort(
+            Port port, FixedIps fixedIps, NetworkDomainId networkContainment, List<EndpointGroupId> endpointGroupIds, Neutron neutron) {
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder epInBuilder = createBasicEndpointInputBuilder(
+                port).setNetworkContainment(networkContainment);
+        if (fixedIps != null) {
+            L3Address l3Address = resolveL3AddressFromPort(port, fixedIps, neutron);
+            epInBuilder.setL3Address(ImmutableList.of(l3Address));
+        }
+        epInBuilder.setEndpointGroups(endpointGroupIds);
+        return epInBuilder;
+    }
+
+    private void changeL3ContextForEpsInSubnet(Uuid subnetUuid, Neutron neutron) {
+        Set<Port> portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, neutron.getPorts());
         for (Port portInSameSubnet : portsInSameSubnet) {
             if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet)) {
                 // endpoints are created only from neutron normal port or DHCP port
@@ -167,29 +255,135 @@ public class NeutronPortAware implements NeutronAware<Port> {
                 if (firstFixedIps.isPresent()) {
                     // endpoint has only one network containment therefore only first IP is used
                     FixedIps ipWithSubnet = firstFixedIps.get();
-                    RegisterEndpointInputBuilder epInBuilder = createBasicEndpointInputBuilder(portInSameSubnet);
-                    epInBuilder.setNetworkContainment(new SubnetId(ipWithSubnet.getSubnetId().getValue()));
-                    L3Address l3Address = new L3AddressBuilder().setL3Context(newl3Context)
-                        .setIpAddress(ipWithSubnet.getIpAddress())
+                    List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
+                    if (PortUtils.isDhcpPort(portInSameSubnet)) {
+                        endpointGroupIds.add(NetworkService.EPG_ID);
+                    } else if (PortUtils.isNormalPort(portInSameSubnet)) {
+                        endpointGroupIds.add(NetworkClient.EPG_ID);
+                    }
+                    NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
+                    AddressEndpointRegBuilder l2BaseEp = createBasicMacAddrEpInputBuilder(portInSameSubnet,
+                            networkContainment, endpointGroupIds);
+                    AddressEndpointRegBuilder l3BaseEp = createBasicL3AddrEpInputBuilder(portInSameSubnet,
+                            networkContainment, endpointGroupIds, neutron);
+                    setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp);
+                    AddressEndpointUnreg addrEpUnreg = new AddressEndpointUnregBuilder().setAddress(l3BaseEp.getAddress())
+                        .setAddressType(l3BaseEp.getAddressType())
+                        .setContextId(new ContextId(portInSameSubnet.getNetworkId().getValue()))
+                        .setContextType(l3BaseEp.getContextType())
                         .build();
-                    epInBuilder.setL3Address(ImmutableList.of(l3Address));
-                    List<EndpointGroupId> epgsFromSecGroups =
-                            resolveEpgIdsFromSecGroups(portInSameSubnet.getSecurityGroups());
-                    epgsFromSecGroups.add(NetworkClient.EPG_ID);
-                    epRegistrator.registerEndpoint(epInBuilder.build());
-                    // unregister L3EP
-                    L3ContextId oldL3Context = new L3ContextId(portInSameSubnet.getNetworkId().getValue());
-                    L3 l3 = new L3Builder().setL3Context(oldL3Context).setIpAddress(ipWithSubnet.getIpAddress())
-                        .build();
-                    UnregisterEndpointInput epUnreg = new UnregisterEndpointInputBuilder().setL3(ImmutableList.of(l3)).build();
-                    epRegistrator.unregisterEndpoint(epUnreg);
+                    epRegistrator.unregisterEndpoint(addrEpUnreg);
+                    epRegistrator.registerEndpoint(l3BaseEp.build());
+
+                    modifyL3ContextForEndpoints(portInSameSubnet, ipWithSubnet, l3BaseEp.getContextId());
                 }
             }
         }
     }
 
-    private static RegisterEndpointInputBuilder createBasicEndpointInputBuilder(Port port) {
-        return new RegisterEndpointInputBuilder().setL2Context(new L2BridgeDomainId(port.getNetworkId().getValue()))
+    private ChildEndpoint createChildEndpoint(AddressEndpointRegBuilder builder) {
+        return new ChildEndpointBuilder().setAddress(builder.getAddress())
+            .setAddressType(builder.getAddressType())
+            .setContextId(builder.getContextId())
+            .setContextType(builder.getContextType())
+            .build();
+    }
+
+    private ParentEndpoint createParentEndpoint(AddressEndpointRegBuilder builder) {
+        return new ParentEndpointBuilder().setAddress(builder.getAddress())
+            .setAddressType(builder.getAddressType())
+            .setContextId(builder.getContextId())
+            .setContextType(builder.getContextType())
+            .build();
+    }
+
+    @Deprecated
+    private void modifyL3ContextForEndpoints(Port port, FixedIps resolvedPortFixedIp, ContextId newContextId) {
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder epInBuilder = createBasicEndpointInputBuilder(port);
+        epInBuilder.setNetworkContainment(new NetworkDomainId(resolvedPortFixedIp.getSubnetId().getValue()));
+        L3Address l3Address = new L3AddressBuilder().setL3Context(new L3ContextId(newContextId))
+            .setIpAddress(resolvedPortFixedIp.getIpAddress())
+            .build();
+        epInBuilder.setL3Address(ImmutableList.of(l3Address));
+        List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
+        epgsFromSecGroups.add(NetworkClient.EPG_ID);
+        epInBuilder.setEndpointGroups(epgsFromSecGroups);
+        epRegistrator.registerEndpoint(epInBuilder.build());
+        // unregister L3EP
+        L3ContextId oldL3Context = new L3ContextId(port.getNetworkId().getValue());
+        L3 l3 = new L3Builder().setL3Context(oldL3Context).setIpAddress(resolvedPortFixedIp.getIpAddress()).build();
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput epUnreg = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder().setL3(
+                ImmutableList.of(l3))
+            .build();
+        epRegistrator.unregisterEndpoint(epUnreg);
+    }
+
+    private AddressEndpointRegBuilder createBasicMacAddrEpInputBuilder(Port port,
+            NetworkDomainId networkContainment, @Nullable List<EndpointGroupId> endpointGroupsToAdd) {
+        AddressEndpointRegBuilder addrEpbuilder = new AddressEndpointRegBuilder().setAddressType(MacAddressType.class)
+            .setAddress(port.getMacAddress())
+            .setAddressType(MacAddressType.class)
+            .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
+            .setContextId(new ContextId(port.getNetworkId().getValue()))
+            .setTenant(new TenantId(port.getTenantId().getValue()))
+            .setTimestamp(System.currentTimeMillis());
+        List<EndpointGroupId> epgs = concatEndpointGroups(port.getSecurityGroups(), endpointGroupsToAdd);
+        addrEpbuilder.setEndpointGroup(epgs);
+        if (networkContainment != null) {
+            addrEpbuilder.setNetworkContainment(new NetworkContainmentBuilder().setContainment(
+                    new NetworkDomainContainmentBuilder().setNetworkDomainId(networkContainment)
+                        .setNetworkDomainType(MappingUtils.SUBNET)
+                        .build()).build());
+        }
+        return addrEpbuilder;
+    }
+
+    private AddressEndpointRegBuilder createBasicL3AddrEpInputBuilder(Port port, NetworkDomainId networkContainment,
+            @Nullable List<EndpointGroupId> endpointGroupsToAdd, Neutron neutron) {
+        Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(port);
+        if (!firstFixedIps.isPresent()) {
+            throw new IllegalStateException("Failed to resolve FixedIps for port " + port.getKey()
+                    + ". Cannot register L3 Address endpoint.");
+        }
+        ContextId resolveL3ContextForPort = resolveL3ContextForPort(port, port.getFixedIps().get(0), neutron);
+
+        AddressEndpointRegBuilder addrEpbuilder = new AddressEndpointRegBuilder().setAddressType(MacAddressType.class)
+            .setAddress(MappingUtils.ipAddressToStringIpPrefix(firstFixedIps.get().getIpAddress()))
+            .setAddressType(IpPrefixType.class)
+            .setContextType(MappingUtils.L3_CONTEXT)
+            .setContextId(resolveL3ContextForPort)
+            .setTenant(new TenantId(port.getTenantId().getValue()))
+            .setTimestamp(System.currentTimeMillis());
+        List<EndpointGroupId> epgs = concatEndpointGroups(port.getSecurityGroups(), endpointGroupsToAdd);
+        addrEpbuilder.setEndpointGroup(epgs);
+        if (networkContainment != null) {
+            addrEpbuilder.setNetworkContainment(new NetworkContainmentBuilder().setContainment(
+                    new NetworkDomainContainmentBuilder().setNetworkDomainId(networkContainment)
+                        .setNetworkDomainType(MappingUtils.SUBNET)
+                        .build()).build());
+        }
+        return addrEpbuilder;
+    }
+
+    private List<EndpointGroupId> concatEndpointGroups(List<Uuid> securityGroups,
+            @Nullable List<EndpointGroupId> endpointGroupsToAdd) {
+        List<EndpointGroupId> epgs = new ArrayList<>();
+        if (securityGroups != null) {
+            for (Uuid sgId : securityGroups) {
+                epgs.add(new EndpointGroupId(sgId.getValue()));
+            }
+        }
+        if (endpointGroupsToAdd != null) {
+            epgs.addAll(endpointGroupsToAdd);
+        }
+        return epgs;
+    }
+
+    @Deprecated
+    private static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder createBasicEndpointInputBuilder(
+            Port port) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder().setL2Context(
+                new L2BridgeDomainId(port.getNetworkId().getValue()))
             .setMacAddress(new MacAddress(port.getMacAddress()))
             .setTenant(new TenantId(port.getTenantId().getValue()))
             .setTimestamp(System.currentTimeMillis());
@@ -206,23 +400,89 @@ public class NeutronPortAware implements NeutronAware<Port> {
         return epgIds;
     }
 
-    private void registerEndpointAndStoreMapping(RegisterEndpointInput regEpInput, Port port) {
+    @Deprecated
+    private void registerEndpointAndStoreMapping(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput regEpInput,
+            Port port, ReadWriteTransaction rwTx) {
         boolean isRegisteredEndpoint = epRegistrator.registerEndpoint(regEpInput);
-        if (isRegisteredEndpoint) {
-            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+        if (!isRegisteredEndpoint) {
+            LOG.error("Failed to register an endpoint: {}", regEpInput);
+            return;
+        }
+        UniqueId portId = new UniqueId(port.getUuid().getValue());
+        EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()), new MacAddress(
+                port.getMacAddress()));
+        LOG.trace("Adding Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getUuid()
+            .getValue(), port.getDeviceOwner(), epKey);
+        EndpointByPort endpointByPort = MappingFactory.createEndpointByPort(epKey, portId);
+        rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByPortIid(portId), endpointByPort, true);
+        PortByEndpoint portByEndpoint = MappingFactory.createPortByEndpoint(portId, epKey);
+        rwTx.put(LogicalDatastoreType.OPERATIONAL,
+                NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), portByEndpoint,
+                true);
+    }
+
+    @Deprecated
+    private void unregisterEndpointAndRemoveMapping(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput unregEpInput,
+            Port port, ReadWriteTransaction rwTx) {
+        boolean isUnregisteredEndpoint = epRegistrator.unregisterEndpoint(unregEpInput);
+        if (isUnregisteredEndpoint) {
+            UniqueId portId = new UniqueId(port.getUuid().getValue());
+            EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()), new MacAddress(
+                    port.getMacAddress()));
+            LOG.trace("Removing Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getUuid()
+                .getValue(), port.getDeviceOwner(), epKey);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.endpointByPortIid(portId), rwTx);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
+        }
+    }
+
+    private void registerBaseEndpointAndStoreMapping(List<AddressEndpointReg> addrEpRegs, Port port,
+            ReadWriteTransaction rwTx) {
+        RegisterEndpointInput regBaseEpInput = new RegisterEndpointInputBuilder().setAddressEndpointReg(addrEpRegs)
+            .build();
+
+        boolean isRegisteredBaseEndpoint = epRegistrator.registerEndpoint(regBaseEpInput);
+        if (!isRegisteredBaseEndpoint) {
+            LOG.error("Failed to register an address endpoint: {}", addrEpRegs);
+            return;
+        }
+        for (AddressEndpointReg addrEpReg : addrEpRegs) {
+            if (MappingUtils.L2_BRDIGE_DOMAIN.equals(addrEpReg.getContextType())) {
+                UniqueId portId = new UniqueId(port.getUuid().getValue());
+                LOG.trace("Adding Port-BaseEndpoint mapping for port {} (device owner {}) and endpoint {}",
+                        port.getUuid());
+                AddressEndpointKey addrEpKey = new AddressEndpointKey(addrEpReg.getAddress(),
+                        addrEpReg.getAddressType(), addrEpReg.getContextId(), addrEpReg.getContextType());
+                BaseEndpointByPort baseEndpointByPort = MappingFactory.createBaseEndpointByPort(addrEpKey, portId);
+                rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.baseEndpointByPortIid(portId),
+                        baseEndpointByPort, true);
+                PortByBaseEndpoint portByBaseEndpoint = MappingFactory.createPortByBaseEndpoint(portId, addrEpKey);
+                rwTx.put(LogicalDatastoreType.OPERATIONAL,
+                        NeutronGbpIidFactory.portByBaseEndpointIid(new PortByBaseEndpointKey(
+                                portByBaseEndpoint.getKey())), portByBaseEndpoint, true);
+            }
+        }
+    }
+
+    private void unregisterEndpointAndRemoveMapping(UnregisterEndpointInput baseEpUnreg, Port port,
+            ReadWriteTransaction rwTx) {
+        boolean isUnregisteredBaseEndpoint = epRegistrator.unregisterEndpoint(baseEpUnreg);
+        if (isUnregisteredBaseEndpoint) {
             UniqueId portId = new UniqueId(port.getUuid().getValue());
-            EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()),
-                    new MacAddress(port.getMacAddress()));
-            LOG.trace("Adding Port-Endpoint mapping for port {} (device owner {}) and endpoint {}",
+            EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()), new MacAddress(
+                    port.getMacAddress()));
+            LOG.trace("Removing Port-BaseEndpoint mapping for port {} (device owner {}) and endpoint {}",
                     port.getUuid().getValue(), port.getDeviceOwner(), epKey);
-            EndpointByPort endpointByPort = MappingFactory.createEndpointByPort(epKey, portId);
-            rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByPortIid(portId), endpointByPort,
-                    true);
-            PortByEndpoint portByEndpoint = MappingFactory.createPortByEndpoint(portId, epKey);
-            rwTx.put(LogicalDatastoreType.OPERATIONAL,
-                    NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), portByEndpoint,
-                    true);
-            DataStoreHelper.submitToDs(rwTx);
+            PortByBaseEndpointKey portByBaseEndpointKey = new PortByBaseEndpointKey(port.getMacAddress(),
+                    MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.baseEndpointByPortIid(portId), rwTx);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.portByBaseEndpointIid(portByBaseEndpointKey), rwTx);
         }
     }
 
@@ -248,33 +508,41 @@ public class NeutronPortAware implements NeutronAware<Port> {
             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
             L3ContextId l3Context = new L3ContextId(port.getNetworkId().getValue());
             // change L3Context for all EPs with same subnet as router port
-            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), oldNeutron.getPorts(), l3Context);
+            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), oldNeutron);
             // set L3Context as parent for bridge domain which is parent of subnet
             TenantId tenantId = new TenantId(port.getTenantId().getValue());
-            Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(), oldNeutron.getSubnets());
+            Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(),
+                    oldNeutron.getSubnets());
             if (!potentialRouterPortSubnet.isPresent()) {
-                LOG.warn("Illegal state - router interface port is in subnet which does not exist. {}",
-                        port);
+                LOG.warn("Illegal state - router interface port is in subnet which does not exist. {}", port);
                 return;
             }
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             Subnet routerPortSubnet = potentialRouterPortSubnet.get();
-            L2BridgeDomainId l2BdId = new L2BridgeDomainId(routerPortSubnet.getNetworkId().getValue());
-            L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(l3Context).build();
-            rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd);
-            // remove virtual router IP for subnet
-            org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet subnet =
-                    NeutronSubnetAware.createSubnet(routerPortSubnet, null);
-            rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet);
+            modifyForwardingOnDelete(routerPortSubnet, l3Context, tenantId, rwTx);
+            ContextId l2BdId = new ContextId(routerPortSubnet.getNetworkId().getValue());
+            ForwardingContext fwdCtx = new ForwardingContextBuilder().setContextId(l2BdId)
+                .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
+                .setParent(MappingUtils.createParent(l3Context, MappingUtils.L3_CONTEXT))
+                .build();
+            rwTx.merge(LogicalDatastoreType.CONFIGURATION,
+                    IidFactory.l2BridgeDomainIid(tenantId, fwdCtx.getContextId()), fwdCtx);
+            NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, null);
+            rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getNetworkDomainId()),
+                    subnet);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isDhcpPort(port)) {
             LOG.trace("Port is DHCP port: {}", port.getUuid().getValue());
-            UnregisterEndpointInput unregEpInput = createUnregisterEndpointInput(port, oldNeutron);
-            unregisterEndpointAndRemoveMapping(unregEpInput, port);
+            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+            unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx);
+            DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isNormalPort(port)) {
             LOG.trace("Port is normal port: {}", port.getUuid().getValue());
-            UnregisterEndpointInput unregEpInput = createUnregisterEndpointInput(port, oldNeutron);
-            unregisterEndpointAndRemoveMapping(unregEpInput, port);
+            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+            unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx);
+            DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isRouterGatewayPort(port)) {
             // do nothing because actual trigger is detaching of port from router
             LOG.trace("Port is router gateway port: {}", port.getUuid().getValue());
@@ -286,15 +554,52 @@ public class NeutronPortAware implements NeutronAware<Port> {
         }
     }
 
-    private UnregisterEndpointInput createUnregisterEndpointInput(Port port, Neutron neutron) {
+    @Deprecated
+    private void modifyForwardingOnDelete(Subnet routerPortSubnet, L3ContextId l3contextId, TenantId tenantId, ReadWriteTransaction rwTx) {
+        L2BridgeDomainId l2BdId = new L2BridgeDomainId(routerPortSubnet.getNetworkId().getValue());
+        L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(l3contextId).build();
+        rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd);
+        // remove virtual router IP for subnet
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet tenantSubnet = NeutronSubnetAware.createTenantSubnet(routerPortSubnet, null);
+        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, tenantSubnet.getId()), tenantSubnet);
+    }
+
+    private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput createUnregisterBaseEndpointInput(
+            Port port, Neutron neutron) {
         UnregisterEndpointInputBuilder inputBuilder = new UnregisterEndpointInputBuilder();
+        List<AddressEndpointUnreg> list = new ArrayList<>();
+        AddressEndpointUnregBuilder addrL2EpUnregBuilder = new AddressEndpointUnregBuilder();
+        addrL2EpUnregBuilder.setAddress(port.getMacAddress())
+            .setAddressType(MacAddressType.class)
+            .setContextId(new ContextId(port.getNetworkId().getValue()))
+            .setContextType(MappingUtils.L2_BRDIGE_DOMAIN);
+        list.add(addrL2EpUnregBuilder.build());
+        Optional<FixedIps> potentialFirstIp = PortUtils.resolveFirstFixedIps(port);
+        if (potentialFirstIp.isPresent()) {
+            ContextId l3ContextId = resolveL3ContextForPort(port, potentialFirstIp.get(), neutron);
+            AddressEndpointUnregBuilder addrL3EpUnregBuilder = new AddressEndpointUnregBuilder();
+            addrL3EpUnregBuilder.setAddress(MappingUtils.ipAddressToStringIpPrefix(potentialFirstIp.get().getIpAddress()))
+                .setAddressType(IpPrefixType.class)
+                .setContextId(l3ContextId)
+                .setContextType(L3Context.class);
+            list.add(addrL3EpUnregBuilder.build());
+        }
+        inputBuilder.setAddressEndpointUnreg(list);
+        return inputBuilder.build();
+    }
+
+    @Deprecated
+    private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput createUnregisterEndpointInput(
+            Port port, Neutron neutron) {
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder inputBuilder =
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder();
         L2 l2Ep = new L2Builder().setL2Context(new L2BridgeDomainId(port.getNetworkId().getValue()))
             .setMacAddress(new MacAddress(port.getMacAddress()))
             .build();
         inputBuilder.setL2(ImmutableList.of(l2Ep));
         // we've registered EP with only first IP so remove only EP with first IP
         Optional<FixedIps> potentialFirstIp = PortUtils.resolveFirstFixedIps(port);
-        if (!potentialFirstIp.isPresent()) {
+        if (potentialFirstIp.isPresent()) {
             FixedIps firstIp = potentialFirstIp.get();
             L3Address l3Address = resolveL3AddressFromPort(port, firstIp, neutron);
             L3 l3 = new L3Builder().setIpAddress(l3Address.getIpAddress())
@@ -305,23 +610,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
         return inputBuilder.build();
     }
 
-    private void unregisterEndpointAndRemoveMapping(UnregisterEndpointInput unregEpInput, Port port) {
-        boolean isUnregisteredEndpoint = epRegistrator.unregisterEndpoint(unregEpInput);
-        if (isUnregisteredEndpoint) {
-            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
-            UniqueId portId = new UniqueId(port.getUuid().getValue());
-            EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()),
-                    new MacAddress(port.getMacAddress()));
-            LOG.trace("Removing Port-Endpoint mapping for port {} (device owner {}) and endpoint {}",
-                    port.getUuid().getValue(), port.getDeviceOwner(), epKey);
-            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
-                    NeutronGbpIidFactory.endpointByPortIid(portId), rwTx);
-            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
-                    NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
-            DataStoreHelper.submitToDs(rwTx);
-        }
-    }
-
+    @Deprecated
     private static L3Address resolveL3AddressFromPort(Port port, FixedIps portFixedIPs, Neutron neutron) {
         Set<Port> routerIfacePorts = PortUtils.findRouterInterfacePorts(neutron.getPorts());
         for (Port routerIfacePort : routerIfacePorts) {
@@ -341,4 +630,17 @@ public class NeutronPortAware implements NeutronAware<Port> {
             .build();
     }
 
+    private static ContextId resolveL3ContextForPort(Port port, FixedIps portFixedIPs, Neutron neutron) {
+        Set<Port> routerIfacePorts = PortUtils.findRouterInterfacePorts(neutron.getPorts());
+        for (Port routerIfacePort : routerIfacePorts) {
+            Uuid routerIfacePortSubnet = routerIfacePort.getFixedIps().get(0).getSubnetId();
+            // if port is in the same subnet as router interface then we want to use L3Context of
+            // router
+            if (portFixedIPs.getSubnetId().equals(routerIfacePortSubnet)) {
+                LOG.trace("Router interface port was found in the same subnet as port have {}", port);
+                return new ContextId(routerIfacePort.getDeviceId());
+            }
+        }
+        return new ContextId(port.getNetworkId().getValue());
+    }
 }
index 7da088ec9ce091627c9803b72c08ea0781d8f44a..0b0199d9ecd6ea375df98216f309718c020a580f 100644 (file)
@@ -11,14 +11,13 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.List;
-import java.util.concurrent.ExecutionException;
 
 import javax.annotation.Nonnull;
 
 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.dto.IndexedTenant;
 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
@@ -27,7 +26,12 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SubnetUtils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
@@ -36,16 +40,22 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentForwarding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentForwardingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.Subnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.SubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomainBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.endpoints.ExternalGatewayAsEndpoint;
 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.policy.rev140421.tenants.TenantBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
@@ -57,6 +67,7 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
 
 public class NeutronRouterAware implements NeutronAware<Router> {
 
@@ -74,6 +85,39 @@ public class NeutronRouterAware implements NeutronAware<Router> {
     @Override
     public void onCreated(Router router, Neutron neutron) {
         LOG.trace("created router - {}", router);
+
+        ContextId routerl3ContextId = new ContextId(router.getUuid().getValue());
+        TenantId tenantId = new TenantId(router.getTenantId().getValue());
+        InstanceIdentifier<ForwardingContext> routerL3CtxIid = IidFactory.l3ContextIid(tenantId, routerl3ContextId);
+        ForwardingContextBuilder fwdCtxBuilder = new ForwardingContextBuilder();
+        Name routerName = null;
+        if (!Strings.isNullOrEmpty(router.getName())) {
+            try {
+                routerName = new Name(router.getName());
+                fwdCtxBuilder.setName(routerName);
+            } catch (Exception e) {
+                LOG.info("Name '{}' of Neutron Subnet '{}' is ignored.", router.getName(),
+                        router.getUuid().getValue());
+                LOG.debug("Name exception", e);
+            }
+        }
+        ForwardingContext routerl3Context = fwdCtxBuilder.setContextId(routerl3ContextId)
+            .setContextType(MappingUtils.L3_CONTEXT)
+            .build();
+        WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.CONFIGURATION, routerL3CtxIid, routerl3Context, true);
+        createTenantL3Context(new L3ContextId(routerl3ContextId), tenantId, routerName, wTx);
+        DataStoreHelper.submitToDs(wTx);
+    }
+
+    @Deprecated
+    private void createTenantL3Context(L3ContextId l3ContextId, TenantId tenantId, Name name, WriteTransaction wTx) {
+        L3ContextBuilder l3ContextBuilder = new L3ContextBuilder();
+        if (name != null) {
+            l3ContextBuilder.setName(name);
+        }
+        L3Context l3Context = l3ContextBuilder.setId(l3ContextId).build();
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3ContextId), l3Context);
     }
 
     @Override
@@ -82,18 +126,7 @@ public class NeutronRouterAware implements NeutronAware<Router> {
 
         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
         TenantId tenantId = new TenantId(newRouter.getTenantId().getValue());
-        L3ContextId l3ContextIdFromRouterId = new L3ContextId(newRouter.getUuid().getValue());
-        InstanceIdentifier<L3Context> l3ContextIidForRouterId =
-                IidFactory.l3ContextIid(tenantId, l3ContextIdFromRouterId);
-        Optional<L3Context> potentialL3ContextForRouter =
-                DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, rwTx);
-        L3Context l3Context = null;
-        if (potentialL3ContextForRouter.isPresent()) {
-            l3Context = potentialL3ContextForRouter.get();
-        } else { // add L3 context if missing
-            l3Context = createL3ContextFromRouter(newRouter);
-            rwTx.put(LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, l3Context);
-        }
+        ContextId routerL3CtxId = new ContextId(newRouter.getUuid().getValue());
 
         if (newRouter.getGatewayPortId() != null && oldRouter.getGatewayPortId() == null) {
             // external network is attached to router
@@ -124,32 +157,21 @@ public class NeutronRouterAware implements NeutronAware<Router> {
                 rwTx.cancel();
                 return;
             }
-            IpAddress gatewayIp =  potentialSubnet.get().getGatewayIp();
-            boolean registeredExternalGateway = epRegistrator.registerL3EndpointAsExternalGateway(tenantId, gatewayIp,
-                    l3ContextIdFromRouterId, new NetworkDomainId(ipWithSubnetFromGwPort.getSubnetId().getValue()));
+            IpPrefix gatewayIp =  MappingUtils.ipAddressToIpPrefix(potentialSubnet.get().getGatewayIp());
+            boolean registeredExternalGateway = registerExternalGateway(tenantId, gatewayIp,
+                    routerL3CtxId, new NetworkDomainId(ipWithSubnetFromGwPort.getSubnetId().getValue()));
             if (!registeredExternalGateway) {
                 LOG.warn("Could not add L3Prefix as gateway of default route. Gateway port {}", gwPort);
                 rwTx.cancel();
                 return;
             }
-            EndpointL3Key epL3Key = new EndpointL3Key(gatewayIp, l3ContextIdFromRouterId);
-            addNeutronExtGwGbpMapping(epL3Key, rwTx);
-
-            boolean registeredDefaultRoute = epRegistrator.registerExternalL3PrefixEndpoint(MappingUtils.DEFAULT_ROUTE,
-                    l3ContextIdFromRouterId, gatewayIp, tenantId);
-            if (!registeredDefaultRoute) {
-                LOG.warn("Could not add EndpointL3Prefix as default route. Gateway port {}", gwPort);
-                rwTx.cancel();
-                return;
-            }
-            Subnet subnetWithGw =
-                    new SubnetBuilder().setId(new SubnetId(ipWithSubnetFromGwPort.getSubnetId().getValue()))
-                        .setVirtualRouterIp(gatewayIp)
-                .build();
-            rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetWithGw.getId()),
-                    subnetWithGw);
-            L2BridgeDomainId l2BdId = new L2BridgeDomainId(potentialSubnet.get().getNetworkId().getValue());
-            Optional<L2BridgeDomain> optBd = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+            addNeutronExtGwGbpMapping(routerL3CtxId, gatewayIp, rwTx);
+            NetworkDomain subnetDomain = createSubnetWithVirtualRouterIp(gatewayIp, new NetworkDomainId(ipWithSubnetFromGwPort.getSubnetId()
+                .getValue()));
+            rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()),
+                    subnetDomain);
+            ContextId l2BdId = new ContextId(potentialSubnet.get().getNetworkId().getValue());
+            Optional<ForwardingContext> optBd = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
                     IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
             if (!optBd.isPresent()) {
                 LOG.warn(
@@ -158,16 +180,137 @@ public class NeutronRouterAware implements NeutronAware<Router> {
                 rwTx.cancel();
                 return;
             }
-            L2BridgeDomain l2BdWithGw = new L2BridgeDomainBuilder(optBd.get())
-                .setParent(new L3ContextId(l3ContextIdFromRouterId.getValue()))
-                .build();
+            ForwardingContext l2BdWithGw = new ForwardingContextBuilder(optBd.get())
+            .setParent(MappingUtils.createParent(routerL3CtxId, MappingUtils.L3_CONTEXT))
+            .build();
             rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId),
                     l2BdWithGw);
         }
+        updateTenantForwarding(newNeutron, oldRouter, newRouter, new L3ContextId(routerL3CtxId), tenantId, rwTx);
         DataStoreHelper.submitToDs(rwTx);
     }
 
-    private static @Nonnull L3Context createL3ContextFromRouter(Router router) {
+    private boolean registerExternalGateway(TenantId tenantId, IpPrefix ipPrefix, ContextId routerl3ContextId,
+            NetworkDomainId networkDomainId) {
+        AddressEndpointRegBuilder addrEpBuilder = new AddressEndpointRegBuilder();
+        addrEpBuilder.setAddressType(IpPrefixType.class);
+        addrEpBuilder.setAddress(MappingUtils.ipPrefixToStringIpAddress(ipPrefix));
+        addrEpBuilder.setContextId(routerl3ContextId);
+        addrEpBuilder.setContextType(MappingUtils.L3_CONTEXT);
+        addrEpBuilder.setTenant(tenantId);
+        addrEpBuilder.setNetworkContainment(new NetworkContainmentBuilder().setContainment(
+                new NetworkDomainContainmentBuilder().setNetworkDomainId(networkDomainId).build()).build());
+        addrEpBuilder.setEndpointGroup(ImmutableList.of(MappingUtils.EPG_EXTERNAL_ID));
+        addrEpBuilder.setTimestamp(System.currentTimeMillis());
+        return epRegistrator.registerEndpoint(addrEpBuilder.build());
+    }
+
+    private NetworkDomain createSubnetWithVirtualRouterIp(IpPrefix gatewayIp, NetworkDomainId subnetId) {
+        Subnet subnet = new SubnetBuilder().setVirtualRouterIp(MappingUtils.ipPrefixToIpAddress(gatewayIp.getValue())).build();
+        return new NetworkDomainBuilder().setKey(new NetworkDomainKey(subnetId, MappingUtils.SUBNET))
+            .addAugmentation(SubnetAugmentForwarding.class,
+                    new SubnetAugmentForwardingBuilder().setSubnet(subnet).build())
+            .build();
+    }
+
+    @Deprecated
+    private void updateTenantForwarding(Neutron newNeutron, Router oldRouter, Router newRouter, L3ContextId l3ContextId, TenantId tenantId, ReadWriteTransaction rwTx) {
+        InstanceIdentifier<L3Context> l3ContextIid =
+                IidFactory.l3ContextIid(tenantId, l3ContextId);
+         Optional<L3Context> optL3Context = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, l3ContextIid, rwTx);
+         L3Context l3Context = null;
+         if (optL3Context.isPresent()) {
+             l3Context = optL3Context.get();
+         } else { // add L3 context if missing
+             l3Context = createL3CtxFromRouter(newRouter);
+             rwTx.put(LogicalDatastoreType.CONFIGURATION, l3ContextIid, l3Context);
+         }
+
+         if (newRouter.getGatewayPortId() != null && oldRouter.getGatewayPortId() == null) {
+             // external network is attached to router
+             Uuid gatewayPortId = newRouter.getGatewayPortId();
+             Optional<Port> potentialGwPort = PortUtils.findPort(gatewayPortId, newNeutron.getPorts());
+             if (!potentialGwPort.isPresent()) {
+                 LOG.warn("Illegal state - router gateway port {} does not exist for router {}.",
+                         gatewayPortId.getValue(), newRouter);
+                 rwTx.cancel();
+                 return;
+             }
+
+             Port gwPort = potentialGwPort.get();
+             List<FixedIps> fixedIpsFromGwPort = gwPort.getFixedIps();
+             if (fixedIpsFromGwPort == null || fixedIpsFromGwPort.isEmpty()) {
+                 LOG.warn("Illegal state - router gateway port {} does not contain fixed IPs {}",
+                         gatewayPortId.getValue(), gwPort);
+                 rwTx.cancel();
+                 return;
+             }
+
+             // router can have only one external network
+             FixedIps ipWithSubnetFromGwPort = fixedIpsFromGwPort.get(0);
+             Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet> potentialSubnet = SubnetUtils.findSubnet(ipWithSubnetFromGwPort.getSubnetId(), newNeutron.getSubnets());
+             if (!potentialSubnet.isPresent()) {
+                 LOG.warn("Illegal state - Subnet {} does not exist for router {}.",
+                         ipWithSubnetFromGwPort.getSubnetId(), newRouter);
+                 rwTx.cancel();
+                 return;
+             }
+             IpAddress gatewayIp =  potentialSubnet.get().getGatewayIp();
+             boolean registeredExternalGateway = epRegistrator.registerL3EpAsExternalGateway(tenantId, gatewayIp,
+                     l3ContextId, new NetworkDomainId(ipWithSubnetFromGwPort.getSubnetId().getValue()));
+             if (!registeredExternalGateway) {
+                 LOG.warn("Could not add L3Prefix as gateway of default route. Gateway port {}", gwPort);
+                 rwTx.cancel();
+                 return;
+             }
+             EndpointL3Key epL3Key = new EndpointL3Key(gatewayIp, l3ContextId);
+             addNeutronExtGwMapping(epL3Key, rwTx);
+
+             boolean registeredDefaultRoute = epRegistrator.registerExternalL3PrefixEndpoint(MappingUtils.DEFAULT_ROUTE,
+                     l3ContextId, gatewayIp, tenantId);
+             if (!registeredDefaultRoute) {
+                 LOG.warn("Could not add EndpointL3Prefix as default route. Gateway port {}", gwPort);
+                 rwTx.cancel();
+                 return;
+             }
+             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet subnetWithGw =
+                     new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder().setId(new SubnetId(ipWithSubnetFromGwPort.getSubnetId().getValue()))
+                         .setVirtualRouterIp(gatewayIp)
+                 .build();
+             rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetWithGw.getId()),
+                     subnetWithGw);
+             L2BridgeDomainId l2BdId = new L2BridgeDomainId(potentialSubnet.get().getNetworkId().getValue());
+             Optional<L2BridgeDomain> optBd = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+                     IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
+             if (!optBd.isPresent()) {
+                 LOG.warn(
+                         "Could not read L2-Bridge-Domain {} Modifiaction of it's parent to L3-Context of router {} aborted.",
+                         l2BdId, newRouter.getUuid());
+                 rwTx.cancel();
+                 return;
+             }
+             L2BridgeDomain l2BdWithGw = new L2BridgeDomainBuilder(optBd.get())
+                 .setParent(new L3ContextId(l3ContextId.getValue()))
+                 .build();
+             rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId),
+                     l2BdWithGw);
+         } 
+    }
+
+    private static @Nonnull ForwardingContext createL3ContextFromRouter(
+            Router router) {
+        Name l3ContextName = null;
+        if (!Strings.isNullOrEmpty(router.getName())) {
+            l3ContextName = new Name(router.getName());
+        }
+        return new ForwardingContextBuilder().setContextId(new ContextId(router.getUuid().getValue()))
+            .setContextType(MappingUtils.L3_CONTEXT)
+            .setName(new Name(l3ContextName.getValue()))
+            .build();
+    }
+
+    @Deprecated
+    private static @Nonnull L3Context createL3CtxFromRouter(Router router) {
         Name l3ContextName = null;
         if (!Strings.isNullOrEmpty(router.getName())) {
             l3ContextName = new Name(router.getName());
@@ -178,7 +321,15 @@ public class NeutronRouterAware implements NeutronAware<Router> {
             .build();
     }
 
-    private static void addNeutronExtGwGbpMapping(EndpointL3Key epL3Key, ReadWriteTransaction rwTx) {
+    private static void addNeutronExtGwGbpMapping(ContextId contextId, IpPrefix ipPrefix, ReadWriteTransaction rwTx) {
+        ExternalGatewayAsEndpoint externalGatewayL3Endpoint = MappingFactory.createEaxternalGatewayAsEndpoint(
+                contextId, ipPrefix);
+        rwTx.put(LogicalDatastoreType.OPERATIONAL,
+                NeutronGbpIidFactory.externalGatewayAsEndpoint(contextId, ipPrefix, MappingUtils.L3_CONTEXT), externalGatewayL3Endpoint, true);
+    }
+
+    @Deprecated
+    private static void addNeutronExtGwMapping(EndpointL3Key epL3Key, ReadWriteTransaction rwTx) {
         ExternalGatewayAsL3Endpoint externalGatewayL3Endpoint =
                 MappingFactory.createExternalGatewayByL3Endpoint(epL3Key);
         rwTx.put(LogicalDatastoreType.OPERATIONAL,
index 8fc2c843d59441e33a9c22b2a13abd0af366886c..adf9442f14e3666e28066637c99b4be39ee8b743 100644 (file)
@@ -22,10 +22,16 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 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.NetworkDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentForwarding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentForwardingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.SubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
@@ -71,10 +77,11 @@ public class NeutronSubnetAware implements
         }
 
         Network networkOfSubnet = potentialNetwork.get();
-        Subnet subnet = null;
+
+        NetworkDomain subnetDomain = null;
         if (NetworkUtils.isProviderPhysicalNetwork(networkOfSubnet)) {
             // add virtual router IP only in case it is provider physical network
-            subnet = createSubnet(neutronSubnet, neutronSubnet.getGatewayIp());
+            subnetDomain = createSubnet(neutronSubnet, neutronSubnet.getGatewayIp());
             IpAddress gatewayIp = neutronSubnet.getGatewayIp();
             boolean registeredDefaultRoute = epRegistrator.registerExternalL3PrefixEndpoint(MappingUtils.DEFAULT_ROUTE,
                     new L3ContextId(neutronSubnet.getNetworkId().getValue()), gatewayIp, tenantId);
@@ -84,35 +91,79 @@ public class NeutronSubnetAware implements
                 rwTx.cancel();
                 return;
             }
-        } else if (NetworkUtils.isRouterExternal(networkOfSubnet)) {
+        } else {
             // virtual router IP is not set and it will be set when router gateway port is set
-            subnet = createSubnet(neutronSubnet, null);
+            // or when a router port is attached to a network
+            subnetDomain = createSubnet(neutronSubnet, null);
+        }
+        processTenantSubnet(neutronSubnet, networkOfSubnet, tenantId, rwTx);
+        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain, true);
+        DataStoreHelper.submitToDs(rwTx);
+    }
+
+    public static NetworkDomain createSubnet(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet subnet,
+            IpAddress virtualRouterIp) {
+        SubnetBuilder sb = new SubnetBuilder();
+        sb.setIpPrefix(Utils.createIpPrefix(subnet.getCidr()));
+        sb.setVirtualRouterIp(virtualRouterIp);
+        NetworkDomainBuilder ndb = new NetworkDomainBuilder();
+        if (!Strings.isNullOrEmpty(subnet.getName())) {
+            try {
+                ndb.setName(new Name(subnet.getName()));
+            } catch (Exception e) {
+                LOG.info("Name '{}' of Neutron Subnet '{}' is ignored.", subnet.getName(), subnet.getUuid().getValue());
+                LOG.debug("Name exception", e);
+            }
+        }
+        ndb.setNetworkDomainId(new NetworkDomainId(subnet.getUuid().getValue()));
+        ndb.setNetworkDomainType(MappingUtils.SUBNET);
+        ndb.setParent(MappingUtils.createParent(new NetworkDomainId(subnet.getUuid().getValue()), L2FloodDomain.class));
+        ndb.addAugmentation(SubnetAugmentForwarding.class, new SubnetAugmentForwardingBuilder().setSubnet(sb.build())
+            .build());
+        return ndb.build();
+    }
+
+    @Deprecated
+    private void processTenantSubnet(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet neutronSubnet, Network networkOfSubnet, TenantId tenantId, ReadWriteTransaction rwTx) {
+        Subnet subnet = null;
+        if (NetworkUtils.isProviderPhysicalNetwork(networkOfSubnet)) {
+            // add virtual router IP only in case it is provider physical network
+            subnet = createTenantSubnet(neutronSubnet, neutronSubnet.getGatewayIp());
+            IpAddress gatewayIp = neutronSubnet.getGatewayIp();
+            boolean registeredDefaultRoute = epRegistrator.registerExternalL3PrefixEndpoint(MappingUtils.DEFAULT_ROUTE,
+                    new L3ContextId(neutronSubnet.getNetworkId().getValue()), gatewayIp, tenantId);
+            if (!registeredDefaultRoute) {
+                LOG.warn("Could not add EndpointL3Prefix as default route. Subnet within provider physical network {}",
+                        neutronSubnet);
+                rwTx.cancel();
+                return;
+            }
         } else {
-            // virtual router IP is not set and it will be set when router port is attached to
-            // network
-            subnet = createSubnet(neutronSubnet, null);
+            // virtual router IP is not set and it will be set when router gateway port is set
+            // or when a router port is attached to a network
+            subnet = createTenantSubnet(neutronSubnet, null);
         }
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet, true);
-
-        DataStoreHelper.submitToDs(rwTx);
     }
 
-    public static Subnet createSubnet(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet neutronSubnet,
+    @Deprecated
+    public static Subnet createTenantSubnet(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet subnet,
             IpAddress virtualRouterIp) {
-        SubnetBuilder subnetBuilder = new SubnetBuilder();
-        subnetBuilder.setId(new SubnetId(neutronSubnet.getUuid().getValue()));
-        subnetBuilder.setParent(new ContextId(neutronSubnet.getNetworkId().getValue()));
-        if (!Strings.isNullOrEmpty(neutronSubnet.getName())) {
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder subnetBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder();
+        subnetBuilder.setId(new SubnetId(subnet.getUuid().getValue()));
+        subnetBuilder.setParent(new ContextId(subnet.getNetworkId().getValue()));
+        if (!Strings.isNullOrEmpty(subnet.getName())) {
             try {
-                subnetBuilder.setName(new Name(neutronSubnet.getName()));
+                subnetBuilder.setName(new Name(subnet.getName()));
             } catch (Exception e) {
-                LOG.info("Name '{}' of Neutron Subnet '{}' is ignored.", neutronSubnet.getName(),
-                        neutronSubnet.getUuid().getValue());
+                LOG.info("Name '{}' of Neutron Subnet '{}' is ignored.", subnet.getName(),
+                        subnet.getUuid().getValue());
                 LOG.debug("Name exception", e);
             }
         }
-        subnetBuilder.setIpPrefix(Utils.createIpPrefix(neutronSubnet.getCidr()));
+        subnetBuilder.setIpPrefix(Utils.createIpPrefix(subnet.getCidr()));
         subnetBuilder.setVirtualRouterIp(virtualRouterIp);
         return subnetBuilder.build();
     }
@@ -132,19 +183,30 @@ public class NeutronSubnetAware implements
             Neutron oldNeutron, Neutron newNeutron) {
         LOG.trace("deleted subnet - {}", neutronSubnet);
         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
-        SubnetId subnetId = new SubnetId(neutronSubnet.getUuid().getValue());
+        NetworkDomainId subnetId = new NetworkDomainId(neutronSubnet.getUuid().getValue());
         TenantId tenantId = new TenantId(neutronSubnet.getTenantId().getValue());
-        Optional<Subnet> potentialSubnet = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
+        Optional<NetworkDomain> potentialSubnetDomain = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
                 IidFactory.subnetIid(tenantId, subnetId), rwTx);
-        if (!potentialSubnet.isPresent()) {
-            LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
+        if (!potentialSubnetDomain.isPresent()) {
+            LOG.warn("Illegal state - subnet network domain {} does not exist.", subnetId.getValue());
             rwTx.cancel();
             return;
         }
+        removeTenantSubnet(tenantId, new SubnetId(subnetId), rwTx);
 
         // TODO remove default gateway EP in case when subnet is in provider physical network
 
         DataStoreHelper.submitToDs(rwTx);
     }
 
+    @Deprecated
+    private void removeTenantSubnet(TenantId tenantId, SubnetId subnetId, ReadWriteTransaction rwTx) {
+        Optional<Subnet> potentialSubnet = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.subnetIid(tenantId, subnetId), rwTx);
+        if (!potentialSubnet.isPresent()) {
+            LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
+            rwTx.cancel();
+            return;
+        }
+    }
 }
index 6772d0d5467267e70ab1a62abb66f36d2ed59cc1..8b901cf8ddf7f6cd31c41aba4a49f928e3251aab 100644 (file)
@@ -9,11 +9,23 @@
 package org.opendaylight.groupbasedpolicy.neutron.mapper.util;
 
 import org.opendaylight.groupbasedpolicy.api.sf.AllowActionDefinition;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
 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.groupbasedpolicy.common.rev140421.ActionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.Subnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.ContextType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.fields.Parent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.fields.ParentBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.ActionChoice;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.AllowActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.SfcActionCaseBuilder;
@@ -44,6 +56,12 @@ public final class MappingUtils {
     public static final String NAME_DELIMETER = "_";
     public static final String NAME_DOUBLE_DELIMETER = "__";
 
+    // Network domains defined here to overcome package conflict resolution
+    public static final Class<L3Context> L3_CONTEXT = L3Context.class;
+    public static final Class<L2BridgeDomain> L2_BRDIGE_DOMAIN = L2BridgeDomain.class;
+    public static final Class<L2FloodDomain> L2_FLOOD_DOMAIN = L2FloodDomain.class;
+    public static final Class<Subnet> SUBNET = Subnet.class;
+
     private MappingUtils() {
         throw new UnsupportedOperationException("Cannot create an instance.");
     }
@@ -56,4 +74,69 @@ public final class MappingUtils {
         return new SfcActionCaseBuilder().setSfcChainName(chainName).build();
     }
 
+    public static <T extends ContextType> Parent createParent(ContextId id, Class<T> domainType) {
+        return new ParentBuilder().setContextId(id).setContextType(domainType).build();
+    }
+
+    public static <T extends ContextType> Parent createParent(NetworkDomainId id, Class<T> domainType) {
+        return new ParentBuilder().setContextId(new ContextId(id.getValue())).setContextType(domainType).build();
+    }
+
+    public static IpPrefix ipAddressToIpPrefix(char[] address) {
+        return ipAddressToIpPrefix(new IpAddress(address));
+    }
+
+    public static IpPrefix ipAddressToIpPrefix(IpAddress address) {
+        if (address.getIpv4Address() != null) {
+            return new IpPrefix(new Ipv4Prefix(ipv4PrefixOf(address)));
+        } else if (address.getIpv6Address() != null) {
+            return new IpPrefix(new Ipv6Prefix(ipv6PrefixOf(address)));
+        }
+        throw new IllegalArgumentException("Ip address [{}] is not a valid Ipv4 or Ipv6 address." + address);
+    }
+
+    public static String ipAddressToStringIpPrefix(String address) {
+        return ipAddressToStringIpPrefix(new IpAddress(address.toCharArray()));
+    }
+
+    public static String ipAddressToStringIpPrefix(char[] address) {
+        return ipAddressToStringIpPrefix(new IpAddress(address));
+    }
+
+    public static String ipAddressToStringIpPrefix(IpAddress address) {
+        if (address.getIpv4Address() != null) {
+            return ipv4PrefixOf(address);
+        } else if (address.getIpv6Address() != null) {
+            return ipv6PrefixOf(address);
+        }
+        throw new IllegalArgumentException("Ip address [{}] is not a valid Ipv4 or Ipv6 address." + address);
+    }
+
+    private static String ipv4PrefixOf(IpAddress ipAddress) {
+        return new String(ipAddress.getValue()) + "/32";
+    }
+
+    private static String ipv6PrefixOf(IpAddress ipAddress) {
+        return new String(ipAddress.getValue()) + "/128";
+    }
+
+    public static IpAddress ipPrefixToIpAddress(char[] ipPrefix) {
+        return ipPrefixToIpAddress(new IpPrefix(ipPrefix));
+    }
+
+    public static IpAddress ipPrefixToIpAddress(IpPrefix prefix) {
+        return new IpAddress(ipPrefixToStringIpAddress(prefix).toCharArray());
+    }
+
+    public static String ipPrefixToStringIpAddress(IpPrefix prefix) {
+        if (prefix.getIpv4Prefix() != null) {
+            String[] split = prefix.getIpv4Prefix().getValue().split("/");
+            return split[0];
+
+        } else if (prefix.getIpv6Prefix() != null) {
+            String[] split = prefix.getIpv6Prefix().getValue().split("/");
+            return split[0];
+        }
+        throw new IllegalArgumentException("Cannot extract IP prefix from IP address {}" + prefix);
+    }
 }
index d4e56fe4b9103e9a30ad5cc3c8e6d4a81b7c5bbf..207cc25b63a661a8b632b49e12eabac75ff1955a 100644 (file)
@@ -4,13 +4,17 @@ module neutron-gbp-mapper {
     namespace "urn:opendaylight:groupbasedpolicy:neutron-gbp-mapper";
     prefix "neutron-gbp-mapper";
 
-     import gbp-common { prefix gbp-common; }
+    import gbp-common { prefix gbp-common; }
     import endpoint { prefix gbp-endpoint; }
     import ietf-yang-types { prefix yang; revision-date 2013-07-15; }
     import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
+    import base-endpoint { prefix base-ep; revision-date 2016-04-27; }
+    import forwarding { prefix fwd; revision-date 2016-04-27; }
+    import l2-l3-forwarding { prefix l2-l3; revision-date 2016-04-27; }
 
 
-    description 
+
+    description
         "This module defines the mapping model between Neutron entities and GBP entities.";
 
     revision "2015-05-13" {
@@ -32,6 +36,7 @@ module neutron-gbp-mapper {
             description "Neutron entities by groupbasedpolicy entities";
             container ports-by-endpoints {
                 description "Neutron ports by groupbasedpolicy endpoint";
+                status deprecated;
                 list port-by-endpoint {
                     description "Neutron port key by groupbasedpolicy endpoint key";
                     key "l2-context mac-address";
@@ -39,8 +44,31 @@ module neutron-gbp-mapper {
                     uses neutron-port-key;
                 }
             }
+            container ports-by-base-endpoints {
+                description "Neutron ports by groupbasedpolicy base-endpoint";
+                list port-by-base-endpoint {
+                    description "Neutron port key by groupbasedpolicy base-endpoint key";
+                    key "context-type context-id address-type address";
+                    uses base-ep:address-endpoint-key;
+                    uses neutron-port-key;
+                }
+            }
+
+            container external-gateways-as-endpoints {
+                description "Endpoints that represent Neutron External Gateways for External Subnets.
+                    Please note these ARE NOT Neutron router ports, they are outside of Neutron.";
+                list external-gateway-as-endpoint {
+                    description "Endpoints that represent Neutron External Gateways for External Subnets.
+                        Please note these ARE NOT Neutron router ports, they are outside of Neutron.";
+
+                    key "context-id context-type address address-type";
+
+                    uses base-ep:address-endpoint-key;
+                }
+            }
 
             container external-gateways-as-l3-endpoints {
+                status deprecated; // use external-gateways-as-endpoints
                 description "L3Endpoints that represent Neutron External Gateways for External Subnets.
                     Please note these ARE NOT Neutron router ports, they are outside of Neutron.";
                 list external-gateway-as-l3-endpoint {
@@ -52,6 +80,7 @@ module neutron-gbp-mapper {
             }
 
             container provider-physical-networks-as-l2-flood-domains {
+                status deprecated;
                 list provider-physical-network-as-l2-flood-domain {
                     key "tenant-id l2-flood-domain-id";
                     leaf tenant-id {
@@ -71,12 +100,33 @@ module neutron-gbp-mapper {
                     }
                 }
             }
+
+            container provider-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 {
+                        type gbp-common:context-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 {
             description "Groupbasedpolicy entities by neutron entities";
             container endpoints-by-ports {
                 description "Groupbasedpolicy endpoints by neutron ports";
+                status deprecated;
                 list endpoint-by-port {
                     description "Groupbasedpolicy endpoint key by neutron port key";
                     key port-id;
@@ -84,6 +134,15 @@ module neutron-gbp-mapper {
                     uses gbp-endpoint:l2-key;
                 }
             }
+            container base-endpoints-by-ports {
+                description "Groupbasedpolicy base-endpoints by neutron ports";
+                list base-endpoint-by-port {
+                    description "Groupbasedpolicy base-endpoint key by neutron port key";
+                    key port-id;
+                    uses neutron-port-key;
+                    uses base-ep:address-endpoint-key;
+                }
+            }
         }
     }
 
index ae6fd385fa09e178d8d636d9ad50f1f3f31f2f29..ef58a5c59e7c9668a36e583f91d54d4dfe70ce13 100644 (file)
@@ -9,19 +9,32 @@ import static org.mockito.Mockito.mock;
 import java.util.Iterator;
 
 import org.junit.Test;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.MacAddressType;
 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.GbpByNeutronMappings;
 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.gbp.by.neutron.mappings.BaseEndpointsByPorts;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.EndpointsByPorts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ExternalGatewaysAsEndpoints;
 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.PortsByBaseEndpoints;
 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.external.gateways.as.endpoints.ExternalGatewayAsEndpoint;
 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.ports.by.base.endpoints.PortByBaseEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.base.endpoints.PortByBaseEndpointKey;
 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.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
@@ -56,6 +69,40 @@ public class NeutronGbpIidFactoryTest {
         assertEquals(mac, id.firstKeyOf(PortByEndpoint.class).getMacAddress());
     }
 
+    @Test
+    public void portByBaseEndpointIidTest() {
+        String address = "00:00:00:00:00:00:01";
+        ContextId ctxId = new ContextId("00000000-1111-2222-3333-44444555566667777");
+        PortByBaseEndpointKey key = new PortByBaseEndpointKey(address, MacAddressType.class, ctxId, MappingUtils.L2_BRDIGE_DOMAIN);
+        InstanceIdentifier<PortByBaseEndpoint> id = NeutronGbpIidFactory.portByBaseEndpointIid(key);
+        assertNotNull(id);
+        Class<?>[] expectedTypes = {Mappings.class, NeutronByGbpMappings.class, PortsByBaseEndpoints.class,
+                PortByBaseEndpoint.class};
+        assertPathArgumentTypes(id.getPathArguments(), expectedTypes);
+        assertEquals(PortByBaseEndpoint.class, id.getTargetType());
+        assertFalse(id.isWildcarded());
+        assertEquals(ctxId, id.firstKeyOf(PortByBaseEndpoint.class).getContextId());
+        assertEquals(MappingUtils.L2_BRDIGE_DOMAIN, id.firstKeyOf(PortByBaseEndpoint.class)
+                .getContextType());
+        assertEquals(address, id.firstKeyOf(PortByBaseEndpoint.class).getAddress());
+        assertEquals(MacAddressType.class, id.firstKeyOf(PortByBaseEndpoint.class)
+                .getAddressType());
+    }
+
+    @Test
+    public void baseEndpointByPortTest() {
+        UniqueId portId = new UniqueId("00000000-1111-2222-3333-44444555566667777");
+
+        InstanceIdentifier<BaseEndpointByPort> id = NeutronGbpIidFactory.baseEndpointByPortIid(portId);
+        assertNotNull(id);
+        Class<?>[] expectedTypes = {Mappings.class, GbpByNeutronMappings.class, BaseEndpointsByPorts.class,
+                BaseEndpointByPort.class};
+        assertPathArgumentTypes(id.getPathArguments(), expectedTypes);
+        assertEquals(BaseEndpointByPort.class, id.getTargetType());
+        assertFalse(id.isWildcarded());
+        assertEquals(portId, id.firstKeyOf(BaseEndpointByPort.class).getPortId());
+    }
+
     @Test
     public void externalGatewayAsL3EndpointTest() {
         L3ContextId l3Context = mock(L3ContextId.class);
@@ -74,6 +121,29 @@ public class NeutronGbpIidFactoryTest {
             .getIpAddress());
     }
 
+    @Test
+    public void externalGatewayAsEndpointTest() {
+        String ipAddress = "192.168.50.20/32";
+        IpPrefix ipPrefix = new IpPrefix(ipAddress.toCharArray());
+        ContextId ctxId = new ContextId("00000000-1111-2222-3333-44444555566667777");
+        InstanceIdentifier<ExternalGatewayAsEndpoint> id = NeutronGbpIidFactory.externalGatewayAsEndpoint(
+                ctxId, ipPrefix, MappingUtils.L3_CONTEXT);
+        assertNotNull(id);
+        Class<?>[] expectedTypes = {Mappings.class, NeutronByGbpMappings.class, ExternalGatewaysAsEndpoints.class,
+                ExternalGatewayAsEndpoint.class};
+        assertPathArgumentTypes(id.getPathArguments(), expectedTypes);
+        assertEquals(ExternalGatewayAsEndpoint.class, id.getTargetType());
+        assertFalse(id.isWildcarded());
+        assertEquals(ctxId, id.firstKeyOf(ExternalGatewayAsEndpoint.class)
+            .getContextId());
+        assertEquals(MappingUtils.L3_CONTEXT, id.firstKeyOf(ExternalGatewayAsEndpoint.class)
+                .getContextType());
+        assertEquals(ipAddress, id.firstKeyOf(ExternalGatewayAsEndpoint.class)
+            .getAddress());
+        assertEquals(IpPrefixType.class, id.firstKeyOf(ExternalGatewayAsEndpoint.class)
+                .getAddressType());
+    }
+
     private static void assertPathArgumentTypes(Iterable<PathArgument> pathArguments, Class<?>[] expectedTypes) {
         assertNotNull(pathArguments);
         Iterator<PathArgument> it = pathArguments.iterator();