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 java.util.EnumMap;
 
  20 import org.onosproject.codec.CodecContext;
 
  21 import org.onosproject.net.OchSignal;
 
  22 import org.onosproject.net.flow.criteria.Criterion;
 
  23 import org.onosproject.net.flow.criteria.EthCriterion;
 
  24 import org.onosproject.net.flow.criteria.EthTypeCriterion;
 
  25 import org.onosproject.net.flow.criteria.IPCriterion;
 
  26 import org.onosproject.net.flow.criteria.IPDscpCriterion;
 
  27 import org.onosproject.net.flow.criteria.IPEcnCriterion;
 
  28 import org.onosproject.net.flow.criteria.IPProtocolCriterion;
 
  29 import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
 
  30 import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
 
  31 import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
 
  32 import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
 
  33 import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
 
  34 import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
 
  35 import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
 
  36 import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
 
  37 import org.onosproject.net.flow.criteria.MetadataCriterion;
 
  38 import org.onosproject.net.flow.criteria.MplsCriterion;
 
  39 import org.onosproject.net.flow.criteria.OchSignalCriterion;
 
  40 import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
 
  41 import org.onosproject.net.flow.criteria.PortCriterion;
 
  42 import org.onosproject.net.flow.criteria.SctpPortCriterion;
 
  43 import org.onosproject.net.flow.criteria.TcpPortCriterion;
 
  44 import org.onosproject.net.flow.criteria.TunnelIdCriterion;
 
  45 import org.onosproject.net.flow.criteria.UdpPortCriterion;
 
  46 import org.onosproject.net.flow.criteria.VlanIdCriterion;
 
  47 import org.onosproject.net.flow.criteria.VlanPcpCriterion;
 
  49 import com.fasterxml.jackson.databind.node.ObjectNode;
 
  51 import static com.google.common.base.Preconditions.checkNotNull;
 
  54  * Encode portion of the criterion codec.
 
  56 public final class EncodeCriterionCodecHelper {
 
  58     private final Criterion criterion;
 
  59     private final CodecContext context;
 
  61     private final EnumMap<Criterion.Type, CriterionTypeFormatter> formatMap;
 
  64      * Creates an encoder object for a criterion.
 
  65      * Initializes the formatter lookup map for the criterion subclasses.
 
  67      * @param criterion Criterion to encode
 
  68      * @param context context of the JSON encoding
 
  70     public EncodeCriterionCodecHelper(Criterion criterion, CodecContext context) {
 
  71         this.criterion = criterion;
 
  72         this.context = context;
 
  74         formatMap = new EnumMap<>(Criterion.Type.class);
 
  76         formatMap.put(Criterion.Type.IN_PORT, new FormatInPort());
 
  77         formatMap.put(Criterion.Type.IN_PHY_PORT, new FormatInPort());
 
  78         formatMap.put(Criterion.Type.METADATA, new FormatMetadata());
 
  79         formatMap.put(Criterion.Type.ETH_DST, new FormatEth());
 
  80         formatMap.put(Criterion.Type.ETH_SRC, new FormatEth());
 
  81         formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType());
 
  82         formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid());
 
  83         formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp());
 
  84         formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp());
 
  85         formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn());
 
  86         formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto());
 
  87         formatMap.put(Criterion.Type.IPV4_SRC, new FormatIp());
 
  88         formatMap.put(Criterion.Type.IPV4_DST, new FormatIp());
 
  89         formatMap.put(Criterion.Type.TCP_SRC, new FormatTcp());
 
  90         formatMap.put(Criterion.Type.TCP_DST, new FormatTcp());
 
  91         formatMap.put(Criterion.Type.UDP_SRC, new FormatUdp());
 
  92         formatMap.put(Criterion.Type.UDP_DST, new FormatUdp());
 
  93         formatMap.put(Criterion.Type.SCTP_SRC, new FormatSctp());
 
  94         formatMap.put(Criterion.Type.SCTP_DST, new FormatSctp());
 
  95         formatMap.put(Criterion.Type.ICMPV4_TYPE, new FormatIcmpV4Type());
 
  96         formatMap.put(Criterion.Type.ICMPV4_CODE, new FormatIcmpV4Code());
 
  97         formatMap.put(Criterion.Type.IPV6_SRC, new FormatIp());
 
  98         formatMap.put(Criterion.Type.IPV6_DST, new FormatIp());
 
  99         formatMap.put(Criterion.Type.IPV6_FLABEL, new FormatIpV6FLabel());
 
 100         formatMap.put(Criterion.Type.ICMPV6_TYPE, new FormatIcmpV6Type());
 
 101         formatMap.put(Criterion.Type.ICMPV6_CODE, new FormatIcmpV6Code());
 
 102         formatMap.put(Criterion.Type.IPV6_ND_TARGET, new FormatV6NDTarget());
 
 103         formatMap.put(Criterion.Type.IPV6_ND_SLL, new FormatV6NDTll());
 
 104         formatMap.put(Criterion.Type.IPV6_ND_TLL, new FormatV6NDTll());
 
 105         formatMap.put(Criterion.Type.MPLS_LABEL, new FormatMplsLabel());
 
 106         formatMap.put(Criterion.Type.IPV6_EXTHDR, new FormatIpV6Exthdr());
 
 107         formatMap.put(Criterion.Type.OCH_SIGID, new FormatOchSigId());
 
 108         formatMap.put(Criterion.Type.OCH_SIGTYPE, new FormatOchSigType());
 
 109         formatMap.put(Criterion.Type.TUNNEL_ID, new FormatTunnelId());
 
 110         formatMap.put(Criterion.Type.DUMMY, new FormatDummyType());
 
 112         // Currently unimplemented
 
 113         formatMap.put(Criterion.Type.ARP_OP, new FormatUnknown());
 
 114         formatMap.put(Criterion.Type.ARP_SPA, new FormatUnknown());
 
 115         formatMap.put(Criterion.Type.ARP_TPA, new FormatUnknown());
 
 116         formatMap.put(Criterion.Type.ARP_SHA, new FormatUnknown());
 
 117         formatMap.put(Criterion.Type.ARP_THA, new FormatUnknown());
 
 118         formatMap.put(Criterion.Type.MPLS_TC, new FormatUnknown());
 
 119         formatMap.put(Criterion.Type.MPLS_BOS, new FormatUnknown());
 
 120         formatMap.put(Criterion.Type.PBB_ISID, new FormatUnknown());
 
 121         formatMap.put(Criterion.Type.UNASSIGNED_40, new FormatUnknown());
 
 122         formatMap.put(Criterion.Type.PBB_UCA, new FormatUnknown());
 
 123         formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
 
 124         formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
 
 125         formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
 
 128     private interface CriterionTypeFormatter {
 
 129         ObjectNode encodeCriterion(ObjectNode root, Criterion criterion);
 
 132     private static class FormatUnknown implements CriterionTypeFormatter {
 
 134         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 139     private static class FormatInPort implements CriterionTypeFormatter {
 
 141         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 142             final PortCriterion portCriterion = (PortCriterion) criterion;
 
 143             return root.put(CriterionCodec.PORT, portCriterion.port().toLong());
 
 147     private static class FormatMetadata implements CriterionTypeFormatter {
 
 149         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 150             final MetadataCriterion metadataCriterion =
 
 151                     (MetadataCriterion) criterion;
 
 152             return root.put(CriterionCodec.METADATA, metadataCriterion.metadata());
 
 156     private static class FormatEth implements CriterionTypeFormatter {
 
 158         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 159             final EthCriterion ethCriterion = (EthCriterion) criterion;
 
 160             return root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
 
 164     private static class FormatEthType implements CriterionTypeFormatter {
 
 166         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 167             final EthTypeCriterion ethTypeCriterion =
 
 168                     (EthTypeCriterion) criterion;
 
 169             return root.put(CriterionCodec.ETH_TYPE, ethTypeCriterion.ethType().toShort());
 
 173     private static class FormatVlanVid implements CriterionTypeFormatter {
 
 175         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 176             final VlanIdCriterion vlanIdCriterion =
 
 177                     (VlanIdCriterion) criterion;
 
 178             return root.put(CriterionCodec.VLAN_ID, vlanIdCriterion.vlanId().toShort());
 
 182     private static class FormatVlanPcp implements CriterionTypeFormatter {
 
 184         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 185             final VlanPcpCriterion vlanPcpCriterion =
 
 186                     (VlanPcpCriterion) criterion;
 
 187             return root.put(CriterionCodec.PRIORITY, vlanPcpCriterion.priority());
 
 191     private static class FormatIpDscp implements CriterionTypeFormatter {
 
 193         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 194             final IPDscpCriterion ipDscpCriterion =
 
 195                     (IPDscpCriterion) criterion;
 
 196             return root.put(CriterionCodec.IP_DSCP, ipDscpCriterion.ipDscp());
 
 200     private static class FormatIpEcn implements CriterionTypeFormatter {
 
 202         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 203             final IPEcnCriterion ipEcnCriterion =
 
 204                     (IPEcnCriterion) criterion;
 
 205             return root.put(CriterionCodec.IP_ECN, ipEcnCriterion.ipEcn());
 
 209     private static class FormatIpProto implements CriterionTypeFormatter {
 
 211         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 212             final IPProtocolCriterion iPProtocolCriterion =
 
 213                     (IPProtocolCriterion) criterion;
 
 214             return root.put(CriterionCodec.PROTOCOL, iPProtocolCriterion.protocol());
 
 218     private static class FormatIp implements CriterionTypeFormatter {
 
 220         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 221             final IPCriterion iPCriterion = (IPCriterion) criterion;
 
 222             return root.put(CriterionCodec.IP, iPCriterion.ip().toString());
 
 226     private static class FormatTcp implements CriterionTypeFormatter {
 
 228         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 229             final TcpPortCriterion tcpPortCriterion =
 
 230                     (TcpPortCriterion) criterion;
 
 231             return root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
 
 235     private static class FormatUdp implements CriterionTypeFormatter {
 
 237         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 238             final UdpPortCriterion udpPortCriterion =
 
 239                     (UdpPortCriterion) criterion;
 
 240             return root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
 
 244     private static class FormatSctp implements CriterionTypeFormatter {
 
 246         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 247             final SctpPortCriterion sctpPortCriterion =
 
 248                     (SctpPortCriterion) criterion;
 
 249             return root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
 
 253     private static class FormatIcmpV4Type implements CriterionTypeFormatter {
 
 255         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 256             final IcmpTypeCriterion icmpTypeCriterion =
 
 257                     (IcmpTypeCriterion) criterion;
 
 258             return root.put(CriterionCodec.ICMP_TYPE, icmpTypeCriterion.icmpType());
 
 262     private static class FormatIcmpV4Code implements CriterionTypeFormatter {
 
 264         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 265             final IcmpCodeCriterion icmpCodeCriterion =
 
 266                     (IcmpCodeCriterion) criterion;
 
 267             return root.put(CriterionCodec.ICMP_CODE, icmpCodeCriterion.icmpCode());
 
 271     private static class FormatIpV6FLabel implements CriterionTypeFormatter {
 
 273         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 274             final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
 
 275                     (IPv6FlowLabelCriterion) criterion;
 
 276             return root.put(CriterionCodec.FLOW_LABEL, ipv6FlowLabelCriterion.flowLabel());
 
 280     private static class FormatIcmpV6Type implements CriterionTypeFormatter {
 
 282         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 283             final Icmpv6TypeCriterion icmpv6TypeCriterion =
 
 284                     (Icmpv6TypeCriterion) criterion;
 
 285             return root.put(CriterionCodec.ICMPV6_TYPE, icmpv6TypeCriterion.icmpv6Type());
 
 289     private static class FormatIcmpV6Code implements CriterionTypeFormatter {
 
 291         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 292             final Icmpv6CodeCriterion icmpv6CodeCriterion =
 
 293                     (Icmpv6CodeCriterion) criterion;
 
 294             return root.put(CriterionCodec.ICMPV6_CODE, icmpv6CodeCriterion.icmpv6Code());
 
 298     private static class FormatV6NDTarget implements CriterionTypeFormatter {
 
 300         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 301             final IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
 
 302                     = (IPv6NDTargetAddressCriterion) criterion;
 
 303             return root.put(CriterionCodec.TARGET_ADDRESS, ipv6NDTargetAddressCriterion.targetAddress().toString());
 
 307     private static class FormatV6NDTll implements CriterionTypeFormatter {
 
 309         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 310             final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
 
 311                     = (IPv6NDLinkLayerAddressCriterion) criterion;
 
 312             return root.put(CriterionCodec.MAC, ipv6NDLinkLayerAddressCriterion.mac().toString());
 
 316     private static class FormatMplsLabel implements CriterionTypeFormatter {
 
 318         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 319             final MplsCriterion mplsCriterion =
 
 320                     (MplsCriterion) criterion;
 
 321             return root.put(CriterionCodec.LABEL, mplsCriterion.label().toInt());
 
 325     private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
 
 327         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 328             final IPv6ExthdrFlagsCriterion exthdrCriterion =
 
 329                     (IPv6ExthdrFlagsCriterion) criterion;
 
 330             return root.put(CriterionCodec.EXT_HDR_FLAGS, exthdrCriterion.exthdrFlags());
 
 334     private static class FormatOchSigId implements CriterionTypeFormatter {
 
 336         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 337             OchSignal ochSignal = ((OchSignalCriterion) criterion).lambda();
 
 338             ObjectNode child = root.putObject(CriterionCodec.OCH_SIGNAL_ID);
 
 340             child.put(CriterionCodec.GRID_TYPE, ochSignal.gridType().name());
 
 341             child.put(CriterionCodec.CHANNEL_SPACING, ochSignal.channelSpacing().name());
 
 342             child.put(CriterionCodec.SPACING_MULIPLIER, ochSignal.spacingMultiplier());
 
 343             child.put(CriterionCodec.SLOT_GRANULARITY, ochSignal.slotGranularity());
 
 349     private static class FormatOchSigType implements CriterionTypeFormatter {
 
 351         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 352             final OchSignalTypeCriterion ochSignalTypeCriterion =
 
 353                     (OchSignalTypeCriterion) criterion;
 
 354             return root.put("ochSignalType", ochSignalTypeCriterion.signalType().name());
 
 358     private static class FormatTunnelId implements CriterionTypeFormatter {
 
 360         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 361             final TunnelIdCriterion tunnelIdCriterion =
 
 362                     (TunnelIdCriterion) criterion;
 
 363             return root.put(CriterionCodec.TUNNEL_ID, tunnelIdCriterion.tunnelId());
 
 367     private class FormatDummyType implements CriterionTypeFormatter {
 
 370         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
 
 371             checkNotNull(criterion, "Criterion cannot be null");
 
 373             return root.put(CriterionCodec.TYPE, criterion.type().toString());
 
 379      * Encodes a criterion into a JSON node.
 
 381      * @return encoded JSON object for the given criterion
 
 383     public ObjectNode encode() {
 
 384         final ObjectNode result = context.mapper().createObjectNode()
 
 385                 .put(CriterionCodec.TYPE, criterion.type().toString());
 
 387         CriterionTypeFormatter formatter =
 
 389                         formatMap.get(criterion.type()),
 
 390                         "No formatter found for criterion type "
 
 391                                 + criterion.type().toString());
 
 393         return formatter.encodeCriterion(result, criterion);