Update MRI projects for Aluminium
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / protocol / deserialization / multipart / MultipartReplyFlowStatsDeserializer.java
1 /*
2  * Copyright (c) 2017 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.openflowplugin.impl.protocol.deserialization.multipart;
10
11 import com.google.common.base.Preconditions;
12 import io.netty.buffer.ByteBuf;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
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.openflowplugin.api.OFConstants;
22 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
23 import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeMatchKey;
24 import org.opendaylight.openflowplugin.impl.protocol.deserialization.util.InstructionUtil;
25 import org.opendaylight.openflowplugin.impl.util.MatchUtil;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStatsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
41
42 public class MultipartReplyFlowStatsDeserializer implements OFDeserializer<MultipartReplyBody>,
43         DeserializerRegistryInjector {
44
45     private static final MessageCodeKey MATCH_KEY = new MessageCodeMatchKey(EncodeConstants.OF13_VERSION_ID,
46             EncodeConstants.EMPTY_VALUE, Match.class,
47             MatchPath.FLOWS_STATISTICS_UPDATE_MATCH);
48
49     private static final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1;
50     private static final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4;
51     private DeserializerRegistry registry;
52
53     @Override
54     public MultipartReplyBody deserialize(ByteBuf message) {
55         final MultipartReplyFlowStatsBuilder builder = new MultipartReplyFlowStatsBuilder();
56         final List<FlowAndStatisticsMapList> items = new ArrayList<>();
57         int key = 0;
58
59         while (message.readableBytes() > 0) {
60             final FlowAndStatisticsMapListBuilder itemBuilder = new FlowAndStatisticsMapListBuilder();
61             final int itemLength = message.readUnsignedShort();
62             final ByteBuf itemMessage = message.readSlice(itemLength - EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
63
64             itemBuilder.setTableId(itemMessage.readUnsignedByte());
65             itemMessage.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01);
66
67             itemBuilder
68                     .setDuration(new DurationBuilder()
69                             .setSecond(new Counter32(itemMessage.readUnsignedInt()))
70                             .setNanosecond(new Counter32(itemMessage.readUnsignedInt()))
71                             .build())
72                     .setPriority(itemMessage.readUnsignedShort())
73                     .setIdleTimeout(itemMessage.readUnsignedShort())
74                     .setHardTimeout(itemMessage.readUnsignedShort())
75                     .setFlags(createFlowModFlagsFromBitmap(itemMessage.readUnsignedShort()));
76
77             itemMessage.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);
78
79             final byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
80             itemMessage.readBytes(cookie);
81             final byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
82             itemMessage.readBytes(packetCount);
83             final byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
84             itemMessage.readBytes(byteCount);
85
86             itemBuilder
87                     .setCookie(new FlowCookie(new BigInteger(1, cookie)))
88                     .setCookieMask(new FlowCookie(OFConstants.DEFAULT_COOKIE_MASK))
89                     .setPacketCount(new Counter64(new BigInteger(1, packetCount)))
90                     .setByteCount(new Counter64(new BigInteger(1, byteCount)));
91
92             final OFDeserializer<Match> matchDeserializer =
93                     Preconditions.checkNotNull(registry).getDeserializer(MATCH_KEY);
94             itemBuilder.setMatch(MatchUtil.transformMatch(matchDeserializer.deserialize(itemMessage),
95                     org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match.class));
96
97             final int length = itemMessage.readableBytes();
98
99             if (length > 0) {
100                 final List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list
101                         .Instruction> instructions = new ArrayList<>();
102                 final int startIndex = itemMessage.readerIndex();
103                 int offset = 0;
104
105                 while (itemMessage.readerIndex() - startIndex < length) {
106                     instructions.add(new InstructionBuilder()
107                             .withKey(new InstructionKey(offset))
108                             .setOrder(offset)
109                             .setInstruction(InstructionUtil
110                                     .readInstruction(EncodeConstants.OF13_VERSION_ID, itemMessage, registry))
111                             .build());
112
113                     offset++;
114                 }
115
116                 itemBuilder.setInstructions(new InstructionsBuilder()
117                         .setInstruction(instructions)
118                         .build());
119             }
120
121             itemBuilder.withKey(new FlowAndStatisticsMapListKey(new FlowId(String.valueOf(key++))));
122             items.add(itemBuilder.build());
123         }
124
125         return builder
126                 .setFlowAndStatisticsMapList(items)
127                 .build();
128     }
129
130     private static FlowModFlags createFlowModFlagsFromBitmap(int input) {
131         final Boolean ofp_FF_SendFlowRem = (input & 1) != 0;
132         final Boolean ofp_FF_CheckOverlap = (input & 1 << 1) != 0;
133         final Boolean ofp_FF_ResetCounts = (input & 1 << 2) != 0;
134         final Boolean ofp_FF_NoPktCounts = (input & 1 << 3) != 0;
135         final Boolean ofp_FF_NoBytCounts = (input & 1 << 4) != 0;
136         return new FlowModFlags(ofp_FF_CheckOverlap, ofp_FF_NoBytCounts, ofp_FF_NoPktCounts, ofp_FF_ResetCounts,
137                 ofp_FF_SendFlowRem);
138     }
139
140     @Override
141     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
142         registry = deserializerRegistry;
143     }
144
145 }