/** * Get an aggregator using the default set of tags for the final result. The tags will * be extracted based on the exact matches for the underlying query. */ default Aggregator aggregator() { return aggregator(query().exactTags(), true); }
/** * Evaluate expressions for all subscriptions associated with the specified group using * the provided data. * * @param group * Name of the group. At Netflix this is typically the cluster that includes * the instance reporting data. * @param timestamp * Timestamp to use for the payload response. * @param vs * Set of values received for the group for the current time period. * @return * Payload that can be encoded and sent to Atlas streaming evaluation cluster. */ public EvalPayload eval(String group, long timestamp, List<TagsValuePair> vs) { List<Subscription> subs = subscriptions.getOrDefault(group, Collections.emptyList()); List<EvalPayload.Metric> metrics = new ArrayList<>(); for (Subscription s : subs) { DataExpr expr = s.dataExpr(); for (TagsValuePair pair : expr.eval(vs)) { EvalPayload.Metric m = new EvalPayload.Metric(s.getId(), pair.tags(), pair.value()); metrics.add(m); } } return new EvalPayload(timestamp, metrics); } }
/** * Evaluate the data expression over the input. * * @param input * Set of data values. The data will get filtered based on the query, that does * not need to be done in advance. * @return * Aggregated data values. */ default Iterable<TagsValuePair> eval(Iterable<TagsValuePair> input) { Aggregator aggr = aggregator(); for (TagsValuePair p : input) { aggr.update(p); } return aggr.result(); }
@Test public void sumEmpty() { DataExpr expr = parse(":true,:sum"); Assertions.assertFalse(expr.eval(Collections.emptyList()).iterator().hasNext()); }
@Test public void maxEmpty() { DataExpr expr = parse(":true,:max"); Assertions.assertFalse(expr.eval(Collections.emptyList()).iterator().hasNext()); }
private Iterable<TagsValuePair> evalNoCheck(DataExpr expr, Iterable<TagsValuePair> input) { DataExpr.Aggregator aggr = expr.aggregator(expr.query().exactTags(), false); for (TagsValuePair p : input) { aggr.update(p); } return aggr.result(); }
@Test public void minEmpty() { DataExpr expr = parse(":true,:min"); Assertions.assertFalse(expr.eval(Collections.emptyList()).iterator().hasNext()); }
@Test public void countEmpty() { DataExpr expr = parse(":true,:count"); Assertions.assertFalse(expr.eval(Collections.emptyList()).iterator().hasNext()); }
@Test public void notData() { DataExpr expr = parse("name,foo,:eq,:not,:all"); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Iterable<TagsValuePair> vs = expr.eval(ms); Assertions.assertEquals(1, StreamSupport.stream(vs.spliterator(), false).count()); }
@Test public void allData() { DataExpr expr = parse("name,foo,:eq,:all"); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Iterable<TagsValuePair> vs = expr.eval(ms); Assertions.assertEquals(4, StreamSupport.stream(vs.spliterator(), false).count()); }
@Test public void groupByUnknownData() { DataExpr expr = parse("name,foo,:eq,:sum,(,a,v,),:by"); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Iterable<TagsValuePair> vs = expr.eval(ms); Assertions.assertFalse(vs.iterator().hasNext()); }
private void aggrData(String aggr, double expected, boolean shouldCheckQuery) { DataExpr expr = parse("name,foo,:eq," + aggr); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Map<String, String> expectedTags = new HashMap<>(); expectedTags.put("name", "foo"); Iterable<TagsValuePair> vs = shouldCheckQuery ? expr.eval(ms) : evalNoCheck(expr, ms); int count = 0; for (TagsValuePair v : vs) { ++count; Assertions.assertEquals(expectedTags, v.tags()); Assertions.assertEquals(expected, v.value(), 1e-12); } Assertions.assertEquals(1, count); }
private void groupingData(String aggr, boolean shouldCheckQuery) { DataExpr expr = parse("name,foo,:eq,:sum," + aggr); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Iterable<TagsValuePair> vs = shouldCheckQuery ? expr.eval(ms) : evalNoCheck(expr, ms); int count = 0; for (TagsValuePair v : vs) { ++count; Assertions.assertEquals(2, v.tags().size()); if (shouldCheckQuery) { Assertions.assertEquals("foo", v.tags().get("name")); } double tv = Double.parseDouble(v.tags().get("v")); Assertions.assertEquals((tv < 2.0) ? 2.0 : tv, v.value(), 1e-12); } Assertions.assertEquals(shouldCheckQuery ? 3 : 4, count); }