Merge "Reg load support for nicira experimenter fields"
authorAnil Vishnoi <vishnoianil@gmail.com>
Wed, 18 Jul 2018 09:43:46 +0000 (09:43 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 18 Jul 2018 09:43:46 +0000 (09:43 +0000)
18 files changed:
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/NiciraExtensionCodecRegistratorImpl.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/NiciraExtensionsRegistrator.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/action/AbstractActionCodec.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/action/ActionDeserializer.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/action/NiciraActionCodecs.java
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/action/RegLoad2Codec.java [new file with mode: 0644]
extension/openflowjava-extension-nicira/src/main/yang/nicira-action.yang
extension/openflowjava-extension-nicira/src/test/java/org/opendaylight/openflowjava/nx/NiciraExtensionCodecRegistratorImplTest.java
extension/openflowjava-extension-nicira/src/test/java/org/opendaylight/openflowjava/nx/NiciraExtensionsRegistratorTest.java
extension/openflowjava-extension-nicira/src/test/java/org/opendaylight/openflowjava/nx/codec/action/RegLoad2CodecTest.java [new file with mode: 0644]
extension/openflowplugin-extension-nicira/pom.xml
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/NiciraExtensionProvider.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoad2Convertor.java [new file with mode: 0644]
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertor.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertorProxy.java [new file with mode: 0644]
extension/openflowplugin-extension-nicira/src/main/yang/openflowplugin-extension-nicira-action.yang
extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoad2ConvertorTest.java [new file with mode: 0644]
parent/pom.xml

index 1dccca2e40a76110cd8809f76814d4883ad21beb..e15582457d47f4c7ecfa554355c629e21bab06bf 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.openflowjava.nx.api.NiciraActionSerializerKey;
 import org.opendaylight.openflowjava.nx.api.NiciraExtensionCodecRegistrator;
 import org.opendaylight.openflowjava.nx.api.NiciraUtil;
 import org.opendaylight.openflowjava.nx.codec.action.ActionDeserializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
 import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer;
 import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer;
@@ -44,11 +45,13 @@ public class NiciraExtensionCodecRegistratorImpl implements NiciraExtensionCodec
             new ConcurrentHashMap<>();
 
     private final List<SwitchConnectionProvider> providers;
+    private final ActionDeserializer of10ActionDeserializer;
+    private final ActionDeserializer of13ActionDeserializer;
 
     public NiciraExtensionCodecRegistratorImpl(List<SwitchConnectionProvider> providers) {
         this.providers = providers;
-        ActionDeserializer of10ActionDeserializer = new ActionDeserializer(EncodeConstants.OF10_VERSION_ID);
-        ActionDeserializer of13ActionDeserializer = new ActionDeserializer(EncodeConstants.OF13_VERSION_ID);
+        of10ActionDeserializer = new ActionDeserializer(EncodeConstants.OF10_VERSION_ID);
+        of13ActionDeserializer = new ActionDeserializer(EncodeConstants.OF13_VERSION_ID);
         registerActionDeserializer(ActionDeserializer.OF10_DESERIALIZER_KEY, of10ActionDeserializer);
         registerActionDeserializer(ActionDeserializer.OF13_DESERIALIZER_KEY, of13ActionDeserializer);
     }
@@ -70,6 +73,15 @@ public class NiciraExtensionCodecRegistratorImpl implements NiciraExtensionCodec
      */
     @Override
     public void registerActionDeserializer(NiciraActionDeserializerKey key, OFDeserializer<Action> deserializer) {
+        if (deserializer instanceof DeserializerRegistryInjector) {
+            DeserializerRegistryInjector registryInjectable = (DeserializerRegistryInjector) deserializer;
+            if (key.getVersion() == EncodeConstants.OF10_VERSION_ID) {
+                registryInjectable.injectDeserializerRegistry(of10ActionDeserializer.getDeserializerRegistry());
+            }
+            if (key.getVersion() == EncodeConstants.OF13_VERSION_ID) {
+                registryInjectable.injectDeserializerRegistry(of13ActionDeserializer.getDeserializerRegistry());
+            }
+        }
         ACTION_DESERIALIZERS.put(key, deserializer);
     }
 
index ef79a8d13d01e44e499784c0c46914060ae3f33e..f187672a16b41818f62abfb7090f766e2d93f2e7 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.openflowjava.nx.codec.action.NiciraActionCodecs;
 import org.opendaylight.openflowjava.nx.codec.action.OutputRegCodec;
 import org.opendaylight.openflowjava.nx.codec.action.PopNshCodec;
 import org.opendaylight.openflowjava.nx.codec.action.PushNshCodec;
+import org.opendaylight.openflowjava.nx.codec.action.RegLoad2Codec;
 import org.opendaylight.openflowjava.nx.codec.action.RegLoadCodec;
 import org.opendaylight.openflowjava.nx.codec.action.RegMoveCodec;
 import org.opendaylight.openflowjava.nx.codec.action.ResubmitCodec;
@@ -80,6 +81,8 @@ public class NiciraExtensionsRegistrator implements AutoCloseable {
 
         registrator.registerActionDeserializer(RegLoadCodec.DESERIALIZER_KEY, NiciraActionCodecs.REG_LOAD_CODEC);
         registrator.registerActionSerializer(RegLoadCodec.SERIALIZER_KEY, NiciraActionCodecs.REG_LOAD_CODEC);
+        registrator.registerActionDeserializer(RegLoad2Codec.DESERIALIZER_KEY, NiciraActionCodecs.REG_LOAD2_CODEC);
+        registrator.registerActionSerializer(RegLoad2Codec.SERIALIZER_KEY, NiciraActionCodecs.REG_LOAD2_CODEC);
         registrator.registerActionDeserializer(RegMoveCodec.DESERIALIZER_KEY, NiciraActionCodecs.REG_MOVE_CODEC);
         registrator.registerActionSerializer(RegMoveCodec.SERIALIZER_KEY, NiciraActionCodecs.REG_MOVE_CODEC);
         registrator.registerActionDeserializer(OutputRegCodec.DESERIALIZER_KEY, NiciraActionCodecs.OUTPUT_REG_CODEC);
@@ -216,6 +219,8 @@ public class NiciraExtensionsRegistrator implements AutoCloseable {
     public void close() throws Exception {
         registrator.unregisterActionDeserializer(RegLoadCodec.DESERIALIZER_KEY);
         registrator.unregisterActionSerializer(RegLoadCodec.SERIALIZER_KEY);
+        registrator.unregisterActionDeserializer(RegLoad2Codec.DESERIALIZER_KEY);
+        registrator.unregisterActionSerializer(RegLoad2Codec.SERIALIZER_KEY);
         registrator.unregisterActionDeserializer(RegMoveCodec.DESERIALIZER_KEY);
         registrator.unregisterActionSerializer(RegMoveCodec.SERIALIZER_KEY);
         registrator.unregisterActionDeserializer(OutputRegCodec.DESERIALIZER_KEY);
index e4ffc19e287ea1e972c62a3eb47fcdbbfa89ae7b..6acb70db83e7e9ed65dcf7ef8ff7e9049f25655f 100644 (file)
@@ -53,5 +53,20 @@ public abstract class AbstractActionCodec implements OFSerializer<Action>, OFDes
         return new ExperimenterId(NiciraConstants.NX_VENDOR_ID);
     }
 
+    private static int getPaddingRemainder(int nonPaddedSize) {
+        int paddingRemainder = EncodeConstants.PADDING - (nonPaddedSize % EncodeConstants.PADDING);
+        return paddingRemainder % EncodeConstants.PADDING;
+    }
+
+    protected static final void skipPadding(ByteBuf message, int startIndex) {
+        int nonPaddedSize = message.readerIndex() - startIndex;
+        message.skipBytes(getPaddingRemainder(nonPaddedSize));
+    }
+
+    protected static final void writePaddingAndSetLength(ByteBuf outBuffer, int startIndex) {
+        int nonPaddedSize = outBuffer.writerIndex() - startIndex;
+        outBuffer.writeZero(getPaddingRemainder(nonPaddedSize));
+        outBuffer.setShort(startIndex + EncodeConstants.SIZE_OF_SHORT_IN_BYTES, outBuffer.writerIndex() - startIndex);
+    }
 
 }
index 34db9d34bcbbb6c7be2d90a877b1032c2ebf2fe2..ad9e7427cde7f846584b61c81ca88b159cb80356 100644 (file)
@@ -12,6 +12,8 @@ import io.netty.buffer.ByteBuf;
 import org.opendaylight.openflowjava.nx.NiciraExtensionCodecRegistratorImpl;
 import org.opendaylight.openflowjava.nx.api.NiciraActionDeserializerKey;
 import org.opendaylight.openflowjava.nx.api.NiciraConstants;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterActionDeserializerKey;
 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
@@ -19,7 +21,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev1
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class ActionDeserializer implements OFDeserializer<Action> {
+public class ActionDeserializer implements OFDeserializer<Action>, DeserializerRegistryInjector {
 
     private static final Logger LOG = LoggerFactory.getLogger(ActionDeserializer.class);
 
@@ -29,6 +31,7 @@ public class ActionDeserializer implements OFDeserializer<Action> {
             EncodeConstants.OF10_VERSION_ID, NiciraConstants.NX_VENDOR_ID);
 
     private final short version;
+    private DeserializerRegistry deserializerRegistry;
 
     /**
      * Constructor.
@@ -62,4 +65,12 @@ public class ActionDeserializer implements OFDeserializer<Action> {
         return actionDeserializer.deserialize(message);
     }
 
+    @Override
+    public void injectDeserializerRegistry(DeserializerRegistry registry) {
+        this.deserializerRegistry = registry;
+    }
+
+    public DeserializerRegistry getDeserializerRegistry() {
+        return deserializerRegistry;
+    }
 }
index 35bd670f06890c31ff28dad554d4cd609a18de8d..2b74ef6cf1343e19b2689473ad00ce0b9d5dce2d 100644 (file)
@@ -15,6 +15,7 @@ package org.opendaylight.openflowjava.nx.codec.action;
 public interface NiciraActionCodecs {
     RegMoveCodec REG_MOVE_CODEC = new RegMoveCodec();
     RegLoadCodec REG_LOAD_CODEC = new RegLoadCodec();
+    RegLoad2Codec REG_LOAD2_CODEC = new RegLoad2Codec();
     OutputRegCodec OUTPUT_REG_CODEC = new OutputRegCodec();
     ResubmitCodec RESUBMIT_CODEC = new ResubmitCodec();
     MultipathCodec MULTIPATH_CODEC = new MultipathCodec();
diff --git a/extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/action/RegLoad2Codec.java b/extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/action/RegLoad2Codec.java
new file mode 100644 (file)
index 0000000..882e3e7
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH.  All rights reserved.
+ *
+ * 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.opendaylight.openflowjava.nx.codec.action;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import io.netty.buffer.ByteBuf;
+import java.util.Collections;
+import java.util.Objects;
+import org.opendaylight.openflowjava.nx.api.NiciraActionDeserializerKey;
+import org.opendaylight.openflowjava.nx.api.NiciraActionSerializerKey;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2Builder;
+
+public class RegLoad2Codec
+        extends AbstractActionCodec
+        implements SerializerRegistryInjector, DeserializerRegistryInjector {
+
+    public static final byte SUBTYPE = 33; // NXAST_REG_LOAD2
+    public static final NiciraActionSerializerKey SERIALIZER_KEY = new NiciraActionSerializerKey(
+            EncodeConstants.OF13_VERSION_ID, ActionRegLoad2.class);
+    public static final NiciraActionDeserializerKey DESERIALIZER_KEY = new NiciraActionDeserializerKey(
+            EncodeConstants.OF13_VERSION_ID, SUBTYPE);
+    private SerializerRegistry serializerRegistry;
+    private DeserializerRegistry deserializerRegistry;
+
+    @Override
+    @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") // FB doesn't recognize Objects.requireNonNull
+    public Action deserialize(ByteBuf message) {
+        Objects.requireNonNull(deserializerRegistry);
+
+        final int startIndex = message.readerIndex();
+        ActionBuilder actionBuilder = deserializeHeader(message);
+
+        int oxmClass = message.getUnsignedShort(message.readerIndex());
+        int oxmField = message.getUnsignedByte(message.readerIndex() + EncodeConstants.SIZE_OF_SHORT_IN_BYTES) >>> 1;
+        MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(
+                EncodeConstants.OF13_VERSION_ID,
+                oxmClass,
+                oxmField);
+        if (oxmClass == EncodeConstants.EXPERIMENTER_VALUE) {
+            long expId = message.getUnsignedInt(message.readerIndex()
+                    + EncodeConstants.SIZE_OF_SHORT_IN_BYTES
+                    + EncodeConstants.SIZE_OF_BYTE_IN_BYTES * 2);
+            key.setExperimenterId(expId);
+        }
+        OFDeserializer<MatchEntry> matchDeserializer = deserializerRegistry.getDeserializer(key);
+        MatchEntry matchEntry = matchDeserializer.deserialize(message);
+
+        skipPadding(message, startIndex);
+
+        NxActionRegLoad2 nxActionRegLoad2 = new NxActionRegLoad2Builder()
+                .setMatchEntry(Collections.singletonList(matchEntry))
+                .build();
+        ActionRegLoad2 actionRegLoad2 = new ActionRegLoad2Builder().setNxActionRegLoad2(nxActionRegLoad2).build();
+        return actionBuilder.setActionChoice(actionRegLoad2).build();
+    }
+
+    @Override
+    @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") // FB doesn't recognize Objects.requireNonNull
+    public void serialize(Action input, ByteBuf outBuffer) {
+        Objects.requireNonNull(serializerRegistry);
+
+        final int startIndex = outBuffer.writerIndex();
+        serializeHeader(EncodeConstants.EMPTY_LENGTH, SUBTYPE, outBuffer);
+
+        ActionRegLoad2 actionRegLoad2 = (ActionRegLoad2) input.getActionChoice();
+        NxActionRegLoad2 nxActionRegLoad2 = actionRegLoad2.getNxActionRegLoad2();
+        MatchEntry matchEntry = nxActionRegLoad2.getMatchEntry().get(0);
+        MatchEntrySerializerKey<?, ?> key = new MatchEntrySerializerKey<>(
+                EncodeConstants.OF13_VERSION_ID,
+                matchEntry.getOxmClass(),
+                matchEntry.getOxmMatchField());
+        if (matchEntry.getOxmClass().equals(ExperimenterClass.class)) {
+            ExperimenterIdCase experimenterIdCase = (ExperimenterIdCase) matchEntry.getMatchEntryValue();
+            key.setExperimenterId(experimenterIdCase.getExperimenter().getExperimenter().getValue());
+        }
+        OFSerializer<MatchEntry> serializer = serializerRegistry.getSerializer(key);
+        serializer.serialize(matchEntry, outBuffer);
+
+        writePaddingAndSetLength(outBuffer, startIndex);
+    }
+
+    @Override
+    public void injectSerializerRegistry(SerializerRegistry registry) {
+        this.serializerRegistry = registry;
+    }
+
+    @Override
+    public void injectDeserializerRegistry(DeserializerRegistry registry) {
+        this.deserializerRegistry = registry;
+    }
+}
index 7563de32a62026063687c5b85fac2650e6d30292..2196feab4b4c8217f99abee7c7f27c5747a3152a 100644 (file)
@@ -4,6 +4,7 @@ module nicira-action {
     namespace "urn:opendaylight:openflowjava:nx:action";
     prefix "nicira-action";
 
+    import openflow-extensible-match { prefix oxm;}
     import openflow-action {prefix ofaction; revision-date "2015-02-03";}
     import openflow-types {prefix oft;}
     import yang-ext {prefix ext; revision-date "2013-07-09";}
@@ -19,6 +20,9 @@ module nicira-action {
     identity nxm-nx-reg-load {
         base ofaction:experimenter-action-sub-type;
     }
+    identity nxm-nx-reg-load2 {
+        base ofaction:experimenter-action-sub-type;
+    }
     identity nxm-nx-reg-move {
         base ofaction:experimenter-action-sub-type;
     }
@@ -75,6 +79,13 @@ module nicira-action {
             }
         }
     }
+
+    grouping ofj-nx-action-reg-load2-grouping {
+        container nx-action-reg-load2 {
+            uses oxm:match-entries-grouping;
+        }
+    }
+
     grouping ofj-nx-action-reg-move-grouping {
         container nx-action-reg-move {
                 leaf n_bits {
@@ -517,6 +528,9 @@ module nicira-action {
         case action-reg-load {
             uses ofj-nx-action-reg-load-grouping;
         }
+        case action-reg-load2 {
+            uses ofj-nx-action-reg-load2-grouping;
+        }
         case action-reg-move {
             uses ofj-nx-action-reg-move-grouping;
         }
index 1da31678de010ac0f87680da35ef470eb9d07d7a..5bb12dbe2f7fb27f511bb342b7b219a96201b3eb 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.openflowjava.nx.api.NiciraActionDeserializerKey;
 import org.opendaylight.openflowjava.nx.api.NiciraActionSerializerKey;
 import org.opendaylight.openflowjava.nx.api.NiciraUtil;
 import org.opendaylight.openflowjava.nx.codec.action.ActionDeserializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
 import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer;
 import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
@@ -51,7 +52,7 @@ public class NiciraExtensionCodecRegistratorImplTest {
 
     @Mock
     OFSerializer<Action> actionSerializer;
-    @Mock
+    @Mock(extraInterfaces = DeserializerRegistryInjector.class)
     OFDeserializer<Action> actionDeserializer;
     @Mock
     OFSerializer<MatchEntry> matchSerializer;
@@ -109,6 +110,8 @@ public class NiciraExtensionCodecRegistratorImplTest {
         assertTrue(niciraExtensionCodecRegistrator.isEmptyActionDeserializers());
         niciraExtensionCodecRegistrator.registerActionDeserializer(actionDeserializerKey, actionDeserializer);
         assertFalse(niciraExtensionCodecRegistrator.isEmptyActionDeserializers());
+        Mockito.verify((DeserializerRegistryInjector) actionDeserializer)
+                .injectDeserializerRegistry(Matchers.any());
     }
 
     @Test
index 1321ff1ce57d5c7e08575108d4d462e50fc23ca8..5dc109edcfc73ca324bd0044c2fb0249d56cbed7 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.openflowjava.nx.codec.action.MultipathCodec;
 import org.opendaylight.openflowjava.nx.codec.action.OutputRegCodec;
 import org.opendaylight.openflowjava.nx.codec.action.PopNshCodec;
 import org.opendaylight.openflowjava.nx.codec.action.PushNshCodec;
+import org.opendaylight.openflowjava.nx.codec.action.RegLoad2Codec;
 import org.opendaylight.openflowjava.nx.codec.action.RegLoadCodec;
 import org.opendaylight.openflowjava.nx.codec.action.RegMoveCodec;
 import org.opendaylight.openflowjava.nx.codec.action.ResubmitCodec;
@@ -81,6 +82,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionPopNsh;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionPushNsh;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegMove;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionResubmit;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxArpSha;
@@ -142,6 +144,12 @@ public class NiciraExtensionsRegistratorTest {
         Mockito.verify(registrator).registerActionSerializer(
                 Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad.class)),
                 Matchers.any(RegLoadCodec.class));
+        Mockito.verify(registrator).registerActionDeserializer(
+                Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 33)),
+                Matchers.any(RegLoad2Codec.class));
+        Mockito.verify(registrator).registerActionSerializer(
+                Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad2.class)),
+                Matchers.any(RegLoad2Codec.class));
         Mockito.verify(registrator).registerActionDeserializer(
                 Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 6)),
                 Matchers.any(RegMoveCodec.class));
@@ -453,6 +461,10 @@ public class NiciraExtensionsRegistratorTest {
                 .unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 7));
         Mockito.verify(registrator).unregisterActionSerializer(
                 new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad.class));
+        Mockito.verify(registrator)
+                .unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 33));
+        Mockito.verify(registrator).unregisterActionSerializer(
+                new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad2.class));
         Mockito.verify(registrator)
                 .unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 6));
         Mockito.verify(registrator).unregisterActionSerializer(
diff --git a/extension/openflowjava-extension-nicira/src/test/java/org/opendaylight/openflowjava/nx/codec/action/RegLoad2CodecTest.java b/extension/openflowjava-extension-nicira/src/test/java/org/opendaylight/openflowjava/nx/codec/action/RegLoad2CodecTest.java
new file mode 100644 (file)
index 0000000..ec07c1f
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH.  All rights reserved.
+ *
+ * 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.opendaylight.openflowjava.nx.codec.action;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.when;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.openflowjava.nx.api.NiciraConstants;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.util.ByteBufUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.experimenter.id._case.ExperimenterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2Builder;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RegLoad2CodecTest {
+
+    private RegLoad2Codec regLoad2Codec;
+
+    @Mock
+    private SerializerRegistry serializerRegistry;
+    @Mock
+    private DeserializerRegistry deserializerRegistry;
+    @Mock
+    private OFSerializer<MatchEntry> ofSerializer;
+    @Mock
+    private OFDeserializer<MatchEntry> ofDeserializer;
+
+    @Before
+    public void setup() {
+        regLoad2Codec = new RegLoad2Codec();
+        regLoad2Codec.injectSerializerRegistry(serializerRegistry);
+        regLoad2Codec.injectDeserializerRegistry(deserializerRegistry);
+    }
+
+    @Test
+    public void deserialize() {
+        final ByteBuf byteBuf = ByteBufUtils.hexStringToByteBuf(
+                "FF FF 00 14 00 00 23 20 00 21"             // REG_LOAD2 header
+                + " FF FF 02 00 00 5A D6 50"                       // OXM field
+                + " 00 00 00 00 00 00");                           // padding
+        MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(
+                EncodeConstants.OF13_VERSION_ID,
+                EncodeConstants.EXPERIMENTER_VALUE,
+                1);
+        key.setExperimenterId(NiciraConstants.NX_NSH_VENDOR_ID);
+        final MatchEntry matchEntry = new MatchEntryBuilder().build();
+        when(deserializerRegistry.getDeserializer(key)).thenReturn(ofDeserializer);
+        when(ofDeserializer.deserialize(byteBuf)).thenAnswer(invocationOnMock -> {
+            invocationOnMock.getArgumentAt(0, ByteBuf.class).skipBytes(8);
+            return matchEntry;
+        });
+
+        Action action = regLoad2Codec.deserialize(byteBuf);
+
+        assertEquals(0, byteBuf.readableBytes());
+        assertSame(((ActionRegLoad2) action.getActionChoice()).getNxActionRegLoad2().getMatchEntry().get(0),
+                matchEntry);
+    }
+
+    @Test
+    public void serialize() {
+        final ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
+        final Action action = createAction();
+        MatchEntrySerializerKey<?, ?> key = new MatchEntrySerializerKey<>(
+                EncodeConstants.OF13_VERSION_ID,
+                ExperimenterClass.class,
+                OxmMatchFieldClass.class);
+        key.setExperimenterId(NiciraConstants.NX_NSH_VENDOR_ID);
+        when(serializerRegistry.getSerializer(key)).thenReturn(ofSerializer);
+        doNothing().when(ofSerializer).serialize(any(), any());
+
+        regLoad2Codec.serialize(action, out);
+
+        assertEquals(EncodeConstants.EXPERIMENTER_VALUE, out.readUnsignedShort());
+        assertEquals(16, out.readUnsignedShort());
+        assertEquals(NiciraConstants.NX_VENDOR_ID.longValue(), out.readUnsignedInt());
+        assertEquals(RegLoad2Codec.SUBTYPE, out.readUnsignedShort());
+    }
+
+    private Action createAction() {
+        ExperimenterBuilder experimenterBuilder = new ExperimenterBuilder();
+        experimenterBuilder.setExperimenter(new ExperimenterId(NiciraConstants.NX_NSH_VENDOR_ID));
+        ExperimenterIdCaseBuilder expCaseBuilder = new ExperimenterIdCaseBuilder();
+        expCaseBuilder.setExperimenter(experimenterBuilder.build());
+        MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
+        matchEntryBuilder.setOxmMatchField(OxmMatchFieldClass.class);
+        matchEntryBuilder.setOxmClass(ExperimenterClass.class);
+        matchEntryBuilder.setMatchEntryValue(expCaseBuilder.build());
+        NxActionRegLoad2 nxActionRegLoad2 = new NxActionRegLoad2Builder()
+                .setMatchEntry(Collections.singletonList(matchEntryBuilder.build()))
+                .build();
+        ActionRegLoad2 actionRegLoad2 = new ActionRegLoad2Builder().setNxActionRegLoad2(nxActionRegLoad2).build();
+        return new ActionBuilder().setActionChoice(actionRegLoad2).build();
+    }
+
+    private interface OxmMatchFieldClass extends MatchField {
+        // only for testing purposes
+    }
+}
\ No newline at end of file
index a14160812db9cab1585fe20c23cc0671bd46cefc..32196391a81224a2d76d77c76266f613fd7d5297 100644 (file)
             <artifactId>slf4j-log4j12</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>pl.pragmatists</groupId>
+            <artifactId>JUnitParams</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
index 271b9ff1796ac8c909320f0e2136f437868ad27a..a688b26b1c2bf92bb039310dfefcd67da108973e 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.openflowjava.nx.codec.action.MultipathCodec;
 import org.opendaylight.openflowjava.nx.codec.action.OutputRegCodec;
 import org.opendaylight.openflowjava.nx.codec.action.PopNshCodec;
 import org.opendaylight.openflowjava.nx.codec.action.PushNshCodec;
+import org.opendaylight.openflowjava.nx.codec.action.RegLoad2Codec;
 import org.opendaylight.openflowjava.nx.codec.action.RegLoadCodec;
 import org.opendaylight.openflowjava.nx.codec.action.RegMoveCodec;
 import org.opendaylight.openflowjava.nx.codec.action.ResubmitCodec;
@@ -89,7 +90,9 @@ import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.
 import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.OutputRegConvertor;
 import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.PopNshConvertor;
 import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.PushNshConvertor;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.RegLoad2Convertor;
 import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.RegLoadConvertor;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.RegLoadConvertorProxy;
 import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.RegMoveConvertor;
 import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.ResubmitConvertor;
 import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.match.ArpOpConvertor;
@@ -143,6 +146,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev1
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionPopNsh;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionPushNsh;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegMove;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionResubmit;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.flow.input.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackRpcAddFlowApplyActionsCase;
@@ -343,6 +347,8 @@ public class NiciraExtensionProvider implements AutoCloseable {
     private static final EthDstConvertor ETH_DST_CONVERTOR = new EthDstConvertor();
     private static final EthSrcConvertor ETH_SRC_CONVERTOR = new EthSrcConvertor();
     private static final RegLoadConvertor REG_LOAD_CONVERTOR = new RegLoadConvertor();
+    private static final RegLoad2Convertor REG_LOAD2_CONVERTOR = new RegLoad2Convertor();
+    private static final RegLoadConvertorProxy REG_LOAD_CONVERTOR_PROXY = new RegLoadConvertorProxy();
     private static final RegMoveConvertor REG_MOVE_CONVERTOR = new RegMoveConvertor();
     private static final OutputRegConvertor OUTPUT_REG_CONVERTOR = new OutputRegConvertor();
     private static final EthTypeConvertor ETH_TYPE_CONVERTOR = new EthTypeConvertor();
@@ -394,7 +400,7 @@ public class NiciraExtensionProvider implements AutoCloseable {
         this.extensionConverterRegistrator = Preconditions.checkNotNull(provider.getExtensionConverterRegistrator());
         registrations = new HashSet<>();
         // src=dataStore/config
-        registerAction13(NxActionRegLoadNodesNodeTableFlowApplyActionsCase.class, REG_LOAD_CONVERTOR);
+        registerAction13(NxActionRegLoadNodesNodeTableFlowApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
         registerAction13(NxActionRegMoveNodesNodeTableFlowApplyActionsCase.class, REG_MOVE_CONVERTOR);
         registerAction13(NxActionOutputRegNodesNodeTableFlowApplyActionsCase.class, OUTPUT_REG_CONVERTOR);
         registerAction13(NxActionResubmitNodesNodeTableFlowApplyActionsCase.class, RESUBMIT_CONVERTOR);
@@ -409,7 +415,7 @@ public class NiciraExtensionProvider implements AutoCloseable {
         registerAction13(NxActionDecapNodesNodeTableFlowApplyActionsCase.class, DECAP_CONVERTOR);
         registerAction13(NxActionDecNshTtlNodesNodeTableFlowApplyActionsCase.class, DEC_NSH_TTL_CONVERTOR);
 
-        registerAction13(NxActionRegLoadNodesNodeTableFlowWriteActionsCase.class, REG_LOAD_CONVERTOR);
+        registerAction13(NxActionRegLoadNodesNodeTableFlowWriteActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
         registerAction13(NxActionRegMoveNodesNodeTableFlowWriteActionsCase.class, REG_MOVE_CONVERTOR);
         registerAction13(NxActionOutputRegNodesNodeTableFlowWriteActionsCase.class, OUTPUT_REG_CONVERTOR);
         registerAction13(NxActionResubmitNodesNodeTableFlowWriteActionsCase.class, RESUBMIT_CONVERTOR);
@@ -424,7 +430,7 @@ public class NiciraExtensionProvider implements AutoCloseable {
         registerAction13(NxActionDecapNodesNodeTableFlowWriteActionsCase.class, DECAP_CONVERTOR);
         registerAction13(NxActionDecNshTtlNodesNodeTableFlowWriteActionsCase.class, DEC_NSH_TTL_CONVERTOR);
 
-        registerAction13(NxActionRegLoadNodesNodeGroupBucketsBucketActionsCase.class, REG_LOAD_CONVERTOR);
+        registerAction13(NxActionRegLoadNodesNodeGroupBucketsBucketActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
         registerAction13(NxActionRegMoveNodesNodeGroupBucketsBucketActionsCase.class, REG_MOVE_CONVERTOR);
         registerAction13(NxActionOutputRegNodesNodeGroupBucketsBucketActionsCase.class, OUTPUT_REG_CONVERTOR);
         registerAction13(NxActionResubmitNodesNodeGroupBucketsBucketActionsCase.class, RESUBMIT_CONVERTOR);
@@ -440,7 +446,7 @@ public class NiciraExtensionProvider implements AutoCloseable {
         registerAction13(NxActionDecNshTtlNodesNodeGroupBucketsBucketActionsCase.class, DEC_NSH_TTL_CONVERTOR);
 
         // src=rpc-addFlow
-        registerAction13(NxActionRegLoadRpcAddFlowApplyActionsCase.class, REG_LOAD_CONVERTOR);
+        registerAction13(NxActionRegLoadRpcAddFlowApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
         registerAction13(NxActionRegMoveRpcAddFlowApplyActionsCase.class, REG_MOVE_CONVERTOR);
         registerAction13(NxActionOutputRegRpcAddFlowApplyActionsCase.class, OUTPUT_REG_CONVERTOR);
         registerAction13(NxActionResubmitRpcAddFlowApplyActionsCase.class, RESUBMIT_CONVERTOR);
@@ -455,7 +461,7 @@ public class NiciraExtensionProvider implements AutoCloseable {
         registerAction13(NxActionDecapRpcAddFlowApplyActionsCase.class, DECAP_CONVERTOR);
         registerAction13(NxActionDecNshTtlRpcAddFlowApplyActionsCase.class, DEC_NSH_TTL_CONVERTOR);
 
-        registerAction13(NxActionRegLoadRpcAddFlowWriteActionsCase.class, REG_LOAD_CONVERTOR);
+        registerAction13(NxActionRegLoadRpcAddFlowWriteActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
         registerAction13(NxActionRegMoveRpcAddFlowWriteActionsCase.class, REG_MOVE_CONVERTOR);
         registerAction13(NxActionOutputRegRpcAddFlowWriteActionsCase.class, OUTPUT_REG_CONVERTOR);
         registerAction13(NxActionResubmitRpcAddFlowWriteActionsCase.class, RESUBMIT_CONVERTOR);
@@ -470,10 +476,10 @@ public class NiciraExtensionProvider implements AutoCloseable {
         registerAction13(NxActionDecapRpcAddFlowWriteActionsCase.class, DECAP_CONVERTOR);
         registerAction13(NxActionDecNshTtlRpcAddFlowWriteActionsCase.class, DEC_NSH_TTL_CONVERTOR);
 
-        registerAction13(NxActionRegLoadRpcAddGroupCase.class, REG_LOAD_CONVERTOR);
-        registerAction13(NxActionRegLoadRpcRemoveGroupCase.class, REG_LOAD_CONVERTOR);
-        registerAction13(NxActionRegLoadRpcUpdateGroupOriginalCase.class, REG_LOAD_CONVERTOR);
-        registerAction13(NxActionRegLoadRpcUpdateGroupUpdatedCase.class, REG_LOAD_CONVERTOR);
+        registerAction13(NxActionRegLoadRpcAddGroupCase.class, REG_LOAD_CONVERTOR_PROXY);
+        registerAction13(NxActionRegLoadRpcRemoveGroupCase.class, REG_LOAD_CONVERTOR_PROXY);
+        registerAction13(NxActionRegLoadRpcUpdateGroupOriginalCase.class, REG_LOAD_CONVERTOR_PROXY);
+        registerAction13(NxActionRegLoadRpcUpdateGroupUpdatedCase.class, REG_LOAD_CONVERTOR_PROXY);
         registerAction13(NxActionRegMoveRpcAddGroupCase.class, REG_MOVE_CONVERTOR);
         registerAction13(NxActionRegMoveRpcRemoveGroupCase.class, REG_MOVE_CONVERTOR);
         registerAction13(NxActionRegMoveRpcUpdateGroupOriginalCase.class, REG_MOVE_CONVERTOR);
@@ -527,17 +533,18 @@ public class NiciraExtensionProvider implements AutoCloseable {
         registerAction13(NxActionDecNshTtlRpcUpdateGroupOriginalCase.class, DEC_NSH_TTL_CONVERTOR);
         registerAction13(NxActionDecNshTtlRpcUpdateGroupUpdatedCase.class, DEC_NSH_TTL_CONVERTOR);
 
-        registerAction13(NxActionRegLoadRpcTransmitPacketCase.class, REG_LOAD_CONVERTOR);
+        registerAction13(NxActionRegLoadRpcTransmitPacketCase.class, REG_LOAD_CONVERTOR_PROXY);
         registerAction13(NxActionResubmitRpcTransmitPacketCase.class, RESUBMIT_CONVERTOR);
-        registerAction13(NxActionRegLoadRpcUpdateFlowOriginalApplyActionsCase.class, REG_LOAD_CONVERTOR);
-        registerAction13(NxActionRegLoadRpcUpdateFlowUpdatedApplyActionsCase.class, REG_LOAD_CONVERTOR);
+        registerAction13(NxActionRegLoadRpcUpdateFlowOriginalApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
+        registerAction13(NxActionRegLoadRpcUpdateFlowUpdatedApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
         registerAction13(NxActionResubmitRpcUpdateFlowUpdatedApplyActionsCase.class, RESUBMIT_CONVERTOR);
         registerAction13(NxActionRegMoveRpcUpdateFlowUpdatedApplyActionsCase.class, REG_MOVE_CONVERTOR);
-        registerAction13(NxActionRegLoadRpcRemoveFlowApplyActionsCase.class, REG_LOAD_CONVERTOR);
+        registerAction13(NxActionRegLoadRpcRemoveFlowApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
         registerAction13(NxActionRegMoveRpcRemoveFlowApplyActionsCase.class, REG_MOVE_CONVERTOR);
         registerAction13(NxActionResubmitRpcRemoveFlowApplyActionsCase.class, RESUBMIT_CONVERTOR);
 
         registerAction13(ActionRegLoad.class, REG_LOAD_CONVERTOR);
+        registerAction13(ActionRegLoad2.class, REG_LOAD2_CONVERTOR);
         registerAction13(ActionRegMove.class, REG_MOVE_CONVERTOR);
         registerAction13(ActionOutputReg.class, OUTPUT_REG_CONVERTOR);
         registerAction13(ActionResubmit.class, RESUBMIT_CONVERTOR);
@@ -554,6 +561,8 @@ public class NiciraExtensionProvider implements AutoCloseable {
 
         registrations.add(extensionConverterRegistrator.registerActionConvertor(
                 NiciraUtil.createOfJavaKeyFrom(RegLoadCodec.SERIALIZER_KEY), REG_LOAD_CONVERTOR));
+        registrations.add(extensionConverterRegistrator.registerActionConvertor(
+                NiciraUtil.createOfJavaKeyFrom(RegLoad2Codec.SERIALIZER_KEY), REG_LOAD2_CONVERTOR));
         registrations.add(extensionConverterRegistrator.registerActionConvertor(
                 NiciraUtil.createOfJavaKeyFrom(RegMoveCodec.SERIALIZER_KEY), REG_MOVE_CONVERTOR));
         registrations.add(extensionConverterRegistrator.registerActionConvertor(
diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoad2Convertor.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoad2Convertor.java
new file mode 100644 (file)
index 0000000..7060f52
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH.  All rights reserved.
+ *
+ * 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.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action;
+
+import com.google.common.base.Preconditions;
+import java.math.BigInteger;
+import java.util.Collections;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowjava.nx.codec.match.NiciraMatchCodecs;
+import org.opendaylight.openflowplugin.extension.api.ConvertorActionFromOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
+import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.CodecPreconditionException;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.match.NshFlagsConvertor;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.match.NshTtlConvertor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.OfjAugNxExpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.ofj.nxm.nx.match.nsh.flags.grouping.NshFlagsValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.ofj.nxm.nx.match.nsh.ttl.grouping.NshTtlValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.oxm.container.match.entry.value.experimenter.id._case.NxExpMatchEntryValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.oxm.container.match.entry.value.experimenter.id._case.nx.exp.match.entry.value.NshFlagsCaseValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.oxm.container.match.entry.value.experimenter.id._case.nx.exp.match.entry.value.NshTtlCaseValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionRegLoadGrouping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshFlagsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshFlagsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshTtlCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshTtlCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoadBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.Dst;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.DstBuilder;
+
+/**
+ * Convert between RegLoad SAL action and RegLoad2 nicira action.
+ */
+public class RegLoad2Convertor implements
+        ConvertorActionToOFJava<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action,
+                Action>,
+        ConvertorActionFromOFJava<Action, ActionPath> {
+
+    @Override
+    public org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action convert(Action input,
+                                                                                                      ActionPath path) {
+        NxActionRegLoad2 actionRegLoad2 = ((ActionRegLoad2) input.getActionChoice()).getNxActionRegLoad2();
+        MatchEntry matchEntry = actionRegLoad2.getMatchEntry().get(0);
+        NxRegLoad nxRegLoad = resolveRegLoad(matchEntry);
+        return RegLoadConvertor.resolveAction(nxRegLoad, path);
+    }
+
+    @Override
+    public Action convert(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionCase) {
+        Preconditions.checkArgument(actionCase instanceof NxActionRegLoadGrouping);
+
+        NxActionRegLoadGrouping nxAction = (NxActionRegLoadGrouping) actionCase;
+        MatchEntry matchEntry = resolveMatchEntry(nxAction.getNxRegLoad());
+        NxActionRegLoad2 nxActionRegLoad2 = new NxActionRegLoad2Builder()
+                .setMatchEntry(Collections.singletonList(matchEntry))
+                .build();
+        ActionRegLoad2 actionRegLoad2 = new ActionRegLoad2Builder().setNxActionRegLoad2(nxActionRegLoad2).build();
+        return ActionUtil.createAction(actionRegLoad2);
+    }
+
+    private static MatchEntry resolveMatchEntry(NxRegLoad nxRegLoad) {
+        Dst dst = nxRegLoad.getDst();
+        BigInteger value = nxRegLoad.getValue();
+        int start = dst.getStart();
+        int end = dst.getEnd();
+        BigInteger[] valueMask = resolveValueMask(value, start, end);
+        value = valueMask[0];
+        BigInteger mask = valueMask[1];
+        DstChoice dstChoice = dst.getDstChoice();
+        return resolveMatchEntry(dstChoice, value, mask);
+    }
+
+    private static MatchEntry resolveMatchEntry(DstChoice dstChoice, BigInteger value, BigInteger mask) {
+        if (dstChoice instanceof DstNxNshFlagsCase) {
+            return NshFlagsConvertor.buildMatchEntry(value.shortValue(), mask.shortValue());
+        }
+        if (dstChoice instanceof DstNxNshTtlCase) {
+            return NshTtlConvertor.buildMatchEntry(value.shortValue(), mask.shortValue());
+        }
+
+        throw new CodecPreconditionException("Missing implementation of a case in dst-choice? " + dstChoice.getClass());
+    }
+
+    private static NxRegLoad resolveRegLoad(MatchEntry matchEntry) {
+        ExperimenterIdCase experimenterIdCase = (ExperimenterIdCase) matchEntry.getMatchEntryValue();
+        OfjAugNxExpMatch ofjAugNxExpMatch = experimenterIdCase.augmentation(OfjAugNxExpMatch.class);
+        NxExpMatchEntryValue nxExpMatchEntryValue = ofjAugNxExpMatch.getNxExpMatchEntryValue();
+        DstBuilder dstBuilder = new DstBuilder();
+        return resolveRegLoad(nxExpMatchEntryValue, dstBuilder);
+    }
+
+    private static NxRegLoad resolveRegLoad(NxExpMatchEntryValue value, DstBuilder dstBuilder) {
+        if (value instanceof NshFlagsCaseValue) {
+            int valueLength = NiciraMatchCodecs.NSH_FLAGS_CODEC.getValueLength();
+            dstBuilder.setDstChoice(new DstNxNshFlagsCaseBuilder().setNxNshFlags(true).build());
+            NshFlagsValues nshFlagsValues = ((NshFlagsCaseValue) value).getNshFlagsValues();
+            return resolveRegLoad(nshFlagsValues.getNshFlags(), nshFlagsValues.getMask(), valueLength, dstBuilder);
+        }
+        if (value instanceof NshTtlCaseValue) {
+            int valueLength = NiciraMatchCodecs.NSH_TTL_CODEC.getValueLength();
+            dstBuilder.setDstChoice(new DstNxNshTtlCaseBuilder().setNxNshTtl(true).build());
+            NshTtlValues nshTtlValues = ((NshTtlCaseValue) value).getNshTtlValues();
+            return resolveRegLoad(nshTtlValues.getNshTtl(), nshTtlValues.getMask(), valueLength, dstBuilder);
+        }
+
+        throw new CodecPreconditionException("Missing codec for " + value.getImplementedInterface());
+    }
+
+    private static NxRegLoad resolveRegLoad(Short value, Short mask, int valueLength, DstBuilder dstBuilder) {
+        return resolveRegLoad(
+                BigInteger.valueOf(value),
+                mask == null ? null : BigInteger.valueOf(mask),
+                valueLength,
+                dstBuilder);
+    }
+
+    private static NxRegLoad resolveRegLoad(BigInteger value,
+                                            @Nullable BigInteger mask,
+                                            int length,
+                                            DstBuilder dstBuilder) {
+        final int start;
+        final int end;
+        if (mask == null) {
+            start = 0;
+            end = length * 8;
+        } else {
+            start = mask.getLowestSetBit();
+            end = start + mask.shiftRight(start).not().getLowestSetBit();
+            value = value.and(mask).shiftRight(start);
+
+            if (value.bitLength() > end - start) {
+                // We cannot map a REG_LOAD2 to a single REG_LOAD if the mask
+                // has multiple 1-bit segments (i.e. 0xFF00FF)
+                throw new IllegalArgumentException("Value does not fit in the first 1-bit segment of the mask");
+            }
+        }
+
+        dstBuilder.setStart(start);
+        dstBuilder.setEnd(end - 1);
+        NxRegLoadBuilder nxRegLoadBuilder = new NxRegLoadBuilder();
+        nxRegLoadBuilder.setDst(dstBuilder.build());
+        nxRegLoadBuilder.setValue(value);
+        return nxRegLoadBuilder.build();
+    }
+
+    private static BigInteger[] resolveValueMask(BigInteger value, int start, int end) {
+        int bits = end - start + 1;
+        if (value.bitLength() > bits) {
+            throw new IllegalArgumentException("Value does not fit the bit range");
+        }
+
+        BigInteger mask = BigInteger.ONE.shiftLeft(bits).subtract(BigInteger.ONE).shiftLeft(start);
+        value = value.shiftLeft(start);
+
+        return new BigInteger[] {value, mask};
+    }
+
+}
index ee3bc42f9fce6f1db75a11485afe039880e938e4..ddd591738066feec65a2e362c662ab97a756a5d9 100644 (file)
@@ -87,7 +87,7 @@ public class RegLoadConvertor implements
         return rightShifted & mask;
     }
 
-    private static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action resolveAction(
+    static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action resolveAction(
             final NxRegLoad value, final ActionPath path) {
         switch (path) {
             case INVENTORY_FLOWNODE_TABLE_WRITE_ACTIONS:
diff --git a/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertorProxy.java b/extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoadConvertorProxy.java
new file mode 100644 (file)
index 0000000..220b963
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH.  All rights reserved.
+ *
+ * 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.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionRegLoadGrouping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshFlagsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshTtlCase;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+/**
+ * RegLoad SAL actions are converted to RegLoad2 action for experimenter
+ * fields, or to RegLoad action otherwise.
+ */
+public class RegLoadConvertorProxy implements
+        ConvertorActionToOFJava<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action,
+                Action> {
+
+    private static final RegLoadConvertor REG_LOAD_CONVERTOR = new RegLoadConvertor();
+    private static final RegLoad2Convertor REG_LOAD2_CONVERTOR = new RegLoad2Convertor();
+
+    private static final Set<Class<? extends DataContainer>> REG_LOAD2_CONVERTEES =
+            new ImmutableSet.Builder<Class<? extends DataContainer>>()
+                    .add(DstNxNshFlagsCase.class)
+                    .add(DstNxNshTtlCase.class)
+                    .build();
+
+    @Override
+    public Action convert(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionCase) {
+        Preconditions.checkArgument(actionCase instanceof NxActionRegLoadGrouping);
+        DstChoice dstChoice = ((NxActionRegLoadGrouping) actionCase).getNxRegLoad().getDst().getDstChoice();
+        if (REG_LOAD2_CONVERTEES.contains(dstChoice.getImplementedInterface())) {
+            return REG_LOAD2_CONVERTOR.convert(actionCase);
+        } else {
+            return REG_LOAD_CONVERTOR.convert(actionCase);
+        }
+    }
+}
index 635c7daed49e3374eb311230ed0689224a27b658..bf671477fb725b510ffded51b47c9186351e3bdd 100644 (file)
@@ -176,6 +176,11 @@ module openflowplugin-extension-nicira-action {
             type empty;
         }
     }
+    grouping nxm-nx-nsh-flags-grouping {
+        leaf nx-nsh-flags {
+            type empty;
+        }
+    }
     grouping nxm-nx-nsh-mdtype-grouping {
         leaf nx-nsh-mdtype {
             type empty;
@@ -186,6 +191,11 @@ module openflowplugin-extension-nicira-action {
             type empty;
         }
     }
+    grouping nxm-nx-nsh-ttl-grouping {
+        leaf nx-nsh-ttl {
+            type empty;
+        }
+    }
     grouping nxm-nx-tun-gpe-np-grouping {
         leaf nx-tun-gpe-np {
             type empty;
@@ -275,12 +285,18 @@ module openflowplugin-extension-nicira-action {
             case dst-nx-encap-eth-dst-case {
                 uses nxm-nx-encap-eth-dst-grouping;
             }
+            case dst-nx-nsh-flags-case {
+                uses nxm-nx-nsh-flags-grouping;
+            }
             case dst-nx-nsh-mdtype-case {
                 uses nxm-nx-nsh-mdtype-grouping;
             }
             case dst-nx-nsh-np-case {
                 uses nxm-nx-nsh-np-grouping;
             }
+            case dst-nx-nsh-ttl-case {
+                uses nxm-nx-nsh-ttl-grouping;
+            }
             case dst-nx-tun-gpe-np-case {
                 uses nxm-nx-tun-gpe-np-grouping;
             }
@@ -370,12 +386,18 @@ module openflowplugin-extension-nicira-action {
             case src-nx-encap-eth-dst-case {
                 uses nxm-nx-encap-eth-dst-grouping;
             }
+            case src-nx-nsh-flags-case {
+                uses nxm-nx-nsh-flags-grouping;
+            }
             case src-nx-nsh-mdtype-case {
                 uses nxm-nx-nsh-mdtype-grouping;
             }
             case src-nx-nsh-np-case {
                 uses nxm-nx-nsh-np-grouping;
             }
+            case src-nx-nsh-ttl-case {
+                uses nxm-nx-nsh-ttl-grouping;
+            }
             case src-nx-tun-gpe-np-case {
                 uses nxm-nx-tun-gpe-np-grouping;
             }
diff --git a/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoad2ConvertorTest.java b/extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/RegLoad2ConvertorTest.java
new file mode 100644 (file)
index 0000000..de818b9
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH.  All rights reserved.
+ *
+ * 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.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collections;
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.match.NshFlagsConvertor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.OfjAugNxExpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.ofj.nxm.nx.match.nsh.flags.grouping.NshFlagsValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.oxm.container.match.entry.value.experimenter.id._case.nx.exp.match.entry.value.NshFlagsCaseValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshFlagsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegLoadNotifGroupDescStatsUpdatedCase;
+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.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNodesNodeTableFlowWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.Dst;
+
+@RunWith(JUnitParamsRunner.class)
+public class RegLoad2ConvertorTest {
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    public static Iterable<Object[]> commonData() {
+        return Arrays.asList(new Object[][] {
+                {0, 0, 0x01, 0x01, 0x01, null},
+                {0, 7, 0xFF, 0xFF, 0xFF, null},
+                {0, 3, 0x0F, 0x0F, 0x0F, null},
+                {4, 7, 0x0F, 0xF0, 0xF0, null},
+                {3, 5, 0x05, 0x28, 0x38, null}
+        });
+    }
+
+    public static Iterable<Object[]> salToOpenflowData() {
+        return Arrays.asList(new Object[][] {
+                // specified values do not fit in the bit range
+                {1, 5, 0xFF, null, null, IllegalArgumentException.class},
+                {3, 5, 0x08, null, null, IllegalArgumentException.class}
+        });
+    }
+
+    public static Iterable<Object[]> openflowToSalData() {
+        return Arrays.asList(new Object[][] {
+                // multiple 1-bit segment in mask
+                {null, null, null, 0x05, 0x05, IllegalArgumentException.class},
+                {null, null, null, 0x28, 0x28, IllegalArgumentException.class},
+                // no mask
+                {0, 7, 0x01, 0x01, null, null}
+        });
+    }
+
+    @Test
+    @Parameters(method = "commonData, salToOpenflowData")
+    public void testConvertSalToOf(Integer rangeStart,
+                                   Integer rangeEnd,
+                                   Integer rangeValue,
+                                   Integer value,
+                                   Integer mask,
+                                   Class<? extends Exception> expectedException) {
+
+        if (expectedException != null) {
+            thrown.expect(expectedException);
+        }
+
+        Dst dst = mock(Dst.class);
+        when(dst.getStart()).thenReturn(rangeStart);
+        when(dst.getEnd()).thenReturn(rangeEnd);
+        NxRegLoad nxRegLoad = mock(NxRegLoad.class);
+        when(nxRegLoad.getValue()).thenReturn(BigInteger.valueOf(rangeValue));
+        when(nxRegLoad.getDst()).thenReturn(dst);
+        when(nxRegLoad.getDst().getDstChoice()).thenReturn(mock(DstNxNshFlagsCase.class));
+        NxActionRegLoadNodesNodeTableFlowApplyActionsCase actionsCase =
+                mock(NxActionRegLoadNodesNodeTableFlowApplyActionsCase.class);
+        when(actionsCase.getNxRegLoad()).thenReturn(nxRegLoad);
+
+        RegLoad2Convertor regLoad2Convertor = new RegLoad2Convertor();
+        ActionRegLoad2 actionRegLoad = (ActionRegLoad2) regLoad2Convertor.convert(actionsCase).getActionChoice();
+
+        MatchEntry matchEntry = actionRegLoad.getNxActionRegLoad2().getMatchEntry().get(0);
+        ExperimenterIdCase experimenterIdCase = (ExperimenterIdCase) matchEntry.getMatchEntryValue();
+        OfjAugNxExpMatch ofjAugNxExpMatch = experimenterIdCase.augmentation(OfjAugNxExpMatch.class);
+        NshFlagsCaseValue nshFlagsCaseValue = (NshFlagsCaseValue) ofjAugNxExpMatch.getNxExpMatchEntryValue();
+        NshFlagsValues nshFlagsValues = nshFlagsCaseValue.getNshFlagsValues();
+
+        assertEquals(value.intValue(), nshFlagsValues.getNshFlags().intValue());
+        assertEquals(mask.intValue(), nshFlagsValues.getMask().intValue());
+    }
+
+    @Test
+    @Parameters(method = "commonData, openflowToSalData")
+    public void testConvertOfToSal(Integer rangeStart,
+                                   Integer rangeEnd,
+                                   Integer rangeValue,
+                                   Integer value,
+                                   Integer mask,
+                                   Class<? extends Exception> expectedException) {
+
+        if (expectedException != null) {
+            thrown.expect(expectedException);
+        }
+
+        NxActionRegLoad2 nxActionRegLoad2 = mock(NxActionRegLoad2.class);
+        when(nxActionRegLoad2.getMatchEntry()).thenReturn(Collections.singletonList(
+                NshFlagsConvertor.buildMatchEntry(value.shortValue(), mask == null ? null : mask.shortValue())));
+        ActionRegLoad2 actionRegLoad2 = mock(ActionRegLoad2.class);
+        when(actionRegLoad2.getNxActionRegLoad2()).thenReturn(nxActionRegLoad2);
+        Action action = mock(Action.class);
+        when(action.getActionChoice()).thenReturn(actionRegLoad2);
+
+        RegLoad2Convertor regLoad2Convertor = new RegLoad2Convertor();
+
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult
+                = regLoad2Convertor.convert(action, ActionPath.INVENTORY_FLOWNODE_TABLE_WRITE_ACTIONS);
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult1
+                = regLoad2Convertor.convert(action, ActionPath.FLOWS_STATISTICS_UPDATE_APPLY_ACTIONS);
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult2
+                = regLoad2Convertor.convert(action, ActionPath.FLOWS_STATISTICS_UPDATE_WRITE_ACTIONS);
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3
+                = regLoad2Convertor.convert(action, ActionPath.GROUP_DESC_STATS_UPDATED_BUCKET_ACTION);
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4
+                = regLoad2Convertor.convert(action, ActionPath.FLOWS_STATISTICS_RPC_APPLY_ACTIONS);
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5
+                = regLoad2Convertor.convert(action, ActionPath.FLOWS_STATISTICS_RPC_WRITE_ACTIONS);
+
+        assertEquals(rangeStart,
+                ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getDst().getStart());
+        assertEquals(rangeEnd,
+                ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getDst().getEnd());
+        assertEquals(BigInteger.valueOf(rangeValue),
+                ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getValue());
+
+        assertEquals(rangeStart,
+                ((NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase) actionResult1).getNxRegLoad().getDst()
+                        .getStart());
+        assertEquals(rangeEnd,
+                ((NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase) actionResult1).getNxRegLoad().getDst()
+                        .getEnd());
+        assertEquals(BigInteger.valueOf(rangeValue),
+                ((NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase) actionResult1).getNxRegLoad().getValue());
+
+        assertEquals(rangeStart,
+                ((NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase) actionResult2).getNxRegLoad().getDst()
+                        .getStart());
+        assertEquals(rangeEnd,
+                ((NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase) actionResult2).getNxRegLoad().getDst()
+                        .getEnd());
+        assertEquals(BigInteger.valueOf(rangeValue),
+                ((NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase) actionResult2).getNxRegLoad().getValue());
+
+        assertEquals(rangeStart,
+                ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getDst().getStart());
+        assertEquals(rangeEnd,
+                ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getDst().getEnd());
+        assertEquals(BigInteger.valueOf(rangeValue),
+                ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getValue());
+
+        assertEquals(rangeStart,
+                ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getDst()
+                        .getStart());
+        assertEquals(rangeEnd,
+                ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getDst()
+                        .getEnd());
+        assertEquals(BigInteger.valueOf(rangeValue),
+                ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getValue());
+
+        assertEquals(rangeStart,
+                ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getDst()
+                        .getStart());
+        assertEquals(rangeEnd,
+                ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getDst()
+                        .getEnd());
+        assertEquals(BigInteger.valueOf(rangeValue),
+                ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getValue());
+    }
+}
\ No newline at end of file
index f6b5f523230b2f38b13555583972a6df6665ef12..5b77e44468d796c2070a5b0394aca1aa77deb50b 100644 (file)
                 <artifactId>argparse4j</artifactId>
                 <version>0.7.0</version>
             </dependency>
+            <dependency>
+                <groupId>pl.pragmatists</groupId>
+                <artifactId>JUnitParams</artifactId>
+                <version>1.0.3</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>