blob: d1e1f195e48ae9acd7090c54f4f5a9b3e9ce1701 [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 }
Seyeon Jeong8f014142020-02-26 12:51:03 -0800141 if (criterion.type() == Criterion.Type.ETH_DST_MASKED) {
142 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 }
281 return true;
282 }
283
284 /**
285 * Matches a UDP port criterion object.
286 *
287 * @param criterion criterion to match
288 * @return true if the JSON matches the criterion, false otherwise.
289 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700290 private boolean matchCriterion(UdpPortCriterion criterion) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700291 final int udpPort = criterion.udpPort().toInt();
Ray Milkey46670a82015-02-08 17:57:17 -0800292 final int jsonUdpPort = jsonCriterion.get("udpPort").intValue();
293 if (udpPort != jsonUdpPort) {
294 description.appendText("udp port was "
295 + Integer.toString(jsonUdpPort));
296 return false;
297 }
298 return true;
299 }
300
301 /**
302 * Matches an SCTP port criterion object.
303 *
304 * @param criterion criterion to match
305 * @return true if the JSON matches the criterion, false otherwise.
306 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700307 private boolean matchCriterion(SctpPortCriterion criterion) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700308 final int sctpPort = criterion.sctpPort().toInt();
Ray Milkey46670a82015-02-08 17:57:17 -0800309 final int jsonSctpPort = jsonCriterion.get("sctpPort").intValue();
310 if (sctpPort != jsonSctpPort) {
311 description.appendText("sctp port was "
312 + Integer.toString(jsonSctpPort));
313 return false;
314 }
315 return true;
316 }
317
318 /**
319 * Matches an ICMP type criterion object.
320 *
321 * @param criterion criterion to match
322 * @return true if the JSON matches the criterion, false otherwise.
323 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700324 private boolean matchCriterion(IcmpTypeCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800325 final short icmpType = criterion.icmpType();
326 final short jsonIcmpType = jsonCriterion.get("icmpType").shortValue();
327 if (icmpType != jsonIcmpType) {
328 description.appendText("icmp type was "
329 + Short.toString(jsonIcmpType));
330 return false;
331 }
332 return true;
333 }
334
335 /**
336 * Matches an ICMP code criterion object.
337 *
338 * @param criterion criterion to match
339 * @return true if the JSON matches the criterion, false otherwise.
340 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700341 private boolean matchCriterion(IcmpCodeCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800342 final short icmpCode = criterion.icmpCode();
343 final short jsonIcmpCode = jsonCriterion.get("icmpCode").shortValue();
344 if (icmpCode != jsonIcmpCode) {
345 description.appendText("icmp code was "
346 + Short.toString(jsonIcmpCode));
347 return false;
348 }
349 return true;
350 }
351
352 /**
353 * Matches an IPV6 flow label criterion object.
354 *
355 * @param criterion criterion to match
356 * @return true if the JSON matches the criterion, false otherwise.
357 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700358 private boolean matchCriterion(IPv6FlowLabelCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800359 final int flowLabel = criterion.flowLabel();
360 final int jsonFlowLabel = jsonCriterion.get("flowLabel").intValue();
361 if (flowLabel != jsonFlowLabel) {
362 description.appendText("IPv6 flow label was "
363 + Integer.toString(jsonFlowLabel));
364 return false;
365 }
366 return true;
367 }
368
369 /**
370 * Matches an ICMP V6 type criterion object.
371 *
372 * @param criterion criterion to match
373 * @return true if the JSON matches the criterion, false otherwise.
374 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700375 private boolean matchCriterion(Icmpv6TypeCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800376 final short icmpv6Type = criterion.icmpv6Type();
377 final short jsonIcmpv6Type =
378 jsonCriterion.get("icmpv6Type").shortValue();
379 if (icmpv6Type != jsonIcmpv6Type) {
380 description.appendText("icmpv6 type was "
381 + Short.toString(jsonIcmpv6Type));
382 return false;
383 }
384 return true;
385 }
386
387 /**
388 * Matches an IPV6 code criterion object.
389 *
390 * @param criterion criterion to match
391 * @return true if the JSON matches the criterion, false otherwise.
392 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700393 private boolean matchCriterion(Icmpv6CodeCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800394 final short icmpv6Code = criterion.icmpv6Code();
395 final short jsonIcmpv6Code =
396 jsonCriterion.get("icmpv6Code").shortValue();
397 if (icmpv6Code != jsonIcmpv6Code) {
398 description.appendText("icmpv6 code was "
399 + Short.toString(jsonIcmpv6Code));
400 return false;
401 }
402 return true;
403 }
404
405 /**
406 * Matches an IPV6 ND target criterion object.
407 *
408 * @param criterion criterion to match
409 * @return true if the JSON matches the criterion, false otherwise.
410 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700411 private boolean matchCriterion(IPv6NDTargetAddressCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800412 final String targetAddress =
413 criterion.targetAddress().toString();
414 final String jsonTargetAddress =
415 jsonCriterion.get("targetAddress").textValue();
416 if (!targetAddress.equals(jsonTargetAddress)) {
417 description.appendText("target address was " +
418 jsonTargetAddress);
419 return false;
420 }
421 return true;
422 }
423
424 /**
425 * Matches an IPV6 ND link layer criterion object.
426 *
427 * @param criterion criterion to match
428 * @return true if the JSON matches the criterion, false otherwise.
429 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700430 private boolean matchCriterion(IPv6NDLinkLayerAddressCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800431 final String llAddress =
432 criterion.mac().toString();
433 final String jsonLlAddress =
434 jsonCriterion.get("mac").textValue();
435 if (!llAddress.equals(jsonLlAddress)) {
436 description.appendText("mac was " + jsonLlAddress);
437 return false;
438 }
439 return true;
440 }
441
442 /**
443 * Matches an MPLS label criterion object.
444 *
445 * @param criterion criterion to match
446 * @return true if the JSON matches the criterion, false otherwise.
447 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700448 private boolean matchCriterion(MplsCriterion criterion) {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100449 final int label = criterion.label().toInt();
Ray Milkey46670a82015-02-08 17:57:17 -0800450 final int jsonLabel = jsonCriterion.get("label").intValue();
451 if (label != jsonLabel) {
452 description.appendText("label was " + Integer.toString(jsonLabel));
453 return false;
454 }
455 return true;
456 }
457
458 /**
459 * Matches an IPV6 exthdr criterion object.
460 *
461 * @param criterion criterion to match
462 * @return true if the JSON matches the criterion, false otherwise.
463 */
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700464 private boolean matchCriterion(IPv6ExthdrFlagsCriterion criterion) {
Ray Milkey46670a82015-02-08 17:57:17 -0800465 final int exthdrFlags = criterion.exthdrFlags();
466 final int jsonExthdrFlags =
467 jsonCriterion.get("exthdrFlags").intValue();
468 if (exthdrFlags != jsonExthdrFlags) {
469 description.appendText("exthdrFlags was "
470 + Long.toHexString(jsonExthdrFlags));
471 return false;
472 }
473 return true;
474 }
475
476 /**
Sho SHIMIZUc44c0c32015-06-01 11:40:48 -0700477 * Matches an Och signal criterion object.
Ray Milkey46670a82015-02-08 17:57:17 -0800478 *
479 * @param criterion criterion to match
480 * @return true if the JSON matches the criterion, false otherwise.
481 */
Sho SHIMIZUc44c0c32015-06-01 11:40:48 -0700482 private boolean matchCriterion(OchSignalCriterion criterion) {
483 final OchSignal ochSignal = criterion.lambda();
484 final JsonNode jsonOchSignal = jsonCriterion.get("ochSignalId");
485 String jsonGridType = jsonOchSignal.get("gridType").textValue();
486 String jsonChannelSpacing = jsonOchSignal.get("channelSpacing").textValue();
487 int jsonSpacingMultiplier = jsonOchSignal.get("spacingMultiplier").intValue();
488 int jsonSlotGranularity = jsonOchSignal.get("slotGranularity").intValue();
489
490 boolean equality = Objects.equals(ochSignal.gridType().name(), jsonGridType)
491 && Objects.equals(ochSignal.channelSpacing().name(), jsonChannelSpacing)
492 && Objects.equals(ochSignal.spacingMultiplier(), jsonSpacingMultiplier)
493 && Objects.equals(ochSignal.slotGranularity(), jsonSlotGranularity);
494
495 if (!equality) {
496 String joined = Joiner.on(", ")
497 .join(jsonGridType, jsonChannelSpacing, jsonSpacingMultiplier, jsonSlotGranularity);
498
499 description.appendText("och signal id was " + joined);
Ray Milkey46670a82015-02-08 17:57:17 -0800500 return false;
501 }
502 return true;
503 }
504
505 /**
Sho SHIMIZU68b8c1f2015-05-29 18:42:26 -0700506 * Matches an Och signal type criterion object.
Ray Milkey46670a82015-02-08 17:57:17 -0800507 *
508 * @param criterion criterion to match
509 * @return true if the JSON matches the criterion, false otherwise.
510 */
Sho SHIMIZU6c70f642015-05-29 17:27:22 -0700511 private boolean matchCriterion(OchSignalTypeCriterion criterion) {
512 final String signalType = criterion.signalType().name();
513 final String jsonSignalType = jsonCriterion.get("ochSignalType").textValue();
514 if (!signalType.equals(jsonSignalType)) {
Sho SHIMIZUc06966e2015-06-01 12:14:37 -0700515 description.appendText("signal type was " + jsonSignalType);
Ray Milkey46670a82015-02-08 17:57:17 -0800516 return false;
517 }
518 return true;
519 }
520
Yafit Hadar5796d972015-10-15 13:16:11 +0300521 /**
522 * Matches an ODU signal ID criterion object.
523 *
524 * @param criterion criterion to match
525 * @return true if the JSON matches the criterion, false otherwise.
526 */
527 private boolean matchCriterion(OduSignalIdCriterion criterion) {
528 final OduSignalId oduSignal = criterion.oduSignalId();
529 final JsonNode jsonOduSignal = jsonCriterion.get(CriterionCodec.ODU_SIGNAL_ID);
530 int jsonTpn = jsonOduSignal.get(CriterionCodec.TRIBUTARY_PORT_NUMBER).intValue();
531 int jsonTsLen = jsonOduSignal.get(CriterionCodec.TRIBUTARY_SLOT_LEN).intValue();
532 byte[] jsonTributaryBitMap = HexString.fromHexString(
533 jsonOduSignal.get(CriterionCodec.TRIBUTARY_SLOT_BITMAP).asText());
534 OduSignalId jsonOduSignalId = OduSignalId.oduSignalId(jsonTpn, jsonTsLen, jsonTributaryBitMap);
535 if (!oduSignal.equals(jsonOduSignalId)) {
536 description.appendText("oduSignalId was " + criterion);
537 return false;
538 }
539 return true;
540 }
541
542 /**
543 * Matches an ODU signal Type criterion object.
544 *
545 * @param criterion criterion to match
546 * @return true if the JSON matches the criterion, false otherwise.
547 */
548 private boolean matchCriterion(OduSignalTypeCriterion criterion) {
549 final String signalType = criterion.signalType().name();
550 final String jsonOduSignalType = jsonCriterion.get("oduSignalType").textValue();
551 if (!signalType.equals(jsonOduSignalType)) {
552 description.appendText("signalType was " + signalType);
553 return false;
554 }
555 return true;
556 }
557
Frank Wang74ce2c12018-04-11 20:26:45 +0800558 /**
559 * Matches a protocol-independent Type criterion object.
560 *
561 * @param criterion criterion to match
562 * @return true if the JSON matches the criterion, false otherwise.
563 */
564 private boolean matchCriterion(PiCriterion criterion) {
565 Collection<PiFieldMatch> piFieldMatches = criterion.fieldMatches();
566 JsonNode jsonMathes = jsonCriterion.get("matches");
567 if (!jsonMathes.isArray()) {
568 return false;
569 }
570 for (JsonNode matchNode : jsonMathes) {
571 for (PiFieldMatch fieldMatch : piFieldMatches) {
572
573 if (!Objects.equals(matchNode.get("field").textValue(), fieldMatch.fieldId().id())) {
574 description.appendText("match field was " + fieldMatch.fieldId().id());
575 return false;
576 }
577
578 if (!Objects.equals(matchNode.get("match").textValue(),
579 fieldMatch.type().name().toLowerCase())) {
580 description.appendText("match type was " + fieldMatch.type().name().toLowerCase());
581 return false;
582 }
583
584 switch (fieldMatch.type()) {
585 case EXACT:
586 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value")
587 .textValue(), null)),
588 ((PiExactFieldMatch) fieldMatch).value())) {
589 description.appendText("match value was " + ((PiExactFieldMatch) fieldMatch).value());
590 return false;
591 }
592 break;
593 case LPM:
594 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value")
595 .textValue(), null)),
596 ((PiLpmFieldMatch) fieldMatch).value())) {
597 description.appendText("match value was " + ((PiLpmFieldMatch) fieldMatch).value());
598 return false;
599 }
600 if (!Objects.equals(matchNode.get("prefixLength").intValue(),
601 ((PiLpmFieldMatch) fieldMatch).prefixLength())) {
602 description.appendText("match prefix was " +
603 ((PiLpmFieldMatch) fieldMatch).prefixLength());
604 return false;
605 }
606 break;
607 case TERNARY:
608 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value")
609 .textValue(), null)),
610 ((PiTernaryFieldMatch) fieldMatch).value())) {
611 description.appendText("match value was " + ((PiTernaryFieldMatch) fieldMatch).value());
612 return false;
613 }
614 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("mask")
615 .textValue(), null)),
616 ((PiTernaryFieldMatch) fieldMatch).mask())) {
617 description.appendText("match mask was " + ((PiTernaryFieldMatch) fieldMatch).mask());
618 return false;
619 }
620 break;
621 case RANGE:
622 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("highValue")
623 .textValue(), null)),
624 ((PiRangeFieldMatch) fieldMatch).highValue())) {
625 description.appendText("match high value was " +
626 ((PiRangeFieldMatch) fieldMatch).highValue());
627 return false;
628 }
629 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("lowValue")
630 .textValue(), null)),
631 ((PiRangeFieldMatch) fieldMatch).lowValue())) {
632 description.appendText("match low value was " +
633 ((PiRangeFieldMatch) fieldMatch).lowValue());
634 return false;
635 }
636 break;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100637 case OPTIONAL:
638 if (!Objects.equals(copyFrom(HexString.fromHexString(matchNode.get("value")
639 .textValue(), null)),
640 ((PiOptionalFieldMatch) fieldMatch).value())) {
641 description.appendText("match value was " + ((PiOptionalFieldMatch) fieldMatch).value());
642 return false;
643 }
644 break;
Frank Wang74ce2c12018-04-11 20:26:45 +0800645 default:
646 description.appendText("match type was " + fieldMatch.type().name().toLowerCase());
647 return false;
648 }
649 }
650 }
651
652 return true;
653 }
Yafit Hadar5796d972015-10-15 13:16:11 +0300654
Ray Milkeydb358082015-01-13 16:34:38 -0800655 @Override
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800656 public boolean matchesSafely(JsonNode jsonCriterion,
657 Description description) {
Ray Milkey46670a82015-02-08 17:57:17 -0800658 this.description = description;
659 this.jsonCriterion = jsonCriterion;
Ray Milkeydb358082015-01-13 16:34:38 -0800660 final String type = criterion.type().name();
661 final String jsonType = jsonCriterion.get("type").asText();
662 if (!type.equals(jsonType)) {
663 description.appendText("type was " + type);
664 return false;
665 }
666
667 switch (criterion.type()) {
668
669 case IN_PORT:
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800670 case IN_PHY_PORT:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700671 return matchCriterion((PortCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800672
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800673 case METADATA:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700674 return matchCriterion((MetadataCriterion) criterion);
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800675
Ray Milkeydb358082015-01-13 16:34:38 -0800676 case ETH_DST:
Seyeon Jeong8f014142020-02-26 12:51:03 -0800677 case ETH_DST_MASKED:
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800678 case ETH_SRC:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700679 return matchCriterion((EthCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800680
681 case ETH_TYPE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700682 return matchCriterion((EthTypeCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800683
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800684 case VLAN_VID:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700685 return matchCriterion((VlanIdCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800686
687 case VLAN_PCP:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700688 return matchCriterion((VlanPcpCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800689
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800690 case IP_DSCP:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700691 return matchCriterion((IPDscpCriterion) criterion);
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800692
693 case IP_ECN:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700694 return matchCriterion((IPEcnCriterion) criterion);
Pavlin Radoslavovd0fd8412015-02-04 13:57:00 -0800695
Ray Milkeydb358082015-01-13 16:34:38 -0800696 case IP_PROTO:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700697 return matchCriterion((IPProtocolCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800698
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800699 case IPV4_SRC:
700 case IPV4_DST:
701 case IPV6_SRC:
702 case IPV6_DST:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700703 return matchCriterion((IPCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800704
705 case TCP_SRC:
706 case TCP_DST:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700707 return matchCriterion((TcpPortCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800708
709 case UDP_SRC:
710 case UDP_DST:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700711 return matchCriterion((UdpPortCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800712
713 case SCTP_SRC:
714 case SCTP_DST:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700715 return matchCriterion((SctpPortCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800716
717 case ICMPV4_TYPE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700718 return matchCriterion((IcmpTypeCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800719
720 case ICMPV4_CODE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700721 return matchCriterion((IcmpCodeCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800722
723 case IPV6_FLABEL:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700724 return matchCriterion((IPv6FlowLabelCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800725
726 case ICMPV6_TYPE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700727 return matchCriterion((Icmpv6TypeCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800728
729 case ICMPV6_CODE:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700730 return matchCriterion((Icmpv6CodeCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800731
732 case IPV6_ND_TARGET:
Ray Milkey46670a82015-02-08 17:57:17 -0800733 return matchCriterion(
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700734 (IPv6NDTargetAddressCriterion) criterion);
Pavlin Radoslavov320e6c92015-02-02 16:51:58 -0800735
736 case IPV6_ND_SLL:
737 case IPV6_ND_TLL:
Ray Milkey46670a82015-02-08 17:57:17 -0800738 return matchCriterion(
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700739 (IPv6NDLinkLayerAddressCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800740
741 case MPLS_LABEL:
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700742 return matchCriterion((MplsCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800743
Pavlin Radoslavov5e4f7542015-02-06 18:18:21 -0800744 case IPV6_EXTHDR:
Ray Milkey46670a82015-02-08 17:57:17 -0800745 return matchCriterion(
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -0700746 (IPv6ExthdrFlagsCriterion) criterion);
Pavlin Radoslavov5e4f7542015-02-06 18:18:21 -0800747
Ray Milkeydb358082015-01-13 16:34:38 -0800748 case OCH_SIGID:
Sho SHIMIZUc44c0c32015-06-01 11:40:48 -0700749 return matchCriterion((OchSignalCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800750
751 case OCH_SIGTYPE:
Sho SHIMIZU6c70f642015-05-29 17:27:22 -0700752 return matchCriterion((OchSignalTypeCriterion) criterion);
Ray Milkeydb358082015-01-13 16:34:38 -0800753
Yafit Hadar5796d972015-10-15 13:16:11 +0300754 case ODU_SIGID:
755 return matchCriterion((OduSignalIdCriterion) criterion);
756
757 case ODU_SIGTYPE:
758 return matchCriterion((OduSignalTypeCriterion) criterion);
Frank Wang74ce2c12018-04-11 20:26:45 +0800759 case PROTOCOL_INDEPENDENT:
760 return matchCriterion((PiCriterion) criterion);
Yafit Hadar5796d972015-10-15 13:16:11 +0300761
Ray Milkeydb358082015-01-13 16:34:38 -0800762 default:
763 // Don't know how to format this type
764 description.appendText("unknown criterion type " +
765 criterion.type());
766 return false;
767 }
Ray Milkeydb358082015-01-13 16:34:38 -0800768 }
769
770 @Override
771 public void describeTo(Description description) {
772 description.appendText(criterion.toString());
773 }
Ray Milkeydb358082015-01-13 16:34:38 -0800774}