f7af736ed3c5afb439be3ed648a46d0a4219790b
[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.OduSignalIdCriterion;
42 import org.onosproject.net.flow.criteria.OduSignalTypeCriterion;
43 import org.onosproject.net.flow.criteria.PortCriterion;
44 import org.onosproject.net.flow.criteria.SctpPortCriterion;
45 import org.onosproject.net.flow.criteria.TcpPortCriterion;
46 import org.onosproject.net.flow.criteria.TunnelIdCriterion;
47 import org.onosproject.net.flow.criteria.UdpPortCriterion;
48 import org.onosproject.net.flow.criteria.VlanIdCriterion;
49 import org.onosproject.net.flow.criteria.VlanPcpCriterion;
50
51 import com.fasterxml.jackson.databind.node.ObjectNode;
52
53 import static com.google.common.base.Preconditions.checkNotNull;
54
55 /**
56  * Encode portion of the criterion codec.
57  */
58 public final class EncodeCriterionCodecHelper {
59
60     private final Criterion criterion;
61     private final CodecContext context;
62
63     private final EnumMap<Criterion.Type, CriterionTypeFormatter> formatMap;
64
65     /**
66      * Creates an encoder object for a criterion.
67      * Initializes the formatter lookup map for the criterion subclasses.
68      *
69      * @param criterion Criterion to encode
70      * @param context context of the JSON encoding
71      */
72     public EncodeCriterionCodecHelper(Criterion criterion, CodecContext context) {
73         this.criterion = criterion;
74         this.context = context;
75
76         formatMap = new EnumMap<>(Criterion.Type.class);
77
78         formatMap.put(Criterion.Type.IN_PORT, new FormatInPort());
79         formatMap.put(Criterion.Type.IN_PHY_PORT, new FormatInPort());
80         formatMap.put(Criterion.Type.METADATA, new FormatMetadata());
81         formatMap.put(Criterion.Type.ETH_DST, new FormatEth());
82         formatMap.put(Criterion.Type.ETH_SRC, new FormatEth());
83         formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType());
84         formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid());
85         formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp());
86         formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp());
87         formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn());
88         formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto());
89         formatMap.put(Criterion.Type.IPV4_SRC, new FormatIp());
90         formatMap.put(Criterion.Type.IPV4_DST, new FormatIp());
91         formatMap.put(Criterion.Type.TCP_SRC, new FormatTcp());
92         formatMap.put(Criterion.Type.TCP_DST, new FormatTcp());
93         formatMap.put(Criterion.Type.UDP_SRC, new FormatUdp());
94         formatMap.put(Criterion.Type.UDP_DST, new FormatUdp());
95         formatMap.put(Criterion.Type.SCTP_SRC, new FormatSctp());
96         formatMap.put(Criterion.Type.SCTP_DST, new FormatSctp());
97         formatMap.put(Criterion.Type.ICMPV4_TYPE, new FormatIcmpV4Type());
98         formatMap.put(Criterion.Type.ICMPV4_CODE, new FormatIcmpV4Code());
99         formatMap.put(Criterion.Type.IPV6_SRC, new FormatIp());
100         formatMap.put(Criterion.Type.IPV6_DST, new FormatIp());
101         formatMap.put(Criterion.Type.IPV6_FLABEL, new FormatIpV6FLabel());
102         formatMap.put(Criterion.Type.ICMPV6_TYPE, new FormatIcmpV6Type());
103         formatMap.put(Criterion.Type.ICMPV6_CODE, new FormatIcmpV6Code());
104         formatMap.put(Criterion.Type.IPV6_ND_TARGET, new FormatV6NDTarget());
105         formatMap.put(Criterion.Type.IPV6_ND_SLL, new FormatV6NDTll());
106         formatMap.put(Criterion.Type.IPV6_ND_TLL, new FormatV6NDTll());
107         formatMap.put(Criterion.Type.MPLS_LABEL, new FormatMplsLabel());
108         formatMap.put(Criterion.Type.IPV6_EXTHDR, new FormatIpV6Exthdr());
109         formatMap.put(Criterion.Type.OCH_SIGID, new FormatOchSigId());
110         formatMap.put(Criterion.Type.OCH_SIGTYPE, new FormatOchSigType());
111         formatMap.put(Criterion.Type.TUNNEL_ID, new FormatTunnelId());
112         formatMap.put(Criterion.Type.DUMMY, new FormatDummyType());
113         formatMap.put(Criterion.Type.ODU_SIGID, new FormatOduSignalId());
114         formatMap.put(Criterion.Type.ODU_SIGTYPE, new FormatOduSignalType());
115         // Currently unimplemented
116         formatMap.put(Criterion.Type.ARP_OP, new FormatUnknown());
117         formatMap.put(Criterion.Type.ARP_SPA, new FormatUnknown());
118         formatMap.put(Criterion.Type.ARP_TPA, new FormatUnknown());
119         formatMap.put(Criterion.Type.ARP_SHA, new FormatUnknown());
120         formatMap.put(Criterion.Type.ARP_THA, new FormatUnknown());
121         formatMap.put(Criterion.Type.MPLS_TC, new FormatUnknown());
122         formatMap.put(Criterion.Type.MPLS_BOS, new FormatUnknown());
123         formatMap.put(Criterion.Type.PBB_ISID, new FormatUnknown());
124         formatMap.put(Criterion.Type.UNASSIGNED_40, new FormatUnknown());
125         formatMap.put(Criterion.Type.PBB_UCA, new FormatUnknown());
126         formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
127         formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
128         formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
129     }
130
131     private interface CriterionTypeFormatter {
132         ObjectNode encodeCriterion(ObjectNode root, Criterion criterion);
133     }
134
135     private static class FormatUnknown implements CriterionTypeFormatter {
136         @Override
137         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
138             return root;
139         }
140     }
141
142     private static class FormatInPort implements CriterionTypeFormatter {
143         @Override
144         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
145             final PortCriterion portCriterion = (PortCriterion) criterion;
146             return root.put(CriterionCodec.PORT, portCriterion.port().toLong());
147         }
148     }
149
150     private static class FormatMetadata implements CriterionTypeFormatter {
151         @Override
152         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
153             final MetadataCriterion metadataCriterion =
154                     (MetadataCriterion) criterion;
155             return root.put(CriterionCodec.METADATA, metadataCriterion.metadata());
156         }
157     }
158
159     private static class FormatEth implements CriterionTypeFormatter {
160         @Override
161         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
162             final EthCriterion ethCriterion = (EthCriterion) criterion;
163             return root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
164         }
165     }
166
167     private static class FormatEthType implements CriterionTypeFormatter {
168         @Override
169         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
170             final EthTypeCriterion ethTypeCriterion =
171                     (EthTypeCriterion) criterion;
172             return root.put(CriterionCodec.ETH_TYPE, ethTypeCriterion.ethType().toShort());
173         }
174     }
175
176     private static class FormatVlanVid implements CriterionTypeFormatter {
177         @Override
178         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
179             final VlanIdCriterion vlanIdCriterion =
180                     (VlanIdCriterion) criterion;
181             return root.put(CriterionCodec.VLAN_ID, vlanIdCriterion.vlanId().toShort());
182         }
183     }
184
185     private static class FormatVlanPcp implements CriterionTypeFormatter {
186         @Override
187         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
188             final VlanPcpCriterion vlanPcpCriterion =
189                     (VlanPcpCriterion) criterion;
190             return root.put(CriterionCodec.PRIORITY, vlanPcpCriterion.priority());
191         }
192     }
193
194     private static class FormatIpDscp implements CriterionTypeFormatter {
195         @Override
196         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
197             final IPDscpCriterion ipDscpCriterion =
198                     (IPDscpCriterion) criterion;
199             return root.put(CriterionCodec.IP_DSCP, ipDscpCriterion.ipDscp());
200         }
201     }
202
203     private static class FormatIpEcn implements CriterionTypeFormatter {
204         @Override
205         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
206             final IPEcnCriterion ipEcnCriterion =
207                     (IPEcnCriterion) criterion;
208             return root.put(CriterionCodec.IP_ECN, ipEcnCriterion.ipEcn());
209         }
210     }
211
212     private static class FormatIpProto implements CriterionTypeFormatter {
213         @Override
214         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
215             final IPProtocolCriterion iPProtocolCriterion =
216                     (IPProtocolCriterion) criterion;
217             return root.put(CriterionCodec.PROTOCOL, iPProtocolCriterion.protocol());
218         }
219     }
220
221     private static class FormatIp implements CriterionTypeFormatter {
222         @Override
223         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
224             final IPCriterion iPCriterion = (IPCriterion) criterion;
225             return root.put(CriterionCodec.IP, iPCriterion.ip().toString());
226         }
227     }
228
229     private static class FormatTcp implements CriterionTypeFormatter {
230         @Override
231         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
232             final TcpPortCriterion tcpPortCriterion =
233                     (TcpPortCriterion) criterion;
234             return root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
235         }
236     }
237
238     private static class FormatUdp implements CriterionTypeFormatter {
239         @Override
240         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
241             final UdpPortCriterion udpPortCriterion =
242                     (UdpPortCriterion) criterion;
243             return root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
244         }
245     }
246
247     private static class FormatSctp implements CriterionTypeFormatter {
248         @Override
249         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
250             final SctpPortCriterion sctpPortCriterion =
251                     (SctpPortCriterion) criterion;
252             return root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
253         }
254     }
255
256     private static class FormatIcmpV4Type implements CriterionTypeFormatter {
257         @Override
258         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
259             final IcmpTypeCriterion icmpTypeCriterion =
260                     (IcmpTypeCriterion) criterion;
261             return root.put(CriterionCodec.ICMP_TYPE, icmpTypeCriterion.icmpType());
262         }
263     }
264
265     private static class FormatIcmpV4Code implements CriterionTypeFormatter {
266         @Override
267         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
268             final IcmpCodeCriterion icmpCodeCriterion =
269                     (IcmpCodeCriterion) criterion;
270             return root.put(CriterionCodec.ICMP_CODE, icmpCodeCriterion.icmpCode());
271         }
272     }
273
274     private static class FormatIpV6FLabel implements CriterionTypeFormatter {
275         @Override
276         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
277             final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
278                     (IPv6FlowLabelCriterion) criterion;
279             return root.put(CriterionCodec.FLOW_LABEL, ipv6FlowLabelCriterion.flowLabel());
280         }
281     }
282
283     private static class FormatIcmpV6Type implements CriterionTypeFormatter {
284         @Override
285         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
286             final Icmpv6TypeCriterion icmpv6TypeCriterion =
287                     (Icmpv6TypeCriterion) criterion;
288             return root.put(CriterionCodec.ICMPV6_TYPE, icmpv6TypeCriterion.icmpv6Type());
289         }
290     }
291
292     private static class FormatIcmpV6Code implements CriterionTypeFormatter {
293         @Override
294         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
295             final Icmpv6CodeCriterion icmpv6CodeCriterion =
296                     (Icmpv6CodeCriterion) criterion;
297             return root.put(CriterionCodec.ICMPV6_CODE, icmpv6CodeCriterion.icmpv6Code());
298         }
299     }
300
301     private static class FormatV6NDTarget implements CriterionTypeFormatter {
302         @Override
303         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
304             final IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
305                     = (IPv6NDTargetAddressCriterion) criterion;
306             return root.put(CriterionCodec.TARGET_ADDRESS, ipv6NDTargetAddressCriterion.targetAddress().toString());
307         }
308     }
309
310     private static class FormatV6NDTll implements CriterionTypeFormatter {
311         @Override
312         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
313             final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
314                     = (IPv6NDLinkLayerAddressCriterion) criterion;
315             return root.put(CriterionCodec.MAC, ipv6NDLinkLayerAddressCriterion.mac().toString());
316         }
317     }
318
319     private static class FormatMplsLabel implements CriterionTypeFormatter {
320         @Override
321         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
322             final MplsCriterion mplsCriterion =
323                     (MplsCriterion) criterion;
324             return root.put(CriterionCodec.LABEL, mplsCriterion.label().toInt());
325         }
326     }
327
328     private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
329         @Override
330         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
331             final IPv6ExthdrFlagsCriterion exthdrCriterion =
332                     (IPv6ExthdrFlagsCriterion) criterion;
333             return root.put(CriterionCodec.EXT_HDR_FLAGS, exthdrCriterion.exthdrFlags());
334         }
335     }
336
337     private static class FormatOchSigId implements CriterionTypeFormatter {
338         @Override
339         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
340             OchSignal ochSignal = ((OchSignalCriterion) criterion).lambda();
341             ObjectNode child = root.putObject(CriterionCodec.OCH_SIGNAL_ID);
342
343             child.put(CriterionCodec.GRID_TYPE, ochSignal.gridType().name());
344             child.put(CriterionCodec.CHANNEL_SPACING, ochSignal.channelSpacing().name());
345             child.put(CriterionCodec.SPACING_MULIPLIER, ochSignal.spacingMultiplier());
346             child.put(CriterionCodec.SLOT_GRANULARITY, ochSignal.slotGranularity());
347
348             return root;
349         }
350     }
351
352     private static class FormatOchSigType implements CriterionTypeFormatter {
353         @Override
354         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
355             final OchSignalTypeCriterion ochSignalTypeCriterion =
356                     (OchSignalTypeCriterion) criterion;
357             return root.put(CriterionCodec.OCH_SIGNAL_TYPE, ochSignalTypeCriterion.signalType().name());
358         }
359     }
360
361     private static class FormatTunnelId implements CriterionTypeFormatter {
362         @Override
363         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
364             final TunnelIdCriterion tunnelIdCriterion =
365                     (TunnelIdCriterion) criterion;
366             return root.put(CriterionCodec.TUNNEL_ID, tunnelIdCriterion.tunnelId());
367         }
368     }
369
370     private static class FormatOduSignalId implements CriterionTypeFormatter {
371         @Override
372         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
373             final OduSignalIdCriterion oduSignalIdCriterion =
374                     (OduSignalIdCriterion) criterion;
375             return root.put(CriterionCodec.ODU_SIGNAL_ID, oduSignalIdCriterion.oduSignalId().toString());
376         }
377     }
378
379     private static class FormatOduSignalType implements CriterionTypeFormatter {
380         @Override
381         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
382             final OduSignalTypeCriterion oduSignalTypeCriterion =
383                     (OduSignalTypeCriterion) criterion;
384             return root.put(CriterionCodec.ODU_SIGNAL_TYPE, oduSignalTypeCriterion.signalType().name());
385         }
386     }
387
388     private class FormatDummyType implements CriterionTypeFormatter {
389
390         @Override
391         public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
392             checkNotNull(criterion, "Criterion cannot be null");
393
394             return root.put(CriterionCodec.TYPE, criterion.type().toString());
395
396         }
397     }
398
399     /**
400      * Encodes a criterion into a JSON node.
401      *
402      * @return encoded JSON object for the given criterion
403      */
404     public ObjectNode encode() {
405         final ObjectNode result = context.mapper().createObjectNode()
406                 .put(CriterionCodec.TYPE, criterion.type().toString());
407
408         CriterionTypeFormatter formatter =
409                 checkNotNull(
410                         formatMap.get(criterion.type()),
411                         "No formatter found for criterion type "
412                                 + criterion.type().toString());
413
414         return formatter.encodeCriterion(result, criterion);
415     }
416
417 }