8e341bd0444ce4c70904c94ceedd3e1c6c6a929c
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / ErrorMessageFactory.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
10
11 import io.netty.buffer.ByteBuf;
12
13 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
14 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
16 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
17 import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadActionCode;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadInstructionCode;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadMatchCode;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadRequestCode;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ErrorType;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFailedCode;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupModFailedCode;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloFailedCode;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterModFailedCode;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortModFailedCode;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueOpFailedCode;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.RoleRequestFailedCode;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFailedCode;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesFailedCode;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableModFailedCode;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
35
36 /**
37  * Translates Error messages
38  * @author michal.polkorab
39  * @author timotej.kubas
40  */
41 public class ErrorMessageFactory implements OFDeserializer<ErrorMessage>,
42         DeserializerRegistryInjector {
43
44     private static final String UNKNOWN_CODE = "UNKNOWN_CODE";
45     private static final String UNKNOWN_TYPE = "UNKNOWN_TYPE";
46     private DeserializerRegistry registry;
47
48     @Override
49     public ErrorMessage deserialize(ByteBuf rawMessage) {
50         int startIndex = rawMessage.readerIndex();
51         ErrorMessageBuilder builder = new ErrorMessageBuilder();
52         builder.setVersion((short) EncodeConstants.OF13_VERSION_ID);
53         builder.setXid(rawMessage.readUnsignedInt());
54         int type = rawMessage.readUnsignedShort();
55         ErrorType errorType = ErrorType.forValue(type);
56         if (ErrorType.EXPERIMENTER.equals(errorType)) {
57             OFDeserializer<ErrorMessage> deserializer = registry.getDeserializer(
58                     ExperimenterDeserializerKeyFactory.createExperimenterErrorDeserializerKey(
59                             EncodeConstants.OF13_VERSION_ID, rawMessage.getUnsignedInt(
60                                     rawMessage.readerIndex() + EncodeConstants.SIZE_OF_SHORT_IN_BYTES)));
61             rawMessage.readerIndex(startIndex);
62             return deserializer.deserialize(rawMessage);
63         }
64         decodeType(builder, errorType, type);
65         decodeCode(rawMessage, builder, errorType);
66         if (rawMessage.readableBytes() > 0) {
67             builder.setData(rawMessage.readBytes(rawMessage.readableBytes()).array());
68         }
69         return builder.build();
70     }
71     
72     private static void decodeType(ErrorMessageBuilder builder, ErrorType type, int readValue) {
73         if (type != null) {
74             builder.setType(type.getIntValue());
75             builder.setTypeString(type.name());
76         } else {
77             builder.setType(readValue);
78             builder.setTypeString(UNKNOWN_TYPE);
79         }
80     }
81
82     private static void decodeCode(ByteBuf rawMessage, ErrorMessageBuilder builder,
83             ErrorType type) {
84         int code = rawMessage.readUnsignedShort();
85         if (type != null) {
86             switch (type) {
87             case HELLOFAILED:
88             {
89                 HelloFailedCode errorCode = HelloFailedCode.forValue(code);
90                 if (errorCode != null) {
91                     setCode(builder, errorCode.getIntValue(), errorCode.name());
92                 } else {
93                     setUnknownCode(builder, code);
94                 }
95                 break;
96             }
97             case BADREQUEST:
98             {
99                 BadRequestCode errorCode = BadRequestCode.forValue(code);
100                 if (errorCode != null) {
101                     setCode(builder, errorCode.getIntValue(), errorCode.name());
102                 } else {
103                     setUnknownCode(builder, code);
104                 }
105                 break;
106             }
107             case BADACTION:
108             {
109                 BadActionCode errorCode = BadActionCode.forValue(code);
110                 if (errorCode != null) {
111                     setCode(builder, errorCode.getIntValue(), errorCode.name());
112                 } else {
113                     setUnknownCode(builder, code);
114                 }
115                 break;
116             }
117             case BADINSTRUCTION:
118             {
119                 BadInstructionCode errorCode = BadInstructionCode.forValue(code);
120                 if (errorCode != null) {
121                     setCode(builder, errorCode.getIntValue(), errorCode.name());
122                 } else {
123                     setUnknownCode(builder, code);
124                 }
125                 break;
126             }
127             case BADMATCH:
128             {
129                 BadMatchCode errorCode = BadMatchCode.forValue(code);
130                 if (errorCode != null) {
131                     setCode(builder, errorCode.getIntValue(), errorCode.name());
132                 } else {
133                     setUnknownCode(builder, code);
134                 }
135                 break;
136             }
137             case FLOWMODFAILED:
138             {
139                 FlowModFailedCode errorCode = FlowModFailedCode.forValue(code);
140                 if (errorCode != null) {
141                     setCode(builder, errorCode.getIntValue(), errorCode.name());
142                 } else {
143                     setUnknownCode(builder, code);
144                 }
145                 break;
146             }
147             case GROUPMODFAILED:
148             {
149                 GroupModFailedCode errorCode = GroupModFailedCode.forValue(code);
150                 if (errorCode != null) {
151                     setCode(builder, errorCode.getIntValue(), errorCode.name());
152                 } else {
153                     setUnknownCode(builder, code);
154                 }
155                 break;
156             }
157             case PORTMODFAILED:
158             {
159                 PortModFailedCode errorCode = PortModFailedCode.forValue(code);
160                 if (errorCode != null) {
161                     setCode(builder, errorCode.getIntValue(), errorCode.name());
162                 } else {
163                     setUnknownCode(builder, code);
164                 }
165                 break;
166             }
167             case TABLEMODFAILED:
168             {
169                 TableModFailedCode errorCode = TableModFailedCode.forValue(code);
170                 if (errorCode != null) {
171                     setCode(builder, errorCode.getIntValue(), errorCode.name());
172                 } else {
173                     setUnknownCode(builder, code);
174                 }
175                 break;
176             }
177             case QUEUEOPFAILED:
178             {
179                 QueueOpFailedCode errorCode = QueueOpFailedCode.forValue(code);
180                 if (errorCode != null) {
181                     setCode(builder, errorCode.getIntValue(), errorCode.name());
182                 } else {
183                     setUnknownCode(builder, code);
184                 }
185                 break;
186             }
187             case SWITCHCONFIGFAILED:
188             {
189                 SwitchConfigFailedCode errorCode = SwitchConfigFailedCode.forValue(code);
190                 if (errorCode != null) {
191                     setCode(builder, errorCode.getIntValue(), errorCode.name());
192                 } else {
193                     setUnknownCode(builder, code);
194                 }
195                 break;
196             }
197             case ROLEREQUESTFAILED:
198             {
199                 RoleRequestFailedCode errorCode = RoleRequestFailedCode.forValue(code);
200                 if (errorCode != null) {
201                     setCode(builder, errorCode.getIntValue(), errorCode.name());
202                 } else {
203                     setUnknownCode(builder, code);
204                 }
205                 break;
206             }
207             case METERMODFAILED:
208             {
209                 MeterModFailedCode errorCode = MeterModFailedCode.forValue(code);
210                 if (errorCode != null) {
211                     setCode(builder, errorCode.getIntValue(), errorCode.name());
212                 } else {
213                     setUnknownCode(builder, code);
214                 }
215                 break;
216             }
217             case TABLEFEATURESFAILED:
218             {
219                 TableFeaturesFailedCode errorCode = TableFeaturesFailedCode.forValue(code);
220                 if (errorCode != null) {
221                     setCode(builder, errorCode.getIntValue(), errorCode.name());
222                 } else {
223                     setUnknownCode(builder, code);
224                 }
225                 break;
226             }
227             default:
228                 setUnknownCode(builder, code);
229                 break;
230             }
231         } else {
232             setUnknownCode(builder, code);
233         }
234     }
235     
236     private static void setUnknownCode(ErrorMessageBuilder builder, int readValue) {
237         builder.setCode(readValue);
238         builder.setCodeString(UNKNOWN_CODE);
239     }
240     
241     private static void setCode(ErrorMessageBuilder builder, int code, String codeString) {
242         builder.setCode(code);
243         builder.setCodeString(codeString);
244     }
245
246     @Override
247     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
248         this.registry = deserializerRegistry;
249     }
250
251 }