blob: 9113124c1c00ac6ff0c790e5e38c317d4d0adf41 [file] [log] [blame]
Ray Milkeydb358082015-01-13 16:34:38 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Ray Milkeydb358082015-01-13 16:34:38 -08003 *
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 */
16package org.onosproject.codec.impl;
17
Frank Wang74ce2c12018-04-11 20:26:45 +080018import java.util.Collection;
Yafit Hadar5796d972015-10-15 13:16:11 +030019import java.util.Objects;
20
Ray Milkeydb358082015-01-13 16:34:38 -080021import org.hamcrest.Description;
22import org.hamcrest.TypeSafeDiagnosingMatcher;
Yafit Hadar5796d972015-10-15 13:16:11 +030023import org.onlab.util.HexString;
Sho SHIMIZUc44c0c32015-06-01 11:40:48 -070024import org.onosproject.net.OchSignal;
Yafit Hadar5796d972015-10-15 13:16:11 +030025import org.onosproject.net.OduSignalId;
Ray Milkeydb358082015-01-13 16:34:38 -080026import org.onosproject.net.flow.criteria.Criterion;
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -070027import org.onosproject.net.flow.criteria.EthCriterion;
28import org.onosproject.net.flow.criteria.EthTypeCriterion;
29import org.onosproject.net.flow.criteria.IPCriterion;
30import org.onosproject.net.flow.criteria.IPDscpCriterion;
31import org.onosproject.net.flow.criteria.IPEcnCriterion;
32import org.onosproject.net.flow.criteria.IPProtocolCriterion;
33import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
34import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
35import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
36import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
37import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
38import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
39import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
40import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -070041import org.onosproject.net.flow.criteria.MetadataCriterion;
42import org.onosproject.net.flow.criteria.MplsCriterion;
Sho SHIMIZUc44c0c32015-06-01 11:40:48 -070043import org.onosproject.net.flow.criteria.OchSignalCriterion;
Sho SHIMIZU6c70f642015-05-29 17:27:22 -070044import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
Yafit Hadar5796d972015-10-15 13:16:11 +030045import org.onosproject.net.flow.criteria.OduSignalIdCriterion;
46import org.onosproject.net.flow.criteria.OduSignalTypeCriterion;
Frank Wang74ce2c12018-04-11 20:26:45 +080047import org.onosproject.net.flow.criteria.PiCriterion;
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -070048import org.onosproject.net.flow.criteria.PortCriterion;
49import org.onosproject.net.flow.criteria.SctpPortCriterion;
50import org.onosproject.net.flow.criteria.TcpPortCriterion;
51import org.onosproject.net.flow.criteria.UdpPortCriterion;
52import org.onosproject.net.flow.criteria.VlanIdCriterion;
53import org.onosproject.net.flow.criteria.VlanPcpCriterion;
Ray Milkeydb358082015-01-13 16:34:38 -080054
Yafit Hadar5796d972015-10-15 13:16:11 +030055import com.fasterxml.jackson.databind.JsonNode;
56import com.google.common.base.Joiner;
Frank Wang74ce2c12018-04-11 20:26:45 +080057import org.onosproject.net.pi.runtime.PiExactFieldMatch;
58import org.onosproject.net.pi.runtime.PiFieldMatch;
59import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +010060import org.onosproject.net.pi.runtime.PiOptionalFieldMatch;
Frank Wang74ce2c12018-04-11 20:26:45 +080061import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
62import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
Frank Wang74ce2c12018-04-11 20:26:45 +080063
64import static org.onlab.util.ImmutableByteSequence.copyFrom;
Sho SHIMIZUc44c0c32015-06-01 11:40:48 -070065
Ray Milkeydb358082015-01-13 16:34:38 -080066/**
67 * Hamcrest matcher for criterion objects.
68 */
Ray Milkey46670a82015-02-08 17:57:17 -080069public final class CriterionJsonMatcher extends
70 TypeSafeDiagnosingMatcher<JsonNode> {
Ray Milkeydb358082015-01-13 16:34:38 -080071
72 final Criterion criterion;
Ray Milkey46670a82015-02-08 17:57:17 -080073 Description description;
74 JsonNode jsonCriterion;
Ray Milkeydb358082015-01-13 16:34:38 -080075
Ray Milkey46670a82015-02-08 17:57:17 -080076 /**
77 * Constructs a matcher object.
78 *
79 * @param criterionValue criterion to match
80 */
Ray Milkeydb358082015-01-13 16:34:38 -080081 private CriterionJsonMatcher(Criterion criterionValue) {
82 criterion = criterionValue;
83 }
84
Ray Milkey46670a82015-02-08 17:57:17 -080085 /**
86 * Factory to allocate an criterion matcher.
87 *
88 * @param criterion criterion object we are looking for
89 * @return matcher
90 */
91 public static CriterionJsonMatcher matchesCriterion(Criterion criterion) {
92 return new CriterionJsonMatcher(criterion);
93 }
94
95 /**
96 * Matches a port criterion object.
97 *
98 * @param criterion criterion to match
99 * @return true if the JSON matches the criterion, false otherwise.
100 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700101 private boolean matchCriterion(PortCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800102 final long port = criterion.port().toLong();
103 final long jsonPort = jsonCriterion.get("port").asLong();
104 if (port != jsonPort) {
105 description.appendText("port was " + Long.toString(jsonPort));
106 return false;
107 }
108 return true;
109 }
110
111 /**
112 * Matches a metadata criterion object.
113 *
114 * @param criterion criterion to match
115 * @return true if the JSON matches the criterion, false otherwise.
116 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700117 private boolean matchCriterion(MetadataCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800118 final long metadata = criterion.metadata();
119 final long jsonMetadata = jsonCriterion.get("metadata").asLong();
120 if (metadata != jsonMetadata) {
121 description.appendText("metadata was "
122 + Long.toString(jsonMetadata));
123 return false;
124 }
125 return true;
126 }
127
128 /**
129 * Matches an eth criterion object.
130 *
131 * @param criterion criterion to match
132 * @return true if the JSON matches the criterion, false otherwise.
133 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700134 private boolean matchCriterion(EthCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800135 final String mac = criterion.mac().toString();
136 final String jsonMac = jsonCriterion.get("mac").textValue();
137 if (!mac.equals(jsonMac)) {
138 description.appendText("mac was " + jsonMac);
139 return false;
140 }
David Glantz6210c4c2021-09-21 15:39:19 -0500141 if (criterion.type() == Criterion.Type.ETH_SRC_MASKED || criterion.type() == Criterion.Type.ETH_DST_MASKED) {
Seyeon Jeong8f014142020-02-26 12:51:03 -0800142 final String macMask = criterion.mask().toString();
143 final String jsonMacMask = jsonCriterion.get("macMask").textValue();
144 if (!macMask.equals(jsonMacMask)) {
145 description.appendText("macMask was " + jsonMacMask);
146 return false;
147 }
148 }
Ray Milkey46670a82015-02-08 17:57:17 -0800149 return true;
150 }
151
152 /**
153 * Matches an eth type criterion object.
154 *
155 * @param criterion criterion to match
156 * @return true if the JSON matches the criterion, false otherwise.
157 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700158 private boolean matchCriterion(EthTypeCriterion criterion) {
andread35f89c2015-11-23 10:02:07 -0800159 final int ethType = criterion.ethType().toShort() & 0xffff;
160 final int jsonEthType = Integer.decode(jsonCriterion.get("ethType").textValue()) & 0xffff;
Ray Milkey46670a82015-02-08 17:57:17 -0800161 if (ethType != jsonEthType) {
162 description.appendText("ethType was "
163 + Integer.toString(jsonEthType));
164 return false;
165 }
166 return true;
167 }
168
169 /**
170 * Matches a VLAN ID criterion object.
171 *
172 * @param criterion criterion to match
173 * @return true if the JSON matches the criterion, false otherwise.
174 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700175 private boolean matchCriterion(VlanIdCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800176 final short vlanId = criterion.vlanId().toShort();
177 final short jsonVlanId = jsonCriterion.get("vlanId").shortValue();
178 if (vlanId != jsonVlanId) {
179 description.appendText("vlanId was " + Short.toString(jsonVlanId));
180 return false;
181 }
182 return true;
183 }
184
185 /**
186 * Matches a VLAN PCP criterion object.
187 *
188 * @param criterion criterion to match
189 * @return true if the JSON matches the criterion, false otherwise.
190 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700191 private boolean matchCriterion(VlanPcpCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800192 final byte priority = criterion.priority();
193 final byte jsonPriority =
194 (byte) jsonCriterion.get("priority").shortValue();
195 if (priority != jsonPriority) {
196 description.appendText("priority was " + Byte.toString(jsonPriority));
197 return false;
198 }
199 return true;
200 }
201
202 /**
203 * Matches an IP DSCP criterion object.
204 *
205 * @param criterion criterion to match
206 * @return true if the JSON matches the criterion, false otherwise.
207 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700208 private boolean matchCriterion(IPDscpCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800209 final byte ipDscp = criterion.ipDscp();
210 final byte jsonIpDscp = (byte) jsonCriterion.get("ipDscp").shortValue();
211 if (ipDscp != jsonIpDscp) {
212 description.appendText("IP DSCP was " + Byte.toString(jsonIpDscp));
213 return false;
214 }
215 return true;
216 }
217
218 /**
219 * Matches an IP ECN criterion object.
220 *
221 * @param criterion criterion to match
222 * @return true if the JSON matches the criterion, false otherwise.
223 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700224 private boolean matchCriterion(IPEcnCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800225 final byte ipEcn = criterion.ipEcn();
226 final byte jsonIpEcn = (byte) jsonCriterion.get("ipEcn").shortValue();
227 if (ipEcn != jsonIpEcn) {
228 description.appendText("IP ECN was " + Byte.toString(jsonIpEcn));
229 return false;
230 }
231 return true;
232 }
233
234 /**
235 * Matches an IP protocol criterion object.
236 *
237 * @param criterion criterion to match
238 * @return true if the JSON matches the criterion, false otherwise.
239 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700240 private boolean matchCriterion(IPProtocolCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800241 final short protocol = criterion.protocol();
242 final short jsonProtocol = jsonCriterion.get("protocol").shortValue();
243 if (protocol != jsonProtocol) {
244 description.appendText("protocol was "
245 + Short.toString(jsonProtocol));
246 return false;
247 }
248 return true;
249 }
250
251 /**
252 * Matches an IP address criterion object.
253 *
254 * @param criterion criterion to match
255 * @return true if the JSON matches the criterion, false otherwise.
256 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700257 private boolean matchCriterion(IPCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800258 final String ip = criterion.ip().toString();
259 final String jsonIp = jsonCriterion.get("ip").textValue();
260 if (!ip.equals(jsonIp)) {
261 description.appendText("ip was " + jsonIp);
262 return false;
263 }
264 return true;
265 }
266
267 /**
268 * Matches a TCP port criterion object.
269 *
270 * @param criterion criterion to match
271 * @return true if the JSON matches the criterion, false otherwise.
272 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700273 private boolean matchCriterion(TcpPortCriterion criterion) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700274 final int tcpPort = criterion.tcpPort().toInt();
Ray Milkey46670a82015-02-08 17:57:17 -0800275 final int jsonTcpPort = jsonCriterion.get("tcpPort").intValue();
276 if (tcpPort != jsonTcpPort) {
277 description.appendText("tcp port was "
278 + Integer.toString(jsonTcpPort));
279 return false;
280 }
David Glantz6210c4c2021-09-21 15:39:19 -0500281 if (criterion.type() == Criterion.Type.TCP_SRC_MASKED || criterion.type() == Criterion.Type.TCP_DST_MASKED) {
282 final int tcpMask = criterion.mask().toInt();
283 final int jsonTcpMask = jsonCriterion.get("tcpMask").intValue();
284 if (tcpMask != jsonTcpMask) {
285 description.appendText("tcp mask was "
286 + Integer.toString(jsonTcpMask));
287 return false;
288 }
289 }
Ray Milkey46670a82015-02-08 17:57:17 -0800290 return true;
291 }
292
293 /**
294 * Matches a UDP port criterion object.
295 *
296 * @param criterion criterion to match
297 * @return true if the JSON matches the criterion, false otherwise.
298 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700299 private boolean matchCriterion(UdpPortCriterion criterion) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700300 final int udpPort = criterion.udpPort().toInt();
Ray Milkey46670a82015-02-08 17:57:17 -0800301 final int jsonUdpPort = jsonCriterion.get("udpPort").intValue();
302 if (udpPort != jsonUdpPort) {
303 description.appendText("udp port was "
304 + Integer.toString(jsonUdpPort));
305 return false;
306 }
David Glantz6210c4c2021-09-21 15:39:19 -0500307
308 if (criterion.type() == Criterion.Type.UDP_SRC_MASKED || criterion.type() == Criterion.Type.UDP_DST_MASKED) {
309 final int udpMask = criterion.mask().toInt();
310 final int jsonUdpMask = jsonCriterion.get("udpMask").intValue();
311 if (udpMask != jsonUdpMask) {
312 description.appendText("udp mask was "
313 + Integer.toString(jsonUdpMask));
314 return false;
315 }
316 }
Ray Milkey46670a82015-02-08 17:57:17 -0800317 return true;
318 }
319
320 /**
321 * Matches an SCTP port criterion object.
322 *
323 * @param criterion criterion to match
324 * @return true if the JSON matches the criterion, false otherwise.
325 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700326 private boolean matchCriterion(SctpPortCriterion criterion) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700327 final int sctpPort = criterion.sctpPort().toInt();
Ray Milkey46670a82015-02-08 17:57:17 -0800328 final int jsonSctpPort = jsonCriterion.get("sctpPort").intValue();
329 if (sctpPort != jsonSctpPort) {
330 description.appendText("sctp port was "
331 + Integer.toString(jsonSctpPort));
332 return false;
333 }
David Glantz6210c4c2021-09-21 15:39:19 -0500334 if (criterion.type() == Criterion.Type.SCTP_SRC_MASKED || criterion.type() == Criterion.Type.SCTP_DST_MASKED) {
335 final int sctpMask = criterion.mask().toInt();
336 final int jsonSctpMask = jsonCriterion.get("sctpMask").intValue();
337 if (sctpMask != jsonSctpMask) {
338 description.appendText("sctp mask was "
339 + Integer.toString(jsonSctpMask));
340 return false;
341 }
342 }
Ray Milkey46670a82015-02-08 17:57:17 -0800343 return true;
344 }
345
346 /**
347 * Matches an ICMP type criterion object.
348 *
349 * @param criterion criterion to match
350 * @return true if the JSON matches the criterion, false otherwise.
351 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700352 private boolean matchCriterion(IcmpTypeCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800353 final short icmpType = criterion.icmpType();
354 final short jsonIcmpType = jsonCriterion.get("icmpType").shortValue();
355 if (icmpType != jsonIcmpType) {
356 description.appendText("icmp type was "
357 + Short.toString(jsonIcmpType));
358 return false;
359 }
360 return true;
361 }
362
363 /**
364 * Matches an ICMP code criterion object.
365 *
366 * @param criterion criterion to match
367 * @return true if the JSON matches the criterion, false otherwise.
368 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700369 private boolean matchCriterion(IcmpCodeCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800370 final short icmpCode = criterion.icmpCode();
371 final short jsonIcmpCode = jsonCriterion.get("icmpCode").shortValue();
372 if (icmpCode != jsonIcmpCode) {
373 description.appendText("icmp code was "
374 + Short.toString(jsonIcmpCode));
375 return false;
376 }
377 return true;
378 }
379
380 /**
381 * Matches an IPV6 flow label criterion object.
382 *
383 * @param criterion criterion to match
384 * @return true if the JSON matches the criterion, false otherwise.
385 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700386 private boolean matchCriterion(IPv6FlowLabelCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800387 final int flowLabel = criterion.flowLabel();
388 final int jsonFlowLabel = jsonCriterion.get("flowLabel").intValue();
389 if (flowLabel != jsonFlowLabel) {
390 description.appendText("IPv6 flow label was "
391 + Integer.toString(jsonFlowLabel));
392 return false;
393 }
394 return true;
395 }
396
397 /**
398 * Matches an ICMP V6 type criterion object.
399 *
400 * @param criterion criterion to match
401 * @return true if the JSON matches the criterion, false otherwise.
402 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700403 private boolean matchCriterion(Icmpv6TypeCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800404 final short icmpv6Type = criterion.icmpv6Type();
405 final short jsonIcmpv6Type =
406 jsonCriterion.get("icmpv6Type").shortValue();
407 if (icmpv6Type != jsonIcmpv6Type) {
408 description.appendText("icmpv6 type was "
409 + Short.toString(jsonIcmpv6Type));
410 return false;
411 }
412 return true;
413 }
414
415 /**
416 * Matches an IPV6 code criterion object.
417 *
418 * @param criterion criterion to match
419 * @return true if the JSON matches the criterion, false otherwise.
420 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700421 private boolean matchCriterion(Icmpv6CodeCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800422 final short icmpv6Code = criterion.icmpv6Code();
423 final short jsonIcmpv6Code =
424 jsonCriterion.get("icmpv6Code").shortValue();
425 if (icmpv6Code != jsonIcmpv6Code) {
426 description.appendText("icmpv6 code was "
427 + Short.toString(jsonIcmpv6Code));
428 return false;
429 }
430 return true;
431 }
432
433 /**
434 * Matches an IPV6 ND target criterion object.
435 *
436 * @param criterion criterion to match
437 * @return true if the JSON matches the criterion, false otherwise.
438 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700439 private boolean matchCriterion(IPv6NDTargetAddressCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800440 final String targetAddress =
441 criterion.targetAddress().toString();
442 final String jsonTargetAddress =
443 jsonCriterion.get("targetAddress").textValue();
444 if (!targetAddress.equals(jsonTargetAddress)) {
445 description.appendText("target address was " +
446 jsonTargetAddress);
447 return false;
448 }
449 return true;
450 }
451
452 /**
453 * Matches an IPV6 ND link layer criterion object.
454 *
455 * @param criterion criterion to match
456 * @return true if the JSON matches the criterion, false otherwise.
457 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700458 private boolean matchCriterion(IPv6NDLinkLayerAddressCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800459 final String llAddress =
460 criterion.mac().toString();
461 final String jsonLlAddress =
462 jsonCriterion.get("mac").textValue();
463 if (!llAddress.equals(jsonLlAddress)) {
464 description.appendText("mac was " + jsonLlAddress);
465 return false;
466 }
467 return true;
468 }
469
470 /**
471 * Matches an MPLS label criterion object.
472 *
473 * @param criterion criterion to match
474 * @return true if the JSON matches the criterion, false otherwise.
475 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700476 private boolean matchCriterion(MplsCriterion criterion) {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100477 final int label = criterion.label().toInt();
Ray Milkey46670a82015-02-08 17:57:17 -0800478 final int jsonLabel = jsonCriterion.get("label").intValue();
479 if (label != jsonLabel) {
480 description.appendText("label was " + Integer.toString(jsonLabel));
481 return false;
482 }
483 return true;
484 }
485
486 /**
487 * Matches an IPV6 exthdr criterion object.
488 *
489 * @param criterion criterion to match
490 * @return true if the JSON matches the criterion, false otherwise.
491 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700492 private boolean matchCriterion(IPv6ExthdrFlagsCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800493 final int exthdrFlags = criterion.exthdrFlags();
494 final int jsonExthdrFlags =
495 jsonCriterion.get("exthdrFlags").intValue();
496 if (exthdrFlags != jsonExthdrFlags) {
497 description.appendText("exthdrFlags was "
498 + Long.toHexString(jsonExthdrFlags));
499 return false;
500 }
501 return true;
502 }
503
504 /**
Sho SHIMIZUc44c0c32015-06-01 11:40:48 -0700505 * Matches an Och signal criterion object.
Ray Milkey46670a82015-02-08 17:57:17 -0800506 *
507 * @param criterion criterion to match
508 * @return true if the JSON matches the criterion, false otherwise.
509 */
Sho SHIMIZUc44c0c32015-06-01 11:40:48 -0700510 private boolean matchCriterion(OchSignalCriterion criterion) {
511 final OchSignal ochSignal = criterion.lambda();
512 final JsonNode jsonOchSignal = jsonCriterion.get("ochSignalId");
513 String jsonGridType = jsonOchSignal.get("gridType").textValue();
514 String jsonChannelSpacing = jsonOchSignal.get("channelSpacing").textValue();
515 int jsonSpacingMultiplier = jsonOchSignal.get("spacingMultiplier").intValue();
516 int jsonSlotGranularity = jsonOchSignal.get("slotGranularity").intValue();
517
518 boolean equality = Objects.equals(ochSignal.gridType().name(), jsonGridType)
519 && Objects.equals(ochSignal.channelSpacing().name(), jsonChannelSpacing)
520 && Objects.equals(ochSignal.spacingMultiplier(), jsonSpacingMultiplier)
521 && Objects.equals(ochSignal.slotGranularity(), jsonSlotGranularity);
522
523 if (!equality) {
524 String joined = Joiner.on(", ")
525 .join(jsonGridType, jsonChannelSpacing, jsonSpacingMultiplier, jsonSlotGranularity);
526
527 description.appendText("och signal id was " + joined);
Ray Milkey46670a82015-02-08 17:57:17 -0800528 return false;
529 }
530 return true;
531 }
532
533 /**
Sho SHIMIZU68b8c1f2015-05-29 18:42:26 -0700534 * Matches an Och signal type criterion object.
Ray Milkey46670a82015-02-08 17:57:17 -0800535 *
536 * @param criterion criterion to match
537 * @return true if the JSON matches the criterion, false otherwise.
538 */
Sho SHIMIZU6c70f642015-05-29 17:27:22 -0700539 private boolean matchCriterion(OchSignalTypeCriterion criterion) {
540 final String signalType = criterion.signalType().name();
541 final String jsonSignalType = jsonCriterion.get("ochSignalType").textValue();
542 if (!signalType.equals(jsonSignalType)) {
Sho SHIMIZUc06966e2015-06-01 12:14:37 -0700543 description.appendText("signal type was " + jsonSignalType);
Ray Milkey46670a82015-02-08 17:57:17 -0800544 return false;
545 }
546 return true;
547 }
548
Yafit Hadar5796d972015-10-15 13:16:11 +0300549 /**
550 * Matches an ODU signal ID criterion object.
551 *
552 * @param criterion criterion to match
553 * @return true if the JSON matches the criterion, false otherwise.
554 */
555 private boolean matchCriterion(OduSignalIdCriterion criterion) {
556 final OduSignalId oduSignal = criterion.oduSignalId();
557 final JsonNode jsonOduSignal = jsonCriterion.get(CriterionCodec.ODU_SIGNAL_ID);
558 int jsonTpn = jsonOduSignal.get(CriterionCodec.TRIBUTARY_PORT_NUMBER).intValue();
559 int jsonTsLen = jsonOduSignal.get(CriterionCodec.TRIBUTARY_SLOT_LEN).intValue();
560 byte[] jsonTributaryBitMap = HexString.fromHexString(
561 jsonOduSignal.get(CriterionCodec.TRIBUTARY_SLOT_BITMAP).asText());
562 OduSignalId jsonOduSignalId = OduSignalId.oduSignalId(jsonTpn, jsonTsLen, jsonTributaryBitMap);
563 if (!oduSignal.equals(jsonOduSignalId)) {
564 description.appendText("oduSignalId was " + criterion);
565 return false;
566 }
567 return true;
568 }
569
570 /**
571 * Matches an ODU signal Type criterion object.
572 *
573 * @param criterion criterion to match
574 * @return true if the JSON matches the criterion, false otherwise.
575 */
576 private boolean matchCriterion(OduSignalTypeCriterion criterion) {
577 final String signalType = criterion.signalType().name();
578 final String jsonOduSignalType = jsonCriterion.get("oduSignalType").textValue();
579 if (!signalType.equals(jsonOduSignalType)) {
580 description.appendText("signalType was " + signalType);
581 return false;
582 }
583 return true;
584 }
585
Frank Wang74ce2c12018-04-11 20:26:45 +0800586 /**
587 * Matches a protocol-independent Type criterion object.
588 *
589 * @param criterion criterion to match
590 * @return true if the JSON matches the criterion, false otherwise.
591 */
592 private boolean matchCriterion(PiCriterion criterion) {
593 Collection<PiFieldMatch> piFieldMatches = criterion.fieldMatches();
594 JsonNode jsonMathes = jsonCriterion.get("matches");
595 if (!jsonMathes.isArray()) {
596 return false;
597 }
598 for (JsonNode matchNode : jsonMathes) {
599 for (PiFieldMatch fieldMatch : piFieldMatches) {
600
601 if (!Objects.equals(matchNode.get("field").textValue(), fieldMatch.fieldId().id())) {
602 description.appendText("match field was " + fieldMatch.fieldId().id());
603 return false;
604 }
605
606 if (!Objects.equals(matchNode.get("match").textValue(),
607 fieldMatch.type().name().toLowerCase())) {
608 description.appendText("match type was " + fieldMatch.type().name().toLowerCase());
609 return false;
610 }
611
612 switch (fieldMatch.type()) {
613 case EXACT:
614 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value")
615 .textValue(), null)),
616 ((PiExactFieldMatch) fieldMatch).value())) {
617 description.appendText("match value was " + ((PiExactFieldMatch) fieldMatch).value());
618 return false;
619 }
620 break;
621 case LPM:
622 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value")
623 .textValue(), null)),
624 ((PiLpmFieldMatch) fieldMatch).value())) {
625 description.appendText("match value was " + ((PiLpmFieldMatch) fieldMatch).value());
626 return false;
627 }
628 if (!Objects.equals(matchNode.get("prefixLength").intValue(),
629 ((PiLpmFieldMatch) fieldMatch).prefixLength())) {
630 description.appendText("match prefix was " +
631 ((PiLpmFieldMatch) fieldMatch).prefixLength());
632 return false;
633 }
634 break;
635 case TERNARY:
636 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value")
637 .textValue(), null)),
638 ((PiTernaryFieldMatch) fieldMatch).value())) {
639 description.appendText("match value was " + ((PiTernaryFieldMatch) fieldMatch).value());
640 return false;
641 }
642 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("mask")
643 .textValue(), null)),
644 ((PiTernaryFieldMatch) fieldMatch).mask())) {
645 description.appendText("match mask was " + ((PiTernaryFieldMatch) fieldMatch).mask());
646 return false;
647 }
648 break;
649 case RANGE:
650 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("highValue")
651 .textValue(), null)),
652 ((PiRangeFieldMatch) fieldMatch).highValue())) {
653 description.appendText("match high value was " +
654 ((PiRangeFieldMatch) fieldMatch).highValue());
655 return false;
656 }
657 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("lowValue")
658 .textValue(), null)),
659 ((PiRangeFieldMatch) fieldMatch).lowValue())) {
660 description.appendText("match low value was " +
661 ((PiRangeFieldMatch) fieldMatch).lowValue());
662 return false;
663 }
664 break;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100665 case OPTIONAL:
666 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value")
667 .textValue(), null)),
668 ((PiOptionalFieldMatch) fieldMatch).value())) {
669 description.appendText("match value was " + ((PiOptionalFieldMatch) fieldMatch).value());
670 return false;
671 }
672 break;
Frank Wang74ce2c12018-04-11 20:26:45 +0800673 default:
674 description.appendText("match type was " + fieldMatch.type().name().toLowerCase());
675 return false;
676 }
677 }
678 }
679
680 return true;
681 }
Yafit Hadar5796d972015-10-15 13:16:11 +0300682
Ray Milkeydb358082015-01-13 16:34:38 -0800683 @Override
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800684 public boolean matchesSafely(JsonNode jsonCriterion,
685 Description description) {
Ray Milkey46670a82015-02-08 17:57:17 -0800686 this.description = description;
687 this.jsonCriterion = jsonCriterion;
Ray Milkeydb358082015-01-13 16:34:38 -0800688 final String type = criterion.type().name();
689 final String jsonType = jsonCriterion.get("type").asText();
690 if (!type.equals(jsonType)) {
691 description.appendText("type was " + type);
692 return false;
693 }
694
695 switch (criterion.type()) {
696
697 case IN_PORT:
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800698 case IN_PHY_PORT:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700699 return matchCriterion((PortCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800700
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800701 case METADATA:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700702 return matchCriterion((MetadataCriterion) criterion);
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800703
Ray Milkeydb358082015-01-13 16:34:38 -0800704 case ETH_DST:
Seyeon Jeong8f014142020-02-26 12:51:03 -0800705 case ETH_DST_MASKED:
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800706 case ETH_SRC:
David Glantz6210c4c2021-09-21 15:39:19 -0500707 case ETH_SRC_MASKED:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700708 return matchCriterion((EthCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800709
710 case ETH_TYPE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700711 return matchCriterion((EthTypeCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800712
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800713 case VLAN_VID:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700714 return matchCriterion((VlanIdCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800715
716 case VLAN_PCP:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700717 return matchCriterion((VlanPcpCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800718
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800719 case IP_DSCP:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700720 return matchCriterion((IPDscpCriterion) criterion);
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800721
722 case IP_ECN:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700723 return matchCriterion((IPEcnCriterion) criterion);
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800724
Ray Milkeydb358082015-01-13 16:34:38 -0800725 case IP_PROTO:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700726 return matchCriterion((IPProtocolCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800727
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800728 case IPV4_SRC:
729 case IPV4_DST:
730 case IPV6_SRC:
731 case IPV6_DST:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700732 return matchCriterion((IPCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800733
734 case TCP_SRC:
David Glantz6210c4c2021-09-21 15:39:19 -0500735 case TCP_SRC_MASKED:
Ray Milkeydb358082015-01-13 16:34:38 -0800736 case TCP_DST:
David Glantz6210c4c2021-09-21 15:39:19 -0500737 case TCP_DST_MASKED:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700738 return matchCriterion((TcpPortCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800739
740 case UDP_SRC:
David Glantz6210c4c2021-09-21 15:39:19 -0500741 case UDP_SRC_MASKED:
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800742 case UDP_DST:
David Glantz6210c4c2021-09-21 15:39:19 -0500743 case UDP_DST_MASKED:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700744 return matchCriterion((UdpPortCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800745
746 case SCTP_SRC:
David Glantz6210c4c2021-09-21 15:39:19 -0500747 case SCTP_SRC_MASKED:
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800748 case SCTP_DST:
David Glantz6210c4c2021-09-21 15:39:19 -0500749 case SCTP_DST_MASKED:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700750 return matchCriterion((SctpPortCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800751
752 case ICMPV4_TYPE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700753 return matchCriterion((IcmpTypeCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800754
755 case ICMPV4_CODE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700756 return matchCriterion((IcmpCodeCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800757
758 case IPV6_FLABEL:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700759 return matchCriterion((IPv6FlowLabelCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800760
761 case ICMPV6_TYPE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700762 return matchCriterion((Icmpv6TypeCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800763
764 case ICMPV6_CODE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700765 return matchCriterion((Icmpv6CodeCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800766
767 case IPV6_ND_TARGET:
Ray Milkey46670a82015-02-08 17:57:17 -0800768 return matchCriterion(
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700769 (IPv6NDTargetAddressCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800770
771 case IPV6_ND_SLL:
772 case IPV6_ND_TLL:
Ray Milkey46670a82015-02-08 17:57:17 -0800773 return matchCriterion(
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700774 (IPv6NDLinkLayerAddressCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800775
776 case MPLS_LABEL:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700777 return matchCriterion((MplsCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800778
Pavlin Radoslavov5e4f7542015-02-06 18:18:21 -0800779 case IPV6_EXTHDR:
Ray Milkey46670a82015-02-08 17:57:17 -0800780 return matchCriterion(
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700781 (IPv6ExthdrFlagsCriterion) criterion);
Pavlin Radoslavov5e4f7542015-02-06 18:18:21 -0800782
Ray Milkeydb358082015-01-13 16:34:38 -0800783 case OCH_SIGID:
Sho SHIMIZUc44c0c32015-06-01 11:40:48 -0700784 return matchCriterion((OchSignalCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800785
786 case OCH_SIGTYPE:
Sho SHIMIZU6c70f642015-05-29 17:27:22 -0700787 return matchCriterion((OchSignalTypeCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800788
Yafit Hadar5796d972015-10-15 13:16:11 +0300789 case ODU_SIGID:
790 return matchCriterion((OduSignalIdCriterion) criterion);
791
792 case ODU_SIGTYPE:
793 return matchCriterion((OduSignalTypeCriterion) criterion);
Frank Wang74ce2c12018-04-11 20:26:45 +0800794 case PROTOCOL_INDEPENDENT:
795 return matchCriterion((PiCriterion) criterion);
Yafit Hadar5796d972015-10-15 13:16:11 +0300796
Ray Milkeydb358082015-01-13 16:34:38 -0800797 default:
798 // Don't know how to format this type
799 description.appendText("unknown criterion type " +
800 criterion.type());
801 return false;
802 }
Ray Milkeydb358082015-01-13 16:34:38 -0800803 }
804
805 @Override
806 public void describeTo(Description description) {
807 description.appendText(criterion.toString());
808 }
Ray Milkeydb358082015-01-13 16:34:38 -0800809}