Skip to content

Commit

Permalink
add support for contains, starts, and ends
Browse files Browse the repository at this point in the history
Update to be consistent with recent changes to Atlas
backend to support `:contains`, `:starts`, and `:ends`
query operations. These get mapped to regex so it only
impacts the query parsing.

See: Netflix/atlas#1470 and Netflix/atlas#1471.
  • Loading branch information
brharrington committed Oct 7, 2022
1 parent e816e9a commit da93b67
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit da93b67

Please sign in to comment.