diff --git a/agent-test/build.gradle b/agent-test/build.gradle deleted file mode 100644 index 9b028d8f91..0000000000 --- a/agent-test/build.gradle +++ /dev/null @@ -1,57 +0,0 @@ -plugins { - id 'java' -} - -dependencies { - implementation(rootProject) - implementation("net.bytebuddy:byte-buddy-agent:1.17.6") - - testImplementation 'org.junit.jupiter:junit-jupiter:5.13.3' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - - testImplementation("org.assertj:assertj-core:3.27.3") - -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - -tasks.named('test', Test) { - dependsOn(':agent:shadowJar') - useJUnitPlatform() - - maxHeapSize = '4G' - - testLogging { - events "passed" - } -} - - -repositories { - mavenCentral() - mavenLocal() -} - - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - - -jar { - manifest { - attributes( - 'Agent-Class': 'graphql.agent.GraphQLJavaAgent', - 'Can-Redefine-Classes': 'true', - 'Can-Retransform-Classes': 'true', - 'Premain-Class': 'graphql.agent.GraphQLJavaAgent' - ) - } -} - diff --git a/agent-test/src/main/java/graphql/GraphQLApp.java b/agent-test/src/main/java/graphql/GraphQLApp.java deleted file mode 100644 index 9d12bfdb15..0000000000 --- a/agent-test/src/main/java/graphql/GraphQLApp.java +++ /dev/null @@ -1,40 +0,0 @@ -package graphql; - -import graphql.agent.result.ExecutionTrackingResult; -import graphql.schema.GraphQLSchema; -import graphql.schema.idl.RuntimeWiring; -import graphql.schema.idl.SchemaGenerator; -import graphql.schema.idl.SchemaParser; -import graphql.schema.idl.TypeDefinitionRegistry; - -/** - * Used for testing loading the agent on startup. - * See StartAgentOnStartupTest - */ -public class GraphQLApp { - - public static void main(String[] args) { - String schema = "type Query { hello: String }"; - TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(schema); - RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() - .type("Query", builder -> builder.dataFetcher("hello", environment -> "world")) - .build(); - GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); - GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build(); - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query("{ hello alias: hello alias2: hello }").build(); - GraphQLContext graphQLContext = executionInput.getGraphQLContext(); - ExecutionResult executionResult = graphQL.execute(executionInput); - System.out.println(executionResult.getData().toString()); - ExecutionTrackingResult executionTrackingResult = graphQLContext.get(ExecutionTrackingResult.EXECUTION_TRACKING_KEY); - if (executionTrackingResult == null) { - System.out.println("No tracking data found"); - System.exit(1); - } - if (executionTrackingResult.timePerPath.size() != 3) { - System.out.println("Expected 3 paths, got " + executionTrackingResult.timePerPath.size()); - System.exit(1); - } - System.out.println("Successfully tracked execution"); - System.exit(0); - } -} diff --git a/agent-test/src/test/java/graphql/test/AgentTest.java b/agent-test/src/test/java/graphql/test/AgentTest.java deleted file mode 100644 index a0add765c2..0000000000 --- a/agent-test/src/test/java/graphql/test/AgentTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package graphql.test; - -import graphql.agent.result.ExecutionTrackingResult; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; - -public class AgentTest { - - @BeforeAll - static void init() { - LoadAgent.loadIntoCurrentJVM(); - } - - @AfterAll - static void cleanup() { - } - - @Test - void test() { - ExecutionTrackingResult executionTrackingResult = TestQuery.executeQuery(); - assertThat(executionTrackingResult.dataFetcherCount()).isEqualTo(5); - assertThat(executionTrackingResult.getTime("/issues")).isGreaterThan(100); - assertThat(executionTrackingResult.getDfResultTypes("/issues")) - .isEqualTo(ExecutionTrackingResult.DFResultType.DONE_OK); - - verifyAgentDataIsEmpty(); - - } - - @Test - void testBatchLoader() { - ExecutionTrackingResult executionTrackingResult = TestQuery.executeBatchedQuery(); - assertThat(executionTrackingResult.dataFetcherCount()).isEqualTo(9); - assertThat(executionTrackingResult.getTime("/issues")).isGreaterThan(100); - assertThat(executionTrackingResult.getDfResultTypes("/issues[0]/author")) - .isEqualTo(ExecutionTrackingResult.DFResultType.PENDING); - assertThat(executionTrackingResult.getDfResultTypes("/issues[1]/author")) - .isEqualTo(ExecutionTrackingResult.DFResultType.PENDING); - - assertThat(executionTrackingResult.getDataLoaderNames()).isEqualTo(Collections.singletonList("userLoader")); - - assertThat(executionTrackingResult.dataLoaderNameToBatchCall).hasSize(1); - List userLoaderCalls = executionTrackingResult.dataLoaderNameToBatchCall.get("userLoader"); - assertThat(userLoaderCalls).hasSize(1); - ExecutionTrackingResult.BatchLoadingCall batchLoadingCall = userLoaderCalls.get(0); - - assertThat(batchLoadingCall.keyCount).isEqualTo(2); - - verifyAgentDataIsEmpty(); - } - - private void verifyAgentDataIsEmpty() { - try { - Class agent = Class.forName("graphql.agent.GraphQLJavaAgent"); - Map executionIdToData = (Map) agent.getField("executionIdToData").get(null); - Map dataLoaderToExecutionId = (Map) agent.getField("dataLoaderToExecutionId").get(null); - assertThat(executionIdToData).isEmpty(); - assertThat(dataLoaderToExecutionId).isEmpty(); - - } catch (Exception e) { - throw new RuntimeException(e); - } - - } -} diff --git a/agent-test/src/test/java/graphql/test/LoadAgent.java b/agent-test/src/test/java/graphql/test/LoadAgent.java deleted file mode 100644 index 90ec46a078..0000000000 --- a/agent-test/src/test/java/graphql/test/LoadAgent.java +++ /dev/null @@ -1,15 +0,0 @@ -package graphql.test; - -import net.bytebuddy.agent.ByteBuddyAgent; - -import java.io.File; - - -public class LoadAgent { - - - public static void loadIntoCurrentJVM() { - ByteBuddyAgent.attach(new File("../agent/build/libs/agent.jar"), String.valueOf(ProcessHandle.current().pid())); - } - -} diff --git a/agent-test/src/test/java/graphql/test/StartAgentOnStartupTest.java b/agent-test/src/test/java/graphql/test/StartAgentOnStartupTest.java deleted file mode 100644 index e4c8c3add6..0000000000 --- a/agent-test/src/test/java/graphql/test/StartAgentOnStartupTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package graphql.test; - -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; - -public class StartAgentOnStartupTest { - - - @Test - void testAgentCanBeLoadedAtStartup() throws IOException, InterruptedException { - // we use the classpath of the current test - String classPath = System.getProperty("java.class.path"); - ProcessBuilder processBuilder = new ProcessBuilder("java", "-javaagent:../agent/build/libs/agent.jar", "-classpath", classPath, "graphql.GraphQLApp"); - Process process = processBuilder.start(); - process.getErrorStream().transferTo(System.err); - process.getInputStream().transferTo(System.out); - int i = process.waitFor(); - assertThat(i).isZero(); - } -} diff --git a/agent-test/src/test/java/graphql/test/TestQuery.java b/agent-test/src/test/java/graphql/test/TestQuery.java deleted file mode 100644 index 2755cf230f..0000000000 --- a/agent-test/src/test/java/graphql/test/TestQuery.java +++ /dev/null @@ -1,102 +0,0 @@ -package graphql.test; - -import graphql.ExecutionInput; -import graphql.ExecutionResult; -import graphql.GraphQL; -import graphql.agent.result.ExecutionTrackingResult; -import graphql.schema.DataFetcher; -import graphql.schema.GraphQLSchema; -import graphql.schema.idl.RuntimeWiring; -import graphql.schema.idl.SchemaGenerator; -import graphql.schema.idl.SchemaParser; -import graphql.schema.idl.TypeDefinitionRegistry; -import org.assertj.core.api.Assertions; -import org.dataloader.BatchLoader; -import org.dataloader.DataLoader; -import org.dataloader.DataLoaderFactory; -import org.dataloader.DataLoaderRegistry; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -public class TestQuery { - - - static ExecutionTrackingResult executeQuery() { - String sdl = "type Query{issues: [Issue]} type Issue {id: ID, title: String}"; - TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(sdl); - DataFetcher issuesDF = (env) -> { - return List.of( - Map.of("id", "1", "title", "issue-1"), - Map.of("id", "2", "title", "issue-2")); - }; - - RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() - .type("Query", builder -> builder.dataFetcher("issues", issuesDF)) - .build(); - GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); - - GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build(); - - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query("{issues{id title}}").build(); - ExecutionResult result = graphQL.execute(executionInput); - Assertions.assertThat(result.getErrors()).isEmpty(); - ExecutionTrackingResult trackingResult = executionInput.getGraphQLContext().get(ExecutionTrackingResult.EXECUTION_TRACKING_KEY); - return trackingResult; - } - - static ExecutionTrackingResult executeBatchedQuery() { - String sdl = "type Query{issues: [Issue]} " + - "type Issue {id: ID, author: User}" + - "type User {id: ID, name: String}"; - - DataFetcher issuesDF = (env) -> List.of( - Map.of("id", "1", "title", "issue-1", "authorId", "user-1"), - Map.of("id", "2", "title", "issue-2", "authorId", "user-2")); - - BatchLoader userBatchLoader = keys -> { - // System.out.println("batch users with keys: " + keys); - return CompletableFuture.supplyAsync(() -> { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - return List.of( - Map.of("id", "user-1", "name", "Foo-1"), - Map.of("id", "user-2", "name", "Foo-2") - ); - }); - }; - DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); - dataLoaderRegistry.register("userLoader", DataLoaderFactory.newDataLoader(userBatchLoader)); - - DataFetcher> authorDF = (env) -> { - DataLoader userLoader = env.getDataLoader("userLoader"); - // System.out.println("author id: " + (String) ((Map) env.getSource()).get("authorId")); - return userLoader.load((String) ((Map) env.getSource()).get("authorId")); - }; - TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(sdl); - - RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() - .type("Query", builder -> builder.dataFetcher("issues", issuesDF)) - .type("Issue", builder -> builder.dataFetcher("author", authorDF)) - .build(); - GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); - - GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build(); - String query = "{issues" + - "{id author {id name}}" + - "}"; - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .dataLoaderRegistry(dataLoaderRegistry) - .query(query).build(); - ExecutionResult result = graphQL.execute(executionInput); - Assertions.assertThat(result.getErrors()).isEmpty(); - ExecutionTrackingResult trackingResult = executionInput.getGraphQLContext().get(ExecutionTrackingResult.EXECUTION_TRACKING_KEY); - return trackingResult; - } - - -} diff --git a/agent/build.gradle b/agent/build.gradle deleted file mode 100644 index 1c42010043..0000000000 --- a/agent/build.gradle +++ /dev/null @@ -1,124 +0,0 @@ -plugins { - id 'java' - id 'java-library' - id 'maven-publish' - id "com.gradleup.shadow" version "8.3.8" -} - -dependencies { - implementation("net.bytebuddy:byte-buddy:1.17.6") - // graphql-java itself - implementation(rootProject) -} - -repositories { - mavenCentral() - mavenLocal() -} - - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(11) - } -} - -shadowJar { - minimize() - archiveClassifier.set('') - configurations = [project.configurations.compileClasspath] - dependencies { - exclude(dependency(rootProject)) - } - manifest { - attributes( - 'Agent-Class': 'graphql.agent.GraphQLJavaAgent', - 'Premain-Class': 'graphql.agent.GraphQLJavaAgent', - 'Can-Redefine-Classes': 'true', - 'Can-Retransform-Classes': 'true', - ) - } -} - -task sourcesJar(type: Jar) { - dependsOn classes - archiveClassifier = 'sources' - from sourceSets.main.allSource -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - archiveClassifier = 'javadoc' - from javadoc.destinationDir -} - -publishing { - - publications { - - agent(MavenPublication) { - version rootProject.version - group rootProject.group - artifactId 'graphql-java-agent' - from components.java - - artifact sourcesJar { - archiveClassifier = "sources" - } - artifact javadocJar { - archiveClassifier = "javadoc" - } - pom.withXml { - // removing the shaded dependencies from the pom - def pomNode = asNode() - pomNode.dependencies.'*'.findAll() { - it.artifactId.text() == 'graphql-java' || it.artifactId.text() == 'byte-buddy' - }.each() { - it.parent().remove(it) - } - pomNode.children().last() + { - resolveStrategy = Closure.DELEGATE_FIRST - name 'graphql-java-agent' - description 'GraphqL Java Agent' - url "https://github.com/graphql-java/graphql-java" - scm { - url "https://github.com/graphql-java/graphql-java" - connection "https://github.com/graphql-java/graphql-java" - developerConnection "https://github.com/graphql-java/graphql-java" - } - licenses { - license { - name 'MIT' - url 'https://github.com/graphql-java/graphql-java/blob/master/LICENSE.md' - distribution 'repo' - } - } - developers { - developer { - id 'andimarek' - name 'Andreas Marek' - } - } - } - } - } - } -} - -signing { - required { !project.hasProperty('publishToMavenLocal') } - def signingKey = System.env.MAVEN_CENTRAL_PGP_KEY - useInMemoryPgpKeys(signingKey, "") - sign publishing.publications -} - - -// all publish tasks depend on the build task -tasks.withType(PublishToMavenRepository) { - dependsOn build -} - -// Only publish Maven POM, disable default Gradle modules file -tasks.withType(GenerateModuleMetadata) { - enabled = false -} - diff --git a/agent/src/main/java/graphql/agent/GraphQLJavaAgent.java b/agent/src/main/java/graphql/agent/GraphQLJavaAgent.java deleted file mode 100644 index 6169e2e7bd..0000000000 --- a/agent/src/main/java/graphql/agent/GraphQLJavaAgent.java +++ /dev/null @@ -1,301 +0,0 @@ -package graphql.agent; - -import graphql.agent.result.ExecutionTrackingResult; -import graphql.execution.ExecutionContext; -import graphql.execution.ExecutionId; -import graphql.execution.ExecutionStrategyParameters; -import graphql.execution.ResultPath; -import graphql.schema.DataFetchingEnvironment; -import net.bytebuddy.agent.builder.AgentBuilder; -import net.bytebuddy.asm.Advice; -import net.bytebuddy.implementation.bytecode.assign.Assigner; -import org.dataloader.DataLoader; -import org.dataloader.DataLoaderRegistry; -import org.dataloader.DispatchResult; - -import java.lang.instrument.Instrumentation; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiConsumer; - -import static graphql.agent.result.ExecutionTrackingResult.DFResultType.DONE_CANCELLED; -import static graphql.agent.result.ExecutionTrackingResult.DFResultType.DONE_EXCEPTIONALLY; -import static graphql.agent.result.ExecutionTrackingResult.DFResultType.DONE_OK; -import static graphql.agent.result.ExecutionTrackingResult.DFResultType.PENDING; -import static graphql.agent.result.ExecutionTrackingResult.EXECUTION_TRACKING_KEY; -import static net.bytebuddy.matcher.ElementMatchers.nameMatches; -import static net.bytebuddy.matcher.ElementMatchers.named; -import static net.bytebuddy.matcher.ElementMatchers.takesArguments; - -public class GraphQLJavaAgent { - - - public static final Map executionIdToData = new ConcurrentHashMap<>(); - public static final Map dataLoaderToExecutionId = new ConcurrentHashMap<>(); - - public static void premain(String agentArgs, Instrumentation inst) { - agentmain(agentArgs, inst); - } - - - public static void agentmain(String agentArgs, Instrumentation inst) { - System.out.println("GraphQL Java Agent is starting"); - new AgentBuilder.Default() - .type(named("graphql.execution.Execution")) - .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { - return builder - .visit(Advice.to(ExecutionAdvice.class).on(nameMatches("executeOperation"))); - - }) - .type(named("graphql.execution.ExecutionStrategy")) - .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { - return builder - .visit(Advice.to(DataFetcherInvokeAdvice.class).on(nameMatches("invokeDataFetcher"))); - }) - .type(named("org.dataloader.DataLoaderRegistry")) - .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { - return builder - .visit(Advice.to(DataLoaderRegistryAdvice.class).on(nameMatches("dispatchAll"))); - }) - .type(named("org.dataloader.DataLoader")) - .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { - return builder - .visit(Advice.to(DataLoaderLoadAdvice.class).on(nameMatches("load"))); - }) - .type(named("org.dataloader.DataLoaderHelper")) - .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { - return builder - .visit(Advice.to(DataLoaderHelperDispatchAdvice.class).on(nameMatches("dispatch"))) - .visit(Advice.to(DataLoaderHelperInvokeBatchLoaderAdvice.class) - .on(nameMatches("invokeLoader").and(takesArguments(List.class, List.class, List.class)))); - }) - .type(named("graphql.schema.DataFetchingEnvironmentImpl")) - .transform((builder, typeDescription, classLoader, module, protectionDomain) -> { - return builder - .visit(Advice.to(DataFetchingEnvironmentAdvice.class).on(nameMatches("getDataLoader"))); - }) - .disableClassFormatChanges() - .installOn(inst); - - } - - public static class ExecutionAdvice { - - public static class AfterExecutionHandler implements BiConsumer { - - private final ExecutionContext executionContext; - - public AfterExecutionHandler(ExecutionContext executionContext) { - this.executionContext = executionContext; - } - - public void accept(Object o, Throwable throwable) { - ExecutionId executionId = executionContext.getExecutionId(); - ExecutionTrackingResult executionTrackingResult = GraphQLJavaAgent.executionIdToData.get(executionId); - executionTrackingResult.endExecutionTime.set(System.nanoTime()); - executionTrackingResult.endThread.set(Thread.currentThread().getName()); - executionContext.getGraphQLContext().put(EXECUTION_TRACKING_KEY, executionTrackingResult); - // cleanup - for (DataLoader dataLoader : executionTrackingResult.dataLoaderToName.keySet()) { - dataLoaderToExecutionId.remove(dataLoader); - } - executionIdToData.remove(executionId); - - } - - } - - - @Advice.OnMethodEnter - public static void executeOperationEnter(@Advice.Argument(0) ExecutionContext executionContext) { - ExecutionTrackingResult executionTrackingResult = new ExecutionTrackingResult(); - executionTrackingResult.startExecutionTime.set(System.nanoTime()); - executionTrackingResult.startThread.set(Thread.currentThread().getName()); - executionContext.getGraphQLContext().put(EXECUTION_TRACKING_KEY, new ExecutionTrackingResult()); - - GraphQLJavaAgent.executionIdToData.put(executionContext.getExecutionId(), executionTrackingResult); - - DataLoaderRegistry dataLoaderRegistry = executionContext.getDataLoaderRegistry(); - for (String name : dataLoaderRegistry.getDataLoadersMap().keySet()) { - DataLoader dataLoader = dataLoaderRegistry.getDataLoader(name); - GraphQLJavaAgent.dataLoaderToExecutionId.put(dataLoader, executionContext.getExecutionId()); - executionTrackingResult.dataLoaderToName.put(dataLoader, name); - } - } - - @Advice.OnMethodExit - public static void executeOperationExit(@Advice.Argument(0) ExecutionContext executionContext, - @Advice.Return(typing = Assigner.Typing.DYNAMIC) CompletableFuture result) { - - result.whenComplete(new AfterExecutionHandler(executionContext)); - } - } - - public static class DataFetcherInvokeAdvice { - - public static class DataFetcherFinishedHandler implements BiConsumer { - - private final ExecutionContext executionContext; - private final ExecutionStrategyParameters parameters; - private final long startTime; - - public DataFetcherFinishedHandler(ExecutionContext executionContext, ExecutionStrategyParameters parameters, long startTime) { - this.executionContext = executionContext; - this.parameters = parameters; - this.startTime = startTime; - } - - @Override - public void accept(Object o, Throwable throwable) { - ExecutionId executionId = executionContext.getExecutionId(); - ExecutionTrackingResult executionTrackingResult = GraphQLJavaAgent.executionIdToData.get(executionId); - ResultPath path = parameters.getPath(); - executionTrackingResult.finishedTimePerPath.put(path, System.nanoTime() - startTime); - executionTrackingResult.finishedThreadPerPath.put(path, Thread.currentThread().getName()); - } - } - - @Advice.OnMethodEnter - public static void invokeDataFetcherEnter(@Advice.Argument(0) ExecutionContext executionContext, - @Advice.Argument(1) ExecutionStrategyParameters parameters) { - ExecutionTrackingResult executionTrackingResult = GraphQLJavaAgent.executionIdToData.get(executionContext.getExecutionId()); - executionTrackingResult.start(parameters.getPath(), System.nanoTime()); - executionTrackingResult.startInvocationThreadPerPath.put(parameters.getPath(), Thread.currentThread().getName()); - } - - @Advice.OnMethodExit - public static void invokeDataFetcherExit(@Advice.Argument(0) ExecutionContext executionContext, - @Advice.Argument(1) ExecutionStrategyParameters parameters, - @Advice.Return(readOnly = false) Object cfOrObject) { - // ExecutionTrackingResult executionTrackingResult = executionContext.getGraphQLContext().get(EXECUTION_TRACKING_KEY); - ExecutionTrackingResult executionTrackingResult = GraphQLJavaAgent.executionIdToData.get(executionContext.getExecutionId()); - ResultPath path = parameters.getPath(); - long startTime = executionTrackingResult.timePerPath.get(path); - executionTrackingResult.end(path, System.nanoTime()); - if (cfOrObject instanceof CompletableFuture) { - CompletableFuture result = (CompletableFuture) cfOrObject; - if (result.isDone()) { - if (result.isCancelled()) { - executionTrackingResult.setDfResultTypes(path, DONE_CANCELLED); - } else if (result.isCompletedExceptionally()) { - executionTrackingResult.setDfResultTypes(path, DONE_EXCEPTIONALLY); - } else { - executionTrackingResult.setDfResultTypes(path, DONE_OK); - } - } else { - executionTrackingResult.setDfResultTypes(path, PENDING); - } - // overriding the result to make sure the finished handler is called first when the DF is finished - // otherwise it is a completion tree instead of chain - cfOrObject = result.whenComplete(new DataFetcherFinishedHandler(executionContext, parameters, startTime)); - } else { - // materialized value - not a CF - executionTrackingResult.setDfResultTypes(path, DONE_OK); - new DataFetcherFinishedHandler(executionContext, parameters, startTime).accept(cfOrObject, null); - } - } - - } - - - public static class DataLoaderHelperInvokeBatchLoaderAdvice { - - @Advice.OnMethodEnter - public static void invokeLoader(@Advice.Argument(0) List keys, - @Advice.Argument(1) List keysContext, - @Advice.Argument(2) List queuedFutures, - @Advice.This(typing = Assigner.Typing.DYNAMIC) Object dataLoaderHelper) { - DataLoader dataLoader = getDataLoaderForHelper(dataLoaderHelper); - ExecutionId executionId = GraphQLJavaAgent.dataLoaderToExecutionId.get(dataLoader); - ExecutionTrackingResult executionTrackingResult = GraphQLJavaAgent.executionIdToData.get(executionId); - String dataLoaderName = executionTrackingResult.dataLoaderToName.get(dataLoader); - - synchronized (executionTrackingResult.dataLoaderNameToBatchCall) { - executionTrackingResult.dataLoaderNameToBatchCall.putIfAbsent(dataLoaderName, new ArrayList<>()); - executionTrackingResult.dataLoaderNameToBatchCall.get(dataLoaderName) - .add(new ExecutionTrackingResult.BatchLoadingCall(keys.size(), Thread.currentThread().getName())); - } - - } - } - - public static class DataLoaderHelperDispatchAdvice { - - @Advice.OnMethodExit - public static void dispatch(@Advice.This(typing = Assigner.Typing.DYNAMIC) Object dataLoaderHelper, - @Advice.Return(typing = Assigner.Typing.DYNAMIC) DispatchResult dispatchResult) { - try { - // System.out.println("dataloader helper Dispatch " + dataLoaderHelper + " load for execution " + dispatchResult); - // DataLoader dataLoader = getDataLoaderForHelper(dataLoaderHelper); - // // System.out.println("dataLoader: " + dataLoader); - // ExecutionId executionId = GraphQLJavaAgent.dataLoaderToExecutionId.get(dataLoader); - // ExecutionTrackingResult ExecutionTrackingResult = GraphQLJavaAgent.executionIdToData.get(executionId); - // String dataLoaderName = ExecutionTrackingResult.dataLoaderToName.get(dataLoader); - // - // ExecutionTrackingResult.dataLoaderNameToBatchCall.putIfAbsent(dataLoaderName, new ArrayList<>()); - // ExecutionTrackingResult.dataLoaderNameToBatchCall.get(dataLoaderName).add(new ExecutionTrackingResult.BatchLoadingCall(dispatchResult.getKeysCount())); - - } catch (Exception e) { - e.printStackTrace(); - } - - } - - } - - public static DataLoader getDataLoaderForHelper(Object dataLoaderHelper) { - try { - Field field = dataLoaderHelper.getClass().getDeclaredField("dataLoader"); - field.setAccessible(true); - return (DataLoader) field.get(dataLoaderHelper); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - -} - -class DataFetchingEnvironmentAdvice { - - - @Advice.OnMethodExit - public static void getDataLoader(@Advice.Argument(0) String dataLoaderName, - @Advice.This(typing = Assigner.Typing.DYNAMIC) DataFetchingEnvironment dataFetchingEnvironment, - @Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) DataLoader dataLoader) { - ExecutionTrackingResult executionTrackingResult = GraphQLJavaAgent.executionIdToData.get(dataFetchingEnvironment.getExecutionId()); - ResultPath resultPath = dataFetchingEnvironment.getExecutionStepInfo().getPath(); - executionTrackingResult.resultPathToDataLoaderUsed.put(resultPath, dataLoaderName); - - } - -} - - -class DataLoaderLoadAdvice { - - @Advice.OnMethodEnter - public static void load(@Advice.This(typing = Assigner.Typing.DYNAMIC) Object dataLoader) { - ExecutionId executionId = GraphQLJavaAgent.dataLoaderToExecutionId.get(dataLoader); - String dataLoaderName = GraphQLJavaAgent.executionIdToData.get(executionId).dataLoaderToName.get(dataLoader); - } - -} - -class DataLoaderRegistryAdvice { - - @Advice.OnMethodEnter - public static void dispatchAll(@Advice.This(typing = Assigner.Typing.DYNAMIC) Object dataLoaderRegistry) { - List> dataLoaders = ((DataLoaderRegistry) dataLoaderRegistry).getDataLoaders(); - ExecutionId executionId = GraphQLJavaAgent.dataLoaderToExecutionId.get(dataLoaders.get(0)); - } - -} - - - diff --git a/settings.gradle b/settings.gradle index 4667568288..b4870c3fc3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,4 +17,3 @@ plugins { } rootProject.name = 'graphql-java' -include("agent", "agent-test")