2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onosproject.codec.impl;
18 import static org.onlab.util.Tools.nullIsIllegal;
20 import java.util.HashMap;
23 import org.onlab.packet.Ip6Address;
24 import org.onlab.packet.IpPrefix;
25 import org.onlab.packet.MacAddress;
26 import org.onlab.packet.MplsLabel;
27 import org.onlab.packet.TpPort;
28 import org.onlab.packet.VlanId;
29 import org.onlab.util.HexString;
30 import org.onosproject.net.ChannelSpacing;
31 import org.onosproject.net.GridType;
32 import org.onosproject.net.Lambda;
33 import org.onosproject.net.OchSignalType;
34 import org.onosproject.net.OduSignalId;
35 import org.onosproject.net.OduSignalType;
36 import org.onosproject.net.PortNumber;
37 import org.onosproject.net.flow.criteria.Criteria;
38 import org.onosproject.net.flow.criteria.Criterion;
40 import com.fasterxml.jackson.databind.JsonNode;
41 import com.fasterxml.jackson.databind.node.ObjectNode;
44 * Decode portion of the criterion codec.
46 public final class DecodeCriterionCodecHelper {
48 private final ObjectNode json;
50 protected static final String MISSING_MEMBER_MESSAGE =
51 " member is required in Criterion";
53 private interface CriterionDecoder {
54 Criterion decodeCriterion(ObjectNode json);
56 private final Map<String, CriterionDecoder> decoderMap;
59 * Creates a decode criterion codec object.
60 * Initializes the lookup map for criterion subclass decoders.
62 * @param json JSON object to decode
64 public DecodeCriterionCodecHelper(ObjectNode json) {
66 decoderMap = new HashMap<>();
68 decoderMap.put(Criterion.Type.IN_PORT.name(), new InPortDecoder());
69 decoderMap.put(Criterion.Type.IN_PHY_PORT.name(), new InPhyPortDecoder());
70 decoderMap.put(Criterion.Type.METADATA.name(), new MetadataDecoder());
71 decoderMap.put(Criterion.Type.ETH_DST.name(), new EthDstDecoder());
72 decoderMap.put(Criterion.Type.ETH_SRC.name(), new EthSrcDecoder());
73 decoderMap.put(Criterion.Type.ETH_TYPE.name(), new EthTypeDecoder());
74 decoderMap.put(Criterion.Type.VLAN_VID.name(), new VlanVidDecoder());
75 decoderMap.put(Criterion.Type.VLAN_PCP.name(), new VlanPcpDecoder());
76 decoderMap.put(Criterion.Type.IP_DSCP.name(), new IpDscpDecoder());
77 decoderMap.put(Criterion.Type.IP_ECN.name(), new IpEcnDecoder());
78 decoderMap.put(Criterion.Type.IP_PROTO.name(), new IpProtoDecoder());
79 decoderMap.put(Criterion.Type.IPV4_SRC.name(), new IpV4SrcDecoder());
80 decoderMap.put(Criterion.Type.IPV4_DST.name(), new IpV4DstDecoder());
81 decoderMap.put(Criterion.Type.TCP_SRC.name(), new TcpSrcDecoder());
82 decoderMap.put(Criterion.Type.TCP_DST.name(), new TcpDstDecoder());
83 decoderMap.put(Criterion.Type.UDP_SRC.name(), new UdpSrcDecoder());
84 decoderMap.put(Criterion.Type.UDP_DST.name(), new UdpDstDecoder());
85 decoderMap.put(Criterion.Type.SCTP_SRC.name(), new SctpSrcDecoder());
86 decoderMap.put(Criterion.Type.SCTP_DST.name(), new SctpDstDecoder());
87 decoderMap.put(Criterion.Type.ICMPV4_TYPE.name(), new IcmpV4TypeDecoder());
88 decoderMap.put(Criterion.Type.ICMPV4_CODE.name(), new IcmpV4CodeDecoder());
89 decoderMap.put(Criterion.Type.IPV6_SRC.name(), new IpV6SrcDecoder());
90 decoderMap.put(Criterion.Type.IPV6_DST.name(), new IpV6DstDecoder());
91 decoderMap.put(Criterion.Type.IPV6_FLABEL.name(), new IpV6FLabelDecoder());
92 decoderMap.put(Criterion.Type.ICMPV6_TYPE.name(), new IcmpV6TypeDecoder());
93 decoderMap.put(Criterion.Type.ICMPV6_CODE.name(), new IcmpV6CodeDecoder());
94 decoderMap.put(Criterion.Type.IPV6_ND_TARGET.name(), new V6NDTargetDecoder());
95 decoderMap.put(Criterion.Type.IPV6_ND_SLL.name(), new V6NDSllDecoder());
96 decoderMap.put(Criterion.Type.IPV6_ND_TLL.name(), new V6NDTllDecoder());
97 decoderMap.put(Criterion.Type.MPLS_LABEL.name(), new MplsLabelDecoder());
98 decoderMap.put(Criterion.Type.IPV6_EXTHDR.name(), new IpV6ExthdrDecoder());
99 decoderMap.put(Criterion.Type.OCH_SIGID.name(), new OchSigIdDecoder());
100 decoderMap.put(Criterion.Type.OCH_SIGTYPE.name(), new OchSigTypeDecoder());
101 decoderMap.put(Criterion.Type.TUNNEL_ID.name(), new TunnelIdDecoder());
102 decoderMap.put(Criterion.Type.ODU_SIGID.name(), new OduSigIdDecoder());
103 decoderMap.put(Criterion.Type.ODU_SIGTYPE.name(), new OduSigTypeDecoder());
106 private class EthTypeDecoder implements CriterionDecoder {
108 public Criterion decodeCriterion(ObjectNode json) {
109 int ethType = nullIsIllegal(json.get(CriterionCodec.ETH_TYPE),
110 CriterionCodec.ETH_TYPE + MISSING_MEMBER_MESSAGE).asInt();
111 return Criteria.matchEthType(ethType);
115 private class EthDstDecoder implements CriterionDecoder {
117 public Criterion decodeCriterion(ObjectNode json) {
118 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
119 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
121 return Criteria.matchEthDst(mac);
125 private class EthSrcDecoder implements CriterionDecoder {
127 public Criterion decodeCriterion(ObjectNode json) {
128 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
129 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
131 return Criteria.matchEthSrc(mac);
135 private class InPortDecoder implements CriterionDecoder {
137 public Criterion decodeCriterion(ObjectNode json) {
138 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
139 CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
141 return Criteria.matchInPort(port);
145 private class InPhyPortDecoder implements CriterionDecoder {
147 public Criterion decodeCriterion(ObjectNode json) {
148 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
149 CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
151 return Criteria.matchInPhyPort(port);
155 private class MetadataDecoder implements CriterionDecoder {
157 public Criterion decodeCriterion(ObjectNode json) {
158 long metadata = nullIsIllegal(json.get(CriterionCodec.METADATA),
159 CriterionCodec.METADATA + MISSING_MEMBER_MESSAGE).asLong();
161 return Criteria.matchMetadata(metadata);
165 private class VlanVidDecoder implements CriterionDecoder {
167 public Criterion decodeCriterion(ObjectNode json) {
168 short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.VLAN_ID),
169 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
171 return Criteria.matchVlanId(VlanId.vlanId(vlanId));
175 private class VlanPcpDecoder implements CriterionDecoder {
177 public Criterion decodeCriterion(ObjectNode json) {
178 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.PRIORITY),
179 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
181 return Criteria.matchVlanPcp(priority);
185 private class IpDscpDecoder implements CriterionDecoder {
187 public Criterion decodeCriterion(ObjectNode json) {
188 byte ipDscp = (byte) nullIsIllegal(json.get(CriterionCodec.IP_DSCP),
189 CriterionCodec.IP_DSCP + MISSING_MEMBER_MESSAGE).asInt();
190 return Criteria.matchIPDscp(ipDscp);
194 private class IpEcnDecoder implements CriterionDecoder {
196 public Criterion decodeCriterion(ObjectNode json) {
197 byte ipEcn = (byte) nullIsIllegal(json.get(CriterionCodec.IP_ECN),
198 CriterionCodec.IP_ECN + MISSING_MEMBER_MESSAGE).asInt();
199 return Criteria.matchIPEcn(ipEcn);
203 private class IpProtoDecoder implements CriterionDecoder {
205 public Criterion decodeCriterion(ObjectNode json) {
206 short proto = (short) nullIsIllegal(json.get(CriterionCodec.PROTOCOL),
207 CriterionCodec.PROTOCOL + MISSING_MEMBER_MESSAGE).asInt();
208 return Criteria.matchIPProtocol(proto);
212 private class IpV4SrcDecoder implements CriterionDecoder {
214 public Criterion decodeCriterion(ObjectNode json) {
215 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
216 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
217 return Criteria.matchIPSrc(IpPrefix.valueOf(ip));
221 private class IpV4DstDecoder implements CriterionDecoder {
223 public Criterion decodeCriterion(ObjectNode json) {
224 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
225 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
226 return Criteria.matchIPDst(IpPrefix.valueOf(ip));
230 private class IpV6SrcDecoder implements CriterionDecoder {
232 public Criterion decodeCriterion(ObjectNode json) {
233 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
234 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
235 return Criteria.matchIPv6Src(IpPrefix.valueOf(ip));
239 private class IpV6DstDecoder implements CriterionDecoder {
241 public Criterion decodeCriterion(ObjectNode json) {
242 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
243 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
244 return Criteria.matchIPv6Dst(IpPrefix.valueOf(ip));
248 private class TcpSrcDecoder implements CriterionDecoder {
250 public Criterion decodeCriterion(ObjectNode json) {
251 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
252 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
253 return Criteria.matchTcpSrc(tcpPort);
257 private class TcpDstDecoder implements CriterionDecoder {
259 public Criterion decodeCriterion(ObjectNode json) {
260 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
261 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
262 return Criteria.matchTcpDst(tcpPort);
266 private class UdpSrcDecoder implements CriterionDecoder {
268 public Criterion decodeCriterion(ObjectNode json) {
269 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
270 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
271 return Criteria.matchUdpSrc(udpPort);
275 private class UdpDstDecoder implements CriterionDecoder {
277 public Criterion decodeCriterion(ObjectNode json) {
278 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
279 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
280 return Criteria.matchUdpDst(udpPort);
284 private class SctpSrcDecoder implements CriterionDecoder {
286 public Criterion decodeCriterion(ObjectNode json) {
287 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
288 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
289 return Criteria.matchSctpSrc(sctpPort);
293 private class SctpDstDecoder implements CriterionDecoder {
295 public Criterion decodeCriterion(ObjectNode json) {
296 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
297 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
298 return Criteria.matchSctpDst(sctpPort);
302 private class IcmpV4TypeDecoder implements CriterionDecoder {
304 public Criterion decodeCriterion(ObjectNode json) {
305 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_TYPE),
306 CriterionCodec.ICMP_TYPE + MISSING_MEMBER_MESSAGE).asInt();
307 return Criteria.matchIcmpType(type);
311 private class IcmpV4CodeDecoder implements CriterionDecoder {
313 public Criterion decodeCriterion(ObjectNode json) {
314 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_CODE),
315 CriterionCodec.ICMP_CODE + MISSING_MEMBER_MESSAGE).asInt();
316 return Criteria.matchIcmpCode(code);
320 private class IpV6FLabelDecoder implements CriterionDecoder {
322 public Criterion decodeCriterion(ObjectNode json) {
323 int flowLabel = nullIsIllegal(json.get(CriterionCodec.FLOW_LABEL),
324 CriterionCodec.FLOW_LABEL + MISSING_MEMBER_MESSAGE).asInt();
325 return Criteria.matchIPv6FlowLabel(flowLabel);
329 private class IcmpV6TypeDecoder implements CriterionDecoder {
331 public Criterion decodeCriterion(ObjectNode json) {
332 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_TYPE),
333 CriterionCodec.ICMPV6_TYPE + MISSING_MEMBER_MESSAGE).asInt();
334 return Criteria.matchIcmpv6Type(type);
338 private class IcmpV6CodeDecoder implements CriterionDecoder {
340 public Criterion decodeCriterion(ObjectNode json) {
341 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_CODE),
342 CriterionCodec.ICMPV6_CODE + MISSING_MEMBER_MESSAGE).asInt();
343 return Criteria.matchIcmpv6Code(code);
347 private class V6NDTargetDecoder implements CriterionDecoder {
349 public Criterion decodeCriterion(ObjectNode json) {
350 Ip6Address target = Ip6Address.valueOf(nullIsIllegal(json.get(CriterionCodec.TARGET_ADDRESS),
351 CriterionCodec.TARGET_ADDRESS + MISSING_MEMBER_MESSAGE).asText());
352 return Criteria.matchIPv6NDTargetAddress(target);
356 private class V6NDSllDecoder implements CriterionDecoder {
358 public Criterion decodeCriterion(ObjectNode json) {
359 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
360 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
361 return Criteria.matchIPv6NDSourceLinkLayerAddress(mac);
365 private class V6NDTllDecoder implements CriterionDecoder {
367 public Criterion decodeCriterion(ObjectNode json) {
368 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
369 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
370 return Criteria.matchIPv6NDTargetLinkLayerAddress(mac);
374 private class MplsLabelDecoder implements CriterionDecoder {
376 public Criterion decodeCriterion(ObjectNode json) {
377 int label = nullIsIllegal(json.get(CriterionCodec.LABEL),
378 CriterionCodec.LABEL + MISSING_MEMBER_MESSAGE).asInt();
379 return Criteria.matchMplsLabel(MplsLabel.mplsLabel(label));
383 private class IpV6ExthdrDecoder implements CriterionDecoder {
385 public Criterion decodeCriterion(ObjectNode json) {
386 int exthdrFlags = nullIsIllegal(json.get(CriterionCodec.EXT_HDR_FLAGS),
387 CriterionCodec.EXT_HDR_FLAGS + MISSING_MEMBER_MESSAGE).asInt();
388 return Criteria.matchIPv6ExthdrFlags(exthdrFlags);
392 private class OchSigIdDecoder implements CriterionDecoder {
394 public Criterion decodeCriterion(ObjectNode json) {
395 if (json.get(CriterionCodec.LAMBDA) != null) {
396 Lambda lambda = Lambda.indexedLambda(nullIsIllegal(json.get(CriterionCodec.LAMBDA),
397 CriterionCodec.LAMBDA + MISSING_MEMBER_MESSAGE).asInt());
398 return Criteria.matchLambda(lambda);
400 JsonNode ochSignalId = nullIsIllegal(json.get(CriterionCodec.OCH_SIGNAL_ID),
401 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE);
404 nullIsIllegal(ochSignalId.get(CriterionCodec.GRID_TYPE),
405 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE).asText());
406 ChannelSpacing channelSpacing =
407 ChannelSpacing.valueOf(
408 nullIsIllegal(ochSignalId.get(CriterionCodec.CHANNEL_SPACING),
409 CriterionCodec.CHANNEL_SPACING + MISSING_MEMBER_MESSAGE).asText());
410 int spacingMultiplier = nullIsIllegal(ochSignalId.get(CriterionCodec.SPACING_MULIPLIER),
411 CriterionCodec.SPACING_MULIPLIER + MISSING_MEMBER_MESSAGE).asInt();
412 int slotGranularity = nullIsIllegal(ochSignalId.get(CriterionCodec.SLOT_GRANULARITY),
413 CriterionCodec.SLOT_GRANULARITY + MISSING_MEMBER_MESSAGE).asInt();
414 return Criteria.matchLambda(
415 Lambda.ochSignal(gridType, channelSpacing,
416 spacingMultiplier, slotGranularity));
421 private class OchSigTypeDecoder implements CriterionDecoder {
423 public Criterion decodeCriterion(ObjectNode json) {
424 OchSignalType ochSignalType = OchSignalType.valueOf(nullIsIllegal(json.get(CriterionCodec.OCH_SIGNAL_TYPE),
425 CriterionCodec.OCH_SIGNAL_TYPE + MISSING_MEMBER_MESSAGE).asText());
426 return Criteria.matchOchSignalType(ochSignalType);
430 private class TunnelIdDecoder implements CriterionDecoder {
432 public Criterion decodeCriterion(ObjectNode json) {
433 long tunnelId = nullIsIllegal(json.get(CriterionCodec.TUNNEL_ID),
434 CriterionCodec.TUNNEL_ID + MISSING_MEMBER_MESSAGE).asLong();
435 return Criteria.matchTunnelId(tunnelId);
439 private class OduSigIdDecoder implements CriterionDecoder {
441 public Criterion decodeCriterion(ObjectNode json) {
442 JsonNode oduSignalId = nullIsIllegal(json.get(CriterionCodec.ODU_SIGNAL_ID),
443 CriterionCodec.TRIBUTARY_PORT_NUMBER + MISSING_MEMBER_MESSAGE);
445 int tributaryPortNumber = nullIsIllegal(oduSignalId.get(CriterionCodec.TRIBUTARY_PORT_NUMBER),
446 CriterionCodec.TRIBUTARY_PORT_NUMBER + MISSING_MEMBER_MESSAGE).asInt();
447 int tributarySlotLen = nullIsIllegal(oduSignalId.get(CriterionCodec.TRIBUTARY_SLOT_LEN),
448 CriterionCodec.TRIBUTARY_SLOT_LEN + MISSING_MEMBER_MESSAGE).asInt();
449 byte[] tributarySlotBitmap = HexString.fromHexString(
450 nullIsIllegal(oduSignalId.get(CriterionCodec.TRIBUTARY_SLOT_BITMAP),
451 CriterionCodec.TRIBUTARY_SLOT_BITMAP + MISSING_MEMBER_MESSAGE).asText());
453 return Criteria.matchOduSignalId(
454 OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen, tributarySlotBitmap));
458 private class OduSigTypeDecoder implements CriterionDecoder {
460 public Criterion decodeCriterion(ObjectNode json) {
461 OduSignalType oduSignalType = OduSignalType.valueOf(nullIsIllegal(json.get(CriterionCodec.ODU_SIGNAL_TYPE),
462 CriterionCodec.ODU_SIGNAL_TYPE + MISSING_MEMBER_MESSAGE).asText());
463 return Criteria.matchOduSignalType(oduSignalType);
468 * Decodes the JSON into a criterion object.
470 * @return Criterion object
471 * @throws IllegalArgumentException if the JSON is invalid
473 public Criterion decode() {
474 String type = json.get(CriterionCodec.TYPE).asText();
476 CriterionDecoder decoder = decoderMap.get(type);
477 if (decoder != null) {
478 return decoder.decodeCriterion(json);
481 throw new IllegalArgumentException("Type " + type + " is unknown");