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 com.fasterxml.jackson.databind.node.ObjectNode;
19 import org.onlab.util.HexString;
20 import org.onosproject.codec.CodecContext;
21 import org.onosproject.net.OchSignal;
22 import org.onosproject.net.OduSignalId;
23 import org.onosproject.net.flow.criteria.Criterion;
24 import org.onosproject.net.flow.criteria.EthCriterion;
25 import org.onosproject.net.flow.criteria.EthTypeCriterion;
26 import org.onosproject.net.flow.criteria.IPCriterion;
27 import org.onosproject.net.flow.criteria.IPDscpCriterion;
28 import org.onosproject.net.flow.criteria.IPEcnCriterion;
29 import org.onosproject.net.flow.criteria.IPProtocolCriterion;
30 import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
31 import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
32 import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
33 import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
34 import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
35 import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
36 import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
37 import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
38 import org.onosproject.net.flow.criteria.MetadataCriterion;
39 import org.onosproject.net.flow.criteria.MplsCriterion;
40 import org.onosproject.net.flow.criteria.OchSignalCriterion;
41 import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
42 import org.onosproject.net.flow.criteria.OduSignalIdCriterion;
43 import org.onosproject.net.flow.criteria.OduSignalTypeCriterion;
44 import org.onosproject.net.flow.criteria.PortCriterion;
45 import org.onosproject.net.flow.criteria.SctpPortCriterion;
46 import org.onosproject.net.flow.criteria.TcpPortCriterion;
47 import org.onosproject.net.flow.criteria.TunnelIdCriterion;
48 import org.onosproject.net.flow.criteria.UdpPortCriterion;
49 import org.onosproject.net.flow.criteria.VlanIdCriterion;
50 import org.onosproject.net.flow.criteria.VlanPcpCriterion;
52 import java.util.EnumMap;
54 import static com.google.common.base.Preconditions.checkNotNull;
57 * Encode portion of the criterion codec.
59 public final class EncodeCriterionCodecHelper {
61 private final Criterion criterion;
62 private final CodecContext context;
64 private final EnumMap<Criterion.Type, CriterionTypeFormatter> formatMap;
67 * Creates an encoder object for a criterion.
68 * Initializes the formatter lookup map for the criterion subclasses.
70 * @param criterion Criterion to encode
71 * @param context context of the JSON encoding
73 public EncodeCriterionCodecHelper(Criterion criterion, CodecContext context) {
74 this.criterion = criterion;
75 this.context = context;
77 formatMap = new EnumMap<>(Criterion.Type.class);
79 formatMap.put(Criterion.Type.IN_PORT, new FormatInPort());
80 formatMap.put(Criterion.Type.IN_PHY_PORT, new FormatInPort());
81 formatMap.put(Criterion.Type.METADATA, new FormatMetadata());
82 formatMap.put(Criterion.Type.ETH_DST, new FormatEth());
83 formatMap.put(Criterion.Type.ETH_SRC, new FormatEth());
84 formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType());
85 formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid());
86 formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp());
87 formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp());
88 formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn());
89 formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto());
90 formatMap.put(Criterion.Type.IPV4_SRC, new FormatIp());
91 formatMap.put(Criterion.Type.IPV4_DST, new FormatIp());
92 formatMap.put(Criterion.Type.TCP_SRC, new FormatTcp());
93 formatMap.put(Criterion.Type.TCP_DST, new FormatTcp());
94 formatMap.put(Criterion.Type.UDP_SRC, new FormatUdp());
95 formatMap.put(Criterion.Type.UDP_DST, new FormatUdp());
96 formatMap.put(Criterion.Type.SCTP_SRC, new FormatSctp());
97 formatMap.put(Criterion.Type.SCTP_DST, new FormatSctp());
98 formatMap.put(Criterion.Type.ICMPV4_TYPE, new FormatIcmpV4Type());
99 formatMap.put(Criterion.Type.ICMPV4_CODE, new FormatIcmpV4Code());
100 formatMap.put(Criterion.Type.IPV6_SRC, new FormatIp());
101 formatMap.put(Criterion.Type.IPV6_DST, new FormatIp());
102 formatMap.put(Criterion.Type.IPV6_FLABEL, new FormatIpV6FLabel());
103 formatMap.put(Criterion.Type.ICMPV6_TYPE, new FormatIcmpV6Type());
104 formatMap.put(Criterion.Type.ICMPV6_CODE, new FormatIcmpV6Code());
105 formatMap.put(Criterion.Type.IPV6_ND_TARGET, new FormatV6NDTarget());
106 formatMap.put(Criterion.Type.IPV6_ND_SLL, new FormatV6NDTll());
107 formatMap.put(Criterion.Type.IPV6_ND_TLL, new FormatV6NDTll());
108 formatMap.put(Criterion.Type.MPLS_LABEL, new FormatMplsLabel());
109 formatMap.put(Criterion.Type.IPV6_EXTHDR, new FormatIpV6Exthdr());
110 formatMap.put(Criterion.Type.OCH_SIGID, new FormatOchSigId());
111 formatMap.put(Criterion.Type.OCH_SIGTYPE, new FormatOchSigType());
112 formatMap.put(Criterion.Type.TUNNEL_ID, new FormatTunnelId());
113 formatMap.put(Criterion.Type.DUMMY, new FormatDummyType());
114 formatMap.put(Criterion.Type.ODU_SIGID, new FormatOduSignalId());
115 formatMap.put(Criterion.Type.ODU_SIGTYPE, new FormatOduSignalType());
116 // Currently unimplemented
117 formatMap.put(Criterion.Type.ARP_OP, new FormatUnknown());
118 formatMap.put(Criterion.Type.ARP_SPA, new FormatUnknown());
119 formatMap.put(Criterion.Type.ARP_TPA, new FormatUnknown());
120 formatMap.put(Criterion.Type.ARP_SHA, new FormatUnknown());
121 formatMap.put(Criterion.Type.ARP_THA, new FormatUnknown());
122 formatMap.put(Criterion.Type.MPLS_TC, new FormatUnknown());
123 formatMap.put(Criterion.Type.MPLS_BOS, new FormatUnknown());
124 formatMap.put(Criterion.Type.PBB_ISID, new FormatUnknown());
125 formatMap.put(Criterion.Type.UNASSIGNED_40, new FormatUnknown());
126 formatMap.put(Criterion.Type.PBB_UCA, new FormatUnknown());
127 formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
128 formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
129 formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
132 private interface CriterionTypeFormatter {
133 ObjectNode encodeCriterion(ObjectNode root, Criterion criterion);
136 private static class FormatUnknown implements CriterionTypeFormatter {
138 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
143 private static class FormatInPort implements CriterionTypeFormatter {
145 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
146 final PortCriterion portCriterion = (PortCriterion) criterion;
147 return root.put(CriterionCodec.PORT, portCriterion.port().toLong());
151 private static class FormatMetadata implements CriterionTypeFormatter {
153 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
154 final MetadataCriterion metadataCriterion =
155 (MetadataCriterion) criterion;
156 return root.put(CriterionCodec.METADATA, metadataCriterion.metadata());
160 private static class FormatEth implements CriterionTypeFormatter {
162 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
163 final EthCriterion ethCriterion = (EthCriterion) criterion;
164 return root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
168 private static class FormatEthType implements CriterionTypeFormatter {
170 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
171 final EthTypeCriterion ethTypeCriterion =
172 (EthTypeCriterion) criterion;
173 return root.put(CriterionCodec.ETH_TYPE, "0x"
174 + Integer.toHexString(ethTypeCriterion.ethType().toShort() & 0xffff));
178 private static class FormatVlanVid implements CriterionTypeFormatter {
180 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
181 final VlanIdCriterion vlanIdCriterion =
182 (VlanIdCriterion) criterion;
183 return root.put(CriterionCodec.VLAN_ID, vlanIdCriterion.vlanId().toShort());
187 private static class FormatVlanPcp implements CriterionTypeFormatter {
189 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
190 final VlanPcpCriterion vlanPcpCriterion =
191 (VlanPcpCriterion) criterion;
192 return root.put(CriterionCodec.PRIORITY, vlanPcpCriterion.priority());
196 private static class FormatIpDscp implements CriterionTypeFormatter {
198 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
199 final IPDscpCriterion ipDscpCriterion =
200 (IPDscpCriterion) criterion;
201 return root.put(CriterionCodec.IP_DSCP, ipDscpCriterion.ipDscp());
205 private static class FormatIpEcn implements CriterionTypeFormatter {
207 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
208 final IPEcnCriterion ipEcnCriterion =
209 (IPEcnCriterion) criterion;
210 return root.put(CriterionCodec.IP_ECN, ipEcnCriterion.ipEcn());
214 private static class FormatIpProto implements CriterionTypeFormatter {
216 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
217 final IPProtocolCriterion iPProtocolCriterion =
218 (IPProtocolCriterion) criterion;
219 return root.put(CriterionCodec.PROTOCOL, iPProtocolCriterion.protocol());
223 private static class FormatIp implements CriterionTypeFormatter {
225 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
226 final IPCriterion iPCriterion = (IPCriterion) criterion;
227 return root.put(CriterionCodec.IP, iPCriterion.ip().toString());
231 private static class FormatTcp implements CriterionTypeFormatter {
233 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
234 final TcpPortCriterion tcpPortCriterion =
235 (TcpPortCriterion) criterion;
236 return root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
240 private static class FormatUdp implements CriterionTypeFormatter {
242 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
243 final UdpPortCriterion udpPortCriterion =
244 (UdpPortCriterion) criterion;
245 return root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
249 private static class FormatSctp implements CriterionTypeFormatter {
251 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
252 final SctpPortCriterion sctpPortCriterion =
253 (SctpPortCriterion) criterion;
254 return root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
258 private static class FormatIcmpV4Type implements CriterionTypeFormatter {
260 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
261 final IcmpTypeCriterion icmpTypeCriterion =
262 (IcmpTypeCriterion) criterion;
263 return root.put(CriterionCodec.ICMP_TYPE, icmpTypeCriterion.icmpType());
267 private static class FormatIcmpV4Code implements CriterionTypeFormatter {
269 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
270 final IcmpCodeCriterion icmpCodeCriterion =
271 (IcmpCodeCriterion) criterion;
272 return root.put(CriterionCodec.ICMP_CODE, icmpCodeCriterion.icmpCode());
276 private static class FormatIpV6FLabel implements CriterionTypeFormatter {
278 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
279 final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
280 (IPv6FlowLabelCriterion) criterion;
281 return root.put(CriterionCodec.FLOW_LABEL, ipv6FlowLabelCriterion.flowLabel());
285 private static class FormatIcmpV6Type implements CriterionTypeFormatter {
287 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
288 final Icmpv6TypeCriterion icmpv6TypeCriterion =
289 (Icmpv6TypeCriterion) criterion;
290 return root.put(CriterionCodec.ICMPV6_TYPE, icmpv6TypeCriterion.icmpv6Type());
294 private static class FormatIcmpV6Code implements CriterionTypeFormatter {
296 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
297 final Icmpv6CodeCriterion icmpv6CodeCriterion =
298 (Icmpv6CodeCriterion) criterion;
299 return root.put(CriterionCodec.ICMPV6_CODE, icmpv6CodeCriterion.icmpv6Code());
303 private static class FormatV6NDTarget implements CriterionTypeFormatter {
305 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
306 final IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
307 = (IPv6NDTargetAddressCriterion) criterion;
308 return root.put(CriterionCodec.TARGET_ADDRESS, ipv6NDTargetAddressCriterion.targetAddress().toString());
312 private static class FormatV6NDTll implements CriterionTypeFormatter {
314 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
315 final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
316 = (IPv6NDLinkLayerAddressCriterion) criterion;
317 return root.put(CriterionCodec.MAC, ipv6NDLinkLayerAddressCriterion.mac().toString());
321 private static class FormatMplsLabel implements CriterionTypeFormatter {
323 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
324 final MplsCriterion mplsCriterion =
325 (MplsCriterion) criterion;
326 return root.put(CriterionCodec.LABEL, mplsCriterion.label().toInt());
330 private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
332 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
333 final IPv6ExthdrFlagsCriterion exthdrCriterion =
334 (IPv6ExthdrFlagsCriterion) criterion;
335 return root.put(CriterionCodec.EXT_HDR_FLAGS, exthdrCriterion.exthdrFlags());
339 private static class FormatOchSigId implements CriterionTypeFormatter {
341 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
342 OchSignal ochSignal = ((OchSignalCriterion) criterion).lambda();
343 ObjectNode child = root.putObject(CriterionCodec.OCH_SIGNAL_ID);
345 child.put(CriterionCodec.GRID_TYPE, ochSignal.gridType().name());
346 child.put(CriterionCodec.CHANNEL_SPACING, ochSignal.channelSpacing().name());
347 child.put(CriterionCodec.SPACING_MULIPLIER, ochSignal.spacingMultiplier());
348 child.put(CriterionCodec.SLOT_GRANULARITY, ochSignal.slotGranularity());
354 private static class FormatOchSigType implements CriterionTypeFormatter {
356 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
357 final OchSignalTypeCriterion ochSignalTypeCriterion =
358 (OchSignalTypeCriterion) criterion;
359 return root.put(CriterionCodec.OCH_SIGNAL_TYPE, ochSignalTypeCriterion.signalType().name());
363 private static class FormatTunnelId implements CriterionTypeFormatter {
365 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
366 final TunnelIdCriterion tunnelIdCriterion =
367 (TunnelIdCriterion) criterion;
368 return root.put(CriterionCodec.TUNNEL_ID, tunnelIdCriterion.tunnelId());
372 private static class FormatOduSignalId implements CriterionTypeFormatter {
374 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
375 OduSignalId oduSignalId = ((OduSignalIdCriterion) criterion).oduSignalId();
376 ObjectNode child = root.putObject(CriterionCodec.ODU_SIGNAL_ID);
378 child.put(CriterionCodec.TRIBUTARY_PORT_NUMBER, oduSignalId.tributaryPortNumber());
379 child.put(CriterionCodec.TRIBUTARY_SLOT_LEN, oduSignalId.tributarySlotLength());
380 child.put(CriterionCodec.TRIBUTARY_SLOT_BITMAP, HexString.toHexString(oduSignalId.tributarySlotBitmap()));
387 private static class FormatOduSignalType implements CriterionTypeFormatter {
389 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
390 final OduSignalTypeCriterion oduSignalTypeCriterion =
391 (OduSignalTypeCriterion) criterion;
392 return root.put(CriterionCodec.ODU_SIGNAL_TYPE, oduSignalTypeCriterion.signalType().name());
396 private class FormatDummyType implements CriterionTypeFormatter {
399 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
400 checkNotNull(criterion, "Criterion cannot be null");
402 return root.put(CriterionCodec.TYPE, criterion.type().toString());
408 * Encodes a criterion into a JSON node.
410 * @return encoded JSON object for the given criterion
412 public ObjectNode encode() {
413 final ObjectNode result = context.mapper().createObjectNode()
414 .put(CriterionCodec.TYPE, criterion.type().toString());
416 CriterionTypeFormatter formatter =
418 formatMap.get(criterion.type()),
419 "No formatter found for criterion type "
420 + criterion.type().toString());
422 return formatter.encodeCriterion(result, criterion);