Bug 3240 3613: Asymetric policy in neutron 47/27147/1
authorMartin Sunal <msunal@cisco.com>
Wed, 17 Jun 2015 14:00:00 +0000 (16:00 +0200)
committerMartin Sunal <msunal@cisco.com>
Fri, 18 Sep 2015 08:26:20 +0000 (08:26 +0000)
bug 3613
naming is more user-friendly because is composed from classifiers and actions

bug 3240
Assymetrical policy can occur when using neutron remote-security-group in rule.
Analysis showed that problem is caused by ANY endpoint-group
Fix of this bug is removing of ANY endpoint-group.

Basicly neutron Security Group Rule (SecRule) is translated to one Contract containing
one Subject with one Rule.

Change-Id: I8724c9eaa0244182ab26e2870399630c74b842df
Signed-off-by: Martin Sunal <msunal@cisco.com>
(cherry picked from commit 3bdadfae6e60e8ac58dd8572786da340f21b14ab)

28 files changed:
neutron-mapper/pom.xml
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkClient.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkService.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/Router.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/NeutronRouterAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSecurityRuleAware.java [deleted file]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/TransformSecRule.java [deleted file]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/group/NeutronSecurityGroupAware.java [moved from neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSecurityGroupAware.java with 82% similarity]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/group/SecGroupDao.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAware.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleDao.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleEntityDecoder.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleNameDecoder.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SingleClassifierRule.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SingleRuleContract.java [new file with mode: 0644]
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/MappingUtils.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/NeutronMapperIidFactory.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/Utils.java
neutron-mapper/src/main/yang/mapper.yang
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareDataStoreTest.java [new file with mode: 0644]
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareTest.java [new file with mode: 0644]
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleDecoderTest.java [new file with mode: 0644]
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/test/GbpDataBrokerTest.java [new file with mode: 0644]
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/UtilsTest.java [new file with mode: 0644]

index b2df807254b847cea49770e03d7252394ea9d755..0a99f84c01d18239899a1d106a7975c6aa8315fd 100644 (file)
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.core</artifactId>
     </dependency>
+    <!-- testing dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-broker-impl</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
     <!-- Sonar -->
     <dependency>
       <groupId>org.codehaus.sonar-plugins.java</groupId>
index 5a196a415cad765b4afd9beb7231da742054bb79..e46cdff4ec7064541605e55217ce2e38bc8e608b 100644 (file)
@@ -19,9 +19,11 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronFloatingI
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronNetworkAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronPortAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronRouterAware;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronSecurityGroupAware;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronSecurityRuleAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronSubnetAware;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.NeutronSecurityGroupAware;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.SecGroupDao;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.SecRuleDao;
 import org.opendaylight.neutron.spi.INeutronFloatingIPAware;
 import org.opendaylight.neutron.spi.INeutronNetworkAware;
 import org.opendaylight.neutron.spi.INeutronPortAware;
@@ -42,38 +44,43 @@ public class NeutronMapper implements AutoCloseable {
         checkNotNull(rpcProvider);
         checkNotNull(context);
         EndpointService epService = rpcProvider.getRpcService(EndpointService.class);
-
         registerAwareProviders(dataProvider, epService, context);
     }
 
     private void registerAwareProviders(DataBroker dataProvider, EndpointService epService, BundleContext context) {
-        ServiceRegistration<INeutronNetworkAware> neutronNetworkAwareRegistration = context.registerService(
-                INeutronNetworkAware.class, new NeutronNetworkAware(dataProvider), null);
+        ServiceRegistration<INeutronNetworkAware> neutronNetworkAwareRegistration =
+                context.registerService(INeutronNetworkAware.class, new NeutronNetworkAware(dataProvider), null);
         registrations.add(neutronNetworkAwareRegistration);
 
-        ServiceRegistration<INeutronSubnetAware> neutronSubnetAwareRegistration = context.registerService(
-                INeutronSubnetAware.class, new NeutronSubnetAware(dataProvider), null);
+        ServiceRegistration<INeutronSubnetAware> neutronSubnetAwareRegistration =
+                context.registerService(INeutronSubnetAware.class, new NeutronSubnetAware(dataProvider), null);
         registrations.add(neutronSubnetAwareRegistration);
 
-        ServiceRegistration<INeutronPortAware> neutronPortAwareRegistration = context.registerService(
-                INeutronPortAware.class, new NeutronPortAware(dataProvider, epService), null);
-        registrations.add(neutronPortAwareRegistration);
+        SecGroupDao secGroupDao = new SecGroupDao();
+        SecRuleDao secRuleDao = new SecRuleDao();
+        NeutronSecurityRuleAware securityRuleAware = new NeutronSecurityRuleAware(dataProvider, secRuleDao, secGroupDao);
+        ServiceRegistration<INeutronSecurityRuleAware> neutronSecurityRuleAwareRegistration =
+                context.registerService(INeutronSecurityRuleAware.class, securityRuleAware, null);
+        registrations.add(neutronSecurityRuleAwareRegistration);
 
-        ServiceRegistration<INeutronSecurityGroupAware> neutronSecurityGroupAwareRegistration = context.registerService(
-                INeutronSecurityGroupAware.class, new NeutronSecurityGroupAware(dataProvider), null);
+        NeutronSecurityGroupAware securityGroupAware = new NeutronSecurityGroupAware(dataProvider, securityRuleAware, secGroupDao);
+        ServiceRegistration<INeutronSecurityGroupAware> neutronSecurityGroupAwareRegistration =
+                context.registerService(INeutronSecurityGroupAware.class, securityGroupAware, null);
         registrations.add(neutronSecurityGroupAwareRegistration);
 
-        ServiceRegistration<INeutronSecurityRuleAware> neutronSecurityRuleAwareRegistration = context.registerService(
-                INeutronSecurityRuleAware.class, new NeutronSecurityRuleAware(dataProvider), null);
-        registrations.add(neutronSecurityRuleAwareRegistration);
+        NeutronPortAware portAware =
+                new NeutronPortAware(dataProvider, epService, securityRuleAware, securityGroupAware);
+        ServiceRegistration<INeutronPortAware> neutronPortAwareRegistration =
+                context.registerService(INeutronPortAware.class, portAware, null);
+        registrations.add(neutronPortAwareRegistration);
 
-        NeutronRouterAware.init(dataProvider, epService);
-        ServiceRegistration<INeutronRouterAware> neutronRouterAwareRegistration = context.registerService(
-                INeutronRouterAware.class, NeutronRouterAware.getInstance(), null);
+        NeutronRouterAware routerAware = new NeutronRouterAware(dataProvider, epService, securityRuleAware);
+        ServiceRegistration<INeutronRouterAware> neutronRouterAwareRegistration =
+                context.registerService(INeutronRouterAware.class, routerAware, null);
         registrations.add(neutronRouterAwareRegistration);
 
-        ServiceRegistration<INeutronFloatingIPAware> neutronFloatingIpAwareRegistration = context.registerService(
-                INeutronFloatingIPAware.class, new NeutronFloatingIpAware(dataProvider, epService), null);
+        ServiceRegistration<INeutronFloatingIPAware> neutronFloatingIpAwareRegistration = context
+            .registerService(INeutronFloatingIPAware.class, new NeutronFloatingIpAware(dataProvider, epService), null);
         registrations.add(neutronFloatingIpAwareRegistration);
     }
 
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkClient.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkClient.java
new file mode 100644 (file)
index 0000000..8ce6717
--- /dev/null
@@ -0,0 +1,67 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure;
+
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+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.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
+
+import com.google.common.base.Preconditions;
+
+public class NetworkClient {
+
+    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.");
+    /**
+     * ID of {@link #EPG}
+     */
+    public static final EndpointGroupId EPG_ID = new EndpointGroupId("ccc5e444-573c-11e5-885d-feff819cdc9f");
+    /**
+     * Network-client endpoint-group consuming no contract
+     */
+    public static final EndpointGroup EPG;
+
+    static {
+        EPG = createNetworkClientEpg();
+    }
+
+    private static EndpointGroup createNetworkClientEpg() {
+        return new EndpointGroupBuilder().setId(EPG_ID)
+            .setName(NETWORK_CLIENT_EPG_NAME)
+            .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
+            .setDescription(NETWORK_CLIENT_EPG_DESC)
+            .build();
+    }
+
+    /**
+     * Puts {@link #EPG} to {@link LogicalDatastoreType#CONFIGURATION}
+     * 
+     * @param tenantId location of {@link #EPG}
+     * @param wTx transaction where {@link #EPG} is written
+     */
+    public static void writeNetworkClientEntitiesToTenant(TenantId tenantId, WriteTransaction wTx) {
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true);
+    }
+
+    /**
+     * Puts consumer-named-selector to {@link #EPG} in {@link LogicalDatastoreType#CONFIGURATION}
+     * 
+     * @param tenantId tenantId location of {@link #EPG}
+     * @param consumerNamedSelector is added to {@link #EPG}
+     * @param wTx transaction where the given consumer-named-selector is written
+     */
+    public static void writeConsumerNamedSelector(TenantId tenantId, ConsumerNamedSelector consumerNamedSelector,
+            WriteTransaction wTx) {
+        Preconditions.checkNotNull(consumerNamedSelector);
+        wTx.put(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.consumerNamedSelectorIid(tenantId, EPG_ID, consumerNamedSelector.getName()),
+                consumerNamedSelector, true);
+    }
+
+}
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkService.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkService.java
new file mode 100644 (file)
index 0000000..5d3860f
--- /dev/null
@@ -0,0 +1,450 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+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.neutron.mapper.util.MappingUtils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.EtherTypeClassifier;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.IpProtoClassifier;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.L4Classifier;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.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.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.Contract;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.SubjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstanceBuilder;
+
+import com.google.common.collect.ImmutableList;
+
+public class NetworkService {
+
+    // ########### DHCP
+    private static final long DHCP_IPV4_SERVER_PORT = 67;
+    private static final long DHCP_IPV4_CLIENT_PORT = 68;
+    private static final long DHCP_IPV6_SERVER_PORT = 547;
+    private static final long DHCP_IPV6_CLIENT_PORT = 546;
+    private static final ClassifierName DHCP_IPV4_CLIENT_SERVER_NAME =
+            new ClassifierName("DHCP_IPv4_FROM_CLIENT_TO_SERVER");
+    private static final ClassifierName DHCP_IPV4_SERVER_CLIENT_NAME =
+            new ClassifierName("DHCP_IPv4_FROM_SERVER_TO_CLIENT");
+    private static final ClassifierName DHCP_IPV6_CLIENT_SERVER_NAME =
+            new ClassifierName("DHCP_IPv6_FROM_CLIENT_TO_SERVER");
+    private static final ClassifierName DHCP_IPV6_SERVER_CLIENT_NAME =
+            new ClassifierName("DHCP_IPv6_FROM_SERVER_TO_CLIENT");
+    private static final SubjectName DHCP_SUBJECT_NAME = new SubjectName("ALLOW_DHCP");
+    private static final Description DHCP_CONTRACT_DESC =
+            new Description("Allow DHCP communication between client and server.");
+    /**
+     * Id of {@link #DHCP_CONTRACT}
+     */
+    public static final ContractId DHCP_CONTRACT_ID = new ContractId("11118d2e-dddd-11e5-885d-feff819cdc9f");
+    /**
+     * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching DHCP communication
+     * between Client and Server.
+     */
+    public static final Contract DHCP_CONTRACT;
+    /**
+     * {@link ConsumerNamedSelector} pointing to {@link #DHCP_CONTRACT}
+     */
+    public static final ConsumerNamedSelector DHCP_CONTRACT_CONSUMER_SELECTOR;
+
+    // ########### DNS
+    private static final long DNS_SERVER_PORT = 53;
+    private static final ClassifierName DNS_UDP_IPV4_CLIENT_SERVER_NAME =
+            new ClassifierName("DNS_UDP_IPv4_FROM_CLIENT_TO_SERVER");
+    private static final ClassifierName DNS_UDP_IPV4_SERVER_CLIENT_NAME =
+            new ClassifierName("DNS_UDP_IPv4_FROM_SERVER_TO_CLIENT");
+    private static final ClassifierName DNS_UDP_IPV6_CLIENT_SERVER_NAME =
+            new ClassifierName("DNS_UDP_IPv6_FROM_CLIENT_TO_SERVER");
+    private static final ClassifierName DNS_UDP_IPV6_SERVER_CLIENT_NAME =
+            new ClassifierName("DNS_UDP_IPv6_FROM_SERVER_TO_CLIENT");
+    private static final ClassifierName DNS_TCP_IPV4_CLIENT_SERVER_NAME =
+            new ClassifierName("DNS_TCP_IPv4_FROM_CLIENT_TO_SERVER");
+    private static final ClassifierName DNS_TCP_IPV4_SERVER_CLIENT_NAME =
+            new ClassifierName("DNS_TCP_IPv4_FROM_SERVER_TO_CLIENT");
+    private static final ClassifierName DNS_TCP_IPV6_CLIENT_SERVER_NAME =
+            new ClassifierName("DNS_TCP_IPv6_FROM_CLIENT_TO_SERVER");
+    private static final ClassifierName DNS_TCP_IPV6_SERVER_CLIENT_NAME =
+            new ClassifierName("DNS_TCP_IPv6_FROM_SERVER_TO_CLIENT");
+    private static final SubjectName DNS_SUBJECT_NAME = new SubjectName("ALLOW_DNS");
+    private static final Description DNS_CONTRACT_DESC =
+            new Description("Allow DNS communication between client and server.");
+    /**
+     * ID of {@link #DNS_CONTRACT}
+     */
+    public static final ContractId DNS_CONTRACT_ID = new ContractId("22218d2e-dddd-11e5-885d-feff819cdc9f");
+    /**
+     * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching DNS communication
+     * between Client and Server.
+     */
+    public static final Contract DNS_CONTRACT;
+    /**
+     * {@link ConsumerNamedSelector} pointing to {@link #DNS_CONTRACT}
+     */
+    public static final ConsumerNamedSelector DNS_CONTRACT_CONSUMER_SELECTOR;
+
+    // ########### NETWORK-SERVICE ENDPOINT-GROUP
+    private static final Name NETWORK_SERVICE_EPG_NAME = new Name("NETWORK_SERVICE");
+    private static final Description NETWORK_SERVICE_EPG_DESC = new Description("Represents DHCP and DNS servers.");
+    /**
+     * ID of {@link #EPG}
+     */
+    public static final EndpointGroupId EPG_ID = new EndpointGroupId("ddd6cfe6-dfe5-11e4-8a00-1681e6b88ec1");
+    /**
+     * Network-service endpoint-group providing {@link #DHCP_CONTRACT} and {@link #DNS_CONTRACT}
+     */
+    public static final EndpointGroup EPG;
+
+    static {
+        DHCP_CONTRACT = createContractDhcp();
+        DHCP_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(DHCP_CONTRACT);
+        DNS_CONTRACT = createContractDns();
+        DNS_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(DNS_CONTRACT);
+        EPG = createNetworkServiceEpg();
+    }
+
+    private static EndpointGroup createNetworkServiceEpg() {
+        ProviderNamedSelector dhcpProviderSelector = createProviderSelector(DHCP_CONTRACT);
+        ProviderNamedSelector dnsProviderSelector = createProviderSelector(DNS_CONTRACT);
+        return new EndpointGroupBuilder().setId(EPG_ID)
+            .setName(NETWORK_SERVICE_EPG_NAME)
+            .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector))
+            .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();
+    }
+
+    private static Contract createContractDhcp() {
+        Rule clientServerIpv4Rule = createRuleAllow(DHCP_IPV4_CLIENT_SERVER_NAME, Direction.In);
+        Rule serverClientIpv4Rule = createRuleAllow(DHCP_IPV4_SERVER_CLIENT_NAME, Direction.Out);
+        Rule clientServerIpv6Rule = createRuleAllow(DHCP_IPV6_CLIENT_SERVER_NAME, Direction.In);
+        Rule serverClientIpv6Rule = createRuleAllow(DHCP_IPV6_SERVER_CLIENT_NAME, Direction.Out);
+        Subject subject = new SubjectBuilder().setName(DHCP_SUBJECT_NAME)
+            .setOrder(0)
+            .setRule(ImmutableList.of(clientServerIpv4Rule, serverClientIpv4Rule, clientServerIpv6Rule,
+                    serverClientIpv6Rule))
+            .build();
+        return new ContractBuilder().setId(DHCP_CONTRACT_ID)
+            .setSubject(ImmutableList.of(subject))
+            .setDescription(DHCP_CONTRACT_DESC)
+            .build();
+    }
+
+    private static Contract createContractDns() {
+        Rule clientServerUdpIpv4Rule = createRuleAllow(DNS_UDP_IPV4_CLIENT_SERVER_NAME, Direction.In);
+        Rule serverClientUdpIpv4Rule = createRuleAllow(DNS_UDP_IPV4_SERVER_CLIENT_NAME, Direction.Out);
+        Rule clientServerUdpIpv6Rule = createRuleAllow(DNS_UDP_IPV6_CLIENT_SERVER_NAME, Direction.In);
+        Rule serverClientUdpIpv6Rule = createRuleAllow(DNS_UDP_IPV6_SERVER_CLIENT_NAME, Direction.Out);
+        Rule clientServerTcpIpv4Rule = createRuleAllow(DNS_TCP_IPV4_CLIENT_SERVER_NAME, Direction.In);
+        Rule serverClientTcpIpv4Rule = createRuleAllow(DNS_TCP_IPV4_SERVER_CLIENT_NAME, Direction.Out);
+        Rule clientServerTcpIpv6Rule = createRuleAllow(DNS_TCP_IPV6_CLIENT_SERVER_NAME, Direction.In);
+        Rule serverClientTcpIpv6Rule = createRuleAllow(DNS_TCP_IPV6_SERVER_CLIENT_NAME, Direction.Out);
+        Subject subject = new SubjectBuilder().setName(DNS_SUBJECT_NAME)
+            .setOrder(0)
+            .setRule(ImmutableList.of(clientServerUdpIpv4Rule, serverClientUdpIpv4Rule, clientServerUdpIpv6Rule,
+                    serverClientUdpIpv6Rule, clientServerTcpIpv4Rule, serverClientTcpIpv4Rule, clientServerTcpIpv6Rule,
+                    serverClientTcpIpv6Rule))
+            .build();
+        return new ContractBuilder().setId(DNS_CONTRACT_ID)
+            .setSubject(ImmutableList.of(subject))
+            .setDescription(DNS_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(MappingUtils.ACTION_REF_ALLOW)
+            .setClassifierRef(ImmutableList.of(classifierRef))
+            .build();
+    }
+
+    /**
+     * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
+     * and {@link ProviderMatchers}. This clause points to subject in {@link #DHCP_CONTRACT}.
+     * 
+     * @param tenantId location of {@link #DHCP_CONTRACT}
+     * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
+     * @param wTx transaction where entities are written
+     */
+    public static void writeDhcpClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
+            WriteTransaction wTx) {
+        Clause clause = createClauseWithConsProvEic(ipPrefix, DHCP_SUBJECT_NAME);
+        wTx.put(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.clauseIid(tenantId, DHCP_CONTRACT_ID, clause.getName()), clause, true);
+    }
+
+    /**
+     * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
+     * and {@link ProviderMatchers}. This clause points to subject in {@link #DNS_CONTRACT}.
+     * 
+     * @param tenantId location of {@link #DNS_CONTRACT}
+     * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
+     * @param wTx transaction where entities are written
+     */
+    public static void writeDnsClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
+            WriteTransaction wTx) {
+        Clause clause = createClauseWithConsProvEic(ipPrefix, DNS_SUBJECT_NAME);
+        wTx.put(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.clauseIid(tenantId, DNS_CONTRACT_ID, clause.getName()), clause, true);
+    }
+
+    private static Clause createClauseWithConsProvEic(@Nullable IpPrefix ipPrefix, SubjectName subjectName) {
+        ConsumerMatchers consumerMatchers = null;
+        ProviderMatchers providerMatchers = null;
+        StringBuilder clauseName = new StringBuilder();
+        clauseName.append(subjectName.getValue());
+        if (ipPrefix != null) {
+            clauseName.append(MappingUtils.NAME_DOUBLE_DELIMETER).append(Utils.getStringIpPrefix(ipPrefix));
+            consumerMatchers =
+                    new ConsumerMatchersBuilder()
+                        .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
+                            .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
+                                .setPrefixConstraint(
+                                        ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
+                                .build())
+                            .build())
+                        .build();
+            providerMatchers =
+                    new ProviderMatchersBuilder()
+                        .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
+                            .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
+                                .setPrefixConstraint(
+                                        ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
+                                .build())
+                            .build())
+                        .build();
+        }
+        return new ClauseBuilder().setName(new ClauseName(clauseName.toString()))
+            .setSubjectRefs(ImmutableList.of(subjectName))
+            .setConsumerMatchers(consumerMatchers)
+            .setProviderMatchers(providerMatchers)
+            .build();
+    }
+
+    /**
+     * Puts network service entities (classifier-instances, {@link #DHCP_CONTRACT},
+     * {@link #DNS_CONTRACT}, 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) {
+        Set<ClassifierInstance> classifierInstances = getAllClassifierInstances();
+        for (ClassifierInstance ci : classifierInstances) {
+            wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, ci.getName()), ci,
+                    true);
+        }
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, DHCP_CONTRACT_ID), DHCP_CONTRACT,
+                true);
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, DNS_CONTRACT_ID), DNS_CONTRACT,
+                true);
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true);
+    }
+
+    /**
+     * @return All classifier-instances used in {@link #DHCP_CONTRACT} and {@link #DNS_CONTRACT}
+     */
+    public static Set<ClassifierInstance> getAllClassifierInstances() {
+        HashSet<ClassifierInstance> cis = new HashSet<>();
+        cis.add(createDhcpIpv4ClientServer());
+        cis.add(createDhcpIpv4ServerClient());
+        cis.add(createDhcpIpv6ClientServer());
+        cis.add(createDhcpIpv6ServerClient());
+        cis.add(createDnsUdpIpv4ClientServer());
+        cis.add(createDnsUdpIpv4ServerClient());
+        cis.add(createDnsUdpIpv6ClientServer());
+        cis.add(createDnsUdpIpv6ServerClient());
+        cis.add(createDnsTcpIpv4ClientServer());
+        cis.add(createDnsTcpIpv4ServerClient());
+        cis.add(createDnsTcpIpv6ClientServer());
+        cis.add(createDnsTcpIpv6ServerClient());
+        return cis;
+    }
+
+    // ###################### DHCP
+    private static ClassifierInstance createDhcpIpv4ClientServer() {
+        return new ClassifierInstanceBuilder().setName(DHCP_IPV4_CLIENT_SERVER_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(createParams(EtherTypeClassifier.IPv4_VALUE, IpProtoClassifier.UDP_VALUE,
+                    DHCP_IPV4_CLIENT_PORT, DHCP_IPV4_SERVER_PORT))
+            .build();
+    }
+
+    private static ClassifierInstance createDhcpIpv4ServerClient() {
+        return new ClassifierInstanceBuilder().setName(DHCP_IPV4_SERVER_CLIENT_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(createParams(EtherTypeClassifier.IPv4_VALUE, IpProtoClassifier.UDP_VALUE,
+                    DHCP_IPV4_SERVER_PORT, DHCP_IPV4_CLIENT_PORT))
+            .build();
+    }
+
+    private static ClassifierInstance createDhcpIpv6ClientServer() {
+        return new ClassifierInstanceBuilder().setName(DHCP_IPV6_CLIENT_SERVER_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(createParams(EtherTypeClassifier.IPv6_VALUE, IpProtoClassifier.UDP_VALUE,
+                    DHCP_IPV6_CLIENT_PORT, DHCP_IPV6_SERVER_PORT))
+            .build();
+    }
+
+    private static ClassifierInstance createDhcpIpv6ServerClient() {
+        return new ClassifierInstanceBuilder().setName(DHCP_IPV6_SERVER_CLIENT_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(createParams(EtherTypeClassifier.IPv6_VALUE, IpProtoClassifier.UDP_VALUE,
+                    DHCP_IPV6_SERVER_PORT, DHCP_IPV6_CLIENT_PORT))
+            .build();
+    }
+
+    // ###################### DNS UDP
+    private static ClassifierInstance createDnsUdpIpv4ClientServer() {
+        return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_CLIENT_SERVER_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(
+                    createParams(EtherTypeClassifier.IPv4_VALUE, IpProtoClassifier.UDP_VALUE, null, DNS_SERVER_PORT))
+            .build();
+    }
+
+    private static ClassifierInstance createDnsUdpIpv4ServerClient() {
+        return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_SERVER_CLIENT_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(
+                    createParams(EtherTypeClassifier.IPv4_VALUE, IpProtoClassifier.UDP_VALUE, DNS_SERVER_PORT, null))
+            .build();
+    }
+
+    private static ClassifierInstance createDnsUdpIpv6ClientServer() {
+        return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_CLIENT_SERVER_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(
+                    createParams(EtherTypeClassifier.IPv6_VALUE, IpProtoClassifier.UDP_VALUE, null, DNS_SERVER_PORT))
+            .build();
+    }
+
+    private static ClassifierInstance createDnsUdpIpv6ServerClient() {
+        return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_SERVER_CLIENT_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(
+                    createParams(EtherTypeClassifier.IPv6_VALUE, IpProtoClassifier.UDP_VALUE, DNS_SERVER_PORT, null))
+            .build();
+    }
+
+    // ###################### DNS TCP
+    private static ClassifierInstance createDnsTcpIpv4ClientServer() {
+        return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_CLIENT_SERVER_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(
+                    createParams(EtherTypeClassifier.IPv4_VALUE, IpProtoClassifier.TCP_VALUE, null, DNS_SERVER_PORT))
+            .build();
+    }
+
+    private static ClassifierInstance createDnsTcpIpv4ServerClient() {
+        return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_SERVER_CLIENT_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(
+                    createParams(EtherTypeClassifier.IPv4_VALUE, IpProtoClassifier.TCP_VALUE, DNS_SERVER_PORT, null))
+            .build();
+    }
+
+    private static ClassifierInstance createDnsTcpIpv6ClientServer() {
+        return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_CLIENT_SERVER_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(
+                    createParams(EtherTypeClassifier.IPv6_VALUE, IpProtoClassifier.TCP_VALUE, null, DNS_SERVER_PORT))
+            .build();
+    }
+
+    private static ClassifierInstance createDnsTcpIpv6ServerClient() {
+        return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_SERVER_CLIENT_NAME)
+            .setClassifierDefinitionId(L4Classifier.DEFINITION.getId())
+            .setParameterValue(
+                    createParams(EtherTypeClassifier.IPv6_VALUE, IpProtoClassifier.TCP_VALUE, DNS_SERVER_PORT, 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(L4Classifier.SRC_PORT_PARAM))
+                .setIntValue(srcPort)
+                .build());
+        }
+        if (dstPort != null) {
+            params.add(new ParameterValueBuilder().setName(new ParameterName(L4Classifier.DST_PORT_PARAM))
+                .setIntValue(dstPort)
+                .build());
+        }
+        params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifier.PROTO_PARAM))
+            .setIntValue(proto)
+            .build());
+        params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifier.ETHERTYPE_PARAM))
+            .setIntValue(etherType)
+            .build());
+        return params;
+    }
+
+}
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/Router.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/Router.java
new file mode 100644 (file)
index 0000000..835a8e1
--- /dev/null
@@ -0,0 +1,249 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+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.neutron.mapper.util.MappingUtils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.EtherTypeClassifier;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.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.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.Contract;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.SubjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstanceBuilder;
+
+import com.google.common.collect.ImmutableList;
+
+public class Router {
+
+    private static final ClassifierName IPV4_NAME = new ClassifierName("IPv4");
+    private static final ClassifierName IPV6_NAME = new ClassifierName("IPv6");
+    private static final SubjectName ROUTER_SUBJECT_NAME = new SubjectName("ALLOW_IPv4_IPv6");
+    private static final Description ROUTER_CONTRACT_DESC =
+            new Description("Allow IPv4 and IPv6 communication between router interfaces and endpoints.");
+    /**
+     * ID of {@link Contract}
+     */
+    public static final ContractId CONTRACT_ID = new ContractId("111bc60e-1110-11e5-885d-feff819cdc9f");
+    /**
+     * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching IPv4 and IPv6
+     * communication in both directions
+     */
+    public static final Contract CONTRACT;
+
+    private static final Name ROUTER_EPG_NAME = new Name("ROUTER_PORTS");
+    private static final Description ROUTER_EPG_DESC = new Description("Represents router's interfaces.");
+    /**
+     * ID of {@link #EPG}
+     */
+    public static final EndpointGroupId EPG_ID = new EndpointGroupId("1118172e-cd84-4933-a35f-749f9a651de9");
+    /**
+     * Router endpoint-group providing {@link #CONTRACT}
+     */
+    public static final EndpointGroup EPG;
+    /**
+     * {@link ConsumerNamedSelector} pointing to {@link #CONTRACT}
+     */
+    public static final ConsumerNamedSelector CONTRACT_CONSUMER_SELECTOR;
+
+    static {
+        CONTRACT = createContractRouter();
+        CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(CONTRACT);
+        EPG = createRouterEpg();
+    }
+
+    private static EndpointGroup createRouterEpg() {
+        ProviderNamedSelector routerProviderSelector = createProviderSelector(CONTRACT);
+        return new EndpointGroupBuilder().setId(EPG_ID)
+            .setName(ROUTER_EPG_NAME)
+            .setProviderNamedSelector(ImmutableList.of(routerProviderSelector))
+            .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
+            .setDescription(ROUTER_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();
+    }
+
+    private static Contract createContractRouter() {
+        Rule endpointRouterIpv4Rule = createRuleAllow(IPV4_NAME, Direction.In);
+        Rule routerEndpointIpv4Rule = createRuleAllow(IPV4_NAME, Direction.Out);
+        Rule endpointRouterIpv6Rule = createRuleAllow(IPV6_NAME, Direction.In);
+        Rule routerEndpointIpv6Rule = createRuleAllow(IPV6_NAME, Direction.Out);
+        Subject subject = new SubjectBuilder().setName(ROUTER_SUBJECT_NAME)
+            .setOrder(0)
+            .setRule(ImmutableList.of(endpointRouterIpv4Rule, routerEndpointIpv4Rule, endpointRouterIpv6Rule,
+                    routerEndpointIpv6Rule))
+            .build();
+        return new ContractBuilder().setId(CONTRACT_ID)
+            .setSubject(ImmutableList.of(subject))
+            .setDescription(ROUTER_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(MappingUtils.ACTION_REF_ALLOW)
+            .setClassifierRef(ImmutableList.of(classifierRef))
+            .build();
+    }
+
+    /**
+     * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
+     * and {@link ProviderMatchers}. This clause points to subject in {@link #CONTRACT}.
+     * 
+     * @param tenantId location of {@link #CONTRACT}
+     * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
+     * @param wTx transaction where entities are written
+     */
+    public static void writeRouterClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
+            WriteTransaction wTx) {
+        Clause clause = createClauseWithConsProvEic(ipPrefix, ROUTER_SUBJECT_NAME);
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, CONTRACT_ID, clause.getName()),
+                clause, true);
+    }
+
+    private static Clause createClauseWithConsProvEic(@Nullable IpPrefix ipPrefix, SubjectName subjectName) {
+        ConsumerMatchers consumerMatchers = null;
+        ProviderMatchers providerMatchers = null;
+        StringBuilder clauseName = new StringBuilder();
+        clauseName.append(subjectName.getValue());
+        if (ipPrefix != null) {
+            clauseName.append(MappingUtils.NAME_DOUBLE_DELIMETER).append(Utils.getStringIpPrefix(ipPrefix));
+            consumerMatchers =
+                    new ConsumerMatchersBuilder()
+                        .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
+                            .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
+                                .setPrefixConstraint(
+                                        ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
+                                .build())
+                            .build())
+                        .build();
+            providerMatchers =
+                    new ProviderMatchersBuilder()
+                        .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
+                            .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
+                                .setPrefixConstraint(
+                                        ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
+                                .build())
+                            .build())
+                        .build();
+        }
+        return new ClauseBuilder().setName(new ClauseName(clauseName.toString()))
+            .setSubjectRefs(ImmutableList.of(subjectName))
+            .setConsumerMatchers(consumerMatchers)
+            .setProviderMatchers(providerMatchers)
+            .build();
+    }
+
+    /**
+     * Puts router entities (classifier-instances, {@link #CONTRACT} and {@link #EPG}) to
+     * {@link LogicalDatastoreType#CONFIGURATION}
+     * 
+     * @param tenantId location of router entities
+     * @param wTx transaction where router entities are written
+     */
+    public static void writeRouterEntitiesToTenant(TenantId tenantId, WriteTransaction wTx) {
+        Set<ClassifierInstance> classifierInstances = getAllClassifierInstances();
+        for (ClassifierInstance ci : classifierInstances) {
+            wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, ci.getName()), ci,
+                    true);
+        }
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, CONTRACT_ID), CONTRACT, true);
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true);
+    }
+
+    /**
+     * @return All classifier-instances used in {@link CONTRACT}
+     */
+    public static Set<ClassifierInstance> getAllClassifierInstances() {
+        HashSet<ClassifierInstance> cis = new HashSet<>();
+        cis.add(createIpv4());
+        cis.add(createIpv6());
+        return cis;
+    }
+
+    private static ClassifierInstance createIpv4() {
+        return new ClassifierInstanceBuilder().setName(IPV4_NAME)
+            .setClassifierDefinitionId(EtherTypeClassifier.DEFINITION.getId())
+            .setParameterValue(createParams(EtherTypeClassifier.IPv4_VALUE))
+            .build();
+    }
+
+    private static ClassifierInstance createIpv6() {
+        return new ClassifierInstanceBuilder().setName(IPV6_NAME)
+            .setClassifierDefinitionId(EtherTypeClassifier.DEFINITION.getId())
+            .setParameterValue(createParams(EtherTypeClassifier.IPv6_VALUE))
+            .build();
+    }
+
+    private static List<ParameterValue> createParams(long etherType) {
+        List<ParameterValue> params = new ArrayList<>();
+        params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifier.ETHERTYPE_PARAM))
+            .setIntValue(etherType)
+            .build());
+        return params;
+    }
+
+}
index cd49fe7b4a89bf193304548cede1251b5854f98e..61a044a76846cb8bdf397070ce9500481a278466 100644 (file)
@@ -9,12 +9,16 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import java.util.HashSet;
+import java.util.Set;
 import java.util.UUID;
 
 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.gbp.util.NeutronGbpIidFactory;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.Router;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronMapperIidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
