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