Merge "Bug 5117 - DOS chars in shell script"
[groupbasedpolicy.git] / renderers / faas / src / main / java / org / opendaylight / groupbasedpolicy / renderer / faas / FaasContractManagerListener.java
1 /*
2  * Copyright (c) 2015 Huawei Technologies 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.renderer.faas;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.UUID;
15 import java.util.concurrent.ConcurrentHashMap;
16 import java.util.concurrent.ScheduledExecutorService;
17
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
20 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
21 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.faas.uln.datastore.api.UlnDatastoreApi;
26 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.common.rev151013.Name;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.common.rev151013.Text;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.common.rev151013.Uuid;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.parameter.values.grouping.ParameterValue;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.parameter.values.grouping.ParameterValueBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.parameter.values.grouping.parameter.value.RangeValueBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.SecurityRuleGroupsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.security.rule.groups.SecurityRuleGroup;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.security.rule.groups.SecurityRuleGroupBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.security.rule.groups.security.rule.group.SecurityRule;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.security.rule.groups.security.rule.group.SecurityRuleBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.security.rule.groups.security.rule.group.security.rule.RuleAction;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.security.rule.groups.security.rule.group.security.rule.RuleActionBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.security.rule.groups.security.rule.group.security.rule.RuleClassifier;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.security.rule.groups.security.rule.group.security.rule.RuleClassifier.Direction;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.security.rules.rev151013.security.rule.groups.attributes.security.rule.groups.container.security.rule.groups.security.rule.group.security.rule.RuleClassifierBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.mapped.entity.MappedContract;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.mapped.entity.MappedContractBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.SubjectFeatureInstances;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstanceKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceKey;
65 import org.opendaylight.yangtools.yang.binding.DataObject;
66 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70 import com.google.common.base.Optional;
71
72 public class FaasContractManagerListener implements DataChangeListener {
73
74     private static final Logger LOG = LoggerFactory.getLogger(FaasContractManagerListener.class);
75     private ConcurrentHashMap<ContractId, Uuid> mappedContracts = new ConcurrentHashMap<>();
76     private final ScheduledExecutorService executor;
77     private final DataBroker dataProvider;
78     private final TenantId gbpTenantId;
79     private final Uuid faasTenantId;
80
81     public FaasContractManagerListener(DataBroker dataProvider, TenantId gbpTenantId, Uuid faasTenantId,
82             ScheduledExecutorService executor) {
83         this.executor = executor;
84         this.gbpTenantId = gbpTenantId;
85         this.faasTenantId = faasTenantId;
86         this.dataProvider = dataProvider;
87     }
88
89     @Override
90     public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
91         executor.execute(new Runnable() {
92
93             public void run() {
94                 executeEvent(change);
95             }
96         });
97     }
98
99     private void executeEvent(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
100         // Create
101         for (DataObject dao : change.getCreatedData().values()) {
102             if (dao instanceof Contract) {
103                 Contract contract = (Contract) dao;
104                 LOG.debug("Contract {} is Created.", contract.getId().getValue());
105                 UlnDatastoreApi.submitSecurityGroupsToDs(initSecurityGroupBuilder(contract).build());
106             }
107         }
108         // Update
109         Map<InstanceIdentifier<?>, DataObject> dao = change.getUpdatedData();
110         for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dao.entrySet()) {
111             if (entry.getValue() instanceof Contract) {
112                 Contract contract = (Contract) dao;
113                 LOG.debug("Contract {} is Updated.", contract.getId().getValue());
114                 UlnDatastoreApi.submitSecurityGroupsToDs(initSecurityGroupBuilder(contract).build());
115             }
116         }
117         // Remove
118         for (InstanceIdentifier<?> iid : change.getRemovedPaths()) {
119             DataObject old = change.getOriginalData().get(iid);
120             if (old == null) {
121                 continue;
122             }
123             if (old instanceof Contract) {
124                 Contract contract = (Contract) old;
125                 LOG.debug("Contract {} is removed.", contract.getId().getValue());
126                 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
127                 Optional<MappedContract> op = DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
128                         FaasIidFactory.mappedContractIid(gbpTenantId, contract.getId()), rwTx);
129                 if (op.isPresent()) {
130                     DataStoreHelper.submitToDs(rwTx);
131                 }
132                 Uuid val = mappedContracts.remove(contract.getId());
133                 if (val != null) {
134                     UlnDatastoreApi.removeSecurityGroupsFromDsIfExists(faasTenantId, val);
135                 }
136             }
137         }
138     }
139
140     public void loadAll(List<Contract> contracts, List<MappedContract> mpContracts) {
141         if (mpContracts != null) {
142             for (MappedContract mpContract : mpContracts) {
143                 mappedContracts.putIfAbsent(mpContract.getGbpContractId(), mpContract.getFaasSecurityRulesId());
144             }
145         }
146         if (contracts != null) {
147             for (Contract contract : contracts) {
148                 LOG.debug("Loading Contract {}", contract.getId().getValue());
149                 UlnDatastoreApi.submitSecurityGroupsToDs(initSecurityGroupBuilder(contract).build());
150             }
151         }
152     }
153
154     protected SecurityRuleGroupsBuilder initSecurityGroupBuilder(Contract contract) {
155         LOG.trace("Start initSecurityGroupBuilder");
156         SecurityRuleGroupsBuilder builder = new SecurityRuleGroupsBuilder();
157         builder.setUuid(getFaasSecurityRulesId(contract.getId()));
158         builder.setName(new Text(contract.getId().getValue()));
159         if (contract.getDescription() != null)
160             builder.setDescription(new Text("gbp-contract: " + contract.getDescription().getValue()));
161         else
162             builder.setDescription(new Text("gbp-contract"));
163         builder.setTenantId(faasTenantId);
164         builder.setSecurityRuleGroup(buildSecurityRuleGroup(contract));
165         LOG.trace("Contract {} is mapped to Faas Security Rules {} ", contract.getId().getValue(), builder.getUuid()
166             .getValue());
167         return builder;
168     }
169
170     private Uuid getFaasSecurityRulesId(ContractId contractId) {
171         Uuid val = mappedContracts.get(contractId);
172         if (val != null) {
173             return val;
174         }
175         Uuid faasContractId = null;
176         if (FaasPolicyManager.isUUid(contractId.getValue())) {
177             faasContractId = new Uuid(contractId.getValue());
178         } else {
179             faasContractId = new Uuid(UUID.randomUUID().toString());
180         }
181         mappedContracts.putIfAbsent(contractId, faasContractId);
182         val = mappedContracts.get(contractId);
183         MappedContractBuilder builder = new MappedContractBuilder();
184         builder.setFaasSecurityRulesId(val);
185         builder.setGbpContractId(contractId);
186         WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
187         MappedContract result = builder.build();
188         wTx.put(LogicalDatastoreType.OPERATIONAL,
189                 FaasIidFactory.mappedContractIid(gbpTenantId, contractId), result);
190         if (DataStoreHelper.submitToDs(wTx)) {
191             LOG.debug("Cached in Datastore Mapped Contract {}", result);
192         } else {
193             LOG.error("Couldn't Cache in Datastore Mapped Contract {}", result);
194         }
195         return val;
196     }
197
198     private List<SecurityRuleGroup> buildSecurityRuleGroup(Contract contract) {
199         LOG.trace("Start buildSecurityRuleGroup for contract {}", contract.getId().getValue());
200         List<SecurityRuleGroup> securityRuleGroups = new ArrayList<>();
201         if (contract.getClause() == null) {
202             LOG.debug("contract {} has no Clause", contract.getId().getValue());
203             return null;
204         }
205         for (Clause clause : contract.getClause()) {
206             if (clause.getSubjectRefs() == null) {
207                 LOG.debug("Clause {} in contract {} has no Subject Ref", clause.getName().getValue(), contract.getId()
208                     .getValue());
209                 continue;
210             }
211             if (contract.getSubject() == null) {
212                 LOG.warn("Couldn't find in Contract {} the expected subject references", contract.getId().getValue());
213                 continue;
214             }
215             for (SubjectName subjectRef : clause.getSubjectRefs()) {
216                 LOG.trace("Start Parsing Subject Ref {} in Contract {}", subjectRef, contract.getId().getValue());
217                 for (Subject sub : contract.getSubject()) {
218                     if (subjectRef.equals(sub.getName())) {
219                         SecurityRuleGroupBuilder securityRuleGroupBuilder = new SecurityRuleGroupBuilder();
220                         securityRuleGroupBuilder.setName(new Name(subjectRef.getValue()));
221                         List<Rule> subRules = sub.getRule();
222                         if (subRules == null) {
223                             LOG.warn("Subject {} in Contract {} doesn't have rules", subjectRef.getValue(),
224                                     contract.getId().getValue());
225                         } else {
226                             List<SecurityRule> securityRules = getSecurityRules(contract, subjectRef, subRules);
227                             LOG.debug("Subject {} in Contract {} has {} rules", subjectRef.getValue(), contract.getId()
228                                 .getValue(), securityRules.size());
229                             securityRuleGroupBuilder.setSecurityRule(securityRules);
230                         }
231                         LOG.debug("Added Rule {} to Subject {} in Contract {}", securityRuleGroupBuilder.getName()
232                             .getValue(), subjectRef.getValue(), contract.getId().getValue());
233                         securityRuleGroups.add(securityRuleGroupBuilder.build());
234                     }
235                 }
236             }
237         }
238         LOG.trace("Done with buildSecurityRuleGroup for contract {}", contract.getId().getValue());
239         return securityRuleGroups;
240     }
241
242     private List<SecurityRule> getSecurityRules(Contract contract, SubjectName subjectRef, List<Rule> subRules) {
243         List<SecurityRule> securityRules = new ArrayList<>();
244         for (Rule rule : subRules) {
245             List<ClassifierRef> classifierRefs = rule.getClassifierRef();
246             List<RuleClassifier> pClassifiers = null;
247             if (classifierRefs == null || classifierRefs.isEmpty()) {
248                 LOG.warn("Rule {} in Subject {} in Contract {} doesn't have classifiers", rule.getName(), subjectRef,
249                         contract.getId());
250             } else {
251                 pClassifiers = getClassifiers(gbpTenantId, contract, classifierRefs, dataProvider);
252                 if (pClassifiers == null || pClassifiers.isEmpty()) {
253                     LOG.warn("Rule {} in Subject {} in Contract {} doesn't have classifiers -- Will ignore this rule",
254                             rule.getName(), subjectRef, contract.getId());
255                 }
256             }
257             List<ActionRef> actionRefs = rule.getActionRef();
258             List<RuleAction> pActions = null;
259             if (actionRefs == null || actionRefs.isEmpty()) {
260                 LOG.warn("Rule {} in Subject {} in Contract {} doesn't have actions", rule.getName(), subjectRef,
261                         contract.getId());
262             } else {
263                 pActions = getActions(contract, actionRefs);
264                 if (pActions == null || pActions.isEmpty()) {
265                     LOG.warn("Rule {} in Subject {} in Contract {} doesn't have actions", rule.getName(), subjectRef,
266                             contract.getId());
267                 }
268             }
269
270             securityRules.add(new SecurityRuleBuilder().setName(new Name(rule.getName().getValue()))
271                 .setOrder(rule.getOrder())
272                 .setRuleClassifier(pClassifiers)
273                 .setRuleAction(pActions)
274                 .build());
275         } // for rules
276         return securityRules;
277     }
278
279     private List<RuleAction> getActions(Contract contract, List<ActionRef> actionRefs) {
280         LOG.trace("Start Parsing Actions for actionRefs count {} in Contract {}", actionRefs.size(), contract.getId()
281             .getValue());
282         List<RuleAction> pActions = new ArrayList<>();
283         for (ActionRef actionRef : actionRefs) {
284             if (actionRef.getName() == null) {
285                 LOG.warn("Couldn't find an Action in Contract {} -- ignored Action", contract.getId().getValue());
286                 continue;
287             }
288             RuleActionBuilder ruleActionBuilder = new RuleActionBuilder();
289             ruleActionBuilder.setName(new Name(actionRef.getName().getValue()));
290             ruleActionBuilder.setOrder(actionRef.getOrder());
291             ActionInstance actionInstance = getActionInstance(actionRef.getName());
292             if (actionInstance == null) {
293                 LOG.warn("Action instance {} is not found -- will only use the Action ref info", actionRef.getName());
294             } else {
295                 if (actionInstance.getActionDefinitionId() != null) {
296                     ruleActionBuilder.setAdditionalInfo(new Text(actionInstance.getActionDefinitionId().getValue()));
297                 }
298                 List<ParameterValue> parms = null;
299                 if (actionInstance.getParameterValue() != null) {
300                     LOG.trace("Action Instance {} has {} parameters", actionInstance.getName().getValue(),
301                             actionInstance.getParameterValue().size());
302                     parms = new ArrayList<>();
303                     for (org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue instance : actionInstance.getParameterValue()) {
304                         ParameterValueBuilder pBuilder = new ParameterValueBuilder();
305                         pBuilder.setIntValue(instance.getIntValue());
306                         if (instance.getName() != null) {
307                             pBuilder.setName(new Name(instance.getName().getValue()));
308                         }
309                         pBuilder.setStringValue(instance.getStringValue());
310                         if (instance.getRangeValue() != null) {
311                             RangeValueBuilder rBuilder = new RangeValueBuilder().setMax(
312                                     instance.getRangeValue().getMax()).setMin(instance.getRangeValue().getMin());
313                             pBuilder.setRangeValue(rBuilder.build());
314                         }
315                         ParameterValue parm = pBuilder.build();
316                         LOG.trace("Added Parm {} from Action Instance {}", parm, actionInstance.getName().getValue());
317                         parms.add(parm);
318                     }
319                 } else {
320                     LOG.trace("Action Instance {} has no parameters", actionInstance.getName().getValue());
321                 }
322                 ruleActionBuilder.setParameterValue(parms);
323             }
324             pActions.add(ruleActionBuilder.build());
325         }
326
327         return pActions;
328     }
329
330     private ActionInstance getActionInstance(ActionName name) {
331         ReadOnlyTransaction trans = dataProvider.newReadOnlyTransaction();
332         InstanceIdentifier<ActionInstance> ciId = InstanceIdentifier.builder(Tenants.class)
333             .child(Tenant.class, new TenantKey(gbpTenantId))
334             .child(Policy.class)
335             .child(SubjectFeatureInstances.class)
336             .child(ActionInstance.class, new ActionInstanceKey(name))
337             .build();
338         try {
339             Optional<ActionInstance> data = trans.read(LogicalDatastoreType.CONFIGURATION, ciId).get();
340             if (data.isPresent()) {
341                 return data.get();
342             }
343         } catch (Exception e) {
344             LOG.error("Couldn't read Action instance from datastore. Exception: ", e);
345         }
346         return null;
347     }
348
349     private List<RuleClassifier> getClassifiers(TenantId tenantId, Contract contract,
350             List<ClassifierRef> classifierRefs, DataBroker dataProvider) {
351         List<RuleClassifier> fClassifiers = new ArrayList<>();
352         for (ClassifierRef classifierRef : classifierRefs) {
353             if (classifierRef.getName() == null) {
354                 LOG.warn("Found a Classifer without name in Contract {} ", contract.getId().getValue());
355                 continue;
356             }
357             RuleClassifierBuilder ruleClassifierBuilder = new RuleClassifierBuilder();
358             ruleClassifierBuilder.setName(new Name(classifierRef.getName().getValue()));
359             ClassifierInstance classifierInstance = getClassifierInstance(tenantId, classifierRef.getName(),
360                     dataProvider);
361             if (classifierInstance == null) {
362                 LOG.warn("Classifer instance {} is not found -- will only use the classifier Ref info",
363                         classifierRef.getName());
364             } else {
365                 if (classifierInstance.getClassifierDefinitionId() != null) {
366                     ruleClassifierBuilder.setAdditionalInfo(new Text(classifierInstance.getClassifierDefinitionId()
367                         .getValue()));
368                 }
369                 List<ParameterValue> parms = null;
370                 if (classifierInstance.getParameterValue() != null) {
371                     LOG.trace("Calssifier Instance {} has {} parameters", classifierInstance.getName().getValue(),
372                             classifierInstance.getParameterValue().size());
373                     parms = new ArrayList<>();
374                     for (org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue instance : classifierInstance.getParameterValue()) {
375                         ParameterValueBuilder pBuilder = new ParameterValueBuilder();
376                         pBuilder.setIntValue(instance.getIntValue());
377                         pBuilder.setName(new Name(instance.getName().getValue()));
378                         pBuilder.setStringValue(instance.getStringValue());
379                         if (instance.getRangeValue() != null) {
380                             RangeValueBuilder rBuilder = new RangeValueBuilder().setMax(
381                                     instance.getRangeValue().getMax()).setMin(instance.getRangeValue().getMin());
382                             pBuilder.setRangeValue(rBuilder.build());
383                         }
384                         ParameterValue parm = pBuilder.build();
385                         LOG.trace("Added parm {} from Classifier Instance {}", parm, classifierInstance.getName()
386                             .getValue());
387                         parms.add(parm);
388                     }
389                 } else {
390                     LOG.trace("Classifier Instance {} has no parameters", classifierInstance.getName().getValue());
391                 }
392                 ruleClassifierBuilder.setParameterValue(parms);
393             }
394             if (classifierRef.getDirection() != null) {
395                 ruleClassifierBuilder.setDirection(Direction.forValue(classifierRef.getDirection().getIntValue()));
396             } else {
397                 ruleClassifierBuilder.setDirection(Direction.Bidirectional);
398             }
399             fClassifiers.add(ruleClassifierBuilder.build());
400         }
401         return fClassifiers;
402     }
403
404     private ClassifierInstance getClassifierInstance(TenantId tenantId, ClassifierName name, DataBroker dataProvider) {
405         ReadOnlyTransaction trans = dataProvider.newReadOnlyTransaction();
406         InstanceIdentifier<ClassifierInstance> ciId = InstanceIdentifier.builder(Tenants.class)
407             .child(Tenant.class, new TenantKey(tenantId))
408             .child(Policy.class)
409             .child(SubjectFeatureInstances.class)
410             .child(ClassifierInstance.class, new ClassifierInstanceKey(name))
411             .build();
412         try {
413             Optional<ClassifierInstance> data = trans.read(LogicalDatastoreType.CONFIGURATION, ciId).get();
414             if (data.isPresent()) {
415                 return data.get();
416             }
417         } catch (Exception e) {
418             LOG.error("Couldn't read Action instance from datastore. Exception: ", e);
419         }
420         return null;
421     }
422 }