@@ -33,7 +37,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gb
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMapping;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMappingBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomainBuilder;
@@ -51,6 +54,7 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
 
     private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkAware.class);
     private final DataBroker dataProvider;
+    private Set<TenantId> tenantsWithRouterEntities = new HashSet<>();
 
     public NeutronNetworkAware(DataBroker dataProvider) {
         this.dataProvider = checkNotNull(dataProvider);
@@ -75,20 +79,20 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
         TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
-        addEpgDhcpIfMissing(tenantId, rwTx);
-        addEpgRouterIfMissing(tenantId, rwTx);
-        // Note that Router External doesn't mean the router exists yet, it simply means it will connect to one.
-        if(network.getRouterExternal()) {
-            addEpgExternalIfMissing(tenantId, rwTx);
-        }
-        Description domainDescription = new Description(MappingUtils.NEUTRON_NETWORK__ + network.getID());
         Name name = null;
         if (network.getNetworkName() != null) {
-            name = new Name(network.getNetworkName());
+            try {
+                name = new Name(network.getNetworkName());
+            } catch (Exception e) {
+                name = null;
+                LOG.info("Name of Neutron Network '{}' is ignored.",
+                        network.getNetworkName());
+                LOG.debug("Name exception", e);
+            }
         }
+
         L3ContextId l3ContextId = new L3ContextId(UUID.randomUUID().toString());
         L3Context l3Context = new L3ContextBuilder().setId(l3ContextId)
-            .setDescription(domainDescription)
             .setName(name)
             .build();
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3ContextId), l3Context, true);
@@ -96,14 +100,12 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
         L2BridgeDomainId l2BdId = new L2BridgeDomainId(UUID.randomUUID().toString());
         L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId)
             .setParent(l3ContextId)
-            .setDescription(domainDescription)
             .setName(name)
             .build();
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
 
         L2FloodDomain l2Fd = new L2FloodDomainBuilder().setId(l2FdId)
             .setParent(l2BdId)
-            .setDescription(domainDescription)
             .setName(name)
             .build();
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
@@ -114,8 +116,14 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
             .build();
         rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.networkMappingIid(l2FdId), networkMapping, true);
 
-        if (network.getRouterExternal() != null
-                && network.getRouterExternal() == true) {
+        if (!tenantsWithRouterEntities.contains(tenantId)) {
+            tenantsWithRouterEntities.add(tenantId);
+            Router.writeRouterEntitiesToTenant(tenantId, rwTx);
+            Router.writeRouterClauseWithConsProvEic(tenantId, null, rwTx);
+            NetworkClient.writeConsumerNamedSelector(tenantId, Router.CONTRACT_CONSUMER_SELECTOR, rwTx);
+        }
+        if (network.getRouterExternal() != null && network.getRouterExternal() == true) {
+            addEpgExternalIfMissing(tenantId, rwTx);
             addExternalNetworkIfMissing(l2Fd.getId(), rwTx);
         }
         DataStoreHelper.submitToDs(rwTx);
@@ -140,44 +148,13 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
             EndpointGroup epgExternal = new EndpointGroupBuilder()
                 .setId(MappingUtils.EPG_EXTERNAL_ID)
                 .setName(new Name("EXTERNAL_group"))
-                .setDescription(new Description(MappingUtils.NEUTRON_EXTERNAL__ + "epg_external_networks"))
-                .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
+                .setDescription(new Description(MappingUtils.NEUTRON_EXTERNAL + "epg_external_networks"))
                 .build();
             rwTx.put(LogicalDatastoreType.CONFIGURATION,
                     IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_EXTERNAL_ID), epgExternal, true);
         }
     }
 
