Merge "BVI fix for L3 scenario with LISP"
authorTomas Cechvala <tcechval@cisco.com>
Thu, 11 May 2017 12:23:12 +0000 (12:23 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 11 May 2017 12:23:12 +0000 (12:23 +0000)
49 files changed:
artifacts/pom.xml
features/features-groupedpolicy/pom.xml
features/features-groupedpolicy/src/main/features/features.xml
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/pom.xml
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 [new file with mode: 0644]
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapperTest.java
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 61d208d0ba2c27d18a4c673b0bc880fc08ff0134..7a603a8ec73c5cfa14a2c0ff1532842a044546c3 100755 (executable)
         <type>xml</type>
         <classifier>config</classifier>
       </dependency>
+      <dependency>
+        <groupId>${project.groupId}</groupId>
+        <artifactId>neutron-mapper</artifactId>
+        <version>${project.version}</version>
+        <type>cfg</type>
+        <classifier>config</classifier>
+      </dependency>
       <dependency>
         <groupId>${project.groupId}</groupId>
         <artifactId>neutron-vpp-mapper</artifactId>
index 5dabb6cb933079d4da5ec50e7b41695913b02172..36ead170d5bc4d9ed5c627806ffb2db642e24cfa 100644 (file)
             <type>cfg</type>
             <classifier>config</classifier>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>neutron-mapper</artifactId>
+            <type>cfg</type>
+            <classifier>config</classifier>
+        </dependency>
     </dependencies>
 </project>
index f32fb7b3297f67406eeba696d96361974c674d78..945d05798bfb62a2ac40ac03d548e017813f5af3 100755 (executable)
         <bundle>mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/{{VERSION}}</bundle>
         <configfile finalname="${config.configfile.directory}/15-l2-l3-domain-extension.xml">mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}/xml/config</configfile>
+        <!-- <configfile finalname="${config.configfile.directory}/15-neutron-mapper.xml">mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/{{VERSION}}/xml/config</configfile> -->
+        <configfile finalname="/etc/org.opendaylight.groupbasedpolicy.neutron.mapper.startup.cfg">mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/{{VERSION}}/cfg/config</configfile>
     </feature>
 
     <!--
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 51c2ea7a84473e752e475f08e7b0e6d075da7e3a..c97a96b440b5ac7b95e5b5d72a808645992a6e2a 100644 (file)
           </instructions>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <phase>package</phase>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/startup.cfg</file>
+                  <type>cfg</type>
+                  <classifier>config</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
index 9b25add6a9b3ee1a9712efb11a91d800bbcf90cb..b761246edc3a15312775cacbed0e4c4869321333 100644 (file)
@@ -8,6 +8,10 @@
 
 package org.opendaylight.controller.config.yang.config.neutron_mapper.impl;
 
+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;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -19,6 +23,9 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
 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;
@@ -33,15 +40,38 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose
     private final DataBroker dataBroker;
     private final ClusterSingletonServiceProvider clusterSingletonService;
     private final RpcProviderRegistry rpcBroker;
+    private IpPrefix metadataIpPrefix;
+    private int metadataPort;
     private ClusterSingletonServiceRegistration singletonServiceRegistration;
     private NeutronMapper mapper;
 
     public NeutronMapperInstance(final DataBroker dataBroker,
                                  final RpcProviderRegistry rpcBroker,
-                                 final ClusterSingletonServiceProvider clusterSingletonService) {
+                                 final ClusterSingletonServiceProvider clusterSingletonService,
+                                 final String metadataIp,
+                                 final String metadataPort) {
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         this.rpcBroker = Preconditions.checkNotNull(rpcBroker);
         this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService);
+        try {
+            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.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);
+            } else {
+                LOG.warn("MetadataIP could not be resolved. Provided value: {}. Continue without support for metadata.",
+                    metadataIp);
+            }
+            this.metadataIpPrefix = null;
+        }
     }
 
     public void instantiate() {
@@ -54,7 +84,7 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose
         LOG.info("Instantiating {}", this.getClass().getSimpleName());
         final EndpointService epService = rpcBroker.getRpcService(EndpointService.class);
         final BaseEndpointService baseEndpointService = rpcBroker.getRpcService(BaseEndpointService.class);
-        mapper = new NeutronMapper(dataBroker, epService, baseEndpointService);
+        mapper = new NeutronMapper(dataBroker, epService, baseEndpointService, metadataIpPrefix, metadataPort);
     }
 
     @Override
