Update MRI projects for Aluminium
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / protocol / serialization / messages / FlowMessageSerializer.java
index 7050c0780c37e8b3e20feb69064485329b3360ad..b1820141d89b535aa6ac6ab607c80bbb2f64b610 100644 (file)
@@ -5,20 +5,16 @@
  * 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.opendaylight.openflowplugin.impl.protocol.serialization.messages;
 
 import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
-import java.math.BigInteger;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector;
@@ -26,7 +22,8 @@ import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
 import org.opendaylight.openflowjava.util.ByteBufUtils;
 import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.impl.protocol.serialization.util.ActionUtil;
+import org.opendaylight.openflowplugin.impl.protocol.serialization.util.InstructionUtil;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.OrderComparator;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.ActionList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
@@ -40,6 +37,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.tp.src.action._case.SetTpSrcActionBuilder;
 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.flow.types.rev131026.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowMessage;
@@ -53,55 +51,55 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 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.list.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.IpMatchFields;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.opendaylight.yangtools.yang.common.Uint8;
 
 /**
  * Translates FlowMod messages.
  * OF protocol versions: 1.3
  */
-public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage> implements SerializerRegistryInjector {
+public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage> implements
+        SerializerRegistryInjector {
     private static final FlowCookie DEFAULT_COOKIE = new FlowCookie(OFConstants.DEFAULT_COOKIE);
     private static final FlowCookie DEFAULT_COOKIE_MASK = new FlowCookie(OFConstants.DEFAULT_COOKIE_MASK);
-    private static final Short DEFAULT_TABLE_ID = (short) 0;
-    private static final Integer DEFAULT_IDLE_TIMEOUT = 0;
-    private static final Integer DEFAULT_HARD_TIMEOUT = 0;
-    private static final Integer DEFAULT_PRIORITY = OFConstants.DEFAULT_FLOW_PRIORITY;
-    private static final Long DEFAULT_BUFFER_ID = OFConstants.OFP_NO_BUFFER;
-    private static final BigInteger DEFAULT_OUT_PORT = BigInteger.valueOf(OFConstants.OFPP_ANY);
-    private static final Long DEFAULT_OUT_GROUP = OFConstants.OFPG_ANY;
+    private static final Uint8 DEFAULT_TABLE_ID = Uint8.ZERO;
+    private static final Uint16 DEFAULT_IDLE_TIMEOUT = Uint16.ZERO;
+    private static final Uint16 DEFAULT_HARD_TIMEOUT = Uint16.ZERO;
+    private static final Uint16 DEFAULT_PRIORITY = OFConstants.DEFAULT_FLOW_PRIORITY;
+    private static final Uint32 DEFAULT_BUFFER_ID = OFConstants.OFP_NO_BUFFER;
+    private static final Uint64 DEFAULT_OUT_PORT = Uint64.valueOf(OFConstants.OFPP_ANY);
+    private static final Uint32 DEFAULT_OUT_GROUP = OFConstants.OFPG_ANY;
     private static final byte PADDING_IN_FLOW_MOD_MESSAGE = 2;
     private static final FlowModFlags DEFAULT_FLAGS = new FlowModFlags(false, false, false, false, false);
-    private static final Integer PUSH_VLAN = 0x8100;
-
-    private static final Comparator<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026
-                .instruction.list.Instruction> COMPARATOR = (inst1, inst2) -> {
-        if (inst1.getOrder() == null || inst2.getOrder() == null) return 0;
-        return inst1.getOrder().compareTo(inst2.getOrder());
-    };
+    private static final Uint16 PUSH_VLAN = Uint16.valueOf(0x8100);
+    private static final Integer PUSH_TAG = PUSH_VLAN.toJava();
+    private static final VlanCfi PUSH_CFI = new VlanCfi(1);
 
     private static final VlanMatch VLAN_MATCH_FALSE = new VlanMatchBuilder()
             .setVlanId(new VlanIdBuilder()
                     .setVlanIdPresent(false)
-                    .setVlanId(new VlanId(0))
+                    .setVlanId(new VlanId(Uint16.ZERO))
                     .build())
             .build();
 
     private static final VlanMatch VLAN_MATCH_TRUE = new VlanMatchBuilder()
             .setVlanId(new VlanIdBuilder()
                     .setVlanIdPresent(true)
-                    .setVlanId(new VlanId(0))
+                    .setVlanId(new VlanId(Uint16.ZERO))
                     .build())
             .build();
 
     private SerializerRegistry registry;
 
     @Override
-    public void serialize(FlowMessage message, ByteBuf outBuffer) {
-        if (isSetVlanIdActionCasePresent(message)) {
+    public void serialize(final FlowMessage message, final ByteBuf outBuffer) {
+        if (!isVlanMatchPresent(message) && isSetVlanIdActionCasePresent(message)) {
             writeVlanFlow(message, outBuffer);
         } else {
             writeFlow(message, outBuffer);
@@ -110,20 +108,22 @@ public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage
 
     /**
      * Serialize flow message. Needs to be separated from main serialize method to prevent recursion
-     * when serializing SetVlanId flows
-     * @param message flow message
+     * when serializing SetVlanId flows.
+     *
+     * @param message   flow message
      * @param outBuffer output buffer
      */
     private void writeFlow(final FlowMessage message, final ByteBuf outBuffer) {
-        int index = outBuffer.writerIndex();
+        final int index = outBuffer.writerIndex();
         super.serialize(message, outBuffer);
         outBuffer.writeLong(MoreObjects.firstNonNull(message.getCookie(), DEFAULT_COOKIE).getValue().longValue());
-        outBuffer.writeLong(MoreObjects.firstNonNull(message.getCookieMask(), DEFAULT_COOKIE_MASK).getValue().longValue());
-        outBuffer.writeByte(MoreObjects.firstNonNull(message.getTableId(), DEFAULT_TABLE_ID));
+        outBuffer.writeLong(MoreObjects.firstNonNull(message.getCookieMask(), DEFAULT_COOKIE_MASK).getValue()
+                .longValue());
+        outBuffer.writeByte(MoreObjects.firstNonNull(message.getTableId(), DEFAULT_TABLE_ID).toJava());
         outBuffer.writeByte(message.getCommand().getIntValue());
-        outBuffer.writeShort(MoreObjects.firstNonNull(message.getIdleTimeout(), DEFAULT_IDLE_TIMEOUT));
-        outBuffer.writeShort(MoreObjects.firstNonNull(message.getHardTimeout(), DEFAULT_HARD_TIMEOUT));
-        outBuffer.writeShort(MoreObjects.firstNonNull(message.getPriority(), DEFAULT_PRIORITY));
+        outBuffer.writeShort(MoreObjects.firstNonNull(message.getIdleTimeout(), DEFAULT_IDLE_TIMEOUT).toJava());
+        outBuffer.writeShort(MoreObjects.firstNonNull(message.getHardTimeout(), DEFAULT_HARD_TIMEOUT).toJava());
+        outBuffer.writeShort(MoreObjects.firstNonNull(message.getPriority(), DEFAULT_PRIORITY).toJava());
         outBuffer.writeInt(MoreObjects.firstNonNull(message.getBufferId(), DEFAULT_BUFFER_ID).intValue());
         outBuffer.writeInt(MoreObjects.firstNonNull(message.getOutPort(), DEFAULT_OUT_PORT).intValue());
         outBuffer.writeInt(MoreObjects.firstNonNull(message.getOutGroup(), DEFAULT_OUT_GROUP).intValue());
@@ -135,60 +135,91 @@ public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage
     }
 
     /**
-     * Serialize OpenFlowPlugin match to raw bytes
-     * @param message OpenFlow flow mod message
+     * Instead of serializing this flow normally, we need to split it to two parts if flow contains
+     * #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase}.
+     *
+     * @param message   flow mod message
+     * @param outBuffer output buffer
+     */
+    private void writeVlanFlow(final FlowMessage message, final ByteBuf outBuffer) {
+        writeFlow(
+                new FlowMessageBuilder(message)
+                        .setMatch(new MatchBuilder(message.getMatch())
+                                .setVlanMatch(VLAN_MATCH_FALSE)
+                                .build())
+                        .setInstructions(new InstructionsBuilder()
+                                .setInstruction(updateSetVlanIdAction(message))
+                                .build())
+                        .build(),
+                outBuffer);
+
+        writeFlow(
+                new FlowMessageBuilder(message)
+                        .setMatch(new MatchBuilder(message.getMatch())
+                                .setVlanMatch(VLAN_MATCH_TRUE)
+                                .build())
+                        .build(),
+                outBuffer);
+    }
+
+    /**
+     * Serialize OpenFlowPlugin match to raw bytes.
+     *
+     * @param message   OpenFlow flow mod message
      * @param outBuffer output buffer
      */
     private void writeMatch(final FlowMessage message, final ByteBuf outBuffer) {
-        registry.<Match, OFSerializer<Match>>getSerializer(new MessageTypeKey<>(message.getVersion(), Match.class))
-                .serialize(message.getMatch(), outBuffer);
+        Preconditions.checkNotNull(registry).<Match, OFSerializer<Match>>getSerializer(
+                new MessageTypeKey<>(message.getVersion().toJava(), Match.class)).serialize(message.getMatch(),
+                    outBuffer);
 
     }
 
     /**
-     * Serialize OpenFlowPlugin instructions and set ip protocol of set-tp-src and set-tp-dst actions of need
-     * @param message OpenFlow flow mod message
+     * Serialize OpenFlowPlugin instructions and set ip protocol of set-tp-src and set-tp-dst actions of need.
+     *
+     * @param message   OpenFlow flow mod message
      * @param outBuffer output buffer
      */
-    @SuppressWarnings("unchecked")
     private void writeInstructions(final FlowMessage message, final ByteBuf outBuffer) {
         // Try to get IP protocol from IP match
-        final Optional<Short> protocol = Optional
+        final Optional<Uint8> protocol = Optional
                 .ofNullable(message.getMatch())
                 .flatMap(m -> Optional.ofNullable(m.getIpMatch()))
-                .map(IpMatchFields::getIpProtocol);
+                .flatMap(ipm -> Optional.ofNullable(ipm.getIpProtocol()));
 
         // Update instructions if needed and then serialize all instructions
         Optional.ofNullable(message.getInstructions())
-                .flatMap(is -> Optional.ofNullable(is.getInstruction()))
-                .ifPresent(is -> is
-                        .stream()
+                .flatMap(is -> Optional.ofNullable(is.nonnullInstruction()))
+                .ifPresent(is -> is.values().stream()
                         .filter(Objects::nonNull)
-                        .sorted(COMPARATOR)
-                        .map(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Instruction::getInstruction)
+                        .sorted(OrderComparator.build())
+                        .map(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types
+                                .rev131026.Instruction::getInstruction)
                         .filter(Objects::nonNull)
                         .map(i -> protocol.flatMap(p -> updateInstruction(i, p)).orElse(i))
-                        .forEach(i -> registry.<Instruction, OFSerializer<Instruction>>getSerializer(
-                                new MessageTypeKey<>(
-                                        EncodeConstants.OF13_VERSION_ID,
-                                        (Class<Instruction>) i.getImplementedInterface()))
-                                .serialize(i, outBuffer)
-                        ));
+                        .forEach(i -> InstructionUtil.writeInstruction(i, EncodeConstants.OF13_VERSION_ID, registry,
+                                outBuffer)));
     }
 
     /**
-     * Determine type of instruction and update it's actions if it is apply-actions instruction
+     * Determine type of instruction and update it's actions if it is apply-actions instruction.
+     *
      * @param instruction instruction
-     * @param protocol protocol
+     * @param protocol    protocol
      * @return updated instruction or empty
      */
-    private static Optional<Instruction> updateInstruction(final Instruction instruction, final Short protocol) {
-        if( ApplyActionsCase.class.isInstance(instruction)) {
-            return Optional.ofNullable(ApplyActionsCase.class.cast(instruction).getApplyActions())
-                    .flatMap(aa -> Optional.ofNullable(aa.getAction()))
-                    .map(as -> (Instruction) new ApplyActionsCaseBuilder()
+    private static Optional<Instruction> updateInstruction(final Instruction instruction, final Uint8 protocol) {
+        if (instruction instanceof ApplyActionsCase) {
+            return Optional
+                    .ofNullable(((ApplyActionsCase) instruction).getApplyActions())
+                    .flatMap(aa -> Optional.ofNullable(aa.nonnullAction()))
+                    .map(as -> new ApplyActionsCaseBuilder()
                             .setApplyActions(new ApplyActionsBuilder()
-                                    .setAction(as.stream()
+                                    .setAction(as
+                                            .values()
+                                            .stream()
+                                            .filter(Objects::nonNull)
                                             .map(a -> updateSetTpActions(a, protocol))
                                             .collect(Collectors.toList()))
                                     .build())
@@ -199,14 +230,15 @@ public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage
     }
 
     /**
-     * If action is set-tp-src or set-tp-dst, inject IP protocol into it, otherwise return original action
-     * @param action OpenFlow action
+     * If action is set-tp-src or set-tp-dst, inject IP protocol into it, otherwise return original action.
+     *
+     * @param action   OpenFlow action
      * @param protocol IP protocol
      * @return updated OpenFlow action
      */
-    private static Action updateSetTpActions(Action action, Short protocol) {
-        if (SetTpSrcActionCase.class.isInstance(action.getAction())) {
-            final SetTpSrcActionCase actionCase = SetTpSrcActionCase.class.cast(action.getAction());
+    private static Action updateSetTpActions(final Action action, final Uint8 protocol) {
+        if (action.getAction() instanceof SetTpSrcActionCase) {
+            final SetTpSrcActionCase actionCase = (SetTpSrcActionCase) action.getAction();
 
             return new ActionBuilder(action)
                     .setAction(new SetTpSrcActionCaseBuilder(actionCase)
@@ -216,8 +248,8 @@ public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage
                                     .build())
                             .build())
                     .build();
-        } else if (SetTpDstActionCase.class.isInstance(action.getAction())) {
-            final SetTpDstActionCase actionCase = SetTpDstActionCase.class.cast(action.getAction());
+        } else if (action.getAction() instanceof SetTpDstActionCase) {
+            final SetTpDstActionCase actionCase = (SetTpDstActionCase) action.getAction();
 
             return new ActionBuilder(action)
                     .setAction(new SetTpDstActionCaseBuilder(actionCase)
@@ -233,92 +265,62 @@ public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage
         return action;
     }
 
-
     /**
-     * Instead of serializing this flow normally, we need to split it to two parts if flow contains
-     * #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase}
-     * @param message flow mod message
-     * @param outBuffer output buffer
-     */
-    private void writeVlanFlow(final FlowMessage message, final ByteBuf outBuffer) {
-        Optional.ofNullable(message.getMatch())
-                .ifPresent(match -> Optional.ofNullable(match.getVlanMatch())
-                        .map(v -> Stream.of(
-                                new FlowMessageBuilder(message)
-                                        .setMatch(new MatchBuilder(match)
-                                                .setVlanMatch(new VlanMatchBuilder(v)
-                                                        .setVlanId(new VlanIdBuilder()
-                                                                .setVlanIdPresent(v.getVlanId().isVlanIdPresent())
-                                                                .setVlanId(v.getVlanId().getVlanId())
-                                                                .build())
-                                                        .build())
-                                                .build())
-                                        .build())
-                        ).orElseGet(() -> Stream.of(
-                                new FlowMessageBuilder(message)
-                                        .setMatch(new MatchBuilder(match)
-                                                .setVlanMatch(VLAN_MATCH_FALSE)
-                                                .build())
-                                        .setInstructions(new InstructionsBuilder()
-                                                .setInstruction(updateSetVlanIdAction(message))
-                                                .build())
-                                        .build(),
-                                new FlowMessageBuilder(message)
-                                        .setMatch(new MatchBuilder(match)
-                                                .setVlanMatch(VLAN_MATCH_TRUE)
-                                                .build())
-                                        .build())
-                        ).forEach(m -> writeFlow(m, outBuffer)));
-    }
-
-    /**
-     * Create copy of instructions of original flow but insert #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase}
-     * before each #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase}
+     * Create copy of instructions of original flow but insert
+     * #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase}
+     * before each
+     * #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase}.
+     *
      * @param message OpenFlowPlugin flow mod message
      * @return list of instructions
      */
     private static List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list
             .Instruction> updateSetVlanIdAction(final FlowMessage message) {
-        return message.getInstructions().getInstruction()
+        return message.getInstructions().nonnullInstruction().values()
                 .stream()
                 .map(i -> {
-                    final int[] offset = { 0 };
+                    final int[] offset = {0};
 
-                    return ApplyActionsCase.class.isInstance(i.getInstruction())
+                    return i.getInstruction() instanceof ApplyActionsCase
                             ? Optional
-                            .ofNullable(ApplyActionsCase.class.cast(i.getInstruction()).getApplyActions())
-                            .flatMap(as -> Optional.ofNullable(as.getAction()))
-                            .map(a -> ActionUtil.sortActions(a)
-                                    .stream()
+                            .ofNullable(((ApplyActionsCase) i.getInstruction()).getApplyActions())
+                            .flatMap(as -> Optional.ofNullable(as.nonnullAction()))
+                            .map(a -> a.values().stream()
+                                    .sorted(OrderComparator.build())
                                     .flatMap(action -> {
-                                final List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112
-                                        .action.list.Action> actions = new ArrayList<>();
+                                        final List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112
+                                                .action.list.Action> actions = new ArrayList<>();
 
-                                // If current action is SetVlanId, insert PushVlan action before it and update order
-                                if (SetVlanIdActionCase.class.isInstance(action.getAction())) {
-                                    actions.add(new ActionBuilder()
-                                            .setAction(new PushVlanActionCaseBuilder()
-                                                    .setPushVlanAction(new PushVlanActionBuilder()
-                                                            .setCfi(new VlanCfi(1))
-                                                            .setVlanId(SetVlanIdActionCase.class.cast(action.getAction()).getSetVlanIdAction().getVlanId())
-                                                            .setEthernetType(PUSH_VLAN)
-                                                            .setTag(PUSH_VLAN)
+                                        // If current action is SetVlanId, insert PushVlan action before it and
+                                        // update order
+                                        if (action.getAction() instanceof SetVlanIdActionCase) {
+                                            actions.add(new ActionBuilder()
+                                                    .setAction(new PushVlanActionCaseBuilder()
+                                                            .setPushVlanAction(new PushVlanActionBuilder()
+                                                                    .setCfi(PUSH_CFI)
+                                                                    .setVlanId(((SetVlanIdActionCase) action
+                                                                        .getAction()).getSetVlanIdAction()
+                                                                            .getVlanId())
+                                                                    .setEthernetType(PUSH_VLAN)
+                                                                    .setTag(PUSH_TAG)
+                                                                    .build())
                                                             .build())
-                                                    .build())
-                                            .setKey(action.getKey())
-                                            .setOrder(action.getOrder() + offset[0])
-                                            .build());
+                                                    .withKey(action.key())
+                                                    .setOrder(action.getOrder() + offset[0])
+                                                    .build());
 
-                                    offset[0]++;
-                                }
+                                            offset[0]++;
+                                        }
 
-                                // Update offset of action if there is any inserted PushVlan actions
-                                actions.add(offset[0] > 0
-                                        ? new ActionBuilder(action).setOrder(action.getOrder() + offset[0]).build()
-                                        : action);
+                                        // Update offset of action if there is any inserted PushVlan actions
+                                        actions.add(offset[0] > 0
+                                                ? new ActionBuilder(action).setOrder(action.getOrder() + offset[0])
+                                                .withKey(new ActionKey(action.getOrder() + offset[0]))
+                                                .build()
+                                                : action);
 
-                                return actions.stream();
-                            }))
+                                        return actions.stream();
+                                    }))
                             .map(as -> new InstructionBuilder(i)
                                     .setInstruction(new ApplyActionsCaseBuilder()
                                             .setApplyActions(new ApplyActionsBuilder()
@@ -332,7 +334,9 @@ public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage
     }
 
     /**
-     * Create integer bit mask from #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags}
+     * Create integer bit mask from
+     * #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags}.
+     *
      * @param flags flow mod flags
      * @return bit mask
      */
@@ -346,24 +350,41 @@ public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage
     }
 
     /**
-     * Determine if flow contains #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase}
-     * instruction with #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase} action
+     * Determine if flow contains vlan match.
+     *
+     * @param flow flow
+     * @return true if flow contains vlan match
+     */
+    private static boolean isVlanMatchPresent(final Flow flow) {
+        return Optional
+                .ofNullable(flow.getMatch())
+                .flatMap(m -> Optional.ofNullable(m.getVlanMatch()))
+                .isPresent();
+    }
+
+    /**
+     * Determine if flow contains
+     * #{@link org.opendaylight.yang.gen.v1.urn.opendaylight
+     * .flow.types.rev131026.instruction.instruction.ApplyActionsCase} instruction with
+     * #{@link org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase}
+     * action.
+     *
      * @param flow OpenFlowPlugin flow
      * @return true if flow contains SetVlanIdAction
      */
     private static boolean isSetVlanIdActionCasePresent(final Flow flow) {
         return Optional
                 .ofNullable(flow.getInstructions())
-                .flatMap(is -> Optional.ofNullable(is.getInstruction()))
-                .flatMap(is -> is
-                        .stream()
-                        .map(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Instruction::getInstruction)
+                .flatMap(is -> Optional.ofNullable(is.nonnullInstruction()))
+                .flatMap(is -> is.values().stream()
+                        .map(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types
+                                .rev131026.Instruction::getInstruction)
                         .filter(ApplyActionsCase.class::isInstance)
-                        .map(i -> ApplyActionsCase.class.cast(i).getApplyActions())
+                        .map(i -> ((ApplyActionsCase) i).getApplyActions())
                         .filter(Objects::nonNull)
-                        .map(ActionList::getAction)
+                        .map(ActionList::nonnullAction)
                         .filter(Objects::nonNull)
-                        .flatMap(Collection::stream)
+                        .flatMap(map -> map.values().stream())
                         .map(Action::getAction)
                         .filter(SetVlanIdActionCase.class::isInstance)
                         .findFirst())
@@ -376,7 +397,7 @@ public class FlowMessageSerializer extends AbstractMessageSerializer<FlowMessage
     }
 
     @Override
-    public void injectSerializerRegistry(SerializerRegistry serializerRegistry) {
+    public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) {
         registry = serializerRegistry;
     }
 }