-    private void addEpgDhcpIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
-        InstanceIdentifier<EndpointGroup> epgDhcpIid = IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_DHCP_ID);
-        Optional<EndpointGroup> potentialDhcpEpg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                epgDhcpIid, rwTx);
-        if (!potentialDhcpEpg.isPresent()) {
-            EndpointGroup epgDhcp = new EndpointGroupBuilder()
-                .setId(MappingUtils.EPG_DHCP_ID)
-                .setName(new Name("DHCP_group"))
-                .setDescription(new Description("Group where are all DHCP endpoints."))
-                .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
-                .build();
-            rwTx.put(LogicalDatastoreType.CONFIGURATION, epgDhcpIid, epgDhcp);
-        }
-    }
-
-    private void addEpgRouterIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
-        Optional<EndpointGroup> potentialEpgRouter = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ROUTER_ID), rwTx);
-        if (!potentialEpgRouter.isPresent()) {
-            EndpointGroup epgRouter = new EndpointGroupBuilder()
-                .setId(MappingUtils.EPG_ROUTER_ID)
-                .setName(new Name("ROUTER_group"))
-                .setDescription(new Description(MappingUtils.NEUTRON_ROUTER__ + "epg_routers"))
-                .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
-                .build();
-            rwTx.put(LogicalDatastoreType.CONFIGURATION,
-                    IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ROUTER_ID), epgRouter);
-        }
-    }
-
     /**
      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canUpdateNetwork(org.opendaylight.neutron.spi.NeutronNetwork,
      *      org.opendaylight.neutron.spi.NeutronNetwork)
index 404d63b088ff91ef5e0666ff4c1824a91ee5bf7b..dc9e8842a8350e9f84753d03e7e1aa09ab693fcb 100644 (file)
@@ -20,13 +20,16 @@ import java.util.concurrent.ExecutionException;
 
 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.ReadTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.Router;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.NeutronSecurityGroupAware;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
@@ -98,15 +101,18 @@ public class NeutronPortAware implements INeutronPortAware {
     private static final String DEVICE_OWNER_ROUTER_IFACE = "network:router_interface";
     private static final String DEVICE_OWNER_ROUTER_GATEWAY = "network:router_gateway";
     private static final String DEVICE_OWNER_FLOATING_IP = "network:floatingip";
-    private static final int DHCP_SERVER_PORT = 67;
-    private static final int DNS_SERVER_PORT = 53;
     private final DataBroker dataProvider;
     private final EndpointService epService;
+    private final NeutronSecurityRuleAware secRuleAware;
+    private final NeutronSecurityGroupAware secGrpAware;
     private final static Map<String, UniqueId> floatingIpPortByDeviceId = new HashMap<>();
+    private final Set<TenantId> tenantsWithNetworkSeviceEntities = new HashSet<>();
 
-    public NeutronPortAware(DataBroker dataProvider, EndpointService epService) {
+    public NeutronPortAware(DataBroker dataProvider, EndpointService epService, NeutronSecurityRuleAware secRuleAware, NeutronSecurityGroupAware secGrpAware) {
         this.dataProvider = checkNotNull(dataProvider);
         this.epService = checkNotNull(epService);
+        this.secRuleAware = checkNotNull(secRuleAware);
+        this.secGrpAware = secGrpAware;
     }
 
     /**
@@ -149,20 +155,23 @@ public class NeutronPortAware implements INeutronPortAware {
         TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
         if (isDhcpPort(port)) {
             LOG.trace("Port is DHCP port. - {}", port.getID());
-            List<NeutronSecurityRule> dhcpSecRules = createDhcpSecRules(port, null, rwTx);
-            if (dhcpSecRules == null) {
+            Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs());
+            if (firstIp == null) {
+                LOG.warn("Illegal state - DHCP port does not have an IP address.");
                 rwTx.cancel();
                 return;
             }
-
-            for (NeutronSecurityRule dhcpSecRule : dhcpSecRules) {
-                boolean isDhcpSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(dhcpSecRule, rwTx);
-                if (!isDhcpSecRuleAdded) {
-                    rwTx.cancel();
-                    return;
-                }
+            if (!tenantsWithNetworkSeviceEntities.contains(tenantId)) {
+                tenantsWithNetworkSeviceEntities.add(tenantId);
+                NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx);
+                NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
+                NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
+                NetworkClient.writeNetworkClientEntitiesToTenant(tenantId, rwTx);
+                NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DHCP_CONTRACT_CONSUMER_SELECTOR, rwTx);
+                NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DNS_CONTRACT_CONSUMER_SELECTOR, rwTx);
             }
         } else {
+            // this is here b/c stable/kilo sends sec-groups only with port
             List<NeutronSecurityGroup> secGroups = port.getSecurityGroups();
             if (secGroups != null) {
                 for (NeutronSecurityGroup secGroup : secGroups) {
@@ -170,28 +179,16 @@ public class NeutronPortAware implements INeutronPortAware {
                     Optional<EndpointGroup> potentialEpg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
                             IidFactory.endpointGroupIid(tenantId, epgId), rwTx);
                     if (!potentialEpg.isPresent()) {
-                        boolean isSecGroupCreated = NeutronSecurityGroupAware.addNeutronSecurityGroup(secGroup, rwTx);
+                        boolean isSecGroupCreated = secGrpAware.addNeutronSecurityGroup(secGroup, rwTx);
                         if (!isSecGroupCreated) {
                             rwTx.cancel();
                             return;
                         }
-                        if (containsSecRuleWithRemoteSecGroup(secGroup)) {
-                            List<NeutronSecurityRule> dhcpSecRules = createDhcpSecRules(port, epgId, rwTx);
-                            if (dhcpSecRules == null) {
-                                rwTx.cancel();
-                                return;
-                            }
-                            List<NeutronSecurityRule> routerSecRules = NeutronRouterAware.createRouterSecRules(port, epgId, rwTx);
-                            if (routerSecRules == null) {
-                                rwTx.cancel();
-                                return;
-                            }
-                        }
                     } else {
                         List<NeutronSecurityRule> secRules = secGroup.getSecurityRules();
                         if (secRules != null) {
                             for (NeutronSecurityRule secRule : secRules) {
-                                NeutronSecurityRuleAware.addNeutronSecurityRule(secRule, rwTx);
+                                secRuleAware.addNeutronSecurityRule(secRule, rwTx);
                             }
                         }
                     }
@@ -240,7 +237,7 @@ public class NeutronPortAware implements INeutronPortAware {
         List<EndpointGroupId> epgIds = new ArrayList<>();
         // each EP has to be in EPG ANY, except dhcp and router
         epgIds.add(MappingUtils.EPG_EXTERNAL_ID);
-        epgIds.add(MappingUtils.EPG_ROUTER_ID);
+        epgIds.add(Router.EPG_ID);
         EndpointL3 epL3 = createL3Endpoint(tenantId, epL3Key, epgIds, networkContainment);
         InstanceIdentifier<EndpointL3> iid_l3 = IidFactory.l3EndpointIid(l3ContextId, ipAddress);
         rwTx.put(LogicalDatastoreType.OPERATIONAL, iid_l3, epL3, true);
@@ -296,18 +293,14 @@ public class NeutronPortAware implements INeutronPortAware {
     }
 
     public static boolean addL3PrefixEndpoint(L3ContextId l3ContextId, IpPrefix ipPrefix, IpAddress ipAddress, TenantId tenantId,
-            ReadWriteTransaction rwTx, EndpointService epService) {
-
+            EndpointService epService) {
         EndpointL3PrefixKey epL3PrefixKey = new EndpointL3PrefixKey( ipPrefix, l3ContextId);
-
         EndpointL3Key epL3Key = null;
         List<EndpointL3Key> l3Gateways = new ArrayList<>();
         if (ipAddress != null) {
             epL3Key = new EndpointL3Key(ipAddress, l3ContextId);
             l3Gateways.add(epL3Key);
         }
-
-
         try {
             RegisterL3PrefixEndpointInput registerL3PrefixEpRpcInput = createRegisterL3PrefixEndpointInput(epL3PrefixKey, l3Gateways,tenantId);
 
@@ -340,106 +333,6 @@ public class NeutronPortAware implements INeutronPortAware {
         return true;
     }
 
-    private List<NeutronSecurityRule> createDhcpSecRules(NeutronPort port, EndpointGroupId consumerEpgId, ReadTransaction rTx) {
-        TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
-        Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs());
-        if (firstIp == null) {
-            LOG.warn("Illegal state - DHCP port does not have an IP address.");
-            return null;
-        }
-        IpAddress ipAddress = Utils.createIpAddress(firstIp.getIpAddress());
-        boolean isIPv4Ethertype = ipAddress.getIpv4Address() == null ? false : true;
-        List<NeutronSecurityRule> rules = new ArrayList<>();
-        rules.add(createDhcpIngressSecRule(port.getID(), tenantId, isIPv4Ethertype, consumerEpgId));
-        rules.add(createDnsSecRule(port.getID(), tenantId, isIPv4Ethertype, consumerEpgId));
-        rules.add(createUdpEgressSecRule(port.getID(), tenantId, isIPv4Ethertype, consumerEpgId));
-        rules.add(createIcmpSecRule(port.getID(), tenantId, isIPv4Ethertype, consumerEpgId, true));
-        rules.add(createIcmpSecRule(port.getID(), tenantId, isIPv4Ethertype, consumerEpgId, false));
-        return rules;
-    }
-
-    private NeutronSecurityRule createDhcpIngressSecRule(String ruleUuid, TenantId tenantId, boolean isIPv4Ethertype, EndpointGroupId consumerEpgId) {
-        NeutronSecurityRule dhcpSecRule = new NeutronSecurityRule();
-        dhcpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
-        dhcpSecRule.setSecurityRuleTenantID(tenantId.getValue());
-        if (consumerEpgId != null) {
-            dhcpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
-        }
-        dhcpSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "_dhcp__" + ruleUuid);
-        dhcpSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
-        dhcpSecRule.setSecurityRulePortMin(DHCP_SERVER_PORT);
-        dhcpSecRule.setSecurityRulePortMax(DHCP_SERVER_PORT);
-        dhcpSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
-        if (isIPv4Ethertype) {
-            dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
-        } else {
-            dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
-        }
-        return dhcpSecRule;
-    }
-
-    private NeutronSecurityRule createUdpEgressSecRule(String ruleUuid, TenantId tenantId, boolean isIPv4Ethertype, EndpointGroupId consumerEpgId) {
-        NeutronSecurityRule dhcpSecRule = new NeutronSecurityRule();
-        dhcpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
-        dhcpSecRule.setSecurityRuleTenantID(tenantId.getValue());
-        if (consumerEpgId != null) {
-            dhcpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
-        }
-        dhcpSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "_udp__" + ruleUuid);
-        dhcpSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
-        dhcpSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
-        if (isIPv4Ethertype) {
-            dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
-        } else {
-            dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
-        }
-        return dhcpSecRule;
-    }
-
-    private NeutronSecurityRule createDnsSecRule(String ruleUuid, TenantId tenantId, boolean isIPv4Ethertype, EndpointGroupId consumerEpgId) {
-        NeutronSecurityRule dnsSecRule = new NeutronSecurityRule();
-        dnsSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
-        dnsSecRule.setSecurityRuleTenantID(tenantId.getValue());
-        if (consumerEpgId != null) {
-            dnsSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
-        }
-        dnsSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "_dns__" + ruleUuid);
-        dnsSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
-        dnsSecRule.setSecurityRulePortMin(DNS_SERVER_PORT);
-        dnsSecRule.setSecurityRulePortMax(DNS_SERVER_PORT);
-        dnsSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
-        if (isIPv4Ethertype) {
-            dnsSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
-        } else {
-            dnsSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
-        }
-        return dnsSecRule;
-    }
-
-    private NeutronSecurityRule createIcmpSecRule(String ruleUuid, TenantId tenantId, boolean isIPv4Ethertype, EndpointGroupId consumerEpgId,
-            boolean isEgress) {
-        NeutronSecurityRule icmpSecRule = new NeutronSecurityRule();
-        icmpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
-        icmpSecRule.setSecurityRuleTenantID(tenantId.getValue());
-        if (consumerEpgId != null) {
-            icmpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
-        }
-        if (isEgress) {
-            icmpSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "_icmp__" + ruleUuid);
-            icmpSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
-        } else {
-            icmpSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "_icmp__" + ruleUuid);
-            icmpSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
-        }
-        icmpSecRule.setSecurityRuleProtocol(NeutronUtils.ICMP);
-        if (isIPv4Ethertype) {
-            icmpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
-        } else {
-            icmpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
-        }
-        return icmpSecRule;
-    }
-
     /**
      * @see org.opendaylight.neutron.spi.INeutronPortAware#canUpdatePort(org.opendaylight.neutron.spi.NeutronPort,
      *      org.opendaylight.neutron.spi.NeutronPort)
@@ -656,9 +549,6 @@ public class NeutronPortAware implements INeutronPortAware {
 
     private static RegisterL3PrefixEndpointInput createRegisterL3PrefixEndpointInput(EndpointL3PrefixKey key, List<EndpointL3Key> endpointL3Keys, TenantId tenantId) {
         List<EndpointGroupId> epgIds = new ArrayList<>();
-        // each EP has to be in EPG ANY, except dhcp and router
-        epgIds.add(MappingUtils.EPG_ANY_ID);
-
         List<EndpointL3Gateways> l3Gateways = new ArrayList<EndpointL3Gateways>();
         for (EndpointL3Key epL3Key : endpointL3Keys) {
             EndpointL3Gateways l3Gateway = new EndpointL3GatewaysBuilder().setIpAddress(epL3Key.getIpAddress())
@@ -692,11 +582,8 @@ public class NeutronPortAware implements INeutronPortAware {
 
     private static RegisterEndpointInput createRegisterEndpointInput(NeutronPort port, ForwardingCtx fwCtx) {
         List<EndpointGroupId> epgIds = new ArrayList<>();
-        // each EP has to be in EPG ANY, except dhcp and router
         if (isDhcpPort(port)) {
-            epgIds.add(MappingUtils.EPG_DHCP_ID);
-        } else if (!containsSecRuleWithRemoteSecGroup(port.getSecurityGroups())) {
-            epgIds.add(MappingUtils.EPG_ANY_ID);
+            epgIds.add(NetworkService.EPG_ID);
         }
 
         List<NeutronSecurityGroup> securityGroups = port.getSecurityGroups();
@@ -712,6 +599,7 @@ public class NeutronPortAware implements INeutronPortAware {
             for (NeutronSecurityGroup secGrp : securityGroups) {
                 epgIds.add(new EndpointGroupId(secGrp.getSecurityGroupUUID()));
             }
+            epgIds.add(NetworkClient.EPG_ID);
         }
         LocationType locationType = LocationType.Internal;
         if(isRouterGatewayPort(port)) {
@@ -745,32 +633,6 @@ public class NeutronPortAware implements INeutronPortAware {
         return inputBuilder.build();
     }
 
-    private static boolean containsSecRuleWithRemoteSecGroup(List<NeutronSecurityGroup> secGroups) {
-        if (secGroups == null) {
-            return false;
-        }
-        for (NeutronSecurityGroup secGroup : secGroups) {
-            boolean containsSecRuleWithRemoteSecGroup = containsSecRuleWithRemoteSecGroup(secGroup);
-            if (containsSecRuleWithRemoteSecGroup) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static boolean containsSecRuleWithRemoteSecGroup(NeutronSecurityGroup secGroup) {
-        List<NeutronSecurityRule> secRules = secGroup.getSecurityRules();
-        if (secRules == null) {
-            return false;
-        }
-        for (NeutronSecurityRule secRule : secRules) {
-            if (!Strings.isNullOrEmpty(secRule.getSecurityRemoteGroupID())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     private static Name createTapPortName(NeutronPort port) {
         return new Name("tap" + port.getID().substring(0, 11));
     }
index 1f6b7f881c844c3c61acb7dd6ea2a560e68ff4f3..9dd928992b970c687f57f7bad798fde744bf72f0 100644 (file)
@@ -13,10 +13,11 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
 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.infrastructure.Router;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronMapperIidFactory;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
@@ -27,13 +28,11 @@ import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
 import org.opendaylight.neutron.spi.NeutronPort;
 import org.opendaylight.neutron.spi.NeutronRouter;
 import org.opendaylight.neutron.spi.NeutronRouter_Interface;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
 import org.opendaylight.neutron.spi.NeutronSubnet;
 import org.opendaylight.neutron.spi.Neutron_IPs;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.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.L2FloodDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
@@ -63,23 +62,14 @@ import com.google.common.collect.ImmutableList;
 public class NeutronRouterAware implements INeutronRouterAware {
 
     private static final Logger LOG = LoggerFactory.getLogger(NeutronRouterAware.class);
-    private static final NeutronRouterAware INSTANCE = new NeutronRouterAware();
-    private static DataBroker dataProvider;
-    private static EndpointService epService;
-
-    private NeutronRouterAware() {
-        if (NeutronRouterAware.INSTANCE != null) {
-            throw new IllegalStateException("Already instantiated");
-        }
-    }
-
-    public static NeutronRouterAware getInstance() {
-        return NeutronRouterAware.INSTANCE;
-    }
-
-    public static void init(DataBroker dataProvider, EndpointService epService) {
-        NeutronRouterAware.dataProvider = checkNotNull(dataProvider);
-        NeutronRouterAware.epService = checkNotNull(epService);
+    private final DataBroker dataProvider;
+    private final  EndpointService epService;
+    private final NeutronSecurityRuleAware secRuleAware;
+
+    public NeutronRouterAware(DataBroker dataProvider, EndpointService epService, NeutronSecurityRuleAware secRuleAware) {
+        this.dataProvider = checkNotNull(dataProvider);
+        this.epService = checkNotNull(epService);
+        this.secRuleAware = checkNotNull(secRuleAware);
     }
 
     @Override
@@ -159,7 +149,7 @@ public class NeutronRouterAware implements INeutronRouterAware {
             for (String route : router.getRoutes()) {
                 IpPrefix ipPrefix = Utils.createIpPrefix(route);
                 boolean addedL3Prefix = NeutronPortAware.addL3PrefixEndpoint(l3ContextIdFromRouterId, ipPrefix,
-                        defaultGateway, tenantId, rwTx, epService);
+                        defaultGateway, tenantId, epService);
                 if (!addedL3Prefix) {
                     LOG.warn("Could not add EndpointL3Prefix for Neutron route {} for router {}", route, router.getID());
                     rwTx.cancel();
@@ -184,19 +174,6 @@ public class NeutronRouterAware implements INeutronRouterAware {
             if (Strings.isNullOrEmpty(routerPort.getTenantID())) {
                 routerPort.setTenantID(router.getTenantID());
             }
-            // create security rules for router
-            List<NeutronSecurityRule> routerSecRules = createRouterSecRules(routerPort, null, rwTx);
-            if (routerSecRules == null) {
-                rwTx.cancel();
-                return;
-            }
-            for (NeutronSecurityRule routerSecRule : routerSecRules) {
-                boolean isRouterSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(routerSecRule, rwTx);
-                if (!isRouterSecRuleAdded) {
-                    rwTx.cancel();
-                    return;
-                }
-            }
 
             boolean isSuccessful = setNewL3ContextToEpsFromSubnet(tenantId, l3Context, subnet, rwTx);
             if (!isSuccessful) {
@@ -221,9 +198,9 @@ public class NeutronRouterAware implements INeutronRouterAware {
         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
         TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
         Optional<EndpointGroup> potentialEpg = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
-                IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ROUTER_ID), rwTx);
+                IidFactory.endpointGroupIid(tenantId, Router.EPG_ID), rwTx);
         if (!potentialEpg.isPresent()) {
-            LOG.warn("Illegal state - Endpoint group {} does not exist.", MappingUtils.EPG_ROUTER_ID.getValue());
+            LOG.warn("Illegal state - Endpoint group {} does not exist.", Router.EPG_ID.getValue());
             rwTx.cancel();
             return;
         }
@@ -292,20 +269,6 @@ public class NeutronRouterAware implements INeutronRouterAware {
         }
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet);
 
-        // create security rules for router
-        List<NeutronSecurityRule> routerSecRules = createRouterSecRules(routerPort, null, rwTx);
-        if (routerSecRules == null) {
-            rwTx.cancel();
-            return;
-        }
-        for (NeutronSecurityRule routerSecRule : routerSecRules) {
-            boolean isRouterSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(routerSecRule, rwTx);
-            if (!isRouterSecRuleAdded) {
-                rwTx.cancel();
-                return;
-            }
-        }
-
         boolean isSuccessful = setNewL3ContextToEpsFromSubnet(tenantId, l3Context, subnet, rwTx);
         if (!isSuccessful) {
             rwTx.cancel();
@@ -322,7 +285,7 @@ public class NeutronRouterAware implements INeutronRouterAware {
         }
         return new L3ContextBuilder().setId(new L3ContextId(router.getID()))
             .setName(l3ContextName)
-            .setDescription(new Description(MappingUtils.NEUTRON_ROUTER__ + router.getID()))
+            .setDescription(new Description(MappingUtils.NEUTRON_ROUTER + router.getID()))
             .build();
     }
 
@@ -399,50 +362,6 @@ public class NeutronRouterAware implements INeutronRouterAware {
         return true;
     }
 
-    public static List<NeutronSecurityRule> createRouterSecRules(NeutronPort port, EndpointGroupId consumerEpgId,
-            ReadTransaction rTx) {
-        TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
-        Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs());
-        if (firstIp == null) {
-            LOG.warn("Illegal state - Router port does not have an IP address.");
-            return null;
-        }
-        SubnetId routerSubnetId = new SubnetId(firstIp.getSubnetUUID());
-        Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                IidFactory.subnetIid(tenantId, routerSubnetId), rTx);
-        if (!potentialSubnet.isPresent()) {
-            LOG.warn("Illegal state - Subnet {} where is router port does not exist.", routerSubnetId.getValue());
-            return null;
-        }
-        IpPrefix ipSubnet = potentialSubnet.get().getIpPrefix();
-        NeutronSecurityRule routerRuleEgress = createRouterSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId,
-                true);
-        NeutronSecurityRule routerRuleIngress = createRouterSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId,
-                false);
-        return ImmutableList.of(routerRuleEgress, routerRuleIngress);
-    }
-
-    private static NeutronSecurityRule createRouterSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet,
-            EndpointGroupId consumerEpgId, boolean isEgress) {
-        NeutronSecurityRule routerSecRule = new NeutronSecurityRule();
-        routerSecRule.setSecurityRuleGroupID(MappingUtils.EPG_ROUTER_ID.getValue());
-        routerSecRule.setSecurityRuleTenantID(tenantId.getValue());
-        routerSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
-        if (isEgress) {
-            routerSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "__" + ruleUuid);
-            routerSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
-        } else {
-            routerSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "__" + ruleUuid);
-            routerSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
-        }
-        if (ipSubnet.getIpv4Prefix() != null) {
-            routerSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
-        } else {
-            routerSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
-        }
-        return routerSecRule;
-    }
-
     @Override
     public int canDetachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface) {
         LOG.trace("canDetachInterface - router: {} interface: {}", router, routerInterface);
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSecurityRuleAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSecurityRuleAware.java
deleted file mode 100644 (file)
index 48a4596..0000000
+++ /dev/null
@@ -1,380 +0,0 @@
-package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.UUID;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
-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.neutron.mapper.util.MappingUtils;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronMapperIidFactory;
-import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
-import org.opendaylight.groupbasedpolicy.util.IidFactory;
-import org.opendaylight.neutron.spi.INeutronSecurityRuleAware;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
-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.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.neutron.mapper.rev150223.mappings.endpoint.group.pair.to.contract.mappings.EndpointGroupPairToContractMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.endpoint.group.pair.to.contract.mappings.EndpointGroupPairToContractMappingBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstance;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
-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.collect.ImmutableList;
-
-public class NeutronSecurityRuleAware implements INeutronSecurityRuleAware {
-
-    private static final Logger LOG = LoggerFactory.getLogger(NeutronSecurityRuleAware.class);
-    private final DataBroker dataProvider;
-
-    public NeutronSecurityRuleAware(DataBroker dataProvider) {
-        this.dataProvider = checkNotNull(dataProvider);
-    }
-
-    @Override
-    public int canCreateNeutronSecurityRule(NeutronSecurityRule securityRule) {
-        LOG.trace("canCreateNeutronSecurityRule - {}", securityRule);
-        // nothing to consider
-        return StatusCode.OK;
-    }
-
-    @Override
-    public void neutronSecurityRuleCreated(NeutronSecurityRule securityRule) {
-        LOG.trace("neutronSecurityRuleCreated - {}", securityRule);
-        ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
-        boolean isNeutronSecurityRuleAdded = addNeutronSecurityRule(securityRule, rwTx);
-        if (isNeutronSecurityRuleAdded) {
-            DataStoreHelper.submitToDs(rwTx);
-        } else {
-            rwTx.cancel();
-        }
-    }
-
-    /**
-     * <b>ASSUMPTION</b>: Endpoint group with id
-     * {@link NeutronSecurityRule#getSecurityRuleGroupID()} and
-     * endpoint group with id {@link NeutronSecurityRule#getSecurityRemoteGroupID()} already exist
-     * in transaction.
-     *
-     * @param secRule neutron security rule from which GBP entities are created
-     * @param rwTx GBP entities are stored to this transaction. This method NEVER submits or cancel
-     *        the transaction.
-     * @return {@code true} if operation was successful; {@code false} if an illegal state occurs -
-     *         the transaction may contain just partial result
-     */
-    public static boolean addNeutronSecurityRule(NeutronSecurityRule secRule, ReadWriteTransaction rwTx) {
-        TransformSecRule transform = new TransformSecRule(secRule);
-        TenantId tenantId = transform.getTenantId();
-        EndpointGroupId providerEpgId = transform.getProviderEpgId();
-        EndpointGroupId consumerEpgId = transform.getConsumerEpgId();
-        SubjectName subjectName = transform.getSubjectName();
-
-        Optional<ContractId> potentialContractId = readContractIdFromEpgPairToContractMapping(tenantId, providerEpgId,
-                tenantId, consumerEpgId, rwTx);
-        ContractId contractId = null;
-        if (potentialContractId.isPresent()) {
-            contractId = potentialContractId.get();
-            Optional<Subject> potentialSubject = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                    IidFactory.subjectIid(tenantId, contractId, subjectName), rwTx);
-            if (!potentialSubject.isPresent()) {
-                // it also means that clause for this subject does not exist
-                rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subjectIid(tenantId, contractId, subjectName),
-                        transform.createSubject());
-                rwTx.put(LogicalDatastoreType.CONFIGURATION,
-                        IidFactory.clauseIid(tenantId, contractId, transform.getClauseName()), transform.createClause());
-            }
-        } else {
-            // check assumption that provider EPG exists
-            Optional<EndpointGroup> potentialProviderEpg = DataStoreHelper.readFromDs(
-                    LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, providerEpgId), rwTx);
-            if (!potentialProviderEpg.isPresent()) {
-                LOG.warn("Illegal state - Endpoint group {} does not exist.", providerEpgId.getValue());
-                return false;
-            }
-
-            if (providerEpgId.equals(consumerEpgId)) {
-                EndpointGroup providerConsumerEpg = potentialProviderEpg.get();
-                if (providerConsumerEpg.getIntraGroupPolicy() == null
-                        || !providerConsumerEpg.getIntraGroupPolicy().equals(IntraGroupPolicy.RequireContract)) {
-                    EndpointGroup newProviderConsumerEpg = new EndpointGroupBuilder(providerConsumerEpg).setIntraGroupPolicy(
-                            IntraGroupPolicy.RequireContract)
-                        .build();
-                    rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, providerEpgId),
-                            newProviderConsumerEpg);
-                }
-            } else {
-                Optional<EndpointGroup> potentialConsumerEpg = DataStoreHelper.readFromDs(
-                        LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, consumerEpgId), rwTx);
-                if (!potentialConsumerEpg.isPresent()) {
-                    if (MappingUtils.EPG_ANY_ID.equals(consumerEpgId)) {
-                        EndpointGroup epgAny = createEpgAny();
-                        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ANY_ID),
-                                epgAny);
-                    } else {
-                        LOG.warn("Illegal state - Endpoint group {} does not exist.", consumerEpgId.getValue());
-                        return false;
-                    }
-                }
-            }
-            // creates and stores contract with clause and subject
-            Subject subject = transform.createSubject();
-            Clause clause = transform.createClause();
-            Contract contract = createContract(clause, subject);
-            contractId = contract.getId();
-            rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, contractId), contract);
-            putEpgPairToContractMapping(tenantId, providerEpgId, tenantId, consumerEpgId, tenantId, contractId, rwTx);
-
-            // adds provider and consumer named selectors
-            ProviderNamedSelector providerSelector = createProviderNamedSelector(contractId);
-            rwTx.put(LogicalDatastoreType.CONFIGURATION,
-                    IidFactory.providerNamedSelectorIid(tenantId, providerEpgId, providerSelector.getName()),
-                    providerSelector);
-            ConsumerNamedSelector consumerSelector = createConsumerNamedSelector(contractId);
-            rwTx.put(LogicalDatastoreType.CONFIGURATION,
-                    IidFactory.consumerNamedSelectorIid(tenantId, consumerEpgId, consumerSelector.getName()),
-                    consumerSelector);
-        }
-
-        // create classifier-instance
-        ClassifierName classifierName = transform.getClassifierName();
-        ClassifierInstance classifier = transform.createClassifier();
-        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, classifierName),
-                classifier, true);
-        // create action-instance if it does not exist yet
-        Optional<ActionInstance> potentialAction = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                IidFactory.actionInstanceIid(tenantId, MappingUtils.ACTION_ALLOW.getName()), rwTx);
-        if (!potentialAction.isPresent()) {
-            rwTx.put(LogicalDatastoreType.CONFIGURATION,
-                    IidFactory.actionInstanceIid(tenantId, MappingUtils.ACTION_ALLOW.getName()),
-                    MappingUtils.ACTION_ALLOW, true);
-        }
-
-        // create rule
-        Rule rule = transform.createRule(0);
-        rwTx.put(LogicalDatastoreType.CONFIGURATION,
-                IidFactory.ruleIid(tenantId, contractId, subjectName, rule.getName()), rule);
-        return true;
-    }
-
-    private static EndpointGroup createEpgAny() {
-        return new EndpointGroupBuilder()
-                .setId(MappingUtils.EPG_ANY_ID)
-                .setName(new Name("ANY_group"))
-                .setDescription(new Description(MappingUtils.NEUTRON_RULE__ + "epg_any"))
-                .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
-                .build();
-    }
-
-    @Override
-    public int canUpdateNeutronSecurityRule(NeutronSecurityRule delta, NeutronSecurityRule original) {
-        LOG.warn("canUpdateNeutronSecurityRule - Never should be called "
-                + "- neutron API does not allow UPDATE on neutron security group rule. \nDelta: {} \nOriginal: {}",
-                delta, original);
-        return StatusCode.BAD_REQUEST;
-    }
-
-    @Override
-    public void neutronSecurityRuleUpdated(NeutronSecurityRule securityRule) {
-        LOG.warn("neutronSecurityRuleUpdated - Never should be called "
-                + "- neutron API does not allow UPDATE on neutron security group rule. \nSecurity group rule: {}",
-                securityRule);
-    }
-
-    @Override
-    public int canDeleteNeutronSecurityRule(NeutronSecurityRule securityRule) {
-        LOG.trace("canDeleteNeutronSecurityRule - {}", securityRule);
-        // nothing to consider
-        return StatusCode.OK;
-    }
-
-    @Override
-    public void neutronSecurityRuleDeleted(NeutronSecurityRule secRule) {
-        LOG.trace("neutronSecurityRuleCreated - {}", secRule);
-        ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
-        boolean isNeutronSecurityRuleDelete = deleteNeutronSecurityRule(secRule, rwTx);
-        if (isNeutronSecurityRuleDelete) {
-            DataStoreHelper.submitToDs(rwTx);
-        } else {
-            DataStoreHelper.submitToDs(rwTx);
-        }
-    }
-
-    /**
-     * @param secRule neutron security rule from which GBP entities are deleted
-     * @param rwTx GBP entities are stored to this transaction. This method NEVER submits or cancel
-     *        the transaction.
-     * @return {@code true} if operation was successful; {@code false} if an illegal state occurs -
-     *         the transaction may contain just partial result
-     */
-    public static boolean deleteNeutronSecurityRule(NeutronSecurityRule secRule, ReadWriteTransaction rwTx) {
-        TransformSecRule transform = new TransformSecRule(secRule);
-        TenantId tenantId = transform.getTenantId();
-        EndpointGroupId providerEpgId = transform.getProviderEpgId();
-        EndpointGroupId consumerEpgId = transform.getConsumerEpgId();
-
-        Optional<ContractId> potentialContractId = readContractIdFromEpgPairToContractMapping(tenantId, providerEpgId,
-                tenantId, consumerEpgId, rwTx);
-        if (!potentialContractId.isPresent()) {
-            LOG.warn("Illegal state - mapping EPG pair (provider EPG {} consumer EPG {}) does not exist.",
-                    providerEpgId.getValue(), consumerEpgId.getValue());
-            return false;
-        }
-
-        ContractId contractId = potentialContractId.get();
-        ClassifierName classifierName = transform.getClassifierName();
-        InstanceIdentifier<ClassifierInstance> classifierIid = IidFactory.classifierInstanceIid(tenantId,
-                classifierName);
-        Optional<ClassifierInstance> potentialClassifier = DataStoreHelper.removeIfExists(
-                LogicalDatastoreType.CONFIGURATION, classifierIid, rwTx);
-        if (!potentialClassifier.isPresent()) {
-            LOG.warn("Illegal state - classifier-instance {} does not exist. {}", classifierName.getValue(),
-                    classifierIid);
-            return false;
-        }
-
-        RuleName ruleName = transform.getRuleName();
-        SubjectName subjectName = transform.getSubjectName();
-        InstanceIdentifier<Rule> ruleIid = IidFactory.ruleIid(tenantId, contractId, subjectName, ruleName);
-        Optional<Rule> potentionalRule = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, ruleIid,
-                rwTx);
-        if (!potentionalRule.isPresent()) {
-            LOG.warn("Illegal state - rule {} does not exist. {}", ruleName.getValue(), ruleIid);
-            return false;
-        }
-
-        InstanceIdentifier<Subject> subjectIid = IidFactory.subjectIid(tenantId, contractId, subjectName);
-        Optional<Subject> potentionalSubject = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                subjectIid, rwTx);
-        if (!potentionalSubject.isPresent()) {
-            LOG.warn("Illegal state - subject {} does not exist. {}", subjectName.getValue(), subjectName);
-            return false;
-        }
-
-        ClauseName clauseName = transform.getClauseName();
-        InstanceIdentifier<Clause> clauseIid = IidFactory.clauseIid(tenantId, contractId, clauseName);
-        Optional<Clause> potentialClause = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, clauseIid,
-                rwTx);
-        if (!potentialClause.isPresent()) {
-            LOG.warn("Illegal state - clause {} does not exist. {}", clauseName.getValue(), clauseIid);
-            return false;
-        }
-
-        Subject subject = potentionalSubject.get();
-        if (subject.getRule() == null || subject.getRule().isEmpty()) {
-            rwTx.delete(LogicalDatastoreType.CONFIGURATION, clauseIid);
-            rwTx.delete(LogicalDatastoreType.CONFIGURATION, subjectIid);
-        }
-
-        InstanceIdentifier<Contract> contractIid = IidFactory.contractIid(tenantId, contractId);
-        Optional<Contract> potentialContract = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                contractIid, rwTx);
-        if (!potentialContract.isPresent()) {
-            LOG.warn("Illegal state - contract {} does not exist. {}", contractId.getValue(), contractIid);
-            return false;
-        }
-
-        Contract contract = potentialContract.get();
-        if (contract.getSubject() == null || contract.getSubject().isEmpty()) {
-            // remove contract and named selectors from EPGs
-            rwTx.delete(LogicalDatastoreType.CONFIGURATION, contractIid);
-            SelectorName providerSelectorName = createNameOfNamedSelector(contractId);
-            InstanceIdentifier<ProviderNamedSelector> providerSelectorIid = IidFactory.providerNamedSelectorIid(
-                    tenantId, providerEpgId, providerSelectorName);
-            Optional<ProviderNamedSelector> potentialProviderSelector = DataStoreHelper.removeIfExists(
-                    LogicalDatastoreType.CONFIGURATION, providerSelectorIid, rwTx);
-            if (!potentialProviderSelector.isPresent()) {
-                LOG.warn("Illegal state - provider-name-selector {} does not exist. {}",
-                        providerSelectorName.getValue(), providerSelectorIid);
-                return false;
-            }
-            SelectorName consumerSelectorName = createNameOfNamedSelector(contractId);
-            InstanceIdentifier<ConsumerNamedSelector> consumerSelectorIid = IidFactory.consumerNamedSelectorIid(
-                    tenantId, consumerEpgId, consumerSelectorName);
-            Optional<ConsumerNamedSelector> potentialConsuemrSelector = DataStoreHelper.removeIfExists(
-                    LogicalDatastoreType.CONFIGURATION, consumerSelectorIid, rwTx);
-            if (!potentialConsuemrSelector.isPresent()) {
-                LOG.warn("Illegal state - consumer-name-selector {} does not exist. {}",
-                        consumerSelectorName.getValue(), consumerSelectorIid);
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public static Optional<ContractId> readContractIdFromEpgPairToContractMapping(TenantId providerTenantId, EndpointGroupId providerEpgId,
-            TenantId consumerTenantId, EndpointGroupId consumerEpgId, ReadTransaction rTx) {
-        Optional<EndpointGroupPairToContractMapping> potentialMapping = DataStoreHelper.readFromDs(
-                LogicalDatastoreType.OPERATIONAL,
-                NeutronMapperIidFactory.endpointGroupPairToContractMappingIid(providerEpgId, providerTenantId, consumerEpgId, consumerTenantId), rTx);
-        if (potentialMapping.isPresent()) {
-            return Optional.of(potentialMapping.get().getContractId());
-        }
-        return Optional.absent();
-    }
-
-    private static void putEpgPairToContractMapping(TenantId providerTenantId, EndpointGroupId providerEpgId, TenantId consumerTenantId,
-            EndpointGroupId consumerEpgId, TenantId contractTenantId, ContractId contractId, WriteTransaction wTx) {
-        EndpointGroupPairToContractMapping epgPairToContractMapping = new EndpointGroupPairToContractMappingBuilder()
-            .setProviderEpgId(providerEpgId)
-            .setProviderTenantId(providerTenantId)
-            .setConsumerEpgId(consumerEpgId)
-            .setConsumerTenantId(consumerTenantId)
-            .setContractId(contractId)
-            .setContractTenantId(contractTenantId)
-            .build();
-        wTx.put(LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.endpointGroupPairToContractMappingIid(
-                epgPairToContractMapping.getProviderEpgId(), epgPairToContractMapping.getProviderTenantId(), epgPairToContractMapping.getConsumerEpgId(),epgPairToContractMapping.getConsumerTenantId()),
-                epgPairToContractMapping, true);
-    }
-
-    private static Contract createContract(Clause clause, Subject subject) {
-        ContractId contractId = new ContractId(UUID.randomUUID().toString());
-        return new ContractBuilder().setId(contractId)
-            .setClause(ImmutableList.of(clause))
-            .setSubject(ImmutableList.of(subject))
-            .build();
-    }
-
-    private static ProviderNamedSelector createProviderNamedSelector(ContractId contractId) {
-        return new ProviderNamedSelectorBuilder().setName(createNameOfNamedSelector(contractId))
-            .setContract(ImmutableList.of(contractId))
-            .build();
-    }
-
-    private static ConsumerNamedSelector createConsumerNamedSelector(ContractId contractId) {
-        return new ConsumerNamedSelectorBuilder().setName(createNameOfNamedSelector(contractId))
-            .setContract(ImmutableList.of(contractId))
-            .build();
-    }
-
-    private static SelectorName createNameOfNamedSelector(ContractId contractId) {
-        return new SelectorName(MappingUtils.NEUTRON_RULE__ + contractId.getValue());
-    }
-
-}
index 6d4db023c9533d594bd46a62dfc56db730a30576..0e5cffd3bc8ba11c442d6172031c80a3e4ab5f4c 100644 (file)
@@ -9,17 +9,14 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
 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.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.neutron.spi.INeutronSubnetAware;
 import org.opendaylight.neutron.spi.NeutronSubnet;
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/TransformSecRule.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/TransformSecRule.java
deleted file mode 100644 (file)
index 9ab37b4..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.EtherTypeClassifier;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.IpProtoClassifier;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.L4Classifier;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.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.EndpointGroupId;
-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.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.action.refs.ActionRefBuilder;
-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.ClassifierRef.ConnectionTracking;
-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.PrefixConstraint;
-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.subject.feature.instance.parameter.value.RangeValueBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.SubjectBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchersBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstanceBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-
-public class TransformSecRule {
-
-    private static final Logger LOG = LoggerFactory.getLogger(TransformSecRule.class);
-    private static final List<ActionRef> ACTION_REF_ALLOW = ImmutableList.of(new ActionRefBuilder().setName(
-            MappingUtils.ACTION_ALLOW.getName())
-        .setOrder(0)
-        .build());
-    private final NeutronSecurityRule secRule;
-    private final TenantId tenantId;
-    private final EndpointGroupId providerEpgId;
-    private final EndpointGroupId consumerEpgId;
-    private final SubjectName subjectName;
-    private final ClauseName clauseName;
-    private final IpPrefix ipPrefix;
-    private final int subjectOrder;
-    private final ClassifierName classifierName;
-    private final RuleName ruleName;
-
-    /**
-     * If a {@link NeutronSecurityRule#getSecurityRuleGroupID()} is {@link MappingUtils#EPG_DHCP_ID}
-     * or {@link MappingUtils#EPG_ROUTER_ID} then the neutron security rule can contain remote ip
-     * prefix besides remote ip security group. I this case {@link #getConsumerEpgId()} returns remote security group id.
-     *
-     * @param secRule
-     */
-    public TransformSecRule(NeutronSecurityRule secRule) {
-        this.secRule = checkNotNull(secRule);
-        tenantId = new TenantId(Utils.normalizeUuid(secRule.getSecurityRuleTenantID()));
-        providerEpgId = new EndpointGroupId(secRule.getSecurityRuleGroupID());
-        if (!Strings.isNullOrEmpty(secRule.getSecurityRemoteGroupID())) {
-            consumerEpgId = new EndpointGroupId(secRule.getSecurityRemoteGroupID());
-            if (isEpgIdRouterOrDhcp(providerEpgId) && !Strings.isNullOrEmpty(secRule.getSecurityRuleRemoteIpPrefix())) {
-                ipPrefix = Utils.createIpPrefix(secRule.getSecurityRuleRemoteIpPrefix());
-            } else {
-                ipPrefix = null;
-            }
-            subjectOrder = 0;
-        } else if (!Strings.isNullOrEmpty(secRule.getSecurityRuleRemoteIpPrefix())) {
-            consumerEpgId = MappingUtils.EPG_ANY_ID;
-            ipPrefix = Utils.createIpPrefix(secRule.getSecurityRuleRemoteIpPrefix());
-            subjectOrder = 0;
-        } else {
-            consumerEpgId = MappingUtils.EPG_ANY_ID;
-            ipPrefix = null;
-            subjectOrder = 1;
-        }
-        subjectName = createSubjectName();
-        clauseName = new ClauseName(subjectName.getValue());
-        classifierName = new ClassifierName(MappingUtils.NEUTRON_RULE__ + secRule.getSecurityRuleUUID());
-        ruleName = new RuleName(MappingUtils.NEUTRON_RULE__ + "Allow--" + classifierName.getValue());
-    }
-
-    private SubjectName createSubjectName() {
-        if (ipPrefix == null) {
-            return new SubjectName(MappingUtils.NEUTRON_RULE__ + providerEpgId.getValue() + "__"
-                    + consumerEpgId.getValue());
-        }
-        String prefix = Utils.getStringIpPrefix(ipPrefix).replace('/', '_');
-        return new SubjectName(MappingUtils.NEUTRON_RULE__ + providerEpgId.getValue() + "__" + prefix + "__"
-                + consumerEpgId.getValue());
-    }
-
-    public Clause createClause() {
-        ClauseBuilder clauseBuilder = new ClauseBuilder().setName(clauseName).setSubjectRefs(
-                ImmutableList.of(subjectName));
-        if (ipPrefix != null) {
-            clauseBuilder.setConsumerMatchers(new ConsumerMatchersBuilder().setEndpointIdentificationConstraints(
-                    new EndpointIdentificationConstraintsBuilder().setL3EndpointIdentificationConstraints(
-                            new L3EndpointIdentificationConstraintsBuilder().setPrefixConstraint(
-                                    ImmutableList.<PrefixConstraint>of(new PrefixConstraintBuilder().setIpPrefix(
-                                            ipPrefix).build())).build()).build()).build());
-            if (isEpgIdRouterOrDhcp(providerEpgId)) {
-                clauseBuilder.setProviderMatchers(new ProviderMatchersBuilder().setEndpointIdentificationConstraints(
-                        new EndpointIdentificationConstraintsBuilder().setL3EndpointIdentificationConstraints(
-                                new L3EndpointIdentificationConstraintsBuilder().setPrefixConstraint(
-                                        ImmutableList.<PrefixConstraint>of(new PrefixConstraintBuilder().setIpPrefix(
-                                                ipPrefix)
-                                            .build()))
-                                    .build())
-                            .build())
-                    .build());
-            }
-        }
-        return clauseBuilder.build();
-    }
-
-    private static boolean isEpgIdRouterOrDhcp(EndpointGroupId epgId) {
-        return (MappingUtils.EPG_ROUTER_ID.equals(epgId) || MappingUtils.EPG_DHCP_ID.equals(epgId));
-    }
-
-    public ClassifierInstance createClassifier() {
-        ClassifierInstanceBuilder classifierBuilder = new ClassifierInstanceBuilder().setName(classifierName);
-        List<ParameterValue> params = new ArrayList<>();
-        Integer portMin = secRule.getSecurityRulePortMin();
-        Integer portMax = secRule.getSecurityRulePortMax();
-        if (portMin != null && portMax != null) {
-            classifierBuilder.setClassifierDefinitionId(L4Classifier.DEFINITION.getId());
-            if (portMin.equals(portMax)) {
-                params.add(new ParameterValueBuilder().setName(new ParameterName(L4Classifier.DST_PORT_PARAM))
-                    .setIntValue(portMin.longValue())
-                    .build());
-            } else {
-                params.add(new ParameterValueBuilder().setName(new ParameterName(L4Classifier.DST_PORT_RANGE_PARAM))
-                    .setRangeValue(
-                            new RangeValueBuilder().setMin(portMin.longValue()).setMax(portMax.longValue()).build())
-                    .build());
-            }
-        }
-        String protocol = secRule.getSecurityRuleProtocol();
-        if (!Strings.isNullOrEmpty(protocol)) {
-            if (classifierBuilder.getClassifierDefinitionId() == null) {
-                classifierBuilder.setClassifierDefinitionId(IpProtoClassifier.DEFINITION.getId());
-            }
-            if (NeutronUtils.TCP.equals(protocol)) {
-                params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifier.PROTO_PARAM))
-                    .setIntValue(IpProtoClassifier.TCP_VALUE)
-                    .build());
-            } else if (NeutronUtils.UDP.equals(protocol)) {
-                params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifier.PROTO_PARAM))
-                    .setIntValue(IpProtoClassifier.UDP_VALUE)
-                    .build());
-            } else if (NeutronUtils.ICMP.equals(protocol)) {
-                params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifier.PROTO_PARAM))
-                    .setIntValue(1L)
-                    .build());
-            } else if (NeutronUtils.NULL.equals(protocol)) {
-                LOG.debug("Protocol is not specified in security group rule {}", secRule.getSecurityRuleUUID());
-            } else {
-                throw new IllegalArgumentException("Protocol " + protocol + " is not supported.");
-            }
-        }
-        String ethertype = secRule.getSecurityRuleEthertype();
-        if (!Strings.isNullOrEmpty(ethertype)) {
-            if (classifierBuilder.getClassifierDefinitionId() == null) {
-                classifierBuilder.setClassifierDefinitionId(EtherTypeClassifier.DEFINITION.getId());
-            }
-            if (NeutronUtils.IPv4.equals(ethertype)) {
-                params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifier.ETHERTYPE_PARAM))
-                    .setIntValue(EtherTypeClassifier.IPv4_VALUE)
-                    .build());
-            } else if (NeutronUtils.IPv6.equals(ethertype)) {
-                params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifier.ETHERTYPE_PARAM))
-                    .setIntValue(EtherTypeClassifier.IPv6_VALUE)
-                    .build());
-            } else {
-                throw new IllegalArgumentException("Ethertype " + ethertype + " is not supported.");
-            }
-        }
-        return classifierBuilder.setParameterValue(params).build();
-    }
-
-    public Rule createRule(int order) {
-        return new RuleBuilder().setName(ruleName)
-            .setOrder(order)
-            .setActionRef(ACTION_REF_ALLOW)
-            .setClassifierRef(ImmutableList.of(createClassifierRef()))
-            .build();
-    }
-
-    public Subject createSubject() {
-        return new SubjectBuilder().setName(subjectName).setOrder(subjectOrder).build();
-    }
-
-    private ClassifierRef createClassifierRef() {
-        ClassifierRefBuilder classifierRefBuilder = new ClassifierRefBuilder().setName(classifierName)
-            .setConnectionTracking(ConnectionTracking.Reflexive)
-            .setInstanceName(classifierName);
-        String direction = secRule.getSecurityRuleDirection();
-        if (NeutronUtils.INGRESS.equals(direction)) {
-            classifierRefBuilder.setDirection(Direction.In);
-        } else if (NeutronUtils.EGRESS.equals(direction)) {
-            classifierRefBuilder.setDirection(Direction.Out);
-        } else {
-            throw new IllegalArgumentException("Direction " + direction + " from security group rule "
-                    + secRule.getSecurityRuleUUID() + " is not supported. Direction can be only 'ingress' or 'egress'.");
-        }
-        return classifierRefBuilder.build();
-    }
-
-    public TenantId getTenantId() {
-        return tenantId;
-    }
-
-    public EndpointGroupId getProviderEpgId() {
-        return providerEpgId;
-    }
-
-    public EndpointGroupId getConsumerEpgId() {
-        return consumerEpgId;
-    }
-
-    public SubjectName getSubjectName() {
-        return subjectName;
-    }
-
-    public ClauseName getClauseName() {
-        return clauseName;
-    }
-
-    public IpPrefix getIpPrefix() {
-        return ipPrefix;
-    }
-
-    public ClassifierName getClassifierName() {
-        return classifierName;
-    }
-
-    public RuleName getRuleName() {
-        return ruleName;
-    }
-
-}
@@ -5,7 +5,7 @@
  * 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.mapping;
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -15,6 +15,8 @@ import java.util.List;
 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.mapping.StatusCode;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
