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