Bug 5409 - setting orders in single rule contract
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / rule / NeutronSecurityRuleAware.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
10
11 import static com.google.common.base.Preconditions.checkNotNull;
12
13 import java.util.Set;
14
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
20 import org.opendaylight.groupbasedpolicy.dto.EgKey;
21 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.StatusCode;
22 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.SecGroupDao;
23 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
24 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
25 import org.opendaylight.groupbasedpolicy.util.IidFactory;
26 import org.opendaylight.neutron.spi.INeutronSecurityRuleAware;
27 import org.opendaylight.neutron.spi.NeutronSecurityRule;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.ActionChoice;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.SfcActionCase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelectorBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstanceBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 import com.google.common.annotations.VisibleForTesting;
54 import com.google.common.base.Strings;
55 import com.google.common.collect.HashMultiset;
56 import com.google.common.collect.ImmutableList;
57 import com.google.common.collect.Multiset;
58 import com.google.common.collect.Sets;
59
60 public class NeutronSecurityRuleAware implements INeutronSecurityRuleAware {
61
62     private static final Logger LOG = LoggerFactory.getLogger(NeutronSecurityRuleAware.class);
63     private static final String CONTRACT_PROVIDER = "Contract provider: ";
64     private final DataBroker dataProvider;
65     private final SecRuleDao secRuleDao;
66     private final SecGroupDao secGroupDao;
67     private final Multiset<InstanceIdentifier<ClassifierInstance>> createdClassifierInstances;
68     private final Multiset<InstanceIdentifier<ActionInstance>> createdActionInstances;
69     final static String PROVIDED_BY = "provided_by-";
70     final static String POSSIBLE_CONSUMER = "possible_consumer-";
71
72     public NeutronSecurityRuleAware(DataBroker dataProvider, SecRuleDao secRuleDao, SecGroupDao secGroupDao) {
73         this(dataProvider, secRuleDao, secGroupDao, HashMultiset.<InstanceIdentifier<ClassifierInstance>>create(),
74                 HashMultiset.<InstanceIdentifier<ActionInstance>>create());
75     }
76
77     @VisibleForTesting
78     NeutronSecurityRuleAware(DataBroker dataProvider, SecRuleDao secRuleDao, SecGroupDao secGroupDao,
79             Multiset<InstanceIdentifier<ClassifierInstance>> classifierInstanceNames,
80             Multiset<InstanceIdentifier<ActionInstance>> createdActionInstances) {
81         this.dataProvider = checkNotNull(dataProvider);
82         this.secRuleDao = checkNotNull(secRuleDao);
83         this.secGroupDao = checkNotNull(secGroupDao);
84         this.createdClassifierInstances = checkNotNull(classifierInstanceNames);
85         this.createdActionInstances = checkNotNull(createdActionInstances);
86     }
87
88     @Override
89     public int canCreateNeutronSecurityRule(NeutronSecurityRule securityRule) {
90         LOG.trace("canCreateNeutronSecurityRule - {}", securityRule);
91         // nothing to consider
92         return StatusCode.OK;
93     }
94
95     @Override
96     public void neutronSecurityRuleCreated(NeutronSecurityRule securityRule) {
97         LOG.trace("neutronSecurityRuleCreated - {}", securityRule);
98         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
99         boolean isNeutronSecurityRuleAdded = addNeutronSecurityRule(securityRule, rwTx);
100         if (isNeutronSecurityRuleAdded) {
101             DataStoreHelper.submitToDs(rwTx);
102         } else {
103             rwTx.cancel();
104         }
105     }
106
107     public boolean changeActionOfNeutronSecurityRule(Uuid secRuleId, ActionChoice action, ReadWriteTransaction rwTx) {
108         NeutronSecurityRule secRule = secRuleDao.getSecRuleByUuid(secRuleId);
109         addSfcChainActionInstance(action, SecRuleEntityDecoder.getTenantId(secRule), rwTx);
110         LOG.trace("Changing to action {} for secuirity group rule {}", action, secRule);
111         return addNeutronSecurityRuleWithAction(secRule, action, rwTx);
112     }
113
114     private void addSfcChainActionInstance(ActionChoice action, TenantId tenantId, ReadWriteTransaction rwTx) {
115         if (action instanceof SfcActionCase) {
116             String sfcChainName = ((SfcActionCase) action).getSfcChainName();
117             ActionName actionName = new ActionName(sfcChainName);
118             ActionInstance sfcActionInstance = new ActionInstanceBuilder().setName(actionName)
119                 .setActionDefinitionId(ChainActionDefinition.ID)
120                 .setParameterValue(
121                         ImmutableList.of(new ParameterValueBuilder().setName(
122                                 new ParameterName(ChainActionDefinition.SFC_CHAIN_NAME))
123                             .setStringValue(sfcChainName)
124                             .build()))
125                 .build();
126             rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.actionInstanceIid(tenantId, actionName),
127                     sfcActionInstance, true);
128         }
129     }
130
131     public boolean addNeutronSecurityRule(NeutronSecurityRule secRule, ReadWriteTransaction rwTx) {
132         return addNeutronSecurityRuleWithAction(secRule, MappingUtils.ALLOW_ACTION_CHOICE, rwTx);
133     }
134
135     public boolean addNeutronSecurityRuleWithAction(NeutronSecurityRule secRule, ActionChoice action,
136             ReadWriteTransaction rwTx) {
137         TenantId tenantId = SecRuleEntityDecoder.getTenantId(secRule);
138         EndpointGroupId providerEpgId = SecRuleEntityDecoder.getProviderEpgId(secRule);
139         secRuleDao.addSecRule(secRule);
140
141         Description contractDescription = new Description(CONTRACT_PROVIDER
142                 + secGroupDao.getNameOrIdOfSecGroup(providerEpgId));
143         SingleRuleContract singleRuleContract = createSingleRuleContract(secRule, contractDescription, action);
144         Contract contract = singleRuleContract.getContract();
145         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, contract.getId()), contract, true);
146         SelectorName providerSelector = getSelectorNameWithConsumer(secRule);
147         writeProviderNamedSelectorToEpg(providerSelector, contract.getId(), new EgKey(tenantId, providerEpgId), rwTx);
148
149         if (SecRuleEntityDecoder.getConsumerEpgId(secRule) != null) {
150             EndpointGroupId consumerEpgId = SecRuleEntityDecoder.getConsumerEpgId(secRule);
151             designContractsBetweenProviderAndConsumer(tenantId, providerEpgId, consumerEpgId, rwTx);
152             designContractsBetweenProviderAndConsumer(tenantId, consumerEpgId, providerEpgId, rwTx);
153         } else {
154             for (EndpointGroupId consumerEpgId : secRuleDao.getAllOwnerSecGrps()) {
155                 designContractsBetweenProviderAndConsumer(tenantId, providerEpgId, consumerEpgId, rwTx);
156                 designContractsBetweenProviderAndConsumer(tenantId, consumerEpgId, providerEpgId, rwTx);
157             }
158         }
159
160         ClassifierInstance classifierInstance = singleRuleContract.getSingleClassifierRule().getClassifierInstance();
161         createClassifierInstanceIfNotExists(tenantId, classifierInstance, rwTx);
162         createAllowActionInstanceIfNotExists(tenantId, rwTx);
163         return true;
164     }
165
166     @VisibleForTesting
167     static SingleRuleContract createSingleRuleContract(NeutronSecurityRule secRule, Description contractDescription,
168             ActionChoice action) {
169         if (!Strings.isNullOrEmpty(secRule.getSecurityRuleRemoteIpPrefix())) {
170             return new SingleRuleContract(secRule, 0, contractDescription, action);
171         }
172         return new SingleRuleContract(secRule, 400, contractDescription, action);
173     }
174
175     @VisibleForTesting
176     void designContractsBetweenProviderAndConsumer(TenantId tenantId, EndpointGroupId provEpgId,
177             EndpointGroupId consEpgId, ReadWriteTransaction rwTx) {
178         Set<NeutronSecurityRule> provSecRules = getProvidedSecRulesBetween(provEpgId, consEpgId);
179         Set<NeutronSecurityRule> consSecRules = getProvidedSecRulesBetween(consEpgId, provEpgId);
180         for (NeutronSecurityRule provSecRule : provSecRules) {
181             if (isProviderSecRuleSuitableForConsumerSecRules(provSecRule, consSecRules)) {
182                 SelectorName consumerSelector = getSelectorNameWithProvider(provSecRule);
183                 ContractId contractId = SecRuleEntityDecoder.getContractId(provSecRule);
184                 writeConsumerNamedSelectorToEpg(consumerSelector, contractId, new EgKey(tenantId, consEpgId), rwTx);
185             }
186             // TODO add case when port ranges overlap
187         }
188     }
189
190     @VisibleForTesting
191     Set<NeutronSecurityRule> getProvidedSecRulesBetween(EndpointGroupId provEpgId, EndpointGroupId consEpgId) {
192         return Sets.union(secRuleDao.getSecRulesBySecGrpIdAndRemoteSecGrpId(provEpgId, consEpgId),
193                 secRuleDao.getSecRulesWithoutRemoteSecGrpBySecGrpId(provEpgId));
194     }
195
196     @VisibleForTesting
197     static boolean isProviderSecRuleSuitableForConsumerSecRules(NeutronSecurityRule provSecRule,
198             Set<NeutronSecurityRule> consSecRules) {
199         Direction directionProvSecRule = SecRuleEntityDecoder.getDirection(provSecRule);
200         for (NeutronSecurityRule consSecRule : consSecRules) {
201             Direction directionConsSecRule = SecRuleEntityDecoder.getDirection(consSecRule);
202             if (isDirectionOpposite(directionProvSecRule, directionConsSecRule)
203                     && isOneWithinTwo(provSecRule, consSecRule)) {
204                 return true;
205             }
206         }
207         return false;
208     }
209
210     private void writeProviderNamedSelectorToEpg(SelectorName providerSelector, ContractId contractId, EgKey epgKey,
211             WriteTransaction wTx) {
212         ProviderNamedSelector providerNamedSelector = new ProviderNamedSelectorBuilder().setName(providerSelector)
213             .setContract(ImmutableList.of(contractId))
214             .build();
215         wTx.put(LogicalDatastoreType.CONFIGURATION,
216                 IidFactory.providerNamedSelectorIid(epgKey.getTenantId(), epgKey.getEgId(),
217                         providerNamedSelector.getName()), providerNamedSelector, true);
218     }
219
220     private void writeConsumerNamedSelectorToEpg(SelectorName consumerSelector, ContractId contractId, EgKey epgKey,
221             WriteTransaction wTx) {
222         ConsumerNamedSelector consumerNamedSelector = new ConsumerNamedSelectorBuilder().setName(consumerSelector)
223             .setContract(ImmutableList.of(contractId))
224             .build();
225         wTx.put(LogicalDatastoreType.CONFIGURATION,
226                 IidFactory.consumerNamedSelectorIid(epgKey.getTenantId(), epgKey.getEgId(),
227                         consumerNamedSelector.getName()), consumerNamedSelector, true);
228     }
229
230     @VisibleForTesting
231     void createClassifierInstanceIfNotExists(TenantId tenantId, ClassifierInstance classifierInstance,
232             WriteTransaction wTx) {
233         InstanceIdentifier<ClassifierInstance> classifierInstanceIid = IidFactory.classifierInstanceIid(tenantId,
234                 classifierInstance.getName());
235         if (!createdClassifierInstances.contains(classifierInstanceIid)) {
236             wTx.put(LogicalDatastoreType.CONFIGURATION, classifierInstanceIid, classifierInstance, true);
237         }
238         createdClassifierInstances.add(classifierInstanceIid);
239     }
240
241     @VisibleForTesting
242     void createAllowActionInstanceIfNotExists(TenantId tenantId, ReadWriteTransaction rwTx) {
243         InstanceIdentifier<ActionInstance> actionInstanceIid = IidFactory.actionInstanceIid(tenantId,
244                 MappingUtils.ACTION_ALLOW.getName());
245         if (!createdActionInstances.contains(actionInstanceIid)) {
246             rwTx.put(LogicalDatastoreType.CONFIGURATION, actionInstanceIid, MappingUtils.ACTION_ALLOW, true);
247         }
248         createdActionInstances.add(actionInstanceIid);
249     }
250
251     @Override
252     public int canUpdateNeutronSecurityRule(NeutronSecurityRule delta, NeutronSecurityRule original) {
253         LOG.warn("canUpdateNeutronSecurityRule - Never should be called "
254                 + "- neutron API does not allow UPDATE on neutron security group rule. \nDelta: {} \nOriginal: {}",
255                 delta, original);
256         return StatusCode.BAD_REQUEST;
257     }
258
259     @Override
260     public void neutronSecurityRuleUpdated(NeutronSecurityRule securityRule) {
261         LOG.warn("neutronSecurityRuleUpdated - Never should be called "
262                 + "- neutron API does not allow UPDATE on neutron security group rule. \nSecurity group rule: {}",
263                 securityRule);
264     }
265
266     @Override
267     public int canDeleteNeutronSecurityRule(NeutronSecurityRule securityRule) {
268         LOG.trace("canDeleteNeutronSecurityRule - {}", securityRule);
269         // nothing to consider
270         return StatusCode.OK;
271     }
272
273     @Override
274     public void neutronSecurityRuleDeleted(NeutronSecurityRule secRule) {
275         LOG.trace("neutronSecurityRuleCreated - {}", secRule);
276         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
277         boolean isNeutronSecurityRuleDeleted = deleteNeutronSecurityRule(secRule, rwTx);
278         if (isNeutronSecurityRuleDeleted) {
279             DataStoreHelper.submitToDs(rwTx);
280         } else {
281             rwTx.cancel();
282         }
283     }
284
285     public boolean deleteNeutronSecurityRule(NeutronSecurityRule secRule, ReadWriteTransaction rwTx) {
286         TenantId tenantId = SecRuleEntityDecoder.getTenantId(secRule);
287         EndpointGroupId providerEpgId = SecRuleEntityDecoder.getProviderEpgId(secRule);
288
289         SelectorName providerSelector = getSelectorNameWithConsumer(secRule);
290         deleteProviderNamedSelectorFromEpg(providerSelector, new EgKey(tenantId, providerEpgId), rwTx);
291
292         if (SecRuleEntityDecoder.getConsumerEpgId(secRule) != null) {
293             EndpointGroupId consumerEpgId = SecRuleEntityDecoder.getConsumerEpgId(secRule);
294             undesignContractsBetweenProviderAndConsumer(tenantId, providerEpgId, consumerEpgId, secRule, rwTx);
295             undesignContractsBetweenProviderAndConsumer(tenantId, consumerEpgId, providerEpgId, secRule, rwTx);
296         } else {
297             for (EndpointGroupId consumerEpgId : secRuleDao.getAllOwnerSecGrps()) {
298                 undesignContractsBetweenProviderAndConsumer(tenantId, providerEpgId, consumerEpgId, secRule, rwTx);
299                 undesignContractsBetweenProviderAndConsumer(tenantId, consumerEpgId, providerEpgId, secRule, rwTx);
300             }
301         }
302
303         secRuleDao.removeSecRule(secRule);
304         ContractId contractId = SecRuleEntityDecoder.getContractId(secRule);
305         rwTx.delete(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, contractId));
306
307         ClassifierInstance classifierInstance = SecRuleEntityDecoder.getClassifierInstance(secRule);
308         deleteClassifierInstanceIfNotUsed(tenantId, classifierInstance, rwTx);
309         return true;
310     }
311
312     @VisibleForTesting
313     void undesignContractsBetweenProviderAndConsumer(TenantId tenantId, EndpointGroupId provEpgId,
314             EndpointGroupId consEpgId, NeutronSecurityRule removedSecRule, ReadWriteTransaction rwTx) {
315         Set<NeutronSecurityRule> provSecRules = getProvidedSecRulesBetween(provEpgId, consEpgId);
316         Set<NeutronSecurityRule> consSecRules = getProvidedSecRulesBetween(consEpgId, provEpgId);
317         for (NeutronSecurityRule provSecRule : provSecRules) {
318             if (isProvidersSecRuleSuitableForConsumersSecRulesAndGoodToRemove(provSecRule, consSecRules, removedSecRule)) {
319                 SelectorName consumerSelector = getSelectorNameWithProvider(provSecRule);
320                 deleteConsumerNamedSelector(consumerSelector, new EgKey(tenantId, consEpgId), rwTx);
321             }
322             // TODO add case when port ranges overlap
323         }
324     }
325
326     @VisibleForTesting
327     static boolean isProvidersSecRuleSuitableForConsumersSecRulesAndGoodToRemove(NeutronSecurityRule provSecRule,
328             Set<NeutronSecurityRule> consSecRules, NeutronSecurityRule removedSecRule) {
329         Direction directionProvSecRule = SecRuleEntityDecoder.getDirection(provSecRule);
330         for (NeutronSecurityRule consSecRule : consSecRules) {
331             if (isRuleIdEqual(removedSecRule, consSecRule) || isRuleIdEqual(removedSecRule, provSecRule)) {
332                 Direction directionConsSecRule = SecRuleEntityDecoder.getDirection(consSecRule);
333                 if (isDirectionOpposite(directionProvSecRule, directionConsSecRule)
334                         && isOneWithinTwo(provSecRule, consSecRule)) {
335                     return true;
336                 }
337             }
338         }
339         return false;
340     }
341
342     @VisibleForTesting
343     static boolean isRuleIdEqual(NeutronSecurityRule one, NeutronSecurityRule two) {
344         checkNotNull(one);
345         checkNotNull(two);
346         return one.getSecurityRuleUUID().equals(two.getSecurityRuleUUID());
347     }
348
349     private void deleteProviderNamedSelectorFromEpg(SelectorName providerSelector, EgKey providerEpgKey,
350             ReadWriteTransaction rwTx) {
351         InstanceIdentifier<ProviderNamedSelector> providerSelectorIid = IidFactory.providerNamedSelectorIid(
352                 providerEpgKey.getTenantId(), providerEpgKey.getEgId(), providerSelector);
353         DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, providerSelectorIid, rwTx);
354     }
355
356     private void deleteConsumerNamedSelector(SelectorName consumerSelector, EgKey consumerEpgKey,
357             ReadWriteTransaction rwTx) {
358         InstanceIdentifier<ConsumerNamedSelector> consumerSelectorIid = IidFactory.consumerNamedSelectorIid(
359                 consumerEpgKey.getTenantId(), consumerEpgKey.getEgId(), consumerSelector);
360         DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, consumerSelectorIid, rwTx);
361     }
362
363     private void deleteClassifierInstanceIfNotUsed(TenantId tenantId, ClassifierInstance classifierInstance,
364             ReadWriteTransaction rwTx) {
365         InstanceIdentifier<ClassifierInstance> classifierInstanceIid = IidFactory.classifierInstanceIid(tenantId,
366                 classifierInstance.getName());
367         createdClassifierInstances.remove(classifierInstanceIid);
368         if (!createdClassifierInstances.contains(classifierInstanceIid)) {
369             DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, classifierInstanceIid, rwTx);
370         }
371     }
372
373     @VisibleForTesting
374     void deleteAllowActionInstanceIfNotUsed(TenantId tenantId, ReadWriteTransaction rwTx) {
375         InstanceIdentifier<ActionInstance> actionInstanceIid = IidFactory.actionInstanceIid(tenantId,
376                 MappingUtils.ACTION_ALLOW.getName());
377         createdActionInstances.remove(actionInstanceIid);
378         if (!createdActionInstances.contains(actionInstanceIid)) {
379             DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, actionInstanceIid, rwTx);
380         }
381     }
382
383     private SelectorName getSelectorNameWithConsumer(NeutronSecurityRule secRule) {
384         ClauseName clauseName = SecRuleNameDecoder.getClauseName(secRule);
385         StringBuilder selectorNameBuilder = new StringBuilder().append(clauseName.getValue());
386         EndpointGroupId consumerEpgId = SecRuleEntityDecoder.getConsumerEpgId(secRule);
387         if (consumerEpgId != null) {
388             selectorNameBuilder.append(MappingUtils.NAME_DOUBLE_DELIMETER)
389                 .append(POSSIBLE_CONSUMER)
390                 .append(secGroupDao.getNameOrIdOfSecGroup(consumerEpgId));
391         }
392         return new SelectorName(selectorNameBuilder.toString());
393     }
394
395     private SelectorName getSelectorNameWithProvider(NeutronSecurityRule secRule) {
396         ClauseName clauseName = SecRuleNameDecoder.getClauseName(secRule);
397         EndpointGroupId providerEpgId = SecRuleEntityDecoder.getProviderEpgId(secRule);
398         String selectorName = new StringBuilder().append(clauseName.getValue())
399             .append(MappingUtils.NAME_DOUBLE_DELIMETER)
400             .append(PROVIDED_BY)
401             .append(secGroupDao.getNameOrIdOfSecGroup(providerEpgId))
402             .toString();
403         return new SelectorName(selectorName);
404     }
405
406     @VisibleForTesting
407     static boolean isDirectionOpposite(Direction one, Direction two) {
408         return (one == Direction.In && two == Direction.Out) || (one == Direction.Out && two == Direction.In);
409     }
410
411     @VisibleForTesting
412     static boolean isOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {
413         if (!isOneGroupIdWithinTwoRemoteGroupId(one, two) || !isOneGroupIdWithinTwoRemoteGroupId(two, one))
414             return false;
415         if (!SecRuleEntityDecoder.isEtherTypeOfOneWithinTwo(one, two))
416             return false;
417         if (!SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two))
418             return false;
419         if (!SecRuleEntityDecoder.isPortsOfOneWithinTwo(one, two))
420             return false;
421         if (!Strings.isNullOrEmpty(two.getSecurityRuleRemoteIpPrefix())
422                 && Strings.isNullOrEmpty(one.getSecurityRuleRemoteIpPrefix()))
423             return false;
424         return true;
425     }
426
427     @VisibleForTesting
428     static boolean isOneGroupIdWithinTwoRemoteGroupId(NeutronSecurityRule one, NeutronSecurityRule two) {
429         return (Strings.isNullOrEmpty(two.getSecurityRemoteGroupID()) || two.getSecurityRemoteGroupID().equals(
430                 one.getSecurityRuleGroupID()));
431     }
432
433 }