aa9a6f9e3b7faedc4fd5bc14a5e48fe67248c625
[openflowplugin.git] / openflowjava / 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 package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
9
10 import static org.opendaylight.yangtools.yang.common.netty.ByteBufUtils.readUint32;
11
12 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
13 import io.netty.buffer.ByteBuf;
14 import java.util.Objects;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
17 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
18 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
19 import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadActionCode;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadInstructionCode;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadMatchCode;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadRequestCode;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ErrorType;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFailedCode;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupModFailedCode;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloFailedCode;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterModFailedCode;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortModFailedCode;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueOpFailedCode;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.RoleRequestFailedCode;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFailedCode;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesFailedCode;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableModFailedCode;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
37 import org.opendaylight.yangtools.yang.common.Uint16;
38
39 /**
40  * Translates Error messages.
41  *
42  * @author michal.polkorab
43  * @author timotej.kubas
44  */
45 public class ErrorMessageFactory implements OFDeserializer<ErrorMessage>,
46         DeserializerRegistryInjector {
47
48     private static final String UNKNOWN_CODE = "UNKNOWN_CODE";
49     private static final String UNKNOWN_TYPE = "UNKNOWN_TYPE";
50     private DeserializerRegistry registry;
51
52     @Override
53     @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") // FB doesn't recognize Objects.requireNonNull
54     public ErrorMessage deserialize(ByteBuf rawMessage) {
55         Objects.requireNonNull(registry);
56
57         int startIndex = rawMessage.readerIndex();
58         ErrorMessageBuilder builder = new ErrorMessageBuilder()
59                 .setVersion(EncodeConstants.OF_VERSION_1_3)
60                 .setXid(readUint32(rawMessage));
61         int type = rawMessage.readUnsignedShort();
62         ErrorType errorType = ErrorType.forValue(type);
63         if (ErrorType.EXPERIMENTER.equals(errorType)) {
64             OFDeserializer<ErrorMessage> deserializer = registry.getDeserializer(
65                     ExperimenterDeserializerKeyFactory.createExperimenterErrorDeserializerKey(
66                             EncodeConstants.OF13_VERSION_ID, rawMessage.getUnsignedInt(
67                                     rawMessage.readerIndex() + Short.BYTES)));
68             rawMessage.readerIndex(startIndex);
69             return deserializer.deserialize(rawMessage);
70         }
71         decodeType(builder, errorType, type);
72         decodeCode(rawMessage, builder, errorType);
73         int remainingBytes = rawMessage.readableBytes();
74         if (remainingBytes > 0) {
75             byte[] data = new byte[remainingBytes];
76             rawMessage.readBytes(data);
77             builder.setData(data);
78         }
79         return builder.build();
80     }
81
82     private static void decodeType(ErrorMessageBuilder builder, ErrorType type, int readValue) {
83         if (type != null) {
84             builder.setType(Uint16.valueOf(type.getIntValue()));
85             builder.setTypeString(type.name());
86         } else {
87             builder.setType(Uint16.valueOf(readValue));
88             builder.setTypeString(UNKNOWN_TYPE);
89         }
90     }
91
92     private static void decodeCode(ByteBuf rawMessage, ErrorMessageBuilder builder,
93             ErrorType type) {
94         int code = rawMessage.readUnsignedShort();
95         if (type != null) {
96             switch (type) {
97                 case HELLOFAILED: {
98                     HelloFailedCode errorCode = HelloFailedCode.forValue(code);
99                     if (errorCode != null) {
100                         setCode(builder, errorCode.getIntValue(), errorCode.name());
101                     } else {
102                         setUnknownCode(builder, code);
103                     }
104                     break;
105                 }
106                 case BADREQUEST: {
107                     BadRequestCode errorCode = BadRequestCode.forValue(code);
108                     if (errorCode != null) {
109                         setCode(builder, errorCode.getIntValue(), errorCode.name());
110                     } else {
111                         setUnknownCode(builder, code);
112                     }
113                     break;
114                 }
115                 case BADACTION: {
116                     BadActionCode errorCode = BadActionCode.forValue(code);
117                     if (errorCode != null) {
118                         setCode(builder, errorCode.getIntValue(), errorCode.name());
119                     } else {
120                         setUnknownCode(builder, code);
121                     }
122                     break;
123                 }
124                 case BADINSTRUCTION: {
125                     BadInstructionCode errorCode = BadInstructionCode.forValue(code);
126                     if (errorCode != null) {
127                         setCode(builder, errorCode.getIntValue(), errorCode.name());
128                     } else {
129                         setUnknownCode(builder, code);
130                     }
131                     break;
132                 }
133                 case BADMATCH: {
134                     BadMatchCode errorCode = BadMatchCode.forValue(code);
135                     if (errorCode != null) {
136                         setCode(builder, errorCode.getIntValue(), errorCode.name());
137                     } else {
138                         setUnknownCode(builder, code);
139                     }
140                     break;
141                 }
142                 case FLOWMODFAILED: {
143                     FlowModFailedCode errorCode = FlowModFailedCode.forValue(code);
144                     if (errorCode != null) {
145                         setCode(builder, errorCode.getIntValue(), errorCode.name());
146                     } else {
147                         setUnknownCode(builder, code);
148                     }
149                     break;
150                 }
151                 case GROUPMODFAILED: {
152                     GroupModFailedCode errorCode = GroupModFailedCode.forValue(code);
153                     if (errorCode != null) {
154                         setCode(builder, errorCode.getIntValue(), errorCode.name());
155                     } else {
156                         setUnknownCode(builder, code);
157                     }
158                     break;
159                 }
160                 case PORTMODFAILED: {
161                     PortModFailedCode errorCode = PortModFailedCode.forValue(code);
162                     if (errorCode != null) {
163                         setCode(builder, errorCode.getIntValue(), errorCode.name());
164                     } else {
165                         setUnknownCode(builder, code);
166                     }
167                     break;
168                 }
169                 case TABLEMODFAILED: {
170                     TableModFailedCode errorCode = TableModFailedCode.forValue(code);
171                     if (errorCode != null) {
172                         setCode(builder, errorCode.getIntValue(), errorCode.name());
173                     } else {
174                         setUnknownCode(builder, code);
175                     }
176                     break;
177                 }
178                 case QUEUEOPFAILED: {
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                     SwitchConfigFailedCode errorCode = SwitchConfigFailedCode.forValue(code);
189                     if (errorCode != null) {
190                         setCode(builder, errorCode.getIntValue(), errorCode.name());
191                     } else {
192                         setUnknownCode(builder, code);
193                     }
194                     break;
195                 }
196                 case ROLEREQUESTFAILED: {
197                     RoleRequestFailedCode errorCode = RoleRequestFailedCode.forValue(code);
198                     if (errorCode != null) {
199                         setCode(builder, errorCode.getIntValue(), errorCode.name());
200                     } else {
201                         setUnknownCode(builder, code);
202                     }
203                     break;
204                 }
205                 case METERMODFAILED: {
206                     MeterModFailedCode errorCode = MeterModFailedCode.forValue(code);
207                     if (errorCode != null) {
208                         setCode(builder, errorCode.getIntValue(), errorCode.name());
209                     } else {
210                         setUnknownCode(builder, code);
211                     }
212                     break;
213                 }
214                 case TABLEFEATURESFAILED: {
215                     TableFeaturesFailedCode errorCode = TableFeaturesFailedCode.forValue(code);
216                     if (errorCode != null) {
217                         setCode(builder, errorCode.getIntValue(), errorCode.name());
218                     } else {
219                         setUnknownCode(builder, code);
220                     }
221                     break;
222                 }
223                 default:
224                     setUnknownCode(builder, code);
225                     break;
226             }
227         } else {
228             setUnknownCode(builder, code);
229         }
230     }
231
232     private static void setUnknownCode(ErrorMessageBuilder builder, int readValue) {
233         builder.setCode(Uint16.valueOf(readValue));
234         builder.setCodeString(UNKNOWN_CODE);
235     }
236
237     private static void setCode(ErrorMessageBuilder builder, int code, String codeString) {
238         builder.setCode(Uint16.valueOf(code));
239         builder.setCodeString(codeString);
240     }
241
242     @Override
243     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
244         this.registry = deserializerRegistry;
245     }
246
247 }