Merge "make ConfigurationServiceFactoryImpl independent of OSGi"
[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                 {
97                     HelloFailedCode errorCode = HelloFailedCode.forValue(code);
98                     if (errorCode != null) {
99                         setCode(builder, errorCode.getIntValue(), errorCode.name());
100                     } else {
101                         setUnknownCode(builder, code);
102                     }
103                     break;
104                 }
105                 case BADREQUEST:
106                 {
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                 {
117                     BadActionCode errorCode = BadActionCode.forValue(code);
118                     if (errorCode != null) {
119                         setCode(builder, errorCode.getIntValue(), errorCode.name());
120                     } else {
121                         setUnknownCode(builder, code);
122                     }
123                     break;
124                 }
125                 case BADINSTRUCTION:
126                 {
127                     BadInstructionCode errorCode = BadInstructionCode.forValue(code);
128                     if (errorCode != null) {
129                         setCode(builder, errorCode.getIntValue(), errorCode.name());
130                     } else {
131                         setUnknownCode(builder, code);
132                     }
133                     break;
134                 }
135                 case BADMATCH:
136                 {
137                     BadMatchCode errorCode = BadMatchCode.forValue(code);
138                     if (errorCode != null) {
139                         setCode(builder, errorCode.getIntValue(), errorCode.name());
140                     } else {
141                         setUnknownCode(builder, code);
142                     }
143                     break;
144                 }
145                 case FLOWMODFAILED:
146                 {
147                     FlowModFailedCode errorCode = FlowModFailedCode.forValue(code);
148                     if (errorCode != null) {
149                         setCode(builder, errorCode.getIntValue(), errorCode.name());
150                     } else {
151                         setUnknownCode(builder, code);
152                     }
153                     break;
154                 }
155                 case GROUPMODFAILED:
156                 {
157                     GroupModFailedCode errorCode = GroupModFailedCode.forValue(code);
158                     if (errorCode != null) {
159                         setCode(builder, errorCode.getIntValue(), errorCode.name());
160                     } else {
161                         setUnknownCode(builder, code);
162                     }
163                     break;
164                 }
165                 case PORTMODFAILED:
166                 {
167                     PortModFailedCode errorCode = PortModFailedCode.forValue(code);
168                     if (errorCode != null) {
169                         setCode(builder, errorCode.getIntValue(), errorCode.name());
170                     } else {
171                         setUnknownCode(builder, code);
172                     }
173                     break;
174                 }
175                 case TABLEMODFAILED:
176                 {
177                     TableModFailedCode errorCode = TableModFailedCode.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 QUEUEOPFAILED:
186                 {
187                     QueueOpFailedCode errorCode = QueueOpFailedCode.forValue(code);
188                     if (errorCode != null) {
189                         setCode(builder, errorCode.getIntValue(), errorCode.name());
190                     } else {
191                         setUnknownCode(builder, code);
192                     }
193                     break;
194                 }
195                 case SWITCHCONFIGFAILED:
196                 {
197                     SwitchConfigFailedCode errorCode = SwitchConfigFailedCode.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 ROLEREQUESTFAILED:
206                 {
207                     RoleRequestFailedCode errorCode = RoleRequestFailedCode.forValue(code);
208                     if (errorCode != null) {
209                         setCode(builder, errorCode.getIntValue(), errorCode.name());
210                     } else {
211                         setUnknownCode(builder, code);
212                     }
213                     break;
214                 }
215                 case METERMODFAILED:
216                 {
217                     MeterModFailedCode errorCode = MeterModFailedCode.forValue(code);
218                     if (errorCode != null) {
219                         setCode(builder, errorCode.getIntValue(), errorCode.name());
220                     } else {
221                         setUnknownCode(builder, code);
222                     }
223                     break;
224                 }
225                 case TABLEFEATURESFAILED:
226                 {
227                     TableFeaturesFailedCode errorCode = TableFeaturesFailedCode.forValue(code);
228                     if (errorCode != null) {
229                         setCode(builder, errorCode.getIntValue(), errorCode.name());
230                     } else {
231                         setUnknownCode(builder, code);
232                     }
233                     break;
234                 }
235                 default:
236                     setUnknownCode(builder, code);
237                     break;
238             }
239         } else {
240             setUnknownCode(builder, code);
241         }
242     }
243
244     private static void setUnknownCode(ErrorMessageBuilder builder, int readValue) {
245         builder.setCode(readValue);
246         builder.setCodeString(UNKNOWN_CODE);
247     }
248
249     private static void setCode(ErrorMessageBuilder builder, int code, String codeString) {
250         builder.setCode(code);
251         builder.setCodeString(codeString);
252     }
253
254     @Override
255     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
256         this.registry = deserializerRegistry;
257     }
258
259 }