@@ -29,6 +31,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 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.EndpointGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -45,9 +48,13 @@ public class NeutronSecurityGroupAware implements INeutronSecurityGroupAware {
 
     private static final Logger LOG = LoggerFactory.getLogger(NeutronSecurityGroupAware.class);
     private final DataBroker dataProvider;
+    private final NeutronSecurityRuleAware secRuleAware;
+    private final SecGroupDao secGroupDao;
 
-    public NeutronSecurityGroupAware(DataBroker dataProvider) {
+    public NeutronSecurityGroupAware(DataBroker dataProvider, NeutronSecurityRuleAware secRuleAware, SecGroupDao secGroupDao) {
         this.dataProvider = checkNotNull(dataProvider);
+        this.secRuleAware = checkNotNull(secRuleAware);
+        this.secGroupDao = checkNotNull(secGroupDao);
     }
 
     /**
@@ -75,13 +82,30 @@ public class NeutronSecurityGroupAware implements INeutronSecurityGroupAware {
         }
     }
 
-    public static boolean addNeutronSecurityGroup(NeutronSecurityGroup secGroup, ReadWriteTransaction rwTx) {
+    public boolean addNeutronSecurityGroup(NeutronSecurityGroup secGroup, ReadWriteTransaction rwTx) {
+        secGroupDao.addSecGroup(secGroup);
         TenantId tenantId = new TenantId(Utils.normalizeUuid(secGroup.getSecurityGroupTenantID()));
         EndpointGroupId providerEpgId = new EndpointGroupId(secGroup.getSecurityGroupUUID());
         EndpointGroupBuilder providerEpgBuilder = new EndpointGroupBuilder().setId(providerEpgId);
-        providerEpgBuilder.setName(new Name(MappingUtils.NEUTRON_GROUP__ + Strings.nullToEmpty(secGroup.getSecurityGroupName())));
-        providerEpgBuilder.setDescription(new Description(MappingUtils.NEUTRON_GROUP__
-                + Strings.nullToEmpty(secGroup.getSecurityGroupDescription())));
+        if (!Strings.isNullOrEmpty(secGroup.getSecurityGroupName())) {
+            try {
+                providerEpgBuilder.setName(new Name(secGroup.getSecurityGroupName()));
+            } catch (Exception e) {
+                LOG.info("Name '{}' of Neutron Security-group '{}' is ignored.",
+                        secGroup.getSecurityGroupName(), secGroup.getSecurityGroupUUID());
+                LOG.debug("Name exception", e);
+            }
+        }
+        if (!Strings.isNullOrEmpty(secGroup.getSecurityGroupDescription())) {
+            try {
+                providerEpgBuilder.setDescription(new Description(secGroup.getSecurityGroupDescription()));
+            } catch (Exception e) {
+                LOG.info("Description '{}' of Neutron Security-group '{}' is ignored.",
+                        secGroup.getSecurityGroupDescription(), secGroup.getSecurityGroupUUID());
+                LOG.debug("Description exception", e);
+            }
+        }
+        providerEpgBuilder.setIntraGroupPolicy(IntraGroupPolicy.RequireContract);
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, providerEpgId),
                 providerEpgBuilder.build(), true);
         List<NeutronSecurityRule> secRules = secGroup.getSecurityRules();
@@ -110,20 +134,20 @@ public class NeutronSecurityGroupAware implements INeutronSecurityGroupAware {
 
     public static void addEpgIfMissing(TenantId tenantId, EndpointGroupId epgId, ReadWriteTransaction rwTx) {
         InstanceIdentifier<EndpointGroup> epgIid = IidFactory.endpointGroupIid(tenantId, epgId);
-        Optional<EndpointGroup> potentialConsumerEpg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                epgIid, rwTx);
+        Optional<EndpointGroup> potentialConsumerEpg =
+                DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, epgIid, rwTx);
         if (!potentialConsumerEpg.isPresent()) {
             EndpointGroup epg = new EndpointGroupBuilder().setId(epgId)
-                .setName(new Name(MappingUtils.NEUTRON_GROUP__))
-                .setDescription(new Description(MappingUtils.NEUTRON_GROUP__ + "EPG was created just based on remote group ID from a security rule."))
+                .setDescription(new Description(MappingUtils.NEUTRON_GROUP
+                        + "EPG was created just based on remote group ID from a security rule."))
                 .build();
             rwTx.put(LogicalDatastoreType.CONFIGURATION, epgIid, epg);
         }
     }
 
-    private static boolean addNeutronSecurityRule(List<NeutronSecurityRule> secRules, ReadWriteTransaction rwTx) {
+    private boolean addNeutronSecurityRule(List<NeutronSecurityRule> secRules, ReadWriteTransaction rwTx) {
         for (NeutronSecurityRule secRule : secRules) {
-            boolean isSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(secRule, rwTx);
+            boolean isSecRuleAdded = secRuleAware.addNeutronSecurityRule(secRule, rwTx);
             if (!isSecRuleAdded) {
                 return false;
             }
@@ -179,6 +203,7 @@ public class NeutronSecurityGroupAware implements INeutronSecurityGroupAware {
         }
         TenantId tenantId = new TenantId(Utils.normalizeUuid(secGroup.getSecurityGroupTenantID()));
         EndpointGroupId epgId = new EndpointGroupId(secGroup.getSecurityGroupUUID());
+        secGroupDao.removeSecGroup(epgId);
         Optional<EndpointGroup> potentialEpg = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
                 IidFactory.endpointGroupIid(tenantId, epgId), rwTx);
         if (!potentialEpg.isPresent()) {
@@ -192,7 +217,7 @@ public class NeutronSecurityGroupAware implements INeutronSecurityGroupAware {
 
     private boolean deleteNeutronSecurityRules(List<NeutronSecurityRule> secRules, ReadWriteTransaction rwTx) {
         for (NeutronSecurityRule secRule : secRules) {
-            boolean isSecRuleDeleted = NeutronSecurityRuleAware.deleteNeutronSecurityRule(secRule, rwTx);
+            boolean isSecRuleDeleted = secRuleAware.deleteNeutronSecurityRule(secRule, rwTx);
             if (!isSecRuleDeleted) {
                 return false;
             }
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/group/SecGroupDao.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/group/SecGroupDao.java
new file mode 100644 (file)
index 0000000..6253f03
--- /dev/null
@@ -0,0 +1,47 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
+import org.opendaylight.neutron.spi.NeutronSecurityGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+
+import com.google.common.base.Strings;
+
+public class SecGroupDao {
+
+    private final Map<EndpointGroupId, NeutronSecurityGroup> secGroupById = new HashMap<>();
+
+    public void addSecGroup(NeutronSecurityGroup secGrp) {
+        checkNotNull(secGrp);
+        secGroupById.put(new EndpointGroupId(Utils.normalizeUuid(secGrp.getSecurityGroupUUID())), secGrp);
+    }
+
+    public NeutronSecurityGroup getSecGroupById(EndpointGroupId id) {
+        return secGroupById.get(id);
+    }
+
+    /**
+     * @param id
+     * @return {@code empty string} if security group with given ID does not exist; returns
+     *         {@code name of security group} if has some; otherwise security group id
+     */
+    public String getNameOrIdOfSecGroup(EndpointGroupId id) {
+        NeutronSecurityGroup secGrp = secGroupById.get(checkNotNull(id));
+        if (secGrp == null) {
+            return "";
+        }
+        if (!Strings.isNullOrEmpty(secGrp.getSecurityGroupName())) {
+            return secGrp.getSecurityGroupName();
+        }
+        return id.getValue();
+    }
+    
+    public void removeSecGroup(EndpointGroupId id) {
+        secGroupById.remove(checkNotNull(id));
+    }
+
+}
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAware.java
new file mode 100644 (file)
index 0000000..23331dc
--- /dev/null
@@ -0,0 +1,396 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.StatusCode;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.SecGroupDao;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
+import org.opendaylight.groupbasedpolicy.resolver.EgKey;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.neutron.spi.INeutronSecurityRuleAware;
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
+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.SelectorName;
+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.tenants.tenant.Contract;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Strings;
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Multiset;
+import com.google.common.collect.Sets;
+
+public class NeutronSecurityRuleAware implements INeutronSecurityRuleAware {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronSecurityRuleAware.class);
+    private static final String CONTRACT_PROVIDER = "Contract provider: ";
+    private final DataBroker dataProvider;
+    private final SecRuleDao secRuleDao;
+    private final SecGroupDao secGroupDao;
+    private final Multiset<InstanceIdentifier<ClassifierInstance>> createdClassifierInstances;
+    private final Multiset<InstanceIdentifier<ActionInstance>> createdActionInstances;
+    final static String PROVIDED_BY = "provided_by-";
+    final static String POSSIBLE_CONSUMER = "possible_consumer-";
+
+    public NeutronSecurityRuleAware(DataBroker dataProvider, SecRuleDao secRuleDao, SecGroupDao secGroupDao) {
+        this(dataProvider, secRuleDao, secGroupDao, HashMultiset.<InstanceIdentifier<ClassifierInstance>>create(),
+                HashMultiset.<InstanceIdentifier<ActionInstance>>create());
+    }
+
+    @VisibleForTesting
+    NeutronSecurityRuleAware(DataBroker dataProvider, SecRuleDao secRuleDao, SecGroupDao secGroupDao,
+            Multiset<InstanceIdentifier<ClassifierInstance>> classifierInstanceNames,
+            Multiset<InstanceIdentifier<ActionInstance>> createdActionInstances) {
+        this.dataProvider = checkNotNull(dataProvider);
+        this.secRuleDao = checkNotNull(secRuleDao);
+        this.secGroupDao = checkNotNull(secGroupDao);
+        this.createdClassifierInstances = checkNotNull(classifierInstanceNames);
+        this.createdActionInstances = checkNotNull(createdActionInstances);
+    }
+
+    @Override
+    public int canCreateNeutronSecurityRule(NeutronSecurityRule securityRule) {
+        LOG.trace("canCreateNeutronSecurityRule - {}", securityRule);
+        // nothing to consider
+        return StatusCode.OK;
+    }
+
+    @Override
+    public void neutronSecurityRuleCreated(NeutronSecurityRule securityRule) {
+        LOG.trace("neutronSecurityRuleCreated - {}", securityRule);
+        ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+        boolean isNeutronSecurityRuleAdded = addNeutronSecurityRule(securityRule, rwTx);
+        if (isNeutronSecurityRuleAdded) {
+            DataStoreHelper.submitToDs(rwTx);
+        } else {
+            rwTx.cancel();
+        }
+    }
+
+    /**
+     * @param secRule this security group rule will be translate to single rule inside single
+     *        subject inside a contract
+     * @param rwTx GBP entities are stored to this transaction. This method NEVER submits or cancel
+     *        the transaction.
+     * @return {@code true} if operation was successful; {@code false} if an illegal state occurs -
+     *         the transaction may contain just partial result
+     */
+    public boolean addNeutronSecurityRule(NeutronSecurityRule secRule, ReadWriteTransaction rwTx) {
+        TenantId tenantId = SecRuleEntityDecoder.getTenantId(secRule);
+        EndpointGroupId providerEpgId = SecRuleEntityDecoder.getProviderEpgId(secRule);
+        secRuleDao.addSecRule(secRule);
+
+        Description contractDescription =
+                new Description(CONTRACT_PROVIDER + secGroupDao.getNameOrIdOfSecGroup(providerEpgId));
+        SingleRuleContract singleRuleContract = createSingleRuleContract(secRule, contractDescription);
+        Contract contract = singleRuleContract.getContract();
+        rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, contract.getId()), contract,
+                true);
+        SelectorName providerSelector = getSelectorNameWithConsumer(secRule);
+        writeProviderNamedSelectorToEpg(providerSelector, contract.getId(), new EgKey(tenantId, providerEpgId), rwTx);
+
+        if (SecRuleEntityDecoder.getConsumerEpgId(secRule) != null) {
+            EndpointGroupId consumerEpgId = SecRuleEntityDecoder.getConsumerEpgId(secRule);
+            designContractsBetweenProviderAndConsumer(tenantId, providerEpgId, consumerEpgId, rwTx);
+            designContractsBetweenProviderAndConsumer(tenantId, consumerEpgId, providerEpgId, rwTx);
+        } else {
+            for (EndpointGroupId consumerEpgId : secRuleDao.getAllOwnerSecGrps()) {
+                designContractsBetweenProviderAndConsumer(tenantId, providerEpgId, consumerEpgId, rwTx);
+                designContractsBetweenProviderAndConsumer(tenantId, consumerEpgId, providerEpgId, rwTx);
+            }
+        }
+
+        ClassifierInstance classifierInstance = singleRuleContract.getSingleClassifierRule().getClassifierInstance();
+        createClassifierInstanceIfNotExists(tenantId, classifierInstance, rwTx);
+        createAllowActionInstanceIfNotExists(tenantId, rwTx);
+        return true;
+    }
+
+    @VisibleForTesting
+    static SingleRuleContract createSingleRuleContract(NeutronSecurityRule secRule, Description contractDescription) {
+        if (Strings.isNullOrEmpty(secRule.getSecurityRuleRemoteIpPrefix())) {
+            return new SingleRuleContract(secRule, 0, contractDescription);
+        }
+        return new SingleRuleContract(secRule, 1, contractDescription);
+    }
+
+    @VisibleForTesting
+    void designContractsBetweenProviderAndConsumer(TenantId tenantId, EndpointGroupId provEpgId,
+            EndpointGroupId consEpgId, ReadWriteTransaction rwTx) {
+        Set<NeutronSecurityRule> provSecRules = getProvidedSecRulesBetween(provEpgId, consEpgId);
+        Set<NeutronSecurityRule> consSecRules = getProvidedSecRulesBetween(consEpgId, provEpgId);
+        for (NeutronSecurityRule provSecRule : provSecRules) {
+            if (isProviderSecRuleSuitableForConsumerSecRules(provSecRule, consSecRules)) {
+                SelectorName consumerSelector = getSelectorNameWithProvider(provSecRule);
+                ContractId contractId = SecRuleEntityDecoder.getContractId(provSecRule);
+                writeConsumerNamedSelectorToEpg(consumerSelector, contractId, new EgKey(tenantId, consEpgId), rwTx);
+            }
+            // TODO add case when port ranges overlap
+        }
+    }
+
+    @VisibleForTesting
+    Set<NeutronSecurityRule> getProvidedSecRulesBetween(EndpointGroupId provEpgId, EndpointGroupId consEpgId) {
+        return Sets.union(secRuleDao.getSecRulesBySecGrpIdAndRemoteSecGrpId(provEpgId, consEpgId),
+                secRuleDao.getSecRulesWithoutRemoteSecGrpBySecGrpId(provEpgId));
+    }
+
+    @VisibleForTesting
+    static boolean isProviderSecRuleSuitableForConsumerSecRules(NeutronSecurityRule provSecRule,
+            Set<NeutronSecurityRule> consSecRules) {
+        Direction directionProvSecRule = SecRuleEntityDecoder.getDirection(provSecRule);
+        for (NeutronSecurityRule consSecRule : consSecRules) {
+            Direction directionConsSecRule = SecRuleEntityDecoder.getDirection(consSecRule);
+            if (isDirectionOpposite(directionProvSecRule, directionConsSecRule)
+                    && isOneWithinTwo(provSecRule, consSecRule)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void writeProviderNamedSelectorToEpg(SelectorName providerSelector, ContractId contractId, EgKey epgKey,
+            WriteTransaction wTx) {
+        ProviderNamedSelector providerNamedSelector = new ProviderNamedSelectorBuilder().setName(providerSelector)
+            .setContract(ImmutableList.of(contractId))
+            .build();
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.providerNamedSelectorIid(epgKey.getTenantId(),
+                epgKey.getEgId(), providerNamedSelector.getName()), providerNamedSelector, true);
+    }
+
+    private void writeConsumerNamedSelectorToEpg(SelectorName consumerSelector, ContractId contractId, EgKey epgKey,
+            WriteTransaction wTx) {
+        ConsumerNamedSelector consumerNamedSelector = new ConsumerNamedSelectorBuilder().setName(consumerSelector)
+            .setContract(ImmutableList.of(contractId))
+            .build();
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.consumerNamedSelectorIid(epgKey.getTenantId(),
+                epgKey.getEgId(), consumerNamedSelector.getName()), consumerNamedSelector, true);
+    }
+
+    @VisibleForTesting
+    void createClassifierInstanceIfNotExists(TenantId tenantId, ClassifierInstance classifierInstance,
+            WriteTransaction wTx) {
+        InstanceIdentifier<ClassifierInstance> classifierInstanceIid =
+                IidFactory.classifierInstanceIid(tenantId, classifierInstance.getName());
+        if (!createdClassifierInstances.contains(classifierInstanceIid)) {
+            wTx.put(LogicalDatastoreType.CONFIGURATION, classifierInstanceIid, classifierInstance, true);
+        }
+        createdClassifierInstances.add(classifierInstanceIid);
+    }
+
+    @VisibleForTesting
+    void createAllowActionInstanceIfNotExists(TenantId tenantId, ReadWriteTransaction rwTx) {
+        InstanceIdentifier<ActionInstance> actionInstanceIid =
+                IidFactory.actionInstanceIid(tenantId, MappingUtils.ACTION_ALLOW.getName());
+        if (!createdActionInstances.contains(actionInstanceIid)) {
+            rwTx.put(LogicalDatastoreType.CONFIGURATION, actionInstanceIid, MappingUtils.ACTION_ALLOW, true);
+        }
+        createdActionInstances.add(actionInstanceIid);
+    }
+
+    @Override
+    public int canUpdateNeutronSecurityRule(NeutronSecurityRule delta, NeutronSecurityRule original) {
+        LOG.warn(
+                "canUpdateNeutronSecurityRule - Never should be called "
+                        + "- neutron API does not allow UPDATE on neutron security group rule. \nDelta: {} \nOriginal: {}",
+                delta, original);
+        return StatusCode.BAD_REQUEST;
+    }
+
+    @Override
+    public void neutronSecurityRuleUpdated(NeutronSecurityRule securityRule) {
+        LOG.warn(
+                "neutronSecurityRuleUpdated - Never should be called "
+                        + "- neutron API does not allow UPDATE on neutron security group rule. \nSecurity group rule: {}",
+                securityRule);
+    }
+
+    @Override
+    public int canDeleteNeutronSecurityRule(NeutronSecurityRule securityRule) {
+        LOG.trace("canDeleteNeutronSecurityRule - {}", securityRule);
+        // nothing to consider
+        return StatusCode.OK;
+    }
+
+    @Override
+    public void neutronSecurityRuleDeleted(NeutronSecurityRule secRule) {
+        LOG.trace("neutronSecurityRuleCreated - {}", secRule);
+        ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+        boolean isNeutronSecurityRuleDeleted = deleteNeutronSecurityRule(secRule, rwTx);
+        if (isNeutronSecurityRuleDeleted) {
+            DataStoreHelper.submitToDs(rwTx);
+        } else {
+            rwTx.cancel();
+        }
+    }
+
+    public boolean deleteNeutronSecurityRule(NeutronSecurityRule secRule, ReadWriteTransaction rwTx) {
+        TenantId tenantId = SecRuleEntityDecoder.getTenantId(secRule);
+        EndpointGroupId providerEpgId = SecRuleEntityDecoder.getProviderEpgId(secRule);
+
+        SelectorName providerSelector = getSelectorNameWithConsumer(secRule);
+        deleteProviderNamedSelectorFromEpg(providerSelector, new EgKey(tenantId, providerEpgId), rwTx);
+
+        if (SecRuleEntityDecoder.getConsumerEpgId(secRule) != null) {
+            EndpointGroupId consumerEpgId = SecRuleEntityDecoder.getConsumerEpgId(secRule);
+            undesignContractsBetweenProviderAndConsumer(tenantId, providerEpgId, consumerEpgId, secRule, rwTx);
+            undesignContractsBetweenProviderAndConsumer(tenantId, consumerEpgId, providerEpgId, secRule, rwTx);
+        } else {
+            for (EndpointGroupId consumerEpgId : secRuleDao.getAllOwnerSecGrps()) {
+                undesignContractsBetweenProviderAndConsumer(tenantId, providerEpgId, consumerEpgId, secRule, rwTx);
+                undesignContractsBetweenProviderAndConsumer(tenantId, consumerEpgId, providerEpgId, secRule, rwTx);
+            }
+        }
+
+        secRuleDao.removeSecRule(secRule);
+        ContractId contractId = SecRuleEntityDecoder.getContractId(secRule);
+        rwTx.delete(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, contractId));
+
+        ClassifierInstance classifierInstance = SecRuleEntityDecoder.getClassifierInstance(secRule);
+        deleteClassifierInstanceIfNotUsed(tenantId, classifierInstance, rwTx);
+        return true;
+    }
+
+    @VisibleForTesting
+    void undesignContractsBetweenProviderAndConsumer(TenantId tenantId, EndpointGroupId provEpgId,
+            EndpointGroupId consEpgId, NeutronSecurityRule removedSecRule, ReadWriteTransaction rwTx) {
+        Set<NeutronSecurityRule> provSecRules = getProvidedSecRulesBetween(provEpgId, consEpgId);
+        Set<NeutronSecurityRule> consSecRules = getProvidedSecRulesBetween(consEpgId, provEpgId);
+        for (NeutronSecurityRule provSecRule : provSecRules) {
+            if (isProvidersSecRuleSuitableForConsumersSecRulesAndGoodToRemove(provSecRule, consSecRules,
+                    removedSecRule)) {
+                SelectorName consumerSelector = getSelectorNameWithProvider(provSecRule);
+                deleteConsumerNamedSelector(consumerSelector, new EgKey(tenantId, consEpgId), rwTx);
+            }
+            // TODO add case when port ranges overlap
+        }
+    }
+
+    @VisibleForTesting
+    static boolean isProvidersSecRuleSuitableForConsumersSecRulesAndGoodToRemove(NeutronSecurityRule provSecRule,
+            Set<NeutronSecurityRule> consSecRules, NeutronSecurityRule removedSecRule) {
+        Direction directionProvSecRule = SecRuleEntityDecoder.getDirection(provSecRule);
+        for (NeutronSecurityRule consSecRule : consSecRules) {
+            if (isRuleIdEqual(removedSecRule, consSecRule) || isRuleIdEqual(removedSecRule, provSecRule)) {
+                Direction directionConsSecRule = SecRuleEntityDecoder.getDirection(consSecRule);
+                if (isDirectionOpposite(directionProvSecRule, directionConsSecRule)
+                        && isOneWithinTwo(provSecRule, consSecRule)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @VisibleForTesting
+    static boolean isRuleIdEqual(NeutronSecurityRule one, NeutronSecurityRule two) {
+        checkNotNull(one);
+        checkNotNull(two);
+        return one.getSecurityRuleUUID().equals(two.getSecurityRuleUUID());
+    }
+
+    private void deleteProviderNamedSelectorFromEpg(SelectorName providerSelector, EgKey epgKey, WriteTransaction wTx) {
+        InstanceIdentifier<ProviderNamedSelector> providerSelectorIid =
+                IidFactory.providerNamedSelectorIid(epgKey.getTenantId(), epgKey.getEgId(), providerSelector);
+        wTx.delete(LogicalDatastoreType.CONFIGURATION, providerSelectorIid);
+    }
+
+    private void deleteConsumerNamedSelector(SelectorName consumerSelector, EgKey consumerEpgKey,
+            WriteTransaction wTx) {
+        InstanceIdentifier<ConsumerNamedSelector> consumerSelectorIid = IidFactory
+            .consumerNamedSelectorIid(consumerEpgKey.getTenantId(), consumerEpgKey.getEgId(), consumerSelector);
+        wTx.delete(LogicalDatastoreType.CONFIGURATION, consumerSelectorIid);
+    }
+
+    private void deleteClassifierInstanceIfNotUsed(TenantId tenantId, ClassifierInstance classifierInstance,
+            ReadWriteTransaction rwTx) {
+        InstanceIdentifier<ClassifierInstance> classifierInstanceIid =
+                IidFactory.classifierInstanceIid(tenantId, classifierInstance.getName());
+        createdClassifierInstances.remove(classifierInstanceIid);
+        if (!createdClassifierInstances.contains(classifierInstanceIid)) {
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, classifierInstanceIid, rwTx);
+        }
+    }
+
+    @VisibleForTesting
+    void deleteAllowActionInstanceIfNotUsed(TenantId tenantId, ReadWriteTransaction rwTx) {
+        InstanceIdentifier<ActionInstance> actionInstanceIid =
+                IidFactory.actionInstanceIid(tenantId, MappingUtils.ACTION_ALLOW.getName());
+        createdActionInstances.remove(actionInstanceIid);
+        if (!createdActionInstances.contains(actionInstanceIid)) {
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, actionInstanceIid, rwTx);
+        }
+    }
+
+    private SelectorName getSelectorNameWithConsumer(NeutronSecurityRule secRule) {
+        ClauseName clauseName = SecRuleNameDecoder.getClauseName(secRule);
+        StringBuilder selectorNameBuilder = new StringBuilder().append(clauseName.getValue());
+        EndpointGroupId consumerEpgId = SecRuleEntityDecoder.getConsumerEpgId(secRule);
+        if (consumerEpgId != null) {
+            selectorNameBuilder.append(MappingUtils.NAME_DOUBLE_DELIMETER)
+                .append(POSSIBLE_CONSUMER)
+                .append(secGroupDao.getNameOrIdOfSecGroup(consumerEpgId));
+        }
+        return new SelectorName(selectorNameBuilder.toString());
+    }
+
+    private SelectorName getSelectorNameWithProvider(NeutronSecurityRule secRule) {
+        ClauseName clauseName = SecRuleNameDecoder.getClauseName(secRule);
+        EndpointGroupId providerEpgId = SecRuleEntityDecoder.getProviderEpgId(secRule);
+        String selectorName = new StringBuilder().append(clauseName.getValue())
+            .append(MappingUtils.NAME_DOUBLE_DELIMETER)
+            .append(PROVIDED_BY)
+            .append(secGroupDao.getNameOrIdOfSecGroup(providerEpgId))
+            .toString();
+        return new SelectorName(selectorName);
+    }
+
+    @VisibleForTesting
+    static boolean isDirectionOpposite(Direction one, Direction two) {
+        return (one == Direction.In && two == Direction.Out) || (one == Direction.Out && two == Direction.In);
+    }
+
+    @VisibleForTesting
+    static boolean isOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {
+        if (!isOneGroupIdWithinTwoRemoteGroupId(one, two) || !isOneGroupIdWithinTwoRemoteGroupId(two, one))
+            return false;
+        if (!SecRuleEntityDecoder.isEtherTypeOfOneWithinTwo(one, two))
+            return false;
+        if (!SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two))
+            return false;
+        if (!SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two))
+            return false;
+        if (!Strings.isNullOrEmpty(two.getSecurityRuleRemoteIpPrefix())
+                && Strings.isNullOrEmpty(one.getSecurityRuleRemoteIpPrefix()))
+            return false;
+        return true;
+    }
+
+    @VisibleForTesting
+    static boolean isOneGroupIdWithinTwoRemoteGroupId(NeutronSecurityRule one, NeutronSecurityRule two) {
+        return (Strings.isNullOrEmpty(two.getSecurityRemoteGroupID())
+                || two.getSecurityRemoteGroupID().equals(one.getSecurityRuleGroupID()));
+    }
+
+}
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleDao.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleDao.java
new file mode 100644 (file)
index 0000000..fc6f607
--- /dev/null
@@ -0,0 +1,96 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
+
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.SetMultimap;
+
+public class SecRuleDao {
+
+    private final SetMultimap<EndpointGroupId, NeutronSecurityRule> secRulesByOwnerSecGrpId = HashMultimap.create();
+    private final SetMultimap<OwnerAndRemoteOfSecRule, NeutronSecurityRule> secRulesByRemoteSecGrpId =
+            HashMultimap.create();
+
+    public void addSecRule(NeutronSecurityRule secRule) {
+        Preconditions.checkNotNull(secRule);
+        EndpointGroupId ownerSecGrp = SecRuleEntityDecoder.getProviderEpgId(secRule);
+        EndpointGroupId remoteSecGrp = SecRuleEntityDecoder.getConsumerEpgId(secRule);
+        secRulesByOwnerSecGrpId.put(ownerSecGrp, secRule);
+        secRulesByRemoteSecGrpId.put(new OwnerAndRemoteOfSecRule(ownerSecGrp, remoteSecGrp), secRule);
+    }
+
+    public Set<NeutronSecurityRule> getSecRulesByOwnerSecGrpId(EndpointGroupId secGrpId) {
+        return secRulesByOwnerSecGrpId.get(secGrpId);
+    }
+
+    public Set<NeutronSecurityRule> getSecRulesBySecGrpIdAndRemoteSecGrpId(EndpointGroupId ownerSecGrpId,
+            @Nullable EndpointGroupId remoteSecGrpId) {
+        return secRulesByRemoteSecGrpId.get(new OwnerAndRemoteOfSecRule(ownerSecGrpId, remoteSecGrpId));
+    }
+
+    public Set<NeutronSecurityRule> getSecRulesWithoutRemoteSecGrpBySecGrpId(EndpointGroupId ownerSecGrpId) {
+        return secRulesByRemoteSecGrpId.get(new OwnerAndRemoteOfSecRule(ownerSecGrpId, null));
+    }
+
+    public Set<EndpointGroupId> getAllOwnerSecGrps() {
+        return secRulesByOwnerSecGrpId.keySet();
+    }
+
+    public void removeSecRule(NeutronSecurityRule secRule) {
+        Preconditions.checkNotNull(secRule);
+        EndpointGroupId ownerSecGrp = SecRuleEntityDecoder.getProviderEpgId(secRule);
+        EndpointGroupId remoteSecGrp = SecRuleEntityDecoder.getConsumerEpgId(secRule);
+        secRulesByOwnerSecGrpId.remove(ownerSecGrp, secRule);
+        secRulesByRemoteSecGrpId.remove(new OwnerAndRemoteOfSecRule(ownerSecGrp, remoteSecGrp), secRule);
+    }
+
+    static class OwnerAndRemoteOfSecRule {
+
+        private final EndpointGroupId owner;
+        private final EndpointGroupId remote;
+
+        private OwnerAndRemoteOfSecRule(EndpointGroupId owner, EndpointGroupId remote) {
+            this.owner = Preconditions.checkNotNull(owner);
+            this.remote = remote;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((owner == null) ? 0 : owner.hashCode());
+            result = prime * result + ((remote == null) ? 0 : remote.hashCode());
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            OwnerAndRemoteOfSecRule other = (OwnerAndRemoteOfSecRule) obj;
+            if (owner == null) {
+                if (other.owner != null)
+                    return false;
+            } else if (!owner.equals(other.owner))
+                return false;
+            if (remote == null) {
+                if (other.remote != null)
+                    return false;
+            } else if (!remote.equals(other.remote))
+                return false;
+            return true;
+        }
+
+    }
+
+}
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleEntityDecoder.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleEntityDecoder.java
new file mode 100644 (file)
index 0000000..440c640
--- /dev/null
@@ -0,0 +1,254 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;\r
+\r
+import static com.google.common.base.Preconditions.checkNotNull;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import javax.annotation.Nullable;\r
+\r
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;\r
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.EtherTypeClassifier;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.IpProtoClassifier;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.L4Classifier;\r
+import org.opendaylight.neutron.spi.NeutronSecurityRule;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef.ConnectionTracking;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraints;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValueBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchers;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstanceBuilder;\r
+\r
+import com.google.common.base.Strings;\r
+import com.google.common.collect.ImmutableList;\r
+\r
+public class SecRuleEntityDecoder {\r
+\r
+    private SecRuleEntityDecoder() {\r
+        throw new UnsupportedOperationException("Cannot create an instace.");\r
+    }\r
+\r
+    public static TenantId getTenantId(NeutronSecurityRule secRule) {\r
+        return new TenantId(Utils.normalizeUuid(secRule.getSecurityRuleTenantID()));\r
+    }\r
+\r
+    public static EndpointGroupId getProviderEpgId(NeutronSecurityRule secRule) {\r
+        return new EndpointGroupId(Utils.normalizeUuid(secRule.getSecurityRuleGroupID()));\r
+    }\r
+\r
+    /**\r
+     * @return {@code null} if {@link NeutronSecurityRule#getSecurityRemoteGroupID()} is null\r
+     */\r
+    public static @Nullable EndpointGroupId getConsumerEpgId(NeutronSecurityRule secRule) {\r
+        if (Strings.isNullOrEmpty(secRule.getSecurityRemoteGroupID())) {\r
+            return null;\r
+        }\r
+        return new EndpointGroupId(Utils.normalizeUuid(secRule.getSecurityRemoteGroupID()));\r
+    }\r
+\r
+    public static ContractId getContractId(NeutronSecurityRule secRule) {\r
+        return new ContractId(Utils.normalizeUuid(secRule.getSecurityRuleUUID()));\r
+    }\r
+\r
+    public static ClassifierInstance getClassifierInstance(NeutronSecurityRule secRule) {\r
+        ClassifierInstanceBuilder classifierBuilder = new ClassifierInstanceBuilder();\r
+        List<ParameterValue> params = new ArrayList<>();\r
+        Integer portMin = secRule.getSecurityRulePortMin();\r
+        Integer portMax = secRule.getSecurityRulePortMax();\r
+        if (portMin != null && portMax != null) {\r
+            classifierBuilder.setClassifierDefinitionId(L4Classifier.DEFINITION.getId());\r
+            if (portMin.equals(portMax)) {\r
+                params.add(new ParameterValueBuilder().setName(new ParameterName(L4Classifier.DST_PORT_PARAM))\r
+                    .setIntValue(portMin.longValue())\r
+                    .build());\r
+            } else {\r
+                params.add(new ParameterValueBuilder().setName(new ParameterName(L4Classifier.DST_PORT_RANGE_PARAM))\r
+                    .setRangeValue(\r
+                            new RangeValueBuilder().setMin(portMin.longValue()).setMax(portMax.longValue()).build())\r
+                    .build());\r
+            }\r
+        }\r
+        Long protocol = getProtocol(secRule);\r
+        if (protocol != null) {\r
+            if (classifierBuilder.getClassifierDefinitionId() == null) {\r
+                classifierBuilder.setClassifierDefinitionId(IpProtoClassifier.DEFINITION.getId());\r
+            }\r
+            params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifier.PROTO_PARAM))\r
+                .setIntValue(protocol)\r
+                .build());\r
+        }\r
+        Long ethertype = getEtherType(secRule);\r
+        if (ethertype != null) {\r
+            if (classifierBuilder.getClassifierDefinitionId() == null) {\r
+                classifierBuilder.setClassifierDefinitionId(EtherTypeClassifier.DEFINITION.getId());\r
+            }\r
+            params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifier.ETHERTYPE_PARAM))\r
+                .setIntValue(ethertype)\r
+                .build());\r
+        }\r
+        ClassifierName classifierName = SecRuleNameDecoder.getClassifierInstanceName(secRule);\r
+        return classifierBuilder.setParameterValue(params).setName(new ClassifierName(classifierName)).build();\r
+    }\r
+\r
+    public static ClassifierRef getClassifierRef(NeutronSecurityRule secRule) {\r
+        checkNotNull(secRule);\r
+        ClassifierName classifierInstanceName = SecRuleNameDecoder.getClassifierInstanceName(secRule);\r
+        ClassifierRefBuilder classifierRefBuilder = new ClassifierRefBuilder()\r
+            .setConnectionTracking(ConnectionTracking.Reflexive).setInstanceName(classifierInstanceName);\r
+        Direction direction = getDirection(secRule);\r
+        classifierRefBuilder.setDirection(direction);\r
+        ClassifierName classifierRefName = SecRuleNameDecoder.getClassifierRefName(secRule);\r
+        return classifierRefBuilder.setName(classifierRefName).build();\r
+    }\r
+\r
+    /**\r
+     * @param secRule\r
+     * @return direction resolved from {@link NeutronSecurityRule#getSecurityRuleDirection()}\r
+     * @throws IllegalArgumentException if return value of\r
+     *         {@link NeutronSecurityRule#getSecurityRuleDirection()} is other than "ingress" or\r
+     *         "egress"\r
+     */\r
+    public static Direction getDirection(NeutronSecurityRule secRule) {\r
+        String direction = secRule.getSecurityRuleDirection();\r
+        if (NeutronUtils.INGRESS.equals(direction)) {\r
+            return Direction.In;\r
+        }\r
+        if (NeutronUtils.EGRESS.equals(direction)) {\r
+            return Direction.Out;\r
+        }\r
+        throw new IllegalArgumentException("Direction " + direction + " from security group rule "\r
+                + secRule.getSecurityRuleUUID() + " is not supported. Direction can be only 'ingress' or 'egress'.");\r
+    }\r
+\r
+    /**\r
+     * @param secRule {@link NeutronSecurityRule#getSecurityRuleRemoteIpPrefix()} is used for EIC\r
+     *        and subject selection\r
+     * @return clause with the subject and with a consumer matcher containing EIC\r
+     */\r
+    public static Clause getClause(NeutronSecurityRule secRule) {\r
+        checkNotNull(secRule);\r
+        SubjectName subjectName = SecRuleNameDecoder.getSubjectName(secRule);\r
+        ClauseBuilder clauseBuilder =\r
+                new ClauseBuilder().setSubjectRefs(ImmutableList.of(subjectName)).setName(SecRuleNameDecoder.getClauseName(secRule));\r
+        String remoteIpPrefix = secRule.getSecurityRuleRemoteIpPrefix();\r
+        if (!Strings.isNullOrEmpty(remoteIpPrefix)) {\r
+            clauseBuilder.setConsumerMatchers(createConsumerMatchersWithEic(remoteIpPrefix));\r
+        }\r
+        return clauseBuilder.build();\r
+    }\r
+\r
+    private static ConsumerMatchers createConsumerMatchersWithEic(String remoteIpPrefix) {\r
+        IpPrefix ipPrefix = Utils.createIpPrefix(remoteIpPrefix);\r
+        PrefixConstraint consumerPrefixConstraint = new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build();\r
+        EndpointIdentificationConstraints eic =\r
+                new EndpointIdentificationConstraintsBuilder()\r
+                    .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()\r
+                        .setPrefixConstraint(ImmutableList.<PrefixConstraint>of(consumerPrefixConstraint)).build())\r
+                    .build();\r
+        return new ConsumerMatchersBuilder().setEndpointIdentificationConstraints(eic).build();\r
+    }\r
+\r
+    public static boolean isEtherTypeOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {\r
+        Long oneEtherType = getEtherType(one);\r
+        Long twoEtherType = getEtherType(two);\r
+        return twoIsNullOrEqualsOne(oneEtherType, twoEtherType);\r
+    }\r
+\r
+    public static boolean isProtocolOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {\r
+        Long oneProtocol = getProtocol(one);\r
+        Long twoProtocol = getProtocol(two);\r
+        return twoIsNullOrEqualsOne(oneProtocol, twoProtocol);\r
+    }\r
+\r
+    private static <T> boolean twoIsNullOrEqualsOne(T one, T two) {\r
+        if (two == null)\r
+            return true;\r
+        if (two.equals(one))\r
+            return true;\r
+        return false;\r
+    }\r
+\r
+    public static boolean isPortsOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {\r
+        Integer onePortMin = one.getSecurityRulePortMin();\r
+        Integer onePortMax = one.getSecurityRulePortMax();\r
+        Integer twoPortMin = two.getSecurityRulePortMin();\r
+        Integer twoPortMax = two.getSecurityRulePortMax();\r
+        if (twoPortMin == null && twoPortMax == null) {\r
+            return true;\r
+        }\r
+        if ((onePortMin != null && twoPortMin != null && onePortMin >= twoPortMin)\r
+                && (onePortMax != null && twoPortMax != null && onePortMax <= twoPortMax)) {\r
+            return true;\r
+        }\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * @param secRule\r
+     * @return {@code null} if {@link NeutronSecurityRule#getSecurityRuleEthertype()} is null or\r
+     *         empty; value of {@link EtherTypeClassifier#IPv4_VALUE} or\r
+     *         {@link EtherTypeClassifier#IPv6_VALUE}\r
+     * @throws IllegalArgumentException if return value of\r
+     *         {@link NeutronSecurityRule#getSecurityRuleEthertype()} is not empty/null and is other\r
+     *         than "IPv4" or "IPv6"\r
+     */\r
+    public static Long getEtherType(NeutronSecurityRule secRule) {\r
+        String ethertype = secRule.getSecurityRuleEthertype();\r
+        if (Strings.isNullOrEmpty(ethertype)) {\r
+            return null;\r
+        }\r
+        if (NeutronUtils.IPv4.equals(ethertype)) {\r
+            return EtherTypeClassifier.IPv4_VALUE;\r
+        }\r
+        if (NeutronUtils.IPv6.equals(ethertype)) {\r
+            return EtherTypeClassifier.IPv6_VALUE;\r
+        }\r
+        throw new IllegalArgumentException("Ethertype " + ethertype + " is not supported.");\r
+    }\r
+\r
+    /**\r
+     * @param secRule\r
+     * @return {@code null} if {@link NeutronSecurityRule#getSecurityRuleProtocol()} is null or\r
+     *         empty; Otherwise protocol number\r
+     * @throws IllegalArgumentException if return value of\r
+     *         {@link NeutronSecurityRule#getSecurityRuleProtocol()} is not empty/null and is other\r
+     *         than "tcp", "udp", "icmp"\r
+     */\r
+    public static Long getProtocol(NeutronSecurityRule secRule) {\r
+        String protocol = secRule.getSecurityRuleProtocol();\r
+        if (Strings.isNullOrEmpty(protocol)) {\r
+            return null;\r
+        }\r
+        if (NeutronUtils.TCP.equals(protocol)) {\r
+            return IpProtoClassifier.TCP_VALUE;\r
+        }\r
+        if (NeutronUtils.UDP.equals(protocol)) {\r
+            return IpProtoClassifier.UDP_VALUE;\r
+        }\r
+        if (NeutronUtils.ICMP.equals(protocol)) {\r
+            return IpProtoClassifier.ICMP_VALUE;\r
+        }\r
+        throw new IllegalArgumentException("Protocol " + protocol + " is not supported.");\r
+    }\r
+\r
+}\r
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleNameDecoder.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleNameDecoder.java
new file mode 100644 (file)
index 0000000..172d8f7
--- /dev/null
@@ -0,0 +1,100 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
+
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.EtherTypeClassifier;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.IpProtoClassifier;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.L4Classifier;
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
+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.RuleName;
+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 com.google.common.base.Strings;
+
+public class SecRuleNameDecoder {
+
+    final static String MIN_PORT = "_min";
+    final static String MAX_PORT = "_max";
+
+    private SecRuleNameDecoder() {
+        throw new UnsupportedOperationException("Cannot create an instance.");
+    }
+
+    public static SubjectName getSubjectName(NeutronSecurityRule secRule) {
+        RuleName ruleName = SecRuleNameDecoder.getRuleName(secRule);
+        return new SubjectName(ruleName);
+    }
+
+    public static RuleName getRuleName(NeutronSecurityRule secRule) {
+        ClassifierName classifierRefName = SecRuleNameDecoder.getClassifierRefName(secRule);
+        String ruleName = new StringBuilder(MappingUtils.ACTION_ALLOW.getName().getValue())
+            .append(MappingUtils.NAME_DOUBLE_DELIMETER).append(classifierRefName.getValue()).toString();
+        return new RuleName(ruleName);
+    }
+
+    public static ClassifierName getClassifierRefName(NeutronSecurityRule secRule) {
+        Direction direction = SecRuleEntityDecoder.getDirection(secRule);
+        ClassifierName classifierInstanceName = getClassifierInstanceName(secRule);
+        String crName = new StringBuilder().append(direction.name())
+            .append(MappingUtils.NAME_DOUBLE_DELIMETER)
+            .append(classifierInstanceName.getValue())
+            .toString();
+        return new ClassifierName(crName);
+    }
+
+    public static ClassifierName getClassifierInstanceName(NeutronSecurityRule secRule) {
+        StringBuilder keyBuilder = new StringBuilder();
+        Integer portMin = secRule.getSecurityRulePortMin();
+        Integer portMax = secRule.getSecurityRulePortMax();
+        if (portMin != null && portMax != null) {
+            keyBuilder.append(L4Classifier.DEFINITION.getName().getValue());
+            if (portMin.equals(portMax)) {
+                keyBuilder.append(MappingUtils.NAME_DELIMETER)
+                    .append(L4Classifier.DST_PORT_PARAM)
+                    .append(MappingUtils.NAME_VALUE_DELIMETER)
+                    .append(portMin.longValue());
+            } else {
+                keyBuilder.append(MappingUtils.NAME_DELIMETER)
+                    .append(L4Classifier.DST_PORT_RANGE_PARAM)
+                    .append(MIN_PORT)
+                    .append(MappingUtils.NAME_VALUE_DELIMETER)
+                    .append(portMin.longValue())
+                    .append(MAX_PORT)
+                    .append(MappingUtils.NAME_VALUE_DELIMETER)
+                    .append(portMax.longValue());
+            }
+        }
+        String protocol = secRule.getSecurityRuleProtocol();
+        if (!Strings.isNullOrEmpty(protocol)) {
+            if (keyBuilder.length() > 0) {
+                keyBuilder.append(MappingUtils.NAME_DOUBLE_DELIMETER);
+            }
+            keyBuilder.append(IpProtoClassifier.DEFINITION.getName().getValue())
+                .append(MappingUtils.NAME_VALUE_DELIMETER)
+                .append(protocol);
+        }
+        String ethertype = secRule.getSecurityRuleEthertype();
+        if (!Strings.isNullOrEmpty(ethertype)) {
+            if (keyBuilder.length() > 0) {
+                keyBuilder.append(MappingUtils.NAME_DOUBLE_DELIMETER);
+            }
+            keyBuilder.append(EtherTypeClassifier.DEFINITION.getName().getValue())
+                .append(MappingUtils.NAME_VALUE_DELIMETER)
+                .append(ethertype);
+        }
+        return new ClassifierName(keyBuilder.toString());
+    }
+
+    public static ClauseName getClauseName(NeutronSecurityRule secRule) {
+        String remoteIpPrefix = secRule.getSecurityRuleRemoteIpPrefix();
+        SubjectName subjectName = getSubjectName(secRule);
+        if (Strings.isNullOrEmpty(remoteIpPrefix)) {
+            return new ClauseName(subjectName);
+        }
+        return new ClauseName(
+                subjectName.getValue() + MappingUtils.NAME_DOUBLE_DELIMETER + remoteIpPrefix.replace('/', '_'));
+    }
+
+}
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SingleClassifierRule.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SingleClassifierRule.java
new file mode 100644 (file)
index 0000000..56d5528
--- /dev/null
@@ -0,0 +1,47 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
+
+import javax.annotation.concurrent.Immutable;
+
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
+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.tenants.tenant.contract.subject.Rule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
+
+import com.google.common.collect.ImmutableList;
+
+@Immutable
+public class SingleClassifierRule {
+
+    private final ClassifierInstance classifierInstance;
+    private final ClassifierRef classifierRef;
+    private final Rule rule;
+
+    public SingleClassifierRule(NeutronSecurityRule secRule, int ruleOrder) {
+        classifierInstance = SecRuleEntityDecoder.getClassifierInstance(secRule);
+        classifierRef = SecRuleEntityDecoder.getClassifierRef(secRule);
+        rule = createRule(ruleOrder, secRule);
+    }
+
+    private Rule createRule(int order, NeutronSecurityRule secRule) {
+        return new RuleBuilder().setName(SecRuleNameDecoder.getRuleName(secRule))
+            .setOrder(order)
+            .setActionRef(MappingUtils.ACTION_REF_ALLOW)
+            .setClassifierRef(ImmutableList.of(classifierRef))
+            .build();
+    }
+
+    public ClassifierInstance getClassifierInstance() {
+        return classifierInstance;
+    }
+
+    public ClassifierRef getClassifierRef() {
+        return classifierRef;
+    }
+
+    public Rule getRule() {
+        return rule;
+    }
+
+}
diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SingleRuleContract.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SingleRuleContract.java
new file mode 100644 (file)
index 0000000..aa9763b
--- /dev/null
@@ -0,0 +1,69 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.SubjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
+
+import com.google.common.collect.ImmutableList;
+
+@Immutable
+public class SingleRuleContract {
+
+    private final SingleClassifierRule singleClassifierRule;
+    private final Rule rule;
+    private final Subject subject;
+    private final Clause clause;
+    private final Contract contract;
+
+    public SingleRuleContract(NeutronSecurityRule secRule, int subjectAndRuleOrder, @Nullable Description contractDescription) {
+        this(secRule, new SingleClassifierRule(secRule, subjectAndRuleOrder), subjectAndRuleOrder, contractDescription);
+    }
+
+    public SingleRuleContract(NeutronSecurityRule secRule, SingleClassifierRule singleClassifierRule,
+            int subjectOrder, @Nullable Description contractDescription) {
+        checkNotNull(secRule);
+        this.singleClassifierRule = checkNotNull(singleClassifierRule);
+        this.rule = singleClassifierRule.getRule();
+        this.subject = new SubjectBuilder().setName(SecRuleNameDecoder.getSubjectName(secRule))
+            .setOrder(subjectOrder)
+            .setRule(ImmutableList.of(rule))
+            .build();
+        this.clause = SecRuleEntityDecoder.getClause(secRule);
+        this.contract = new ContractBuilder().setId(SecRuleEntityDecoder.getContractId(secRule))
+            .setSubject(ImmutableList.of(subject))
+            .setClause(ImmutableList.of(clause))
+            .setDescription(contractDescription)
+            .build();
+    }
+
+    public SingleClassifierRule getSingleClassifierRule() {
+        return singleClassifierRule;
+    }
+
+    public Rule getRule() {
+        return rule;
+    }
+
+    public Subject getSubject() {
+        return subject;
+    }
+
+    public Clause getClause() {
+        return clause;
+    }
+
+    public Contract getContract() {
+        return contract;
+    }
+
+}
index 100a1661f3dadca1ff79b5e2a8e9759e1133bc2a..72b9618c9c7c6d816b2294f1fb05edc73d05f7a8 100644 (file)
@@ -15,6 +15,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRefBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
@@ -22,23 +24,25 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstanceBuilder;
 
 import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
 
 public final class MappingUtils {
 
-    public static final String NEUTRON_RULE__ = "neutron_rule__";
-    public static final String NEUTRON_NETWORK__ = "neutron_network__";
-    public static final String NEUTRON_ROUTER__ = "neutron_router__";
-    public static final String NEUTRON_EXTERNAL__ = "neutron_external_network__";
-    public static final String NEUTRON_GROUP__ = "neutron_group__";
+    public static final String NEUTRON_ROUTER = "neutron_router-";
+    public static final String NEUTRON_EXTERNAL = "neutron_external_network-";
+    public static final String NEUTRON_GROUP = "neutron_group-";
     public static final ActionInstance ACTION_ALLOW = new ActionInstanceBuilder().setName(
-            new ActionName(NEUTRON_RULE__ + "allow"))
+            new ActionName("Allow"))
         .setActionDefinitionId(AllowAction.DEFINITION.getId())
         .build();
-    public static final EndpointGroupId EPG_ANY_ID = new EndpointGroupId("aaaec0ce-dd5a-11e4-b9d6-1681e6b88ec1");
-    public static final EndpointGroupId EPG_DHCP_ID = new EndpointGroupId("ddd6cfe6-dfe5-11e4-8a00-1681e6b88ec1");
-    public static final EndpointGroupId EPG_ROUTER_ID = new EndpointGroupId("1118172e-cd84-4933-a35f-749f9a651de9");
+    public static final List<ActionRef> ACTION_REF_ALLOW =
+            ImmutableList.of(new ActionRefBuilder().setName(ACTION_ALLOW.getName()).setOrder(0).build());
     public static final EndpointGroupId EPG_EXTERNAL_ID = new EndpointGroupId("eeeaa3a2-e9ba-44e0-a462-bea923d30e38");
 
+    public static final String NAME_VALUE_DELIMETER = "-";
+    public static final String NAME_DELIMETER = "_";
+    public static final String NAME_DOUBLE_DELIMETER = "__";
+
     private MappingUtils() {
         throw new UnsupportedOperationException("Cannot create an instance.");
     }
index 1247935d6dd084aa13322ce6d3323d793c37c44d..423a2bda6a654afbf1b3f916c6d1cb79536a2966 100644 (file)
@@ -1,18 +1,12 @@
 package org.opendaylight.groupbasedpolicy.neutron.mapper.util;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.Mappings;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.EndpointGroupPairToContractMappings;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.NetworkMappings;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.endpoint.group.pair.to.contract.mappings.EndpointGroupPairToContractMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.endpoint.group.pair.to.contract.mappings.EndpointGroupPairToContractMappingKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMapping;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMappingKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-
 public class NeutronMapperIidFactory {
 
     public static InstanceIdentifier<NetworkMapping> networkMappingIid(UniqueId networkId) {
@@ -22,13 +16,4 @@ public class NeutronMapperIidFactory {
             .build();
     }
 
-    public static InstanceIdentifier<EndpointGroupPairToContractMapping> endpointGroupPairToContractMappingIid(
-            EndpointGroupId providerEpg, TenantId providerTenantId, EndpointGroupId consumerEpg, TenantId consumerTenantId) {
-        return InstanceIdentifier.builder(Mappings.class)
-            .child(EndpointGroupPairToContractMappings.class)
-            .child(EndpointGroupPairToContractMapping.class,
-                    new EndpointGroupPairToContractMappingKey(consumerEpg, consumerTenantId, providerEpg, providerTenantId))
-            .build();
-    }
-
 }
index 8f30ebbf28ec523128dcf8c308020cc03adfec67..245baeb42594f923a89c160311755784634886e0 100644 (file)
@@ -10,12 +10,8 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.util;
 import static com.google.common.base.Preconditions.checkArgument;
 
 import java.net.Inet4Address;
-import java.net.Inet6Address;
 import java.net.InetAddress;
-import java.net.UnknownHostException;
 
-import org.apache.commons.net.util.SubnetUtils;
-import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
@@ -23,15 +19,15 @@ 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.rev100924.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
 
+import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import com.google.common.net.InetAddresses;
 
-/**
- * @author Martin Sunal
- */
 public class Utils {
 
-    private Utils() {}
+    private Utils() {
+        throw new UnsupportedOperationException("Cannot create an instance.");
+    }
 
     /**
      * This implementation does not use nameservice lookups (e.g. no DNS).
@@ -69,6 +65,7 @@ public class Utils {
     }
 
     public static String getStringIpPrefix(IpPrefix ipPrefix) {
+        Preconditions.checkNotNull(ipPrefix);
         if (ipPrefix.getIpv4Prefix() != null) {
             return ipPrefix.getIpv4Prefix().getValue();
         }
@@ -82,48 +79,6 @@ public class Utils {
         return ipAddress.getIpv6Address().getValue();
     }
 
-    public static boolean isHostInIpPrefix(IpAddress host, IpPrefix ipPrefix) {
-        String ipAddress = "";
-        int ipVersion = 0;
-        if (host.getIpv4Address() != null) {
-            ipAddress = host.getIpv4Address().getValue();
-            ipVersion = 4;
-        } else {
-            ipAddress = host.getIpv6Address().getValue();
-            ipVersion = 6;
-        }
-        String cidr = getStringIpPrefix(ipPrefix);
-
-        if (ipVersion == 4) {
-            try {
-                SubnetUtils util = new SubnetUtils(cidr);
-                SubnetInfo info = util.getInfo();
-                return info.isInRange(ipAddress);
-            } catch (IllegalArgumentException e) {
-                return false;
-            }
-        }
-
-        if (ipVersion == 6) {
-            String[] parts = cidr.split("/");
-            try {
-                int length = Integer.parseInt(parts[1]);
-                byte[] cidrBytes = ((Inet6Address) InetAddress.getByName(parts[0])).getAddress();
-                byte[] ipBytes = ((Inet6Address) InetAddress.getByName(ipAddress)).getAddress();
-                int i;
-                for (i = 0; i < length; i++) { // offset is to ensure proper comparison
-                    if ((((cidrBytes[i / 8]) & 0x000000FF) & (1 << (7 - (i % 8)))) != (((ipBytes[i / 8]) & 0x000000FF) & (1 << (7 - (i % 8))))) {
-                        return false;
-                    }
-                }
-                return true;
-            } catch (UnknownHostException e) {
-                return false;
-            }
-        }
-        return false;
-    }
-
     public static String normalizeUuid(String string) {
         return string.replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)",
                 "$1-$2-$3-$4-$5");
index de626e18e6d4344195cb0216003ce5ad3d8f9801..e972b38ba113669dc93e2de0ff791d76bc31e629 100644 (file)
@@ -25,27 +25,6 @@ module neutron-mapper {
         }
     }
 
-    grouping endpoint-group-pair-fields {
-        leaf provider-tenant-id {
-            type gbp-common:tenant-id;
-        }
-        leaf consumer-tenant-id {
-            type gbp-common:tenant-id;
-        }
-        leaf contract-tenant-id {
-            type gbp-common:tenant-id;
-        }
-        leaf provider-epg-id {
-            type gbp-common:endpoint-group-id;
-        }
-        leaf consumer-epg-id {
-            type gbp-common:endpoint-group-id;
-        }
-        leaf contract-id {
-            type gbp-common:contract-id;
-        }
-    }
-
     container mappings {
         config false;
         container network-mappings {
@@ -65,12 +44,6 @@ module neutron-mapper {
                 }
             }
         }
-        container endpoint-group-pair-to-contract-mappings {
-            list endpoint-group-pair-to-contract-mapping {
-                key "provider-tenant-id provider-epg-id consumer-tenant-id consumer-epg-id";
-                uses endpoint-group-pair-fields;
-            }
-        }
     }
 
 }
\ No newline at end of file
diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareDataStoreTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareDataStoreTest.java
new file mode 100644 (file)
index 0000000..9ab7beb
--- /dev/null
@@ -0,0 +1,415 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Set;
+
+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.mapping.group.SecGroupDao;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.test.GbpDataBrokerTest;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.neutron.spi.NeutronSecurityGroup;
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+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.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.tenants.Tenant;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * END 2 END TESTING - inputs are Neutron entities and expected outputs are GBP entities in
+ * datastore
+ */
+public class NeutronSecurityRuleAwareDataStoreTest extends GbpDataBrokerTest {
+
+    @Test
+    public final void testAddNeutronSecurityRule_rulesWithRemoteIpPrefix() throws Exception {
+        String tenant = "ad4c6c25-2424-4ad3-97ee-f9691ce03645";
+        String goldSecGrp = "fe40e28f-ad6a-4a2d-b12a-47510876344a";
+        NeutronSecurityRule goldInIpv4 = createSecRuleWithEtherType("166aedab-fdf5-4788-9e36-2b00b5f8722f", tenant,
+                NeutronUtils.IPv4, NeutronUtils.INGRESS, goldSecGrp, null);
+        NeutronSecurityRule goldOutIpv4 = createSecRuleWithEtherType("dabfd4da-af89-45dd-85f8-181768c1b4c9", tenant,
+                NeutronUtils.IPv4, NeutronUtils.EGRESS, goldSecGrp, null);
+        String serverSecGrp = "71cf4fe5-b146-409e-8151-cd921298ce32";
+        NeutronSecurityRule serverIn80Tcp10_1_1_0 = createSecRuleWithEtherType("9dbb533d-d9b2-4dc9-bae7-ee60c8df184d",
+                tenant, NeutronUtils.IPv4, NeutronUtils.INGRESS, serverSecGrp, null);
+        serverIn80Tcp10_1_1_0.setSecurityRuleProtocol(NeutronUtils.TCP);
+        serverIn80Tcp10_1_1_0.setSecurityRulePortMin(80);
+        serverIn80Tcp10_1_1_0.setSecurityRulePortMax(80);
+        serverIn80Tcp10_1_1_0.setSecurityRuleRemoteIpPrefix("10.1.1.0/24");
+        NeutronSecurityRule serverInIp20_1_1_0 = createSecRuleWithEtherType("adf7e558-de47-4f9e-a9b8-96e19db5d1ac",
+                tenant, NeutronUtils.IPv4, NeutronUtils.INGRESS, serverSecGrp, null);
+        serverInIp20_1_1_0.setSecurityRuleRemoteIpPrefix("20.1.1.0/24");
+        NeutronSecurityRule serverOutIpv4 = createSecRuleWithEtherType("8b9c48d3-44a8-46be-be35-6f3237d98071", tenant,
+                NeutronUtils.IPv4, NeutronUtils.EGRESS, serverSecGrp, null);
+        DataBroker dataBroker = getDataBroker();
+        SecRuleDao secRuleDao = new SecRuleDao();
+        SecGroupDao secGroupDao = new SecGroupDao();
+        secGroupDao.addSecGroup(createSecGroup(goldSecGrp, tenant));
+        secGroupDao.addSecGroup(createSecGroup(serverSecGrp, tenant));
+        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, secRuleDao, secGroupDao);
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        ruleAware.addNeutronSecurityRule(goldInIpv4, rwTx);
+        ruleAware.addNeutronSecurityRule(goldOutIpv4, rwTx);
+        ruleAware.addNeutronSecurityRule(serverIn80Tcp10_1_1_0, rwTx);
+        ruleAware.addNeutronSecurityRule(serverInIp20_1_1_0, rwTx);
+        ruleAware.addNeutronSecurityRule(serverOutIpv4, rwTx);
+        TenantId tenantId = new TenantId(tenant);
+        Optional<Tenant> potentialTenant =
+                rwTx.read(LogicalDatastoreType.CONFIGURATION, IidFactory.tenantIid(tenantId)).get();
+        assertTrue(potentialTenant.isPresent());
+        Optional<Contract> potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(goldInIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        Contract contract = potentialContract.get();
+        assertContract(contract, goldInIpv4);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(goldOutIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, goldOutIpv4);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(serverOutIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, serverOutIpv4);
+        potentialContract = rwTx
+            .read(LogicalDatastoreType.CONFIGURATION,
+                    IidFactory.contractIid(tenantId, new ContractId(serverIn80Tcp10_1_1_0.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContractWithEic(contract, serverIn80Tcp10_1_1_0);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(serverInIp20_1_1_0.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContractWithEic(contract, serverInIp20_1_1_0);
+        Optional<EndpointGroup> potentialEpg = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.endpointGroupIid(tenantId, new EndpointGroupId(goldSecGrp)))
+            .get();
+        assertTrue(potentialEpg.isPresent());
+        EndpointGroup epg = potentialEpg.get();
+        assertConsumerNamedSelectors(epg,
+                ImmutableSet.of(new ContractId(goldInIpv4.getSecurityRuleUUID()),
+                        new ContractId(goldOutIpv4.getSecurityRuleUUID()),
+                        new ContractId(serverIn80Tcp10_1_1_0.getSecurityRuleUUID()),
+                        new ContractId(serverInIp20_1_1_0.getSecurityRuleUUID()),
+                        new ContractId(serverOutIpv4.getSecurityRuleUUID())));
+        potentialEpg = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.endpointGroupIid(tenantId, new EndpointGroupId(serverSecGrp)))
+            .get();
+        assertTrue(potentialEpg.isPresent());
+        epg = potentialEpg.get();
+        assertConsumerNamedSelectors(epg,
+                ImmutableSet.of(new ContractId(serverIn80Tcp10_1_1_0.getSecurityRuleUUID()),
+                        new ContractId(serverInIp20_1_1_0.getSecurityRuleUUID()),
+                        new ContractId(goldInIpv4.getSecurityRuleUUID())));
+    }
+
+    @Test
+    public final void testAddNeutronSecurityRule_rulesWithoutRemote() throws Exception {
+        String tenant = "ad4c6c25-2424-4ad3-97ee-f9691ce03645";
+        String goldSecGrp = "fe40e28f-ad6a-4a2d-b12a-47510876344a";
+        NeutronSecurityRule goldInIpv4 = createSecRuleWithEtherType("166aedab-fdf5-4788-9e36-2b00b5f8722f", tenant,
+                NeutronUtils.IPv4, NeutronUtils.INGRESS, goldSecGrp, null);
+        NeutronSecurityRule goldOutIpv4 = createSecRuleWithEtherType("dabfd4da-af89-45dd-85f8-181768c1b4c9", tenant,
+                NeutronUtils.IPv4, NeutronUtils.EGRESS, goldSecGrp, null);
+        String serverSecGrp = "71cf4fe5-b146-409e-8151-cd921298ce32";
+        NeutronSecurityRule serverOutIpv4 = createSecRuleWithEtherType("8b9c48d3-44a8-46be-be35-6f3237d98071", tenant,
+                NeutronUtils.IPv4, NeutronUtils.EGRESS, serverSecGrp, null);
+        NeutronSecurityRule serverInIpv4 = createSecRuleWithEtherType("adf7e558-de47-4f9e-a9b8-96e19db5d1ac", tenant,
+                NeutronUtils.IPv4, NeutronUtils.INGRESS, serverSecGrp, null);
+        DataBroker dataBroker = getDataBroker();
+        SecRuleDao secRuleDao = new SecRuleDao();
+        SecGroupDao secGroupDao = new SecGroupDao();
+        secGroupDao.addSecGroup(createSecGroup(goldSecGrp, tenant));
+        secGroupDao.addSecGroup(createSecGroup(serverSecGrp, tenant));
+        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, secRuleDao, secGroupDao);
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        ruleAware.addNeutronSecurityRule(goldInIpv4, rwTx);
+        ruleAware.addNeutronSecurityRule(goldOutIpv4, rwTx);
+        ruleAware.addNeutronSecurityRule(serverOutIpv4, rwTx);
+        ruleAware.addNeutronSecurityRule(serverInIpv4, rwTx);
+        TenantId tenantId = new TenantId(tenant);
+        Optional<Contract> potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(goldInIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        Contract contract = potentialContract.get();
+        assertContract(contract, goldInIpv4);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(goldOutIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, goldOutIpv4);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(serverOutIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, serverOutIpv4);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(serverInIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, serverInIpv4);
+        Optional<EndpointGroup> potentialEpg = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.endpointGroupIid(tenantId, new EndpointGroupId(goldSecGrp)))
+            .get();
+        assertTrue(potentialEpg.isPresent());
+        EndpointGroup epg = potentialEpg.get();
+        assertConsumerNamedSelectors(epg, ImmutableSet.of(new ContractId(goldInIpv4.getSecurityRuleUUID()),
+                new ContractId(goldOutIpv4.getSecurityRuleUUID()), new ContractId(serverOutIpv4.getSecurityRuleUUID()),
+                new ContractId(serverInIpv4.getSecurityRuleUUID())));
+        potentialEpg = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.endpointGroupIid(tenantId, new EndpointGroupId(serverSecGrp)))
+            .get();
+        assertTrue(potentialEpg.isPresent());
+        assertConsumerNamedSelectors(epg, ImmutableSet.of(new ContractId(goldInIpv4.getSecurityRuleUUID()),
+                new ContractId(goldOutIpv4.getSecurityRuleUUID()), new ContractId(serverOutIpv4.getSecurityRuleUUID()),
+                new ContractId(serverInIpv4.getSecurityRuleUUID())));
+    }
+
+    @Test
+    public final void testAddNeutronSecurityRule_asymmetricRulesWithoutRemote() throws Exception {
+        String tenant = "ad4c6c25-2424-4ad3-97ee-f9691ce03645";
+        String goldSecGrp = "fe40e28f-ad6a-4a2d-b12a-47510876344a";
+        NeutronSecurityRule goldInIpv4 = createSecRuleWithEtherType("166aedab-fdf5-4788-9e36-2b00b5f8722f", tenant,
+                NeutronUtils.IPv4, NeutronUtils.INGRESS, goldSecGrp, null);
+        NeutronSecurityRule goldOutIpv4 = createSecRuleWithEtherType("dabfd4da-af89-45dd-85f8-181768c1b4c9", tenant,
+                NeutronUtils.IPv4, NeutronUtils.EGRESS, goldSecGrp, null);
+        String serverSecGrp = "71cf4fe5-b146-409e-8151-cd921298ce32";
+        NeutronSecurityRule serverOutIpv4 = createSecRuleWithEtherType("8b9c48d3-44a8-46be-be35-6f3237d98071", tenant,
+                NeutronUtils.IPv4, NeutronUtils.EGRESS, serverSecGrp, null);
+        NeutronSecurityRule serverIn80TcpIpv4 = createSecRuleWithEtherType("adf7e558-de47-4f9e-a9b8-96e19db5d1ac",
+                tenant, NeutronUtils.IPv4, NeutronUtils.INGRESS, serverSecGrp, null);
+        serverIn80TcpIpv4.setSecurityRuleProtocol(NeutronUtils.TCP);
+        serverIn80TcpIpv4.setSecurityRulePortMin(80);
+        serverIn80TcpIpv4.setSecurityRulePortMax(80);
+        DataBroker dataBroker = getDataBroker();
+        SecRuleDao secRuleDao = new SecRuleDao();
+        SecGroupDao secGroupDao = new SecGroupDao();
+        secGroupDao.addSecGroup(createSecGroup(goldSecGrp, tenant));
+        secGroupDao.addSecGroup(createSecGroup(serverSecGrp, tenant));
+        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, secRuleDao, secGroupDao);
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        ruleAware.addNeutronSecurityRule(goldInIpv4, rwTx);
+        ruleAware.addNeutronSecurityRule(goldOutIpv4, rwTx);
+        ruleAware.addNeutronSecurityRule(serverOutIpv4, rwTx);
+        ruleAware.addNeutronSecurityRule(serverIn80TcpIpv4, rwTx);
+        TenantId tenantId = new TenantId(tenant);
+        Optional<Contract> potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(goldInIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        Contract contract = potentialContract.get();
+        assertContract(contract, goldInIpv4);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(goldOutIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, goldOutIpv4);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(serverOutIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, serverOutIpv4);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(serverIn80TcpIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, serverIn80TcpIpv4);
+        Optional<EndpointGroup> potentialEpg = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.endpointGroupIid(tenantId, new EndpointGroupId(goldSecGrp)))
+            .get();
+        assertTrue(potentialEpg.isPresent());
+        EndpointGroup epg = potentialEpg.get();
+        assertConsumerNamedSelectors(epg, ImmutableSet.of(new ContractId(goldInIpv4.getSecurityRuleUUID()),
+                new ContractId(goldOutIpv4.getSecurityRuleUUID()), new ContractId(serverOutIpv4.getSecurityRuleUUID()),
+                new ContractId(serverIn80TcpIpv4.getSecurityRuleUUID())));
+        potentialEpg = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.endpointGroupIid(tenantId, new EndpointGroupId(serverSecGrp)))
+            .get();
+        assertTrue(potentialEpg.isPresent());
+        epg = potentialEpg.get();
+        assertConsumerNamedSelectors(epg, ImmutableSet.of(new ContractId(goldInIpv4.getSecurityRuleUUID()),
+                new ContractId(serverIn80TcpIpv4.getSecurityRuleUUID())));
+    }
+
+    @Test
+    public final void testAddNeutronSecurityRule_defaultSecGrp() throws Exception {
+        String tenant = "111aaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa";
+        String defaultSecGrp = "111fffff-ffff-ffff-ffff-ffffffffffff";
+        NeutronSecurityRule defaultInIpv4Default = createSecRuleWithEtherType("111ccccc-111c-cccc-cccc-cccccccccccc",
+                tenant, NeutronUtils.IPv4, NeutronUtils.INGRESS, defaultSecGrp, defaultSecGrp);
+        NeutronSecurityRule defaultInIpv6Default = createSecRuleWithEtherType("222ccccc-111c-cccc-cccc-cccccccccccc",
+                tenant, NeutronUtils.IPv6, NeutronUtils.INGRESS, defaultSecGrp, defaultSecGrp);
+        NeutronSecurityRule defaultOutIpv4 = createSecRuleWithEtherType("333ccccc-111c-cccc-cccc-cccccccccccc", tenant,
+                NeutronUtils.IPv4, NeutronUtils.EGRESS, defaultSecGrp, null);
+        NeutronSecurityRule defaultOutIpv6 = createSecRuleWithEtherType("444ccccc-111c-cccc-cccc-cccccccccccc", tenant,
+                NeutronUtils.IPv6, NeutronUtils.EGRESS, defaultSecGrp, null);
+        DataBroker dataBroker = getDataBroker();
+        SecRuleDao secRuleDao = new SecRuleDao();
+        SecGroupDao secGroupDao = new SecGroupDao();
+        secGroupDao.addSecGroup(createSecGroup(defaultSecGrp, tenant));
+        NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, secRuleDao, secGroupDao);
+        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
+        ruleAware.addNeutronSecurityRule(defaultInIpv4Default, rwTx);
+        ruleAware.addNeutronSecurityRule(defaultInIpv6Default, rwTx);
+        ruleAware.addNeutronSecurityRule(defaultOutIpv4, rwTx);
+        ruleAware.addNeutronSecurityRule(defaultOutIpv6, rwTx);
+        TenantId tenantId = new TenantId(tenant);
+        Optional<Contract> potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(defaultInIpv4Default.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        Contract contract = potentialContract.get();
+        assertContract(contract, defaultInIpv4Default);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(defaultInIpv6Default.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, defaultInIpv6Default);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(defaultOutIpv4.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, defaultOutIpv4);
+        potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.contractIid(tenantId, new ContractId(defaultOutIpv6.getSecurityRuleUUID())))
+            .get();
+        assertTrue(potentialContract.isPresent());
+        contract = potentialContract.get();
+        assertContract(contract, defaultOutIpv6);
+    }
+
+    private final void assertContractWithEic(Contract contract, NeutronSecurityRule secRule) {
+        assertEquals(new ContractId(secRule.getSecurityRuleUUID()), contract.getId());
+        assertNull(contract.getQuality());
+        assertNull(contract.getTarget());
+        assertOneClauseWithEicWithOneSubject(contract, secRule);
+        assertOneSubjectWithOneRule(contract, secRule);
+    }
+
+    private final void assertOneClauseWithEicWithOneSubject(Contract contract, NeutronSecurityRule secRule) {
+        Clause clause = assertOneItem(contract.getClause());
+        assertNull(clause.getAnyMatchers());
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(secRule.getSecurityRuleRemoteIpPrefix()));
+        IpPrefix expectedIpPrefix = Utils.createIpPrefix(secRule.getSecurityRuleRemoteIpPrefix());
+        assertNotNull(clause.getConsumerMatchers());
+        IpPrefix ipPrefix = clause.getConsumerMatchers()
+            .getEndpointIdentificationConstraints()
+            .getL3EndpointIdentificationConstraints()
+            .getPrefixConstraint()
+            .get(0)
+            .getIpPrefix();
+        assertEquals(expectedIpPrefix, ipPrefix);
+        SubjectName subjectRef = assertOneItem(clause.getSubjectRefs());
+        assertEquals(SecRuleNameDecoder.getSubjectName(secRule), subjectRef);
+    }
+
+    private final void assertContract(Contract contract, NeutronSecurityRule secRule) {
+        assertEquals(new ContractId(secRule.getSecurityRuleUUID()), contract.getId());
+        assertNull(contract.getQuality());
+        assertNull(contract.getTarget());
+        assertOneClauseWithOneSubject(contract, secRule);
+        assertOneSubjectWithOneRule(contract, secRule);
+    }
+
+    private final void assertOneClauseWithOneSubject(Contract contract, NeutronSecurityRule secRule) {
+        Clause clause = assertOneItem(contract.getClause());
+        assertNull(clause.getAnyMatchers());
+        assertNull(clause.getConsumerMatchers());
+        assertNull(clause.getProviderMatchers());
+        SubjectName subjectRef = assertOneItem(clause.getSubjectRefs());
+        assertEquals(SecRuleNameDecoder.getSubjectName(secRule), subjectRef);
+    }
+
+    private final void assertOneSubjectWithOneRule(Contract contract, NeutronSecurityRule secRule) {
+        Subject subject = assertOneItem(contract.getSubject());
+        assertEquals(SecRuleNameDecoder.getSubjectName(secRule), subject.getName());
+        Rule rule = assertOneItem(subject.getRule());
+        assertEquals(SecRuleNameDecoder.getRuleName(secRule), rule.getName());
+        ActionRef actionRef = assertOneItem(rule.getActionRef());
+        assertEquals(MappingUtils.ACTION_ALLOW.getName(), actionRef.getName());
+        ClassifierRef classifierRef = assertOneItem(rule.getClassifierRef());
+        assertEquals(SecRuleNameDecoder.getClassifierRefName(secRule), classifierRef.getName());
+        assertEquals(SecRuleNameDecoder.getClassifierInstanceName(secRule), classifierRef.getInstanceName());
+        assertEquals(SecRuleEntityDecoder.getDirection(secRule), classifierRef.getDirection());
+    }
+
+    private final <T> T assertOneItem(Collection<T> c) {
+        assertNotNull(c);
+        assertTrue(c.size() == 1);
+        return c.iterator().next();
+    }
+
+    private final void assertConsumerNamedSelectors(EndpointGroup epg, Set<ContractId> expectedContracts) {
+        Preconditions.checkNotNull(expectedContracts);
+        assertNotNull(epg.getConsumerNamedSelector());
+        int numberOfContracts = 0;
+        for (ConsumerNamedSelector cns : epg.getConsumerNamedSelector()) {
+            assertNotNull(cns.getContract());
+            numberOfContracts += cns.getContract().size();
+            for (ContractId contractId : cns.getContract()) {
+                assertTrue(expectedContracts.contains(contractId));
+            }
+        }
+        assertEquals(expectedContracts.size(), numberOfContracts);
+    }
+
+    private final NeutronSecurityRule createSecRuleWithEtherType(String id, String tenant, String etherType,
+            String direction, String ownerGroupId, String remoteGroupId) {
+        NeutronSecurityRule secRule = new NeutronSecurityRule();
+        secRule.setSecurityRuleUUID(id);
+        secRule.setSecurityRuleTenantID(tenant);
+        secRule.setSecurityRuleEthertype(etherType);
+        secRule.setSecurityRuleDirection(direction);
+        secRule.setSecurityRuleGroupID(ownerGroupId);
+        secRule.setSecurityRemoteGroupID(remoteGroupId);
+        return secRule;
+    }
+
+    private final NeutronSecurityGroup createSecGroup(String id, String tenant) {
+        NeutronSecurityGroup secGrp = new NeutronSecurityGroup();
+        secGrp.setSecurityGroupUUID(id);
+        secGrp.setSecurityGroupTenantID(tenant);
+        return secGrp;
+    }
+}
diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareTest.java
new file mode 100644 (file)
index 0000000..b8539f1
--- /dev/null
@@ -0,0 +1,31 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
+
+public class NeutronSecurityRuleAwareTest {
+
+    @Test
+    public final void testIsDirectionOpposite_InIn() {
+        assertFalse(NeutronSecurityRuleAware.isDirectionOpposite(Direction.In, Direction.In));
+    }
+
+    @Test
+    public final void testIsDirectionOpposite_OutOut() {
+        assertFalse(NeutronSecurityRuleAware.isDirectionOpposite(Direction.Out, Direction.Out));
+    }
+
+    @Test
+    public final void testIsDirectionOpposite_InOut() {
+        assertTrue(NeutronSecurityRuleAware.isDirectionOpposite(Direction.In, Direction.Out));
+    }
+
+    @Test
+    public final void testIsDirectionOpposite_OutIn() {
+        assertTrue(NeutronSecurityRuleAware.isDirectionOpposite(Direction.Out, Direction.In));
+    }
+
+}
diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleDecoderTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/SecRuleDecoderTest.java
new file mode 100644 (file)
index 0000000..6064755
--- /dev/null
@@ -0,0 +1,759 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.SecRuleEntityDecoder;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.SecRuleNameDecoder;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.EtherTypeClassifier;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.IpProtoClassifier;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.L4Classifier;
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+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.ParameterName;
+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.classifier.refs.ClassifierRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraints;
+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.l3.endpoint.identification.constraints.PrefixConstraint;
+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.parameter.value.RangeValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
+
+public class SecRuleDecoderTest {
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    private NeutronSecurityRule secRule;
+
+    @Before
+    public void setUp() throws Exception {
+        secRule = new NeutronSecurityRule();
+    }
+
+    @Test
+    public final void testGetTenantId_lowercaseUuidTenantID() {
+        secRule.setSecurityRuleTenantID("01234567-abcd-ef01-0123-0123456789ab");
+        Assert.assertEquals("01234567-abcd-ef01-0123-0123456789ab", SecRuleEntityDecoder.getTenantId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetTenantId_uppercaseUuidTenantID() {
+        secRule.setSecurityRuleTenantID("01234567-ABCD-EF01-0123-0123456789AB");
+        Assert.assertEquals("01234567-ABCD-EF01-0123-0123456789AB", SecRuleEntityDecoder.getTenantId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetTenantId_mixUuidTenantID() {
+        secRule.setSecurityRuleTenantID("01234567-ABCD-ef01-0123-0123456789Ab");
+        Assert.assertEquals("01234567-ABCD-ef01-0123-0123456789Ab", SecRuleEntityDecoder.getTenantId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetTenantId_noSlashLowercaseUuidTenantID() {
+        secRule.setSecurityRuleTenantID("01234567abcdef0101230123456789ab");
+        Assert.assertEquals("01234567-abcd-ef01-0123-0123456789ab", SecRuleEntityDecoder.getTenantId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetTenantId_noSlashUppercaseUuidTenantID() {
+        secRule.setSecurityRuleTenantID("01234567ABCDEF0101230123456789AB");
+        Assert.assertEquals("01234567-ABCD-EF01-0123-0123456789AB", SecRuleEntityDecoder.getTenantId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetTenantId_noSlashMixUuidTenantID() {
+        secRule.setSecurityRuleTenantID("01234567ABCDef0101230123456789Ab");
+        Assert.assertEquals("01234567-ABCD-ef01-0123-0123456789Ab", SecRuleEntityDecoder.getTenantId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetTenantId_emptyUuidTenantID() {
+        secRule.setSecurityRuleTenantID("");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getTenantId(secRule);
+    }
+
+    @Test
+    public final void testGetTenantId_badLengthUuidTenantID() {
+        secRule.setSecurityRuleTenantID("abc");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getTenantId(secRule);
+    }
+
+    @Test
+    public final void testGetTenantId_badContentUuidTenantID() {
+        secRule.setSecurityRuleTenantID("xyz34567-abcd-ef01-0123-0123456789ab");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getTenantId(secRule);
+    }
+
+    @Test
+    public final void testGetTenantId_nullUuidTenantID() {
+        secRule.setSecurityRuleTenantID(null);
+        thrown.expect(NullPointerException.class);
+        SecRuleEntityDecoder.getTenantId(secRule);
+    }
+
+    @Test
+    public final void testGetProviderEpgId_lowercaseUuidGroupID() {
+        secRule.setSecurityRuleGroupID("01234567-abcd-ef01-0123-0123456789ab");
+        Assert.assertEquals("01234567-abcd-ef01-0123-0123456789ab",
+                SecRuleEntityDecoder.getProviderEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetProviderEpgId_uppercaseUuidGroupID() {
+        secRule.setSecurityRuleGroupID("01234567-ABCD-EF01-0123-0123456789AB");
+        Assert.assertEquals("01234567-ABCD-EF01-0123-0123456789AB",
+                SecRuleEntityDecoder.getProviderEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetProviderEpgId_mixUuidGroupID() {
+        secRule.setSecurityRuleGroupID("01234567-ABCD-ef01-0123-0123456789Ab");
+        Assert.assertEquals("01234567-ABCD-ef01-0123-0123456789Ab",
+                SecRuleEntityDecoder.getProviderEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetProviderEpgId_noSlashLowercaseUuidGroupID() {
+        secRule.setSecurityRuleGroupID("01234567abcdef0101230123456789ab");
+        Assert.assertEquals("01234567-abcd-ef01-0123-0123456789ab",
+                SecRuleEntityDecoder.getProviderEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetProviderEpgId_noSlashUppercaseUuidGroupID() {
+        secRule.setSecurityRuleGroupID("01234567ABCDEF0101230123456789AB");
+        Assert.assertEquals("01234567-ABCD-EF01-0123-0123456789AB",
+                SecRuleEntityDecoder.getProviderEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetProviderEpgId_noSlashMixUuidGroupID() {
+        secRule.setSecurityRuleGroupID("01234567ABCDef0101230123456789Ab");
+        Assert.assertEquals("01234567-ABCD-ef01-0123-0123456789Ab",
+                SecRuleEntityDecoder.getProviderEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetProviderEpgId_emptyUuidGroupID() {
+        secRule.setSecurityRuleGroupID("");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getProviderEpgId(secRule);
+    }
+
+    @Test
+    public final void testGetProviderEpgId_badLengthUuidGroupID() {
+        secRule.setSecurityRuleGroupID("abcdxy");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getProviderEpgId(secRule);
+    }
+
+    @Test
+    public final void testGetProviderEpgId_badContentUuidGroupID() {
+        secRule.setSecurityRuleGroupID("xyz34567-abcd-ef01-0123-0123456789ab");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getProviderEpgId(secRule);
+    }
+
+    @Test
+    public final void testGetProviderEpgId_nullUuidGroupID() {
+        secRule.setSecurityRuleGroupID(null);
+        thrown.expect(NullPointerException.class);
+        SecRuleEntityDecoder.getProviderEpgId(secRule);
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_lowercaseUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID("01234567-abcd-ef01-0123-0123456789ab");
+        Assert.assertEquals("01234567-abcd-ef01-0123-0123456789ab",
+                SecRuleEntityDecoder.getConsumerEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_uppercaseUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID("01234567-ABCD-EF01-0123-0123456789AB");
+        Assert.assertEquals("01234567-ABCD-EF01-0123-0123456789AB",
+                SecRuleEntityDecoder.getConsumerEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_mixUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID("01234567-ABCD-ef01-0123-0123456789Ab");
+        Assert.assertEquals("01234567-ABCD-ef01-0123-0123456789Ab",
+                SecRuleEntityDecoder.getConsumerEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_noSlashLowercaseUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID("01234567abcdef0101230123456789ab");
+        Assert.assertEquals("01234567-abcd-ef01-0123-0123456789ab",
+                SecRuleEntityDecoder.getConsumerEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_noSlashUppercaseUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID("01234567ABCDEF0101230123456789AB");
+        Assert.assertEquals("01234567-ABCD-EF01-0123-0123456789AB",
+                SecRuleEntityDecoder.getConsumerEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_noSlashMixUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID("01234567ABCDef0101230123456789Ab");
+        Assert.assertEquals("01234567-ABCD-ef01-0123-0123456789Ab",
+                SecRuleEntityDecoder.getConsumerEpgId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_emptyUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID("");
+        Assert.assertSame(null, SecRuleEntityDecoder.getConsumerEpgId(secRule));
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_badLengthUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID("abc");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getConsumerEpgId(secRule);
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_badContentUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID("xyz34567-abcd-ef01-0123-0123456789ab");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getConsumerEpgId(secRule);
+    }
+
+    @Test
+    public final void testGetConsumerEpgId_nullUuidRemoteGroupID() {
+        secRule.setSecurityRemoteGroupID(null);
+        Assert.assertSame(null, SecRuleEntityDecoder.getConsumerEpgId(secRule));
+    }
+
+    @Test
+    public final void testGetContractId_lowercaseUuidID() {
+        secRule.setSecurityRuleUUID("01234567-abcd-ef01-0123-0123456789ab");
+        Assert.assertEquals("01234567-abcd-ef01-0123-0123456789ab", SecRuleEntityDecoder.getContractId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetContractId_uppercaseUuidID() {
+        secRule.setSecurityRuleUUID("01234567-ABCD-EF01-0123-0123456789AB");
+        Assert.assertEquals("01234567-ABCD-EF01-0123-0123456789AB", SecRuleEntityDecoder.getContractId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetContractId_mixUuidID() {
+        secRule.setSecurityRuleUUID("01234567-ABCD-ef01-0123-0123456789Ab");
+        Assert.assertEquals("01234567-ABCD-ef01-0123-0123456789Ab", SecRuleEntityDecoder.getContractId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetContractId_noSlashLowercaseUuidID() {
+        secRule.setSecurityRuleUUID("01234567abcdef0101230123456789ab");
+        Assert.assertEquals("01234567-abcd-ef01-0123-0123456789ab", SecRuleEntityDecoder.getContractId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetContractId_noSlashUppercaseUuidID() {
+        secRule.setSecurityRuleUUID("01234567ABCDEF0101230123456789AB");
+        Assert.assertEquals("01234567-ABCD-EF01-0123-0123456789AB", SecRuleEntityDecoder.getContractId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetContractId_noSlashMixUuidID() {
+        secRule.setSecurityRuleUUID("01234567ABCDef0101230123456789Ab");
+        Assert.assertEquals("01234567-ABCD-ef01-0123-0123456789Ab", SecRuleEntityDecoder.getContractId(secRule).getValue());
+    }
+
+    @Test
+    public final void testGetContractId_emptyUuidID() {
+        secRule.setSecurityRuleUUID("");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getContractId(secRule);
+    }
+
+    @Test
+    public final void testGetContractId_badLengthUuidID() {
+        secRule.setSecurityRuleUUID("abcdxy");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getContractId(secRule);
+    }
+
+    @Test
+    public final void testGetContractId_badContentUuidID() {
+        secRule.setSecurityRuleUUID("xyz34567-abcd-ef01-0123-0123456789ab");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getContractId(secRule);
+    }
+
+    @Test
+    public final void testGetContractId_nullUuidID() {
+        secRule.setSecurityRuleUUID(null);
+        thrown.expect(NullPointerException.class);
+        SecRuleEntityDecoder.getContractId(secRule);
+    }
+
+    @Test
+    public final void testGetClassifierInstance_onlyEthertype() {
+        secRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        ClassifierInstance ci = SecRuleEntityDecoder.getClassifierInstance(secRule);
+        Assert.assertEquals(EtherTypeClassifier.DEFINITION.getId(), ci.getClassifierDefinitionId());
+        // name is ether_type_IPv4
+        String expectedName = new StringBuilder().append(EtherTypeClassifier.DEFINITION.getName().getValue())
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(NeutronUtils.IPv4)
+            .toString();
+        Assert.assertEquals(expectedName, ci.getName().getValue());
+        Assert.assertEquals(expectedName, ci.getName().getValue());
+        List<ParameterValue> parameterValues = ci.getParameterValue();
+        Assert.assertNotNull(parameterValues);
+        Assert.assertEquals(1, parameterValues.size());
+        ParameterValue parameter = parameterValues.get(0);
+        Assert.assertEquals(EtherTypeClassifier.ETHERTYPE_PARAM, parameter.getName().getValue());
+        assertClassifierParameterValue(parameter, EtherTypeClassifier.IPv4_VALUE, null, null);
+    }
+
+    @Test
+    public final void testGetClassifierInstance_EthertypeAndProtocol() {
+        secRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        secRule.setSecurityRuleProtocol(NeutronUtils.TCP);
+        ClassifierInstance ci = SecRuleEntityDecoder.getClassifierInstance(secRule);
+        Assert.assertEquals(IpProtoClassifier.DEFINITION.getId(), ci.getClassifierDefinitionId());
+        // name is ip_proto_tcp__ether_type_IPv4
+        String expectedName = new StringBuilder().append(IpProtoClassifier.DEFINITION.getName().getValue())
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(NeutronUtils.TCP)
+            .append(MappingUtils.NAME_DOUBLE_DELIMETER)
+            .append(EtherTypeClassifier.DEFINITION.getName().getValue())
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(NeutronUtils.IPv4)
+            .toString();
+        Assert.assertEquals(expectedName, ci.getName().getValue());
+        List<ParameterValue> parameterValues = ci.getParameterValue();
+        Assert.assertNotNull(parameterValues);
+        Assert.assertEquals(2, parameterValues.size());
+        boolean containsEthertypeParam = false;
+        boolean containsProtoParam = false;
+        for (ParameterValue parameter : parameterValues) {
+            ParameterName parameterName = parameter.getName();
+            Assert.assertNotNull(parameterName);
+            if (EtherTypeClassifier.ETHERTYPE_PARAM.equals(parameterName.getValue())) {
+                containsEthertypeParam = true;
+                assertClassifierParameterValue(parameter, EtherTypeClassifier.IPv4_VALUE, null, null);
+            } else if (IpProtoClassifier.PROTO_PARAM.equals(parameterName.getValue())) {
+                containsProtoParam = true;
+                assertClassifierParameterValue(parameter, IpProtoClassifier.TCP_VALUE, null, null);
+            } else {
+                fail("This parameter is not expected: " + parameter);
+            }
+        }
+        Assert.assertTrue("Classifier-instance does not contain ethertype parameter", containsEthertypeParam);
+        Assert.assertTrue("Classifier-instance does not contain protocol parameter", containsProtoParam);
+    }
+
+    @Test
+    public final void testGetClassifierInstance_EthertypeAndProtocolAndPort() {
+        secRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        secRule.setSecurityRuleProtocol(NeutronUtils.TCP);
+        secRule.setSecurityRulePortMin(5);
+        secRule.setSecurityRulePortMax(5);
+        ClassifierInstance ci = SecRuleEntityDecoder.getClassifierInstance(secRule);
+        Assert.assertEquals(L4Classifier.DEFINITION.getId(), ci.getClassifierDefinitionId());
+        // name is l4_destport-5__ip_proto-tcp__ether_type-IPv4
+        String expectedName = new StringBuilder().append(L4Classifier.DEFINITION.getName().getValue())
+            .append(MappingUtils.NAME_DELIMETER)
+            .append(L4Classifier.DST_PORT_PARAM)
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(secRule.getSecurityRulePortMin())
+            .append(MappingUtils.NAME_DOUBLE_DELIMETER)
+            .append(IpProtoClassifier.DEFINITION.getName().getValue())
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(NeutronUtils.TCP)
+            .append(MappingUtils.NAME_DOUBLE_DELIMETER)
+            .append(EtherTypeClassifier.DEFINITION.getName().getValue())
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(NeutronUtils.IPv4)
+            .toString();
+        Assert.assertEquals(expectedName, ci.getName().getValue());
+        List<ParameterValue> parameterValues = ci.getParameterValue();
+        Assert.assertNotNull(parameterValues);
+        Assert.assertEquals(3, parameterValues.size());
+        boolean containsEthertypeParam = false;
+        boolean containsProtoParam = false;
+        boolean containsDstPortParam = false;
+        for (ParameterValue parameter : parameterValues) {
+            ParameterName parameterName = parameter.getName();
+            Assert.assertNotNull(parameterName);
+            if (EtherTypeClassifier.ETHERTYPE_PARAM.equals(parameterName.getValue())) {
+                containsEthertypeParam = true;
+                assertClassifierParameterValue(parameter, EtherTypeClassifier.IPv4_VALUE, null, null);
+            } else if (IpProtoClassifier.PROTO_PARAM.equals(parameterName.getValue())) {
+                containsProtoParam = true;
+                assertClassifierParameterValue(parameter, IpProtoClassifier.TCP_VALUE, null, null);
+            } else if (L4Classifier.DST_PORT_PARAM.equals(parameterName.getValue())) {
+                containsDstPortParam = true;
+                assertClassifierParameterValue(parameter, 5L, null, null);
+            } else {
+                fail("This parameter is not expected: " + parameter);
+            }
+        }
+        Assert.assertTrue("Classifier-instance does not contain ethertype parameter", containsEthertypeParam);
+        Assert.assertTrue("Classifier-instance does not contain protocol parameter", containsProtoParam);
+        Assert.assertTrue("Classifier-instance does not contain destination port parameter", containsDstPortParam);
+    }
+
+    private final void assertClassifierParameterValue(ParameterValue parameter, Long expectedIntValue,
+            String expectedStringValue, RangeValue expectedRangeValue) {
+        Assert.assertEquals(expectedIntValue, parameter.getIntValue());
+        Assert.assertEquals(expectedStringValue, parameter.getStringValue());
+        Assert.assertEquals(expectedRangeValue, parameter.getRangeValue());
+    }
+
+    @Test
+    public final void testGetClassifierInstance_EthertypeAndProtocolAndPorts() {
+        secRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        secRule.setSecurityRuleProtocol(NeutronUtils.TCP);
+        secRule.setSecurityRulePortMin(5);
+        secRule.setSecurityRulePortMax(10);
+        ClassifierInstance ci = SecRuleEntityDecoder.getClassifierInstance(secRule);
+        Assert.assertEquals(L4Classifier.DEFINITION.getId(), ci.getClassifierDefinitionId());
+        // name is l4_destport_range_min-5_max-10__ip_proto-tcp__ether_type-IPv4
+        String expectedName = new StringBuilder().append(L4Classifier.DEFINITION.getName().getValue())
+            .append(MappingUtils.NAME_DELIMETER)
+            .append(L4Classifier.DST_PORT_RANGE_PARAM)
+            .append(SecRuleNameDecoder.MIN_PORT)
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(secRule.getSecurityRulePortMin())
+            .append(SecRuleNameDecoder.MAX_PORT)
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(secRule.getSecurityRulePortMax())
+            .append(MappingUtils.NAME_DOUBLE_DELIMETER)
+            .append(IpProtoClassifier.DEFINITION.getName().getValue())
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(NeutronUtils.TCP)
+            .append(MappingUtils.NAME_DOUBLE_DELIMETER)
+            .append(EtherTypeClassifier.DEFINITION.getName().getValue())
+            .append(MappingUtils.NAME_VALUE_DELIMETER)
+            .append(NeutronUtils.IPv4)
+            .toString();
+        Assert.assertEquals(expectedName, ci.getName().getValue());
+    }
+
+    @Test
+    public final void testGetClassifierRef() {
+        secRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
+        secRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        ClassifierName expectedName = SecRuleNameDecoder.getClassifierRefName(secRule);
+        ClassifierRef cr = SecRuleEntityDecoder.getClassifierRef(secRule);
+        Assert.assertEquals(expectedName, cr.getName());
+    }
+
+    @Test
+    public final void testGetDirection_directionIngress() {
+        secRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
+        Assert.assertEquals(Direction.In, SecRuleEntityDecoder.getDirection(secRule));
+    }
+
+    @Test
+    public final void testGetDirection_directionEgress() {
+        secRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
+        Assert.assertEquals(Direction.Out, SecRuleEntityDecoder.getDirection(secRule));
+    }
+
+    @Test
+    public final void testGetDirection_directionNull() {
+        secRule.setSecurityRuleDirection(null);
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getDirection(secRule);
+    }
+
+    @Test
+    public final void testGetDirection_directionUnknown() {
+        secRule.setSecurityRuleDirection("foo");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getDirection(secRule);
+    }
+
+    @Test
+    public final void testGetClause_noRemoteIpPrefix() {
+        secRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
+        secRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        ClauseName expectedClauseName = SecRuleNameDecoder.getClauseName(secRule);
+        Clause clause = SecRuleEntityDecoder.getClause(secRule);
+        Assert.assertEquals(expectedClauseName, clause.getName());
+        List<SubjectName> subjectRefs = clause.getSubjectRefs();
+        Assert.assertNotNull(subjectRefs);
+        Assert.assertEquals(1, subjectRefs.size());
+        SubjectName subjectNameFromClause = subjectRefs.get(0);
+        SubjectName expectedSubjectName = SecRuleNameDecoder.getSubjectName(secRule);
+        Assert.assertEquals(expectedSubjectName, subjectNameFromClause);
+        Assert.assertNull(clause.getConsumerMatchers());
+        Assert.assertNull(clause.getProviderMatchers());
+    }
+
+    @Test
+    public final void testGetClause_remoteIpPrefix() {
+        secRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
+        secRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        secRule.setSecurityRuleRemoteIpPrefix("10.0.0.0/8");
+        Clause clause = SecRuleEntityDecoder.getClause(secRule);
+        ClauseName expectedClauseName = SecRuleNameDecoder.getClauseName(secRule);
+        Assert.assertEquals(expectedClauseName, clause.getName());
+        List<SubjectName> subjectRefs = clause.getSubjectRefs();
+        Assert.assertNotNull(subjectRefs);
+        Assert.assertEquals(1, subjectRefs.size());
+        SubjectName subjectNameFromClause = subjectRefs.get(0);
+        SubjectName expectedSubjectName = SecRuleNameDecoder.getSubjectName(secRule);
+        Assert.assertEquals(expectedSubjectName, subjectNameFromClause);
+        Assert.assertNull(clause.getProviderMatchers());
+        ConsumerMatchers consumerMatchers = clause.getConsumerMatchers();
+        Assert.assertNotNull(consumerMatchers);
+        Assert.assertNull(consumerMatchers.getConditionMatcher());
+        Assert.assertNull(consumerMatchers.getGroupIdentificationConstraints());
+        EndpointIdentificationConstraints endpointIdentificationConstraints =
+                consumerMatchers.getEndpointIdentificationConstraints();
+        Assert.assertNotNull(endpointIdentificationConstraints);
+        L3EndpointIdentificationConstraints l3EndpointIdentificationConstraints =
+                endpointIdentificationConstraints.getL3EndpointIdentificationConstraints();
+        Assert.assertNotNull(l3EndpointIdentificationConstraints);
+        List<PrefixConstraint> prefixConstraints = l3EndpointIdentificationConstraints.getPrefixConstraint();
+        Assert.assertNotNull(prefixConstraints);
+        Assert.assertEquals(1, prefixConstraints.size());
+        PrefixConstraint prefixConstraint = prefixConstraints.get(0);
+        Assert.assertEquals(new Ipv4Prefix("10.0.0.0/8"), prefixConstraint.getIpPrefix().getIpv4Prefix());
+    }
+
+    @Test
+    public final void testIsEtherTypeOfOneWithinTwo_oneEthTypeIPv4TwoEthTypeIPv4() {
+        NeutronSecurityRule one = createSecRuleWithEtherType(NeutronUtils.IPv4);
+        NeutronSecurityRule two = createSecRuleWithEtherType(NeutronUtils.IPv4);
+        assertTrue(SecRuleEntityDecoder.isEtherTypeOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsEtherTypeOfOneWithinTwo_oneEthTypeIPv4TwoEthTypeNull() {
+        NeutronSecurityRule one = createSecRuleWithEtherType(NeutronUtils.IPv4);
+        NeutronSecurityRule two = createSecRuleWithEtherType(null);
+        assertTrue(SecRuleEntityDecoder.isEtherTypeOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsEtherTypeOfOneWithinTwo_oneEthTypeNullTwoEthTypeNull() {
+        NeutronSecurityRule one = createSecRuleWithEtherType(null);
+        NeutronSecurityRule two = createSecRuleWithEtherType(null);
+        assertTrue(SecRuleEntityDecoder.isEtherTypeOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsEtherTypeOfOneWithinTwo_oneEthTypeIPv4TwoEthTypeIPv6() {
+        NeutronSecurityRule one = createSecRuleWithEtherType(NeutronUtils.IPv4);
+        NeutronSecurityRule two = createSecRuleWithEtherType(NeutronUtils.IPv6);
+        assertFalse(SecRuleEntityDecoder.isEtherTypeOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsEtherTypeOfOneWithinTwo_oneEthTypeNullTwoEthTypeIPv4() {
+        NeutronSecurityRule one = createSecRuleWithEtherType(null);
+        NeutronSecurityRule two = createSecRuleWithEtherType(NeutronUtils.IPv4);
+        assertFalse(SecRuleEntityDecoder.isEtherTypeOfOneWithinTwo(one, two));
+    }
+
+    private final NeutronSecurityRule createSecRuleWithEtherType(String etherType) {
+        NeutronSecurityRule secRule = new NeutronSecurityRule();
+        secRule.setSecurityRuleEthertype(etherType);
+        return secRule;
+    }
+
+    @Test
+    public void testIsProtocolOfOneWithinTwo_oneProtocolTcpTwoProtocolTcp() {
+        NeutronSecurityRule one = createSecRuleWithProtocol(NeutronUtils.TCP);
+        NeutronSecurityRule two = createSecRuleWithProtocol(NeutronUtils.TCP);
+        assertTrue(SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public void testIsProtocolOfOneWithinTwo_oneProtocolTcpTwoProtocolNull() {
+        NeutronSecurityRule one = createSecRuleWithProtocol(NeutronUtils.TCP);
+        NeutronSecurityRule two = createSecRuleWithProtocol(null);
+        assertTrue(SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public void testIsProtocolOfOneWithinTwo_oneProtocolNullTwoProtocolNull() {
+        NeutronSecurityRule one = createSecRuleWithProtocol(null);
+        NeutronSecurityRule two = createSecRuleWithProtocol(null);
+        assertTrue(SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public void testIsProtocolOfOneWithinTwo_oneProtocolTcpTwoProtocolUdp() {
+        NeutronSecurityRule one = createSecRuleWithProtocol(NeutronUtils.TCP);
+        NeutronSecurityRule two = createSecRuleWithProtocol(NeutronUtils.UDP);
+        assertFalse(SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public void testIsProtocolOfOneWithinTwo_oneProtocolNullTwoProtocolTcp() {
+        NeutronSecurityRule one = createSecRuleWithProtocol(null);
+        NeutronSecurityRule two = createSecRuleWithProtocol(NeutronUtils.TCP);
+        assertFalse(SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two));
+    }
+
+    private NeutronSecurityRule createSecRuleWithProtocol(String protocol) {
+        NeutronSecurityRule secRule = new NeutronSecurityRule();
+        secRule.setSecurityRuleProtocol(protocol);
+        return secRule;
+    }
+
+    @Test
+    public final void testIsPortsOfOneWithinTwo_onePortMinGtTwoPortMinOnePortMaxLtTwoPortMax() {
+        NeutronSecurityRule one = createSecRuleWithMinMaxPort(6, 9);
+        NeutronSecurityRule two = createSecRuleWithMinMaxPort(5, 10);
+        assertTrue(SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsPortsOfOneWithinTwo_onePortMinEqTwoPortMinOnePortMaxEqTwoPortMax() {
+        NeutronSecurityRule one = createSecRuleWithMinMaxPort(5, 10);
+        NeutronSecurityRule two = createSecRuleWithMinMaxPort(5, 10);
+        assertTrue(SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsPortsOfOneWithinTwo_onePortMinTwoPortMinNullOnePortMaxTwoPortMaxNull() {
+        NeutronSecurityRule one = createSecRuleWithMinMaxPort(4, 9);
+        NeutronSecurityRule two = createSecRuleWithMinMaxPort(null, null);
+        assertTrue(SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsPortsOfOneWithinTwo_onePortMinNullTwoPortMinNullOnePortMaxNullTwoPortMaxNull() {
+        NeutronSecurityRule one = createSecRuleWithMinMaxPort(null, null);
+        NeutronSecurityRule two = createSecRuleWithMinMaxPort(null, null);
+        assertTrue(SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsPortsOfOneWithinTwo_onePortMinNullTwoPortMinOnePortMaxNullTwoPortMax() {
+        NeutronSecurityRule one = createSecRuleWithMinMaxPort(null, null);
+        NeutronSecurityRule two = createSecRuleWithMinMaxPort(5, 10);
+        assertFalse(SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsPortsOfOneWithinTwo_onePortMinLtTwoPortMinOnePortMaxLtTwoPortMax() {
+        NeutronSecurityRule one = createSecRuleWithMinMaxPort(4, 9);
+        NeutronSecurityRule two = createSecRuleWithMinMaxPort(5, 10);
+        assertFalse(SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsPortsOfOneWithinTwo_onePortMinGtTwoPortMinOnePortMaxGtTwoPortMax() {
+        NeutronSecurityRule one = createSecRuleWithMinMaxPort(6, 11);
+        NeutronSecurityRule two = createSecRuleWithMinMaxPort(5, 10);
+        assertFalse(SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two));
+    }
+
+    @Test
+    public final void testIsPortsOfOneWithinTwo_onePortMinLtTwoPortMinOnePortMaxGtTwoPortMax() {
+        NeutronSecurityRule one = createSecRuleWithMinMaxPort(4, 11);
+        NeutronSecurityRule two = createSecRuleWithMinMaxPort(5, 10);
+        assertFalse(SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two));
+    }
+
+    private NeutronSecurityRule createSecRuleWithMinMaxPort(Integer portMin, Integer portMax) {
+        NeutronSecurityRule secRule = new NeutronSecurityRule();
+        secRule.setSecurityRulePortMin(portMin);
+        secRule.setSecurityRulePortMax(portMax);
+        return secRule;
+    }
+
+    @Test
+    public final void testGetEtherType_ethertypeIPv4() {
+        secRule.setSecurityRuleEthertype("IPv4");
+        Assert.assertEquals(EtherTypeClassifier.IPv4_VALUE, SecRuleEntityDecoder.getEtherType(secRule));
+    }
+
+    @Test
+    public final void testGetEtherType_ethertypeIPv6() {
+        secRule.setSecurityRuleEthertype("IPv6");
+        Assert.assertEquals(EtherTypeClassifier.IPv6_VALUE, SecRuleEntityDecoder.getEtherType(secRule));
+    }
+
+    @Test
+    public final void testGetEtherType_ethertypeNull() {
+        secRule.setSecurityRuleEthertype(null);
+        Assert.assertNull(SecRuleEntityDecoder.getEtherType(secRule));
+    }
+
+    @Test
+    public final void testGetEtherType_ethertypeEmptyString() {
+        secRule.setSecurityRuleEthertype("");
+        Assert.assertNull(SecRuleEntityDecoder.getEtherType(secRule));
+    }
+
+    @Test
+    public final void testGetEtherType_ethertypeUnknown() {
+        secRule.setSecurityRuleEthertype("foo");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getEtherType(secRule);
+    }
+
+    @Test
+    public final void testGetProtocol_protoTcp() {
+        secRule.setSecurityRuleProtocol("tcp");
+        Assert.assertEquals(IpProtoClassifier.TCP_VALUE, SecRuleEntityDecoder.getProtocol(secRule));
+    }
+
+    @Test
+    public final void testGetProtocol_protoUdp() {
+        secRule.setSecurityRuleProtocol("udp");
+        Assert.assertEquals(IpProtoClassifier.UDP_VALUE, SecRuleEntityDecoder.getProtocol(secRule));
+    }
+
+    @Test
+    public final void testGetProtocol_protoIcmp() {
+        secRule.setSecurityRuleProtocol("icmp");
+        Assert.assertEquals(IpProtoClassifier.ICMP_VALUE, SecRuleEntityDecoder.getProtocol(secRule));
+    }
+
+    @Test
+    public final void testGetProtocol_protoNull() {
+        secRule.setSecurityRuleProtocol(null);
+        Assert.assertNull(SecRuleEntityDecoder.getProtocol(secRule));
+    }
+
+    @Test
+    public final void testGetProtocol_protoEmptyString() {
+        secRule.setSecurityRuleProtocol("");
+        Assert.assertNull(SecRuleEntityDecoder.getProtocol(secRule));
+    }
+
+    @Test
+    public final void testGetProtocol_protoUnknown() {
+        secRule.setSecurityRuleProtocol("foo");
+        thrown.expect(IllegalArgumentException.class);
+        SecRuleEntityDecoder.getProtocol(secRule);
+    }
+
+}
diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/test/GbpDataBrokerTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/test/GbpDataBrokerTest.java
new file mode 100644 (file)
index 0000000..70de327
--- /dev/null
@@ -0,0 +1,42 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.test;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import java.io.IOException;
+
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
+
+// TODO this class exists b/c https://bugs.opendaylight.org/show_bug.cgi?id=4281
+/**
+ * Loads only modules of GBP and it's dependencies for data broker.
+ * <br>Therefore this implementation is faster than {@link AbstractDataBrokerTest}
+ */
+public class GbpDataBrokerTest extends AbstractDataBrokerTest {
+
+    @Override
+    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+        Builder<YangModuleInfo> moduleInfoSet = ImmutableSet.<YangModuleInfo>builder();
+        loadModuleInfos(Tenant.class, moduleInfoSet);
+        return moduleInfoSet.build();
+    }
+
+    public static void loadModuleInfos(Class<?> clazzFromModule, Builder<YangModuleInfo> moduleInfoSet) throws Exception {
+        YangModuleInfo moduleInfo = BindingReflections.getModuleInfo(clazzFromModule);
+        checkState(moduleInfo != null, "Module Info for %s is not available.", clazzFromModule);
+        collectYangModuleInfo(moduleInfo, moduleInfoSet);
+    }
+
+    private static void collectYangModuleInfo(final YangModuleInfo moduleInfo,
+            final Builder<YangModuleInfo> moduleInfoSet) throws IOException {
+        moduleInfoSet.add(moduleInfo);
+        for (YangModuleInfo dependency : moduleInfo.getImportedModules()) {
+            collectYangModuleInfo(dependency, moduleInfoSet);
+        }
+    }
+}
diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/UtilsTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/UtilsTest.java
new file mode 100644 (file)
index 0000000..46266e6
--- /dev/null
@@ -0,0 +1,178 @@
+package org.opendaylight.groupbasedpolicy.neutron.mapper.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+
+public class UtilsTest {
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    @Test
+    public final void testCreateIpPrefix_ipv4() {
+        String ipv4Prefix = "1.1.1.1/8";
+        IpPrefix ipPrefix = Utils.createIpPrefix(ipv4Prefix);
+        Assert.assertNotNull(ipPrefix);
+        Assert.assertNull(ipPrefix.getIpv6Prefix());
+        assertEquals(ipv4Prefix, ipPrefix.getIpv4Prefix().getValue());
+    }
+
+    @Test
+    public final void testCreateIpPrefix_ipv6() {
+        String ipv6Prefix = "fd1c:29d6:85d1::/48";
+        IpPrefix ipPrefix = Utils.createIpPrefix(ipv6Prefix);
+        Assert.assertNotNull(ipPrefix);
+        Assert.assertNull(ipPrefix.getIpv4Prefix());
+        assertEquals(ipv6Prefix, ipPrefix.getIpv6Prefix().getValue());
+    }
+
+    @Test
+    public final void testCreateIpPrefix_null() {
+        thrown.expect(IllegalArgumentException.class);
+        Utils.createIpPrefix(null);
+    }
+
+    @Test
+    public final void testCreateIpPrefix_emptyString() {
+        thrown.expect(IllegalArgumentException.class);
+        Utils.createIpPrefix("");
+    }
+
+    @Test
+    public final void testCreateIpPrefix_invalidFormat() {
+        thrown.expect(IllegalArgumentException.class);
+        Utils.createIpPrefix("1.1.1.1/33");
+    }
+
+    @Test
+    public final void testCreateIpAddress_ipv4() {
+        String ipv4Address = "1.1.1.1";
+        IpAddress ipAddress = Utils.createIpAddress(ipv4Address);
+        Assert.assertNotNull(ipAddress);
+        Assert.assertNull(ipAddress.getIpv6Address());
+        assertEquals(ipv4Address, ipAddress.getIpv4Address().getValue());
+    }
+    
+    @Test
+    public final void testCreateIpAddress_ipv6() {
+        String ipv6Address = "2001:db8::211:22ff:fe33:4455";
+        IpAddress ipAddress = Utils.createIpAddress(ipv6Address);
+        Assert.assertNotNull(ipAddress);
+        Assert.assertNull(ipAddress.getIpv4Address());
+        assertEquals(ipv6Address, ipAddress.getIpv6Address().getValue());
+    }
+
+    @Test
+    public final void testCreateIpAddress_null() {
+        thrown.expect(IllegalArgumentException.class);
+        Utils.createIpAddress(null);
+    }
+
+    @Test
+    public final void testCreateIpAddress_emptyString() {
+        thrown.expect(IllegalArgumentException.class);
+        Utils.createIpAddress("");
+    }
+
+    @Test
+    public final void testCreateIpAddress_invalidFormat() {
+        thrown.expect(IllegalArgumentException.class);
+        Utils.createIpAddress("1.1.1.256");
+    }
+
+    @Test
+    public final void testGetStringIpPrefix_ipv4() {
+        String ipv4Prefix = "1.1.1.1/8";
+        assertEquals(ipv4Prefix, Utils.getStringIpPrefix(new IpPrefix(new Ipv4Prefix(ipv4Prefix))));
+    }
+
+    @Test
+    public final void testGetStringIpPrefix_ipv6() {
+        String ipv6Prefix = "fd1c:29d6:85d1::/48";
+        assertEquals(ipv6Prefix, Utils.getStringIpPrefix(new IpPrefix(new Ipv6Prefix(ipv6Prefix))));
+    }
+
+    @Test
+    public final void testGetStringIpPrefix_null() {
+        thrown.expect(NullPointerException.class);
+        Utils.getStringIpPrefix(null);
+    }
+    
+    @Test
+    public final void testGetStringIpAddress_ipv4() {
+        String ipv4Address = "1.1.1.1";
+        assertEquals(ipv4Address, Utils.getStringIpAddress(new IpAddress(new Ipv4Address(ipv4Address))));
+    }
+
+    @Test
+    public final void testGetStringIpAddress_ipv6() {
+        String ipv6Address = "2001:db8::211:22ff:fe33:4455";
+        assertEquals(ipv6Address, Utils.getStringIpAddress(new IpAddress(new Ipv6Address(ipv6Address))));
+    }
+
+    @Test
+    public final void testGetStringIpAddress_null() {
+        thrown.expect(NullPointerException.class);
+        Utils.getStringIpAddress(null);
+    }
+
+    @Test
+    public final void testNormalizeUuid_lowercaseUuid() {
+        assertEquals("01234567-abcd-ef01-0123-0123456789ab",
+                Utils.normalizeUuid("01234567-abcd-ef01-0123-0123456789ab"));
+    }
+
+    @Test
+    public final void testNormalizeUuid_uppercaseUuid() {
+        assertEquals("01234567-ABCD-EF01-0123-0123456789AB",
+                Utils.normalizeUuid("01234567-ABCD-EF01-0123-0123456789AB"));
+    }
+
+    @Test
+    public final void testNormalizeUuid_mixUuid() {
+        assertEquals("01234567-ABCD-ef01-0123-0123456789Ab",
+                Utils.normalizeUuid("01234567-ABCD-ef01-0123-0123456789Ab"));
+    }
+
+    @Test
+    public final void testNormalizeUuid_noSlashLowercaseUuid() {
+        assertEquals("01234567-abcd-ef01-0123-0123456789ab", Utils.normalizeUuid("01234567abcdef0101230123456789ab"));
+    }
+
+    @Test
+    public final void testNormalizeUuid_noSlashUppercaseUuid() {
+        assertEquals("01234567-ABCD-EF01-0123-0123456789AB", Utils.normalizeUuid("01234567ABCDEF0101230123456789AB"));
+    }
+
+    @Test
+    public final void testNormalizeUuid_noSlashMixUuid() {
+        assertEquals("01234567-ABCD-ef01-0123-0123456789Ab", Utils.normalizeUuid("01234567ABCDef0101230123456789Ab"));
+    }
+
+    @Test
+    public final void testNormalizeUuid_emptyUuid() {
+        assertEquals("", Utils.normalizeUuid(""));
+    }
+
+    @Test
+    public final void testNormalizeUuid_badUuid() {
+        assertEquals("abcdxy", Utils.normalizeUuid("abcdxy"));
+    }
+
+    @Test
+    public final void testNormalizeUuid_nullUuid() {
+        thrown.expect(NullPointerException.class);
+        Utils.normalizeUuid(null);
+    }
+
+}