Skip to content

Commit

Permalink
feat(matchexpressions): expressions can reference target JFR event ty…
Browse files Browse the repository at this point in the history
…pe IDs (#735)
  • Loading branch information
andrewazores authored Dec 19, 2024
1 parent 29cfed3 commit 9ca5669
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@
import java.util.concurrent.CompletionException;
import java.util.stream.Collectors;

import io.cryostat.events.SerializableEventTypeInfo;
import io.cryostat.expressions.MatchExpression.ExpressionEvent;
import io.cryostat.targets.Target;
import io.cryostat.targets.Target.Annotations;
import io.cryostat.targets.Target.TargetDiscovery;
import io.cryostat.targets.TargetConnectionManager;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.quarkus.cache.CacheManager;
import io.quarkus.cache.CacheResult;
import io.quarkus.cache.CompositeCacheKey;
import io.quarkus.logging.Log;
import io.quarkus.vertx.ConsumeEvent;
import jakarta.annotation.Nullable;
import jakarta.enterprise.context.ApplicationScoped;
Expand All @@ -42,7 +45,12 @@
import jdk.jfr.Label;
import jdk.jfr.Name;
import org.jboss.logging.Logger;
import org.projectnessie.cel.EnvOption;
import org.projectnessie.cel.Library;
import org.projectnessie.cel.ProgramOption;
import org.projectnessie.cel.checker.Decls;
import org.projectnessie.cel.common.types.ListT;
import org.projectnessie.cel.interpreter.functions.Overload;
import org.projectnessie.cel.tools.Script;
import org.projectnessie.cel.tools.ScriptCreateException;
import org.projectnessie.cel.tools.ScriptException;
Expand All @@ -56,6 +64,7 @@ public class MatchExpressionEvaluator {
@Inject ScriptHost scriptHost;
@Inject Logger logger;
@Inject CacheManager cacheManager;
@Inject TargetConnectionManager connectionManager;

@ConsumeEvent(value = MatchExpression.EXPRESSION_ADDRESS, blocking = true)
void onMessage(ExpressionEvent event) {
Expand Down Expand Up @@ -104,6 +113,7 @@ Script createScript(String matchExpression) throws ScriptCreateException {
Decls.newVar(
"target",
Decls.newObjectType(SimplifiedTarget.class.getName())))
.withLibraries(List.of(new EventTypesLibrary(connectionManager)))
.build();
} finally {
evt.end();
Expand Down Expand Up @@ -221,6 +231,7 @@ public static class ScriptCreation extends Event {}
* expression-relevant fields exposed, connection URI exposed as a String, etc.
*/
private static record SimplifiedTarget(
long id,
boolean agent,
String connectUrl,
String alias,
Expand All @@ -240,6 +251,7 @@ private static record SimplifiedTarget(

static SimplifiedTarget from(Target target) {
return new SimplifiedTarget(
target.id,
target.isAgent(),
target.connectUrl.toString(),
target.alias,
Expand All @@ -248,4 +260,57 @@ static SimplifiedTarget from(Target target) {
target.annotations);
}
}

static class EventTypesLibrary implements Library {

private final TargetConnectionManager connectionManager;

EventTypesLibrary(TargetConnectionManager connectionManager) {
this.connectionManager = connectionManager;
}

@Override
public List<EnvOption> getCompileOptions() {
return List.of(
EnvOption.declarations(
Decls.newFunction(
"jfrEventTypeIds",
Decls.newOverload(
"jfrEventTypeIds_void",
List.of(
Decls.newObjectType(
SimplifiedTarget.class.getName())),
Decls.newListType(Decls.String)))));
}

@Override
public List<ProgramOption> getProgramOptions() {
return List.of(
ProgramOption.functions(
Overload.unary(
"jfrEventTypeIds",
(arg) ->
ListT.newStringArrayList(
getJfrEventTypeIds(
(SimplifiedTarget) arg.value())))));
}

private String[] getJfrEventTypeIds(SimplifiedTarget st) {
Target target = Target.find("id", st.id()).singleResult();
try {
return connectionManager.executeConnectedTask(
target,
connection ->
connection.getService().getAvailableEventTypes().stream()
.map(SerializableEventTypeInfo::fromEventTypeInfo)
.map(SerializableEventTypeInfo::typeId)
.distinct()
.toList()
.toArray(new String[0]));
} catch (Exception e) {
Log.error(e);
return new String[0];
}
}
}
}
13 changes: 12 additions & 1 deletion src/test/java/io/cryostat/expressions/MatchExpressionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,18 @@ public void testPostWithoutTargets() {
}

@ParameterizedTest
@CsvSource(value = {"true, 200, true", "false, 200, false", "this is garbage, 400, false"})
@CsvSource(
delimiter = '|',
value = {
"true | 200 | true",
"false | 200 | false",
"this is garbage | 400 | false",
"target.alias == 'selftest' | 200 | true",
"target.alias == '' | 200 | false",
"jfrEventTypeIds(target).exists(x, x.contains('jdk')) | 200 | true",
"jfrEventTypeIds(target).exists(t, t.contains('nonsense')) | 200 | false",
"jfrEventTypeIds(target).exists(x, t.contains('wrong binding')) | 400 | false",
})
public void testExpressionTest(String expr, int status, boolean expectTargets) {
int id = defineSelfCustomTarget();

Expand Down

0 comments on commit 9ca5669

Please sign in to comment.