diff --git a/hypertrace-core-graphql-platform/build.gradle.kts b/hypertrace-core-graphql-platform/build.gradle.kts index 77716efb..de256c14 100644 --- a/hypertrace-core-graphql-platform/build.gradle.kts +++ b/hypertrace-core-graphql-platform/build.gradle.kts @@ -16,7 +16,7 @@ dependencies { api("org.hypertrace.core.grpcutils:grpc-context-utils:0.12.1") api("org.hypertrace.core.grpcutils:grpc-client-utils:0.12.1") api("org.hypertrace.core.grpcutils:grpc-client-rx-utils:0.12.1") - api("org.hypertrace.gateway.service:gateway-service-api:0.2.25") + api("org.hypertrace.gateway.service:gateway-service-api:0.3.0") api("org.hypertrace.core.attribute.service:caching-attribute-service-client:${attributeServiceVersion}") api("org.hypertrace.core.attribute.service:attribute-service-api:${attributeServiceVersion}") diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanConverter.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanConverter.java index e1d96932..beda91fc 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanConverter.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanConverter.java @@ -34,7 +34,7 @@ class GatewayServiceSpanConverter { } public Single convert(SpanRequest request, SpanLogEventsResponse response) { - int total = response.spansResponse().getTotal(); + int total = response.spansResponse().hasTotal() ? response.spansResponse().getTotal() : 0; return Observable.fromIterable(response.spansResponse().getSpansList()) .flatMapSingle(spanEvent -> this.convert(request, spanEvent, response.spanIdToLogEvents())) diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanRequestBuilder.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanRequestBuilder.java index 48798841..1445d3a9 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanRequestBuilder.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanRequestBuilder.java @@ -56,6 +56,7 @@ Single buildRequest(SpanRequest gqlRequest) { .spanEventsRequest() .spaceId() .orElse("")) // String proto default value + .setFetchTotal(gqlRequest.fetchTotal()) .build()); } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/DefaultSpanRequestBuilder.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/DefaultSpanRequestBuilder.java index 2cae9188..6d498f52 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/DefaultSpanRequestBuilder.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/DefaultSpanRequestBuilder.java @@ -15,20 +15,26 @@ import org.hypertrace.core.graphql.common.request.ResultSetRequest; import org.hypertrace.core.graphql.common.request.ResultSetRequestBuilder; import org.hypertrace.core.graphql.common.schema.attributes.arguments.AttributeExpression; +import org.hypertrace.core.graphql.common.schema.results.ResultSet; import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.utils.schema.GraphQlSelectionFinder; +import org.hypertrace.core.graphql.utils.schema.SelectionQuery; class DefaultSpanRequestBuilder implements SpanRequestBuilder { private final ResultSetRequestBuilder resultSetRequestBuilder; private final LogEventAttributeRequestBuilder logEventAttributeRequestBuilder; + private final GraphQlSelectionFinder selectionFinder; @Inject public DefaultSpanRequestBuilder( ResultSetRequestBuilder resultSetRequestBuilder, - LogEventAttributeRequestBuilder logEventAttributeRequestBuilder) { + LogEventAttributeRequestBuilder logEventAttributeRequestBuilder, + GraphQlSelectionFinder selectionFinder) { this.resultSetRequestBuilder = resultSetRequestBuilder; this.logEventAttributeRequestBuilder = logEventAttributeRequestBuilder; + this.selectionFinder = selectionFinder; } @Override @@ -36,6 +42,13 @@ public Single build( GraphQlRequestContext context, Map arguments, DataFetchingFieldSelectionSet selectionSet) { + boolean fetchTotal = + this.selectionFinder + .findSelections( + selectionSet, SelectionQuery.namedChild(ResultSet.RESULT_SET_TOTAL_NAME)) + .count() + > 0; + return zip( resultSetRequestBuilder.build( context, @@ -45,7 +58,8 @@ public Single build( OrderArgument.class), logEventAttributeRequestBuilder.buildAttributeRequest(context, selectionSet), (resultSetRequest, logEventAttributeRequest) -> - new DefaultSpanRequest(context, resultSetRequest, logEventAttributeRequest)); + new DefaultSpanRequest( + context, resultSetRequest, logEventAttributeRequest, fetchTotal)); } @Override @@ -54,12 +68,16 @@ public Single build( Map arguments, List spanAttributeExpressions, List logAttributeExpressions) { + return zip( resultSetRequestBuilder.build( context, HypertraceCoreAttributeScopeString.SPAN, arguments, spanAttributeExpressions), logEventAttributeRequestBuilder.buildAttributeRequest(context, logAttributeExpressions), (resultSetRequest, logEventAttributeRequest) -> - new DefaultSpanRequest(context, resultSetRequest, logEventAttributeRequest)); + // This build method is utilized in the exportSpans API, which does not accept the total + // parameter as an argument. Ref {@link ExportSpanResult}. + // So, we explicitly set fetchTotal to false. + new DefaultSpanRequest(context, resultSetRequest, logEventAttributeRequest, false)); } @Value @@ -68,5 +86,6 @@ private static class DefaultSpanRequest implements SpanRequest { GraphQlRequestContext context; ResultSetRequest spanEventsRequest; Collection logEventAttributes; + boolean fetchTotal; } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequest.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequest.java index 471debb3..3e04e01d 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequest.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequest.java @@ -10,4 +10,6 @@ public interface SpanRequest extends ContextualRequest { ResultSetRequest spanEventsRequest(); Collection logEventAttributes(); + + boolean fetchTotal(); } diff --git a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/DaoTestUtil.java b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/DaoTestUtil.java index d6ecc19c..19a9d6f2 100644 --- a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/DaoTestUtil.java +++ b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/DaoTestUtil.java @@ -72,6 +72,7 @@ static class DefaultSpanRequest implements SpanRequest { GraphQlRequestContext context; ResultSetRequest spanEventsRequest; Collection logEventAttributes; + boolean fetchTotal; } @Value diff --git a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilderTest.java b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilderTest.java index ffa5fba0..1258ee03 100644 --- a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilderTest.java +++ b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilderTest.java @@ -152,7 +152,8 @@ void testBuildRequest() { List.of(), Collections.emptyList(), Optional.empty()); - SpanRequest spanRequest = new DefaultSpanRequest(null, resultSetRequest, logAttributeRequests); + SpanRequest spanRequest = + new DefaultSpanRequest(null, resultSetRequest, logAttributeRequests, true); LogEventsRequest expectedLogEventsRequest = LogEventsRequest.newBuilder() @@ -193,7 +194,8 @@ void testBuildRequest_addSpanId() { List.of(), Collections.emptyList(), Optional.empty()); - SpanRequest spanRequest = new DefaultSpanRequest(null, resultSetRequest, logAttributeRequests); + SpanRequest spanRequest = + new DefaultSpanRequest(null, resultSetRequest, logAttributeRequests, true); LogEventsRequest expectedLogEventsRequest = LogEventsRequest.newBuilder() diff --git a/hypertrace-core-graphql-trace-schema/build.gradle.kts b/hypertrace-core-graphql-trace-schema/build.gradle.kts index ffeb5590..f1a9e9f9 100644 --- a/hypertrace-core-graphql-trace-schema/build.gradle.kts +++ b/hypertrace-core-graphql-trace-schema/build.gradle.kts @@ -24,4 +24,5 @@ dependencies { implementation(project(":hypertrace-core-graphql-attribute-store")) implementation(project(":hypertrace-core-graphql-deserialization")) implementation(project(":hypertrace-core-graphql-request-transformation")) + implementation(project(":hypertrace-core-graphql-schema-utils")) } diff --git a/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/dao/GatewayServiceTraceConverter.java b/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/dao/GatewayServiceTraceConverter.java index 263e481a..0a637e46 100644 --- a/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/dao/GatewayServiceTraceConverter.java +++ b/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/dao/GatewayServiceTraceConverter.java @@ -30,8 +30,7 @@ public class GatewayServiceTraceConverter { } public Single convert(ResultSetRequest request, TracesResponse response) { - int total = response.getTotal(); - + int total = response.hasTotal() ? response.getTotal() : 0; return Observable.fromIterable(response.getTracesList()) .flatMapSingle(trace -> this.convert(request, trace)) .toList() diff --git a/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/dao/GatewayServiceTraceRequestBuilder.java b/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/dao/GatewayServiceTraceRequestBuilder.java index ffa630c6..1cb37645 100644 --- a/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/dao/GatewayServiceTraceRequestBuilder.java +++ b/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/dao/GatewayServiceTraceRequestBuilder.java @@ -54,6 +54,7 @@ Single buildRequest(TraceRequest request) { .setFilter(filters) .setSpaceId( request.resultSetRequest().spaceId().orElse("")) // String proto default value + .setFetchTotal(request.fetchTotal()) .build()); } } diff --git a/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/request/DefaultTraceRequestBuilder.java b/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/request/DefaultTraceRequestBuilder.java index 4167e64e..7bd799b8 100644 --- a/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/request/DefaultTraceRequestBuilder.java +++ b/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/request/DefaultTraceRequestBuilder.java @@ -8,22 +8,29 @@ import lombok.experimental.Accessors; import org.hypertrace.core.graphql.common.request.ResultSetRequest; import org.hypertrace.core.graphql.common.request.ResultSetRequestBuilder; +import org.hypertrace.core.graphql.common.schema.results.ResultSet; import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.context.GraphQlRequestContext; import org.hypertrace.core.graphql.deserialization.ArgumentDeserializer; import org.hypertrace.core.graphql.trace.schema.arguments.TraceType; import org.hypertrace.core.graphql.trace.schema.arguments.TraceTypeArgument; +import org.hypertrace.core.graphql.utils.schema.GraphQlSelectionFinder; +import org.hypertrace.core.graphql.utils.schema.SelectionQuery; class DefaultTraceRequestBuilder implements TraceRequestBuilder { private final ResultSetRequestBuilder resultSetRequestBuilder; private final ArgumentDeserializer argumentDeserializer; + private final GraphQlSelectionFinder selectionFinder; @Inject DefaultTraceRequestBuilder( - ResultSetRequestBuilder resultSetRequestBuilder, ArgumentDeserializer argumentDeserializer) { + ResultSetRequestBuilder resultSetRequestBuilder, + ArgumentDeserializer argumentDeserializer, + GraphQlSelectionFinder selectionFinder) { this.resultSetRequestBuilder = resultSetRequestBuilder; this.argumentDeserializer = argumentDeserializer; + this.selectionFinder = selectionFinder; } @Override @@ -37,18 +44,28 @@ public Single build( .deserializePrimitive(arguments, TraceTypeArgument.class) .orElseThrow(); - return this.build(context, traceType, arguments, selectionSet); + boolean fetchTotal = + this.selectionFinder + .findSelections( + selectionSet, SelectionQuery.namedChild(ResultSet.RESULT_SET_TOTAL_NAME)) + .count() + > 0; + + return this.build(context, traceType, arguments, selectionSet, fetchTotal); } private Single build( GraphQlRequestContext context, TraceType traceType, Map arguments, - DataFetchingFieldSelectionSet selectionSet) { + DataFetchingFieldSelectionSet selectionSet, + boolean fetchTotal) { return this.resultSetRequestBuilder .build(context, traceType.getScopeString(), arguments, selectionSet) - .map(resultSetRequest -> new DefaultTraceRequest(context, resultSetRequest, traceType)); + .map( + resultSetRequest -> + new DefaultTraceRequest(context, resultSetRequest, traceType, fetchTotal)); } @Value @@ -57,5 +74,6 @@ private static class DefaultTraceRequest implements TraceRequest { GraphQlRequestContext context; ResultSetRequest resultSetRequest; TraceType traceType; + boolean fetchTotal; } } diff --git a/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/request/TraceRequest.java b/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/request/TraceRequest.java index 05c169bb..c8704aeb 100644 --- a/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/request/TraceRequest.java +++ b/hypertrace-core-graphql-trace-schema/src/main/java/org/hypertrace/core/graphql/trace/request/TraceRequest.java @@ -9,4 +9,6 @@ public interface TraceRequest extends ContextualRequest { ResultSetRequest resultSetRequest(); TraceType traceType(); + + boolean fetchTotal(); } diff --git a/owasp-suppressions.xml b/owasp-suppressions.xml index 894dcf1b..07948e5c 100644 --- a/owasp-suppressions.xml +++ b/owasp-suppressions.xml @@ -15,7 +15,7 @@ ^pkg:maven/io\.github\.graphql\-java/graphql\-java\-annotations@.*$ cpe:/a:graphql-java:graphql-java - +