index f1cd873f3f6a60eae27c55c0f3b418c5c0287471..da456032c19f63189996cadc455a0cabe201e536 100644 (file)
@@ -32,6 +32,7 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronSubnetAwa
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
@@ -104,14 +105,14 @@ public class NeutronMapper implements ClusteredDataTreeChangeListener<Neutron>,
     private Neutron neutronBefore;
     private Neutron neutronAfter;
 
-    public NeutronMapper(DataBroker dataProvider, EndpointService epService,
-            BaseEndpointService baseEpService) {
+    public NeutronMapper(DataBroker dataProvider, EndpointService epService, BaseEndpointService baseEpService,
+        @Nullable IpPrefix metadataIpPrefix, long metadataTcpPort) {
         EndpointRegistrator epRegistrator = new EndpointRegistrator(epService, baseEpService);
-        networkAware = new NeutronNetworkAware(dataProvider);
-        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 6a33eb3709377885d4c43d2ee78f7a55e85db3b9..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}
@@ -201,25 +176,8 @@ public class NetworkService {
         ProviderNamedSelector dhcpProviderSelector = createProviderSelector(DHCP_CONTRACT);
         ProviderNamedSelector dnsProviderSelector = createProviderSelector(DNS_CONTRACT);
         ProviderNamedSelector mgmtProviderSelector = createProviderSelector(MGMT_CONTRACT);
-        return new EndpointGroupBuilder().setId(EPG_ID)
-            .setName(NETWORK_SERVICE_EPG_NAME)
+        return createEpgBuilder(EPG_ID, NETWORK_SERVICE_EPG_NAME, NETWORK_SERVICE_EPG_DESC)
             .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector, mgmtProviderSelector))
-            .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()))
             .build();
     }
 
