Fixing issues with ARP integration of VpnService
[vpnservice.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / vpnservice / mdsalutil / MDSALUtil.java
1 /*
2  * Copyright (c) 2015 - 2016 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
9 package org.opendaylight.vpnservice.mdsalutil;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.concurrent.ConcurrentHashMap;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.LinkedBlockingQueue;
19
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder;
71 import org.opendaylight.yangtools.yang.binding.DataObject;
72 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
73 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
74 import org.opendaylight.yangtools.yang.binding.DataObject;
75 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
76 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
77 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
78 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
79 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
80 import org.slf4j.Logger;
81 import org.slf4j.LoggerFactory;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
83 import org.opendaylight.controller.liblldp.HexEncode;
84 import com.google.common.base.Joiner;
85 import com.google.common.base.Optional;
86 import com.google.common.primitives.Bytes;
87 import com.google.common.primitives.Ints;
88 import com.google.common.util.concurrent.CheckedFuture;
89
90 public class MDSALUtil {
91
92     public static final String NODE_PREFIX = "openflow";
93     public static final String SEPARATOR = ":";
94     private static final Buckets EMPTY_Buckets = new BucketsBuilder().build();
95     private static final Instructions EMPTY_Instructions = new InstructionsBuilder().setInstruction(
96             new ArrayList<Instruction>()).build();
97     private static final Match EMPTY_Matches = new MatchBuilder().build();
98     private static final Logger logger = LoggerFactory.getLogger(MDSALUtil.class);
99
100     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId, int priority, String flowName,
101             int idleTimeOut, int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
102             List<InstructionInfo> listInstructionInfo) {
103
104         FlowEntity flowEntity = new FlowEntity(dpnId);
105
106         flowEntity.setTableId(tableId);
107         flowEntity.setFlowId(flowId);
108         flowEntity.setPriority(priority);
109         flowEntity.setFlowName(flowName);
110         flowEntity.setIdleTimeOut(idleTimeOut);
111         flowEntity.setHardTimeOut(hardTimeOut);
112         flowEntity.setCookie(cookie);
113         flowEntity.setMatchInfoList(listMatchInfo);
114         flowEntity.setInstructionInfoList(listInstructionInfo);
115
116         return flowEntity;
117     }
118
119     // TODO: CHECK IF THIS IS USED
120     public static Flow buildFlow(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
121             int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo, List<InstructionInfo> listInstructionInfo) {
122         return MDSALUtil.buildFlow(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie,
123                 listMatchInfo, listInstructionInfo, true);
124     }
125
126     public static Flow buildFlow(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
127             int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
128             List<InstructionInfo> listInstructionInfo, boolean isStrict) {
129         FlowKey key = new FlowKey(new FlowId(flowId));
130         return new FlowBuilder().setMatch(buildMatches(listMatchInfo)).setKey(key)
131                 .setPriority(Integer.valueOf(priority)).setInstructions(buildInstructions(listInstructionInfo))
132                 .setBarrier(false).setInstallHw(true).setHardTimeout(hardTimeOut).setIdleTimeout(idleTimeOut)
133                 .setFlowName(flowName).setTableId(Short.valueOf(tableId)).setStrict(isStrict)
134                 .setCookie(new FlowCookie(cookie)).build();
135     }
136
137     public static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
138                                  int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo, List<Instruction> listInstructionInfo) {
139         return MDSALUtil.buildFlowNew(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie,
140                 listMatchInfo, listInstructionInfo, true);
141     }
142
143     private static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
144                                   int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
145                                   List<Instruction> listInstructionInfo, boolean isStrict) {
146         FlowKey key = new FlowKey(new FlowId(flowId));
147         return new FlowBuilder().setMatch(buildMatches(listMatchInfo)).setKey(key)
148                 .setPriority(Integer.valueOf(priority)).setInstructions(new InstructionsBuilder().setInstruction(listInstructionInfo).build())
149                 .setBarrier(false).setInstallHw(true).setHardTimeout(hardTimeOut).setIdleTimeout(idleTimeOut)
150                 .setFlowName(flowName).setTableId(Short.valueOf(tableId)).setStrict(isStrict)
151                 .setCookie(new FlowCookie(cookie)).build();
152     }
153
154     public static GroupEntity buildGroupEntity(BigInteger dpnId, long groupId, String groupName, GroupTypes groupType,
155             List<BucketInfo> listBucketInfo) {
156
157         GroupEntity groupEntity = new GroupEntity(dpnId);
158
159         groupEntity.setGroupId(groupId);
160         groupEntity.setGroupName(groupName);
161         groupEntity.setGroupType(groupType);
162         groupEntity.setBucketInfoList(listBucketInfo);
163
164         return groupEntity;
165     }
166
167     public static TransmitPacketInput getPacketOutDefault(List<ActionInfo> actionInfos, byte[] payload, BigInteger dpnId) {
168         return new TransmitPacketInputBuilder()
169                 .setAction(buildActions(actionInfos))
170                 .setPayload(payload)
171                 .setNode(
172                         new NodeRef(InstanceIdentifier.builder(Nodes.class)
173                                 .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance()))
174                 .setIngress(getDefaultNodeConnRef(dpnId)).setEgress(getDefaultNodeConnRef(dpnId)).build();
175     }
176
177     public static TransmitPacketInput getPacketOut(List<ActionInfo> actionInfos, byte[] payload, long dpnId,
178             NodeConnectorRef ingress) {
179         return new TransmitPacketInputBuilder()
180                 .setAction(buildActions(actionInfos))
181                 .setPayload(payload)
182                 .setNode(
183                         new NodeRef(InstanceIdentifier.builder(Nodes.class)
184                                 .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance()))
185                 .setIngress(ingress).setEgress(ingress).build();
186     }
187
188     private static List<Action> buildActions(List<ActionInfo> actions) {
189         List<Action> actionsList = new ArrayList<Action>();
190         for (ActionInfo actionInfo : actions) {
191             actionsList.add(actionInfo.buildAction());
192         }
193         return actionsList;
194     }
195
196     public static String longToIp(long ip, long mask) {
197         StringBuilder sb = new StringBuilder(15);
198         Joiner joiner = Joiner.on('.');
199
200         joiner.appendTo(sb, Bytes.asList(Ints.toByteArray((int) ip)));
201
202         sb.append("/" + mask);
203
204         return sb.toString();
205     }
206
207     protected static Buckets buildBuckets(List<BucketInfo> listBucketInfo) {
208         long i = 0;
209         if (listBucketInfo != null) {
210             BucketsBuilder bucketsBuilder = new BucketsBuilder();
211             List<Bucket> bucketList = new ArrayList<Bucket>();
212
213             for (BucketInfo bucketInfo : listBucketInfo) {
214                 BucketBuilder bucketBuilder = new BucketBuilder();
215                 List<Action> actionsList = new ArrayList<Action>();
216
217                 bucketInfo.buildAndAddActions(actionsList);
218                 bucketBuilder.setAction(actionsList);
219                 bucketBuilder.setWeight(bucketInfo.getWeight());
220                 bucketBuilder.setBucketId(new BucketId(i++));
221                 bucketBuilder.setWeight(bucketInfo.getWeight()).setWatchPort(bucketInfo.getWatchPort())
222                         .setWatchGroup(bucketInfo.getWatchGroup());
223                 bucketList.add(bucketBuilder.build());
224             }
225
226             bucketsBuilder.setBucket(bucketList);
227             return bucketsBuilder.build();
228         }
229
230         return EMPTY_Buckets;
231     }
232
233     protected static Instructions buildInstructions(List<InstructionInfo> listInstructionInfo) {
234         if (listInstructionInfo != null) {
235             List<Instruction> instructions = new ArrayList<Instruction>();
236             int instructionKey = 0;
237
238             for (InstructionInfo instructionInfo : listInstructionInfo) {
239                 instructions.add(instructionInfo.buildInstruction(instructionKey));
240                 instructionKey++;
241             }
242
243             return new InstructionsBuilder().setInstruction(instructions).build();
244         }
245
246         return EMPTY_Instructions;
247     }
248
249     protected static Match buildMatches(List<MatchInfo> listMatchInfo) {
250         if (listMatchInfo != null) {
251             MatchBuilder matchBuilder = new MatchBuilder();
252             Map<Class<?>, Object> mapMatchBuilder = new HashMap<Class<?>, Object>();
253
254             for (MatchInfo matchInfo : listMatchInfo) {
255                 matchInfo.createInnerMatchBuilder(mapMatchBuilder);
256             }
257
258             for (MatchInfo matchInfo : listMatchInfo) {
259                 matchInfo.setMatch(matchBuilder, mapMatchBuilder);
260             }
261
262             return matchBuilder.build();
263         }
264
265         return EMPTY_Matches;
266     }
267
268     // TODO: Check the port const
269     public static NodeConnectorRef getDefaultNodeConnRef(BigInteger nDpId) {
270         return getNodeConnRef(NODE_PREFIX + SEPARATOR + nDpId, "0xfffffffd");
271     }
272
273     public static NodeConnectorRef getNodeConnRef(BigInteger nDpId, String port) {
274         return getNodeConnRef(NODE_PREFIX + SEPARATOR + nDpId, port);
275     }
276
277     public static NodeConnectorRef getNodeConnRef(String sNodeId, String port) {
278         String sNodeConnectorKey;
279         StringBuilder sbTmp;
280         NodeId nodeId;
281         NodeKey nodeKey;
282         NodeConnectorId nodeConnectorId;
283         NodeConnectorKey nodeConnectorKey;
284         InstanceIdentifierBuilder<Nodes> nodesInstanceIdentifierBuilder;
285         InstanceIdentifierBuilder<Node> nodeInstanceIdentifierBuilder;
286         InstanceIdentifierBuilder<NodeConnector> nodeConnectorInstanceIdentifierBuilder;
287         InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifier;
288         NodeConnectorRef nodeConnectorRef;
289
290         sbTmp = new StringBuilder();
291
292         sbTmp.append(sNodeId);
293         sbTmp.append(SEPARATOR);
294         sbTmp.append(port);
295
296         sNodeConnectorKey = sbTmp.toString();
297         nodeConnectorId = new NodeConnectorId(sNodeConnectorKey);
298         nodeConnectorKey = new NodeConnectorKey(nodeConnectorId);
299
300         nodeId = new NodeId(sNodeId);
301         nodeKey = new NodeKey(nodeId);
302
303         nodesInstanceIdentifierBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
304         nodeInstanceIdentifierBuilder = nodesInstanceIdentifierBuilder.<Node, NodeKey> child(Node.class, nodeKey);
305         nodeConnectorInstanceIdentifierBuilder = nodeInstanceIdentifierBuilder.<NodeConnector, NodeConnectorKey> child(
306                 NodeConnector.class, nodeConnectorKey);
307         nodeConnectorInstanceIdentifier = nodeConnectorInstanceIdentifierBuilder.toInstance();
308         nodeConnectorRef = new NodeConnectorRef(nodeConnectorInstanceIdentifier);
309         return nodeConnectorRef;
310     }
311
312     public static BigInteger getDpnIdFromNodeName(NodeId nodeId) {
313         return getDpnIdFromNodeName(nodeId.getValue());
314     }
315
316     public static BigInteger getDpnIdFromNodeName(String sMdsalNodeName) {
317         String sDpId = sMdsalNodeName.substring(sMdsalNodeName.lastIndexOf(":") + 1);
318         return new BigInteger(sDpId);
319     }
320
321     public static long getOfPortNumberFromPortName(NodeConnectorId nodeConnectorId) {
322         return getOfPortNumberFromPortName(nodeConnectorId.getValue());
323     }
324
325     public static long getDpnIdFromPortName(NodeConnectorId nodeConnectorId) {
326         String ofPortName = nodeConnectorId.getValue();
327         return Long.parseLong(ofPortName.substring(ofPortName.indexOf(":")+1, 
328                 ofPortName.lastIndexOf(":")));
329     }
330
331     public static long getOfPortNumberFromPortName(String sMdsalPortName) {
332         String sPortNumber = sMdsalPortName.substring(sMdsalPortName.lastIndexOf(":") + 1);
333         return Long.parseLong(sPortNumber);
334     }
335
336     public static TransmitPacketInput getPacketOut(List<ActionInfo> actionInfos, byte[] payload, BigInteger dpnId,
337                     NodeConnectorRef nodeConnRef) {
338         // TODO Auto-generated method stub
339         return null;
340     }
341
342     public static Instruction buildAndGetPopVlanActionInstruction(int actionKey, int instructionKey) {
343         Action popVlanAction = new ActionBuilder().setAction(
344                 new PopVlanActionCaseBuilder().setPopVlanAction(new PopVlanActionBuilder().build()).build())
345                 .setKey(new ActionKey(actionKey)).build();
346         List<Action> listAction = new ArrayList<Action> ();
347         listAction.add(popVlanAction);
348         ApplyActions applyActions = new ApplyActionsBuilder().setAction(listAction).build();
349         ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();
350         InstructionBuilder instructionBuilder = new InstructionBuilder();
351
352         instructionBuilder.setInstruction(applyActionsCase);
353         instructionBuilder.setKey(new InstructionKey(instructionKey));
354         return instructionBuilder.build();
355     }
356
357     public static Instruction buildAndGetWriteMetadaInstruction(BigInteger metadata,
358                                                                 BigInteger mask, int instructionKey) {
359         return new InstructionBuilder()
360                 .setInstruction(
361                         new WriteMetadataCaseBuilder().setWriteMetadata(
362                                 new WriteMetadataBuilder().setMetadata(metadata).setMetadataMask(mask).build())
363                                 .build()).setKey(new InstructionKey(instructionKey)).build();
364     }
365
366     public static Instruction buildAndGetGotoTableInstruction(short tableId, int instructionKey) {
367         return new InstructionBuilder()
368             .setInstruction(
369                 new GoToTableCaseBuilder().setGoToTable(
370                     new GoToTableBuilder().setTableId(tableId).build()).build())
371             .setKey(new InstructionKey(instructionKey)).build();
372     }
373
374     public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
375                                                           InstanceIdentifier<T> path, DataBroker broker) {
376
377         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
378
379         Optional<T> result = Optional.absent();
380         try {
381             result = tx.read(datastoreType, path).get();
382         } catch (Exception e) {
383             logger.error("An error occured while reading data from the path {} with the exception {}", path, e);
384         }
385         return result;
386     }
387
388     public static <T extends DataObject> Optional<T> read(DataBroker broker,
389                                                           LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
390
391         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
392
393         Optional<T> result = Optional.absent();
394         try {
395             result = tx.read(datastoreType, path).get();
396         } catch (Exception e) {
397             throw new RuntimeException(e);
398         }
399         return result;
400     }
401
402     public static <T extends DataObject> void syncWrite(DataBroker broker,
403                                                         LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
404                                                         T data) {
405         WriteTransaction tx = broker.newWriteOnlyTransaction();
406         tx.put(datastoreType, path, data, true);
407         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
408         try {
409             futures.get();
410         } catch (InterruptedException | ExecutionException e) {
411             logger.error("Error writing to datastore (path, data) : ({}, {})", path, data);
412             throw new RuntimeException(e.getMessage());
413         }
414     }
415
416     public static <T extends DataObject> void syncUpdate(DataBroker broker,
417                                                          LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
418                                                          T data) {
419         WriteTransaction tx = broker.newWriteOnlyTransaction();
420         tx.merge(datastoreType, path, data, true);
421         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
422         try {
423             futures.get();
424         } catch (InterruptedException | ExecutionException e) {
425             logger.error("Error writing to datastore (path, data) : ({}, {})", path, data);
426             throw new RuntimeException(e.getMessage());
427         }
428     }
429
430     public static <T extends DataObject> void syncDelete(DataBroker broker,
431                                                          LogicalDatastoreType datastoreType, InstanceIdentifier<T> obj) {
432         WriteTransaction tx = broker.newWriteOnlyTransaction();
433         tx.delete(datastoreType, obj);
434         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
435         try {
436             futures.get();
437         } catch (InterruptedException | ExecutionException e) {
438             logger.error("Error deleting from datastore (path) : ({})", obj);
439             throw new RuntimeException(e.getMessage());
440         }
441     }
442
443     public static byte[] getMacAddressForNodeConnector(DataBroker broker,
444             InstanceIdentifier<NodeConnector> nodeConnectorId)  {
445         Optional<NodeConnector> optNc = MDSALDataStoreUtils.read(broker,
446                 LogicalDatastoreType.OPERATIONAL, nodeConnectorId);
447         if(optNc.isPresent()) {
448             NodeConnector nc = optNc.get();
449             FlowCapableNodeConnector fcnc = nc.getAugmentation(FlowCapableNodeConnector.class);
450             MacAddress macAddress = fcnc.getHardwareAddress();
451             return HexEncode.bytesFromHexString(macAddress.getValue());
452         }
453         return null;
454     }
455
456     public static NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
457         return new NodeId(ncId.getValue().substring(0,
458                 ncId.getValue().lastIndexOf(":")));
459     }
460
461     public static String getInterfaceName(NodeConnectorRef ref, DataBroker dataBroker) {
462         NodeConnectorId nodeConnectorId = getNodeConnectorId(dataBroker, ref);
463         NodeId nodeId = getNodeIdFromNodeConnectorId(nodeConnectorId);
464         InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier
465                 .builder(Nodes.class)
466                 .child(Node.class, new NodeKey(nodeId))
467                 .child(NodeConnector.class,
468                         new NodeConnectorKey(nodeConnectorId)).build();
469
470         Optional<NodeConnector> nodeConnectorOptional = read(
471                 dataBroker,
472                 LogicalDatastoreType.OPERATIONAL, ncIdentifier);
473         if (!nodeConnectorOptional.isPresent()) {
474             return null;
475         }
476         NodeConnector nc = nodeConnectorOptional.get();
477         FlowCapableNodeConnector fc = nc
478                 .getAugmentation(FlowCapableNodeConnector.class);
479         return fc.getName();
480     }
481
482     public static NodeConnectorId getNodeConnectorId(DataBroker dataBroker,
483             NodeConnectorRef ref) {
484         Optional<NodeConnector> nc = (Optional<NodeConnector>) read(
485                 dataBroker,
486                 LogicalDatastoreType.OPERATIONAL, ref.getValue());
487         if(nc.isPresent()){
488             return nc.get().getId();
489         }
490         return null;
491     }
492
493 }