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