33dd46a37f25d9e5888ebf5190462df270fd30a7
[onosfw.git] /
1 /*
2  * Copyright 2015 Open Networking Laboratory
3  *
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  */
16 package org.onosproject.codec.impl;
17
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;
51
52 import java.util.EnumMap;
53
54 import static com.google.common.base.Preconditions.checkNotNull;
55
56 /**
57  * Encode portion of the criterion codec.
58  */
59 public final class EncodeCriterionCodecHelper {
60
61     private final Criterion criterion;
62     private final CodecContext context;
63
64     private final EnumMap<Criterion.Type, CriterionTypeFormatter> formatMap;
65
66     /**
67      * Creates an encoder object for a criterion.
68      * Initializes the formatter lookup map for the criterion subclasses.
69      *
70      * @param criterion Criterion to encode
71      * @param context   context of the JSON encoding
72      */
73     public EncodeCriterionCodecHelper(Criterion criterion, CodecContext context) {
74         this.criterion = criterion;
75         this.context = context;
76
77         formatMap = new EnumMap<>(Criterion.Type.class);
78
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());
130     }
131
132     private interface CriterionTypeFormatter {
133         ObjectNode encodeCriterion(ObjectNode root, Criterion criterion);
134     }
135
136     private static class FormatUnknown implements CriterionTypeFormatter {
137         @Override
138         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
139             return root;
140         }
141     }
142
143     private static class FormatInPort implements CriterionTypeFormatter {
144         @Override
145         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
146             final PortCriterion portCriterion = (PortCriterion) criterion;
147             return root.put(CriterionCodec.PORT, portCriterion.port().toLong());
148         }
149     }
150
151     private static class FormatMetadata implements CriterionTypeFormatter {
152         @Override
153         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
154             final MetadataCriterion metadataCriterion =
155                     (MetadataCriterion) criterion;
156             return root.put(CriterionCodec.METADATA, metadataCriterion.metadata());
157         }
158     }
159
160     private static class FormatEth implements CriterionTypeFormatter {
161         @Override
162         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
163             final EthCriterion ethCriterion = (EthCriterion) criterion;
164             return root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
165         }
166     }
167
168     private static class FormatEthType implements CriterionTypeFormatter {
169         @Override
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));
175         }
176     }
177
178     private static class FormatVlanVid implements CriterionTypeFormatter {
179         @Override
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());
184         }
185     }
186
187     private static class FormatVlanPcp implements CriterionTypeFormatter {
188         @Override
189         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
190             final VlanPcpCriterion vlanPcpCriterion =
191                     (VlanPcpCriterion) criterion;
192             return root.put(CriterionCodec.PRIORITY, vlanPcpCriterion.priority());
193         }
194     }
195
196     private static class FormatIpDscp implements CriterionTypeFormatter {
197         @Override
198         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
199             final IPDscpCriterion ipDscpCriterion =
200                     (IPDscpCriterion) criterion;
201             return root.put(CriterionCodec.IP_DSCP, ipDscpCriterion.ipDscp());
202         }
203     }
204
205     private static class FormatIpEcn implements CriterionTypeFormatter {
206         @Override
207         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
208             final IPEcnCriterion ipEcnCriterion =
209                     (IPEcnCriterion) criterion;
210             return root.put(CriterionCodec.IP_ECN, ipEcnCriterion.ipEcn());
211         }
212     }
213
214     private static class FormatIpProto implements CriterionTypeFormatter {
215         @Override
216         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
217             final IPProtocolCriterion iPProtocolCriterion =
218                     (IPProtocolCriterion) criterion;
219             return root.put(CriterionCodec.PROTOCOL, iPProtocolCriterion.protocol());
220         }
221     }
222
223     private static class FormatIp implements CriterionTypeFormatter {
224         @Override
225         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
226             final IPCriterion iPCriterion = (IPCriterion) criterion;
227             return root.put(CriterionCodec.IP, iPCriterion.ip().toString());
228         }
229     }
230
231     private static class FormatTcp implements CriterionTypeFormatter {
232         @Override
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());
237         }
238     }
239
240     private static class FormatUdp implements CriterionTypeFormatter {
241         @Override
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());
246         }
247     }
248
249     private static class FormatSctp implements CriterionTypeFormatter {
250         @Override
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());
255         }
256     }
257
258     private static class FormatIcmpV4Type implements CriterionTypeFormatter {
259         @Override
260         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
261             final IcmpTypeCriterion icmpTypeCriterion =
262                     (IcmpTypeCriterion) criterion;
263             return root.put(CriterionCodec.ICMP_TYPE, icmpTypeCriterion.icmpType());
264         }
265     }
266
267     private static class FormatIcmpV4Code implements CriterionTypeFormatter {
268         @Override
269         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
270             final IcmpCodeCriterion icmpCodeCriterion =
271                     (IcmpCodeCriterion) criterion;
272             return root.put(CriterionCodec.ICMP_CODE, icmpCodeCriterion.icmpCode());
273         }
274     }
275
276     private static class FormatIpV6FLabel implements CriterionTypeFormatter {
277         @Override
278         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
279             final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
280                     (IPv6FlowLabelCriterion) criterion;
281             return root.put(CriterionCodec.FLOW_LABEL, ipv6FlowLabelCriterion.flowLabel());
282         }
283     }
284
285     private static class FormatIcmpV6Type implements CriterionTypeFormatter {
286         @Override
287         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
288             final Icmpv6TypeCriterion icmpv6TypeCriterion =
289                     (Icmpv6TypeCriterion) criterion;
290             return root.put(CriterionCodec.ICMPV6_TYPE, icmpv6TypeCriterion.icmpv6Type());
291         }
292     }
293
294     private static class FormatIcmpV6Code implements CriterionTypeFormatter {
295         @Override
296         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
297             final Icmpv6CodeCriterion icmpv6CodeCriterion =
298                     (Icmpv6CodeCriterion) criterion;
299             return root.put(CriterionCodec.ICMPV6_CODE, icmpv6CodeCriterion.icmpv6Code());
300         }
301     }
302
303     private static class FormatV6NDTarget implements CriterionTypeFormatter {
304         @Override
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());
309         }
310     }
311
312     private static class FormatV6NDTll implements CriterionTypeFormatter {
313         @Override
314         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
315             final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
316                     = (IPv6NDLinkLayerAddressCriterion) criterion;
317             return root.put(CriterionCodec.MAC, ipv6NDLinkLayerAddressCriterion.mac().toString());
318         }
319     }
320
321     private static class FormatMplsLabel implements CriterionTypeFormatter {
322         @Override
323         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
324             final MplsCriterion mplsCriterion =
325                     (MplsCriterion) criterion;
326             return root.put(CriterionCodec.LABEL, mplsCriterion.label().toInt());
327         }
328     }
329
330     private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
331         @Override
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());
336         }
337     }
338
339     private static class FormatOchSigId implements CriterionTypeFormatter {
340         @Override
341         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
342             OchSignal ochSignal = ((OchSignalCriterion) criterion).lambda();
343             ObjectNode child = root.putObject(CriterionCodec.OCH_SIGNAL_ID);
344
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());
349
350             return root;
351         }
352     }
353
354     private static class FormatOchSigType implements CriterionTypeFormatter {
355         @Override
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());
360         }
361     }
362
363     private static class FormatTunnelId implements CriterionTypeFormatter {
364         @Override
365         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
366             final TunnelIdCriterion tunnelIdCriterion =
367                     (TunnelIdCriterion) criterion;
368             return root.put(CriterionCodec.TUNNEL_ID, tunnelIdCriterion.tunnelId());
369         }
370     }
371
372     private static class FormatOduSignalId implements CriterionTypeFormatter {
373         @Override
374         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
375             OduSignalId oduSignalId = ((OduSignalIdCriterion) criterion).oduSignalId();
376             ObjectNode child = root.putObject(CriterionCodec.ODU_SIGNAL_ID);
377
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()));
381
382             return root;
383         }
384     }
385
386
387     private static class FormatOduSignalType implements CriterionTypeFormatter {
388         @Override
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());
393         }
394     }
395
396     private class FormatDummyType implements CriterionTypeFormatter {
397
398         @Override
399         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
400             checkNotNull(criterion, "Criterion cannot be null");
401
402             return root.put(CriterionCodec.TYPE, criterion.type().toString());
403
404         }
405     }
406
407     /**
408      * Encodes a criterion into a JSON node.
409      *
410      * @return encoded JSON object for the given criterion
411      */
412     public ObjectNode encode() {
413         final ObjectNode result = context.mapper().createObjectNode()
414                 .put(CriterionCodec.TYPE, criterion.type().toString());
415
416         CriterionTypeFormatter formatter =
417                 checkNotNull(
418                         formatMap.get(criterion.type()),
419                         "No formatter found for criterion type "
420                                 + criterion.type().toString());
421
422         return formatter.encodeCriterion(result, criterion);
423     }
424
425 }