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