Bug 8228 - metadata service fix made cleaner 66/55966/13
authorTomas Cechvala <tcechval@cisco.com>
Mon, 10 Apr 2017 15:39:51 +0000 (17:39 +0200)
committerTomas Cechvala <tcechval@cisco.com>
Tue, 9 May 2017 08:34:15 +0000 (08:34 +0000)
This patch sticks more to the architecture.

In OPNFV scenarios, Openstack metadata service may be reached
via DHCP port which acts as a GW to metadata server. VMs have
a route configured to metadata server via DHCP port.

Metadata IP and port are specified in blueprint cfg file and
processed by neutron-mapper bundle. An ip-prefix  endpoint is
registered by neutron-mapper, it points to the same mac- address
endpoint as DHCP ip-prefix endpoint, i.e. DHCP ip-prefix EP &
Metadata ip-prefix EP point to the same mac address endpoint.

This configuration is supported by VPP renderer's implementation
of location resolver. In this case both DHCP and Metadata have
the same absolute location.

When ACL manager recongnizes this fact, it will build ACL for
both endpoints behind the same interface.

Remote IP prefix is revisioned here too. Remote IP prefix is
mapped to GBP as external ip-prefix endpoint. Location resolver
then looks for external interfaces and on nodes and create a
relative location for this endpoint.

Change-Id: Id72d5646fbd7af1a8094749e58ba714bb3d84959
Signed-off-by: Tomas Cechvala <tcechval@cisco.com>
44 files changed:
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolver.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationInfo.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/util/AddressEndpointUtils.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/DataTreeChangeHandler.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/EndpointUtils.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java
neutron-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_mapper/impl/NeutronMapperInstance.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/MetadataService.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkClient.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkService.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/ServiceUtil.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAware.java
neutron-mapper/src/main/resources/org/opendaylight/blueprint/neutron-mapper.xml
neutron-mapper/src/main/resources/startup.cfg
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkServiceTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAwareDataStoreTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAwareDataStoreTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAwareDataStoreTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSecurityGroupAwareDataStoreTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareDataStoreTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/test/NeutronMapperDataBrokerTest.java
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java
renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/AclManager.java [deleted file]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProvider.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManager.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtil.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AclManager.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/DestinationMapper.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/SourceMapper.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppIidFactory.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManagerTest.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProviderTest.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/BridgeDomainManagerImplTest.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManagerTest.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtilTest.java

index 02f5419e5f6d208145ad8c37836fe89569f9b5bb..623a917d87788181fe6ad44109c9d82293216813 100644 (file)
@@ -105,7 +105,9 @@ public class LocationResolver implements ClusteredDataTreeChangeListener<Locatio
             } else {
                 priority = provider.getPriority();
             }
-            realLocations.get(epKey).remove(priority);
+            if (realLocations.get(epKey) != null) {
+                realLocations.get(epKey).remove(priority);
+            }
             AbsoluteLocation newAbsoluteLocation = getBestAbsoluteLocation(epKey);
             if (newAbsoluteLocation == null) {
                 InstanceIdentifier<AbsoluteLocation> iid = IidFactory.absoluteLocationIid(epKey);
index dabf7e90dddcdb5547ca0f3627fdd050a955f59d..3bae3ff8decb02085947b374abac08a819a4cb7a 100644 (file)
@@ -125,8 +125,7 @@ public class EndpointLocationInfo {
         if (relLocations == null) {
             return false;
         }
-        List<InternalLocation> locs = relLocations.getInternalLocation();
-        if (locs == null) {
+        if (relLocations.getInternalLocation() == null && relLocations.getExternalLocation() == null) {
             return false;
         }
         return true;
index f8688cf0f22cf7641d620fde448cbbe78d89a1b2..623ff8ab5c03f0f783e36c1eb0bafc70d282104a 100644 (file)
@@ -8,7 +8,13 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.util;
 
+import java.util.Optional;
+
 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.absolute.location.absolute.location.LocationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointKey;
@@ -40,8 +46,33 @@ public class AddressEndpointUtils {
                 peerEpKey.getContextType());
     }
 
+    public static AddressEndpointKey fromAddressEndpointWithLocationKey(AddressEndpointWithLocationKey key) {
+        return new AddressEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(), key.getContextType());
+    }
+
     public static AddressEndpointKey fromPeerExtEpKey(PeerExternalEndpointKey peerExtEpKey) {
         return new AddressEndpointKey(peerExtEpKey.getAddress(), peerExtEpKey.getAddressType(),
                 peerExtEpKey.getContextId(), peerExtEpKey.getContextType());
     }
+
+    /**
+     * Compares absolute external locations of address end-points in the arguments.
+     */
+    public static boolean sameExternalLocationCase(AddressEndpointWithLocation ae0, AddressEndpointWithLocation ae1) {
+        if (ae0.getAbsoluteLocation() == null || ae1.getAbsoluteLocation() == null) {
+            return false;
+        }
+        Optional<LocationType> loc0Type = Optional.ofNullable(ae0.getAbsoluteLocation().getLocationType());
+        Optional<LocationType> loc1Type = Optional.ofNullable(ae1.getAbsoluteLocation().getLocationType());
+        if (!(loc0Type.isPresent() && loc0Type.get() instanceof ExternalLocationCase)
+                || !(loc1Type.isPresent() && loc1Type.get() instanceof ExternalLocationCase)) {
+            return false;
+        }
+        ExternalLocationCase loc0 = (ExternalLocationCase) loc0Type.get();
+        ExternalLocationCase loc1 = (ExternalLocationCase) loc1Type.get();
+        return (loc0.getExternalNodeMountPoint() == null || loc1.getExternalNodeMountPoint() == null
+                || loc0.getExternalNodeConnector() == null || loc1.getExternalNodeConnector() == null) ? false : loc0
+                    .getExternalNodeMountPoint().toString().equals(loc1.getExternalNodeMountPoint().toString())
+                        && loc0.getExternalNodeConnector().equals(loc1.getExternalNodeConnector());
+    }
 }
index 9321163a46847a48cee874785f1d06e17fd847d3..f19797fb378d2ce7b9541b635975891b55708baf 100644 (file)
@@ -108,6 +108,13 @@ public abstract class DataTreeChangeHandler<T extends DataObject> implements Clu
 
     @Override
     public void close() {
+        closeRegisteredListener();
+    }
+
+    /**
+     * For child classes which override close() method.
+     */
+    protected void closeRegisteredListener() {
         registeredListener.close();
     }
 
index dcc056a7d90308755bcdfba56e8604e0d4320729..909f69599ef54cfa55ddb13798179769b6cbcecd 100644 (file)
@@ -8,19 +8,34 @@
 
 package org.opendaylight.groupbasedpolicy.util;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.ExecutionException;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
 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.absolute.location.absolute.location.location.type.ExternalLocationCase;
 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.parent.child.endpoints.ParentEndpointChoice;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentContainmentEndpointCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCase;
 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.endpoint._case.ParentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 
 public class EndpointUtils {
 
@@ -57,4 +72,36 @@ public class EndpointUtils {
         }
         return Collections.emptyList();
     }
+
+    public static boolean isExternalEndpoint(@Nonnull DataBroker dataBroker, @Nonnull AddressEndpoint addrEp) {
+        ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+        List<ListenableFuture<Boolean>> results = new ArrayList<>();
+        for (EndpointGroupId epgId : addrEp.getEndpointGroup()) {
+            results.add(Futures.transform(
+                    rTx.read(LogicalDatastoreType.CONFIGURATION,
+                            IidFactory.externalImplicitGroupIid(addrEp.getTenant(), epgId)),
+                    new Function<Optional<ExternalImplicitGroup>, Boolean>() {
+
+                        @Override
+                        public Boolean apply(Optional<ExternalImplicitGroup> input) {
+                            return input.isPresent();
+                        }
+                    }));
+        }
+        rTx.close();
+        try {
+            List<Boolean> list = Futures.allAsList(results).get();
+            return list.stream().anyMatch(Boolean::booleanValue);
+        } catch (InterruptedException | ExecutionException e) {
+            return false;
+        }
+    }
+
+    public static Optional<ExternalLocationCase> getExternalLocationFrom(AddressEndpointWithLocation input) {
+        if (input.getAbsoluteLocation() != null && input.getAbsoluteLocation().getLocationType() != null
+                && input.getAbsoluteLocation().getLocationType() instanceof ExternalLocationCase) {
+            return Optional.of((ExternalLocationCase) input.getAbsoluteLocation().getLocationType());
+        }
+        return Optional.absent();
+    }
 }
index 5c7cf1deed397143bcdb9c19719a2b71db87cb23..6c90580c97e0cfd2b47d9ca15f2cb067a25645d6 100644 (file)
@@ -115,6 +115,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 {
 
@@ -129,96 +130,69 @@ public class IidFactory {
         return InstanceIdentifier.builder(Tenants.class).child(Tenant.class, new TenantKey(id)).build();
     }
 
-    public static InstanceIdentifier<EndpointGroup> endpointGroupIid(TenantId tenantId, EndpointGroupId epgId) {
+    public static InstanceIdentifierBuilder<Policy> policyIid(TenantId tenantId) {
         return InstanceIdentifier.builder(Tenants.class)
             .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(EndpointGroup.class, new EndpointGroupKey(epgId))
-            .build();
+            .child(Policy.class);
+    }
+
+    public static InstanceIdentifier<EndpointGroup> endpointGroupIid(TenantId tenantId, EndpointGroupId epgId) {
+        return policyIid(tenantId).child(EndpointGroup.class, new EndpointGroupKey(epgId)).build();
     }
 
     public static InstanceIdentifier<Contract> contractIid(TenantId tenantId, ContractId contractId) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(Contract.class, new ContractKey(contractId))
-            .build();
+        return policyIid(tenantId).child(Contract.class, new ContractKey(contractId)).build();
     }
 
     public static InstanceIdentifier<Contract> contractWildcardIid(TenantId tenantId) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(Contract.class)
-            .build();
+        return policyIid(tenantId).child(Contract.class).build();
     }
 
     public static InstanceIdentifier<Subject> subjectIid(TenantId tenantId, ContractId contractId,
             SubjectName subjectName) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(Contract.class, new ContractKey(contractId))
+        return policyIid(tenantId).child(Contract.class, new ContractKey(contractId))
             .child(Subject.class, new SubjectKey(subjectName))
             .build();
     }
 
     public static InstanceIdentifier<ProviderNamedSelector> providerNamedSelectorIid(TenantId tenantId,
             EndpointGroupId epgId, SelectorName providerSelectorName) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(EndpointGroup.class, new EndpointGroupKey(epgId))
+        return policyIid(tenantId).child(EndpointGroup.class, new EndpointGroupKey(epgId))
             .child(ProviderNamedSelector.class, new ProviderNamedSelectorKey(providerSelectorName))
             .build();
     }
 
     public static InstanceIdentifier<ConsumerNamedSelector> consumerNamedSelectorIid(TenantId tenantId,
             EndpointGroupId epgId, SelectorName consumerSelectorName) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(EndpointGroup.class, new EndpointGroupKey(epgId))
+        return policyIid(tenantId).child(EndpointGroup.class, new EndpointGroupKey(epgId))
             .child(ConsumerNamedSelector.class, new ConsumerNamedSelectorKey(consumerSelectorName))
             .build();
     }
 
     public static InstanceIdentifier<Clause> clauseIid(TenantId tenantId, ContractId contractId,
             ClauseName clauseName) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(Contract.class, new ContractKey(contractId))
+        return policyIid(tenantId).child(Contract.class, new ContractKey(contractId))
             .child(Clause.class, new ClauseKey(clauseName))
             .build();
     }
 
     public static InstanceIdentifier<Rule> ruleIid(TenantId tenantId, ContractId contractId, SubjectName subjectName,
             RuleName ruleName) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(Contract.class, new ContractKey(contractId))
+        return policyIid(tenantId).child(Contract.class, new ContractKey(contractId))
             .child(Subject.class, new SubjectKey(subjectName))
             .child(Rule.class, new RuleKey(ruleName))
             .build();
     }
 
     public static InstanceIdentifier<ActionInstance> actionInstanceIid(TenantId tenantId, ActionName actionName) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(SubjectFeatureInstances.class)
+        return policyIid(tenantId).child(SubjectFeatureInstances.class)
             .child(ActionInstance.class, new ActionInstanceKey(actionName))
             .build();
     }
 
     public static InstanceIdentifier<ClassifierInstance> classifierInstanceIid(TenantId tenantId,
             ClassifierName classifierName) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(SubjectFeatureInstances.class)
+        return policyIid(tenantId).child(SubjectFeatureInstances.class)
             .child(ClassifierInstance.class, new ClassifierInstanceKey(classifierName))
             .build();
     }
