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