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