2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.genius.mdsalutil;
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;
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;
97 // This class needs to be mocked
98 @SuppressWarnings({ "checkstyle:AbbreviationAsWordInName", "checkstyle:FinalClass" })
99 public class MDSALUtil {
101 private static final Logger LOG = LoggerFactory.getLogger(MDSALUtil.class);
103 public enum MdsalOp { CREATION_OP, UPDATE_OP, REMOVAL_OP }
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();
115 private MDSALUtil() {
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) {
123 FlowEntityBuilder builder = new FlowEntityBuilder()
127 .setPriority(priority)
128 .setFlowName(flowName)
129 .setIdleTimeOut(idleTimeOut)
130 .setHardTimeOut(hardTimeOut)
132 if (listMatchInfoBase != null) {
133 builder.addAllMatchInfoList(listMatchInfoBase);
135 if (listInstructionInfo != null) {
136 builder.addAllInstructionInfoList(listInstructionInfo);
138 return builder.build();
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);
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();
164 public static Flow buildFlow(short tableId, String flowId) {
165 return new FlowBuilder().setTableId(tableId).setId(new FlowId(flowId)).build();
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);
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();
187 public static GroupEntity buildGroupEntity(Uint64 dpnId, long groupId, String groupName, GroupTypes groupType,
188 List<BucketInfo> listBucketInfo) {
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();
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();
205 public static TransmitPacketInput getPacketOutDefault(List<ActionInfo> actionInfos, byte[] payload,
207 return new TransmitPacketInputBuilder()
208 .setAction(buildActions(actionInfos))
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();
216 public static TransmitPacketInput getPacketOutFromController(List<ActionInfo> actionInfos, byte[] payload,
217 long dpnId, NodeConnectorRef egress) {
218 return new TransmitPacketInputBuilder()
219 .setAction(buildActions(actionInfos))
222 new NodeRef(InstanceIdentifier.builder(Nodes.class)
223 .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).build()))
224 .setEgress(egress).build();
227 public static TransmitPacketInput getPacketOut(List<ActionInfo> actionInfos, byte[] payload, long dpnId,
228 NodeConnectorRef ingress) {
229 return new TransmitPacketInputBuilder()
230 .setAction(buildActions(actionInfos))
233 new NodeRef(InstanceIdentifier.builder(Nodes.class)
234 .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).build()))
235 .setIngress(ingress).setEgress(ingress).build();
238 public static TransmitPacketInput getPacketOut(List<ActionInfo> actionInfos, byte[] payload, Uint64 dpnId,
239 NodeConnectorRef nodeConnRef) {
240 // TODO Auto-generated method stub
244 public static TransmitPacketInput getPacketOut(List<Action> actions, byte[] payload, Uint64 dpnId) {
245 NodeConnectorRef ncRef = getDefaultNodeConnRef(dpnId);
246 return new TransmitPacketInputBuilder()
250 new NodeRef(InstanceIdentifier.builder(Nodes.class)
251 .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).build()))
252 .setIngress(ncRef).setEgress(ncRef).build();
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();
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());
270 public static String longToIp(long ip, long mask) {
271 return ((ip & 0xFF000000) >> 3 * 8) + "."
272 + ((ip & 0x00FF0000) >> 2 * 8) + "."
273 + ((ip & 0x0000FF00) >> 8) + "."
275 + (mask == 0 ? "" : "/" + mask);
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);
285 public static Bucket buildBucket(List<Action> actionsList, int weight, int bucketId, long watchPort,
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();
292 public static Buckets buildBucketLists(List<Bucket> bucketList) {
293 return new BucketsBuilder().setBucket(bucketList).build();
296 protected static Buckets buildBuckets(List<BucketInfo> listBucketInfo) {
298 if (listBucketInfo != null) {
299 BucketsBuilder bucketsBuilder = new BucketsBuilder();
300 List<Bucket> bucketList = new ArrayList<>();
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());
312 bucketsBuilder.setBucket(bucketList);
313 return bucketsBuilder.build();
316 return EMPTY_BUCKETS;
319 public static Instructions buildInstructions(List<InstructionInfo> listInstructionInfo) {
320 if (listInstructionInfo != null) {
321 List<Instruction> instructions = new ArrayList<>();
322 int instructionKey = 0;
324 for (InstructionInfo instructionInfo : listInstructionInfo) {
325 instructions.add(instructionInfo.buildInstruction(instructionKey));
329 return new InstructionsBuilder().setInstruction(instructions).build();
332 return EMPTY_INSTRUCTIONS;
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<>();
340 for (MatchInfoBase matchInfoBase : listMatchInfoBase) {
341 matchInfoBase.createInnerMatchBuilder(mapMatchBuilder);
344 for (MatchInfoBase matchInfoBase : listMatchInfoBase) {
345 matchInfoBase.setMatch(matchBuilder, mapMatchBuilder);
348 return matchBuilder.build();
351 return EMPTY_MATCHES;
354 // TODO: Check the port const
355 public static NodeConnectorRef getDefaultNodeConnRef(Uint64 dpId) {
356 return getNodeConnRef(NODE_PREFIX + SEPARATOR + dpId, "0xfffffffd");
359 public static NodeConnectorRef getNodeConnRef(Uint64 dpId, String port) {
360 return getNodeConnRef(NODE_PREFIX + SEPARATOR + dpId, port);
363 public static NodeConnectorRef getNodeConnRef(String nodeId, String port) {
364 StringBuilder sb = new StringBuilder();
366 sb.append(SEPARATOR);
368 String nodeConnectorKeyAsString = sb.toString();
369 NodeConnectorId nodeConnectorId = new NodeConnectorId(nodeConnectorKeyAsString);
370 NodeConnectorKey nodeConnectorKey = new NodeConnectorKey(nodeConnectorId);
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;
383 public static Uint64 getDpnIdFromNodeName(NodeId nodeId) {
384 return getDpnIdFromNodeName(nodeId.getValue());
387 public static Uint64 getDpnIdFromNodeName(String mdsalNodeName) {
388 String dpId = mdsalNodeName.substring(mdsalNodeName.lastIndexOf(':') + 1);
389 return Uint64.valueOf(dpId);
392 public static long getOfPortNumberFromPortName(NodeConnectorId nodeConnectorId) {
393 return getOfPortNumberFromPortName(nodeConnectorId.getValue());
396 public static long getOfPortNumberFromPortName(String mdsalPortName) {
397 String portNumber = mdsalPortName.substring(mdsalPortName.lastIndexOf(':') + 1);
398 return Long.parseLong(portNumber);
401 public static long getDpnIdFromPortName(NodeConnectorId nodeConnectorId) {
402 if (nodeConnectorId == null || nodeConnectorId.getValue() == null) {
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");
415 public static Uint64 getDpnId(String datapathId) {
416 return datapathId == null ? null : Uint64.valueOf(datapathId.replace(":", ""), 16);
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);
430 * Create action to set REG6 to the given value.
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.
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)
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));
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)),
461 public static Instruction buildApplyActionsInstruction(List<Action> actions) {
462 return buildApplyActionsInstruction(actions, 0);
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();
470 instructionBuilder.setInstruction(applyActionsCase);
471 instructionBuilder.withKey(new InstructionKey(instructionKey));
472 return instructionBuilder.build();
475 public static Instruction buildWriteActionsInstruction(List<Action> actions) {
476 return buildWriteActionsInstruction(actions, 0);
480 * Build write actions instruction with the given actions and key.
482 * @param actions the actions.
483 * @param instructionKey the instruction key.
484 * @return the instruction.
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();
491 instructionBuilder.setInstruction(writeActionsCase);
492 instructionBuilder.withKey(new InstructionKey(instructionKey));
493 return instructionBuilder.build();
496 public static Instruction buildInstruction(Instruction instruction, int instructionKey) {
497 return new InstructionBuilder(instruction).withKey(new InstructionKey(instructionKey)).build();
500 public static List<Instruction> buildInstructionsDrop() {
501 return buildInstructionsDrop(0);
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;
513 * Build write actions instruction with the given actions and key.
515 * @param listAction the actions.
516 * @param instructionKey the instruction key.
517 * @return the instruction.
518 * @deprecated Use buildWriteActionsInstruction
521 public static Instruction getWriteActionsInstruction(List<Action> listAction, int instructionKey) {
522 return buildWriteActionsInstruction(listAction, instructionKey);
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)
533 .withKey(new InstructionKey(instructionKey)).build();
536 public static Instruction buildAndGetGotoTableInstruction(short tableId, int instructionKey) {
537 return new InstructionBuilder()
539 new GoToTableCaseBuilder().setGoToTable(
540 new GoToTableBuilder().setTableId(tableId).build()).build())
541 .withKey(new InstructionKey(instructionKey)).build();
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
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);
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
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);
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.
587 * {@link SingleTransactionDataBroker#syncWrite(
588 * DataBroker, LogicalDatastoreType, InstanceIdentifier, DataObject)}
589 * @param <T> DataObject subclass
592 public static <T extends DataObject> void syncWrite(DataBroker broker,
593 LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
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);
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.
611 * {@link SingleTransactionDataBroker#syncUpdate(
612 * DataBroker, LogicalDatastoreType, InstanceIdentifier, DataObject)}
613 * @param <T> DataObject subclass
616 public static <T extends DataObject> void syncUpdate(DataBroker broker,
617 LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
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);
630 * @param broker the broker
631 * @param datastoreType the {@link Datastore} type that will be accessed
632 * @param path The path to write to.
634 * {@link SingleTransactionDataBroker#syncDelete(DataBroker, LogicalDatastoreType, InstanceIdentifier)}
635 * @param <T> DataObject subclass
638 public static <T extends DataObject> void syncDelete(DataBroker broker,
639 LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
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);
648 public static NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
649 return new NodeId(ncId.getValue().substring(0,
650 ncId.getValue().lastIndexOf(':')));
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(
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);
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();
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();