@@ -238,10 +212,7 @@ public class IidFactory {
 
     public static InstanceIdentifier<ClassifierRef> classifierRefIid(TenantId tenantId, ContractId contractId,
             SubjectName subjectName, RuleName ruleName, ClassifierName classifierRefName) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(Contract.class, new ContractKey(contractId))
+        return policyIid(tenantId).child(Contract.class, new ContractKey(contractId))
             .child(Subject.class, new SubjectKey(subjectName))
             .child(Rule.class, new RuleKey(ruleName))
             .child(ClassifierRef.class, new ClassifierRefKey(classifierRefName))
@@ -384,11 +355,7 @@ public class IidFactory {
 
     public static InstanceIdentifier<ExternalImplicitGroup> externalImplicitGroupIid(TenantId tenantId,
             EndpointGroupId epgId) {
-        return InstanceIdentifier.builder(Tenants.class)
-            .child(Tenant.class, new TenantKey(tenantId))
-            .child(Policy.class)
-            .child(ExternalImplicitGroup.class, new ExternalImplicitGroupKey(epgId))
-            .build();
+        return policyIid(tenantId).child(ExternalImplicitGroup.class, new ExternalImplicitGroupKey(epgId)).build();
     }
 
     public static InstanceIdentifier<ContainmentEndpoint> containmentEndpointIid(ContainmentEndpointKey key) {
index e7a6d2cd89cd2c530b27a363679e9dcda4aa5753..b761246edc3a15312775cacbed0e4c4869321333 100644 (file)
@@ -8,7 +8,9 @@
 
 package org.opendaylight.controller.config.yang.config.neutron_mapper.impl;
 
-import java.util.regex.Pattern;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
 
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
@@ -23,6 +25,7 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegist
 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
 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.slf4j.Logger;
@@ -51,11 +54,15 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose
         this.rpcBroker = Preconditions.checkNotNull(rpcBroker);
         this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService);
         try {
-            this.metadataIpPrefix = new IpPrefix(new Ipv4Prefix(Preconditions.checkNotNull(metadataIp)));
+            InetAddress inetAddr = InetAddress.getByName(metadataIp);
+            if (inetAddr instanceof Inet4Address) {
+                this.metadataIpPrefix = new IpPrefix(new Ipv4Prefix(Preconditions.checkNotNull(metadataIp) + "/32"));
+            } else if (inetAddr instanceof Inet6Address) {
+                this.metadataIpPrefix = new IpPrefix(new Ipv6Prefix(Preconditions.checkNotNull(metadataIp) + "/128"));
+            }
             this.metadataPort = Integer.parseInt(Preconditions.checkNotNull(metadataPort));
-            LOG.trace("Resolved Metadata IP prefix: {}", metadataIpPrefix);
+            LOG.info("Resolved Metadata CIDR: {} and port {}.", metadataIpPrefix, metadataPort);
         } catch (Exception ex) {
-
             if (ex instanceof NumberFormatException) {
                 LOG.warn("Metadata port cannot be resolved. Provided value: {}. Continue without support for metadata.",
                     metadataPort);
@@ -65,7 +72,6 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose
             }
             this.metadataIpPrefix = null;
         }
-
     }
 
     public void instantiate() {
index 1b623971797363ece5fb95197aec4c020d579b93..da456032c19f63189996cadc455a0cabe201e536 100644 (file)
@@ -106,13 +106,13 @@ public class NeutronMapper implements ClusteredDataTreeChangeListener<Neutron>,
     private Neutron neutronAfter;
 
     public NeutronMapper(DataBroker dataProvider, EndpointService epService, BaseEndpointService baseEpService,
-        @Nullable IpPrefix metadataIpPrefix, long metadataPort) {
+        @Nullable IpPrefix metadataIpPrefix, long metadataTcpPort) {
         EndpointRegistrator epRegistrator = new EndpointRegistrator(epService, baseEpService);
-        networkAware = new NeutronNetworkAware(dataProvider, metadataIpPrefix, metadataPort);
-        securityRuleAware = new NeutronSecurityRuleAware(dataProvider);
+        networkAware = new NeutronNetworkAware(dataProvider, metadataTcpPort);
+        securityRuleAware = new NeutronSecurityRuleAware(dataProvider, epRegistrator);
         securityGroupAware = new NeutronSecurityGroupAware(dataProvider, securityRuleAware);
         subnetAware = new NeutronSubnetAware(dataProvider, epRegistrator);
-        portAware = new NeutronPortAware(dataProvider, epRegistrator);
+        portAware = new NeutronPortAware(dataProvider, epRegistrator, metadataIpPrefix);
         routerAware = new NeutronRouterAware(dataProvider, epRegistrator);
         floatingIpAware = new NeutronFloatingIpAware(dataProvider);
         registerDataTreeChangeListener =
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/MetadataService.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/MetadataService.java
new file mode 100644 (file)
index 0000000..5fe1220
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
+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.SubjectName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraints;
+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.EndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.SubjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
+
+import com.google.common.collect.ImmutableList;
+
+public class MetadataService extends ServiceUtil {
+
+    private static final ClassifierName METADATA_SERVER_TO_CLIENT_NAME =
+        new ClassifierName("METADATA_FROM_SERVER_TO_CLIENT");
+    private static final ClassifierName METADATA_CLIENT_TO_SERVER_NAME =
+        new ClassifierName("METADATA_FROM_CLIENT_TO_SERVER");
+    private static final SubjectName METADATA_SUBJECT_NAME = new SubjectName("ALLOW_METADATA");
+    private static final Description METADATA_CONTRACT_DESC =
+        new Description("Allow METADATA management communication between server and client.");
+
+    /**
+     * Id of {@link #METADATA_CONTRACT}
+     */
+    public static final ContractId METADATA_CONTRACT_ID = new ContractId("be0675b7-b0d6-46cc-acf1-247ed31cf572");
+    /**
+     * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching ICMP and SSH
+     * communication
+     * between Client and Server.
+     */
+    public static final Contract METADATA_CONTRACT;
+    /**
+     * {@link ConsumerNamedSelector} pointing to {@link #METADATA_CONTRACT}
+     */
+    public static final ConsumerNamedSelector METADATA_CONTRACT_CONSUMER_SELECTOR;
+
+    // ########### NETWORK-SERVICE ENDPOINT-GROUP
+    private static final Name METADATA_SERVICE_EPG_NAME = new Name("NETWORK_SERVICE");
+    private static final Description METADATA_SERVICE_EPG_DESC = new Description("Represents DHCP and DNS servers.");
+    /**
+     * ID of {@link #EPG}
+     */
+    public static final EndpointGroupId EPG_ID = new EndpointGroupId("ffff1111-dfe5-11e4-8a00-1681e6b88ec1");
+    /**
+     * Network-service endpoint-group providing {@link #METADATA_CONTRACT}
+     */
+    public static final EndpointGroup EPG;
+
+    static {
+        METADATA_CONTRACT = createContractMetadata();
+        METADATA_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(METADATA_CONTRACT);
+        EPG = createNetworkServiceEpg();
+    }
+
+    private static EndpointGroup createNetworkServiceEpg() {
+        ProviderNamedSelector metadataProviderSelector = createProviderSelector(METADATA_CONTRACT);
+        return createEpgBuilder(EPG_ID, METADATA_SERVICE_EPG_NAME, METADATA_SERVICE_EPG_DESC)
+            .setProviderNamedSelector(ImmutableList.of(metadataProviderSelector))
+            .build();
+    }
+
+    private static Contract createContractMetadata() {
+        Rule serverClientMetadataIpv4Rule = createRuleAllow(METADATA_SERVER_TO_CLIENT_NAME, Direction.Out);
+        Rule clientServerMetadataIpv4Rule = createRuleAllow(METADATA_CLIENT_TO_SERVER_NAME, Direction.In);
+        Subject subject = new SubjectBuilder().setName(METADATA_SUBJECT_NAME)
+            .setOrder(0)
+            .setRule(ImmutableList.of(serverClientMetadataIpv4Rule, clientServerMetadataIpv4Rule))
+            .build();
+        return createContract(METADATA_CONTRACT_ID, ImmutableList.of(subject), METADATA_CONTRACT_DESC);
+    }
+
+    /**
+     * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
+     * and {@link ProviderMatchers}. This clause points to subject in {@link #METADATA_CONTRACT}.
+     *
+     * @param tenantId location of {@link #METADATA_CONTRACT}
+     * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
+     * @param wTx transaction where entities are written
+     */
+    public static void writeMetadataClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
+        WriteTransaction wTx) {
+        Clause clause = createClauseWithConsProvEic(ipPrefix, METADATA_SUBJECT_NAME);
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, METADATA_CONTRACT_ID, clause.getName()),
+            clause, true);
+    }
+
+    /**
+     * Puts network service entities (classifier-instances, {@link #METADATA_CONTRACT},
+     * and {@link #EPG}) to {@link LogicalDatastoreType#CONFIGURATION}
+     *
+     * @param tenantId location of network-service entities
+     * @param wTx transaction where network-service entities are written
+     */
+    public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx, long metadataPort) {
+        Set<ClassifierInstance> classifierInstances = getAllClassifierInstances(metadataPort);
+        for (ClassifierInstance ci : classifierInstances) {
+            wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, ci.getName()), ci,
+                    true);
+        }
+        for (ActionInstance ai : Collections.singleton(MappingUtils.ACTION_ALLOW)) {
+            wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.actionInstanceIid(tenantId, ai.getName()), ai, true);
+        }
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, METADATA_CONTRACT_ID), METADATA_CONTRACT,
+                true);
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true);
+    }
+
+    /**
+     * @return All classifier-instances used in {@link #METADATA_CONTRACT}
+     */
+    public static Set<ClassifierInstance> getAllClassifierInstances(long metadataPort) {
+        HashSet<ClassifierInstance> cis = new HashSet<>();
+        // METADATA
+        cis.add(createMetadataIpv4ClientServer(metadataPort));
+        cis.add(createMetadataIpv4ServerClient(metadataPort));
+        return cis;
+    }
+
+    private static ClassifierInstance createMetadataIpv4ClientServer(long dstPort) {
+        return createClassifInstance(METADATA_CLIENT_TO_SERVER_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, null, dstPort));
+    }
+
+    private static ClassifierInstance createMetadataIpv4ServerClient(long srcPort) {
+        return createClassifInstance(METADATA_SERVER_TO_CLIENT_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, srcPort, null));
+    }
+}
index 0ac5cf05e860c9ba5bf5ec8fb4616db7660ef80c..75a7907a0155320cdfb876b341c10ecfa0446ef7 100644 (file)
@@ -16,13 +16,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 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.policy.rev140421.tenants.tenant.policy.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector;
 
 import com.google.common.base.Preconditions;
 
-public class NetworkClient {
+public class NetworkClient extends ServiceUtil {
 
     private static final Name NETWORK_CLIENT_EPG_NAME = new Name("NETWORK_CLIENT");
     private static final Description NETWORK_CLIENT_EPG_DESC = new Description("Represents DHCP and DNS clients.");
@@ -40,11 +38,7 @@ public class NetworkClient {
     }
 
     private static EndpointGroup createNetworkClientEpg() {
-        return new EndpointGroupBuilder().setId(EPG_ID)
-            .setName(NETWORK_CLIENT_EPG_NAME)
-            .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
-            .setDescription(NETWORK_CLIENT_EPG_DESC)
-            .build();
+        return createEpgBuilder(EPG_ID, NETWORK_CLIENT_EPG_NAME, NETWORK_CLIENT_EPG_DESC).build();
     }
 
     /**
index 5ce0b774c391a84edce458bce0df285baa61cbb5..5dad3f0595a70a65e5390efead1d177c038738bc 100755 (executable)
@@ -8,10 +8,8 @@
 
 package org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 import javax.annotation.Nullable;
@@ -22,56 +20,33 @@ import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
 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.ParameterName;
-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.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
-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.has.classifier.refs.ClassifierRefBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraints;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
 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.ContractBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.SubjectBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchers;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelectorBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;
 
 import com.google.common.collect.ImmutableList;
 
-public class NetworkService {
+public class NetworkService extends ServiceUtil {
 
     /**
      * Unit tests {@link NetworkServiceTest}
@@ -175,30 +150,6 @@ public class NetworkService {
      */
     public static final ConsumerNamedSelector MGMT_CONTRACT_CONSUMER_SELECTOR;
 
-    // ########### METADATA management
-    private static final ClassifierName METADATA_SERVER_TO_CLIENT_NAME =
-        new ClassifierName("METADATA_FROM_SERVER_TO_CLIENT");
-    private static final ClassifierName METADATA_CLIENT_TO_SERVER_NAME =
-        new ClassifierName("METADATA_FROM_CLIENT_TO_SERVER");
-    private static final SubjectName METADATA_SUBJECT_NAME = new SubjectName("ALLOW_METADATA");
-    private static final Description METADATA_CONTRACT_DESC =
-        new Description("Allow METADATA management communication between server and client.");
-
-    /**
-     * Id of {@link #METADATA_CONTRACT}
-     */
-    public static final ContractId METADATA_CONTRACT_ID = new ContractId("be0675b7-b0d6-46cc-acf1-247ed31cf572");
-    /**
-     * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching ICMP and SSH
-     * communication
-     * between Client and Server.
-     */
-    public static final Contract METADATA_CONTRACT;
-    /**
-     * {@link ConsumerNamedSelector} pointing to {@link #METADATA_CONTRACT}
-     */
-    public static final ConsumerNamedSelector METADATA_CONTRACT_CONSUMER_SELECTOR;
-
     // ########### NETWORK-SERVICE ENDPOINT-GROUP
     private static final Name NETWORK_SERVICE_EPG_NAME = new Name("NETWORK_SERVICE");
     private static final Description NETWORK_SERVICE_EPG_DESC = new Description("Represents DHCP and DNS servers.");
@@ -218,8 +169,6 @@ public class NetworkService {
         DNS_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(DNS_CONTRACT);
         MGMT_CONTRACT = createContractMgmt();
         MGMT_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(MGMT_CONTRACT);
-        METADATA_CONTRACT = createContractMetadata();
-        METADATA_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(METADATA_CONTRACT);
         EPG = createNetworkServiceEpg();
     }
 
@@ -227,27 +176,8 @@ public class NetworkService {
         ProviderNamedSelector dhcpProviderSelector = createProviderSelector(DHCP_CONTRACT);
         ProviderNamedSelector dnsProviderSelector = createProviderSelector(DNS_CONTRACT);
         ProviderNamedSelector mgmtProviderSelector = createProviderSelector(MGMT_CONTRACT);
-        ProviderNamedSelector metadataProviderSelector = createProviderSelector(METADATA_CONTRACT);
-        return new EndpointGroupBuilder().setId(EPG_ID)
-            .setName(NETWORK_SERVICE_EPG_NAME)
-            .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector, mgmtProviderSelector,
-                metadataProviderSelector))
-            .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
-            .setDescription(NETWORK_SERVICE_EPG_DESC)
-            .build();
-    }
-
-    private static ProviderNamedSelector createProviderSelector(Contract contract) {
-        SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue());
-        return new ProviderNamedSelectorBuilder().setName(selectorName)
-            .setContract(ImmutableList.of(contract.getId()))
-            .build();
-    }
-
-    private static ConsumerNamedSelector createConsumerSelector(Contract contract) {
-        SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue());
-        return new ConsumerNamedSelectorBuilder().setName(selectorName)
-            .setContract(ImmutableList.of(contract.getId()))
+        return createEpgBuilder(EPG_ID, NETWORK_SERVICE_EPG_NAME, NETWORK_SERVICE_EPG_DESC)
+            .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector, mgmtProviderSelector))
             .build();
     }
 
@@ -261,10 +191,7 @@ public class NetworkService {
             .setRule(ImmutableList.of(clientServerIpv4Rule, serverClientIpv4Rule, clientServerIpv6Rule,
                     serverClientIpv6Rule))
             .build();
-        return new ContractBuilder().setId(DHCP_CONTRACT_ID)
-            .setSubject(ImmutableList.of(subject))
-            .setDescription(DHCP_CONTRACT_DESC)
-            .build();
+        return createContract(DHCP_CONTRACT_ID, ImmutableList.of(subject), DHCP_CONTRACT_DESC);
     }
 
     private static Contract createContractDns() {
@@ -282,10 +209,7 @@ public class NetworkService {
                     serverClientUdpIpv6Rule, clientServerTcpIpv4Rule, serverClientTcpIpv4Rule, clientServerTcpIpv6Rule,
                     serverClientTcpIpv6Rule))
             .build();
-        return new ContractBuilder().setId(DNS_CONTRACT_ID)
-            .setSubject(ImmutableList.of(subject))
-            .setDescription(DNS_CONTRACT_DESC)
-            .build();
+        return createContract(DNS_CONTRACT_ID, ImmutableList.of(subject), DNS_CONTRACT_DESC);
     }
 
     private static Contract createContractMgmt() {
@@ -304,43 +228,7 @@ public class NetworkService {
                     clientServerSshIpv6Rule, clientServerIcmpIpv4Rule, clientServerIcmpIpv6Rule,
                     serverClientIcmpIpv4Rule, serverClientIcmpIpv6Rule))
             .build();
-        return new ContractBuilder().setId(MGMT_CONTRACT_ID)
-            .setSubject(ImmutableList.of(subject))
-            .setDescription(MGMT_CONTRACT_DESC)
-            .build();
-    }
-
-    private static Contract createContractMetadata() {
-        Rule serverClientMetadataIpv4Rule = createRuleAllow(METADATA_SERVER_TO_CLIENT_NAME, Direction.Out);
-        Rule clientServerMetadataIpv4Rule = createRuleAllow(METADATA_CLIENT_TO_SERVER_NAME, Direction.In);
-        Rule serverClientIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
-        Rule serverClientIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
-        Rule clientServerIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
-        Rule clientServerIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
-
-        Subject subject = new SubjectBuilder().setName(METADATA_SUBJECT_NAME)
-            .setOrder(0)
-            .setRule(ImmutableList.of(serverClientMetadataIpv4Rule, clientServerMetadataIpv4Rule,
-                clientServerIcmpIpv4Rule, clientServerIcmpIpv6Rule,
-                serverClientIcmpIpv4Rule, serverClientIcmpIpv6Rule))
-            .build();
-        return new ContractBuilder().setId(METADATA_CONTRACT_ID)
-            .setSubject(ImmutableList.of(subject))
-            .setDescription(METADATA_CONTRACT_DESC)
-            .build();
-    }
-
-    private static Rule createRuleAllow(ClassifierName classifierName, Direction direction) {
-        ClassifierName name =
-                new ClassifierName(direction.name() + MappingUtils.NAME_DOUBLE_DELIMETER + classifierName.getValue());
-        ClassifierRef classifierRef = new ClassifierRefBuilder().setName(name)
-            .setInstanceName(classifierName)
-            .setDirection(direction)
-            .build();
-        return new RuleBuilder().setName(new RuleName(name))
-            .setActionRef(ImmutableList.<ActionRef>of(MappingUtils.ACTION_REF_ALLOW))
-            .setClassifierRef(ImmutableList.of(classifierRef))
-            .build();
+        return createContract(MGMT_CONTRACT_ID, ImmutableList.of(subject), MGMT_CONTRACT_DESC);
     }
 
     /**
@@ -388,54 +276,6 @@ public class NetworkService {
                 clause, true);
     }
 
-    /**
-     * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
-     * and {@link ProviderMatchers}. This clause points to subject in {@link #METADATA_CONTRACT}.
-     *
-     * @param tenantId location of {@link #METADATA_CONTRACT}
-     * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
-     * @param wTx transaction where entities are written
-     */
-    public static void writeMetadataClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
-        WriteTransaction wTx) {
-        Clause clause = createClauseWithConsProvEic(ipPrefix, METADATA_SUBJECT_NAME);
-        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, METADATA_CONTRACT_ID, clause.getName()),
-            clause, true);
-    }
-
-    private static Clause createClauseWithConsProvEic(@Nullable IpPrefix ipPrefix, SubjectName subjectName) {
-        ConsumerMatchers consumerMatchers = null;
-        ProviderMatchers providerMatchers = null;
-        StringBuilder clauseName = new StringBuilder();
-        clauseName.append(subjectName.getValue());
-        if (ipPrefix != null) {
-            clauseName.append(MappingUtils.NAME_DOUBLE_DELIMETER).append(Utils.getStringIpPrefix(ipPrefix));
-            consumerMatchers =
-                    new ConsumerMatchersBuilder()
-                        .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
-                            .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
-                                .setPrefixConstraint(
-                                        ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
-                                .build())
-                            .build())
-                        .build();
-            providerMatchers =
-                    new ProviderMatchersBuilder()
-                        .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
-                            .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
-                                .setPrefixConstraint(
-                                        ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
-                                .build())
-                            .build())
-                        .build();
-        }
-        return new ClauseBuilder().setName(new ClauseName(clauseName.toString()))
-            .setSubjectRefs(ImmutableList.of(subjectName))
-            .setConsumerMatchers(consumerMatchers)
-            .setProviderMatchers(providerMatchers)
-            .build();
-    }
-
     /**
      * Puts network service entities (classifier-instances, {@link #DHCP_CONTRACT},
      * {@link #DNS_CONTRACT}, {@link #MGMT_CONTRACT} and {@link #EPG}) to
@@ -444,8 +284,8 @@ public class NetworkService {
      * @param tenantId location of network-service entities
      * @param wTx transaction where network-service entities are written
      */
