multipart reply message updated 06/2206/2
authorTimotej Kubas <timotej.kubas@pantheon.sk>
Mon, 28 Oct 2013 08:00:41 +0000 (09:00 +0100)
committerTimotej Kubas <timotej.kubas@pantheon.sk>
Mon, 28 Oct 2013 12:55:26 +0000 (13:55 +0100)
added actions
added match entries
fixed names for augmentation

Change-Id: I4d663eabb8ad0ac883c470ca0577b9c853e50805
Signed-off-by: Timotej Kubas <timotej.kubas@pantheon.sk>
openflow-protocol-api/pom.xml
openflow-protocol-api/src/main/yang/openflow-augments.yang
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionCreator.java [new file with mode: 0644]
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntriesCreator.java [new file with mode: 0644]
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactoryTest.java

index c8cea44e4f93b035ec3d263bef791456ffe85359..fc71be0d6f9c8e20d61bf677a119f5d1d8aaac54 100644 (file)
             <artifactId>ietf-yang-types</artifactId>\r
             <version>2010.09.24-SNAPSHOT</version>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller.model</groupId>\r
+            <artifactId>model-flow-service</artifactId>\r
+            <version>1.0-SNAPSHOT</version>\r
+        </dependency>\r
 \r
     </dependencies>\r
 </project>
\ No newline at end of file
index 37c2f5b2ed904f95c870f4a445235ff9f82148e0..75c6590b96c6e6d032f6a4d9d029394a105d23ad 100644 (file)
@@ -1,7 +1,8 @@
 module openflow-augments {\r
     namespace "urn:opendaylight:openflow:augments";\r
     prefix "aug";\r
-\r
+    \r
+    import yang-ext {prefix ext;}\r
     import ietf-inet-types {prefix inet;}\r
     import ietf-yang-types {prefix yang;}\r
 \r
@@ -17,126 +18,151 @@ module openflow-augments {
 \r
 // OFP_MATCH AUGMENTS\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "port-number-match-entry";\r
          leaf port-number {\r
              type oft:port-number;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "metadata-match-entry";\r
          leaf metadata {\r
              type binary;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "mask-match-entry";\r
          leaf mask {\r
              type binary;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "mac-address-match-entry";\r
          leaf mac-address {\r
              type yang:mac-address;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "eth-type-match-entry";\r
          leaf eth-type {\r
              type oft:ether-type;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "vlan-vid-match-entry";\r
          leaf vlan-vid {\r
              type uint16;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "vlan-pcp-match-entry";\r
          leaf vlan-pcp {\r
              type uint8;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "dscp-match-entry";\r
          leaf dscp {\r
              type inet:dscp;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "ecn-match-entry";\r
          leaf ecn {\r
              type uint8;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "protocol-number-match-entry";\r
          leaf protocol-number {\r
              type uint8;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "ipv4-prefix-match-entry";\r
          leaf ipv4-prefix {\r
              type inet:ipv4-prefix;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "port-match-entry";\r
          leaf port {\r
              type inet:port-number;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "icmpv4-type-match-entry";\r
          leaf icmpv4-type {\r
              type uint8;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "icmpv4-code-match-entry";\r
          leaf icmpv4-code {\r
              type uint8;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "op-code-match-entry";\r
          leaf op-code {\r
              type uint16;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "ipv6-prefix-match-entry";\r
          leaf ipv6-prefix {\r
              type inet:ipv6-prefix;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "ipv6-flabel-match-entry";\r
          leaf ipv6-flabel {\r
              type inet:ipv6-flow-label;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "icmpv6-type-match-entry";\r
          leaf icmpv6-type {\r
              type uint8;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "icmpv6-code-match-entry";\r
          leaf icmpv6-code {\r
              type uint8;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "ipv6-address-match-entry";\r
          leaf ipv6-address {\r
              type inet:ipv6-address;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "mpls-label-match-entry";\r
          leaf mpls-label {\r
              type uint32;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "tc-match-entry";\r
          leaf tc {\r
              type uint8;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "bos-match-entry";\r
          leaf bos {\r
              type boolean;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "isid-match-entry";\r
          leaf isid {\r
              type uint32;\r
          }\r
      }\r
      augment "/oxm:oxm-container/oxm:match-entries" {\r
+         ext:augment-identifier "pseudo-field-match-entry";\r
          leaf pseudo-field {\r
              type bits {\r
                  bit nonext {\r
@@ -181,44 +207,53 @@ module openflow-augments {
 \r
 // OFP_ACTION AUGMENTS\r
      augment "/ofaction:actions-container/ofaction:action" {\r
+         ext:augment-identifier "port-action";\r
          leaf port {\r
              type oft:any-port-number;\r
          }\r
      }\r
      augment "/ofaction:actions-container/ofaction:action" {\r
+         ext:augment-identifier "max-length-action";\r
          leaf max-length {\r
              type uint16;\r
          }\r
      }\r
      augment "/ofaction:actions-container/ofaction:action" {\r
+         ext:augment-identifier "mpls-ttl-action";\r
          leaf mpls-ttl {\r
              type uint8;\r
          }\r
      }\r
      augment "/ofaction:actions-container/ofaction:action" {\r
+         ext:augment-identifier "ethertype-action";\r
          leaf ethertype {\r
              type oft:ether-type;\r
          }\r
      }\r
      augment "/ofaction:actions-container/ofaction:action" {\r
+         ext:augment-identifier "queue-id-action";\r
          leaf queue-id {\r
              type uint32;\r
          }\r
      }\r
      augment "/ofaction:actions-container/ofaction:action" {\r
+         ext:augment-identifier "group-id-action";\r
          leaf group-id {\r
              type uint32;\r
          }\r
      }\r
      augment "/ofaction:actions-container/ofaction:action" {\r
+         ext:augment-identifier "nw-ttl-action";\r
          leaf nw-ttl {\r
              type uint8;\r
          }\r
      }\r
      augment "/ofaction:actions-container/ofaction:action" {\r
+         ext:augment-identifier "oxm-fields-action";\r
          uses oxm:oxm-fields;\r
      }\r
      augment "/ofaction:actions-container/ofaction:action" {\r
+         ext:augment-identifier "experimenter-action";\r
          leaf experimenter {\r
              type uint32;\r
          }\r
@@ -226,11 +261,13 @@ module openflow-augments {
 \r
 // OFP_TABLE_FEATURES_PROPERTIES AUGMENTS\r
      augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" {\r
+         ext:augment-identifier "instruction-ids-table-feature-properties";\r
          list instruction-ids {\r
              uses ofinstruction:instructions;\r
          }\r
      }\r
      augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" {\r
+         ext:augment-identifier "next-table-ids-table-feature-properties";\r
          list next-table-ids {\r
              leaf table-id {\r
                  type uint8;\r
@@ -238,16 +275,19 @@ module openflow-augments {
          }\r
      }\r
      augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" {\r
+         ext:augment-identifier "action-ids-table-feature-properties";\r
          list action-ids {\r
              uses ofaction:action-header;\r
          }\r
      }\r
      augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" {\r
+         ext:augment-identifier "oxm-ids-table-feature-properties";\r
          list oxm-ids {\r
              uses oxm:oxm-fields;\r
          }\r
      }\r
      augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" {\r
+         ext:augment-identifier "experimenter-table-feature-properties";\r
          leaf experimenter {\r
              type uint32;\r
          }\r
@@ -261,11 +301,13 @@ module openflow-augments {
 \r
 // OFP_INSTRUCTION AUGMENTS\r
      augment "/ofinstruction:instruction-container/ofinstruction:instruction" {\r
+         ext:augment-identifier "table-id-instruction";\r
          leaf table-id {\r
              type uint8;\r
          }\r
      }\r
      augment "/ofinstruction:instruction-container/ofinstruction:instruction" {\r
+         ext:augment-identifier "metadata-instruction";\r
          leaf metadata {\r
              type binary;\r
          }\r
@@ -274,16 +316,19 @@ module openflow-augments {
          }\r
      }\r
      augment "/ofinstruction:instruction-container/ofinstruction:instruction" {\r
+         ext:augment-identifier "action-header-instruction";\r
          list actions {\r
              uses ofaction:action-header;\r
          }\r
      }\r
      augment "/ofinstruction:instruction-container/ofinstruction:instruction" {\r
+         ext:augment-identifier "meter-id-instruction";\r
          leaf meter-id {\r
              type uint32;\r
          }\r
      }\r
      augment "/ofinstruction:instruction-container/ofinstruction:instruction" {\r
+         ext:augment-identifier "experimenter-instruction";\r
          leaf experimenter {\r
              type uint32;\r
          }\r
index ffa36485441eb2da8bf87ca49e681842d5304c1a..a8011b81506e4289687c29f9ed7bfe5a3e81a13d 100644 (file)
@@ -8,8 +8,10 @@ import java.util.ArrayList;
 import java.util.List;\r
 \r
 import org.opendaylight.openflowjava.protocol.impl.deserialization.OFDeserializer;\r
+import org.opendaylight.openflowjava.protocol.impl.util.ActionCreator;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandType;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterModCommand;\r
@@ -17,9 +19,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev13
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.bucket.ActionsList;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterBuilder;\r
@@ -33,6 +37,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroup;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDesc;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeter;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfig;\r
@@ -51,6 +57,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow.FlowStatsBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.GroupStats;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.GroupStatsBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.GroupDesc;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.GroupDescBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.group.desc.BucketsList;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.group.desc.BucketsListBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.group.stats.BucketStats;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.group.stats.BucketStatsBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.MeterStats;\r
@@ -119,6 +129,8 @@ public class MultipartReplyMessageFactory implements OFDeserializer<MultipartRep
                  break;         \r
         case 6:  builder.setMultipartReplyBody(setGroup(rawMessage));\r
                  break;\r
+        case 7:  builder.setMultipartReplyBody(setGroupDesc(rawMessage));\r
+                 break;\r
         case 9:  builder.setMultipartReplyBody(setMeter(rawMessage));\r
                  break;\r
         case 10:  builder.setMultipartReplyBody(setMeterConfig(rawMessage));\r
@@ -166,12 +178,12 @@ public class MultipartReplyMessageFactory implements OFDeserializer<MultipartRep
     private static MultipartReplyFlow setFlow(ByteBuf input) {\r
         final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1;\r
         final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4;\r
+        final byte flowLength = 2;\r
         MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();\r
         List<FlowStats> flowStatsList = new ArrayList<>();\r
         FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();\r
-        int flowLen = 0;\r
         while (input.readableBytes() > 0) {\r
-            flowLen = input.readUnsignedShort();\r
+            input.skipBytes(flowLength);\r
             flowStatsBuilder.setTableId(input.readUnsignedByte());\r
             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01);\r
             flowStatsBuilder.setDurationSec(input.readUnsignedInt());\r
@@ -461,6 +473,7 @@ public class MultipartReplyMessageFactory implements OFDeserializer<MultipartRep
     private static MultipartReplyMeterConfig setMeterConfig(ByteBuf input) {\r
         final byte METER_BAND_LENGTH = 16;\r
         final byte METER_CONFIG_LENGTH = 8;\r
+        final byte bandLength = 2;\r
         int actualLength;\r
         MultipartReplyMeterConfigBuilder builder = new MultipartReplyMeterConfigBuilder();\r
         List<MeterConfig> meterConfigList = new ArrayList<>();\r
@@ -481,18 +494,17 @@ public class MultipartReplyMessageFactory implements OFDeserializer<MultipartRep
                 MeterBandDscpRemarkBuilder bandDscpRemarkBuilder = new MeterBandDscpRemarkBuilder();\r
                 final byte PADDING_IN_METER_BAND_DSCP_HEADER = 3;\r
                 MeterBandExperimenterBuilder bandExperimenterBuilder = new MeterBandExperimenterBuilder(); \r
-                int bandLen = 0;\r
                 int bandType = input.readUnsignedShort();\r
                 switch (bandType) {\r
                     case 1: bandDropBuilder.setType(MeterBandType.forValue(bandType));\r
-                            bandLen = input.readUnsignedShort();\r
+                            input.skipBytes(bandLength);\r
                             bandDropBuilder.setRate(input.readUnsignedInt());\r
                             bandDropBuilder.setBurstSize(input.readUnsignedInt());\r
                             input.skipBytes(PADDING_IN_METER_BAND_DROP_HEADER);\r
                             bandsBuilder.setMeterBand(bandDropBuilder.build());\r
                             break;\r
                     case 2: bandDscpRemarkBuilder.setType(MeterBandType.forValue(bandType));\r
-                            bandLen = input.readUnsignedShort();\r
+                            input.skipBytes(bandLength);\r
                             bandDscpRemarkBuilder.setRate(input.readUnsignedInt());\r
                             bandDscpRemarkBuilder.setBurstSize(input.readUnsignedInt());\r
                             bandDscpRemarkBuilder.setPrecLevel(input.readUnsignedByte());\r
@@ -500,7 +512,7 @@ public class MultipartReplyMessageFactory implements OFDeserializer<MultipartRep
                             bandsBuilder.setMeterBand(bandDscpRemarkBuilder.build());\r
                             break;\r
                     case 0xFFFF: bandExperimenterBuilder.setType(MeterBandType.forValue(bandType));\r
-                                 bandLen = input.readUnsignedShort();          \r
+                                 input.skipBytes(bandLength);\r
                                  bandExperimenterBuilder.setRate(input.readUnsignedInt());\r
                                  bandExperimenterBuilder.setBurstSize(input.readUnsignedInt());\r
                                  bandExperimenterBuilder.setExperimenter(input.readUnsignedInt());\r
@@ -607,4 +619,52 @@ public class MultipartReplyMessageFactory implements OFDeserializer<MultipartRep
         return new PortFeatures(_10mbHd, _10mbFd, _100mbHd, _100mbFd, _1gbHd, _1gbFd, _10gbFd,\r
                 _40gbFd, _100gbFd, _1tbFd, _other, _copper, _fiber, _autoneg, _pause, _pauseAsym);\r
     }\r
+    \r
+    private static MultipartReplyGroupDesc setGroupDesc(ByteBuf input) {\r
+        final byte PADDING_IN_GROUP_DESC_HEADER = 1;\r
+        final byte PADDING_IN_BUCKETS_HEADER = 4;\r
+        final byte GROUP_DESC_HEADER_LENGTH = 8;\r
+        int actualLength;\r
+        int bucketsLength = 0;\r
+        int bucketsCurrentLength = 0;\r
+        int bodyLength = 0;\r
+        MultipartReplyGroupDescBuilder builder = new MultipartReplyGroupDescBuilder();\r
+        GroupDescBuilder groupDescBuilder = new GroupDescBuilder();\r
+        List<GroupDesc> groupDescsList = new ArrayList<>();\r
+        BucketsListBuilder bucketsBuilder = new BucketsListBuilder();\r
+        List<BucketsList> bucketsList = new ArrayList<>();\r
+        List<ActionsList> actionsList = new ArrayList<>();\r
+        \r
+        while (input.readableBytes() > 0) {\r
+            bodyLength = input.readUnsignedShort();\r
+            actualLength = 0;\r
+            \r
+            groupDescBuilder.setType(GroupType.forValue(input.readUnsignedByte())); // TODO enum or class?\r
+            input.skipBytes(PADDING_IN_GROUP_DESC_HEADER);\r
+            groupDescBuilder.setGroupId(input.readUnsignedInt());\r
+            actualLength = GROUP_DESC_HEADER_LENGTH;\r
+            \r
+            while (actualLength < bodyLength) {\r
+                \r
+                bucketsLength = input.readUnsignedShort();\r
+                bucketsBuilder.setWeight(input.readUnsignedShort());\r
+                bucketsBuilder.setWatchPort(new PortNumber(input.readUnsignedInt()));\r
+                bucketsBuilder.setWatchGroup(input.readUnsignedInt());\r
+                input.skipBytes(PADDING_IN_BUCKETS_HEADER);\r
+                bucketsCurrentLength = bucketsLength;\r
+                actionsList = ActionCreator.createActionsList(input, bucketsLength);\r
+                bucketsBuilder.setActionsList(new ArrayList<>(actionsList));\r
+                actionsList.clear();\r
+                bucketsList.add(bucketsBuilder.build());\r
+                actualLength = actualLength + bucketsCurrentLength;\r
+            }\r
+            groupDescBuilder.setBucketsList(new ArrayList<>(bucketsList));\r
+            bucketsList.clear();\r
+            groupDescsList.add(groupDescBuilder.build());\r
+        }\r
+        builder.setGroupDesc(new ArrayList<>(groupDescsList));\r
+        groupDescsList.clear();\r
+        return builder.build();\r
+    }\r
+    \r
 }\r
diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionCreator.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionCreator.java
new file mode 100644 (file)
index 0000000..3610d73
--- /dev/null
@@ -0,0 +1,403 @@
+/* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
+package org.opendaylight.openflowjava.protocol.impl.util;\r
+\r
+import io.netty.buffer.ByteBuf;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlIn;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlOut;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecMplsTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecNwTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Experimenter;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Group;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopMpls;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopPbb;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopVlan;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushMpls;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushPbb;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushVlan;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetMplsTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetQueue;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.action.header.ActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.AnyPortNumber;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.bucket.ActionsList;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.bucket.ActionsListBuilder;\r
+\r
+/**\r
+ * Class for easy creation of actions\r
+ * \r
+ * @author timotej.kubas\r
+ * @author michal.polkorab\r
+ */\r
+public abstract class ActionCreator {\r
+    final static byte PAD_ACTION_LENGTH = 2;\r
+    private static ActionBuilder actionBuilder = new ActionBuilder();\r
+    private static ActionsListBuilder actionsListBuilder = new ActionsListBuilder();\r
+    private static List<ActionsList> actionsList = new ArrayList<>();\r
+/**\r
+ * @param inp input ByteBuf\r
+ * @param bucketsLength length of buckets\r
+ * @return ActionsList\r
+ */\r
+    public static List<ActionsList> createActionsList(ByteBuf inp, int bucketsLength) {\r
+        final byte BUCKET_HEADER_LENGTH = 16;\r
+        int bucketsCurrentLength = BUCKET_HEADER_LENGTH;\r
+        int actionsLength = 0;\r
+            \r
+            while (bucketsCurrentLength < bucketsLength) {\r
+                switch(inp.readUnsignedShort()) {\r
+                case 0: actionsLength = inp.readUnsignedShort(); //outputActionLength\r
+                        actionsList.add(ActionCreator.createOutputAction(inp));\r
+                        bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                        break;\r
+                case 11: \r
+                         actionsLength = inp.readUnsignedShort();//empty header length\r
+                         actionsList.add(ActionCreator.createCopyTtlOutAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                         \r
+                case 12: \r
+                         actionsLength = inp.readUnsignedShort();//empty header length\r
+                         actionsList.add(ActionCreator.createCopyTtlInAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                \r
+                case 15: \r
+                         actionsLength = inp.readUnsignedShort();//empty header length\r
+                         actionsList.add(ActionCreator.createSetMplsTtlAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                         \r
+                case 16:                              \r
+                         actionsLength = inp.readUnsignedShort();//empty header length\r
+                         actionsList.add(ActionCreator.createDecMplsTtlOutAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                         \r
+                case 17: \r
+                         actionsLength = inp.readUnsignedShort();\r
+                         actionsList.add(ActionCreator.createPushVlanAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                         \r
+                case 18:                              \r
+                         actionsLength = inp.readUnsignedShort();//empty header length\r
+                         actionsList.add(ActionCreator.createPopVlanAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                         \r
+                case 19: \r
+                         actionsLength = inp.readUnsignedShort();//8\r
+                         actionsList.add(ActionCreator.createPushMplsAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                         \r
+                case 20: \r
+                         actionsLength = inp.readUnsignedShort();//8\r
+                         actionsList.add(ActionCreator.createPopMplsAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                         \r
+                case 21: \r
+                         actionsLength = inp.readUnsignedShort();\r
+                         actionsList.add(ActionCreator.createSetQueueAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                         \r
+                case 22: \r
+                        actionsLength = inp.readUnsignedShort();//8\r
+                        actionsList.add(ActionCreator.createGroupAction(inp));\r
+                        bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                        break;\r
+                        \r
+                case 23: \r
+                         actionsLength = inp.readUnsignedShort();//8\r
+                         actionsList.add(ActionCreator.createSetNwTtlAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                        \r
+                case 24:                              \r
+                        actionsLength = inp.readUnsignedShort();//empty header length\r
+                        actionsList.add(ActionCreator.createDecNwTtlAction(inp));\r
+                        bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                        break;\r
+                        \r
+                case 25:\r
+                        actionsLength = inp.readUnsignedShort();//8\r
+                        //TODO field\r
+                        actionsList.add(ActionCreator.createSetFieldAction(inp, actionsLength));\r
+                        bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                        break; \r
+                case 26: \r
+                         actionsLength = inp.readUnsignedShort();//8\r
+                         actionsList.add(ActionCreator.createPushPbbAction(inp));\r
+                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                         break;\r
+                         \r
+                case 27:                              \r
+                        actionsLength = inp.readUnsignedShort();//empty header length\r
+                        actionsList.add(ActionCreator.createPopPbbAction(inp));\r
+                        bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                        break;\r
+                        \r
+                case 0xFFFF: \r
+                        actionsLength = inp.readUnsignedShort();\r
+                        actionsList.add(ActionCreator.createExperimenterAction(inp));\r
+                        bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
+                        break;\r
+                default: \r
+                         break;\r
+                }\r
+            } \r
+        return actionsList;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * @param action input action that contains empty header\r
+     * @param in input ByteBuf \r
+     * @return Action\r
+     */\r
+    private static ActionsList createEmptyHeader(Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Action> action, ByteBuf in) {\r
+        final byte PADDING_IN_ACTIONS_HEADER = 4;\r
+        \r
+        actionBuilder.setType(action);\r
+        in.skipBytes(PADDING_IN_ACTIONS_HEADER);\r
+        actionsListBuilder.setAction(actionBuilder.build());\r
+        return actionsListBuilder.build();\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createCopyTtlInAction(ByteBuf in) {\r
+        return createEmptyHeader(CopyTtlIn.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createCopyTtlOutAction(ByteBuf in) {\r
+        return createEmptyHeader(CopyTtlOut.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createDecMplsTtlOutAction(ByteBuf in) {\r
+        return createEmptyHeader(DecMplsTtl.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createPopVlanAction(ByteBuf in) {\r
+        return createEmptyHeader(PopVlan.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createDecNwTtlAction(ByteBuf in) {\r
+        return createEmptyHeader(DecNwTtl.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createPopPbbAction(ByteBuf in) {\r
+        return createEmptyHeader(PopPbb.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return ActionList\r
+     */\r
+    public static ActionsList createOutputAction(ByteBuf in) {\r
+        final byte PADDING_IN_OUTPUT_ACTIONS_HEADER = 6;\r
+        \r
+        actionBuilder.setType(Output.class);\r
+        PortActionBuilder port = new PortActionBuilder();\r
+        port.setPort(new AnyPortNumber(new PortNumber(in.readUnsignedInt())));\r
+        actionBuilder.addAugmentation(PortAction.class, port.build());\r
+        MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();\r
+        maxLen.setMaxLength(in.readUnsignedShort());\r
+        actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build());\r
+        actionsListBuilder.setAction(actionBuilder.build());\r
+        in.skipBytes(PADDING_IN_OUTPUT_ACTIONS_HEADER);\r
+        \r
+        return actionsListBuilder.build();\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return ActionList\r
+     */\r
+    public static ActionsList createSetMplsTtlAction(ByteBuf in) {\r
+        final byte PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER = 3;\r
+        \r
+        actionBuilder.setType(SetMplsTtl.class);\r
+        MplsTtlActionBuilder mplsTtl = new MplsTtlActionBuilder();\r
+        mplsTtl.setMplsTtl(in.readUnsignedByte());\r
+        actionBuilder.addAugmentation(MplsTtlAction.class, mplsTtl.build());\r
+        actionsListBuilder.setAction(actionBuilder.build());\r
+        in.skipBytes(PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER);\r
+        \r
+        return actionsListBuilder.build();\r
+    }\r
+    \r
+    /**\r
+     * @param action input action that contains push\r
+     * @param in input ByteBuf\r
+     * @return ActionList\r
+     */\r
+    private static ActionsList createPushAction(Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Action> action, ByteBuf in) {\r
+        final byte PADDING_IN_PUSH_VLAN_ACTIONS_HEADER = 2;\r
+        \r
+        actionBuilder.setType(action);\r
+        EthertypeActionBuilder etherType = new EthertypeActionBuilder();\r
+        etherType.setEthertype(new EtherType(in.readUnsignedShort()));\r
+        actionBuilder.addAugmentation(EthertypeAction.class, etherType.build());\r
+        actionsListBuilder.setAction(actionBuilder.build());\r
+        in.skipBytes(PADDING_IN_PUSH_VLAN_ACTIONS_HEADER);\r
+        \r
+        return actionsListBuilder.build();\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createPushVlanAction(ByteBuf in) {\r
+        return createPushAction(PushVlan.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createPushMplsAction(ByteBuf in) {\r
+        return createPushAction(PushMpls.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createPopMplsAction(ByteBuf in) {\r
+        return createPushAction(PopMpls.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return Action\r
+     */\r
+    public static ActionsList createPushPbbAction(ByteBuf in) {\r
+        return createPushAction(PushPbb.class, in);\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return ActionList\r
+     */\r
+    public static ActionsList createSetQueueAction(ByteBuf in) {\r
+        actionBuilder.setType(SetQueue.class);\r
+        QueueIdActionBuilder queueId = new QueueIdActionBuilder();\r
+        queueId.setQueueId(in.readUnsignedInt());\r
+        actionBuilder.addAugmentation(QueueIdAction.class, queueId.build());\r
+        actionsListBuilder.setAction(actionBuilder.build());\r
+        \r
+        return actionsListBuilder.build();\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return ActionList\r
+     */\r
+    public static ActionsList createGroupAction(ByteBuf in) {\r
+        actionBuilder.setType(Group.class);\r
+        GroupIdActionBuilder group = new GroupIdActionBuilder();\r
+        group.setGroupId(in.readUnsignedInt());\r
+        actionBuilder.addAugmentation(GroupIdAction.class, group.build());\r
+        actionsListBuilder.setAction(actionBuilder.build());\r
+        \r
+        return actionsListBuilder.build();\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return ActionList\r
+     */\r
+    public static ActionsList createExperimenterAction(ByteBuf in) {\r
+        actionBuilder.setType(Experimenter.class);\r
+        ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();\r
+        experimenter.setExperimenter(in.readUnsignedInt());\r
+        actionBuilder.addAugmentation(ExperimenterAction.class, experimenter.build());\r
+        actionsListBuilder.setAction(actionBuilder.build());\r
+        \r
+        return actionsListBuilder.build();\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @return ActionList\r
+     */\r
+    public static ActionsList createSetNwTtlAction(ByteBuf in) {\r
+        final byte PADDING_IN_NW_TTL_ACTIONS_HEADER = 3;\r
+        \r
+        actionBuilder.setType(SetNwTtl.class);\r
+        NwTtlActionBuilder nwTtl = new NwTtlActionBuilder();\r
+        nwTtl.setNwTtl(in.readUnsignedByte());\r
+        actionBuilder.addAugmentation(NwTtlAction.class, nwTtl.build());\r
+        actionsListBuilder.setAction(actionBuilder.build());\r
+        in.skipBytes(PADDING_IN_NW_TTL_ACTIONS_HEADER);\r
+        \r
+        return actionsListBuilder.build();\r
+    }\r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @param actionLength length of action\r
+     * @return ActionList\r
+     */\r
+    public static ActionsList createSetFieldAction(ByteBuf in, int actionLength) {\r
+        actionBuilder.setType(SetField.class);\r
+        OxmFieldsActionBuilder matchEntries = new OxmFieldsActionBuilder();\r
+        matchEntries.setMatchEntries(MatchEntriesCreator.createMatchEntry(in, actionLength - 4));\r
+        actionBuilder.addAugmentation(OxmFieldsAction.class, matchEntries.build());\r
+        actionsListBuilder.setAction(actionBuilder.build());\r
+        \r
+        return actionsListBuilder.build();\r
+    }\r
+}\r
diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntriesCreator.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntriesCreator.java
new file mode 100644 (file)
index 0000000..7d5456c
--- /dev/null
@@ -0,0 +1,117 @@
+/* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
+package org.opendaylight.openflowjava.protocol.impl.util;\r
+\r
+import io.netty.buffer.ByteBuf;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MacAddressMatchEntry;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MacAddressMatchEntryBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataMatchEntry;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataMatchEntryBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntryBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthDst;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ExperimenterClass;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Metadata;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm0Class;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm1Class;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntriesBuilder;\r
+\r
+/**\r
+ * To create matches\r
+ * @author timotej.kubas\r
+ * @author michal.polkorab\r
+ */\r
+public abstract class MatchEntriesCreator {\r
+    private static List<MatchEntries> matchEntriesList = new ArrayList<>();\r
+    private static MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder(); \r
+    \r
+    /**\r
+     * @param in input ByteBuf\r
+     * @param matchArrayLength to infer size of array\r
+     * @return MatchEntriesList\r
+     */\r
+    public static List<MatchEntries> createMatchEntry(ByteBuf in, int matchArrayLength) {\r
+        int currMatchLength = 0;\r
+        final byte MATCH_LENGTH = 1;\r
+        \r
+        while(currMatchLength < matchArrayLength) {\r
+            \r
+            switch (in.readUnsignedShort()) { \r
+            case 0x0000:\r
+                        matchEntriesBuilder.setOxmClass(Nxm0Class.class);\r
+                        break;\r
+            case 0x0001:\r
+                        matchEntriesBuilder.setOxmClass(Nxm1Class.class);\r
+                        break;\r
+            case 0x8000:\r
+                        matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
+                        break;\r
+            case 0xFFFF:\r
+                        matchEntriesBuilder.setOxmClass(ExperimenterClass.class);\r
+                        break;\r
+            default:\r
+                        break;\r
+            }\r
+            currMatchLength = currMatchLength +2;\r
+            \r
+            int matchField = in.readUnsignedByte() >>> 1;\r
+            in.skipBytes(MATCH_LENGTH);\r
+            \r
+            currMatchLength = currMatchLength + 2;\r
+            \r
+            switch(matchField) {\r
+            case 0: \r
+                matchEntriesBuilder.setOxmMatchField(InPort.class);\r
+                PortNumberMatchEntryBuilder port = new PortNumberMatchEntryBuilder();\r
+                port.setPortNumber(new PortNumber(in.readUnsignedInt())); \r
+                matchEntriesBuilder.addAugmentation(PortNumberMatchEntry.class, port.build());\r
+                currMatchLength = currMatchLength + 4;\r
+                break;\r
+            case 1:\r
+                matchEntriesBuilder.setOxmMatchField(InPhyPort.class);\r
+                PortNumberMatchEntryBuilder phyPort = new PortNumberMatchEntryBuilder();\r
+                phyPort.setPortNumber(new PortNumber(in.readUnsignedInt())); \r
+                matchEntriesBuilder.addAugmentation(PortNumberMatchEntry.class, phyPort.build());\r
+                currMatchLength = currMatchLength + 4;\r
+                break;\r
+            case 2:\r
+                matchEntriesBuilder.setOxmMatchField(Metadata.class);\r
+                MetadataMatchEntryBuilder metadata = new MetadataMatchEntryBuilder();\r
+                byte[] metadataBytes = new byte[Long.SIZE/Byte.SIZE];\r
+                in.readBytes(metadataBytes);\r
+                metadata.setMetadata(metadataBytes); \r
+                matchEntriesBuilder.addAugmentation(MetadataMatchEntry.class, metadata.build());\r
+                currMatchLength = currMatchLength + 8;\r
+                break;\r
+            case 3:\r
+                matchEntriesBuilder.setOxmMatchField(EthDst.class);\r
+                MacAddressMatchEntryBuilder macAddress = new MacAddressMatchEntryBuilder();\r
+                StringBuffer macToString = new StringBuffer();\r
+                final int macAddressLength = 6;\r
+                for(int i=0; i<macAddressLength ; i++){\r
+                    short mac = 0;\r
+                    mac = in.readUnsignedByte();\r
+                    macToString.append(String.format("%02X", mac));\r
+                }\r
+                macAddress.setMacAddress(new MacAddress(macToString.toString())); \r
+                matchEntriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddress.build());\r
+                currMatchLength = currMatchLength + 8;\r
+                break;\r
+            default: \r
+                break;\r
+            }\r
+          matchEntriesList.add(matchEntriesBuilder.build());\r
+        }\r
+        \r
+        return matchEntriesList;\r
+    }\r
+}\r
index af700bbba83467e99733d71ff6e6c37b253728f8..e96b05b8b13930efc2adebe0ae4dd33468c07cb7 100644 (file)
@@ -10,11 +10,41 @@ import org.junit.Test;
 import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper;\r
 import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlIn;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlOut;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecMplsTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecNwTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Experimenter;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Group;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopMpls;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopPbb;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopVlan;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushMpls;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushPbb;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushVlan;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetMplsTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetQueue;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDrop;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemark;\r
@@ -24,6 +54,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenter;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlow;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroup;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDesc;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeter;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfig;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeatures;\r
@@ -40,7 +71,7 @@ public class MultipartReplyMessageFactoryTest {
 \r
     /**\r
      * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO\r
-     */\r
+     *//*\r
     @Test\r
     public void test(){\r
         ByteBuf bb = BufferHelper.buildBuffer("00 07 00 01 00 00 00 00 01 02 03 04");\r
@@ -51,7 +82,7 @@ public class MultipartReplyMessageFactoryTest {
         Assert.assertEquals("Wrong type", 0x07, builtByFactory.getType().getIntValue());\r
         Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE());\r
         //Assert.assertArrayEquals("Wrong body", new byte[]{0x01, 0x02, 0x03, 0x04}, builtByFactory.getBody());\r
-    }\r
+    }*/\r
     \r
     /**\r
      * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO\r
@@ -847,4 +878,377 @@ public class MultipartReplyMessageFactoryTest {
         Assert.assertEquals("Wrong currSpeed", 129L, message.getPorts().get(0).getCurrSpeed().longValue());\r
         Assert.assertEquals("Wrong maxSpeed", 128L, message.getPorts().get(0).getMaxSpeed().longValue());\r
     }\r
+    \r
+    /**\r
+     * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO\r
+     * Test covers bodies of actions Output, Copy TTL Out, Copy TTL In\r
+     */\r
+    @Test\r
+    public void testMultipartReplyGroupDescBody01(){\r
+        ByteBuf bb = BufferHelper.buildBuffer("00 07 00 01 00 00 00 00 "+\r
+                                              "00 38 "+//len\r
+                                              "01 "+//type\r
+                                              "00 "+//pad\r
+                                              "00 00 00 08 "+//groupId\r
+                                              "00 30 "+//bucketLen\r
+                                              "00 06 "+//bucketWeight\r
+                                              "00 00 00 05 "+//bucketWatchPort\r
+                                              "00 00 00 04 "+//bucketWatchGroup\r
+                                              "00 00 00 00 "+//bucketPad\r
+                                              "00 00 "+//outputType\r
+                                              "00 10 "+//outputLen\r
+                                              "00 00 10 FF "+//outputPort\r
+                                              "FF FF "+//outputMaxLen\r
+                                              "00 00 00 00 00 00 "+//outputPad\r
+                                              "00 0B "+//copyTTLOutType\r
+                                              "00 08 "+//copyTTLOutLen\r
+                                              "00 00 00 00 "+//copyTTLOutPad\r
+                                              "00 0C "+//copyTTLIntType\r
+                                              "00 08 "+//copyTTLIntLen\r
+                                              "00 00 00 00"//copyTTLInPad\r
+                                              );\r
+        \r
+        MultipartReplyMessage builtByFactory = BufferHelper.decodeV13(MultipartReplyMessageFactory.getInstance(), bb);\r
+        \r
+        BufferHelper.checkHeaderV13(builtByFactory);\r
+        Assert.assertEquals("Wrong type", 7, builtByFactory.getType().getIntValue());\r
+        Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE());\r
+        \r
+        MultipartReplyGroupDesc message = (MultipartReplyGroupDesc) builtByFactory.getMultipartReplyBody();\r
+        \r
+        Assert.assertEquals("Wrong type", 1, \r
+                             message.getGroupDesc().get(0).getType().getIntValue());\r
+        Assert.assertEquals("Wrong groupId", 8, \r
+                             message.getGroupDesc().get(0).getGroupId().intValue());\r
+        Assert.assertEquals("Wrong bucketWeight", 6, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWeight().intValue());\r
+        Assert.assertEquals("Wrong bucketWatchPort", 5, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWatchPort().\r
+                                                                        getValue().intValue());\r
+        Assert.assertEquals("Wrong bucketWatchGroup", 4, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWatchGroup().intValue());\r
+        \r
+        Assert.assertEquals("Wrong outputType", Output.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(0).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong outputPort", 4351, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(0).\r
+                getAction().getAugmentation(PortAction.class).\r
+                getPort().getPortNumber().getValue().intValue());\r
+        \r
+        Assert.assertEquals("Wrong outputMaxLen", 65535, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(0).\r
+                getAction().getAugmentation(MaxLengthAction.class).\r
+                getMaxLength().intValue());\r
+        \r
+        Assert.assertEquals("Wrong copyTtlOutType", CopyTtlOut.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(1).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong copyTtlInType", CopyTtlIn.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getType());\r
+    }\r
+    \r
+    /**\r
+     * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO\r
+     * Test covers bodies of actions Set MPLS TTL , Dec MPLS TTL, Push VLAN. Push MPLS, Push PBB\r
+     */\r
+    @Test\r
+    public void testMultipartReplyGroupDescBody02(){\r
+        ByteBuf bb = BufferHelper.buildBuffer("00 07 00 01 00 00 00 00 "+\r
+                                              "00 40 "+//len\r
+                                              "01 "+//type\r
+                                              "00 "+//pad\r
+                                              "00 00 00 08 "+//groupId\r
+                                              "00 38 "+//bucketLen\r
+                                              "00 06 "+//bucketWeight\r
+                                              "00 00 00 05 "+//bucketWatchPort\r
+                                              "00 00 00 04 "+//bucketWatchGroup\r
+                                              "00 00 00 00 "+//bucketPad\r
+                                              "00 0F "+//setMplsTtlType\r
+                                              "00 08 "+//setMplsTtlLen\r
+                                              "09 "+//setMplsTtlMPLS_TTL\r
+                                              "00 00 00 "+//setMplsTtlPad\r
+                                              "00 10 "+//decMplsTtlType\r
+                                              "00 08 "+//decMplsTtlLen\r
+                                              "00 00 00 00 "+//decMplsTtlPad\r
+                                              "00 11 "+//pushVlanType\r
+                                              "00 08 "+//pushVlanLen\r
+                                              "00 20 "+//pushVlanEthertype\r
+                                              "00 00 "+//pushVlanPad\r
+                                              "00 13 "+//pushMplsType\r
+                                              "00 08 "+//pushMplsLen\r
+                                              "00 FF "+//pushMplsEthertype\r
+                                              "00 00 "+//pushMplsPad\r
+                                              "00 1A "+//pushPbbType\r
+                                              "00 08 "+//pushPbbLen\r
+                                              "0F FF "+//pushPbbEthertype\r
+                                              "00 00"//pushPbbPad\r
+                                              );\r
+        \r
+        MultipartReplyMessage builtByFactory = BufferHelper.decodeV13(MultipartReplyMessageFactory.getInstance(), bb);\r
+        \r
+        BufferHelper.checkHeaderV13(builtByFactory);\r
+        Assert.assertEquals("Wrong type", 7, builtByFactory.getType().getIntValue());\r
+        Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE());\r
+        \r
+        MultipartReplyGroupDesc message = (MultipartReplyGroupDesc) builtByFactory.getMultipartReplyBody();\r
+        \r
+        Assert.assertEquals("Wrong type", 1, \r
+                             message.getGroupDesc().get(0).getType().getIntValue());\r
+        Assert.assertEquals("Wrong groupId", 8, \r
+                             message.getGroupDesc().get(0).getGroupId().intValue());\r
+        Assert.assertEquals("Wrong bucketWeight", 6, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWeight().intValue());\r
+        Assert.assertEquals("Wrong bucketWatchPort", 5, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWatchPort().\r
+                                                                        getValue().intValue());\r
+        Assert.assertEquals("Wrong bucketWatchGroup", 4, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWatchGroup().intValue());\r
+        \r
+        \r
+        Assert.assertEquals("Wrong setMplsTtlType", SetMplsTtl.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(0).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong setMplsTtlMPLS_TTL", 9, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(0).\r
+                getAction().getAugmentation(MplsTtlAction.class).\r
+                getMplsTtl().intValue());\r
+        \r
+        Assert.assertEquals("Wrong decMplsTtlType", DecMplsTtl.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(1).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong pushVlanType", PushVlan.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong pushVlanEthertype", 32, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getAugmentation(EthertypeAction.class).\r
+                getEthertype().getValue().intValue());\r
+        \r
+        Assert.assertEquals("Wrong pushMplsType", PushMpls.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(3).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong pushMplsEthertype", 255, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(3).\r
+                getAction().getAugmentation(EthertypeAction.class).\r
+                getEthertype().getValue().intValue());\r
+        \r
+        Assert.assertEquals("Wrong pushPbbType", PushPbb.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(4).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong pushPbbEthertype", 4095, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(4).\r
+                getAction().getAugmentation(EthertypeAction.class).\r
+                getEthertype().getValue().intValue());\r
+        \r
+    }\r
+    \r
+    /**\r
+     * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO\r
+     * Test covers bodies of actions Pop VLAN, Pop PBB, Pop MPLS, Group, Dec NW TTL\r
+     */\r
+    @Test\r
+    public void testMultipartReplyGroupDescBody03(){\r
+        ByteBuf bb = BufferHelper.buildBuffer("00 07 00 01 00 00 00 00 "+\r
+                                              "00 48 "+//len\r
+                                              "01 "+//type\r
+                                              "00 "+//pad\r
+                                              "00 00 00 08 "+//groupId\r
+                                              "00 40 "+//bucketLen\r
+                                              "00 06 "+//bucketWeight\r
+                                              "00 00 00 05 "+//bucketWatchPort\r
+                                              "00 00 00 04 "+//bucketWatchGroup\r
+                                              "00 00 00 00 "+//bucketPad\r
+                                              "00 12 "+//popVlanType\r
+                                              "00 08 "+//popVlanLen\r
+                                              "00 00 00 00 "+//popVlanPad\r
+                                              "00 1B "+//popPbbType\r
+                                              "00 08 "+//popPbbLen\r
+                                              "00 00 00 00 "+//popPbbPad\r
+                                              "00 14 "+//popMplsType\r
+                                              "00 08 "+//popMplsLen\r
+                                              "00 CF "+//popMplsEthertype\r
+                                              "00 00 "+//popMplsPad\r
+                                              "00 15 "+//setQueueType\r
+                                              "00 08 "+//setQueueLen\r
+                                              "00 CF 00 00 "+//setQueueQueueId\r
+                                              "00 16 "+//groupType\r
+                                              "00 08 "+//groupLen\r
+                                              "00 CF 00 00 "+//groupGroupId\r
+                                              "00 18 "+//decNwTtlType\r
+                                              "00 08 "+//decNwTtlLen\r
+                                              "00 00 00 00"//decNwTtlPad\r
+                                              );\r
+        \r
+        MultipartReplyMessage builtByFactory = BufferHelper.decodeV13(MultipartReplyMessageFactory.getInstance(), bb);\r
+        \r
+        BufferHelper.checkHeaderV13(builtByFactory);\r
+        Assert.assertEquals("Wrong type", 7, builtByFactory.getType().getIntValue());\r
+        Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE());\r
+        \r
+        MultipartReplyGroupDesc message = (MultipartReplyGroupDesc) builtByFactory.getMultipartReplyBody();\r
+        \r
+        Assert.assertEquals("Wrong type", 1, \r
+                             message.getGroupDesc().get(0).getType().getIntValue());\r
+        Assert.assertEquals("Wrong groupId", 8, \r
+                             message.getGroupDesc().get(0).getGroupId().intValue());\r
+        Assert.assertEquals("Wrong bucketWeight", 6, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWeight().intValue());\r
+        Assert.assertEquals("Wrong bucketWatchPort", 5, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWatchPort().\r
+                                                                        getValue().intValue());\r
+        Assert.assertEquals("Wrong bucketWatchGroup", 4, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWatchGroup().intValue());\r
+        \r
+        Assert.assertEquals("Wrong popVlanType", PopVlan.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(0).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong popPbbType", PopPbb.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(1).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong popMplsType", PopMpls.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong popMplsEthertype", 207, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getAugmentation(EthertypeAction.class).\r
+                getEthertype().getValue().intValue());\r
+        \r
+        Assert.assertEquals("Wrong setQueueType", SetQueue.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(3).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong setQueueQueueId", 13565952, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(3).\r
+                getAction().getAugmentation(QueueIdAction.class).\r
+                getQueueId().intValue());\r
+        \r
+        Assert.assertEquals("Wrong groupType", Group.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(4).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong groupGroupId", 13565952, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(4).\r
+                getAction().getAugmentation(GroupIdAction.class).\r
+                getGroupId().intValue());\r
+        \r
+        Assert.assertEquals("Wrong decNwTtlType", DecNwTtl.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(5).\r
+                getAction().getType());\r
+    }\r
+    \r
+    /**\r
+     * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO\r
+     * Test covers bodies of actions NW TTL, Experimenter\r
+     */\r
+    @Test\r
+    public void testMultipartReplyGroupDescBody04(){\r
+        ByteBuf bb = BufferHelper.buildBuffer("00 07 00 01 00 00 00 00 "+\r
+                                              "00 3C "+//len\r
+                                              "01 "+//type\r
+                                              "00 "+//pad\r
+                                              "00 00 00 08 "+//groupId\r
+                                              "00 34 "+//bucketLen\r
+                                              "00 06 "+//bucketWeight\r
+                                              "00 00 00 05 "+//bucketWatchPort\r
+                                              "00 00 00 04 "+//bucketWatchGroup\r
+                                              "00 00 00 00 "+//bucketPad\r
+                                              "00 17 "+//nwTTlType\r
+                                              "00 08 "+//nwTTlLen\r
+                                              "0E "+//nwTTlnwTTL\r
+                                              "00 00 00 "+//nwTTlPad\r
+                                              "FF FF "+//experimenterType\r
+                                              "00 08 "+//experimenterLen\r
+                                              "00 01 02 03 "+//experimenterExperimenter\r
+                                              "00 19 "+//setFieldType\r
+                                              "00 14 "+//setFieldLen\r
+                                              "80 00 "+//setFieldOXMClass\r
+                                              "00 "+//setFieldOXMField\r
+                                              "04 "+//setFieldOXMLength\r
+                                              "00 00 00 FF "+//setFieldPort\r
+                                              \r
+                                              "80 00 "+//setFieldOXMClass\r
+                                              "03 "+//setFieldOXMField\r
+                                              "04 "+//setFieldOXMLength\r
+                                              "00 00 0F FF"//setFieldPort\r
+                                              );\r
+        \r
+        MultipartReplyMessage builtByFactory = BufferHelper.decodeV13(MultipartReplyMessageFactory.getInstance(), bb);\r
+        \r
+        BufferHelper.checkHeaderV13(builtByFactory);\r
+        Assert.assertEquals("Wrong type", 7, builtByFactory.getType().getIntValue());\r
+        Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE());\r
+        \r
+        MultipartReplyGroupDesc message = (MultipartReplyGroupDesc) builtByFactory.getMultipartReplyBody();\r
+        \r
+        Assert.assertEquals("Wrong type", 1, \r
+                             message.getGroupDesc().get(0).getType().getIntValue());\r
+        Assert.assertEquals("Wrong groupId", 8, \r
+                             message.getGroupDesc().get(0).getGroupId().intValue());\r
+        Assert.assertEquals("Wrong bucketWeight", 6, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWeight().intValue());\r
+        Assert.assertEquals("Wrong bucketWatchPort", 5, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWatchPort().\r
+                                                                        getValue().intValue());\r
+        Assert.assertEquals("Wrong bucketWatchGroup", 4, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getWatchGroup().intValue());\r
+        \r
+        Assert.assertEquals("Wrong nwTTlType", SetNwTtl.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(0).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong nwTTlnwTTL", 14, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(0).\r
+                getAction().getAugmentation(NwTtlAction.class).getNwTtl().intValue());\r
+        \r
+        Assert.assertEquals("Wrong experimenterType", Experimenter.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(1).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong experimenterExperimenter", 66051, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(1).\r
+                getAction().getAugmentation(ExperimenterAction.class).getExperimenter().intValue());\r
+        \r
+        Assert.assertEquals("Wrong setFieldType", SetField.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getType());\r
+        \r
+        Assert.assertEquals("Wrong setFieldOXMClass", OpenflowBasicClass.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getAugmentation(OxmFieldsAction.class).getMatchEntries().get(0).getOxmClass());\r
+        \r
+        Assert.assertEquals("Wrong setFieldOXMField", InPort.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getAugmentation(OxmFieldsAction.class).getMatchEntries().get(0).getOxmMatchField());\r
+        \r
+        Assert.assertEquals("Wrong setFieldOXMField", 255, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getAugmentation(OxmFieldsAction.class).getMatchEntries().get(0).\r
+                getAugmentation(PortNumberMatchEntry.class).getPortNumber().getValue().intValue());\r
+        \r
+        \r
+        Assert.assertEquals("Wrong setFieldOXMClass", OpenflowBasicClass.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getAugmentation(OxmFieldsAction.class).getMatchEntries().get(1).getOxmClass());\r
+        \r
+        Assert.assertEquals("Wrong setFieldOXMField", InPhyPort.class, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getAugmentation(OxmFieldsAction.class).getMatchEntries().get(1).getOxmMatchField());\r
+        \r
+        Assert.assertEquals("Wrong setFieldOXMField", 4095, \r
+                message.getGroupDesc().get(0).getBucketsList().get(0).getActionsList().get(2).\r
+                getAction().getAugmentation(OxmFieldsAction.class).getMatchEntries().get(1).\r
+                getAugmentation(PortNumberMatchEntry.class).getPortNumber().getValue().intValue());\r
+    }\r
 }\r