OF1.0 fixes
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / ErrorMessageFactory.java
index e4122ac4e677d75ec3529327f9157390a2533368..3463855bafd1ef70f7a88f83b23054210d72df45 100644 (file)
@@ -4,17 +4,37 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
 import io.netty.buffer.ByteBuf;\r
 \r
 import org.opendaylight.openflowjava.protocol.impl.deserialization.OFDeserializer;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterError;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterErrorBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadActionCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadInstructionCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadMatchCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadRequestCode;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ErrorType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFailedCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupModFailedCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloFailedCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterModFailedCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortModFailedCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueOpFailedCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.RoleRequestFailedCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFailedCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesFailedCode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableModFailedCode;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;\r
 \r
 /**\r
+ * Translates Error messages\r
  * @author michal.polkorab\r
- *\r
+ * @author timotej.kubas\r
  */\r
 public class ErrorMessageFactory implements OFDeserializer<ErrorMessage> {\r
 \r
-private static ErrorMessageFactory instance;\r
+    private static final String UNKNOWN_CODE = "UNKNOWN_CODE";\r
+    private static final String UNKNOWN_TYPE = "UNKNOWN_TYPE";\r
+    \r
+    private static ErrorMessageFactory instance;\r
     \r
     private ErrorMessageFactory() {\r
         // do nothing, just singleton\r
@@ -23,7 +43,7 @@ private static ErrorMessageFactory instance;
     /**\r
      * @return singleton factory\r
      */\r
-    public static ErrorMessageFactory getInstance() {\r
+    public static synchronized ErrorMessageFactory getInstance() {\r
         if (instance == null) {\r
             instance = new ErrorMessageFactory();\r
         }\r
@@ -32,17 +52,197 @@ private static ErrorMessageFactory instance;
     \r
     @Override\r
     public ErrorMessage bufferToMessage(ByteBuf rawMessage, short version) {\r
-        ErrorMessageBuilder emb = new ErrorMessageBuilder();\r
-        emb.setVersion(version);\r
-        emb.setXid(rawMessage.readUnsignedInt());\r
-        ErrorType[] errorTypes = ErrorType.values();\r
-        // TODO - finish implementation after enums are generated with proper funcionality\r
-        //emb.setType();\r
-        emb.setCode(rawMessage.readInt());\r
-        byte[] data = new byte[rawMessage.readableBytes()];\r
-        rawMessage.readBytes(data);\r
-        emb.setData(data);\r
-        return emb.build();\r
+        ErrorMessageBuilder builder = new ErrorMessageBuilder();\r
+        builder.setVersion(version);\r
+        builder.setXid(rawMessage.readUnsignedInt());\r
+        int type = rawMessage.readUnsignedShort();\r
+        ErrorType errorType = ErrorType.forValue(type);\r
+        decodeType(builder, errorType, type);\r
+        decodeCode(rawMessage, builder, errorType);\r
+        if (rawMessage.readableBytes() > 0) {\r
+            builder.setData(rawMessage.readBytes(rawMessage.readableBytes()).array());\r
+        }\r
+        return builder.build();\r
+    }\r
+    \r
+    private static void decodeType(ErrorMessageBuilder builder, ErrorType type, int readValue) {\r
+        if (type != null) {\r
+            builder.setType(type.getIntValue());\r
+            builder.setTypeString(type.name());\r
+        } else {\r
+            builder.setType(readValue);\r
+            builder.setTypeString(UNKNOWN_TYPE);\r
+        }\r
+    }\r
+\r
+    private static void decodeCode(ByteBuf rawMessage, ErrorMessageBuilder builder,\r
+            ErrorType type) {\r
+        int code = rawMessage.readUnsignedShort();\r
+        if (type != null) {\r
+            switch (type) {\r
+            case HELLOFAILED:\r
+            {\r
+                HelloFailedCode errorCode = HelloFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case BADREQUEST:\r
+            {\r
+                BadRequestCode errorCode = BadRequestCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case BADACTION:\r
+            {\r
+                BadActionCode errorCode = BadActionCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case BADINSTRUCTION:\r
+            {\r
+                BadInstructionCode errorCode = BadInstructionCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case BADMATCH:\r
+            {\r
+                BadMatchCode errorCode = BadMatchCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case FLOWMODFAILED:\r
+            {\r
+                FlowModFailedCode errorCode = FlowModFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case GROUPMODFAILED:\r
+            {\r
+                GroupModFailedCode errorCode = GroupModFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case PORTMODFAILED:\r
+            {\r
+                PortModFailedCode errorCode = PortModFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case TABLEMODFAILED:\r
+            {\r
+                TableModFailedCode errorCode = TableModFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case QUEUEOPFAILED:\r
+            {\r
+                QueueOpFailedCode errorCode = QueueOpFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case SWITCHCONFIGFAILED:\r
+            {\r
+                SwitchConfigFailedCode errorCode = SwitchConfigFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case ROLEREQUESTFAILED:\r
+            {\r
+                RoleRequestFailedCode errorCode = RoleRequestFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case METERMODFAILED:\r
+            {\r
+                MeterModFailedCode errorCode = MeterModFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case TABLEFEATURESFAILED:\r
+            {\r
+                TableFeaturesFailedCode errorCode = TableFeaturesFailedCode.forValue(code);\r
+                if (errorCode != null) {\r
+                    setCode(builder, errorCode.getIntValue(), errorCode.name());\r
+                } else {\r
+                    setUnknownCode(builder, code);\r
+                }\r
+                break;\r
+            }\r
+            case EXPERIMENTER:\r
+                ExperimenterErrorBuilder expBuilder = new ExperimenterErrorBuilder();\r
+                expBuilder.setExpType(code);\r
+                expBuilder.setExperimenter(rawMessage.readUnsignedInt());\r
+                builder.addAugmentation(ExperimenterError.class, expBuilder.build());\r
+                break;\r
+            default:\r
+                setUnknownCode(builder, code);\r
+                break;\r
+            }\r
+        } else {\r
+            setUnknownCode(builder, code);\r
+        }\r
+    }\r
+    \r
+    private static void setUnknownCode(ErrorMessageBuilder builder, int readValue) {\r
+        builder.setCode(readValue);\r
+        builder.setCodeString(UNKNOWN_CODE);\r
+    }\r
+    \r
+    private static void setCode(ErrorMessageBuilder builder, int code, String codeString) {\r
+        builder.setCode(code);\r
+        builder.setCodeString(codeString);\r
     }\r
 \r
 }\r