-    public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx, long metadataPort) {
-        Set<ClassifierInstance> classifierInstances = getAllClassifierInstances(metadataPort);
+    public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx) {
+        Set<ClassifierInstance> classifierInstances = getAllClassifierInstances();
         for (ClassifierInstance ci : classifierInstances) {
             wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, ci.getName()), ci,
                     true);
@@ -459,8 +299,6 @@ public class NetworkService {
                 true);
         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, MGMT_CONTRACT_ID), MGMT_CONTRACT,
                 true);
-        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, METADATA_CONTRACT_ID), METADATA_CONTRACT,
-                true);
         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true);
     }
 
@@ -468,7 +306,7 @@ public class NetworkService {
      * @return All classifier-instances used in {@link #DHCP_CONTRACT}, {@link #DNS_CONTRACT} and
      *         {@link #MGMT_CONTRACT}
      */
-    public static Set<ClassifierInstance> getAllClassifierInstances(long metadataPort) {
+    public static Set<ClassifierInstance> getAllClassifierInstances() {
         HashSet<ClassifierInstance> cis = new HashSet<>();
         cis.add(createDhcpIpv4ClientServer());
         cis.add(createDhcpIpv4ServerClient());
@@ -489,198 +327,127 @@ public class NetworkService {
         cis.add(createSshTcpIpv6ClientServer());
         cis.add(createIcmpIpv4());
         cis.add(createIcmpIpv6());
-        // METADATA
-        cis.add(createMetadataIpv4ClientServer(metadataPort));
-        cis.add(createMetadataIpv4ServerClient(metadataPort));
-
         return cis;
     }
 
     // ###################### DHCP
     private static ClassifierInstance createDhcpIpv4ClientServer() {
-        return new ClassifierInstanceBuilder().setName(DHCP_IPV4_CLIENT_SERVER_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
-                    DHCP_IPV4_CLIENT_PORT, DHCP_IPV4_SERVER_PORT))
-            .build();
+        return createClassifInstance(DHCP_IPV4_CLIENT_SERVER_NAME, L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
+                        DHCP_IPV4_CLIENT_PORT, DHCP_IPV4_SERVER_PORT));
     }
 
     private static ClassifierInstance createDhcpIpv4ServerClient() {
-        return new ClassifierInstanceBuilder().setName(DHCP_IPV4_SERVER_CLIENT_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
-                    DHCP_IPV4_SERVER_PORT, DHCP_IPV4_CLIENT_PORT))
-            .build();
+        return createClassifInstance(DHCP_IPV4_SERVER_CLIENT_NAME, L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
+                        DHCP_IPV4_SERVER_PORT, DHCP_IPV4_CLIENT_PORT));
     }
 
     private static ClassifierInstance createDhcpIpv6ClientServer() {
-        return new ClassifierInstanceBuilder().setName(DHCP_IPV6_CLIENT_SERVER_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
-                    DHCP_IPV6_CLIENT_PORT, DHCP_IPV6_SERVER_PORT))
-            .build();
+        return createClassifInstance(DHCP_IPV6_CLIENT_SERVER_NAME, L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
+                        DHCP_IPV6_CLIENT_PORT, DHCP_IPV6_SERVER_PORT));
     }
 
     private static ClassifierInstance createDhcpIpv6ServerClient() {
-        return new ClassifierInstanceBuilder().setName(DHCP_IPV6_SERVER_CLIENT_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
-                    DHCP_IPV6_SERVER_PORT, DHCP_IPV6_CLIENT_PORT))
-            .build();
+        return createClassifInstance(DHCP_IPV6_SERVER_CLIENT_NAME, L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
+                        DHCP_IPV6_SERVER_PORT, DHCP_IPV6_CLIENT_PORT));
     }
 
     // ###################### DNS UDP
     private static ClassifierInstance createDnsUdpIpv4ClientServer() {
-        return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_CLIENT_SERVER_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, DNS_SERVER_PORT))
-            .build();
+        return createClassifInstance(DNS_UDP_IPV4_CLIENT_SERVER_NAME, L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null,
+                        DNS_SERVER_PORT));
     }
 
     private static ClassifierInstance createDnsUdpIpv4ServerClient() {
-        return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_SERVER_CLIENT_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, DNS_SERVER_PORT, null))
-            .build();
+        return createClassifInstance(DNS_UDP_IPV4_SERVER_CLIENT_NAME, L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
+                        DNS_SERVER_PORT, null));
     }
 
     private static ClassifierInstance createDnsUdpIpv6ClientServer() {
-        return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_CLIENT_SERVER_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, DNS_SERVER_PORT))
-            .build();
+        return createClassifInstance(DNS_UDP_IPV6_CLIENT_SERVER_NAME, L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null,
+                        DNS_SERVER_PORT));
     }
 
     private static ClassifierInstance createDnsUdpIpv6ServerClient() {
-        return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_SERVER_CLIENT_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, DNS_SERVER_PORT, null))
-            .build();
+        return createClassifInstance(DNS_UDP_IPV6_SERVER_CLIENT_NAME, L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
+                        DNS_SERVER_PORT, null));
     }
 
     // ###################### DNS TCP
     private static ClassifierInstance createDnsTcpIpv4ClientServer() {
-        return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_CLIENT_SERVER_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT))
-            .build();
+        return createClassifInstance(DNS_TCP_IPV4_CLIENT_SERVER_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT));
     }
 
     private static ClassifierInstance createDnsTcpIpv4ServerClient() {
-        return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_SERVER_CLIENT_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null))
-            .build();
+        return createClassifInstance(DNS_TCP_IPV4_SERVER_CLIENT_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null));
     }
 
     private static ClassifierInstance createDnsTcpIpv6ClientServer() {
-        return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_CLIENT_SERVER_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT))
-            .build();
+        return createClassifInstance(DNS_TCP_IPV6_CLIENT_SERVER_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv6_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT));
     }
 
     private static ClassifierInstance createDnsTcpIpv6ServerClient() {
-        return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_SERVER_CLIENT_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null))
-            .build();
+        return createClassifInstance(DNS_TCP_IPV6_SERVER_CLIENT_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv6_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null));
     }
 
     // ###################### SSH TCP
     private static ClassifierInstance createSshTcpIpv4ClientServer() {
-        return new ClassifierInstanceBuilder().setName(SSH_IPV4_CLIENT_TO_SERVER_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null))
-            .build();
+        return createClassifInstance(SSH_IPV4_CLIENT_TO_SERVER_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null));
     }
 
     private static ClassifierInstance createSshTcpIpv4ServerClient() {
-        return new ClassifierInstanceBuilder().setName(SSH_IPV4_SERVER_TO_CLIENT_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT))
-            .build();
+        return createClassifInstance(SSH_IPV4_SERVER_TO_CLIENT_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv4_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT));
     }
 
     private static ClassifierInstance createSshTcpIpv6ClientServer() {
-        return new ClassifierInstanceBuilder().setName(SSH_IPV6_CLIENT_TO_SERVER_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null))
-            .build();
+        return createClassifInstance(SSH_IPV6_CLIENT_TO_SERVER_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv6_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null));
     }
 
     private static ClassifierInstance createSshTcpIpv6ServerClient() {
-        return new ClassifierInstanceBuilder().setName(SSH_IPV6_SERVER_TO_CLIENT_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                    createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT))
-            .build();
+        return createClassifInstance(SSH_IPV6_SERVER_TO_CLIENT_NAME,
+                L4ClassifierDefinition.DEFINITION.getId(),
+                createParams(EtherTypeClassifierDefinition.IPv6_VALUE,
+                        IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT));
     }
 
     // ###################### ICMP
     private static ClassifierInstance createIcmpIpv4() {
-        return new ClassifierInstanceBuilder().setName(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME)
-            .setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null))
-            .build();
+        return createClassifInstance(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME,
+                IpProtoClassifierDefinition.DEFINITION.getId(), createParams(
+                        EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null));
     }
 
     private static ClassifierInstance createIcmpIpv6() {
-        return new ClassifierInstanceBuilder().setName(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME)
-            .setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null))
-            .build();
-    }
-
-    // ###################### METADATA
-    private static ClassifierInstance createMetadataIpv4ClientServer(long dstPort) {
-        return new ClassifierInstanceBuilder().setName(METADATA_CLIENT_TO_SERVER_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null,
-                    dstPort))
-            .build();
-    }
-
-    private static ClassifierInstance createMetadataIpv4ServerClient(long srcPort) {
-        return new ClassifierInstanceBuilder().setName(METADATA_SERVER_TO_CLIENT_NAME)
-            .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
-            .setParameterValue(
-                createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE,
-                    srcPort, null))
-            .build();
-    }
-
-    private static List<ParameterValue> createParams(long etherType, long proto, @Nullable Long srcPort,
-            @Nullable Long dstPort) {
-        List<ParameterValue> params = new ArrayList<>();
-        if (srcPort != null) {
-            params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.SRC_PORT_PARAM))
-                .setIntValue(srcPort)
-                .build());
-        }
-        if (dstPort != null) {
-            params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM))
-                .setIntValue(dstPort)
-                .build());
-        }
-        params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM))
-            .setIntValue(proto)
-            .build());
-        params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))
-            .setIntValue(etherType)
-            .build());
-        return params;
+        return createClassifInstance((ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME),
+                IpProtoClassifierDefinition.DEFINITION.getId(), createParams(
+                        EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null));
     }
 }
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/ServiceUtil.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/ServiceUtil.java
new file mode 100644 (file)
index 0000000..db66f12
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
+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.ParameterName;
+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.policy.rev140421.HasDirection.Direction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
+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.has.classifier.refs.ClassifierRefBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
+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.ContractBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;
+
+import com.google.common.collect.ImmutableList;
+
+public class ServiceUtil {
+
+    protected static Contract createContract(ContractId cid, List<Subject> subjects, Description description) {
+        return new ContractBuilder().setId(cid).setSubject(subjects).setDescription(description).build();
+    }
+
+    protected static ClassifierInstance createClassifInstance(ClassifierName name, ClassifierDefinitionId id,
+            List<ParameterValue> pv) {
+        return new ClassifierInstanceBuilder().setName(name)
+            .setClassifierDefinitionId(id)
+            .setParameterValue(pv)
+            .build();
+    }
+
+    protected static EndpointGroupBuilder createEpgBuilder(EndpointGroupId epgId, Name name, Description description) {
+        return new EndpointGroupBuilder().setId(epgId)
+            .setName(name)
+            .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
+            .setDescription(description);
+    }
+
+    protected static List<ParameterValue> createParams(long etherType, long proto, @Nullable Long srcPort,
+            @Nullable Long dstPort) {
+        List<ParameterValue> params = new ArrayList<>();
+        if (srcPort != null) {
+            params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.SRC_PORT_PARAM))
+                .setIntValue(srcPort)
+                .build());
+        }
+        if (dstPort != null) {
+            params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM))
+                .setIntValue(dstPort)
+                .build());
+        }
+        params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM))
+            .setIntValue(proto)
+            .build());
+        params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))
+            .setIntValue(etherType)
+            .build());
+        return params;
+    }
+
+    protected static Clause createClauseWithConsProvEic(@Nullable IpPrefix ipPrefix, SubjectName subjectName) {
+         ConsumerMatchers consumerMatchers = null;
+         ProviderMatchers providerMatchers = null;
+         StringBuilder clauseName = new StringBuilder();
+         clauseName.append(subjectName.getValue());
+         if (ipPrefix != null) {
+             clauseName.append(MappingUtils.NAME_DOUBLE_DELIMETER).append(Utils.getStringIpPrefix(ipPrefix));
+             consumerMatchers =
+                     new ConsumerMatchersBuilder()
+                         .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
+                             .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
+                                 .setPrefixConstraint(
+                                         ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
+                                 .build())
+                             .build())
+                         .build();
+             providerMatchers =
+                     new ProviderMatchersBuilder()
+                         .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
+                             .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
+                                 .setPrefixConstraint(
+                                         ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
+                                 .build())
+                             .build())
+                         .build();
+         }
+         return new ClauseBuilder().setName(new ClauseName(clauseName.toString()))
+             .setSubjectRefs(ImmutableList.of(subjectName))
+             .setConsumerMatchers(consumerMatchers)
+             .setProviderMatchers(providerMatchers)
+             .build();
+     }
+
+    protected static Rule createRuleAllow(ClassifierName classifierName, Direction direction) {
+         ClassifierName name =
+                 new ClassifierName(direction.name() + MappingUtils.NAME_DOUBLE_DELIMETER + classifierName.getValue());
+         ClassifierRef classifierRef = new ClassifierRefBuilder().setName(name)
+             .setInstanceName(classifierName)
+             .setDirection(direction)
+             .build();
+         return new RuleBuilder().setName(new RuleName(name))
+             .setActionRef(ImmutableList.<ActionRef>of(MappingUtils.ACTION_REF_ALLOW))
+             .setClassifierRef(ImmutableList.of(classifierRef))
+             .build();
+     }
+
+    protected static ProviderNamedSelector createProviderSelector(Contract contract) {
+         SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue());
+         return new ProviderNamedSelectorBuilder().setName(selectorName)
+             .setContract(ImmutableList.of(contract.getId()))
+             .build();
+     }
+
+    protected static ConsumerNamedSelector createConsumerSelector(Contract contract) {
+         SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue());
+         return new ConsumerNamedSelectorBuilder().setName(selectorName)
+             .setContract(ImmutableList.of(contract.getId()))
+             .build();
+     }
+}
index c7d7ca2b0a015c3748b96a5fca24346ed8ea0b72..00342dcb2d82a5084ae249d1070ad59ae811c654 100644 (file)
@@ -12,21 +12,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import java.util.HashSet;
 import java.util.Set;
 
-import javax.annotation.Nullable;
-
 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.domain_extension.l2_l3.util.L2L3IidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.MetadataService;
 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.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 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;
@@ -60,13 +58,11 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
             InstanceIdentifier.builder(Neutron.class).child(Networks.class).child(Network.class).build();
     private final DataBroker dataProvider;
     private final Set<TenantId> tenantsWithRouterAndNetworkServiceEntities = new HashSet<>();
-    private final IpPrefix metadataIpPrefix;
-    private final long metadataPort;
+    private final long metadataTcpPort;
 
-    public NeutronNetworkAware(DataBroker dataProvider, @Nullable IpPrefix metadataIpPrefix, long metadataPort) {
+    public NeutronNetworkAware(DataBroker dataProvider, long metadataPort) {
         this.dataProvider = checkNotNull(dataProvider);
-        this.metadataIpPrefix = metadataIpPrefix;
-        this.metadataPort = metadataPort;
+        this.metadataTcpPort = metadataPort;
     }
 
     @Override
@@ -108,7 +104,7 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
 
         if (!tenantsWithRouterAndNetworkServiceEntities.contains(tenantId)) {
             tenantsWithRouterAndNetworkServiceEntities.add(tenantId);
-            NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx, metadataPort);
+            NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx);
             NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
             NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
             NetworkService.writeMgmtClauseWithConsProvEic(tenantId, null, rwTx);
@@ -116,9 +112,11 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DHCP_CONTRACT_CONSUMER_SELECTOR, rwTx);
             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DNS_CONTRACT_CONSUMER_SELECTOR, rwTx);
             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.MGMT_CONTRACT_CONSUMER_SELECTOR, rwTx);
-            if (metadataIpPrefix != null) {
-                NetworkService.writeMetadataClauseWithConsProvEic(tenantId, metadataIpPrefix, rwTx);
-                NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.METADATA_CONTRACT_CONSUMER_SELECTOR,
+            MetadataService.writeMetadataClauseWithConsProvEic(tenantId, null, rwTx);
+            if (metadataTcpPort != 0) {
+                MetadataService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx, metadataTcpPort);
+                MetadataService.writeMetadataClauseWithConsProvEic(tenantId, null, rwTx);
+                NetworkClient.writeConsumerNamedSelector(tenantId, MetadataService.METADATA_CONTRACT_CONSUMER_SELECTOR,
                     rwTx);
             }
         }
index c6bb87ddc0109be347f3137dd16cfc2b84fcbf06..f9550d7bc78c877fa251167a44d756b5ae6c67ef 100644 (file)
@@ -10,8 +10,10 @@ 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;
+import java.util.stream.Collectors;
 
 import javax.annotation.Nullable;
 
