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