@@ -233,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() {
@@ -254,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() {
@@ -276,23 +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 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);
     }
 
     /**
@@ -340,39 +276,6 @@ public class NetworkService {
                 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
@@ -424,176 +327,127 @@ public class NetworkService {
         cis.add(createSshTcpIpv6ClientServer());
         cis.add(createIcmpIpv4());
         cis.add(createIcmpIpv6());
-
         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();
-    }
-
-    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 bd2a45faaa7abaddfe05cdd5481be721c38b2704..00342dcb2d82a5084ae249d1070ad59ae811c654 100644 (file)
@@ -18,6 +18,7 @@ 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;
@@ -56,10 +57,12 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
     public static final InstanceIdentifier<Network> NETWORK_WILDCARD_IID =
             InstanceIdentifier.builder(Neutron.class).child(Networks.class).child(Network.class).build();
     private final DataBroker dataProvider;
-    private final Set<TenantId> tenantsWithRouterAndNetworkSeviceEntities = new HashSet<>();
+    private final Set<TenantId> tenantsWithRouterAndNetworkServiceEntities = new HashSet<>();
+    private final long metadataTcpPort;
 
-    public NeutronNetworkAware(DataBroker dataProvider) {
+    public NeutronNetworkAware(DataBroker dataProvider, long metadataPort) {
         this.dataProvider = checkNotNull(dataProvider);
+        this.metadataTcpPort = metadataPort;
     }
 
     @Override
@@ -99,8 +102,8 @@ public class NeutronNetworkAware implements NeutronAware<Network> {
 
         createTenantNetworkDomains(network, tenantId, rwTx);
 
-        if (!tenantsWithRouterAndNetworkSeviceEntities.contains(tenantId)) {
-            tenantsWithRouterAndNetworkSeviceEntities.add(tenantId);
+        if (!tenantsWithRouterAndNetworkServiceEntities.contains(tenantId)) {
+            tenantsWithRouterAndNetworkServiceEntities.add(tenantId);
             NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx);
             NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
             NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
@@ -109,6 +112,13 @@ 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);
+            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);
+            }
         }
         if (!NetworkUtils.getPhysicalNetwork(network).isEmpty() && !NetworkUtils.getSegmentationId(network).isEmpty()) {
             addProviderPhysicalNetworkMapping(tenantId, ctxId, NetworkUtils.getSegmentationId(network), 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 e06639d7b5294816b0b3c45d7caaae9dc8c30fe1..b9bc8a3650cf9a795ee4d57d8704577526eeb24a 100644 (file)
@@ -1,16 +1,26 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
            odl:use-default-for-reference-types="true">
 
     <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
     <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
     <reference id="clusterSingletonService" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
+    <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"/>
+            <cm:property name="metadata-port" value="80"/>
+        </cm:default-properties>
+    </cm:property-placeholder>
+
     <bean id="neutronMapper" class="org.opendaylight.controller.config.yang.config.neutron_mapper.impl.NeutronMapperInstance"
           init-method="instantiate" destroy-method="close">
         <argument ref="dataBroker"/>
         <argument ref="rpcRegistry"/>
         <argument ref="clusterSingletonService"/>
+        <argument value="${metadata-ip}"/>
+        <argument value="${metadata-port}"/>
     </bean>
-</blueprint>
\ No newline at end of file
+</blueprint>
diff --git a/neutron-mapper/src/main/resources/startup.cfg b/neutron-mapper/src/main/resources/startup.cfg
new file mode 100644 (file)
index 0000000..e8f6aa5
--- /dev/null
@@ -0,0 +1,13 @@
+# INITIAL NEUTRON MAPPER CONFIGURATION
+#
+# Uncomment lines on the bottom of this file to change default values of neutron
+# mapper bundle config. The file should be placed to karaf_root_dir/etc
+#
+# 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.253
+
+# To explicitly specify which port should be used for metadata
+# service in openstack, uncomment and modify following line.
+metadata-port = 80
index 059ef8d08e3b12006823da545be68245428f072a..5525dd436afc733f9f5f4c453f62e005473a3258 100644 (file)
@@ -27,12 +27,13 @@ import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronNetworkAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 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.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.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
@@ -61,9 +62,10 @@ public class NeutronMapperTest extends NeutronMapperDataBrokerTest {
     private final Uuid tenantUuid = new Uuid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
     private final Uuid networkUuid = new Uuid("dddddddd-dddd-dddd-dddd-dddddddddddd");
     private final Uuid networkUuid2 = new Uuid("dddddddd-dddd-dddd-dddd-ddddddddddd2");
+    private static final long METADATA_IPV4_SERVER_PORT = 80;
+    private static final IpPrefix METADATA_IP_PREFIX = new IpPrefix(new Ipv4Prefix("169.254.169.254/32"));
 
     private DataBroker dataBroker;
-    private RpcProviderRegistry rpcProvider;
     private EndpointService epService;
     private BaseEndpointService baseEpService;
 
@@ -84,7 +86,7 @@ public class NeutronMapperTest extends NeutronMapperDataBrokerTest {
         epService = mock(EndpointService.class);
         baseEpService = mock(BaseEndpointService.class);
 
-        mapper = new NeutronMapper(dataBroker, epService, baseEpService);
+        mapper = new NeutronMapper(dataBroker, epService, baseEpService, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT);
 
         networkL3Extension = new NetworkL3ExtensionBuilder().setExternal(true).build();
 
@@ -117,7 +119,8 @@ public class NeutronMapperTest extends NeutronMapperDataBrokerTest {
     @Test
     public void testConstructor() throws IOException {
         DataBroker dataBrokerSpy = spy(dataBroker);
-        NeutronMapper other = new NeutronMapper(dataBrokerSpy, epService, baseEpService);
+        NeutronMapper other = new NeutronMapper(dataBrokerSpy, epService, baseEpService, METADATA_IP_PREFIX,
+            METADATA_IPV4_SERVER_PORT);
 
         verify(dataBrokerSpy).registerDataTreeChangeListener(new DataTreeIdentifier<>(
                 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Neutron.class).build()), other);
index fc2bb82bab3f15dd0008998ab1c0a201db4583bd..2d5c2fcb5ceb42ad65f758c5ca698fe936090715 100644 (file)
@@ -55,6 +55,13 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
     private static final String ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME = "ICMP_IPV4_BETWEEN_SERVER_CLIENT";
     private static final String ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME = "ICMP_IPV6_BETWEEN_SERVER_CLIENT";
 
+    // metadata
+    private static final SubjectName METADATA_SUBJECT_NAME = new SubjectName("ALLOW_METADATA");
+    private static final String METADATA_SERVER_TO_CLIENT_NAME = "METADATA_FROM_SERVER_TO_CLIENT";
+    private static final String METADATA_CLIENT_TO_SERVER_NAME = "METADATA_FROM_CLIENT_TO_SERVER";
+    private static final long METADATA_IPV4_SERVER_PORT = 80;
+    private final IpPrefix metadataIpv4Prefix = new IpPrefix(new Ipv4Prefix("169.254.169.254/32"));
+
     private final String tenantId = "00000000-0000-0000-0000-000000000001";
     private final IpPrefix ipv4Prefix = new IpPrefix(new Ipv4Prefix("170.0.0.1/8"));
     private final IpPrefix ipv6Prefix = new IpPrefix(new Ipv6Prefix("2001:0db8:85a3:0000:0000:8a2e:0370:7334/128"));
@@ -131,6 +138,58 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
                 clauseNameIpV6);
     }
 
+
+    @Test
+    public void testWriteMgmtClauseWithConsProvEicIpv4() throws Exception {
+        // ipv4
+        DataBroker dataBroker = getDataBroker();
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        NetworkService.writeMgmtClauseWithConsProvEic(new TenantId(tenantId), ipv4Prefix, rwTx);
+        rwTx.submit().get();
+
+        // expected clause name
+        String clauseNameIpV4 = MGMT_SUBJECT_NAME.getValue() + MappingUtils.NAME_DOUBLE_DELIMETER
+            + ipv4Prefix.getIpv4Prefix().getValue();
+        clauseNameIpV4 = clauseNameIpV4.replace('/', '_');
+
+        PolicyAssert.assertClauseExists(dataBroker, tenantId, NetworkService.MGMT_CONTRACT_ID.getValue(),
+            clauseNameIpV4);
+    }
+
+    @Test
+    public void testWriteMgmtClauseWithConsProvEicIpv6() throws Exception {
+        // ipv6
+        DataBroker dataBroker = getDataBroker();
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        NetworkService.writeMgmtClauseWithConsProvEic(new TenantId(tenantId), ipv6Prefix, rwTx);
+        rwTx.submit().get();
+
+        // expected clause name
+        String clauseNameIpV6 = MGMT_SUBJECT_NAME.getValue() + MappingUtils.NAME_DOUBLE_DELIMETER
+            + ipv6Prefix.getIpv6Prefix().getValue();
+        clauseNameIpV6 = clauseNameIpV6.replace('/', '_').replace(':', '.');
+
+        PolicyAssert.assertClauseExists(dataBroker, tenantId, NetworkService.MGMT_CONTRACT_ID.getValue(),
+            clauseNameIpV6);
+    }
+
+    @Test
+    public void testWriteMetadataClauseWithConsProvEicIpv4() throws Exception {
+        // ipv4
+        DataBroker dataBroker = getDataBroker();
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        MetadataService.writeMetadataClauseWithConsProvEic(new TenantId(tenantId), metadataIpv4Prefix, rwTx);
+        rwTx.submit().get();
+
+        // expected clause name
+        String clauseNameIpV4 = METADATA_SUBJECT_NAME.getValue() + MappingUtils.NAME_DOUBLE_DELIMETER
+            + metadataIpv4Prefix.getIpv4Prefix().getValue();
+        clauseNameIpV4 = clauseNameIpV4.replace('/', '_');
+
+        PolicyAssert.assertClauseExists(dataBroker, tenantId, MetadataService.METADATA_CONTRACT_ID.getValue(),
+            clauseNameIpV4);
+    }
+
     @Test
     public void testWriteNetworkServiceEntitiesToTenant() throws Exception {
         // write everything
@@ -170,10 +229,11 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest {
 
     @Test
     public void testGetAllClassifierInstances() {
-        Set<ClassifierInstance> classifierInstances = NetworkService.getAllClassifierInstances();
+        Set<ClassifierInstance> classifierInstances =
+            NetworkService.getAllClassifierInstances();
         assertNotNull(classifierInstances);
         assertFalse(classifierInstances.isEmpty());
-        assertEquals(classifierInstances.size(), 18);
+        assertEquals(18, classifierInstances.size());
     }
 
 }
index a56822f93fbcdf564c4390e9f2ed561dde73b64c..e18818bd472a5e7ee3540373825267a88f89f08c 100644 (file)
@@ -18,6 +18,7 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
 import com.google.common.base.Optional;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -28,6 +29,8 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
 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.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.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
@@ -45,6 +48,8 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes
 
     private final Uuid tenantUuid = new Uuid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
     private final Uuid networkUuid = new Uuid("dddddddd-dddd-dddd-dddd-dddddddddddd");
+    private static final long METADATA_IPV4_SERVER_PORT = 80;
+    private static final IpPrefix METADATA_IP_PREFIX = new IpPrefix(new Ipv4Prefix("169.254.169.254/32"));
 
     private DataBroker dataBroker;
     private NeutronNetworkAware networkAware;
@@ -80,7 +85,7 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes
             .addAugmentation(NetworkProviderExtension.class, providerExtension)
             .build();
 
-        networkAware = new NeutronNetworkAware(dataBroker);
+        networkAware = new NeutronNetworkAware(dataBroker, METADATA_IPV4_SERVER_PORT);
     }
 
     @Rule
@@ -89,7 +94,7 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes
     @Test
     public void testConstructor_invalidArgument() throws NullPointerException {
         thrown.expect(NullPointerException.class);
-        new NeutronNetworkAware(null);
+        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 683ff807f76bbdcc78da0059a0f847eca73de688..813d8df7d0b52a0c53b5341d60e52f9144eecc7c 100644 (file)
@@ -33,7 +33,9 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
 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.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.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
@@ -69,6 +71,8 @@ public class NeutronRouterAwareDataStoreTest extends NeutronMapperDataBrokerTest
     private final Uuid networkUuid = new Uuid("dddddddd-dddd-dddd-dddd-dddddddddddd");
     private final Uuid gatewayPortUuid = new Uuid("dddddddd-dddd-dddd-dddd-ddddddddddd1");
     private final IpAddress ipAddress = new IpAddress(new Ipv4Address("10.0.0.2"));
+    private static final long METADATA_IPV4_SERVER_PORT = 80;
+    private static final IpPrefix METADATA_IP_PREFIX = new IpPrefix(new Ipv4Prefix("169.254.169.254/32"));
 
     private DataBroker dataBroker;
     private NeutronRouterAware routerAware;
@@ -108,7 +112,7 @@ public class NeutronRouterAwareDataStoreTest extends NeutronMapperDataBrokerTest
                     .thenReturn(futureRpcResult);
         epRegistrator = new EndpointRegistrator(epService, baseEpService);
 
-        networkAware = new NeutronNetworkAware(dataBroker);
+        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 a8a33222655e118a7c7413ecf90e88e68ff1153e..2d8086b84980d781d3088adc42db0878a4ade365 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.GbpSubnetListener;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.RendererPolicyListener;
@@ -33,6 +32,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 987b126192393bf91a0b0d1bc617f159f43b92e9..d8da5666930fad1cb5ad951e432f2838b773bea0 100644 (file)
@@ -602,7 +602,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 f65248ca8655e17228427ecd04fd6e3b0302c243..759e849604bcefd1162663b142730b50f3d00b0a 100644 (file)
@@ -26,11 +26,10 @@ 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.config.ConfigUtil;
-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;
@@ -210,11 +209,10 @@ public final class ForwardingManager {
                 LOG.info("Renderer endpoint does not have l2FloodDomain as network containment {}", rEp);
                 return;
             }
-
             if (!ConfigUtil.getInstance().isL3FlatEnabled()) {
                 String l2FloodDomain = optL2FloodDomain.get();
                 try {
-                    ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, AccessListUtil.resolveAclsOnInterface(
+                    ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, aclManager.resolveAclsOnInterface(
                         rEpKey, policyCtx), isBviForEndpoint(rEp)).get();
                     LOG.debug("Interface added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp);
 
index 348c96b13320958035a61f49a8426806bee62d34..c5369d8f6bd493354e92f934abe5d2baafc5191e 100644 (file)
@@ -25,7 +25,7 @@ import org.opendaylight.groupbasedpolicy.renderer.util.AddressEndpointUtils;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil;
 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;
@@ -121,6 +121,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();
@@ -267,6 +268,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();
         if (!ConfigUtil.getInstance().isL3FlatEnabled()) {
             SetMultimap<String, NodeId> vppNodesByL2Fd = resolveVppNodesByL2Fd(rEpKeys, policyCtx);
@@ -280,6 +282,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 bb7f7dbb13e6de720354db84ea8b9a78e986c905..73c2bbdfd79af567d654d1b94294eeae18ce8c60 100644 (file)
@@ -37,18 +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)) {
-                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 ebaeb361178e2ba926ae1744f1ea1d14791841a2..6f88ea7fb4ca52f797c1ea6200e335ee289dda10 100644 (file)
@@ -37,18 +37,23 @@ class SourceMapper extends AddressMapper {
 
     @Override
     void updateRule(AddressEndpointWithLocation addrEp, GbpAceBuilder aclRuleBuilder) {
-        if (!EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).isEmpty()) {
-            // TODO more parents
+        // 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)) {
-                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 827b961014c0894aeee8fefc11a3df5c949b7046..95e0bc39fd277461404ef7f37a65ac217e22855b 100644 (file)
@@ -54,9 +54,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.servers.grouping.map.servers.MapServerKey;
 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;
@@ -94,11 +94,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..435a7a5caaa21bf7e01f68adac2ccc94867db7d1 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 {
+        AddressEndpoint addrEp = new AddressEndpointBuilder()
+            .setKey(new AddressEndpointKey(vhostVppEpBuilder().getAddress(), vhostVppEpBuilder().getAddressType(),
+                    vhostVppEpBuilder().getContextId(), vhostVppEpBuilder().getContextType()))
+            .setEndpointGroup(ImmutableList.of())
+            .build();
+        VppEndpointLocationProvider vppEpLocProvider = new VppEndpointLocationProvider(dataBroker);
+        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 -> {