a962c0dd527b81207eb74f55233fb8ca31bf60df
[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 java.util.EnumMap;
19
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;
48
49 import com.fasterxml.jackson.databind.node.ObjectNode;
50
51 import static com.google.common.base.Preconditions.checkNotNull;
52
53 /**
54  * Encode portion of the criterion codec.
55  */
56 public final class EncodeCriterionCodecHelper {
57
58     private final Criterion criterion;
59     private final CodecContext context;
60
61     private final EnumMap<Criterion.Type, CriterionTypeFormatter> formatMap;
62
63     /**
64      * Creates an encoder object for a criterion.
65      * Initializes the formatter lookup map for the criterion subclasses.
66      *
67      * @param criterion Criterion to encode
68      * @param context context of the JSON encoding
69      */
70     public EncodeCriterionCodecHelper(Criterion criterion, CodecContext context) {
71         this.criterion = criterion;
72         this.context = context;
73
74         formatMap = new EnumMap<>(Criterion.Type.class);
75
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());
111
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());
126     }
127
128     private interface CriterionTypeFormatter {
129         ObjectNode encodeCriterion(ObjectNode root, Criterion criterion);
130     }
131
132     private static class FormatUnknown implements CriterionTypeFormatter {
133         @Override
134         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
135             return root;
136         }
137     }
138
139     private static class FormatInPort implements CriterionTypeFormatter {
140         @Override
141         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
142             final PortCriterion portCriterion = (PortCriterion) criterion;
143             return root.put(CriterionCodec.PORT, portCriterion.port().toLong());
144         }
145     }
146
147     private static class FormatMetadata implements CriterionTypeFormatter {
148         @Override
149         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
150             final MetadataCriterion metadataCriterion =
151                     (MetadataCriterion) criterion;
152             return root.put(CriterionCodec.METADATA, metadataCriterion.metadata());
153         }
154     }
155
156     private static class FormatEth implements CriterionTypeFormatter {
157         @Override
158         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
159             final EthCriterion ethCriterion = (EthCriterion) criterion;
160             return root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
161         }
162     }
163
164     private static class FormatEthType implements CriterionTypeFormatter {
165         @Override
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());
170         }
171     }
172
173     private static class FormatVlanVid implements CriterionTypeFormatter {
174         @Override
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());
179         }
180     }
181
182     private static class FormatVlanPcp implements CriterionTypeFormatter {
183         @Override
184         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
185             final VlanPcpCriterion vlanPcpCriterion =
186                     (VlanPcpCriterion) criterion;
187             return root.put(CriterionCodec.PRIORITY, vlanPcpCriterion.priority());
188         }
189     }
190
191     private static class FormatIpDscp implements CriterionTypeFormatter {
192         @Override
193         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
194             final IPDscpCriterion ipDscpCriterion =
195                     (IPDscpCriterion) criterion;
196             return root.put(CriterionCodec.IP_DSCP, ipDscpCriterion.ipDscp());
197         }
198     }
199
200     private static class FormatIpEcn implements CriterionTypeFormatter {
201         @Override
202         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
203             final IPEcnCriterion ipEcnCriterion =
204                     (IPEcnCriterion) criterion;
205             return root.put(CriterionCodec.IP_ECN, ipEcnCriterion.ipEcn());
206         }
207     }
208
209     private static class FormatIpProto implements CriterionTypeFormatter {
210         @Override
211         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
212             final IPProtocolCriterion iPProtocolCriterion =
213                     (IPProtocolCriterion) criterion;
214             return root.put(CriterionCodec.PROTOCOL, iPProtocolCriterion.protocol());
215         }
216     }
217
218     private static class FormatIp implements CriterionTypeFormatter {
219         @Override
220         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
221             final IPCriterion iPCriterion = (IPCriterion) criterion;
222             return root.put(CriterionCodec.IP, iPCriterion.ip().toString());
223         }
224     }
225
226     private static class FormatTcp implements CriterionTypeFormatter {
227         @Override
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());
232         }
233     }
234
235     private static class FormatUdp implements CriterionTypeFormatter {
236         @Override
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());
241         }
242     }
243
244     private static class FormatSctp implements CriterionTypeFormatter {
245         @Override
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());
250         }
251     }
252
253     private static class FormatIcmpV4Type implements CriterionTypeFormatter {
254         @Override
255         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
256             final IcmpTypeCriterion icmpTypeCriterion =
257                     (IcmpTypeCriterion) criterion;
258             return root.put(CriterionCodec.ICMP_TYPE, icmpTypeCriterion.icmpType());
259         }
260     }
261
262     private static class FormatIcmpV4Code implements CriterionTypeFormatter {
263         @Override
264         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
265             final IcmpCodeCriterion icmpCodeCriterion =
266                     (IcmpCodeCriterion) criterion;
267             return root.put(CriterionCodec.ICMP_CODE, icmpCodeCriterion.icmpCode());
268         }
269     }
270
271     private static class FormatIpV6FLabel implements CriterionTypeFormatter {
272         @Override
273         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
274             final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
275                     (IPv6FlowLabelCriterion) criterion;
276             return root.put(CriterionCodec.FLOW_LABEL, ipv6FlowLabelCriterion.flowLabel());
277         }
278     }
279
280     private static class FormatIcmpV6Type implements CriterionTypeFormatter {
281         @Override
282         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
283             final Icmpv6TypeCriterion icmpv6TypeCriterion =
284                     (Icmpv6TypeCriterion) criterion;
285             return root.put(CriterionCodec.ICMPV6_TYPE, icmpv6TypeCriterion.icmpv6Type());
286         }
287     }
288
289     private static class FormatIcmpV6Code implements CriterionTypeFormatter {
290         @Override
291         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
292             final Icmpv6CodeCriterion icmpv6CodeCriterion =
293                     (Icmpv6CodeCriterion) criterion;
294             return root.put(CriterionCodec.ICMPV6_CODE, icmpv6CodeCriterion.icmpv6Code());
295         }
296     }
297
298     private static class FormatV6NDTarget implements CriterionTypeFormatter {
299         @Override
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());
304         }
305     }
306
307     private static class FormatV6NDTll implements CriterionTypeFormatter {
308         @Override
309         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
310             final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
311                     = (IPv6NDLinkLayerAddressCriterion) criterion;
312             return root.put(CriterionCodec.MAC, ipv6NDLinkLayerAddressCriterion.mac().toString());
313         }
314     }
315
316     private static class FormatMplsLabel implements CriterionTypeFormatter {
317         @Override
318         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
319             final MplsCriterion mplsCriterion =
320                     (MplsCriterion) criterion;
321             return root.put(CriterionCodec.LABEL, mplsCriterion.label().toInt());
322         }
323     }
324
325     private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
326         @Override
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());
331         }
332     }
333
334     private static class FormatOchSigId implements CriterionTypeFormatter {
335         @Override
336         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
337             OchSignal ochSignal = ((OchSignalCriterion) criterion).lambda();
338             ObjectNode child = root.putObject(CriterionCodec.OCH_SIGNAL_ID);
339
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());
344
345             return root;
346         }
347     }
348
349     private static class FormatOchSigType implements CriterionTypeFormatter {
350         @Override
351         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
352             final OchSignalTypeCriterion ochSignalTypeCriterion =
353                     (OchSignalTypeCriterion) criterion;
354             return root.put("ochSignalType", ochSignalTypeCriterion.signalType().name());
355         }
356     }
357
358     private static class FormatTunnelId implements CriterionTypeFormatter {
359         @Override
360         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
361             final TunnelIdCriterion tunnelIdCriterion =
362                     (TunnelIdCriterion) criterion;
363             return root.put(CriterionCodec.TUNNEL_ID, tunnelIdCriterion.tunnelId());
364         }
365     }
366
367     private class FormatDummyType implements CriterionTypeFormatter {
368
369         @Override
370         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
371             checkNotNull(criterion, "Criterion cannot be null");
372
373             return root.put(CriterionCodec.TYPE, criterion.type().toString());
374
375         }
376     }
377
378     /**
379      * Encodes a criterion into a JSON node.
380      *
381      * @return encoded JSON object for the given criterion
382      */
383     public ObjectNode encode() {
384         final ObjectNode result = context.mapper().createObjectNode()
385                 .put(CriterionCodec.TYPE, criterion.type().toString());
386
387         CriterionTypeFormatter formatter =
388                 checkNotNull(
389                         formatMap.get(criterion.type()),
390                         "No formatter found for criterion type "
391                                 + criterion.type().toString());
392
393         return formatter.encodeCriterion(result, criterion);
394     }
395
396 }