blob: 94fc97cd5b74306517dc38570aaeb0d3844281fc [file] [log] [blame]
Ray Milkeyd43fe452015-05-29 09:35:12 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Ray Milkeyd43fe452015-05-29 09:35:12 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.codec.impl;
17
Jian Lidab72562016-04-12 14:10:32 -070018import com.fasterxml.jackson.databind.JsonNode;
Jian Li1ef82db2016-03-03 14:43:21 -080019import com.fasterxml.jackson.databind.node.ObjectNode;
Jian Lidab72562016-04-12 14:10:32 -070020import org.onlab.osgi.DefaultServiceDirectory;
21import org.onlab.osgi.ServiceDirectory;
Konstantinos Kanonakis9215ff22016-11-04 13:28:11 -050022import org.onlab.packet.EthType;
Ray Milkeyd43fe452015-05-29 09:35:12 -070023import org.onlab.packet.IpAddress;
24import org.onlab.packet.MacAddress;
25import org.onlab.packet.MplsLabel;
Hyunsun Moonfab29502015-08-25 13:39:16 -070026import org.onlab.packet.TpPort;
Ray Milkeyd43fe452015-05-29 09:35:12 -070027import org.onlab.packet.VlanId;
Yafit Hadar5796d972015-10-15 13:16:11 +030028import org.onlab.util.HexString;
Jonathan Harte3bcfc32016-08-16 17:12:49 -070029import org.onosproject.codec.CodecContext;
Jian Lidab72562016-04-12 14:10:32 -070030import org.onosproject.codec.ExtensionTreatmentCodec;
Jian Lice8c5602016-03-03 21:43:24 -080031import org.onosproject.core.GroupId;
Ray Milkeyd43fe452015-05-29 09:35:12 -070032import org.onosproject.net.ChannelSpacing;
Jian Lidab72562016-04-12 14:10:32 -070033import org.onosproject.net.Device;
34import org.onosproject.net.DeviceId;
Ray Milkeyd43fe452015-05-29 09:35:12 -070035import org.onosproject.net.GridType;
Ray Milkeyd43fe452015-05-29 09:35:12 -070036import org.onosproject.net.OchSignal;
Yafit Hadar5796d972015-10-15 13:16:11 +030037import org.onosproject.net.OduSignalId;
Ray Milkeyd43fe452015-05-29 09:35:12 -070038import org.onosproject.net.PortNumber;
Jian Lidab72562016-04-12 14:10:32 -070039import org.onosproject.net.device.DeviceService;
40import org.onosproject.net.flow.instructions.ExtensionTreatment;
Ray Milkeyd43fe452015-05-29 09:35:12 -070041import org.onosproject.net.flow.instructions.Instruction;
42import org.onosproject.net.flow.instructions.Instructions;
43import org.onosproject.net.flow.instructions.L0ModificationInstruction;
Yafit Hadar5796d972015-10-15 13:16:11 +030044import org.onosproject.net.flow.instructions.L1ModificationInstruction;
Ray Milkeyd43fe452015-05-29 09:35:12 -070045import org.onosproject.net.flow.instructions.L2ModificationInstruction;
46import org.onosproject.net.flow.instructions.L3ModificationInstruction;
Hyunsun Moonfab29502015-08-25 13:39:16 -070047import org.onosproject.net.flow.instructions.L4ModificationInstruction;
Jian Li47b26232016-03-07 09:59:59 -080048import org.onosproject.net.meter.MeterId;
Jian Lidab72562016-04-12 14:10:32 -070049import org.slf4j.Logger;
Ray Milkeyd43fe452015-05-29 09:35:12 -070050
Konstantinos Kanonakis9215ff22016-11-04 13:28:11 -050051import java.util.regex.Matcher;
52import java.util.regex.Pattern;
53
Jian Li1ef82db2016-03-03 14:43:21 -080054import static org.onlab.util.Tools.nullIsIllegal;
Jian Lidab72562016-04-12 14:10:32 -070055import static org.slf4j.LoggerFactory.getLogger;
Ray Milkeyd43fe452015-05-29 09:35:12 -070056
57/**
58 * Decoding portion of the instruction codec.
59 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070060public final class DecodeInstructionCodecHelper {
Jian Lidab72562016-04-12 14:10:32 -070061 protected static final Logger log = getLogger(DecodeInstructionCodecHelper.class);
Ray Milkeyd43fe452015-05-29 09:35:12 -070062 private final ObjectNode json;
Jonathan Harte3bcfc32016-08-16 17:12:49 -070063 private final CodecContext context;
Konstantinos Kanonakis9215ff22016-11-04 13:28:11 -050064 private static final Pattern ETHTYPE_PATTERN = Pattern.compile("0x([0-9a-fA-F]{4})");
Ray Milkeyd43fe452015-05-29 09:35:12 -070065
66 /**
67 * Creates a decode instruction codec object.
68 *
69 * @param json JSON object to decode
Ray Milkeyef794342016-11-09 16:20:29 -080070 * @param context codec context
Ray Milkeyd43fe452015-05-29 09:35:12 -070071 */
Jonathan Harte3bcfc32016-08-16 17:12:49 -070072 public DecodeInstructionCodecHelper(ObjectNode json, CodecContext context) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070073 this.json = json;
Jonathan Harte3bcfc32016-08-16 17:12:49 -070074 this.context = context;
Ray Milkeyd43fe452015-05-29 09:35:12 -070075 }
76
77 /**
78 * Decodes a Layer 2 instruction.
79 *
80 * @return instruction object decoded from the JSON
81 * @throws IllegalArgumentException if the JSON is invalid
82 */
83 private Instruction decodeL2() {
Jayasree Ghosh8aca6772016-10-04 03:32:11 +053084 String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
85 InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();
Ray Milkeyd43fe452015-05-29 09:35:12 -070086
87 if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC.name())) {
88 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
89 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
90 return Instructions.modL2Src(MacAddress.valueOf(mac));
91 } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST.name())) {
92 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
93 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
94 return Instructions.modL2Dst(MacAddress.valueOf(mac));
95 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_ID.name())) {
96 short vlanId = (short) nullIsIllegal(json.get(InstructionCodec.VLAN_ID),
97 InstructionCodec.VLAN_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
98 return Instructions.modVlanId(VlanId.vlanId(vlanId));
99 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PCP.name())) {
100 byte vlanPcp = (byte) nullIsIllegal(json.get(InstructionCodec.VLAN_PCP),
101 InstructionCodec.VLAN_PCP + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
102 return Instructions.modVlanPcp(vlanPcp);
103 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_LABEL.name())) {
104 int label = nullIsIllegal(json.get(InstructionCodec.MPLS_LABEL),
105 InstructionCodec.MPLS_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
106 return Instructions.modMplsLabel(MplsLabel.mplsLabel(label));
107 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_PUSH.name())) {
108 return Instructions.pushMpls();
109 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_POP.name())) {
Sivachidambaram Subramaniandab7f4b2017-05-15 12:28:12 +0530110 if (json.has(InstructionCodec.ETHERNET_TYPE)) {
111 return Instructions.popMpls(getEthType());
112 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700113 return Instructions.popMpls();
114 } else if (subType.equals(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name())) {
115 return Instructions.decMplsTtl();
116 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_POP.name())) {
117 return Instructions.popVlan();
118 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PUSH.name())) {
Konstantinos Kanonakis9215ff22016-11-04 13:28:11 -0500119 if (json.has(InstructionCodec.ETHERNET_TYPE)) {
120 return Instructions.pushVlan(getEthType());
121 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700122 return Instructions.pushVlan();
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700123 } else if (subType.equals(L2ModificationInstruction.L2SubType.TUNNEL_ID.name())) {
124 long tunnelId = nullIsIllegal(json.get(InstructionCodec.TUNNEL_ID),
125 InstructionCodec.TUNNEL_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong();
126 return Instructions.modTunnelId(tunnelId);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700127 }
128 throw new IllegalArgumentException("L2 Instruction subtype "
129 + subType + " is not supported");
130 }
131
132 /**
133 * Decodes a Layer 3 instruction.
134 *
135 * @return instruction object decoded from the JSON
136 * @throws IllegalArgumentException if the JSON is invalid
137 */
138 private Instruction decodeL3() {
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530139 String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
140 InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700141
142 if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_SRC.name())) {
143 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
144 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
145 return Instructions.modL3Src(ip);
146 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_DST.name())) {
147 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
148 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
149 return Instructions.modL3Dst(ip);
150 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_SRC.name())) {
151 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
152 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
153 return Instructions.modL3IPv6Src(ip);
154 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_DST.name())) {
155 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
156 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
157 return Instructions.modL3IPv6Dst(ip);
158 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_FLABEL.name())) {
159 int flowLabel = nullIsIllegal(json.get(InstructionCodec.FLOW_LABEL),
160 InstructionCodec.FLOW_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
161 return Instructions.modL3IPv6FlowLabel(flowLabel);
Jonathan Hartcc962d82016-08-09 16:52:22 -0700162 } else if (subType.equals(L3ModificationInstruction.L3SubType.TTL_IN.name())) {
163 return Instructions.copyTtlIn();
164 } else if (subType.equals(L3ModificationInstruction.L3SubType.TTL_OUT.name())) {
165 return Instructions.copyTtlOut();
166 } else if (subType.equals(L3ModificationInstruction.L3SubType.DEC_TTL.name())) {
167 return Instructions.decNwTtl();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700168 }
169 throw new IllegalArgumentException("L3 Instruction subtype "
170 + subType + " is not supported");
171 }
172
173 /**
174 * Decodes a Layer 0 instruction.
175 *
176 * @return instruction object decoded from the JSON
177 * @throws IllegalArgumentException if the JSON is invalid
178 */
179 private Instruction decodeL0() {
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530180 String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
181 InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700182
Sho SHIMIZUcc137a92016-03-11 15:10:54 -0800183 if (subType.equals(L0ModificationInstruction.L0SubType.OCH.name())) {
Ray Milkeyd43fe452015-05-29 09:35:12 -0700184 String gridTypeString = nullIsIllegal(json.get(InstructionCodec.GRID_TYPE),
185 InstructionCodec.GRID_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
186 GridType gridType = GridType.valueOf(gridTypeString);
187 if (gridType == null) {
188 throw new IllegalArgumentException("Unknown grid type "
189 + gridTypeString);
190 }
191 String channelSpacingString = nullIsIllegal(json.get(InstructionCodec.CHANNEL_SPACING),
192 InstructionCodec.CHANNEL_SPACING + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
193 ChannelSpacing channelSpacing = ChannelSpacing.valueOf(channelSpacingString);
194 if (channelSpacing == null) {
195 throw new IllegalArgumentException("Unknown channel spacing "
196 + channelSpacingString);
197 }
198 int spacingMultiplier = nullIsIllegal(json.get(InstructionCodec.SPACING_MULTIPLIER),
199 InstructionCodec.SPACING_MULTIPLIER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
200 int slotGranularity = nullIsIllegal(json.get(InstructionCodec.SLOT_GRANULARITY),
201 InstructionCodec.SLOT_GRANULARITY + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
202 return Instructions.modL0Lambda(new OchSignal(gridType, channelSpacing,
203 spacingMultiplier, slotGranularity));
204 }
205 throw new IllegalArgumentException("L0 Instruction subtype "
206 + subType + " is not supported");
207 }
208
209 /**
Yafit Hadar5796d972015-10-15 13:16:11 +0300210 * Decodes a Layer 1 instruction.
211 *
212 * @return instruction object decoded from the JSON
213 * @throws IllegalArgumentException if the JSON is invalid
214 */
215 private Instruction decodeL1() {
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530216 String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
217 InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();
Yafit Hadar5796d972015-10-15 13:16:11 +0300218 if (subType.equals(L1ModificationInstruction.L1SubType.ODU_SIGID.name())) {
219 int tributaryPortNumber = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_PORT_NUMBER),
220 InstructionCodec.TRIBUTARY_PORT_NUMBER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
221 int tributarySlotLen = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_LEN),
222 InstructionCodec.TRIBUTARY_SLOT_LEN + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
223 byte[] tributarySlotBitmap = null;
224 tributarySlotBitmap = HexString.fromHexString(
225 nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_BITMAP),
226 InstructionCodec.TRIBUTARY_SLOT_BITMAP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
227 return Instructions.modL1OduSignalId(OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen,
228 tributarySlotBitmap));
229 }
230 throw new IllegalArgumentException("L1 Instruction subtype "
231 + subType + " is not supported");
232 }
233
234 /**
Hyunsun Moonfab29502015-08-25 13:39:16 -0700235 * Decodes a Layer 4 instruction.
236 *
237 * @return instruction object decoded from the JSON
238 * @throws IllegalArgumentException if the JSON is invalid
239 */
240 private Instruction decodeL4() {
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530241 String subType = nullIsIllegal(json.get(InstructionCodec.SUBTYPE),
242 InstructionCodec.SUBTYPE + InstructionCodec.ERROR_MESSAGE).asText();
Hyunsun Moonfab29502015-08-25 13:39:16 -0700243
244 if (subType.equals(L4ModificationInstruction.L4SubType.TCP_DST.name())) {
245 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
246 InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
247 return Instructions.modTcpDst(tcpPort);
248 } else if (subType.equals(L4ModificationInstruction.L4SubType.TCP_SRC.name())) {
249 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
250 InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
251 return Instructions.modTcpSrc(tcpPort);
252 } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_DST.name())) {
253 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
254 InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
255 return Instructions.modUdpDst(udpPort);
256 } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_SRC.name())) {
257 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
258 InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
259 return Instructions.modUdpSrc(udpPort);
260 }
261 throw new IllegalArgumentException("L4 Instruction subtype "
262 + subType + " is not supported");
263 }
264
265 /**
Jian Lidab72562016-04-12 14:10:32 -0700266 * Decodes a extension instruction.
267 *
268 * @return extension treatment
269 */
270 private Instruction decodeExtension() {
271 ObjectNode node = (ObjectNode) json.get(InstructionCodec.EXTENSION);
272 if (node != null) {
273 DeviceId deviceId = getDeviceId();
274
275 ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
276 DeviceService deviceService = serviceDirectory.get(DeviceService.class);
277 Device device = deviceService.getDevice(deviceId);
278
Jonathan Harte3bcfc32016-08-16 17:12:49 -0700279 if (device == null) {
280 throw new IllegalArgumentException("Device not found");
281 }
282
Jian Lidab72562016-04-12 14:10:32 -0700283 if (device.is(ExtensionTreatmentCodec.class)) {
284 ExtensionTreatmentCodec treatmentCodec = device.as(ExtensionTreatmentCodec.class);
Jonathan Harte3bcfc32016-08-16 17:12:49 -0700285 ExtensionTreatment treatment = treatmentCodec.decode(node, context);
Jian Lidab72562016-04-12 14:10:32 -0700286 return Instructions.extension(treatment, deviceId);
287 } else {
Jonathan Harte3bcfc32016-08-16 17:12:49 -0700288 throw new IllegalArgumentException(
289 "There is no codec to decode extension for device " + deviceId.toString());
Jian Lidab72562016-04-12 14:10:32 -0700290 }
291 }
292 return null;
293 }
294
295 /**
296 * Returns device identifier.
297 *
298 * @return device identifier
299 * @throws IllegalArgumentException if the JSON is invalid
300 */
301 private DeviceId getDeviceId() {
302 JsonNode deviceIdNode = json.get(InstructionCodec.DEVICE_ID);
303 if (deviceIdNode != null) {
304 return DeviceId.deviceId(deviceIdNode.asText());
305 }
306 throw new IllegalArgumentException("Empty device identifier");
307 }
308
309 /**
Jian Li70dffe42016-03-08 22:23:02 -0800310 * Extracts port number of the given json node.
311 *
312 * @param jsonNode json node
313 * @return port number
314 */
315 private PortNumber getPortNumber(ObjectNode jsonNode) {
316 PortNumber portNumber;
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530317 JsonNode portNode = nullIsIllegal(jsonNode.get(InstructionCodec.PORT),
318 InstructionCodec.PORT + InstructionCodec.ERROR_MESSAGE);
319 if (portNode.isLong() || portNode.isInt()) {
320 portNumber = PortNumber.portNumber(portNode.asLong());
321 } else if (portNode.isTextual()) {
322 portNumber = PortNumber.fromString(portNode.textValue());
Jian Li70dffe42016-03-08 22:23:02 -0800323 } else {
324 throw new IllegalArgumentException("Port value "
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530325 + portNode.toString()
Jian Li70dffe42016-03-08 22:23:02 -0800326 + " is not supported");
327 }
328 return portNumber;
329 }
330
331 /**
Konstantinos Kanonakis9215ff22016-11-04 13:28:11 -0500332 * Returns Ethernet type.
333 *
334 * @return ethernet type
335 * @throws IllegalArgumentException if the JSON is invalid
336 */
337 private EthType getEthType() {
338 String ethTypeStr = nullIsIllegal(json.get(InstructionCodec.ETHERNET_TYPE),
339 InstructionCodec.ETHERNET_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
340 Matcher matcher = ETHTYPE_PATTERN.matcher(ethTypeStr);
341 if (!matcher.matches()) {
342 throw new IllegalArgumentException("ETHERNET_TYPE must be a four digit hex string starting with 0x");
343 }
344 short ethernetType = (short) Integer.parseInt(matcher.group(1), 16);
345 return new EthType(ethernetType);
346 }
347
348 /**
Ray Milkeyd43fe452015-05-29 09:35:12 -0700349 * Decodes the JSON into an instruction object.
350 *
351 * @return Criterion object
352 * @throws IllegalArgumentException if the JSON is invalid
353 */
354 public Instruction decode() {
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530355 String type = nullIsIllegal(json.get(InstructionCodec.TYPE),
356 InstructionCodec.TYPE + InstructionCodec.ERROR_MESSAGE).asText();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700357
358 if (type.equals(Instruction.Type.OUTPUT.name())) {
Jian Li70dffe42016-03-08 22:23:02 -0800359 return Instructions.createOutput(getPortNumber(json));
Ray Milkey2be39ed2016-02-22 15:54:19 -0800360 } else if (type.equals(Instruction.Type.NOACTION.name())) {
361 return Instructions.createNoAction();
Jian Li1ef82db2016-03-03 14:43:21 -0800362 } else if (type.equals(Instruction.Type.TABLE.name())) {
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530363 return Instructions.transition(nullIsIllegal(json.get(InstructionCodec.TABLE_ID),
364 InstructionCodec.TABLE_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
Jian Lice8c5602016-03-03 21:43:24 -0800365 } else if (type.equals(Instruction.Type.GROUP.name())) {
Yi Tsengfa394de2017-02-01 11:26:40 -0800366 GroupId groupId = new GroupId(nullIsIllegal(json.get(InstructionCodec.GROUP_ID),
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530367 InstructionCodec.GROUP_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
Jian Lice8c5602016-03-03 21:43:24 -0800368 return Instructions.createGroup(groupId);
Jian Li47b26232016-03-07 09:59:59 -0800369 } else if (type.equals(Instruction.Type.METER.name())) {
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530370 MeterId meterId = MeterId.meterId(nullIsIllegal(json.get(InstructionCodec.METER_ID),
371 InstructionCodec.METER_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong());
Jian Li47b26232016-03-07 09:59:59 -0800372 return Instructions.meterTraffic(meterId);
Jian Li70dffe42016-03-08 22:23:02 -0800373 } else if (type.equals(Instruction.Type.QUEUE.name())) {
Jayasree Ghosh8aca6772016-10-04 03:32:11 +0530374 long queueId = nullIsIllegal(json.get(InstructionCodec.QUEUE_ID),
375 InstructionCodec.QUEUE_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong();
ke han74702102016-11-29 14:57:29 +0800376 if (json.get(InstructionCodec.PORT) == null ||
377 json.get(InstructionCodec.PORT).isNull()) {
378 return Instructions.setQueue(queueId, null);
379 } else {
380 return Instructions.setQueue(queueId, getPortNumber(json));
381 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700382 } else if (type.equals(Instruction.Type.L0MODIFICATION.name())) {
383 return decodeL0();
Yafit Hadar5796d972015-10-15 13:16:11 +0300384 } else if (type.equals(Instruction.Type.L1MODIFICATION.name())) {
385 return decodeL1();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700386 } else if (type.equals(Instruction.Type.L2MODIFICATION.name())) {
387 return decodeL2();
388 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
389 return decodeL3();
Hyunsun Moonfab29502015-08-25 13:39:16 -0700390 } else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
391 return decodeL4();
Jian Lidab72562016-04-12 14:10:32 -0700392 } else if (type.equals(Instruction.Type.EXTENSION.name())) {
393 return decodeExtension();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700394 }
395 throw new IllegalArgumentException("Instruction type "
396 + type + " is not supported");
397 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700398}