@@ -22,6 +24,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.domain_extension.l2_l3.util.L2L3IidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.MetadataService;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
@@ -29,6 +32,8 @@ 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.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.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;
@@ -76,8 +81,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIpsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIpsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortBuilder;
 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.Subnet;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -86,6 +94,7 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 
 public class NeutronPortAware implements NeutronAware<Port> {
 
@@ -94,10 +103,13 @@ public class NeutronPortAware implements NeutronAware<Port> {
             InstanceIdentifier.builder(Neutron.class).child(Ports.class).child(Port.class).build();
     private final DataBroker dataProvider;
     private final EndpointRegistrator epRegistrator;
+    private final IpPrefix metadataIpPrefix;
 
-    public NeutronPortAware(DataBroker dataProvider, EndpointRegistrator epRegistrator) {
+    public NeutronPortAware(DataBroker dataProvider, EndpointRegistrator epRegistrator,
+            @Nullable IpPrefix metadataIpPrefix) {
         this.dataProvider = checkNotNull(dataProvider);
         this.epRegistrator = checkNotNull(epRegistrator);
+        this.metadataIpPrefix = checkNotNull(metadataIpPrefix);
     }
 
     @Override public void onCreated(Port createdItem, Neutron neutron) {
@@ -193,21 +205,26 @@ public class NeutronPortAware implements NeutronAware<Port> {
             NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
             List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
             epgsFromSecGroups.add(NetworkService.EPG_ID);
-
-            // BUILD BASE ENDPOINT
             AddressEndpointRegBuilder l2BaseEp = createBasicMacAddrEpInputBuilder(port, networkContainment,
-                    epgsFromSecGroups);
+                    Collections.emptyList());
             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, addBaseEpMapping);
+
+            AddressEndpointRegBuilder metadataEp = createBasicL3AddrEpInputBuilder(cloneMetadataPortFromDhcpPort(port, metadataIpPrefix), networkContainment,
+                    Lists.newArrayList(MetadataService.EPG_ID), neutron);
+            setParentChildRelationshipForEndpoints(metadataEp, l2BaseEp);
+            registerBaseEndpointAndStoreMapping(
+                    ImmutableList.of(metadataEp.build()), port, rwTx, true);
+
             registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isNormalPort(port)) {
@@ -252,6 +269,15 @@ public class NeutronPortAware implements NeutronAware<Port> {
         }
     }
 
+    private Port cloneMetadataPortFromDhcpPort(Port port, IpPrefix metadataPrefix) {
+        IpAddress metadataIp = MappingUtils.ipPrefixToIpAddress(metadataPrefix);
+        List<FixedIps> metadataIps = port.getFixedIps().stream().map(fi -> {
+            FixedIpsKey key = new FixedIpsKey(metadataIp, fi.getKey().getSubnetId());
+            return new FixedIpsBuilder(fi).setKey(key).setIpAddress(metadataIp).build();
+        }).collect(Collectors.toList());
+        return new PortBuilder(port).setFixedIps(metadataIps).build();
+    }
+
     private void setParentChildRelationshipForEndpoints(AddressEndpointRegBuilder parentEp,
             AddressEndpointRegBuilder childEp) {
         childEp.setParentEndpointChoice(new ParentEndpointCaseBuilder().setParentEndpoint(
@@ -456,7 +482,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
             Port port, ReadWriteTransaction rwTx) {
         boolean isRegisteredEndpoint = epRegistrator.registerEndpoint(regEpInput);
         if (!isRegisteredEndpoint) {
-            LOG.error("Failed to register an endpoint: {}", regEpInput);
+            LOG.error("Failed to register endpoint: {}", regEpInput);
             return;
         }
         UniqueId portId = new UniqueId(port.getUuid().getValue());
@@ -497,7 +523,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
 
         boolean isRegisteredBaseEndpoint = epRegistrator.registerEndpoint(regBaseEpInput);
         if (!isRegisteredBaseEndpoint) {
-            LOG.error("Failed to register an address endpoint: {}", addrEpRegs);
+            LOG.error("Failed to register address endpoint: {}", addrEpRegs);
             return;
         }
         for (AddressEndpointReg addrEpReg : addrEpRegs) {
index 86e21b876a58761e99ae47af0953c47e5f554c2a..62006ec9016a26d93606b2bf62b09ac89dfc3dac 100644 (file)
@@ -14,7 +14,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.stream.Collector;
 import java.util.stream.Collectors;
 
 import javax.annotation.Nonnull;
@@ -26,27 +25,36 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
 import org.opendaylight.groupbasedpolicy.dto.EpgKeyDto;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronSecurityGroupAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SecurityGroupUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SecurityRuleUtils;
 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.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.register.endpoint.input.AddressEndpointRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName;
 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.IpPrefixType;
 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.SfcActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
 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.EndpointGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector;
@@ -54,6 +62,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstanceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
+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.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroupKey;
@@ -85,21 +94,23 @@ public class NeutronSecurityRuleAware implements NeutronAware<SecurityRule> {
     private final Map<SecurityGroupKey, SecurityGroup> pendingDeletedGroups;
     final static String PROVIDED_BY = "provided_by-";
     final static String POSSIBLE_CONSUMER = "possible_consumer-";
+    private final EndpointRegistrator epRegistrator;
 
-    public NeutronSecurityRuleAware(DataBroker dataProvider) {
+    public NeutronSecurityRuleAware(DataBroker dataProvider, EndpointRegistrator epRegistrator) {
         this(dataProvider, HashMultiset.<InstanceIdentifier<ClassifierInstance>>create(),
-                HashMultiset.<InstanceIdentifier<ActionInstance>>create());
+                HashMultiset.<InstanceIdentifier<ActionInstance>>create(), epRegistrator);
     }
 
     @VisibleForTesting
     NeutronSecurityRuleAware(DataBroker dataProvider,
             Multiset<InstanceIdentifier<ClassifierInstance>> classifierInstanceNames,
-            Multiset<InstanceIdentifier<ActionInstance>> createdActionInstances) {
+            Multiset<InstanceIdentifier<ActionInstance>> createdActionInstances, EndpointRegistrator epRegistrator) {
         this.dataProvider = checkNotNull(dataProvider);
         this.createdClassifierInstances = checkNotNull(classifierInstanceNames);
         this.createdActionInstances = checkNotNull(createdActionInstances);
         this.pendingCreatedRules = new HashMap<>();
         this.pendingDeletedGroups = new HashMap<>();
+        this.epRegistrator = Preconditions.checkNotNull(epRegistrator);
     }
 
     @Override
@@ -155,7 +166,7 @@ public class NeutronSecurityRuleAware implements NeutronAware<SecurityRule> {
         EndpointGroupId providerEpgId = new EndpointGroupId(providerSecGroupId.getValue());
 
         Description contractDescription = createContractDescription(secRule, neutron);
-        SingleRuleContract singleRuleContract = createSingleRuleContract(secRule, contractDescription, action);
+        SingleRuleContract singleRuleContract = createSingleRuleContract(secRule, contractDescription, action, neutron);
         Contract contract = singleRuleContract.getContract();
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, contract.getId()), contract, true);
         SelectorName providerSelector = getSelectorNameWithConsumer(secRule, neutron);
@@ -196,8 +207,44 @@ public class NeutronSecurityRuleAware implements NeutronAware<SecurityRule> {
     }
 
     @VisibleForTesting
-    static SingleRuleContract createSingleRuleContract(SecurityRule secRule, Description contractDescription, ActionChoice action) {
+    SingleRuleContract createSingleRuleContract(SecurityRule secRule, Description contractDescription,
+            ActionChoice action, Neutron neutron) {
         if (secRule.getRemoteIpPrefix() != null) {
+            if (neutron.getNetworks() != null && neutron.getNetworks().getNetwork() != null) {
+                java.util.Optional<Network> publicNet = neutron.getNetworks()
+                    .getNetwork()
+                    .stream()
+                    .filter(net -> NetworkUtils.isRouterExternal(net))
+                    .findAny();
+                if (publicNet.isPresent()) {
+                    WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+                    wTx.merge(LogicalDatastoreType.CONFIGURATION,
+                            IidFactory.externalImplicitGroupIid(new TenantId(secRule.getTenantId().getValue()),
+                                    MappingUtils.EPG_EXTERNAL_ID),
+                            new ExternalImplicitGroupBuilder().setId(MappingUtils.EPG_EXTERNAL_ID).build(), true);
+                    wTx.merge(LogicalDatastoreType.CONFIGURATION,
+                            IidFactory.endpointGroupIid(new TenantId(secRule.getTenantId().getValue()),
+                                    MappingUtils.EPG_EXTERNAL_ID),
+                            new EndpointGroupBuilder().setId(MappingUtils.EPG_EXTERNAL_ID).build(), true);
+                    DataStoreHelper.submitToDs(wTx);
+                    AddressEndpointRegBuilder addrEpbuilder = new AddressEndpointRegBuilder()
+                        .setAddress(String.valueOf(secRule.getRemoteIpPrefix().getValue()))
+                        .setAddressType(IpPrefixType.class)
+                        .setContextType(MappingUtils.L3_CONTEXT)
+                        .setContextId(new ContextId(publicNet.get().getUuid().getValue()))
+                        .setTenant(new TenantId(secRule.getTenantId().getValue()))
+                        .setTimestamp(System.currentTimeMillis())
+                        .setEndpointGroup(ImmutableList.<EndpointGroupId>of(MappingUtils.EPG_EXTERNAL_ID));
+                    RegisterEndpointInput regEp = new RegisterEndpointInputBuilder()
+                        .setAddressEndpointReg(ImmutableList.of(addrEpbuilder.build())).build();
+                    boolean registered = epRegistrator.registerEndpoint(regEp);
+                    if (registered) {
+                        LOG.info("Registering endpoint representing remote-ip-prefix {}", addrEpbuilder.getKey());
+                    } else {
+                        LOG.error("Failed to register endpoint {}", addrEpbuilder.getKey());
+                    }
+                }
+            }
             return new SingleRuleContract(secRule, 0, contractDescription, action);
         }
         return new SingleRuleContract(secRule, 400, contractDescription, action);
index ed69af45fb4e5557111984c0f9e6abe0d00306bd..b9bc8a3650cf9a795ee4d57d8704577526eeb24a 100644 (file)
@@ -10,7 +10,7 @@
 
     <cm:property-placeholder persistent-id="org.opendaylight.groupbasedpolicy.neutron.mapper.startup" update-strategy="none">
         <cm:default-properties>
-            <cm:property name="metadata-ip" value="169.254.169.254/32"/>
+            <cm:property name="metadata-ip" value="169.254.169.254"/>
             <cm:property name="metadata-port" value="80"/>
         </cm:default-properties>
     </cm:property-placeholder>
index 4fa71dd15923628b9de39abcac7f3eaaa0a56c93..6ba246d09e2f6edfe3c4384a4cb1899f342d7f8f 100644 (file)
@@ -6,7 +6,7 @@
 # To explicitly specify which IP prefix should be used for metadata
 # service in openstack, uncomment and modify following line.
 # Specifying one IP for metadata service is currently supported.
-#metadata-ip = 169.254.169.254/32
+#metadata-ip = 169.254.169.254
 
 # To explicitly specify which port should be used for metadata
 # service in openstack, uncomment and modify following line.
index 121476820d5fc42575c17fb18868f7150776e2cf..2d5c2fcb5ceb42ad65f758c5ca698fe936090715 100644 (file)
@@ -178,7 +178,7 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
         // ipv4
         DataBroker dataBroker = getDataBroker();
         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
-        NetworkService.writeMetadataClauseWithConsProvEic(new TenantId(tenantId), metadataIpv4Prefix, rwTx);
+        MetadataService.writeMetadataClauseWithConsProvEic(new TenantId(tenantId), metadataIpv4Prefix, rwTx);
         rwTx.submit().get();
 
         // expected clause name
@@ -186,7 +186,7 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
             + metadataIpv4Prefix.getIpv4Prefix().getValue();
         clauseNameIpV4 = clauseNameIpV4.replace('/', '_');
 
-        PolicyAssert.assertClauseExists(dataBroker, tenantId, NetworkService.METADATA_CONTRACT_ID.getValue(),
+        PolicyAssert.assertClauseExists(dataBroker, tenantId, MetadataService.METADATA_CONTRACT_ID.getValue(),
             clauseNameIpV4);
     }
 
@@ -195,7 +195,7 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
         // write everything
         DataBroker dataBroker = getDataBroker();
         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
-        NetworkService.writeNetworkServiceEntitiesToTenant(new TenantId(tenantId), rwTx, METADATA_IPV4_SERVER_PORT);
+        NetworkService.writeNetworkServiceEntitiesToTenant(new TenantId(tenantId), rwTx);
         rwTx.submit().get();
 
         // read classifier instances
@@ -217,14 +217,11 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
         PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, SSH_IPV6_CLIENT_TO_SERVER_NAME);
         PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME);
         PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME);
-        PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, METADATA_CLIENT_TO_SERVER_NAME);
-        PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, METADATA_SERVER_TO_CLIENT_NAME);
 
         // read contracts
         PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.DHCP_CONTRACT_ID.getValue());
         PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.DNS_CONTRACT_ID.getValue());
         PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.MGMT_CONTRACT_ID.getValue());
-        PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.METADATA_CONTRACT_ID.getValue());
 
         // read group id
         PolicyAssert.assertEndpointGroupExists(dataBroker, tenantId, NetworkService.EPG_ID.getValue());
@@ -233,10 +230,10 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
     @Test
     public void testGetAllClassifierInstances() {
         Set<ClassifierInstance> classifierInstances =
-            NetworkService.getAllClassifierInstances(METADATA_IPV4_SERVER_PORT);
+            NetworkService.getAllClassifierInstances();
         assertNotNull(classifierInstances);
         assertFalse(classifierInstances.isEmpty());
-        assertEquals(20, classifierInstances.size());
+        assertEquals(18, classifierInstances.size());
     }
 
 }
index 3cc85f2baeaba649b191f70281356872de6ae51d..e18818bd472a5e7ee3540373825267a88f89f08c 100644 (file)
@@ -85,7 +85,7 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes
             .addAugmentation(NetworkProviderExtension.class, providerExtension)
             .build();
 
-        networkAware = new NeutronNetworkAware(dataBroker, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT);
+        networkAware = new NeutronNetworkAware(dataBroker, METADATA_IPV4_SERVER_PORT);
     }
 
     @Rule
@@ -94,7 +94,7 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes
     @Test
     public void testConstructor_invalidArgument() throws NullPointerException {
         thrown.expect(NullPointerException.class);
-        new NeutronNetworkAware(null, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT);
+        new NeutronNetworkAware(null, METADATA_IPV4_SERVER_PORT);
     }
 
     @Test
index 8d375b4b18bca161308b29a96561814c2a70d4ea..0f7d0608740cc93cce5c446035262df03e4921fa 100644 (file)
@@ -25,7 +25,9 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBr
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.PortUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.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;
@@ -71,7 +73,7 @@ public class NeutronPortAwareDataStoreTest extends NeutronMapperDataBrokerTest {
                 any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput.class)))
                     .thenReturn(true);
 
-        portAware = new NeutronPortAware(dataBroker, epRegistrator);
+        portAware = new NeutronPortAware(dataBroker, epRegistrator, new IpPrefix(new Ipv4Prefix("192.168.192.168/32")));
     }
 
     @Rule
@@ -80,7 +82,7 @@ public class NeutronPortAwareDataStoreTest extends NeutronMapperDataBrokerTest {
     @Test
     public void testConstructor_invalidArgument() throws NullPointerException {
         thrown.expect(NullPointerException.class);
-        new NeutronPortAware(null, null);
+        new NeutronPortAware(null, null, null);
     }
 
     @Test
index b6e42d545b62e1479051e03279a7d3272729d635..813d8df7d0b52a0c53b5341d60e52f9144eecc7c 100644 (file)
@@ -112,7 +112,7 @@ public class NeutronRouterAwareDataStoreTest extends NeutronMapperDataBrokerTest
                     .thenReturn(futureRpcResult);
         epRegistrator = new EndpointRegistrator(epService, baseEpService);
 
-        networkAware = new NeutronNetworkAware(dataBroker, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT);
+        networkAware = new NeutronNetworkAware(dataBroker, METADATA_IPV4_SERVER_PORT);
         network = new NetworkBuilder().setTenantId(tenantUuid).setUuid(networkUuid).setName("networkName").build();
 
         routerAware = new NeutronRouterAware(dataBroker, epRegistrator);
index bb2f9695c7b9bad10cab0a54f774c8bd5007a8dc..c4bfd09b6b23a16afc593b46ac91e26d00d0ff5b 100644 (file)
@@ -8,6 +8,10 @@
 
 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
 
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import org.apache.commons.lang3.StringUtils;
 import org.junit.Before;
 import org.junit.Rule;
@@ -15,11 +19,14 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronEntityFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.PolicyAssert;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 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.UnregisterEndpointInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroupBuilder;
@@ -34,14 +41,26 @@ public class NeutronSecurityGroupAwareDataStoreTest extends NeutronMapperDataBro
     private NeutronSecurityGroupAware groupAware;
     private SecurityGroup secGroup1;
     private SecurityGroup secGroup2;
+    private EndpointRegistrator epRegistrator;
 
     @Before
     public void init() {
         dataBroker = getDataBroker();
-        groupAware = new NeutronSecurityGroupAware(dataBroker, new NeutronSecurityRuleAware(dataBroker));
 
         secGroup1 = NeutronEntityFactory.securityGroup(secGroupId1, tenantId);
         secGroup2 = NeutronEntityFactory.securityGroup(secGroupId2, tenantId);
+
+
+        epRegistrator = mock(EndpointRegistrator.class);
+        when(epRegistrator.registerEndpoint(any(RegisterEndpointInput.class))).thenReturn(true);
+        when(epRegistrator.registerEndpoint(
+                any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput.class)))
+                    .thenReturn(true);
+        when(epRegistrator.unregisterEndpoint(any(UnregisterEndpointInput.class))).thenReturn(true);
+        when(epRegistrator.unregisterEndpoint(
+                any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput.class)))
+                    .thenReturn(true);
+        groupAware = new NeutronSecurityGroupAware(dataBroker, new NeutronSecurityRuleAware(dataBroker, epRegistrator));
     }
 
     @Test
