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