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