index a5ee96a3bf84511c3b5a2a14c4244447a64351a5..5e73207974fe0b84ca156cef83af9e1be87243d0 100644 (file)
@@ -13,13 +13,15 @@ import static org.junit.Assert.fail;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.ConfigDataStoreReader;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronEntityFactory;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.PolicyAssert;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
@@ -56,6 +58,13 @@ import com.google.common.collect.ImmutableSet;
 
 public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrokerTest {
 
+    private EndpointRegistrator epRegistrator;
+
+    @Before
+    public void init() {
+        epRegistrator = getEpRegistrator();
+    }
+
     @Test
     public final void testAddNeutronSecurityRule_rulesWithRemoteIpPrefix() throws Exception {
         String tenant = "ad4c6c25-2424-4ad3-97ee-f9691ce03645";
@@ -98,7 +107,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok
                     ImmutableList.of(goldInIpv4, goldOutIpv4, serverIn80Tcp10_1_1_0, serverInIp20_1_1_0, serverOutIpv4))
                 .build())
             .build();
-        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker);
+        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator);
         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
         ruleAware.addNeutronSecurityRule(goldInIpv4, neutron, rwTx);
         ruleAware.addNeutronSecurityRule(goldOutIpv4, neutron, rwTx);
@@ -158,7 +167,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok
     @Test
     public final void testAddAndDeleteNeutronSecurityRule() throws Exception {
         DataBroker dataBroker = getDataBroker();
-        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker);
+        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator);
 
         final String tenantId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa";
         final String secGroupId1 = "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb";
@@ -282,7 +291,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok
             .setSecurityRules(new SecurityRulesBuilder()
                     .setSecurityRule(ImmutableList.of(goldInIpv4, goldOutIpv4, serverOutIpv4, serverInIpv4)).build())
             .build();
-        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker);
+        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator);
         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
         ruleAware.addNeutronSecurityRule(goldInIpv4, neutron, rwTx);
         ruleAware.addNeutronSecurityRule(goldOutIpv4, neutron, rwTx);
@@ -363,7 +372,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok
             .setSecurityRules(new SecurityRulesBuilder()
                 .setSecurityRule(ImmutableList.of(goldInIpv4, goldOutIpv4, serverOutIpv4, serverIn80TcpIpv4)).build())
             .build();
-        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker);
+        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator);
         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
         ruleAware.addNeutronSecurityRule(goldInIpv4, neutron, rwTx);
         ruleAware.addNeutronSecurityRule(goldOutIpv4, neutron, rwTx);
@@ -431,7 +440,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok
         secGroups.add(NeutronEntityFactory.securityGroup(defaultSecGrp, tenant));
         Neutron neutron = new NeutronBuilder()
             .setSecurityGroups(new SecurityGroupsBuilder().setSecurityGroup(secGroups).build()).build();
-        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker);
+        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator);
         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
         ruleAware.addNeutronSecurityRule(defaultInIpv4Default, neutron, rwTx);
         ruleAware.addNeutronSecurityRule(defaultInIpv6Default, neutron, rwTx);
@@ -463,7 +472,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok
     @Test
     public void testConstructor_invalidArgument() throws Exception {
         try {
-            new NeutronSecurityRuleAware(null);
+            new NeutronSecurityRuleAware(null, null);
             fail(NullPointerException.class.getName() + " expected");
         } catch (NullPointerException ex) {
             // do nothing
index b3366fc0b84ac2fd429ac942a770d8ee9d5a59fd..0f0951ee00f34eb50b0ff99c460707f72796157e 100644 (file)
@@ -16,8 +16,10 @@ import static org.junit.Assert.assertTrue;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.ConfigDataStoreReader;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronEntityFactory;
@@ -44,6 +46,13 @@ public class NeutronSecurityRuleAwareTest extends NeutronMapperDataBrokerTest {
     private static final String RULE_TENANT_ID = "00000000-0000-0000-0000-000000000002";
     private static final String RULE_GROUP_ID = "00000000-0000-0000-0000-000000000003";
 
+    private EndpointRegistrator epRegistrator;
+
+    @Before
+    public void init() {
+        epRegistrator = getEpRegistrator();
+    }
+
     @Test
     public final void testIsDirectionOpposite_InIn() {
         assertFalse(NeutronSecurityRuleAware.isDirectionOpposite(Direction.In, Direction.In));
@@ -67,7 +76,7 @@ public class NeutronSecurityRuleAwareTest extends NeutronMapperDataBrokerTest {
     @Test
     public void testNeutronSecurityRuleCreatedAndDeleted() throws Exception {
         DataBroker dataProvider = getDataBroker();
-        NeutronSecurityRuleAware neutronSecurityRuleAware = new NeutronSecurityRuleAware(dataProvider);
+        NeutronSecurityRuleAware neutronSecurityRuleAware = new NeutronSecurityRuleAware(dataProvider, epRegistrator);
 
         //create security rule and put to DS
         SecurityRule neutronRule = buildNeutronSecurityRule();
index 01269fe51b90b609231cb3efa5964db38738ba88..ef416e4f5efad70de6ed430427b5d6a539b7d3d7 100644 (file)
@@ -7,16 +7,24 @@
  */
 package org.opendaylight.groupbasedpolicy.neutron.mapper.test;
 
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import java.util.Collection;
 
-import com.google.common.collect.ImmutableList;
 import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
+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.UnregisterEndpointInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentForwarding;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 
+import com.google.common.collect.ImmutableList;
+
 /**
  * Loads only modules of GBP and it's dependencies for data broker.
  * <br>
@@ -30,4 +38,17 @@ public class NeutronMapperDataBrokerTest extends CustomDataBrokerTest {
                 Mappings.class);
     }
 
+    protected EndpointRegistrator getEpRegistrator() {
+        EndpointRegistrator epRegistrator = mock(EndpointRegistrator.class);
+        when(epRegistrator.registerEndpoint(any(RegisterEndpointInput.class))).thenReturn(true);
+        when(epRegistrator.registerEndpoint(
+                any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput.class)))
+                    .thenReturn(true);
+        when(epRegistrator.unregisterEndpoint(any(UnregisterEndpointInput.class))).thenReturn(true);
+        when(epRegistrator.unregisterEndpoint(
+                any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput.class)))
+                    .thenReturn(true);
+        return epRegistrator;
+    }
+
 }
index 3ca0883ea42a8b8699cacf92a545359e07c2d1b4..d22ff19d011ee91699d45be22a8932271b0a1634 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;
 import java.util.Collections;\r
 import java.util.List;\r
 \r
+import javax.annotation.Nonnull;\r
 import javax.annotation.Nullable;\r
 \r
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;\r
@@ -65,8 +66,6 @@ import org.slf4j.LoggerFactory;
 import com.google.common.annotations.VisibleForTesting;\r
 import com.google.common.base.Optional;\r
 import com.google.common.base.Strings;\r
-\r
-import javax.annotation.Nonnull;\r
 public class PortHandler implements TransactionChainListener {\r
 \r
     private static final Logger LOG = LoggerFactory.getLogger(PortHandler.class);\r
index 9dc7a8537fef15925d7bac222bc9d31fccd76efc..3bac3905ac67b40855e60945df7989ef8623083e 100644 (file)
@@ -22,7 +22,6 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.RendererPolicyListener;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppEndpointListener;
@@ -32,6 +31,7 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.BridgeDomainManagerImpl;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.ForwardingManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.VppRendererPolicyManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.AllowAction;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.Classifier;
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/AclManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/AclManager.java
deleted file mode 100644 (file)
index 502abd7..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.groupbasedpolicy.renderer.vpp.iface;
-
-import java.util.stream.Collectors;
-
-import javax.annotation.Nonnull;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.groupbasedpolicy.renderer.util.AddressEndpointUtils;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.PolicyContext;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListUtil;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-
-public class AclManager {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AclManager.class);
-    private final MountedDataBrokerProvider mountDataProvider;
-
-    public AclManager(@Nonnull MountedDataBrokerProvider mountDataProvider) {
-        this.mountDataProvider = Preconditions.checkNotNull(mountDataProvider);
-    }
-
-    public void updateAclsForPeers(PolicyContext policyCtx, RendererEndpointKey rEpKey) {
-        ImmutableSet<PeerEndpointKey> peers = policyCtx.getPolicyTable().row(rEpKey).keySet();
-        for (RendererEndpointKey peerRendEp : peers.stream()
-            .map(AddressEndpointUtils::fromPeerEpKey)
-            .collect(Collectors.toList())
-            .stream()
-            .map(AddressEndpointUtils::toRendererEpKey)
-            .collect(Collectors.toList())) {
-            updateAclsForRendEp(peerRendEp, policyCtx);
-        }
-    }
-
-    public void updateAclsForRendEp(RendererEndpointKey rEpKey, PolicyContext policyCtx) {
-        LOG.info("Updating policy for endpoint {}", rEpKey);
-        AddressEndpointWithLocation peerAddrEp = policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey));
-        ExternalLocationCase epLoc;
-        try {
-            epLoc = InterfaceManager.resolveAndValidateLocation(peerAddrEp);
-        } catch (NullPointerException | IllegalArgumentException e) {
-            //TODO investigate, don't just move on.
-            LOG.warn("Peer {} has no location. Moving on...", peerAddrEp, e.getMessage());
-            return;
-        }
-        InstanceIdentifier<?> vppNodeIid = epLoc.getExternalNodeMountPoint();
-        Optional<InstanceIdentifier<Interface>> optInterfaceIid =
-                VppPathMapper.interfaceToInstanceIdentifier(epLoc.getExternalNodeConnector());
-        if (!optInterfaceIid.isPresent()) {
-            LOG.warn("Cannot  find interface for endpoint {}. ACLs for endpoint not updated {}. ", rEpKey);
-            return;
-        }
-        Optional<DataBroker> optMountPoint = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);
-        AccessListUtil.resolveAclsOnInterface(rEpKey, policyCtx).forEach(aclWrapper -> aclWrapper
-            .writeAcl(optMountPoint.get(), optInterfaceIid.get().firstKeyOf(Interface.class)));
-    }
-}
index d2bfec90e5b38ea704a2b2496a512840507e474b..9b3471fcb364dd862921e0507d2aa74b2200d6a9 100644 (file)
@@ -589,7 +589,7 @@ public class InterfaceManager implements AutoCloseable {
         }
     }
 
-    static ExternalLocationCase resolveAndValidateLocation(AddressEndpointWithLocation addrEpWithLoc) {
+    public static ExternalLocationCase resolveAndValidateLocation(AddressEndpointWithLocation addrEpWithLoc) {
         LocationType locationType = addrEpWithLoc.getAbsoluteLocation().getLocationType();
         if (!(locationType instanceof ExternalLocationCase)) {
             throw new IllegalArgumentException("Endpoint does not have external location " + addrEpWithLoc);
index 93f770e8ac97eeefda6546e81fee9c354e88465d..3a32c8978792a8a6c1d9cbe020736e8dcdad94ce 100644 (file)
@@ -10,23 +10,41 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.iface;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+
 import javax.annotation.Nonnull;
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.manager.VppNodeManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.CloseOnFailTransactionChain;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.groupbasedpolicy.util.EndpointUtils;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
 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.absolute.location.AbsoluteLocationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCaseBuilder;
+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.RelativeLocationsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocationBuilder;
+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.ParentEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.ProviderName;
 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.LocationProviderBuilder;
@@ -35,20 +53,32 @@ 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.location.provider.ProviderAddressEndpointLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class VppEndpointLocationProvider implements AutoCloseable {
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class VppEndpointLocationProvider extends DataTreeChangeHandler<AddressEndpoint> {
 
     private static final Logger LOG = LoggerFactory.getLogger(VppEndpointLocationProvider.class);
     public static final ProviderName VPP_ENDPOINT_LOCATION_PROVIDER =
             new ProviderName("VPP endpoint location provider");
     public static final long PROVIDER_PRIORITY = 10L;
     private final BindingTransactionChain txChain;
+    private final Map<VppEndpointKey, VppEndpoint> vppEndpoints = new HashMap<>();
+    private final Map<VppEndpointKey, DataObjectModification<AddressEndpoint>> cachedVppEndpoints = new HashMap<>();
 
     public VppEndpointLocationProvider(DataBroker dataProvider) {
+        super(dataProvider);
         LocationProvider locationProvider = new LocationProviderBuilder().setProvider(VPP_ENDPOINT_LOCATION_PROVIDER)
             .setPriority(PROVIDER_PRIORITY)
             .build();
@@ -70,54 +100,171 @@ public class VppEndpointLocationProvider implements AutoCloseable {
                 LOG.error("{} was NOT created", VPP_ENDPOINT_LOCATION_PROVIDER.getValue());
             }
         });
+        registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                InstanceIdentifier.builder(Endpoints.class).child(AddressEndpoints.class).child(AddressEndpoint.class).build()));
     }
 
-    ListenableFuture<Void> createLocationForVppEndpoint(final VppEndpoint vppEndpoint) {
-        final ProviderAddressEndpointLocation providerAddressEndpointLocation =
-                createProviderAddressEndpointLocation(vppEndpoint);
-        final WriteTransaction wTx = txChain.newWriteOnlyTransaction();
-        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.providerAddressEndpointLocationIid(
-                VPP_ENDPOINT_LOCATION_PROVIDER, providerAddressEndpointLocation.getKey()),
-                providerAddressEndpointLocation);
-        LOG.debug("Creating location for {}", providerAddressEndpointLocation.getKey());
-        return Futures.transform(wTx.submit(), (Function<Void, Void>) input -> {
-            LOG.debug("{} provided location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
-                    providerAddressEndpointLocation);
-            return null;
-        });
+    @Override
+    protected void onWrite(DataObjectModification<AddressEndpoint> rootNode,
+            InstanceIdentifier<AddressEndpoint> rootIdentifier) {
+        LOG.debug("onWrite triggered by {}", rootNode.getDataAfter());
+        try {
+            if (EndpointUtils.isExternalEndpoint(dataProvider, rootNode.getDataAfter())) {
+                writeLocation(createRelativeAddressEndpointLocation(rootNode.getDataAfter().getKey(),
+                        VppNodeManager.resolvePublicInterfaces(dataProvider))).get();
+            } else {
+                createAbsoluteAddressEndpointLocation(null, rootNode).get();
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Failed to write location for endpoint {}. {}", rootNode.getDataAfter().getKey(), e.getMessage());
+        }
+    }
+
+    @Override
+    protected void onDelete(DataObjectModification<AddressEndpoint> rootNode,
+            InstanceIdentifier<AddressEndpoint> rootIdentifier) {
+        LOG.debug("onDelete triggered by {}", rootNode.getDataBefore());
+        try {
+            if (EndpointUtils.isExternalEndpoint(dataProvider, rootNode.getDataBefore())) {
+                deleteLocation(createProviderAddressEndpointLocationKey(rootNode.getDataBefore().getKey())).get();
+            } else {
+                createAbsoluteAddressEndpointLocation(null, rootNode).get();
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Failed to delete location for endpoint {}. {}", rootNode.getDataBefore().getKey(),
+                    e.getMessage());
+        }
+    }
+
+    @Override
+    protected void onSubtreeModified(DataObjectModification<AddressEndpoint> rootNode,
+            InstanceIdentifier<AddressEndpoint> rootIdentifier) {
+        LOG.debug("onSubtreeModified triggered by change: before={} after={}", rootNode.getDataBefore(),
+                rootNode.getDataAfter());
+        if (rootNode.getDataBefore() != null) {
+            onDelete(rootNode, rootIdentifier);
+        }
+        if (rootNode.getDataAfter() != null) {
+            onWrite(rootNode, rootIdentifier);
+        }
+    }
+
+    public ListenableFuture<Void> createLocationForVppEndpoint(VppEndpoint vppEndpoint) {
+        return createAbsoluteAddressEndpointLocation(vppEndpoint, null);
+    }
+
+    public ListenableFuture<Void> deleteLocationForVppEndpoint(VppEndpoint vppEndpoint) {
+        // removing VPP EP from cache out of since block, it's not needed for the other thread.
+        vppEndpoints.remove(vppEndpoint.getKey());
+        return deleteLocation(createProviderAddressEndpointLocationKey(vppEndpoint));
+    }
+
+    /**
+     * There are two inputs from which we need to resolve location - {@link AddressEndpoint} and {@link VppEndpoint}
+     * These data are delivered by different threads which meet here.
+     */
+    @VisibleForTesting
+    synchronized ListenableFuture<Void> createAbsoluteAddressEndpointLocation(VppEndpoint vppEndpoint,
+            DataObjectModification<AddressEndpoint> rootNode) {
+        if (vppEndpoint != null) {
+            vppEndpoints.put(vppEndpoint.getKey(), vppEndpoint);
+            if (cachedVppEndpoints.get(vppEndpoint.getKey()) != null) {
+                return processAddrEp(cachedVppEndpoints.get(vppEndpoint.getKey()));
+            }
+        } else if (rootNode != null) {
+            return processAddrEp(rootNode);
+        }
+        return Futures.immediateFuture(null);
+    }
+
+    private ListenableFuture<Void> processAddrEp(DataObjectModification<AddressEndpoint> rootNode) {
+        if (rootNode != null) {
+            AddressEndpointChange aec = new AddressEndpointChange(rootNode, dataProvider);
+            switch (rootNode.getModificationType()) {
+                case WRITE:
+                case SUBTREE_MODIFIED: {
+                    VppEndpoint vpp = vppEndpoints.get(vppEndpointKeyFrom(rootNode.getDataAfter().getKey()));
+                    if (vpp == null) {
+                        VppEndpointKey key = vppEndpointKeyFrom(rootNode.getDataAfter().getKey());
+                        cachedVppEndpoints.put(key, rootNode);
+                        return Futures.immediateFuture(null);
+                    }
+                    if (aec.hasMoreParents()) {
+                        return aec.syncMultiparents();
+                    }
+                        return aec.write();
+                }
+                case DELETE: {
+                    if (aec.hasMoreParents()) {
+                        return aec.syncMultiparents();
+                    } else {
+                        return aec.delete();
+                    }
+                }
+            }
+        }
+        return Futures.immediateFuture(null);
     }
 
-    public static ProviderAddressEndpointLocation createProviderAddressEndpointLocation(VppEndpoint vppEndpoint) {
+    private ProviderAddressEndpointLocation createAbsoluteLocationFromVppEndpoint(VppEndpoint vppEndpoint) {
         InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(vppEndpoint.getVppNodeId());
         String restIfacePath = VppPathMapper.interfaceToRestPath(vppEndpoint.getVppInterfaceName());
-        AbsoluteLocation absoluteLocation = new AbsoluteLocationBuilder()
-            .setLocationType(new ExternalLocationCaseBuilder().setExternalNodeMountPoint(vppNodeIid)
-                .setExternalNodeConnector(restIfacePath)
-                .build())
-            .build();
+        AbsoluteLocation absoluteLocation =
+                new AbsoluteLocationBuilder().setLocationType(new ExternalLocationCaseBuilder()
+                    .setExternalNodeMountPoint(vppNodeIid).setExternalNodeConnector(restIfacePath).build()).build();
         return new ProviderAddressEndpointLocationBuilder()
             .setKey(createProviderAddressEndpointLocationKey(vppEndpoint))
             .setAbsoluteLocation(absoluteLocation)
             .build();
     }
 
-    ListenableFuture<Void> deleteLocationForVppEndpoint(final VppEndpoint vppEndpoint) {
-        final ProviderAddressEndpointLocationKey provAddrEpLocKey =
-                createProviderAddressEndpointLocationKey(vppEndpoint);
-        final WriteTransaction wTx = txChain.newWriteOnlyTransaction();
-        wTx.delete(LogicalDatastoreType.CONFIGURATION,
-                IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, provAddrEpLocKey));
-        LOG.debug("Deleting location for {}", provAddrEpLocKey);
-        return Futures.transform(wTx.submit(), (Function<Void, Void>) input -> {
-            LOG.debug("{} removed location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), provAddrEpLocKey);
-            return null;
+    public ProviderAddressEndpointLocation createRelativeAddressEndpointLocation(@Nonnull AddressEndpointKey addrEp,
+            @Nonnull Map<NodeId, String> publicIntfNamesByNodes) {
+        RelativeLocations relLocations =
+                new RelativeLocationsBuilder()
+                    .setExternalLocation(publicIntfNamesByNodes.keySet()
+                        .stream()
+                        .filter(nodeId -> publicIntfNamesByNodes.get(nodeId) != null)
+                        .map(nodeId -> new ExternalLocationBuilder()
+                            .setExternalNodeMountPoint(VppIidFactory.getNetconfNodeIid(nodeId))
+                            .setExternalNodeConnector(
+                                    VppPathMapper.interfaceToRestPath(publicIntfNamesByNodes.get(nodeId)))
+                            .build())
+                        .collect(Collectors.toList()))
+                    .build();
+        return new ProviderAddressEndpointLocationBuilder().setKey(createProviderAddressEndpointLocationKey(addrEp))
+            .setRelativeLocations(relLocations)
+            .build();
+    }
+
+    public ListenableFuture<Void> writeLocation(ProviderAddressEndpointLocation location) {
+        WriteTransaction wTx = txChain.newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, location.getKey()),
+                location, true);
+        return Futures.transform(wTx.submit(), new Function<Void, Void>() {
+
+            @Override
+            public Void apply(Void input) {
+                LOG.debug("{} provided location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), location);
+                return null;
+            }
         });
     }
 
-    private static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(
-            VppEndpoint vppEndpoint) {
-        return new ProviderAddressEndpointLocationKey(vppEndpoint.getAddress(), vppEndpoint.getAddressType(),
-                vppEndpoint.getContextId(), vppEndpoint.getContextType());
+    public ListenableFuture<Void> deleteLocation(ProviderAddressEndpointLocationKey key) {
+        ReadWriteTransaction rwTx = txChain.newReadWriteTransaction();
+        LOG.debug("Deleting location for {}", key);
+        DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, key), rwTx);
+        return Futures.transform(rwTx.submit(), new Function<Void, Void>() {
+
+            @Override
+            public Void apply(Void input) {
+                LOG.debug("{} removed location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), key);
+                return null;
+            }
+        });
     }
 
     public ListenableFuture<Void> replaceLocationForEndpoint(@Nonnull ExternalLocationCase location, @Nonnull AddressEndpointWithLocationKey addrEpWithLocKey) {
@@ -144,10 +291,95 @@ public class VppEndpointLocationProvider implements AutoCloseable {
         });
     }
 
+    static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(VppEndpoint vpp) {
+        return new ProviderAddressEndpointLocationKey(vpp.getAddress(), vpp.getAddressType(), vpp.getContextId(),
+                vpp.getContextType());
+    }
+
+    static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(AddressEndpointKey key) {
+        return new ProviderAddressEndpointLocationKey(key.getAddress(), key.getAddressType(), key.getContextId(),
+                key.getContextType());
+    }
+
+    private static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(ParentEndpointKey key) {
+        return new ProviderAddressEndpointLocationKey(key.getAddress(), key.getAddressType(), key.getContextId(),
+                key.getContextType());
+    }
+
+    private VppEndpointKey vppEndpointKeyFrom(AddressEndpointKey key) {
+        return new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(), key.getContextType());
+    }
+
+    private VppEndpointKey vppEndpointKeyFrom(ParentEndpointKey key) {
+        return new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(), key.getContextType());
+    }
+
     @Override
-    public void close() throws Exception {
+    public void close() {
+        super.closeRegisteredListener();
         WriteTransaction wTx = txChain.newWriteOnlyTransaction();
         wTx.delete(LogicalDatastoreType.CONFIGURATION, IidFactory.locationProviderIid(VPP_ENDPOINT_LOCATION_PROVIDER));
         wTx.submit();
     }
+
+    private class AddressEndpointChange {
+
+        private final AddressEndpoint before;
+        private final AddressEndpoint after;
+        private final DataBroker dataBroker;
+
+        public AddressEndpointChange(DataObjectModification<AddressEndpoint> addrEp, @Nonnull DataBroker dataBroker) {
+            this.before = addrEp.getDataBefore();
+            this.after = addrEp.getDataAfter();
+            this.dataBroker = dataBroker;
+        }
+
+        boolean hasMoreParents() {
+            return (before != null && EndpointUtils.getParentEndpoints(before.getParentEndpointChoice()).size() > 1)
+                    || (after != null && EndpointUtils.getParentEndpoints(after.getParentEndpointChoice()).size() > 1);
+        }
+
+        ListenableFuture<Void> syncMultiparents() {
+            ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+            if (before != null) {
+                for (ParentEndpoint pe : EndpointUtils.getParentEndpoints(before.getParentEndpointChoice())) {
+                    InstanceIdentifier<ProviderAddressEndpointLocation> iid =
+                            IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER,
+                                    createProviderAddressEndpointLocationKey(pe.getKey()));
+                    DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, iid, rwTx);
+                }
+            }
+            if (after != null) {
+                for (ParentEndpoint pe : EndpointUtils.getParentEndpoints(after.getParentEndpointChoice())) {
+                    VppEndpoint vppEndpoint = vppEndpoints.get(vppEndpointKeyFrom(after.getKey()));
+                    InstanceIdentifier<ProviderAddressEndpointLocation> iid =
+                            IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER,
+                                    createProviderAddressEndpointLocationKey(pe.getKey()));
+                    ProviderAddressEndpointLocation location = createAbsoluteLocationFromVppEndpoint(
+                            new VppEndpointBuilder(vppEndpoint).setKey(vppEndpointKeyFrom(pe.getKey())).build());
+                    rwTx.put(LogicalDatastoreType.CONFIGURATION, iid, location, true);
+                }
+            }
+            return rwTx.submit();
+        }
+
+        ListenableFuture<Void> write() {
+            VppEndpoint vpp = vppEndpoints.get(vppEndpointKeyFrom(after.getKey()));
+            WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
+            ProviderAddressEndpointLocation location =
+                    createAbsoluteLocationFromVppEndpoint(vpp);
+            InstanceIdentifier<ProviderAddressEndpointLocation> iid = IidFactory.providerAddressEndpointLocationIid(
+                    VPP_ENDPOINT_LOCATION_PROVIDER, createProviderAddressEndpointLocationKey(vpp));
+            wTx.put(LogicalDatastoreType.CONFIGURATION, iid, location, true);
+            return wTx.submit();
+        }
+
+        ListenableFuture<Void> delete() {
+            ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+            InstanceIdentifier<ProviderAddressEndpointLocation> iid = IidFactory.providerAddressEndpointLocationIid(
+                    VPP_ENDPOINT_LOCATION_PROVIDER, createProviderAddressEndpointLocationKey(before.getKey()));
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, iid, rwTx);
+            return rwTx.submit();
+        }
+    }
 }
index 6988567f3e64479c536919b6e5233f27aa2a3a8d..501256c9c018b12bf948ed096464c5a0b2b56ca9 100644 (file)
@@ -54,6 +54,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeKey;
@@ -441,4 +442,31 @@ public class VppNodeManager {
         }
         return Lists.newArrayList();
     }
+
+    public static Map<NodeId, String> resolvePublicInterfaces(DataBroker dataProvider) {
+        Map<NodeId, String> nodes = new HashMap<>();
+        ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
+        Optional<RendererNodes> rendNodes =
+                DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, VppIidFactory.getRendererNodesIid(), rTx);
+        rTx.close();
+        if (!rendNodes.isPresent()) {
+            return nodes;
+        }
+        rendNodes.get()
+            .getRendererNode()
+            .stream()
+            .filter(rn -> rn.getAugmentation(VppInterfaceAugmentation.class) != null)
+            .filter(rn -> rn.getAugmentation(VppInterfaceAugmentation.class).getPhysicalInterface() != null)
+            .forEach(rn -> {
+                java.util.Optional<PhysicalInterface> pubInt = rn.getAugmentation(VppInterfaceAugmentation.class)
+                    .getPhysicalInterface()
+                    .stream()
+                    .filter(phInt -> phInt.isExternal())
+                    .findFirst();
+                if (pubInt.isPresent()) {
+                    nodes.put(rn.getNodePath().firstKeyOf(Node.class).getNodeId(), pubInt.get().getInterfaceName());
+                }
+            });
+        return nodes;
+    }
 }
