From f918d8263f30dc26404c03ef1bc6d509e40d473c Mon Sep 17 00:00:00 2001 From: Tomas Cechvala Date: Mon, 23 May 2016 20:42:29 +0200 Subject: [PATCH] Introducing new API in neutron-mapper 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 --- .../groupbasedpolicy/util/IidFactory.java | 100 ++-- .../groupbasedpolicy/util/IidFactoryTest.java | 38 ++ .../gbp/util/NeutronGbpIidFactory.java | 76 ++- .../neutron/mapper/EndpointRegistrator.java | 78 ++- .../neutron/mapper/NeutronMapper.java | 4 +- .../mapper/mapping/MappingFactory.java | 41 ++ .../mapper/mapping/NeutronNetworkAware.java | 125 ++++- .../mapper/mapping/NeutronPortAware.java | 502 ++++++++++++++---- .../mapper/mapping/NeutronRouterAware.java | 241 +++++++-- .../mapper/mapping/NeutronSubnetAware.java | 110 +++- .../neutron/mapper/util/MappingUtils.java | 83 +++ .../src/main/yang/neutron-gbp-mapper.yang | 63 ++- .../gbp/util/NeutronGbpIidFactoryTest.java | 70 +++ 13 files changed, 1293 insertions(+), 238 deletions(-) diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java index f8bb98c2e..9faabd823 100644 --- a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java +++ b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java @@ -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 l2FloodDomainIid(TenantId tenantId, + public static InstanceIdentifier subnetIid(TenantId tenantId, NetworkDomainId id) { + NetworkDomainKey domainKey = new NetworkDomainKey(id, Subnet.class); + return createForwardingByTenantIidBuilder(tenantId).child(NetworkDomain.class, domainKey).build(); + } + + public static InstanceIdentifier l2FloodDomainIid(TenantId tenantId, ContextId id) { + ForwardingContextKey domainKey = new ForwardingContextKey(id, L2FloodDomain.class); + return createForwardingByTenantIidBuilder(tenantId).child(ForwardingContext.class, domainKey).build(); + } + + public static InstanceIdentifier l2BridgeDomainIid(TenantId tenantId, ContextId id) { + ForwardingContextKey domainKey = new ForwardingContextKey(id, L2BridgeDomain.class); + return createForwardingByTenantIidBuilder(tenantId).child(ForwardingContext.class, domainKey).build(); + } + + public static InstanceIdentifier l3ContextIid(TenantId tenantId, ContextId id) { + ForwardingContextKey domainKey = new ForwardingContextKey(id, L3Context.class); + return createForwardingByTenantIidBuilder(tenantId).child(ForwardingContext.class, domainKey).build(); + } + + private static InstanceIdentifierBuilder createForwardingByTenantIidBuilder(TenantId tenantId) { + return InstanceIdentifier.builder(Forwarding.class).child(ForwardingByTenant.class, + new ForwardingByTenantKey(tenantId)); + } + + @Deprecated + public static InstanceIdentifier 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 l2BridgeDomainIid(TenantId tenantId, + @Deprecated + public static InstanceIdentifier 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 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 l3ContextIid(TenantId tenantId, L3ContextId l3ContextId) { + @Deprecated + public static InstanceIdentifier 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 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 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 subnetWildcardIid(TenantId tenantId) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(ForwardingContext.class) - .child(Subnet.class) - .build(); - } - public static InstanceIdentifier followedEndpointgroupIid(RendererName rendererName, TenantId tenantId, EndpointGroupId epgId) { return InstanceIdentifier.builder(Renderers.class) diff --git a/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/util/IidFactoryTest.java b/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/util/IidFactoryTest.java index a168b8fc2..8e3a656bb 100755 --- a/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/util/IidFactoryTest.java +++ b/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/util/IidFactoryTest.java @@ -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 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 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 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 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 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 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 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 identifier = IidFactory.subnetIid(tenantId, subnetId); Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId()); diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactory.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactory.java index e337409c8..c8aaaa6df 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactory.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactory.java @@ -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 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 endpointByPortIid(UniqueId portId) { return InstanceIdentifier .builder( @@ -43,6 +67,16 @@ public class NeutronGbpIidFactory { .build(); } + public static InstanceIdentifier 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 portByEndpointIid(L2BridgeDomainId l2BdId, MacAddress mac) { return InstanceIdentifier .builder( @@ -53,6 +87,22 @@ public class NeutronGbpIidFactory { .build(); } + public static InstanceIdentifier externalGatewayAsEndpoint(ContextId contextId, + IpPrefix ipPrefix, Class 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(L3ContextId l3Context, IpAddress ipAddress) { return InstanceIdentifier @@ -65,15 +115,25 @@ public class NeutronGbpIidFactory { } public static InstanceIdentifier 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 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(); + } } diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java index bc15b4045..25fe227b0 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java @@ -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.of(regEndpointInput)) + .build(); + return registerEndpoint(regBaseEpInput); + } + + public boolean registerEndpoint(RegisterEndpointInput regBaseEpInput) { + try { + RpcResult 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.of(new AddressEndpointUnregBuilder().setKey(addrEpUnreg.getKey()) + .build())).build(); + return unregisterEndpoint(input); + } + + public boolean unregisterEndpoint(UnregisterEndpointInput input) { + try { + RpcResult 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 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 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 l3Gateways = new ArrayList(); @@ -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) diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java index ece7573cd..bfa6523e3 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java @@ -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, 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); diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/MappingFactory.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/MappingFactory.java index 64b5114d2..5be9ff200 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/MappingFactory.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/MappingFactory.java @@ -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())) diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java index 1c0b349ca..045e9624c 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java @@ -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 { 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 { } } - 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 { 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 { LOG.trace("deleted network - {}", network); ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction(); TenantId tenantId = new TenantId(network.getTenantId().getValue()); + ContextId id = new ContextId(network.getUuid().getValue()); + Optional 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 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 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 potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), rwTx); @@ -136,8 +223,12 @@ public class NeutronNetworkAware implements NeutronAware { LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", l2BdId.getValue()); return; } - - DataStoreHelper.submitToDs(rwTx); + L3ContextId l3CtxId = new L3ContextId(l2FdId); + Optional 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; + } } - } diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java index e8cede6ee..f7a891d93 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java @@ -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 { 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 potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(), neutron.getSubnets()); @@ -100,15 +121,22 @@ public class NeutronPortAware implements NeutronAware { 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 { 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 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.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 firstFixedIps = PortUtils.resolveFirstFixedIps(port); + List 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 epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups()); - epgsFromSecGroups.add(NetworkClient.EPG_ID); - epInBuilder.setEndpointGroups(epgsFromSecGroups); - registerEndpointAndStoreMapping(epInBuilder.build(), port); + List 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 { } } - private void changeL3ContextForEpsInSubnet(Uuid subnetUuid, Ports ports, L3ContextId newl3Context) { - Set portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, ports); + private void setParentChildRelationshipForEndpoints(AddressEndpointRegBuilder parentEp, + AddressEndpointRegBuilder childEp) { + childEp.setParentEndpointChoice(new ParentEndpointCaseBuilder().setParentEndpoint( + ImmutableList.of(createParentEndpoint(parentEp))).build()); + parentEp.setChildEndpoint(ImmutableList.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 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 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 { 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 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 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 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 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 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 endpointGroupsToAdd, Neutron neutron) { + Optional 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 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 concatEndpointGroups(List securityGroups, + @Nullable List endpointGroupsToAdd) { + List 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 { 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 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 { 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 potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(), oldNeutron.getSubnets()); + Optional 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 { } } - 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 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 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 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 { 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 routerIfacePorts = PortUtils.findRouterInterfacePorts(neutron.getPorts()); for (Port routerIfacePort : routerIfacePorts) { @@ -341,4 +630,17 @@ public class NeutronPortAware implements NeutronAware { .build(); } + private static ContextId resolveL3ContextForPort(Port port, FixedIps portFixedIPs, Neutron neutron) { + Set 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()); + } } diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAware.java index 7da088ec9..0b0199d9e 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAware.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAware.java @@ -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 { @@ -74,6 +85,39 @@ public class NeutronRouterAware implements NeutronAware { @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 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 { ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction(); TenantId tenantId = new TenantId(newRouter.getTenantId().getValue()); - L3ContextId l3ContextIdFromRouterId = new L3ContextId(newRouter.getUuid().getValue()); - InstanceIdentifier l3ContextIidForRouterId = - IidFactory.l3ContextIid(tenantId, l3ContextIdFromRouterId); - Optional 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 { 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 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 optBd = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx); if (!optBd.isPresent()) { LOG.warn( @@ -158,16 +180,137 @@ public class NeutronRouterAware implements NeutronAware { 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 l3ContextIid = + IidFactory.l3ContextIid(tenantId, l3ContextId); + Optional 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 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 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 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 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 { .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, diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAware.java index 8fc2c843d..adf9442f1 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAware.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAware.java @@ -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 potentialSubnet = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, + Optional 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 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; + } + } } diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/MappingUtils.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/MappingUtils.java index 6772d0d54..8b901cf8d 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/MappingUtils.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/MappingUtils.java @@ -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 L3_CONTEXT = L3Context.class; + public static final Class L2_BRDIGE_DOMAIN = L2BridgeDomain.class; + public static final Class L2_FLOOD_DOMAIN = L2FloodDomain.class; + public static final Class 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 Parent createParent(ContextId id, Class domainType) { + return new ParentBuilder().setContextId(id).setContextType(domainType).build(); + } + + public static Parent createParent(NetworkDomainId id, Class 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); + } } diff --git a/neutron-mapper/src/main/yang/neutron-gbp-mapper.yang b/neutron-mapper/src/main/yang/neutron-gbp-mapper.yang index d4e56fe4b..207cc25b6 100644 --- a/neutron-mapper/src/main/yang/neutron-gbp-mapper.yang +++ b/neutron-mapper/src/main/yang/neutron-gbp-mapper.yang @@ -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; + } + } } } diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactoryTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactoryTest.java index ae6fd385f..ef58a5c59 100644 --- a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactoryTest.java +++ b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactoryTest.java @@ -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 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 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 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 pathArguments, Class[] expectedTypes) { assertNotNull(pathArguments); Iterator it = pathArguments.iterator(); -- 2.36.6