diff --git a/gradle.properties b/gradle.properties index 79ca433d4..904fdfffb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # The agent version. agentVersion=1.4.2 -jsonVersion=1.2.7 +jsonVersion=1.2.9 # Updated exposed NR APM API version. nrAPIVersion=8.12.0 diff --git a/instrumentation-security/graphql-java-16.2/build.gradle b/instrumentation-security/graphql-java-16.2/build.gradle new file mode 100644 index 000000000..2ac60f459 --- /dev/null +++ b/instrumentation-security/graphql-java-16.2/build.gradle @@ -0,0 +1,22 @@ +dependencies { + implementation(project(":newrelic-security-api")) + implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}") + implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}") + implementation("com.graphql-java:graphql-java:16.2") +} + +jar { + manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.graphql-java-16.2' } +} + +verifyInstrumentation { + passesOnly('com.graphql-java:graphql-java:[16.0,)') + excludeRegex('com.graphql-java:graphql-java:(0.0.0|201|202).*') + excludeRegex('com.graphql-java:graphql-java:.*(vTEST|-beta|-alpha1|-nf-execution|-rc|-TEST).*') + exclude('com.graphql-java:graphql-java:15.0') +} + +site { + title 'GraphQL Java' + type 'Framework' +} diff --git a/instrumentation-security/graphql-java-16.2/src/main/java/graphql/GraphQL_Instrumentation.java b/instrumentation-security/graphql-java-16.2/src/main/java/graphql/GraphQL_Instrumentation.java new file mode 100644 index 000000000..bf6f1bbe8 --- /dev/null +++ b/instrumentation-security/graphql-java-16.2/src/main/java/graphql/GraphQL_Instrumentation.java @@ -0,0 +1,32 @@ +package graphql; + +import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.HttpRequestCustomDataTypeEnum; +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; +import graphql.execution.instrumentation.InstrumentationState; +import graphql.language.Document; +import graphql.schema.GraphQLSchema; + +import java.util.concurrent.CompletableFuture; + +@Weave(originalName = "graphql.GraphQL", type = MatchType.ExactClass) +public class GraphQL_Instrumentation { + + private CompletableFuture execute(ExecutionInput executionInput, Document document, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState) { + try { + if (NewRelicSecurity.isHookProcessingActive()) { + HttpRequest request = NewRelicSecurity.getAgent().getSecurityMetaData().getRequest(); + if (executionInput.getQuery() != null && !executionInput.getQuery().isEmpty()) { + request.getCustomDataType().put("*.query", HttpRequestCustomDataTypeEnum.GRAPHQL_QUERY.name()); + } + if (executionInput.getVariables() != null && !executionInput.getVariables().isEmpty()) { + request.getCustomDataType().put("*.variables", HttpRequestCustomDataTypeEnum.GRAPHQL_VARIABLE.name()); + } + } + } catch (Exception ignored) {} + return Weaver.callOriginal(); + } +} diff --git a/instrumentation-security/graphql-java-16.2/src/main/java/graphql/ParseAndValidate_Instrumentation.java b/instrumentation-security/graphql-java-16.2/src/main/java/graphql/ParseAndValidate_Instrumentation.java new file mode 100644 index 000000000..84c3ddf2b --- /dev/null +++ b/instrumentation-security/graphql-java-16.2/src/main/java/graphql/ParseAndValidate_Instrumentation.java @@ -0,0 +1,9 @@ +package graphql; + +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; + +@Weave(originalName = "graphql.ParseAndValidate", type = MatchType.ExactClass) +public class ParseAndValidate_Instrumentation { + +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequest.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequest.java index 3da2d74d7..1910758bd 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequest.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequest.java @@ -1,7 +1,6 @@ package com.newrelic.api.agent.security.schema; import com.newrelic.api.agent.security.schema.annotations.JsonIgnore; - import java.nio.file.Paths; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -37,9 +36,13 @@ public class HttpRequest { private Map pathParameterMap; private boolean isRequestParsed; + private boolean isGrpc; + private String route; + private Map customDataType; + @JsonIgnore private List pathParameters; @@ -70,6 +73,7 @@ public HttpRequest() { this.isRequestParsed = false; this.isGrpc = false; this.route = StringUtils.EMPTY; + this.customDataType = new HashMap<>(); } public HttpRequest(HttpRequest servletInfo) { @@ -92,6 +96,7 @@ public HttpRequest(HttpRequest servletInfo) { this.requestHeaderParameters = servletInfo.requestHeaderParameters; this.requestBodyParameters = servletInfo.requestBodyParameters; this.isRequestParametersParsed = servletInfo.isRequestParametersParsed; + this.customDataType = servletInfo.customDataType; } public String getMethod() { @@ -294,6 +299,11 @@ public boolean isRequestParametersParsed() { public void setRequestParametersParsed(boolean requestParametersParsed) { isRequestParametersParsed = requestParametersParsed; } + + public Map getCustomDataType() { + return customDataType; + } + } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequestCustomDataTypeEnum.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequestCustomDataTypeEnum.java new file mode 100644 index 000000000..473eefc83 --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequestCustomDataTypeEnum.java @@ -0,0 +1,8 @@ +package com.newrelic.api.agent.security.schema; + +public enum HttpRequestCustomDataTypeEnum { + GRAPHQL_QUERY, + GRAPHQL_VARIABLE, + + NONE; +} diff --git a/settings.gradle b/settings.gradle index a2b70cb0c..64dd79da8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -216,4 +216,5 @@ include 'instrumentation:solr-5.1.0' include 'instrumentation:solr-7.0.0' include 'instrumentation:solr-8.0.0' include 'instrumentation:solr-9.0.0' +include 'instrumentation:graphql-java-16.2' include 'instrumentation:websphere-liberty-profile-environment-8.5.5.5' \ No newline at end of file