Bug-1421 - MD-SAL app cannot create a flow entry which adds a VLAN tag with the speci...
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / TableFeaturesConvertor.java
index 8a95399febd67a5e0229db9eeca5ff02ad369578..d4f34222f2c36996f66074a30845559ed9d0a12a 100644 (file)
@@ -8,10 +8,8 @@
 
 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
+import com.google.common.collect.Ordering;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.OrderComparator;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.CopyTtlInCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.CopyTtlOutCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecMplsTtlCase;
@@ -45,10 +43,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeaturePropertyBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIdsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.actions.list.ActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpOp;
@@ -86,21 +83,21 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.PbbI
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.SctpDst;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.SctpSrc;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpDst;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpFlag;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpSrc;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TunnelId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TunnelIpv4Dst;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TunnelIpv4Src;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.UdpDst;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.UdpSrc;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanPcp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanVid;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntriesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeatureProperties;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeaturePropertiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.ApplyActions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.ApplyActionsMiss;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.ApplySetfield;
@@ -115,9 +112,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.WriteActionsMiss;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.WriteSetfield;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.WriteSetfieldMiss;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.match.MatchSetfield;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.next.table.miss.TablesMiss;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.wildcards.WildcardSetfield;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * Utility class for converting a MD-SAL Table features into the OF library table
  * features.