index 91396d85f6a1c92cec5c99a4152bd48a18905a34..be7f5d09c9360679255f93b6791c90e7b0e2ddda 100644 (file)
@@ -25,11 +25,10 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.RoutingCommand;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatUtil;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListUtil;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
@@ -211,7 +210,7 @@ public final class ForwardingManager {
             }
             String l2FloodDomain = optL2FloodDomain.get();
             try {
-                ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, AccessListUtil.resolveAclsOnInterface(
+                ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, aclManager.resolveAclsOnInterface(
                         rEpKey, policyCtx), isBviForEndpoint(rEp)).get();
                 aclManager.updateAclsForPeers(policyCtx, rEpKey);
                 LOG.debug("Interface added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp);
index 3b7ae60461820784397e571691a738c6f102d796..59d80322d67c2a32cd3e0810b7d3a0b4dc6c50e5 100644 (file)
@@ -24,7 +24,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.util.AddressEndpointUtils;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.NodeOperEvent;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.RendererPolicyConfEvent;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
@@ -120,6 +120,7 @@ public class VppRendererPolicyManager {
         LOG.trace("VPP renderer policy updated");
         PolicyContext policyCtxBefore = new PolicyContext(rPolicyBefore);
         PolicyContext policyCtxAfter = new PolicyContext(rPolicyAfter);
+        aclManager.cacheMultiInterfaces(policyCtxAfter);
         MapDifference<String, Collection<NodeId>> vppNodesByL2FlDiff =
                 createDiffForVppNodesByL2Fd(policyCtxBefore, policyCtxAfter);
         SetMultimap<String, NodeId> removedVppNodesByL2Fd = HashMultimap.create();
@@ -264,6 +265,7 @@ public class VppRendererPolicyManager {
     private void rendererPolicyCreated(RendererPolicy rPolicy) {
         LOG.trace("VPP renderer policy version {} created", rPolicy.getVersion());
         PolicyContext policyCtx = new PolicyContext(rPolicy);
+        aclManager.cacheMultiInterfaces(policyCtx);
         ImmutableSet<RendererEndpointKey> rEpKeys = policyCtx.getPolicyTable().rowKeySet();
 
         SetMultimap<String, NodeId> vppNodesByL2Fd = resolveVppNodesByL2Fd(rEpKeys, policyCtx);
@@ -276,6 +278,7 @@ public class VppRendererPolicyManager {
     private void rendererPolicyDeleted(RendererPolicy rendererPolicy) {
         LOG.trace("VPP renderer policy version {} deleted", rendererPolicy.getVersion());
         PolicyContext policyCtx = new PolicyContext(rendererPolicy);
+        aclManager.cacheMultiInterfaces(policyCtx);
         ImmutableSet<RendererEndpointKey> rEpKeys = policyCtx.getPolicyTable().rowKeySet();
 
         rEpKeys.forEach(rEpKey -> fwManager.removeForwardingForEndpoint(rEpKey, policyCtx));
index 6e15411df4d84ce5a26d0f3438cd50abf50ee943..9f7715da15063c6c112d20a0cae24987bf8c0795 100644 (file)
@@ -33,7 +33,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
 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.forwarding.l2_l3.rev160427.L2BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentRenderer;
 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.policy.rev140421.HasDirection.Direction;
@@ -74,55 +73,26 @@ public class AccessListUtil {
     // hiding default public constructor
     private AccessListUtil() {}
 
-    public static List<AccessListWrapper> resolveAclsOnInterface(RendererEndpointKey rEpKey, PolicyContext ctx) {
-        List<AccessListWrapper> aclWrappers = new ArrayList<>();
-        for (ACE_DIRECTION dir : new ACE_DIRECTION[] {ACE_DIRECTION.INGRESS, ACE_DIRECTION.EGRESS}) {
-            aclWrappers.add(buildAccessListWrappers(dir, ctx, rEpKey));
-        }
-        return aclWrappers;
-    }
-
-    /**
-     * @param policyDirection direction for which policy should be resolved. EP -> VPP = OUTBOUND, EP <- VPP = INBOUND 
-     * @param ctx with cached data
-     * @param rEpKey key of EP for which to create ACLs.
-     * @return synchronization futures, so that INGRESS and EGRESS ACLS can be resolved in parallel.
-     */
-    private static AccessListWrapper buildAccessListWrappers(ACE_DIRECTION policyDirection, PolicyContext ctx,
-            RendererEndpointKey rEpKey) {
-        LOG.trace("Resolving policy for VPP renderer endpoint {} in a separate thread in {} direction.", rEpKey,
-                policyDirection);
-        AccessListWrapper aclWrapper = AccessListUtil.ACE_DIRECTION.INGRESS
-            .equals(policyDirection) ? new IngressAccessListWrapper() : new EgressAccessListWrapper();
+    static void configureLocalRules(PolicyContext ctx, RendererEndpointKey rEpKey, ACE_DIRECTION policyDirection,
+            AccessListWrapper aclWrapper) {
         ctx.getPolicyTable()
             .row(rEpKey)
             .keySet()
             .stream()
             .filter(peerEpKey -> peerHasLocation(ctx, peerEpKey))
             .forEach(peerEpKey -> {
-            ctx.getPolicyTable().get(rEpKey, peerEpKey).forEach(resolvedRules -> {
-                List<GbpAceBuilder> rules = new ArrayList<>();
-                LOG.debug("Resolving policy for {} and peer endpoint {}", rEpKey, peerEpKey);
-                Direction classifDir =
-                        calculateClassifDirection(resolvedRules.getRendererEndpointParticipation(), policyDirection);
-                rules.addAll(resolveAclRulesFromPolicy(resolvedRules, classifDir,
-                        rEpKey.getAddress() + UNDERSCORE + peerEpKey.getAddress()));
-                updateAddressesInRules(rules, rEpKey, peerEpKey, ctx, policyDirection, true);
-                aclWrapper.writeRules(rules);
+                ctx.getPolicyTable().get(rEpKey, peerEpKey).forEach(resolvedRules -> {
+                    List<GbpAceBuilder> rules = new ArrayList<>();
+                    LOG.debug("Resolving policy for {} and peer endpoint {}", rEpKey, peerEpKey);
+                    Direction classifDir = calculateClassifDirection(resolvedRules.getRendererEndpointParticipation(),
+                            policyDirection);
+                    rules.addAll(resolveAclRulesFromPolicy(resolvedRules, classifDir,
+                            rEpKey.getAddress() + UNDERSCORE + peerEpKey.getAddress()));
+                    updateAddressesInRules(rules, rEpKey, peerEpKey, ctx, policyDirection, true);
+                    aclWrapper.writeRules(rules);
+
+                });
             });
-        });
-        // resolve peers with no location
-        aclWrapper.writeRules(denyDomainSubnets(ctx, policyDirection));
-        // TODO currently any traffic heading to/from outside of managed domain is
-        // permitted for demonstration purposes
-        if (rEpKey.getContextType().isAssignableFrom(L2BridgeDomain.class) && findAddrEp(ctx, rEpKey) != null) {
-            Optional<GbpAceBuilder> allowExtAccess =
-                    allowExternalNetworksForEp(findAddrEp(ctx, rEpKey), policyDirection);
-            if (allowExtAccess.isPresent()) {
-                aclWrapper.writeRule(allowExtAccess.get());
-            }
-        }
-        return aclWrapper;
     }
 
     /**
@@ -174,7 +144,7 @@ public class AccessListUtil {
                 AddressEndpointUtils.fromPeerEpKey(peerEpKey)) != null;
     }
 
-    private static AddressEndpointWithLocation findAddrEp(PolicyContext ctx, RendererEndpointKey rEpKey) {
+    static AddressEndpointWithLocation findAddrEp(PolicyContext ctx, RendererEndpointKey rEpKey) {
         return ctx.getAddrEpByKey().get(
                 AddressEndpointUtils.fromRendererEpKey(rEpKey));
     }
@@ -270,7 +240,7 @@ public class AccessListUtil {
      * purposes
      * TODO initial workaround for external networking
      */
-   private static Optional<GbpAceBuilder> allowExternalNetworksForEp(@Nonnull AddressEndpointWithLocation addrEp,
+   static Optional<GbpAceBuilder> allowExternalNetworksForEp(@Nonnull AddressEndpointWithLocation addrEp,
             AccessListUtil.ACE_DIRECTION dir) {
         List<ParentEndpoint> parentEndpoints = EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice());
         if (parentEndpoints.isEmpty()) {
@@ -312,7 +282,7 @@ public class AccessListUtil {
         return (address.contains("/") && address.split("/").length > 0) ? address.split("/")[0] : address;
     }
 
-    private static List<GbpAceBuilder> denyDomainSubnets(@Nonnull PolicyContext ctx, @Nonnull ACE_DIRECTION policyDirection) {
+    static List<GbpAceBuilder> denyDomainSubnets(@Nonnull PolicyContext ctx, @Nonnull ACE_DIRECTION policyDirection) {
         List<GbpAceBuilder> aclRuleBuilders = new ArrayList<>();
         for (RendererForwardingByTenant rf : ctx.getPolicy()
             .getConfiguration()
@@ -329,7 +299,7 @@ public class AccessListUtil {
                     if (policyDirection.equals(ACE_DIRECTION.INGRESS) && subnetAug.getSubnet().isIsTenant()) {
                         aclRuleBuilders.add(denyIngressTrafficForPrefix(subnetAug.getSubnet()));
                     }
-                    else if(subnetAug.getSubnet().isIsTenant()) {
+                    else if (subnetAug.getSubnet().isIsTenant()) {
                         aclRuleBuilders.add(denyEgressTrafficForPrefix(subnetAug.getSubnet()));
                     }
                 });
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AclManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AclManager.java
new file mode 100644 (file)
index 0000000..aba8d12
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.groupbasedpolicy.renderer.util.AddressEndpointUtils;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppPathMapper;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.PolicyContext;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListUtil.ACE_DIRECTION;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
+import org.opendaylight.groupbasedpolicy.util.EndpointUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.ImmutableTable.Builder;
+import com.google.common.collect.Sets;
+
+public class AclManager {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AclManager.class);
+    private final MountedDataBrokerProvider mountDataProvider;
+
+    private static ImmutableTable<NodeId, InterfaceKey, ImmutableSet<AddressEndpointKey>> multipleEndpointsOnInterface;
+
+    public AclManager(@Nonnull MountedDataBrokerProvider mountDataProvider) {
+        this.mountDataProvider = Preconditions.checkNotNull(mountDataProvider);
+    }
+
+    public List<AccessListWrapper> resolveAclsOnInterface(RendererEndpointKey rEpKey, PolicyContext ctx) {
+        List<AccessListWrapper> aclWrappers = new ArrayList<>();
+        for (ACE_DIRECTION dir : new ACE_DIRECTION[] {ACE_DIRECTION.INGRESS, ACE_DIRECTION.EGRESS}) {
+            aclWrappers.add(buildAccessListWrappers(dir, ctx, rEpKey));
+        }
+        return aclWrappers;
+    }
+
+    /**
+     * @param policyDirection direction for which policy should be resolved. EP -> VPP = OUTBOUND, EP <- VPP = INBOUND 
+     * @param ctx with cached data
+     * @param rEpKey key of EP for which to create ACLs.
+     * @return synchronization futures, so that INGRESS and EGRESS ACLS can be resolved in parallel.
+     */
+    private static AccessListWrapper buildAccessListWrappers(ACE_DIRECTION policyDirection, PolicyContext ctx,
+            RendererEndpointKey rEpKey) {
+        LOG.trace("Resolving policy for VPP renderer endpoint {} in a separate thread in {} direction.", rEpKey,
+                policyDirection);
+        AccessListWrapper aclWrapper = AccessListUtil.ACE_DIRECTION.INGRESS
+            .equals(policyDirection) ? new IngressAccessListWrapper() : new EgressAccessListWrapper();
+            AccessListUtil.configureLocalRules(ctx, rEpKey, policyDirection, aclWrapper);
+        // we support multiple IP end-points on a same interface
+       for (AddressEndpointKey aek : otherEndpointsOnTheSameInterface(ctx,
+                AddressEndpointUtils.fromRendererEpKey(rEpKey))) {
+           AccessListUtil.configureLocalRules(ctx, AddressEndpointUtils.toRendererEpKey(aek), policyDirection, aclWrapper);
+        }
+        // resolve peers with no location
+        aclWrapper.writeRules(AccessListUtil.denyDomainSubnets(ctx, policyDirection));
+        // TODO currently any traffic heading to/from outside of managed domain is
+        // permitted for demonstration purposes
+        if (rEpKey.getContextType().isAssignableFrom(L2BridgeDomain.class) && AccessListUtil.findAddrEp(ctx, rEpKey) != null) {
+            Optional<GbpAceBuilder> allowExtAccess =
+                    AccessListUtil.allowExternalNetworksForEp(AccessListUtil.findAddrEp(ctx, rEpKey), policyDirection);
+            if (allowExtAccess.isPresent()) {
+                aclWrapper.writeRule(allowExtAccess.get());
+            }
+        }
+        return aclWrapper;
+    }
+
+    public void updateAclsForPeers(PolicyContext policyCtx, RendererEndpointKey rEpKey) {
+        ImmutableSet<PeerEndpointKey> peers = policyCtx.getPolicyTable().row(rEpKey).keySet();
+        for (RendererEndpointKey peerRendEp : peers.stream()
+            .map(AddressEndpointUtils::fromPeerEpKey)
+            .collect(Collectors.toList())
+            .stream()
+            .map(AddressEndpointUtils::toRendererEpKey)
+            .collect(Collectors.toList())) {
+            updateAclsForRendEp(peerRendEp, policyCtx);
+        }
+    }
+
+    public void updateAclsForRendEp(RendererEndpointKey rEpKey, PolicyContext policyCtx) {
+        LOG.info("Updating policy for endpoint {}", rEpKey);
+        AddressEndpointWithLocation peerAddrEp = policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey));
+        ExternalLocationCase epLoc;
+        try {
+            epLoc = InterfaceManager.resolveAndValidateLocation(peerAddrEp);
+        } catch (NullPointerException | IllegalArgumentException e) {
+            //TODO investigate, don't just move on.
+            LOG.warn("Peer {} has no location. Moving on...", peerAddrEp, e.getMessage());
+            return;
+        }
+        InstanceIdentifier<?> vppNodeIid = epLoc.getExternalNodeMountPoint();
+        Optional<InstanceIdentifier<Interface>> optInterfaceIid =
+                VppPathMapper.interfaceToInstanceIdentifier(epLoc.getExternalNodeConnector());
+        if (!optInterfaceIid.isPresent()) {
+            LOG.warn("Cannot  find interface for endpoint {}. ACLs for endpoint not updated {}. ", rEpKey);
+            return;
+        }
+        Optional<DataBroker> optMountPoint = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);
+        resolveAclsOnInterface(rEpKey, policyCtx).forEach(aclWrapper -> aclWrapper
+            .writeAcl(optMountPoint.get(), optInterfaceIid.get().firstKeyOf(Interface.class)));
+    }
+
+    /**
+     * Cache end-points accessible via a single interface for further processing.
+     */
+    public void cacheMultiInterfaces(@Nonnull PolicyContext ctx) {
+        Builder<NodeId, InterfaceKey, ImmutableSet<AddressEndpointKey>> resultBuilder = new Builder<>();
+        resolveEndpointsOnMultipleInterface(ImmutableList.copyOf(ctx.getAddrEpByKey().values()), resultBuilder);
+        multipleEndpointsOnInterface = resultBuilder.build();
+    }
+
+    private void resolveEndpointsOnMultipleInterface(@Nullable ImmutableList<AddressEndpointWithLocation> eps,
+            @Nonnull Builder<NodeId, InterfaceKey, ImmutableSet<AddressEndpointKey>> builder) {
+        if (eps == null || eps.isEmpty()) {
+            return;
+        }
+        eps.get(0);
+        ImmutableSet<AddressEndpointKey> copyOf = ImmutableSet.copyOf(eps.stream()
+            .filter(addrEp -> AddressEndpointUtils.sameExternalLocationCase(eps.get(0), addrEp))
+            .map(addrEp -> AddressEndpointUtils.fromAddressEndpointWithLocationKey(addrEp.getKey()))
+            .collect(Collectors.toSet()));
+        Optional<ExternalLocationCase> extLoc = EndpointUtils.getExternalLocationFrom(eps.get(0));
+        builder.put(extLoc.get().getExternalNodeMountPoint().firstKeyOf(Node.class).getNodeId(),
+                new InterfaceKey(extLoc.get().getExternalNodeConnector()), copyOf);
+        ImmutableList<AddressEndpointWithLocation> lisst = ImmutableList.copyOf(eps.stream()
+            .filter(addrEp -> !AddressEndpointUtils.sameExternalLocationCase(eps.get(0), addrEp))
+            .collect(Collectors.toList()));
+        if (!lisst.isEmpty()) {
+            resolveEndpointsOnMultipleInterface(lisst, builder);
+        }
+    }
+
+    public @Nonnull static ImmutableSet<AddressEndpointKey> otherEndpointsOnTheSameInterface(@Nonnull PolicyContext ctx,
+            @Nonnull AddressEndpointKey key) {
+        if (multipleEndpointsOnInterface != null) {
+            for (InterfaceKey ifaceKey : multipleEndpointsOnInterface.columnKeySet()) {
+                for (NodeId nodeId : multipleEndpointsOnInterface.column(ifaceKey).keySet()) {
+                    ImmutableSet<AddressEndpointKey> addrEps = multipleEndpointsOnInterface.get(nodeId, ifaceKey);
+                    if (addrEps != null && addrEps.contains(key) && addrEps.size() > 1) {
+                        return multipleEndpointsOnInterface.get(nodeId, ifaceKey);
+                    }
+                }
+            }
+        }
+        return ImmutableSet.copyOf(Sets.newHashSet());
+    }
+}
index 1eca68663e8331214af4fa0e6dd521880d8507cc..73c2bbdfd79af567d654d1b94294eeae18ce8c60 100644 (file)
@@ -23,8 +23,6 @@ import org.slf4j.LoggerFactory;
 class DestinationMapper extends AddressMapper {
 
     private static final Logger LOG = LoggerFactory.getLogger(DestinationMapper.class);
-    private static final String METADATA_IP_PREFIX = "169.254.169.254/32";
-    private static final String IN__METADATA = "In__METADATA";
 
     DestinationMapper(ACE_DIRECTION direction) {
         super(direction);
@@ -39,31 +37,22 @@ class DestinationMapper extends AddressMapper {
 
     @Override
     void updateRule(AddressEndpointWithLocation addrEp, GbpAceBuilder aclRuleBuilder) {
-        if (!EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).isEmpty()) {
-            // TODO more parents, when supported
+        String address;
+        if (addrEp.getContextType().isAssignableFrom(L3Context.class)) {
+            address = addrEp.getAddress();
+        } else {
             ParentEndpoint parentEp = EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).get(0);
-            if (parentEp != null && parentEp.getContextType().isAssignableFrom(L3Context.class)) {
-                // TODO this is a fix for metadata agent in DHCP namespace, when we will fully support multiple IPs
-                // per interface we shall rework this
-                if (aclRuleBuilder.getName().contains(IN__METADATA)) {
-                    LOG.trace("Setting dst IP address {} in rule {}", METADATA_IP_PREFIX, aclRuleBuilder);
-                    try {
-                        AccessListUtil.setDestinationL3Address(aclRuleBuilder, METADATA_IP_PREFIX);
-                    } catch (UnknownHostException e) {
-                        LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", METADATA_IP_PREFIX,
-                            aclRuleBuilder, e);
-                    }
-                } else {
-                    LOG.trace("Setting dst IP address {} in rule {}", parentEp.getAddress(), aclRuleBuilder);
-                    try {
-                        AccessListUtil.setDestinationL3Address(aclRuleBuilder, parentEp.getAddress());
-                    } catch (UnknownHostException e) {
-                        LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", parentEp.getAddress(),
-                            aclRuleBuilder, e);
-                    }
-                }
-
+            if (parentEp == null || !parentEp.getContextType().isAssignableFrom(L3Context.class)) {
+                LOG.warn("Cannot resolve IP address for endpoint {}", addrEp);
+                return;
             }
+            address = parentEp.getAddress();
+        }
+        LOG.trace("Setting dst IP address {} in rule {}", address, aclRuleBuilder);
+        try {
+            AccessListUtil.setDestinationL3Address(aclRuleBuilder, address);
+        } catch (UnknownHostException e) {
+            LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", address, aclRuleBuilder, e);
         }
     }
 }
index 28b03d8f9825896dd8d214f755e6786991c8ced9..a163f09a3bfcadde00bb15d11c21e82de06f13f3 100644 (file)
@@ -23,8 +23,6 @@ import org.slf4j.LoggerFactory;
 class SourceMapper extends AddressMapper {
 
     private static final Logger LOG = LoggerFactory.getLogger(SourceMapper.class);
-    private static final String METADATA_IP_PREFIX = "169.254.169.254/32";
-    private static final String OUT__METADATA = "Out__METADATA";
 
     SourceMapper(ACE_DIRECTION direction) {
         super(direction);
@@ -39,30 +37,22 @@ class SourceMapper extends AddressMapper {
 
     @Override
     void updateRule(AddressEndpointWithLocation addrEp, GbpAceBuilder aclRuleBuilder) {
-        if (!EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).isEmpty()) {
-            // TODO more parents
+        String address;
+        if (addrEp.getContextType().isAssignableFrom(L3Context.class)) {
+            address = addrEp.getAddress();
+        } else {
             ParentEndpoint parentEp = EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).get(0);
-            if (parentEp != null && parentEp.getContextType().isAssignableFrom(L3Context.class)) {
-                // TODO this is a fix for metadata agent in DHCP namespace, when we will fully support multiple IPs
-                // per interface we shall rework this
-                if (aclRuleBuilder.getName().contains(OUT__METADATA)) {
-                    LOG.trace("Setting src IP address {} in rule {}", METADATA_IP_PREFIX, aclRuleBuilder);
-                    try {
-                        AccessListUtil.setSourceL3Address(aclRuleBuilder, METADATA_IP_PREFIX);
-                    } catch (UnknownHostException e) {
-                        LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", METADATA_IP_PREFIX,
-                            aclRuleBuilder, e);
-                    }
-                } else {
-                    LOG.trace("Setting src IP address {} in rule {}", parentEp.getAddress(), aclRuleBuilder);
-                    try {
-                        AccessListUtil.setSourceL3Address(aclRuleBuilder, parentEp.getAddress());
-                    } catch (UnknownHostException e) {
-                        LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", parentEp.getAddress(),
-                            aclRuleBuilder, e);
-                    }
-                }
+            if (parentEp == null || !parentEp.getContextType().isAssignableFrom(L3Context.class)) {
+                LOG.warn("Cannot resolve IP address for endpoint {}", addrEp);
+                return;
             }
+            address = parentEp.getAddress();
+        }
+        LOG.trace("Setting src IP address {} in rule {}", address, aclRuleBuilder);
+        try {
+            AccessListUtil.setSourceL3Address(aclRuleBuilder, address);
+        } catch (UnknownHostException e) {
+            LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", address, aclRuleBuilder, e);
         }
     }
 }
index 150bc312825f584ee013f1306181b6802906bf79..952ba2d7b4f29d80570f769595d8e0f30d1263ff 100644 (file)
@@ -35,9 +35,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.VppAclInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.BridgeDomainsState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.VppInterfaceAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.L2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.bridge.domains.state.BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.bridge.domains.state.BridgeDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.L2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppAcl;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -75,11 +75,7 @@ public class VppIidFactory {
     }
 
     public static InstanceIdentifier<RendererNode> getRendererNodeIid(RendererNode rendererNode) {
-        return InstanceIdentifier.builder(Renderers.class)
-            .child(Renderer.class, new RendererKey(VppRenderer.NAME))
-            .child(RendererNodes.class)
-            .child(RendererNode.class, new RendererNodeKey(rendererNode.getNodePath()))
-            .build();
+        return getRendererNodesIid().child(RendererNode.class, new RendererNodeKey(rendererNode.getNodePath()));
     }
 
     public static InstanceIdentifier<Node> getNodeIid(TopologyKey topologyKey, NodeKey nodeKey) {
index 0ee2f999a486a527462ff791af9cf17c2a119b2a..12ac16add538576cc46734104888c94c2e07ea37 100644 (file)
@@ -18,6 +18,7 @@ import org.junit.Test;
 import org.mockito.Mockito;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.VppEndpointConfEvent;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
@@ -26,6 +27,9 @@ import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
+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.endpoint_location_provider.rev160419.LocationProviders;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider;
@@ -42,13 +46,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.BridgeDomains;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
 
 public class InterfaceManagerTest extends CustomDataBrokerTest {
 
@@ -59,7 +62,6 @@ public class InterfaceManagerTest extends CustomDataBrokerTest {
             new VppEndpointKey(ADDRESS, AddressType.class, CONTEXT_ID, ContextType.class);
     private final static InstanceIdentifier<VppEndpoint> BASIC_VPP_EP_IID =
             InstanceIdentifier.builder(Config.class).child(VppEndpoint.class, BASIC_VPP_EP_KEY).build();
-    private final static TopologyKey TOPO_KEY = new TopologyKey(new TopologyId("topo1"));
     private final static NodeKey NODE_KEY = new NodeKey(new NodeId("node1"));
     private final static String SOCKET = "socket1";
 
@@ -87,6 +89,15 @@ public class InterfaceManagerTest extends CustomDataBrokerTest {
 
     @Test
     public void testVppEndpointChanged_created() throws Exception {
+        VppEndpointLocationProvider vppEpLocProvider = new VppEndpointLocationProvider(dataBroker);
+        AddressEndpoint addrEp = new AddressEndpointBuilder()
+            .setKey(new AddressEndpointKey(vhostVppEpBuilder().getAddress(), vhostVppEpBuilder().getAddressType(),
+                    vhostVppEpBuilder().getContextId(), vhostVppEpBuilder().getContextType()))
+            .setEndpointGroup(ImmutableList.of())
+            .build();
+        WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(addrEp.getKey()), addrEp, true);
+        wTx.submit().get();
         VppEndpoint vhostEp = vhostVppEpBuilder().build();
         VppEndpointConfEvent event = new VppEndpointConfEvent(BASIC_VPP_EP_IID, null, vhostEp);
 
@@ -116,8 +127,7 @@ public class InterfaceManagerTest extends CustomDataBrokerTest {
         List<ProviderAddressEndpointLocation> epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
         Assert.assertNotNull(epLocs);
         Assert.assertEquals(1, epLocs.size());
-        ProviderAddressEndpointLocation epLoc = VppEndpointLocationProvider.createProviderAddressEndpointLocation(vhostEp);
-        Assert.assertEquals(epLoc, epLocs.get(0));
+        vppEpLocProvider.close();
     }
 
     @Test
@@ -137,11 +147,10 @@ public class InterfaceManagerTest extends CustomDataBrokerTest {
         Assert.assertFalse(potentialIface.isPresent());
         // assert state on ODL data store
         ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
-        ProviderAddressEndpointLocation providerAddressEndpointLocation =
-                VppEndpointLocationProvider.createProviderAddressEndpointLocation(vhostEp);
+        VppEndpointLocationProvider.createProviderAddressEndpointLocationKey(vhostEp);
         InstanceIdentifier<ProviderAddressEndpointLocation> providerAddressEndpointLocationIid = IidFactory
             .providerAddressEndpointLocationIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER,
-                    providerAddressEndpointLocation.getKey());
+                    VppEndpointLocationProvider.createProviderAddressEndpointLocationKey(vhostEp));
         Optional<ProviderAddressEndpointLocation> optProvEpLoc =
                 rTx.read(LogicalDatastoreType.CONFIGURATION, providerAddressEndpointLocationIid).get();
         Assert.assertFalse(optProvEpLoc.isPresent());
index e9026fa502e588ab0986ac458c7f0dc38b30b4e6..6a766cba573c2e581f6315432275c416fb1ed150 100644 (file)
@@ -15,17 +15,16 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 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.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-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.absolute.location.absolute.location.location.type.ExternalLocationCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
@@ -36,10 +35,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+
 @SuppressWarnings("unchecked")
 public class VppEndpointLocationProviderTest {
 
@@ -49,19 +53,29 @@ public class VppEndpointLocationProviderTest {
     private final DataBroker dataProvider = mock(DataBroker.class);
     private final BindingTransactionChain transactionChain = mock(BindingTransactionChain.class);
     private final WriteTransaction wTx = mock(WriteTransaction.class);
+    private final ReadWriteTransaction rwTx = mock(ReadWriteTransaction.class);
     private final CheckedFuture<Void, TransactionCommitFailedException> future = mock(CheckedFuture.class);
+    private final CheckedFuture<Optional<DataObject>,ReadFailedException> readFuture = mock(CheckedFuture.class);
+    private final Optional<DataObject> vppEpOpt = mock(Optional.class);
+    private final VppEndpointKey VPP_EP_KEY =
+            new VppEndpointKey("192.168.192.168/32", IpPrefixType.class, new ContextId("TEST_CTX"), L3Context.class);
 
     @Before
-    public void init() {
+    public void init() throws ReadFailedException {
         when(dataProvider.createTransactionChain(any())).thenReturn(transactionChain);
         when(transactionChain.newWriteOnlyTransaction()).thenReturn(wTx);
+        when(transactionChain.newReadWriteTransaction()).thenReturn(rwTx);
+        when(dataProvider.newReadWriteTransaction()).thenReturn(rwTx);
+        when(rwTx.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(readFuture);
+        when(readFuture.checkedGet()).thenReturn(vppEpOpt);
+        when(vppEpOpt.isPresent()).thenReturn(true);
         when(wTx.submit()).thenReturn(future);
+        when(rwTx.submit()).thenReturn(future);
     }
 
     @Test
     public void constructorTest() {
         new VppEndpointLocationProvider(dataProvider);
-
         verify(dataProvider, times(1)).createTransactionChain(any());
         verify(transactionChain, times(1)).newWriteOnlyTransaction();
         verify(wTx, times(1)).put(eq(LogicalDatastoreType.CONFIGURATION),
@@ -73,44 +87,29 @@ public class VppEndpointLocationProviderTest {
     public void createLocationForVppEndpointTest() {
         final VppEndpointLocationProvider locationProvider = new VppEndpointLocationProvider(dataProvider);
         final ListenableFuture<Void> result = locationProvider.createLocationForVppEndpoint(vppEndpointBuilder());
-
         Assert.assertNotNull(result);
         verify(dataProvider, times(1)).createTransactionChain(any());
-        verify(transactionChain, times(2)).newWriteOnlyTransaction();
+        verify(transactionChain, times(1)).newWriteOnlyTransaction();
         verify(wTx, times(1)).put(eq(LogicalDatastoreType.CONFIGURATION),
                 any(InstanceIdentifier.class), any(LocationProvider.class), eq(true));
         verify(wTx, times(1)).put(eq(LogicalDatastoreType.CONFIGURATION),
                 any(InstanceIdentifier.class), any(ProviderAddressEndpointLocation.class), eq(true));
-        verify(wTx, times(2)).submit();
-    }
-
-    @Test
-    public void createProviderAddressEndpointLocationTest() {
-        final ProviderAddressEndpointLocation result =
-                VppEndpointLocationProvider.createProviderAddressEndpointLocation(vppEndpointBuilder());
-        Assert.assertNotNull(result);
-        final AbsoluteLocation location = result.getAbsoluteLocation();
-        Assert.assertNotNull(location);
-        Assert.assertEquals(location.getLocationType().getImplementedInterface(), ExternalLocationCase.class);
-        final ExternalLocationCase locationType = (ExternalLocationCase) location.getLocationType();
-        Assert.assertEquals(locationType.getExternalNodeMountPoint().firstKeyOf(Node.class).getNodeId(), nodeId);
-        Assert.assertTrue(locationType.getExternalNodeConnector().contains(INTERFACE_NAME));
-
+        verify(wTx, times(1)).submit();
     }
 
     @Test
     public void deleteLocationForVppEndpointTest() {
         final VppEndpointLocationProvider locationProvider = new VppEndpointLocationProvider(dataProvider);
         final ListenableFuture<Void> result = locationProvider.deleteLocationForVppEndpoint(vppEndpointBuilder());
-
         Assert.assertNotNull(result);
         verify(dataProvider, times(1)).createTransactionChain(any());
-        verify(transactionChain, times(2)).newWriteOnlyTransaction();
+        verify(transactionChain, times(1)).newWriteOnlyTransaction();
         verify(wTx, times(1)).put(eq(LogicalDatastoreType.CONFIGURATION),
                 any(InstanceIdentifier.class), any(LocationProvider.class), eq(true));
-        verify(wTx, times(1)).delete(eq(LogicalDatastoreType.CONFIGURATION),
+        verify(rwTx, times(1)).delete(eq(LogicalDatastoreType.CONFIGURATION),
                 any(InstanceIdentifier.class));
-        verify(wTx, times(2)).submit();
+        verify(wTx, times(1)).submit();
+        verify(rwTx, times(1)).submit();
     }
 
     @Test
@@ -131,8 +130,7 @@ public class VppEndpointLocationProviderTest {
 
     private VppEndpoint vppEndpointBuilder() {
         final VppEndpointBuilder vppEndpointBuilder = new VppEndpointBuilder();
-        vppEndpointBuilder.setVppNodeId(nodeId)
-                .setVppInterfaceName(INTERFACE_NAME);
+        vppEndpointBuilder.setKey(VPP_EP_KEY).setVppNodeId(nodeId).setVppInterfaceName(INTERFACE_NAME);
         return vppEndpointBuilder.build();
     }
 
index da8f757816e3e73f7674e0047e9dd0319d4a25e6..66fc78951bd0248115610aba27be4aef9ed1da8e 100644 (file)
@@ -22,9 +22,9 @@ import org.mockito.Mockito;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
 import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
index 09e5d719ef02b75d58c951df605a79a337d7b8c2..40caf4490db1d21dfde97df06583f7c6056bd4f3 100644 (file)
@@ -22,10 +22,10 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.DtoFactory;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListWrapper;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
 import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
index fb609691ef5d873c1361046e722d713e593d4d33..112c8aadbea1263a60da294f084463e977bcc426 100644 (file)
@@ -26,10 +26,10 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.DtoFactory;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.RendererPolicyConfEvent;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.VppEndpointConfEvent;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppEndpointLocationProvider;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
@@ -115,12 +115,12 @@ public class VppRendererPolicyManagerTest extends CustomDataBrokerTest {
 
     @Test
     public void testRendererPolicyChanged_created_oneEpPerEpg() throws Exception {
-        String clientIp = "1.1.1.1";
+        String clientIp = "1.1.1.1/32";
         String clientIfaceName = "client1";
         AbsoluteLocation clientLocation = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, clientIfaceName);
         AddressEndpointWithLocation clientEp =
                 DtoFactory.createEndpoint(clientIp, DtoFactory.L2FD_CTX.getValue(), clientLocation);
-        String webIp = "2.2.2.2";
+        String webIp = "2.2.2.2/32";
         String webIfaceName = "web1";
         AbsoluteLocation webLocation = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, webIfaceName);
         AddressEndpointWithLocation webEp =
@@ -164,22 +164,22 @@ public class VppRendererPolicyManagerTest extends CustomDataBrokerTest {
         AbsoluteLocation client1LocationNodeNull =
                 DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, client1IfaceName);
         AddressEndpointWithLocation client1Ep =
-                DtoFactory.createEndpoint("10.0.0.1", DtoFactory.L2FD_CTX.getValue(), client1LocationNodeNull);
+                DtoFactory.createEndpoint("10.0.0.1/32", DtoFactory.L2FD_CTX.getValue(), client1LocationNodeNull);
         String web1IfaceName = "web1";
         AbsoluteLocation web1LocationNodeNull =
                 DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID, null, web1IfaceName);
         AddressEndpointWithLocation web1Ep =
-                DtoFactory.createEndpoint("20.0.0.1", DtoFactory.L2FD_CTX.getValue(), web1LocationNodeNull);
+                DtoFactory.createEndpoint("20.0.0.1/32", DtoFactory.L2FD_CTX.getValue(), web1LocationNodeNull);
         String client2IfaceName = "client2";
         AbsoluteLocation client2LocationNodeNull =
                 DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, client2IfaceName);
         AddressEndpointWithLocation client2Ep =
-                DtoFactory.createEndpoint("10.0.0.2", DtoFactory.L2FD_CTX.getValue(), client2LocationNodeNull);
+                DtoFactory.createEndpoint("10.0.0.2/32", DtoFactory.L2FD_CTX.getValue(), client2LocationNodeNull);
         String web2IfaceName = "web2";
         AbsoluteLocation web2LocationNodeNull =
                 DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID, null, web2IfaceName);
         AddressEndpointWithLocation web2Ep =
-                DtoFactory.createEndpoint("20.0.0.2", DtoFactory.L2FD_CTX.getValue(), web2LocationNodeNull);
+                DtoFactory.createEndpoint("20.0.0.2/32", DtoFactory.L2FD_CTX.getValue(), web2LocationNodeNull);
 
         storeVppEndpoint(client1Ep.getKey(), client1IfaceName, createVppEndpointIid(client1Ep.getKey()));
         storeVppEndpoint(web1Ep.getKey(), web1IfaceName, createVppEndpointIid(web1Ep.getKey()));
index 5828b9b93ecfdf3fbb9f4807e2d0adde36af090d..122290353a2a076a97fef1c25b63f017ae9faacc 100644 (file)
@@ -14,22 +14,35 @@ import java.util.stream.Collectors;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.PolicyContext;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
 
 public class AccessListUtilTest extends TestResources {
 
     private PolicyContext ctx;
+    private MountedDataBrokerProvider mountedDataProviderMock;
+    private DataBroker mountPointDataBroker;
 
     @Before
     public void init() {
         ctx = super.createPolicyContext();
+        mountedDataProviderMock = Mockito.mock(MountedDataBrokerProvider.class);
+        mountPointDataBroker = Mockito.mock(DataBroker.class);
+        Mockito.when(mountedDataProviderMock.getDataBrokerForMountPoint(Mockito.any(InstanceIdentifier.class)))
+            .thenReturn(Optional.of(mountPointDataBroker));
     }
 
     @Test
     public void resolveAclsOnInterfaceTest() {
         // TODO add more checking
+        AclManager aclManager = new AclManager(mountedDataProviderMock);
         List<AccessListWrapper> acls =
-                AccessListUtil.resolveAclsOnInterface(rendererEndpoint(l2AddrEp2).build().getKey(), ctx);
+                aclManager.resolveAclsOnInterface(rendererEndpoint(l2AddrEp2).build().getKey(), ctx);
         Assert.assertEquals(2, acls.size());
         Assert.assertEquals(2, acls.stream().map(AccessListWrapper::getDirection).collect(Collectors.toSet()).size());
         acls.stream().forEach(ace -> {