gt:                     Action actionNewOrder = ab.build();
context: /*
   * Copyright (C) 2013 Red Hat, Inc.
   *
   * This program and the accompanying materials are made available under the
   * terms of the Eclipse Public License v1.0 which accompanies this distribution,
   * and is available at http://www.eclipse.org/legal/epl-v10.html
   *
   */
  package org.sdnhub.odl.tutorial.utils.openflow13;
  
  import static org.sdnhub.odl.tutorial.utils.openflow13.ActionUtils.dropAction;
  
  import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
  import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
  import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
  import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4MatchBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
  import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
  
  import com.google.common.collect.Lists;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.math.BigInteger;
  import java.util.ArrayList;
  import java.util.List;
  
  public class InstructionUtils {
      private static final Logger logger = LoggerFactory.getLogger(InstructionUtils.class);
      private static final int IPV4 = 0x8100;
      private static final int MAX_LENGTH = 0xffff;
  
      /**
       * Create Send to Controller Reserved Port Instruction (packet_in)
       *
       * @param ib Map InstructionBuilder without any instructions
       * @return ib Map InstructionBuilder with instructions
       */
      public static InstructionBuilder createSendToControllerInstructions(InstructionBuilder ib) {
  
          List<Action> actionList = Lists.newArrayList();
          ActionBuilder ab = new ActionBuilder();
  
          OutputActionBuilder output = new OutputActionBuilder();
          output.setMaxLength(MAX_LENGTH);
          Uri value = new Uri("CONTROLLER");
          output.setOutputNodeConnector(value);
          ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
          ab.setOrder(0);
          ab.setKey(new ActionKey(0));
          actionList.add(ab.build());
  
          // Create an Apply Action
          ApplyActionsBuilder aab = new ApplyActionsBuilder();
          aab.setAction(actionList);
  
          // Wrap our Apply Action in an Instruction
          ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
  
          return ib;
      }
  
      /**
       * Create NORMAL Reserved Port Instruction (packet_in)
       *
       * @param ib Map InstructionBuilder without any instructions
       * @return ib Map InstructionBuilder with instructions
       */
  
      public static InstructionBuilder createNormalInstructions(InstructionBuilder ib) {
  
          List<Action> actionList = Lists.newArrayList();
          ActionBuilder ab = new ActionBuilder();
  
          OutputActionBuilder output = new OutputActionBuilder();
          Uri value = new Uri("NORMAL");
          output.setOutputNodeConnector(value);
          ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
          ab.setOrder(0);
          ab.setKey(new ActionKey(0));
          actionList.add(ab.build());
  
          // Create an Apply Action
          ApplyActionsBuilder aab = new ApplyActionsBuilder();
          aab.setAction(actionList);
  
          // Wrap our Apply Action in an Instruction
          ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
  
          return ib;
      }
  
      /**
       * Create Output Port Instruction
       *
       * @param ib       Map InstructionBuilder without any instructions
       * @param dpidLong Long the datapath ID of a switch/node
       * @param port     Long representing a port on a switch/node
       * @return ib InstructionBuilder Map with instructions
       */
      public static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) {
  
          NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
          logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ",
                  dpidLong, port);
  
          List<Action> actionList = Lists.newArrayList();
          ActionBuilder ab = new ActionBuilder();
          OutputActionBuilder oab = new OutputActionBuilder();
          oab.setOutputNodeConnector(ncid);
  
          ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
          ab.setOrder(0);
          ab.setKey(new ActionKey(0));
          actionList.add(ab.build());
  
          // Create an Apply Action
          ApplyActionsBuilder aab = new ApplyActionsBuilder();
          aab.setAction(actionList);
          ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
  
          return ib;
      }
  
      /**
       * add Output Port action to Instruction action list.
       * This is use for flow with single output port actions.
       * Flow with mutiple output port actions should use createOutputPortInstructions() method.
       *
       * @param ib       Map InstructionBuilder without any instructions
       * @param dpidLong Long the datapath ID of a switch/node
       * @param port     Long representing a port on a switch/node
       * @return ib InstructionBuilder Map with instructions
       */
      public static InstructionBuilder addOutputPortInstructions(InstructionBuilder ib,
              Long dpidLong, Long port,
              List<Instruction> instructions) {
          NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
          logger.debug(
                  "addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}",
                  dpidLong, port, instructions);
  
          List<Action> actionList = Lists.newArrayList();
          ActionBuilder ab = new ActionBuilder();
  
          List<Action> existingActions;
          if (instructions != null) {
              for (Instruction in : instructions) {
                  if (in.getInstruction() instanceof ApplyActionsCase) {
                      existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
                      actionList.addAll(existingActions);
                  }
              }
          }
  
          /* Create output action for this port*/
          OutputActionBuilder oab = new OutputActionBuilder();
          oab.setOutputNodeConnector(ncid);
          ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
          ab.setOrder(actionList.size());
          ab.setKey(new ActionKey(actionList.size()));
          actionList.add(ab.build());
  
          // Create an Apply Action
          ApplyActionsBuilder aab = new ApplyActionsBuilder();
          aab.setAction(actionList);
          ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
  
          return ib;
      }
  
      /**
       * Remove Output Port from Instruction
       *
       * @param ib       Map InstructionBuilder without any instructions
       * @param dpidLong Long the datapath ID of a switch/node
       * @param port     Long representing a port on a switch/node
       * @return ib InstructionBuilder Map with instructions
       */
      public static boolean removeOutputPortFromInstructions(InstructionBuilder ib,
              Long dpidLong, Long port, List<Instruction> instructions) {
  
          NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
          logger.debug(
                  "removeOutputPortFromInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}",
                  dpidLong, port, instructions);
  
          List<Action> actionList = Lists.newArrayList();
          ActionBuilder ab;
  
          List<Action> existingActions;
          if (instructions != null) {
              for (Instruction in : instructions) {
                  if (in.getInstruction() instanceof ApplyActionsCase) {
                      existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
                      actionList.addAll(existingActions);
                      break;
                  }
              }
          }
  
          int index = 0;
          boolean isPortDeleted = false;
          boolean removeFlow = true;
          for (Action action : actionList) {
              if (action.getAction() instanceof OutputActionCase) {
                  OutputActionCase opAction = (OutputActionCase) action.getAction();
                  if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
                      /* Find the output port in action list and remove */
                      index = actionList.indexOf(action);
                      actionList.remove(action);
                      isPortDeleted = true;
                      break;
                  }
                  removeFlow = false;
              }
          }
  
          if (isPortDeleted) {
              for (int i = index; i < actionList.size(); i++) {
                  Action action = actionList.get(i);
                  if (action.getOrder() != i) {
                      /* Shift the action order */
                      ab = new ActionBuilder();
                      ab.setAction(action.getAction());
                      ab.setOrder(i);
                      ab.setKey(new ActionKey(i));
  