/** * Constant-time constructor for AndMatchExpr. Simplifies if given zero or one conjunct. Doesn't * do other simplifications that require more work (like removing all {@link TrueExpr TrueExprs}). */ public static AclLineMatchExpr and(Iterable<AclLineMatchExpr> exprs) { Iterator<AclLineMatchExpr> iter = exprs.iterator(); if (!iter.hasNext()) { // Empty. Return the identity element return TrueExpr.INSTANCE; } AclLineMatchExpr first = iter.next(); if (!iter.hasNext()) { // Only 1 element return first; } return new AndMatchExpr(exprs); }
@Override public AclLineMatchExpr visitAndMatchExpr(AndMatchExpr andMatchExpr) throws CircularReferenceException, UndefinedReferenceException { return new AndMatchExpr( andMatchExpr.getConjuncts().stream().map(this::visit).collect(Collectors.toList())); }
@Test public void testCompareToForEqualVals() { // Test equivalent expressions with both non-null and null descriptions assertThat(new AndMatchExpr(null, "x").compareTo(new AndMatchExpr(null, "x")), equalTo(0)); assertThat(new AndMatchExpr(null, null).compareTo(new AndMatchExpr(null, null)), equalTo(0)); } }
@Override public Void visitAndMatchExpr(AndMatchExpr andMatchExpr) { andMatchExpr.getConjuncts().forEach(this::visit); return null; }
@Override public Void visitAndMatchExpr(AndMatchExpr andMatchExpr) { andMatchExpr.getConjuncts().forEach(this::visit); return null; }
/** Merge the list of lines with the specified conjunct match expression. */ private static List<IpAccessListLine> mergeIpAccessListLines( List<IpAccessListLine> lines, @Nullable AclLineMatchExpr conjunctMatchExpr) { if (conjunctMatchExpr == null) { return lines; } else { return lines.stream() .map( l -> new IpAccessListLine( l.getAction(), new AndMatchExpr(ImmutableList.of(l.getMatchCondition(), conjunctMatchExpr)), l.getName())) .collect(ImmutableList.toImmutableList()); } }
@Override public AclLineMatchExpr visitAndMatchExpr(AndMatchExpr andMatchExpr) { return new AndMatchExpr( andMatchExpr.getConjuncts().stream() .map(this::visit) .collect(ImmutableSortedSet.toImmutableSortedSet(Ordering.natural()))); }
@Override protected SortedSet<AclLineMatchExpr> featureValueOf(AndMatchExpr actual) { return actual.getConjuncts(); } }
@Override public AclLineMatchExpr visitOrMatchExpr(OrMatchExpr orMatchExpr) { return new AndMatchExpr(negate(orMatchExpr.getDisjuncts())); }
@Override public final AclLineMatchExpr visitAndMatchExpr(AndMatchExpr andMatchExpr) { List<AclLineMatchExpr> conjuncts = andMatchExpr.getConjuncts().stream() .map(expr -> expr.accept(this)) .filter(expr -> expr != TrueExpr.INSTANCE) .collect(ImmutableList.toImmutableList()); if (conjuncts.isEmpty()) { return TrueExpr.INSTANCE; } if (conjuncts.contains(FalseExpr.INSTANCE)) { return FalseExpr.INSTANCE; } return new AndMatchExpr(conjuncts); }
@Override public List<T> visitAndMatchExpr(AndMatchExpr andMatchExpr) { List<T> matchingExprs = new ArrayList<>(); if (_type.isAssignableFrom(AndMatchExpr.class)) { matchingExprs.add(_type.cast(andMatchExpr)); } for (AclLineMatchExpr conjunct : andMatchExpr.getConjuncts()) { matchingExprs.addAll(visit(conjunct)); } return matchingExprs; }
@Nullable @VisibleForTesting IpAccessList buildScreensPerZone(@Nonnull Zone zone, String aclName) { List<AclLineMatchExpr> matches = zone.getScreens().stream() .map( screenName -> { Screen screen = _masterLogicalSystem.getScreens().get(screenName); String screenAclName = ACL_NAME_SCREEN + screenName; IpAccessList screenAcl = _c.getIpAccessLists() .computeIfAbsent(screenAclName, x -> buildScreen(screen, screenAclName)); return screenAcl != null ? new PermittedByAcl(screenAcl.getName(), false) : null; }) .filter(Objects::nonNull) .collect(Collectors.toList()); return matches.isEmpty() ? null : IpAccessList.builder() .setName(aclName) .setLines(ImmutableList.of(IpAccessListLine.accepting(new AndMatchExpr(matches)))) .build(); }
@Override public Void visitAndMatchExpr(AndMatchExpr andMatchExpr) { andMatchExpr.getConjuncts().forEach(this::visit); return null; }
return new AclLineMatchExprWithProvenance<>(conjuncts.first(), conjunctsProvenance); return new AclLineMatchExprWithProvenance<>(new AndMatchExpr(conjuncts), conjunctsProvenance);
@Override public BoolExpr visitAndMatchExpr(AndMatchExpr andMatchExpr) { return _context.mkAnd( andMatchExpr.getConjuncts().stream().map(this::toBoolExpr).toArray(BoolExpr[]::new)); }
@Test public void testSingleExpr() { // Test that if and only if the only ACL line is a match, the AndMatchExpr indicates a match // Setup simple expression with a single true boolean expr List<AclLineMatchExpr> setTrue = ImmutableList.of(TrueExpr.INSTANCE); AndMatchExpr exprTrue = new AndMatchExpr(setTrue); // Setup simple expression with a single false boolean expr List<AclLineMatchExpr> setFalse = ImmutableList.of(FalseExpr.INSTANCE); AndMatchExpr exprFalse = new AndMatchExpr(setFalse); // Confirm true boolean expr matches assertThat(exprTrue, matches(createFlow(), "")); // Confirm false boolean expr does not match assertThat(exprFalse, not(matches(createFlow(), ""))); }
/** A factor is either a literal or a conjunction of literals. */ static AclLineMatchExprWithProvenance<AclLineMatchExpr> explainFactor(AclLineMatchExpr factor) { if (factor instanceof AndMatchExpr) { return explainLiterals(((AndMatchExpr) factor).getConjuncts()); } return explainLiterals(ImmutableList.of(factor)); }
@Test public void testMultipleExprs() { // Test that if and only if all ACL lines are a match, the AndMatchExpr returns a match List<AclLineMatchExpr> setTrueTrue = ImmutableList.of(TrueExpr.INSTANCE, TrueExpr.INSTANCE); AndMatchExpr exprTrueTrue = new AndMatchExpr(setTrueTrue); List<AclLineMatchExpr> setTrueFalse = ImmutableList.of(TrueExpr.INSTANCE, FalseExpr.INSTANCE); AndMatchExpr exprTrueFalse = new AndMatchExpr(setTrueFalse); List<AclLineMatchExpr> setFalseFalse = ImmutableList.of(FalseExpr.INSTANCE, FalseExpr.INSTANCE); AndMatchExpr exprFalseFalse = new AndMatchExpr(setFalseFalse); // Confirm boolean expr true AND true = true assertThat(exprTrueTrue, matches(createFlow(), "")); // Confirm boolean expr true AND false = false assertThat(exprTrueFalse, not(matches(createFlow(), ""))); // Confirm boolean expr false AND false = false assertThat(exprFalseFalse, not(matches(createFlow(), ""))); } }
@Override public Boolean visitAndMatchExpr(AndMatchExpr andMatchExpr) { return andMatchExpr.getConjuncts().stream().allMatch(c -> c.accept(this)); }
switch (matchSemantics) { case MATCH_ALL: matchClassMap = new AndMatchExpr(matchConditions); break; case MATCH_ANY: