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