diff --git a/codequality/checkstyle.xml b/codequality/checkstyle.xml index 76df51deb..642098094 100644 --- a/codequality/checkstyle.xml +++ b/codequality/checkstyle.xml @@ -166,17 +166,8 @@ - - - - - - - - - - - - + + + diff --git a/spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/Parser.java b/spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/Parser.java index c2723d107..6272af69e 100644 --- a/spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/Parser.java +++ b/spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/Parser.java @@ -15,6 +15,8 @@ */ package com.netflix.spectator.atlas.impl; +import com.netflix.spectator.impl.matcher.PatternUtils; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; @@ -56,7 +58,7 @@ public static Query parseQuery(String expr) { } } - @SuppressWarnings({"unchecked", "PMD"}) + @SuppressWarnings({"unchecked", "checkstyle:MethodLength", "PMD"}) private static Object parse(String expr) { DataExpr.AggregateFunction af; Query q, q1, q2; @@ -156,6 +158,21 @@ private static Object parse(String expr) { k = (String) stack.pop(); pushRegex(stack, new Query.Regex(k, v, true, ":reic")); break; + case ":contains": + v = (String) stack.pop(); + k = (String) stack.pop(); + pushRegex(stack, new Query.Regex(k, ".*" + PatternUtils.escape(v))); + break; + case ":starts": + v = (String) stack.pop(); + k = (String) stack.pop(); + pushRegex(stack, new Query.Regex(k, PatternUtils.escape(v))); + break; + case ":ends": + v = (String) stack.pop(); + k = (String) stack.pop(); + pushRegex(stack, new Query.Regex(k, ".*" + PatternUtils.escape(v) + "$")); + break; case ":all": q = (Query) stack.pop(); stack.push(new DataExpr.All(q)); diff --git a/spectator-reg-atlas/src/test/java/com/netflix/spectator/atlas/impl/QueryTest.java b/spectator-reg-atlas/src/test/java/com/netflix/spectator/atlas/impl/QueryTest.java index c87a806ca..a91345453 100644 --- a/spectator-reg-atlas/src/test/java/com/netflix/spectator/atlas/impl/QueryTest.java +++ b/spectator-reg-atlas/src/test/java/com/netflix/spectator/atlas/impl/QueryTest.java @@ -42,7 +42,10 @@ private Query parse(String expr) { Query q1 = Parser.parseQuery(expr); Query q2 = Parser.parseQuery(expr); Assertions.assertEquals(q1, q2); - Assertions.assertEquals(expr, q1.toString()); + + Query q3 = Parser.parseQuery(q1.toString()); + Assertions.assertEquals(q1, q3); + Assertions.assertEquals(q1.toString(), q3.toString()); return q1; } @@ -210,6 +213,63 @@ public void reEqualsContract() { .verify(); } + @Test + public void containsQuery() { + Query q = parse("name,foo,:contains"); + Assertions.assertTrue(q.matches(registry.createId("foo"))); + Assertions.assertTrue(q.matches(registry.createId("foo_"))); + Assertions.assertTrue(q.matches(registry.createId("_foo_"))); + Assertions.assertTrue(q.matches(registry.createId("_foo"))); + Assertions.assertFalse(q.matches(registry.createId("_Foo_"))); + } + + @Test + public void containsQueryEscape() { + Query q = parse("name,^$.?*+[](){}\\#&!%,:contains"); + Assertions.assertEquals( + "name,.*\\^\\$\\.\\?\\*\\+\\[\\]\\(\\)\\{\\}\\\\#&!%,:re", + q.toString()); + Assertions.assertTrue(q.matches(registry.createId("^$.?*+[](){}\\#&!%"))); + } + + @Test + public void startsQuery() { + Query q = parse("name,foo,:starts"); + Assertions.assertTrue(q.matches(registry.createId("foo"))); + Assertions.assertTrue(q.matches(registry.createId("foo_"))); + Assertions.assertFalse(q.matches(registry.createId("_foo_"))); + Assertions.assertFalse(q.matches(registry.createId("_foo"))); + Assertions.assertFalse(q.matches(registry.createId("Foo_"))); + } + + @Test + public void startsQueryEscape() { + Query q = parse("name,^$.?*+[](){}\\#&!%,:starts"); + Assertions.assertEquals( + "name,\\^\\$\\.\\?\\*\\+\\[\\]\\(\\)\\{\\}\\\\#&!%,:re", + q.toString()); + Assertions.assertTrue(q.matches(registry.createId("^$.?*+[](){}\\#&!%"))); + } + + @Test + public void endsQuery() { + Query q = parse("name,foo,:ends"); + Assertions.assertTrue(q.matches(registry.createId("foo"))); + Assertions.assertFalse(q.matches(registry.createId("foo_"))); + Assertions.assertFalse(q.matches(registry.createId("_foo_"))); + Assertions.assertTrue(q.matches(registry.createId("_foo"))); + Assertions.assertFalse(q.matches(registry.createId("_Foo"))); + } + + @Test + public void endsQueryEscape() { + Query q = parse("name,^$.?*+[](){}\\#&!%,:ends"); + Assertions.assertEquals( + "name,.*\\^\\$\\.\\?\\*\\+\\[\\]\\(\\)\\{\\}\\\\#&!%$,:re", + q.toString()); + Assertions.assertTrue(q.matches(registry.createId("^$.?*+[](){}\\#&!%"))); + } + @Test public void andQuery() { Query q = parse("name,foo,:eq,bar,baz,:eq,:and");