@@ -135,7 +139,7 @@ public class TableFeaturesConvertor {
             ofTableFeatures.setName(salTableFeatures.getName());
             ofTableFeatures.setMetadataMatch(salTableFeatures.getMetadataMatch());
             ofTableFeatures.setMetadataWrite(salTableFeatures.getMetadataWrite());
-            ofTableFeatures.setMaxEntries(new Long(0)); 
+            ofTableFeatures.setMaxEntries(salTableFeatures.getMaxEntries()); 
             if (salTableFeatures.getConfig() != null) {
                 ofTableFeatures.setConfig(new TableConfig(salTableFeatures.getConfig().isDEPRECATEDMASK()));
             }
@@ -151,9 +155,14 @@ public class TableFeaturesConvertor {
             return Collections.<TableFeatureProperties> emptyList();
         }
         List<TableFeatureProperties> ofTablePropertiesList = new ArrayList<>();
-        
-        for (org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.table.features.table.properties.TableFeatureProperties property : tableProperties
-                .getTableFeatureProperties()) {
+
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.table.features.table.properties.TableFeatureProperties>
+            sortedTableProperties =
+                Ordering.from(OrderComparator.<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.table.features.table.properties.TableFeatureProperties>toInstance())
+                    .sortedCopy(tableProperties.getTableFeatureProperties());
+
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.table.features.table.properties.TableFeatureProperties
+            property : sortedTableProperties) {
                TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder();
                
             org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.TableFeaturePropType propType = property
@@ -175,8 +184,8 @@ public class TableFeaturesConvertor {
                 setNextTableFeatureProperty(propBuilder, TableFeaturesPropType.OFPTFPTNEXTTABLES,
                         (tables == null) ? new ArrayList<Short>() : tables.getTableIds());
             } else if (propType instanceof NextTableMiss) {
-                org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.next.table.miss.Tables tables = ((NextTableMiss) propType)
-                        .getTables();
+                TablesMiss tables = ((NextTableMiss) propType)
+                        .getTablesMiss();
                 setNextTableFeatureProperty(propBuilder, TableFeaturesPropType.OFPTFPTNEXTTABLESMISS,
                         (tables == null) ? new ArrayList<Short>() : tables.getTableIds());
             } else if (propType instanceof WriteActions) {
@@ -212,48 +221,75 @@ public class TableFeaturesConvertor {
                         ((applyActionsMiss == null) ? new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action>()
                                 : applyActionsMiss.getAction()));
             } else if (propType instanceof Match) {
-                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = ((Match) propType)
-                        .getSetFieldMatch();
+                MatchSetfield matchSetField = ((Match) propType).getMatchSetfield();
+                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = null;
+                
+                if( null != matchSetField) {
+                    setFieldMatch = matchSetField.getSetFieldMatch();
+                }
+                
                 setSetFieldTableFeatureProperty(
                         propBuilder,
                         TableFeaturesPropType.OFPTFPTMATCH,
                         ((setFieldMatch == null) ? new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch>()
                                 : setFieldMatch));
             } else if (propType instanceof Wildcards) {
-                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = ((Wildcards) propType)
-                        .getSetFieldMatch();
+                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = null;
+                WildcardSetfield wildcardSetField = ((Wildcards) propType).getWildcardSetfield();
+                
+                if (null != wildcardSetField) {
+                    setFieldMatch = wildcardSetField.getSetFieldMatch();
+                }
+                
                 setSetFieldTableFeatureProperty(
                         propBuilder,
                         TableFeaturesPropType.OFPTFPTWILDCARDS,
                         ((setFieldMatch == null) ? new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch>()
                                 : setFieldMatch));
             } else if (propType instanceof WriteSetfield) {
-                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = ((WriteSetfield) propType)
-                        .getSetFieldMatch();
+                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = null; 
+                org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.write.setfield.WriteSetfield writeSetField = ((WriteSetfield) propType).getWriteSetfield();
+                
+                if (null != writeSetField) {
+                    setFieldMatch = writeSetField.getSetFieldMatch();
+                }
+                
                 setSetFieldTableFeatureProperty(
                         propBuilder,
                         TableFeaturesPropType.OFPTFPTWRITESETFIELD,
                         ((setFieldMatch == null) ? new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch>()
                                 : setFieldMatch));
             } else if (propType instanceof WriteSetfieldMiss) {
-                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = ((WriteSetfieldMiss) propType)
-                        .getSetFieldMatch();
+                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = null;
+                org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.write.setfield.miss.WriteSetfieldMiss writeSetfieldMiss = ((WriteSetfieldMiss) propType).getWriteSetfieldMiss();
+                
+                if (null != writeSetfieldMiss) {
+                    setFieldMatch = writeSetfieldMiss.getSetFieldMatch();
+                }
                 setSetFieldTableFeatureProperty(
                         propBuilder,
                         TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS,
                         ((setFieldMatch == null) ? new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch>()
                                 : setFieldMatch));
             } else if (propType instanceof ApplySetfield) {
-                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = ((ApplySetfield) propType)
-                        .getSetFieldMatch();
+                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = null; 
+                org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.apply.setfield.ApplySetfield applySetfield = ((ApplySetfield) propType).getApplySetfield();
+                  
+                if (null != applySetfield) {
+                    setFieldMatch = applySetfield.getSetFieldMatch();
+                }
                 setSetFieldTableFeatureProperty(
                         propBuilder,
                         TableFeaturesPropType.OFPTFPTAPPLYSETFIELD,
                         ((setFieldMatch == null) ? new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch>()
                                 : setFieldMatch));
             } else if (propType instanceof ApplySetfieldMiss) {
-                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = ((ApplySetfieldMiss) propType)
-                        .getSetFieldMatch();
+                List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch> setFieldMatch = null;
+                org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.apply.setfield.miss.ApplySetfieldMiss applySetfieldMiss = ((ApplySetfieldMiss) propType).getApplySetfieldMiss();
+                
+                if (null != applySetfieldMiss) {
+                    setFieldMatch = applySetfieldMiss.getSetFieldMatch();
+                }
                 setSetFieldTableFeatureProperty(
                         propBuilder,
                         TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS,
@@ -268,10 +304,10 @@ public class TableFeaturesConvertor {
 
     private static void setInstructionTableFeatureProperty(TableFeaturePropertiesBuilder builder,
             TableFeaturesPropType type, List<Instruction> instructionList) {
-        List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions> instructionTypeList = new ArrayList<>();
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction> instructionTypeList = new ArrayList<>();
         
         for (Instruction currInstruction : instructionList) {
-               InstructionsBuilder instructionType = new InstructionsBuilder();
+               InstructionBuilder instructionType = new InstructionBuilder();
                
             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction instruction = currInstruction
                     .getInstruction();
@@ -297,7 +333,7 @@ public class TableFeaturesConvertor {
             instructionTypeList.add(instructionType.build());
         }
         InstructionRelatedTableFeaturePropertyBuilder propBuilder = new InstructionRelatedTableFeaturePropertyBuilder();
-        propBuilder.setInstructions(instructionTypeList);
+        propBuilder.setInstruction(instructionTypeList);
         builder.setType(type);
         builder.addAugmentation(InstructionRelatedTableFeatureProperty.class, propBuilder.build());
     }
@@ -320,9 +356,7 @@ public class TableFeaturesConvertor {
     private static void setActionTableFeatureProperty(TableFeaturePropertiesBuilder builder,
             TableFeaturesPropType type,
             List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> salActions) {
-        List<ActionsList> actionList = new ArrayList<>();
-        
-        ActionsListBuilder actionListBuilder = new ActionsListBuilder();
+        List<Action> actionList = new ArrayList<>();
         
         for (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action currAction : salActions) {
             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionType = currAction
@@ -377,10 +411,10 @@ public class TableFeaturesConvertor {
                 actionBuilder
                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopPbb.class);
             } // Experimenter action is unhandled
-            actionList.add(actionListBuilder.setAction(actionBuilder.build()).build());
+            actionList.add(actionBuilder.build());
         }
         ActionRelatedTableFeaturePropertyBuilder propBuilder = new ActionRelatedTableFeaturePropertyBuilder();
-        propBuilder.setActionsList(actionList);
+        propBuilder.setAction(actionList);
         builder.setType(type);
         builder.addAugmentation(ActionRelatedTableFeatureProperty.class, propBuilder.build());
     }
@@ -514,6 +548,18 @@ public class TableFeaturesConvertor {
             } else if (currMatchType
                     .equals(org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.VlanVid.class)) {
                 setMatchEntry(matchEntryBuilder, VlanVid.class, currMatch.isHasMask());
+            } else if (currMatchType
+                    .equals(org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TcpFlag.class)) {
+
+                //FIXME: move to extensible support
+                // TODO: Move to seperate bundle as soon as extensions are supported
+                setMatchEntry(matchEntryBuilder, TcpFlag.class, currMatch.isHasMask());
+            } else if (currMatchType
+                    .equals(org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelIpv4Dst.class)) {
+                setMatchEntry(matchEntryBuilder, TunnelIpv4Dst.class, currMatch.isHasMask());
+            } else if (currMatchType
+                    .equals(org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelIpv4Src.class)) {
+                setMatchEntry(matchEntryBuilder, TunnelIpv4Src.class, currMatch.isHasMask());
             }
             matchEntriesList.add(matchEntryBuilder.build());
         }
@@ -530,4 +576,4 @@ public class TableFeaturesConvertor {
         builder.setOxmMatchField(field);
         builder.setHasMask(hasMask);
     }
-}
\ No newline at end of file
+}