Bump odlparent->6.0.0,mdsal->5.0.3
[netvirt.git] / elanmanager / impl / src / test / java / org / opendaylight / netvirt / elanmanager / tests / Verifications.java
1 /*
2  * Copyright © 2017 Ericsson India Global Services Pvt Ltd. 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 package org.opendaylight.netvirt.elanmanager.tests;
9
10 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
11
12 import com.google.common.collect.Sets;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.concurrent.ExecutionException;
19 import java.util.function.BiPredicate;
20 import java.util.function.Function;
21 import java.util.stream.Collectors;
22 import org.awaitility.core.ConditionFactory;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
25 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
26 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
27 import org.opendaylight.genius.mdsalutil.MDSALUtil;
28 import org.opendaylight.genius.mdsalutil.NwConstants;
29 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
30 import org.opendaylight.genius.testutils.interfacemanager.TunnelInterfaceDetails;
31 import org.opendaylight.mdsal.binding.testutils.AssertDataObjects;
32 import org.opendaylight.netvirt.elan.utils.ElanUtils;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
60 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
63 import org.opendaylight.yangtools.yang.binding.DataObject;
64 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
65 import org.opendaylight.yangtools.yang.common.Uint32;
66 import org.opendaylight.yangtools.yang.common.Uint64;
67
68 public class Verifications {
69
70     private static final boolean CHECK_FOR_EXISTS = true;
71     private static final boolean CHECK_FOR_DELETED = false;
72     private static final Function<Uint64, NodeId> GET_OPENFLOW_NODE_ID = (dpnId) -> new NodeId("openflow:" + dpnId);
73     private static final InstanceIdentifier<ElanInstance> ELAN_IID = InstanceIdentifier
74             .builder(ElanInstances.class)
75             .child(ElanInstance.class, new ElanInstanceKey(ExpectedObjects.ELAN1))
76             .build();
77     private static final BiPredicate<Group, Group> BUCKETS_SIZE_MIS_MATCHED = (actual, expected) -> {
78         return !(actual.getBuckets().getBucket().size() == expected.getBuckets().getBucket().size());
79     };
80
81     private final SingleTransactionDataBroker singleTxdataBroker;
82     private final OdlInterfaceRpcService odlInterfaceRpcService;
83     private final Map<String, TunnelInterfaceDetails> extnIntfs;
84     private final ConditionFactory awaiter;
85
86     public Verifications(final SingleTransactionDataBroker singleTxdataBroker,
87                          final OdlInterfaceRpcService odlInterfaceRpcService,
88                          final Map<String, TunnelInterfaceDetails> extnIntfs,
89                          final ConditionFactory awaiter) {
90         this.singleTxdataBroker = singleTxdataBroker;
91         this.odlInterfaceRpcService = odlInterfaceRpcService;
92         this.extnIntfs = extnIntfs;
93         this.awaiter = awaiter;
94     }
95
96     private void awaitForData(LogicalDatastoreType dsType, InstanceIdentifier<? extends DataObject> iid) {
97         awaiter.until(() -> singleTxdataBroker.syncReadOptional(dsType, iid).isPresent());
98     }
99
100     private void awaitForDataDelete(LogicalDatastoreType dsType, InstanceIdentifier<? extends DataObject> iid) {
101         awaiter.until(() -> !singleTxdataBroker.syncReadOptional(dsType, iid).isPresent());
102     }
103
104     public void verifyThatMcastMacTepsCreated(InstanceIdentifier<Node> torNodeId, List<String> tepIps) {
105         for (String tepIp : tepIps) {
106             awaiter.until(() -> checkForRemoteMcastMac(torNodeId, tepIp, CHECK_FOR_EXISTS));
107         }
108     }
109
110     public void verifyThatMcastMacTepsDeleted(InstanceIdentifier<Node> torNodeId, List<String> tepIps) {
111         for (String tepIp : tepIps) {
112             awaiter.until(() -> checkForRemoteMcastMac(torNodeId, tepIp, CHECK_FOR_DELETED));
113         }
114     }
115
116     private boolean checkForRemoteMcastMac(InstanceIdentifier<Node> torNodeId, String tepIp, boolean checkForExists) {
117         try {
118             Node node = singleTxdataBroker.syncRead(LogicalDatastoreType.CONFIGURATION, torNodeId);
119             HwvtepGlobalAugmentation augmentation = node.augmentation(HwvtepGlobalAugmentation.class);
120             if (augmentation == null || augmentation.getRemoteMcastMacs() == null
121                     || augmentation.getRemoteMcastMacs().isEmpty()) {
122                 if (checkForExists) {
123                     return false;
124                 } else {
125                     return true;
126                 }
127             }
128             boolean remoteMcastFoundFlag = false;
129             for (RemoteMcastMacs remoteMcastMacs : augmentation.getRemoteMcastMacs()) {
130                 for (LocatorSet locatorSet : remoteMcastMacs.getLocatorSet()) {
131                     TpId tpId = locatorSet.getLocatorRef().getValue().firstKeyOf(TerminationPoint.class).getTpId();
132                     if (tpId.getValue().contains(tepIp)) {
133                         remoteMcastFoundFlag = true;
134                         break;
135                     }
136                 }
137             }
138             if (checkForExists) {
139                 return remoteMcastFoundFlag == true;
140             } else {
141                 return remoteMcastFoundFlag == false;
142             }
143         } catch (ReadFailedException e) {
144             return false;
145         }
146     }
147
148     public void verifyThatUcastCreated(InstanceIdentifier<Node> torNodeId, List<String> macs) {
149         for (String mac : macs) {
150             awaiter.until(() -> checkForRemoteUcastMac(torNodeId, mac, CHECK_FOR_EXISTS));
151         }
152     }
153
154     public void verifyThatUcastDeleted(InstanceIdentifier<Node> torNodeId, List<String> macs) {
155         for (String mac : macs) {
156             awaiter.until(() -> checkForRemoteUcastMac(torNodeId, mac, CHECK_FOR_DELETED));
157         }
158     }
159
160     public boolean checkForRemoteUcastMac(InstanceIdentifier<Node> torNodeId, String dpnMac, boolean checkForExists) {
161         try {
162             Node node = singleTxdataBroker.syncRead(LogicalDatastoreType.CONFIGURATION, torNodeId);
163             HwvtepGlobalAugmentation augmentation = node.augmentation(HwvtepGlobalAugmentation.class);
164             if (augmentation == null || augmentation.getRemoteUcastMacs() == null
165                     || augmentation.getRemoteUcastMacs().isEmpty()) {
166                 if (checkForExists) {
167                     return false;
168                 } else {
169                     return true;
170                 }
171             }
172             boolean remoteUcastFoundFlag = false;
173             for (RemoteUcastMacs remoteUcastMacs : augmentation.getRemoteUcastMacs()) {
174                 String mac = remoteUcastMacs.getMacEntryKey().getValue();
175                 if (mac.equals(dpnMac)) {
176                     remoteUcastFoundFlag = true;
177                     break;
178                 }
179             }
180             if (checkForExists) {
181                 return remoteUcastFoundFlag == true;
182             } else {
183                 return remoteUcastFoundFlag == false;
184             }
185         } catch (ReadFailedException e) {
186             return false;
187         }
188     }
189
190     private List<Bucket> buildRemoteBcGroupBuckets(ElanInstance elanInfo,
191                                                   List<Uint64> otherDpns,
192                                                   List<String> otherTors,
193                                                   Uint64 dpnId,
194                                                   int bucketId)
195             throws ExecutionException, InterruptedException {
196         List<Bucket> listBucketInfo = new ArrayList<>();
197         if (otherDpns != null) {
198             for (Uint64 otherDpn : otherDpns) {
199                 GetEgressActionsForInterfaceInput getEgressActInput = new GetEgressActionsForInterfaceInputBuilder()
200                         .setIntfName(extnIntfs.get(dpnId + ":" + otherDpn).getInterfaceInfo().getInterfaceName())
201                         .setTunnelKey(elanInfo.getElanTag()).build();
202                 List<Action> actionsList =
203                         odlInterfaceRpcService.getEgressActionsForInterface(getEgressActInput).get().getResult()
204                                 .getAction();
205                 listBucketInfo.add(MDSALUtil.buildBucket(actionsList, MDSALUtil.GROUP_WEIGHT, bucketId,
206                         MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
207
208                 bucketId++;
209             }
210         }
211
212         if (otherTors != null) {
213             for (String otherTor : otherTors) {
214                 GetEgressActionsForInterfaceInput getEgressActInput = new GetEgressActionsForInterfaceInputBuilder()
215                         .setIntfName(extnIntfs.get(dpnId + ":" + otherTor).getInterfaceInfo().getInterfaceName())
216                         .setTunnelKey(elanInfo.getSegmentationId()).build();
217                 List<Action> actionsList =
218                         odlInterfaceRpcService.getEgressActionsForInterface(getEgressActInput).get().getResult()
219                                 .getAction();
220                 listBucketInfo.add(MDSALUtil.buildBucket(actionsList, MDSALUtil.GROUP_WEIGHT, bucketId,
221                         MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
222
223                 bucketId++;
224             }
225         }
226         return listBucketInfo;
227     }
228
229     private Group buildStandardElanBroadcastGroups(ElanInstance elanInfo, Uint64 dpnId, List<Uint64> otherdpns,
230                                                   List<String> tepIps)
231             throws ExecutionException, InterruptedException {
232         List<Bucket> listBucket = new ArrayList<>();
233         int bucketId = 0;
234         int actionKey = 0;
235         Uint32 elanTag = elanInfo.getElanTag();
236         List<Action> listAction = new ArrayList<>();
237         listAction.add(new ActionGroup(ElanUtils.getElanLocalBCGId(elanTag.longValue())).buildAction(++actionKey));
238         listBucket.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,
239                 MDSALUtil.WATCH_GROUP));
240         bucketId++;
241         listBucket.addAll(buildRemoteBcGroupBuckets(elanInfo, otherdpns, tepIps, dpnId, bucketId));
242         long groupId = ElanUtils.getElanRemoteBCGId(elanTag.longValue());
243         Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
244                 MDSALUtil.buildBucketLists(listBucket));
245         return group;
246     }
247
248     private boolean validateGroup(ElanInstance actualElanInstances,
249                                  Uint64 dpnId,
250                                  List<Uint64> otherdpns,
251                                  List<String> torips)
252             throws ExecutionException, InterruptedException, ReadFailedException, TransactionCommitFailedException {
253         Group expected = buildStandardElanBroadcastGroups(actualElanInstances, dpnId, otherdpns, torips);
254         InstanceIdentifier<Group> grpIid = DpnNodeBuilders.createGroupIid(expected, dpnId);
255         Group actual = singleTxdataBroker.syncRead(CONFIGURATION, grpIid);
256         singleTxdataBroker.syncWrite(CONFIGURATION, grpIid, expected);
257         expected = singleTxdataBroker.syncRead(CONFIGURATION, grpIid);
258
259         if (BUCKETS_SIZE_MIS_MATCHED.test(expected, actual)) {
260             AssertDataObjects.assertEqualBeans(expected, actual);
261         }
262
263         Set<Bucket> actualBuckets = modifyBucketId(actual.getBuckets().getBucket());
264         Set<Bucket> expectedBuckets = modifyBucketId(expected.getBuckets().getBucket());
265         Set<Bucket> diff = Sets.difference(actualBuckets, expectedBuckets);
266         if (diff != null && !diff.isEmpty()) {
267             AssertDataObjects.assertEqualBeans(expected, actual);
268         }
269         return true;
270     }
271
272     private static Set<Bucket> modifyBucketId(List<Bucket> input) {
273         return input.stream()
274                 .map(bucket -> new BucketBuilder(bucket).setBucketId(new BucketId(1L))
275                         .withKey(new BucketKey(new BucketId(1L))).build())
276                 .collect(Collectors.toSet());
277     }
278
279     public void verifyThatDpnGroupUpdated(Uint64 dpnId, List<Uint64> otherdpns, List<String> othertors)
280             throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
281         verifyDPNGroup(dpnId, otherdpns, othertors, CHECK_FOR_EXISTS);
282     }
283
284     public void verifyThatDpnGroupDeleted(Uint64 dpnId)
285             throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
286         verifyDPNGroup(dpnId, Collections.emptyList(), Collections.emptyList(), CHECK_FOR_DELETED);
287     }
288
289     public void verifyLocalBcGroup(Uint64 dpnId, int expectedNoBuckets)
290             throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
291         awaiter.until(() -> {
292             ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, ELAN_IID);
293             InstanceIdentifier<Group> grpIid = buildLocalGroupIid(actualElanInstances, dpnId);
294             awaitForData(CONFIGURATION, grpIid);
295             Group localGroup = singleTxdataBroker.syncRead(CONFIGURATION, grpIid);
296             if (localGroup != null && localGroup.getBuckets() != null
297                     && localGroup.getBuckets().getBucket() != null) {
298                 return localGroup.getBuckets().getBucket().size() == expectedNoBuckets;
299             }
300             return false;
301         });
302     }
303
304     public void verifyThatLocalBcGroupDeleted(Uint64 dpnId)
305             throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
306         ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, ELAN_IID);
307         InstanceIdentifier<Group> grpIid = buildLocalGroupIid(actualElanInstances, dpnId);
308         awaitForDataDelete(CONFIGURATION, grpIid);
309     }
310
311     public void verifyDPNGroup(Uint64 dpnId,
312                                List<Uint64> otherdpns,
313                                List<String> othertors,
314                                boolean checkForExists)
315             throws ReadFailedException, TransactionCommitFailedException, ExecutionException, InterruptedException {
316
317         ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, ELAN_IID);
318         InstanceIdentifier<Group> grpIid = buildGroupIid(actualElanInstances, dpnId);
319
320         if (checkForExists) {
321             awaitForData(LogicalDatastoreType.CONFIGURATION, grpIid);
322             validateGroup(actualElanInstances, dpnId, otherdpns, othertors);
323         } else {
324             awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, grpIid);
325         }
326     }
327
328     public void verifyThatDmacFlowOfTORCreated(List<Uint64> dpns,
329                                                InstanceIdentifier<Node> torNodeId,
330                                                List<String> macs) throws ReadFailedException {
331         for (String mac : macs) {
332             for (Uint64 srcDpnId : dpns) {
333                 verifyDmacFlowOfTOR(srcDpnId, torNodeId, mac, CHECK_FOR_EXISTS);
334             }
335         }
336     }
337
338     public void verifyThatDmacFlowOfTORDeleted(List<Uint64> dpns,
339                                                InstanceIdentifier<Node> torNodeId,
340                                                List<String> macs) throws ReadFailedException {
341         for (String mac : macs) {
342             for (Uint64 srcDpnId : dpns) {
343                 verifyDmacFlowOfTOR(srcDpnId, torNodeId, mac, CHECK_FOR_DELETED);
344             }
345         }
346     }
347
348     public void verifyDmacFlowOfTOR(Uint64 srcDpnId,
349                                     InstanceIdentifier<Node> torNodeIid,
350                                     String mac,
351                                     boolean checkForExists) throws ReadFailedException {
352
353         String torNodeId = torNodeIid.firstKeyOf(Node.class).getNodeId().getValue();
354         ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, ELAN_IID);
355         FlowId flowId = new FlowId(
356                 ElanUtils.getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE,
357                         srcDpnId,
358                         torNodeId,
359                         mac,
360                         actualElanInstances.getElanTag().toJava(),
361                         false));
362
363         InstanceIdentifier<Flow> flowIid = getFlowIid(NwConstants.ELAN_DMAC_TABLE, flowId, srcDpnId);
364
365         if (checkForExists) {
366             awaitForData(LogicalDatastoreType.CONFIGURATION, flowIid);
367         } else {
368             awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, flowIid);
369         }
370     }
371
372     public void  verifyThatDmacOfOtherDpnCreated(Uint64 srcDpnId, Uint64 dpnId, List<String> dpnMacs)
373             throws ReadFailedException, InterruptedException {
374         for (String dpnMac : dpnMacs) {
375             verifyDmacFlowOfOtherDPN(srcDpnId, dpnId, dpnMac, CHECK_FOR_EXISTS);
376         }
377     }
378
379     public void  verifyThatDmacOfOtherDPNDeleted(Uint64 srcDpnId, Uint64 dpnId, List<String> dpnMacs)
380             throws ReadFailedException, InterruptedException {
381         for (String dpnMac : dpnMacs) {
382             verifyDmacFlowOfOtherDPN(srcDpnId, dpnId, dpnMac, CHECK_FOR_DELETED);
383         }
384     }
385
386     private void  verifyDmacFlowOfOtherDPN(Uint64 srcDpnId, Uint64 dpnId, String dpnMac, boolean createFlag)
387             throws ReadFailedException, InterruptedException {
388         InstanceIdentifier<ElanInstance> elanInstanceIid = InstanceIdentifier.builder(ElanInstances.class)
389                 .child(ElanInstance.class, new ElanInstanceKey(ExpectedObjects.ELAN1)).build();
390         ElanInstance actualElanInstances = singleTxdataBroker.syncRead(CONFIGURATION, elanInstanceIid);
391         FlowId flowId = new FlowId(
392                 ElanUtils.getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE,
393                         srcDpnId,
394                         dpnId,
395                         dpnMac,
396                         actualElanInstances.getElanTag()));
397         InstanceIdentifier<Flow> flowInstanceIidDst = getFlowIid(NwConstants.ELAN_DMAC_TABLE, flowId, srcDpnId);
398         if (createFlag) {
399             awaitForData(LogicalDatastoreType.CONFIGURATION, flowInstanceIidDst);
400         } else {
401             awaitForDataDelete(LogicalDatastoreType.CONFIGURATION, flowInstanceIidDst);
402         }
403     }
404
405     private static InstanceIdentifier<Flow> getFlowIid(short tableId, FlowId flowid, Uint64 dpnId) {
406
407         FlowKey flowKey = new FlowKey(new FlowId(flowid));
408         NodeId nodeId = GET_OPENFLOW_NODE_ID.apply(dpnId);
409         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node nodeDpn =
410                 new NodeBuilder().setId(nodeId).withKey(new NodeKey(nodeId)).build();
411         return InstanceIdentifier.builder(Nodes.class)
412                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
413                         nodeDpn.key()).augmentation(FlowCapableNode.class)
414                 .child(Table.class, new TableKey(tableId)).child(Flow.class, flowKey).build();
415     }
416
417     private static InstanceIdentifier<Group> buildGroupIid(ElanInstance actualElanInstances, Uint64 dpnId) {
418         return DpnNodeBuilders.buildGroupInstanceIdentifier(
419                 ElanUtils.getElanRemoteBCGId(actualElanInstances.getElanTag().toJava()),
420                 DpnNodeBuilders.buildDpnNode(dpnId));
421     }
422
423     private static InstanceIdentifier<Group> buildLocalGroupIid(ElanInstance actualElanInstances, Uint64 dpnId) {
424         return DpnNodeBuilders.buildGroupInstanceIdentifier(
425                 ElanUtils.getElanLocalBCGId(actualElanInstances.getElanTag().toJava()),
426                 DpnNodeBuilders.buildDpnNode(dpnId));
427     }
428 }