Merge "Add INFO.yaml for openflowplugin"
[openflowplugin.git] / openflowjava / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / MultipartRequestInputMessageFactory.java
1 /*
2  * Copyright (c) 2015 NetIDE Consortium 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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
11 import io.netty.buffer.ByteBuf;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Objects;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
17 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
18 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
19 import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey;
20 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
21 import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMaker;
22 import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory;
23 import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer;
24 import org.opendaylight.openflowjava.util.ByteBufUtils;
25 import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeaturePropertyBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeaturePropertyBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeaturePropertyBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeatureProperty;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeaturePropertyBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIdsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCaseBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCase;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCaseBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCaseBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDescCase;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDescCaseBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCaseBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.desc._case.MultipartRequestDescBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group.desc._case.MultipartRequestGroupDescBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group.features._case.MultipartRequestGroupFeaturesBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.features._case.MultipartRequestMeterFeaturesBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.desc._case.MultipartRequestPortDescBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table._case.MultipartRequestTableBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder;
97 import org.opendaylight.yangtools.yang.common.Empty;
98
99 /**
100  * Translates MultipartRequestInput messages.
101  *
102  * @author giuseppex.petralia@intel.com
103  */
104 @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") // FB doesn't recognize Objects.requireNonNull
105 public class MultipartRequestInputMessageFactory
106         implements OFDeserializer<MultipartRequestInput>, DeserializerRegistryInjector {
107     private static final byte PADDING = 4;
108     private static final byte FLOW_PADDING_1 = 3;
109     private static final byte FLOW_PADDING_2 = 4;
110     private static final byte AGGREGATE_PADDING_1 = 3;
111     private static final byte AGGREGATE_PADDING_2 = 4;
112     private static final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES = 5;
113     private static final byte MAX_TABLE_NAME_LENGTH = 32;
114     private static final byte MULTIPART_REQUEST_TABLE_FEATURES_STRUCTURE_LENGTH = 64;
115     private static final byte COMMON_PROPERTY_LENGTH = 4;
116
117     private DeserializerRegistry registry;
118
119     @Override
120     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
121         registry = deserializerRegistry;
122     }
123
124     @Override
125     public MultipartRequestInput deserialize(ByteBuf rawMessage) {
126         Objects.requireNonNull(registry);
127
128         MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();
129         builder.setVersion((short) EncodeConstants.OF13_VERSION_ID);
130         builder.setXid(rawMessage.readUnsignedInt());
131         int type = rawMessage.readUnsignedShort();
132         builder.setType(getMultipartType(type));
133         builder.setFlags(getMultipartRequestFlags(rawMessage.readUnsignedShort()));
134         rawMessage.skipBytes(PADDING);
135         switch (MultipartType.forValue(type)) {
136             case OFPMPDESC:
137                 builder.setMultipartRequestBody(setDesc(rawMessage));
138                 break;
139             case OFPMPFLOW:
140                 builder.setMultipartRequestBody(setFlow(rawMessage));
141                 break;
142             case OFPMPAGGREGATE:
143                 builder.setMultipartRequestBody(setAggregate(rawMessage));
144                 break;
145             case OFPMPTABLE:
146                 builder.setMultipartRequestBody(setTable(rawMessage));
147                 break;
148             case OFPMPTABLEFEATURES:
149                 builder.setMultipartRequestBody(setTableFeatures(rawMessage));
150                 break;
151             case OFPMPPORTSTATS:
152                 builder.setMultipartRequestBody(setPortStats(rawMessage));
153                 break;
154             case OFPMPPORTDESC:
155                 builder.setMultipartRequestBody(setPortDesc(rawMessage));
156                 break;
157             case OFPMPQUEUE:
158                 builder.setMultipartRequestBody(setQueue(rawMessage));
159                 break;
160             case OFPMPGROUP:
161                 builder.setMultipartRequestBody(setGroup(rawMessage));
162                 break;
163             case OFPMPGROUPDESC:
164                 builder.setMultipartRequestBody(setGroupDesc(rawMessage));
165                 break;
166             case OFPMPGROUPFEATURES:
167                 builder.setMultipartRequestBody(setGroupFeatures(rawMessage));
168                 break;
169             case OFPMPMETER:
170                 builder.setMultipartRequestBody(setMeter(rawMessage));
171                 break;
172             case OFPMPMETERCONFIG:
173                 builder.setMultipartRequestBody(setMeterConfig(rawMessage));
174                 break;
175             case OFPMPMETERFEATURES:
176                 builder.setMultipartRequestBody(setMeterFeatures(rawMessage));
177                 break;
178             case OFPMPEXPERIMENTER:
179                 builder.setMultipartRequestBody(setExperimenter(rawMessage));
180                 break;
181             default:
182                 break;
183         }
184
185         return builder.build();
186     }
187
188     private static MultipartType getMultipartType(int input) {
189         return MultipartType.forValue(input);
190     }
191
192     @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
193     private static MultipartRequestFlags getMultipartRequestFlags(int input) {
194         final Boolean _oFPMPFREQMORE = (input & 1 << 0) != 0;
195         MultipartRequestFlags flag = new MultipartRequestFlags(_oFPMPFREQMORE);
196         return flag;
197     }
198
199     private MultipartRequestTableFeaturesCase setTableFeatures(ByteBuf input) {
200         MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
201         MultipartRequestTableFeaturesBuilder tableFeaturesBuilder = new MultipartRequestTableFeaturesBuilder();
202         List<TableFeatures> features = new ArrayList<>();
203         while (input.readableBytes() > 0) {
204             TableFeaturesBuilder featuresBuilder = new TableFeaturesBuilder();
205             final int length = input.readUnsignedShort();
206             featuresBuilder.setTableId(input.readUnsignedByte());
207             input.skipBytes(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES);
208             featuresBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, MAX_TABLE_NAME_LENGTH));
209             byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
210             input.readBytes(metadataMatch);
211             featuresBuilder.setMetadataMatch(new BigInteger(1, metadataMatch));
212             byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
213             input.readBytes(metadataWrite);
214             featuresBuilder.setMetadataWrite(new BigInteger(1, metadataWrite));
215             featuresBuilder.setConfig(createTableConfig(input.readUnsignedInt()));
216             featuresBuilder.setMaxEntries(input.readUnsignedInt());
217             featuresBuilder.setTableFeatureProperties(
218                     createTableFeaturesProperties(input, length - MULTIPART_REQUEST_TABLE_FEATURES_STRUCTURE_LENGTH));
219             features.add(featuresBuilder.build());
220         }
221         tableFeaturesBuilder.setTableFeatures(features);
222         caseBuilder.setMultipartRequestTableFeatures(tableFeaturesBuilder.build());
223         return caseBuilder.build();
224     }
225
226     private List<TableFeatureProperties> createTableFeaturesProperties(ByteBuf input, int length) {
227         List<TableFeatureProperties> properties = new ArrayList<>();
228         int tableFeaturesLength = length;
229         while (tableFeaturesLength > 0) {
230             int propStartIndex = input.readerIndex();
231             TableFeaturePropertiesBuilder builder = new TableFeaturePropertiesBuilder();
232             TableFeaturesPropType type = TableFeaturesPropType.forValue(input.readUnsignedShort());
233             builder.setType(type);
234             int propertyLength = input.readUnsignedShort();
235             int paddingRemainder = propertyLength % EncodeConstants.PADDING;
236             tableFeaturesLength -= propertyLength;
237             if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS)
238                     || type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) {
239                 InstructionRelatedTableFeaturePropertyBuilder insBuilder =
240                         new InstructionRelatedTableFeaturePropertyBuilder();
241                 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
242                 List<Instruction> instructions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
243                         propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
244                 insBuilder.setInstruction(instructions);
245                 builder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insBuilder.build());
246             } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES)
247                     || type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) {
248                 propertyLength -= COMMON_PROPERTY_LENGTH;
249                 NextTableRelatedTableFeaturePropertyBuilder tableBuilder =
250                         new NextTableRelatedTableFeaturePropertyBuilder();
251                 List<NextTableIds> ids = new ArrayList<>();
252                 while (propertyLength > 0) {
253                     NextTableIdsBuilder nextTableIdsBuilder = new NextTableIdsBuilder();
254                     nextTableIdsBuilder.setTableId(input.readUnsignedByte());
255                     ids.add(nextTableIdsBuilder.build());
256                     propertyLength--;
257                 }
258                 tableBuilder.setNextTableIds(ids);
259                 builder.addAugmentation(NextTableRelatedTableFeatureProperty.class, tableBuilder.build());
260             } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS)
261                     || type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS)
262                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS)
263                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) {
264                 ActionRelatedTableFeaturePropertyBuilder actionBuilder = new ActionRelatedTableFeaturePropertyBuilder();
265                 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
266                 List<Action> actions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
267                         propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
268                 actionBuilder.setAction(actions);
269                 builder.addAugmentation(ActionRelatedTableFeatureProperty.class, actionBuilder.build());
270             } else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH)
271                     || type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS)
272                     || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD)
273                     || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS)
274                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD)
275                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) {
276                 OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
277                 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID);
278                 List<MatchEntry> entries = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
279                         propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
280                 oxmBuilder.setMatchEntry(entries);
281                 builder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
282             } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER)
283                     || type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) {
284                 long expId = input.readUnsignedInt();
285                 input.readerIndex(propStartIndex);
286                 OFDeserializer<TableFeatureProperties> propDeserializer = registry
287                         .getDeserializer(ExperimenterDeserializerKeyFactory
288                                 .createMultipartReplyTFDeserializerKey(EncodeConstants.OF13_VERSION_ID, expId));
289                 TableFeatureProperties expProp = propDeserializer.deserialize(input);
290                 properties.add(expProp);
291                 continue;
292             }
293             if (paddingRemainder != 0) {
294                 input.skipBytes(EncodeConstants.PADDING - paddingRemainder);
295                 tableFeaturesLength -= EncodeConstants.PADDING - paddingRemainder;
296             }
297             properties.add(builder.build());
298         }
299         return properties;
300     }
301
302     private static TableConfig createTableConfig(long input) {
303         boolean deprecated = (input & 3) != 0;
304         return new TableConfig(deprecated);
305     }
306
307     private static MultipartRequestDescCase setDesc(ByteBuf input) {
308         MultipartRequestDescCaseBuilder caseBuilder = new MultipartRequestDescCaseBuilder();
309         MultipartRequestDescBuilder descBuilder = new MultipartRequestDescBuilder();
310         descBuilder.setEmpty(Empty.getInstance());
311         caseBuilder.setMultipartRequestDesc(descBuilder.build());
312         return caseBuilder.build();
313     }
314
315     private MultipartRequestFlowCase setFlow(ByteBuf input) {
316         final MultipartRequestFlowCaseBuilder caseBuilder = new MultipartRequestFlowCaseBuilder();
317         MultipartRequestFlowBuilder flowBuilder = new MultipartRequestFlowBuilder();
318         flowBuilder.setTableId(input.readUnsignedByte());
319         input.skipBytes(FLOW_PADDING_1);
320         flowBuilder.setOutPort(input.readUnsignedInt());
321         flowBuilder.setOutGroup(input.readUnsignedInt());
322         input.skipBytes(FLOW_PADDING_2);
323         byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
324         input.readBytes(cookie);
325         flowBuilder.setCookie(new BigInteger(1, cookie));
326         final byte[] cookieMask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
327         input.readBytes(cookieMask);
328         flowBuilder.setCookieMask(new BigInteger(1, cookieMask));
329         OFDeserializer<Match> matchDeserializer = registry.getDeserializer(
330                 new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class));
331         flowBuilder.setMatch(matchDeserializer.deserialize(input));
332         caseBuilder.setMultipartRequestFlow(flowBuilder.build());
333         return caseBuilder.build();
334     }
335
336     private MultipartRequestAggregateCase setAggregate(ByteBuf input) {
337         final MultipartRequestAggregateCaseBuilder caseBuilder = new MultipartRequestAggregateCaseBuilder();
338         MultipartRequestAggregateBuilder aggregateBuilder = new MultipartRequestAggregateBuilder();
339         aggregateBuilder.setTableId(input.readUnsignedByte());
340         input.skipBytes(AGGREGATE_PADDING_1);
341         aggregateBuilder.setOutPort(input.readUnsignedInt());
342         aggregateBuilder.setOutGroup(input.readUnsignedInt());
343         input.skipBytes(AGGREGATE_PADDING_2);
344         byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
345         input.readBytes(cookie);
346         aggregateBuilder.setCookie(new BigInteger(1, cookie));
347         final byte[] cookieMask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
348         input.readBytes(cookieMask);
349         aggregateBuilder.setCookieMask(new BigInteger(1, cookieMask));
350         OFDeserializer<Match> matchDeserializer = registry.getDeserializer(
351                 new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class));
352         aggregateBuilder.setMatch(matchDeserializer.deserialize(input));
353         caseBuilder.setMultipartRequestAggregate(aggregateBuilder.build());
354         return caseBuilder.build();
355     }
356
357     private static MultipartRequestPortDescCase setPortDesc(ByteBuf input) {
358         MultipartRequestPortDescCaseBuilder caseBuilder = new MultipartRequestPortDescCaseBuilder();
359         MultipartRequestPortDescBuilder portBuilder = new MultipartRequestPortDescBuilder();
360         portBuilder.setEmpty(Empty.getInstance());
361         caseBuilder.setMultipartRequestPortDesc(portBuilder.build());
362         return caseBuilder.build();
363     }
364
365     private static MultipartRequestPortStatsCase setPortStats(ByteBuf input) {
366         MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder();
367         MultipartRequestPortStatsBuilder portBuilder = new MultipartRequestPortStatsBuilder();
368         portBuilder.setPortNo(input.readUnsignedInt());
369         caseBuilder.setMultipartRequestPortStats(portBuilder.build());
370         return caseBuilder.build();
371     }
372
373     private static MultipartRequestQueueCase setQueue(ByteBuf input) {
374         MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
375         MultipartRequestQueueBuilder queueBuilder = new MultipartRequestQueueBuilder();
376         queueBuilder.setPortNo(input.readUnsignedInt());
377         queueBuilder.setQueueId(input.readUnsignedInt());
378         caseBuilder.setMultipartRequestQueue(queueBuilder.build());
379         return caseBuilder.build();
380     }
381
382     private static MultipartRequestGroupCase setGroup(ByteBuf input) {
383         MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder();
384         MultipartRequestGroupBuilder groupBuilder = new MultipartRequestGroupBuilder();
385         groupBuilder.setGroupId(new GroupId(input.readUnsignedInt()));
386         caseBuilder.setMultipartRequestGroup(groupBuilder.build());
387         return caseBuilder.build();
388     }
389
390     private static MultipartRequestGroupDescCase setGroupDesc(ByteBuf input) {
391         MultipartRequestGroupDescCaseBuilder caseBuilder = new MultipartRequestGroupDescCaseBuilder();
392         MultipartRequestGroupDescBuilder groupBuilder = new MultipartRequestGroupDescBuilder();
393         groupBuilder.setEmpty(Empty.getInstance());
394         caseBuilder.setMultipartRequestGroupDesc(groupBuilder.build());
395         return caseBuilder.build();
396     }
397
398     private static MultipartRequestGroupFeaturesCase setGroupFeatures(ByteBuf input) {
399         MultipartRequestGroupFeaturesCaseBuilder caseBuilder = new MultipartRequestGroupFeaturesCaseBuilder();
400         MultipartRequestGroupFeaturesBuilder groupBuilder = new MultipartRequestGroupFeaturesBuilder();
401         groupBuilder.setEmpty(Empty.getInstance());
402         caseBuilder.setMultipartRequestGroupFeatures(groupBuilder.build());
403         return caseBuilder.build();
404     }
405
406     private static MultipartRequestMeterCase setMeter(ByteBuf input) {
407         MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder();
408         MultipartRequestMeterBuilder meterBuilder = new MultipartRequestMeterBuilder();
409         meterBuilder.setMeterId(new MeterId(input.readUnsignedInt()));
410         caseBuilder.setMultipartRequestMeter(meterBuilder.build());
411         return caseBuilder.build();
412     }
413
414     private static MultipartRequestMeterConfigCase setMeterConfig(ByteBuf input) {
415         MultipartRequestMeterConfigCaseBuilder caseBuilder = new MultipartRequestMeterConfigCaseBuilder();
416         MultipartRequestMeterConfigBuilder meterBuilder = new MultipartRequestMeterConfigBuilder();
417         meterBuilder.setMeterId(new MeterId(input.readUnsignedInt()));
418         caseBuilder.setMultipartRequestMeterConfig(meterBuilder.build());
419         return caseBuilder.build();
420     }
421
422     private static MultipartRequestMeterFeaturesCase setMeterFeatures(ByteBuf input) {
423         MultipartRequestMeterFeaturesCaseBuilder caseBuilder = new MultipartRequestMeterFeaturesCaseBuilder();
424         MultipartRequestMeterFeaturesBuilder meterBuilder = new MultipartRequestMeterFeaturesBuilder();
425         meterBuilder.setEmpty(Empty.getInstance());
426         caseBuilder.setMultipartRequestMeterFeatures(meterBuilder.build());
427         return caseBuilder.build();
428     }
429
430     private static MultipartRequestTableCase setTable(ByteBuf input) {
431         MultipartRequestTableCaseBuilder caseBuilder = new MultipartRequestTableCaseBuilder();
432         MultipartRequestTableBuilder tableBuilder = new MultipartRequestTableBuilder();
433         tableBuilder.setEmpty(Empty.getInstance());
434         caseBuilder.setMultipartRequestTable(tableBuilder.build());
435         return caseBuilder.build();
436     }
437
438     private static MultipartRequestExperimenterCase setExperimenter(ByteBuf input) {
439         MultipartRequestExperimenterCaseBuilder caseBuilder = new MultipartRequestExperimenterCaseBuilder();
440         MultipartRequestExperimenterBuilder experimenterBuilder = new MultipartRequestExperimenterBuilder();
441         caseBuilder.setMultipartRequestExperimenter(experimenterBuilder.build());
442         return caseBuilder.build();
443     }
444 }