Bug 8228 - metadata service fix made cleaner 35/54835/25
authorMichal Cmarada <mcmarada@cisco.com>
Wed, 5 Apr 2017 11:22:11 +0000 (13:22 +0200)
committerTomas Cechvala <tcechval@cisco.com>
Wed, 10 May 2017 15:47:14 +0000 (17:47 +0200)
This patch sticks more to the architecture.

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

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

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

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

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

Change-Id: Id72d5646fbd7af1a8094749e58ba714bb3d84959
Signed-off-by: Tomas Cechvala <tcechval@cisco.com>
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 cf1ad19a3132df4d1ff906fb6a5d92084469f239..070828d56f23d92db98ae3b41b13f8365a9aa4c1 100644 (file)
@@ -591,7 +591,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 -> {