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