From 967df5310ffbe69f2f544d77fb94fec622150afb Mon Sep 17 00:00:00 2001 From: rish691 Date: Mon, 26 Apr 2021 22:32:17 +0530 Subject: [PATCH 1/9] Capability to fetch logs alongwith span --- .../schema/attributes/AttributeQueryable.java | 1 + .../build.gradle.kts | 3 + .../dao/GatewayServiceFutureStubProvider.java | 34 +++ .../span/dao/GatewayServiceSpanConverter.java | 29 ++- .../span/dao/GatewayServiceSpanDao.java | 28 +-- .../dao/GatewayServiceSpanRequestBuilder.java | 26 ++- .../core/graphql/span/dao/SpanDao.java | 4 +- .../core/graphql/span/dao/SpanDaoModule.java | 6 +- .../graphql/span/dao/SpanLogEventFetcher.java | 193 ++++++++++++++++++ .../span/dao/SpanLogEventsResponse.java | 15 ++ .../graphql/span/fetcher/SpanFetcher.java | 6 +- .../request/DefaultSpanRequestBuilder.java | 83 ++++++++ .../LogEventAttributeRequestBuilder.java | 51 +++++ .../graphql/span/request/SpanRequest.java | 12 ++ .../span/request/SpanRequestBuilder.java | 16 ++ .../span/request/SpanRequestModule.java | 25 +++ .../core/graphql/span/schema/Span.java | 8 + 17 files changed, 498 insertions(+), 42 deletions(-) create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceFutureStubProvider.java create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventsResponse.java create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/DefaultSpanRequestBuilder.java create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequest.java create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestModule.java diff --git a/hypertrace-core-graphql-common-schema/src/main/java/org/hypertrace/core/graphql/common/schema/attributes/AttributeQueryable.java b/hypertrace-core-graphql-common-schema/src/main/java/org/hypertrace/core/graphql/common/schema/attributes/AttributeQueryable.java index 6557abe6..c52da8df 100644 --- a/hypertrace-core-graphql-common-schema/src/main/java/org/hypertrace/core/graphql/common/schema/attributes/AttributeQueryable.java +++ b/hypertrace-core-graphql-common-schema/src/main/java/org/hypertrace/core/graphql/common/schema/attributes/AttributeQueryable.java @@ -6,6 +6,7 @@ import org.hypertrace.core.graphql.common.schema.attributes.arguments.AttributeKeyArgument; public interface AttributeQueryable { + String ATTRIBUTE_FIELD_NAME = "attribute"; @GraphQLField diff --git a/hypertrace-core-graphql-span-schema/build.gradle.kts b/hypertrace-core-graphql-span-schema/build.gradle.kts index 664c7473..e2613cfb 100644 --- a/hypertrace-core-graphql-span-schema/build.gradle.kts +++ b/hypertrace-core-graphql-span-schema/build.gradle.kts @@ -22,4 +22,7 @@ dependencies { implementation(project(":hypertrace-core-graphql-grpc-utils")) implementation(project(":hypertrace-core-graphql-common-schema")) implementation(project(":hypertrace-core-graphql-attribute-store")) + implementation(project(":hypertrace-core-graphql-log-event-schema")) + implementation(project(":hypertrace-core-graphql-deserialization")) + implementation(project(":hypertrace-core-graphql-schema-utils")) } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceFutureStubProvider.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceFutureStubProvider.java new file mode 100644 index 00000000..644f91cc --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceFutureStubProvider.java @@ -0,0 +1,34 @@ +package org.hypertrace.core.graphql.span.dao; + +import io.grpc.CallCredentials; +import javax.inject.Inject; +import javax.inject.Provider; +import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig; +import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry; +import org.hypertrace.gateway.service.GatewayServiceGrpc; +import org.hypertrace.gateway.service.GatewayServiceGrpc.GatewayServiceFutureStub; + +class GatewayServiceFutureStubProvider implements Provider { + + private final GraphQlServiceConfig serviceConfig; + private final CallCredentials credentials; + private final GrpcChannelRegistry channelRegistry; + + @Inject + GatewayServiceFutureStubProvider( + GraphQlServiceConfig serviceConfig, + CallCredentials credentials, + GrpcChannelRegistry channelRegistry) { + this.serviceConfig = serviceConfig; + this.credentials = credentials; + this.channelRegistry = channelRegistry; + } + + @Override + public GatewayServiceFutureStub get() { + return GatewayServiceGrpc.newFutureStub( + channelRegistry.forAddress( + serviceConfig.getGatewayServiceHost(), serviceConfig.getGatewayServicePort())) + .withCallCredentials(credentials); + } +} 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 faa91b9d..4f8a0502 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 @@ -8,13 +8,13 @@ import javax.inject.Inject; import lombok.experimental.Accessors; import org.hypertrace.core.graphql.common.request.AttributeRequest; -import org.hypertrace.core.graphql.common.request.ResultSetRequest; import org.hypertrace.core.graphql.common.utils.BiConverter; +import org.hypertrace.core.graphql.log.event.schema.LogEvent; +import org.hypertrace.core.graphql.span.request.SpanRequest; import org.hypertrace.core.graphql.span.schema.Span; import org.hypertrace.core.graphql.span.schema.SpanResultSet; import org.hypertrace.gateway.service.v1.common.Value; import org.hypertrace.gateway.service.v1.span.SpanEvent; -import org.hypertrace.gateway.service.v1.span.SpansResponse; class GatewayServiceSpanConverter { @@ -28,22 +28,27 @@ class GatewayServiceSpanConverter { this.attributeMapConverter = attributeMapConverter; } - public Single convert(ResultSetRequest request, SpansResponse response) { - int total = response.getTotal(); + public Single convert(SpanRequest request, SpanLogEventsResponse response) { + int total = response.spansResponse().getTotal(); - return Observable.fromIterable(response.getSpansList()) - .flatMapSingle(spanEvent -> this.convert(request, spanEvent)) + return Observable.fromIterable(response.spansResponse().getSpansList()) + .flatMapSingle(spanEvent -> this.convert(request, spanEvent, response.spanIdToLogEvents())) .toList() .map(spans -> new ConvertedSpanResultSet(spans, total, spans.size())); } - private Single convert(ResultSetRequest request, SpanEvent spanEvent) { + private Single convert( + SpanRequest request, SpanEvent spanEvent, Map> spanIdToLogEvents) { return this.attributeMapConverter - .convert(request.attributes(), spanEvent.getAttributesMap()) + .convert(request.spanEventsRequest().attributes(), spanEvent.getAttributesMap()) .map( attrMap -> new ConvertedSpan( - attrMap.get(request.idAttribute().attribute().key()).toString(), attrMap)); + attrMap + .get(request.spanEventsRequest().idAttribute().attribute().key()) + .toString(), + attrMap, + spanIdToLogEvents)); } @lombok.Value @@ -51,11 +56,17 @@ private Single convert(ResultSetRequest request, SpanEvent spanEvent) { private static class ConvertedSpan implements Span { String id; Map attributeValues; + Map> spanIdToLogEvents; @Override public Object attribute(String key) { return this.attributeValues.get(key); } + + @Override + public List logEvents() { + return spanIdToLogEvents.get(id); + } } @lombok.Value diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java index 07a1c8eb..0878aa26 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java @@ -2,18 +2,14 @@ import static java.util.concurrent.TimeUnit.SECONDS; -import io.grpc.CallCredentials; import io.reactivex.rxjava3.core.Single; import javax.inject.Inject; import javax.inject.Singleton; -import org.hypertrace.core.graphql.common.request.ResultSetRequest; import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.span.request.SpanRequest; import org.hypertrace.core.graphql.span.schema.SpanResultSet; -import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig; import org.hypertrace.core.graphql.utils.grpc.GraphQlGrpcContextBuilder; -import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry; -import org.hypertrace.gateway.service.GatewayServiceGrpc; import org.hypertrace.gateway.service.GatewayServiceGrpc.GatewayServiceFutureStub; import org.hypertrace.gateway.service.v1.span.SpansRequest; import org.hypertrace.gateway.service.v1.span.SpansResponse; @@ -25,31 +21,29 @@ class GatewayServiceSpanDao implements SpanDao { private final GraphQlGrpcContextBuilder grpcContextBuilder; private final GatewayServiceSpanRequestBuilder requestBuilder; private final GatewayServiceSpanConverter spanConverter; + private final SpanLogEventFetcher spanLogEventFetcher; @Inject GatewayServiceSpanDao( - GraphQlServiceConfig serviceConfig, - CallCredentials credentials, + GatewayServiceFutureStubProvider gatewayServiceFutureStubProvider, GraphQlGrpcContextBuilder grpcContextBuilder, - GrpcChannelRegistry channelRegistry, GatewayServiceSpanRequestBuilder requestBuilder, - GatewayServiceSpanConverter spanConverter) { + GatewayServiceSpanConverter spanConverter, + SpanLogEventFetcher spanLogEventFetcher) { this.grpcContextBuilder = grpcContextBuilder; this.requestBuilder = requestBuilder; this.spanConverter = spanConverter; - - this.gatewayServiceStub = - GatewayServiceGrpc.newFutureStub( - channelRegistry.forAddress( - serviceConfig.getGatewayServiceHost(), serviceConfig.getGatewayServicePort())) - .withCallCredentials(credentials); + this.spanLogEventFetcher = spanLogEventFetcher; + this.gatewayServiceStub = gatewayServiceFutureStubProvider.get(); } @Override - public Single getSpans(ResultSetRequest request) { + public Single getSpans(SpanRequest request) { return this.requestBuilder .buildRequest(request) - .flatMap(serverRequest -> this.makeRequest(request.context(), serverRequest)) + .flatMap( + serverRequest -> this.makeRequest(request.spanEventsRequest().context(), serverRequest)) + .flatMap(serverResponse -> spanLogEventFetcher.fetchLogEvents(request, serverResponse)) .flatMap(serverResponse -> this.spanConverter.convert(request, serverResponse)); } 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 a38de1df..f7fe6f9e 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 @@ -9,10 +9,10 @@ import javax.inject.Inject; import org.hypertrace.core.graphql.common.request.AttributeAssociation; import org.hypertrace.core.graphql.common.request.AttributeRequest; -import org.hypertrace.core.graphql.common.request.ResultSetRequest; import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.common.utils.Converter; +import org.hypertrace.core.graphql.span.request.SpanRequest; import org.hypertrace.gateway.service.v1.common.Expression; import org.hypertrace.gateway.service.v1.common.Filter; import org.hypertrace.gateway.service.v1.common.OrderByExpression; @@ -35,21 +35,27 @@ class GatewayServiceSpanRequestBuilder { this.attributeConverter = attributeConverter; } - Single buildRequest(ResultSetRequest gqlRequest) { + Single buildRequest(SpanRequest gqlRequest) { return zip( - this.attributeConverter.convert(gqlRequest.attributes()), - this.orderConverter.convert(gqlRequest.orderArguments()), - this.filterConverter.convert(gqlRequest.filterArguments()), + this.attributeConverter.convert(gqlRequest.spanEventsRequest().attributes()), + this.orderConverter.convert(gqlRequest.spanEventsRequest().orderArguments()), + this.filterConverter.convert(gqlRequest.spanEventsRequest().filterArguments()), (selections, orderBys, filters) -> SpansRequest.newBuilder() - .setStartTimeMillis(gqlRequest.timeRange().startTime().toEpochMilli()) - .setEndTimeMillis(gqlRequest.timeRange().endTime().toEpochMilli()) + .setStartTimeMillis( + gqlRequest.spanEventsRequest().timeRange().startTime().toEpochMilli()) + .setEndTimeMillis( + gqlRequest.spanEventsRequest().timeRange().endTime().toEpochMilli()) .addAllSelection(selections) .addAllOrderBy(orderBys) - .setLimit(gqlRequest.limit()) - .setOffset(gqlRequest.offset()) + .setLimit(gqlRequest.spanEventsRequest().limit()) + .setOffset(gqlRequest.spanEventsRequest().offset()) .setFilter(filters) - .setSpaceId(gqlRequest.spaceId().orElse("")) // String proto default value + .setSpaceId( + gqlRequest + .spanEventsRequest() + .spaceId() + .orElse("")) // String proto default value .build()); } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDao.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDao.java index 7a92783f..ad938394 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDao.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDao.java @@ -1,11 +1,11 @@ package org.hypertrace.core.graphql.span.dao; import io.reactivex.rxjava3.core.Single; -import org.hypertrace.core.graphql.common.request.ResultSetRequest; import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; +import org.hypertrace.core.graphql.span.request.SpanRequest; import org.hypertrace.core.graphql.span.schema.SpanResultSet; public interface SpanDao { - Single getSpans(ResultSetRequest request); + Single getSpans(SpanRequest request); } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java index 5e1a8f1d..d011ede7 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java @@ -2,6 +2,7 @@ import com.google.inject.AbstractModule; import com.google.inject.Key; +import com.google.inject.Singleton; import com.google.inject.TypeLiteral; import io.grpc.CallCredentials; import java.util.Collection; @@ -17,6 +18,7 @@ import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig; import org.hypertrace.core.graphql.utils.grpc.GraphQlGrpcContextBuilder; import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry; +import org.hypertrace.gateway.service.GatewayServiceGrpc.GatewayServiceFutureStub; import org.hypertrace.gateway.service.v1.common.Expression; import org.hypertrace.gateway.service.v1.common.Filter; import org.hypertrace.gateway.service.v1.common.OrderByExpression; @@ -27,7 +29,9 @@ public class SpanDaoModule extends AbstractModule { @Override protected void configure() { bind(SpanDao.class).to(GatewayServiceSpanDao.class); - + bind(GatewayServiceFutureStub.class) + .toProvider(GatewayServiceFutureStubProvider.class) + .in(Singleton.class); requireBinding(CallCredentials.class); requireBinding(GraphQlServiceConfig.class); requireBinding(GraphQlGrpcContextBuilder.class); diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java new file mode 100644 index 00000000..130740a2 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java @@ -0,0 +1,193 @@ +package org.hypertrace.core.graphql.span.dao; + +import static io.reactivex.rxjava3.core.Single.zip; +import static java.util.concurrent.TimeUnit.SECONDS; + +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Single; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import javax.inject.Inject; +import javax.inject.Singleton; +import lombok.experimental.Accessors; +import org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString; +import org.hypertrace.core.graphql.common.request.AttributeAssociation; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.request.FilterRequestBuilder; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterOperatorType; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterType; +import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; +import org.hypertrace.core.graphql.common.utils.BiConverter; +import org.hypertrace.core.graphql.common.utils.Converter; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.deserialization.ArgumentDeserializer; +import org.hypertrace.core.graphql.span.request.SpanRequest; +import org.hypertrace.core.graphql.utils.grpc.GraphQlGrpcContextBuilder; +import org.hypertrace.gateway.service.GatewayServiceGrpc.GatewayServiceFutureStub; +import org.hypertrace.gateway.service.v1.common.Expression; +import org.hypertrace.gateway.service.v1.common.Filter; +import org.hypertrace.gateway.service.v1.common.Value; +import org.hypertrace.gateway.service.v1.log.events.LogEventsRequest; +import org.hypertrace.gateway.service.v1.log.events.LogEventsResponse; +import org.hypertrace.gateway.service.v1.span.SpansResponse; + +@Singleton +class SpanLogEventFetcher { + + private static final int DEFAULT_DEADLINE_SEC = 10; + private static final String LOG_EVENT_SPAN_ID_ATTRIBUTE = "spanId"; + + private final Converter, Set> attributeConverter; + private final Converter>, Filter> filterConverter; + private final BiConverter, Map, Map> + attributeMapConverter; + private final ArgumentDeserializer argumentDeserializer; + private final FilterRequestBuilder filterRequestBuilder; + private final GatewayServiceFutureStub gatewayServiceStub; + private final GraphQlGrpcContextBuilder grpcContextBuilder; + + @Inject + SpanLogEventFetcher( + Converter, Set> attributeConverter, + Converter>, Filter> filterConverter, + BiConverter, Map, Map> + attributeMapConverter, + ArgumentDeserializer argumentDeserializer, + FilterRequestBuilder filterRequestBuilder, + GatewayServiceFutureStubProvider gatewayServiceFutureStubProvider, + GraphQlGrpcContextBuilder grpcContextBuilder) { + this.attributeConverter = attributeConverter; + this.filterConverter = filterConverter; + this.attributeMapConverter = attributeMapConverter; + this.argumentDeserializer = argumentDeserializer; + this.filterRequestBuilder = filterRequestBuilder; + this.gatewayServiceStub = gatewayServiceFutureStubProvider.get(); + this.grpcContextBuilder = grpcContextBuilder; + } + + /** + * + * + *
    + *
  • 1. Fetch log event attributes from {@code gqlRequest} + *
  • 2. Build log event request using attribute and spanIds as filter + *
  • 3. Query log events + *
  • 4. Processed log events response to build mapping from spanId to logEvent + *
+ */ + Single fetchLogEvents( + SpanRequest gqlRequest, SpansResponse spansResponse) { + if (null == gqlRequest.spanEventsRequest().idAttribute() + || null == gqlRequest.logEventAttributes() + || gqlRequest.logEventAttributes().isEmpty()) { + return Single.just(new SpanLogEventsResponse(spansResponse, Map.of())); + } + return buildLogEventsRequest(gqlRequest, spansResponse) + .flatMap( + logEventsRequest -> + makeRequest(gqlRequest.spanEventsRequest().context(), logEventsRequest)) + .flatMap( + logEventsResponse -> + buildResponse(gqlRequest.logEventAttributes(), spansResponse, logEventsResponse)); + } + + private Single buildLogEventsRequest( + SpanRequest gqlRequest, SpansResponse spansResponse) { + return zip( + this.attributeConverter.convert(gqlRequest.logEventAttributes()), + buildLogEventsQueryFilter(gqlRequest, spansResponse).flatMap(filterConverter::convert), + (selections, filter) -> + LogEventsRequest.newBuilder() + .setStartTimeMillis( + gqlRequest.spanEventsRequest().timeRange().startTime().toEpochMilli()) + .setEndTimeMillis( + gqlRequest.spanEventsRequest().timeRange().endTime().toEpochMilli()) + .addAllSelection(selections) + .setFilter(filter) + .build()); + } + + private Single>> buildLogEventsQueryFilter( + SpanRequest gqlRequest, SpansResponse spansResponse) { + List spanIds = + spansResponse.getSpansList().stream() + .map( + v -> + v.getAttributesMap() + .get(gqlRequest.spanEventsRequest().idAttribute().attribute().key()) + .getString()) + .collect(Collectors.toList()); + Map argMap = + Map.of( + FilterArgument.ARGUMENT_NAME, + List.of( + Map.of( + FilterArgument.FILTER_ARGUMENT_KEY, + LOG_EVENT_SPAN_ID_ATTRIBUTE, + FilterArgument.FILTER_ARGUMENT_OPERATOR, + FilterOperatorType.IN, + FilterArgument.FILTER_ARGUMENT_TYPE, + FilterType.ATTRIBUTE, + FilterArgument.FILTER_ARGUMENT_VALUE, + spanIds, + FilterArgument.FILTER_ARGUMENT_ID_SCOPE, + HypertraceCoreAttributeScopeString.LOG_EVENT))); + + List requestedFilters = + this.argumentDeserializer + .deserializeObjectList(argMap, FilterArgument.class) + .orElse(Collections.emptyList()); + + return filterRequestBuilder.build( + gqlRequest.spanEventsRequest().context(), + HypertraceCoreAttributeScopeString.LOG_EVENT, + requestedFilters); + } + + private Single makeRequest( + GraphQlRequestContext context, LogEventsRequest request) { + return Single.fromFuture( + this.grpcContextBuilder + .build(context) + .callInContext( + () -> + this.gatewayServiceStub + .withDeadlineAfter(DEFAULT_DEADLINE_SEC, SECONDS) + .getLogEvents(request))); + } + + private Single buildResponse( + Collection attributeRequests, + SpansResponse spansResponse, + LogEventsResponse logEventsResponse) { + return Observable.fromIterable(logEventsResponse.getLogEventsList()) + .concatMapSingle(logEvent -> this.convert(attributeRequests, logEvent)) + .collect(Collectors.groupingBy(v -> (String) v.attribute(LOG_EVENT_SPAN_ID_ATTRIBUTE))) + .map(v -> new SpanLogEventsResponse(spansResponse, v)); + } + + private Single convert( + Collection request, + org.hypertrace.gateway.service.v1.log.events.LogEvent logEvent) { + return this.attributeMapConverter + .convert(request, logEvent.getAttributesMap()) + .map(ConvertedLogEvent::new); + } + + @lombok.Value + @Accessors(fluent = true) + private static class ConvertedLogEvent + implements org.hypertrace.core.graphql.log.event.schema.LogEvent { + Map attributeValues; + + @Override + public Object attribute(String key) { + return this.attributeValues.get(key); + } + } +} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventsResponse.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventsResponse.java new file mode 100644 index 00000000..947b1fa9 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventsResponse.java @@ -0,0 +1,15 @@ +package org.hypertrace.core.graphql.span.dao; + +import java.util.List; +import java.util.Map; +import lombok.experimental.Accessors; +import org.hypertrace.core.graphql.log.event.schema.LogEvent; +import org.hypertrace.gateway.service.v1.span.SpansResponse; + +@lombok.Value +@Accessors(fluent = true) +class SpanLogEventsResponse { + + SpansResponse spansResponse; + Map> spanIdToLogEvents; +} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/fetcher/SpanFetcher.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/fetcher/SpanFetcher.java index 7b07805f..f7b9cd2b 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/fetcher/SpanFetcher.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/fetcher/SpanFetcher.java @@ -6,8 +6,8 @@ import javax.inject.Inject; import org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString; import org.hypertrace.core.graphql.common.fetcher.InjectableDataFetcher; -import org.hypertrace.core.graphql.common.request.ResultSetRequestBuilder; import org.hypertrace.core.graphql.span.dao.SpanDao; +import org.hypertrace.core.graphql.span.request.SpanRequestBuilder; import org.hypertrace.core.graphql.span.schema.SpanResultSet; public class SpanFetcher extends InjectableDataFetcher { @@ -17,11 +17,11 @@ public SpanFetcher() { } static final class SpanFetcherImpl implements DataFetcher> { - private final ResultSetRequestBuilder requestBuilder; + private final SpanRequestBuilder requestBuilder; private final SpanDao spanDao; @Inject - SpanFetcherImpl(ResultSetRequestBuilder requestBuilder, SpanDao spanDao) { + SpanFetcherImpl(SpanRequestBuilder requestBuilder, SpanDao spanDao) { this.requestBuilder = requestBuilder; this.spanDao = spanDao; } 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 new file mode 100644 index 00000000..b400c101 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/DefaultSpanRequestBuilder.java @@ -0,0 +1,83 @@ +package org.hypertrace.core.graphql.span.request; + +import static io.reactivex.rxjava3.core.Single.zip; + +import graphql.schema.DataFetchingFieldSelectionSet; +import io.reactivex.rxjava3.core.Single; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import lombok.Value; +import lombok.experimental.Accessors; +import org.hypertrace.core.graphql.common.request.AttributeAssociation; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.request.ResultSetRequest; +import org.hypertrace.core.graphql.common.request.ResultSetRequestBuilder; +import org.hypertrace.core.graphql.common.schema.arguments.TimeRangeArgument; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; +import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.log.event.request.LogEventRequest; + +public class DefaultSpanRequestBuilder implements SpanRequestBuilder { + + private final ResultSetRequestBuilder resultSetRequestBuilder; + private final LogEventAttributeRequestBuilder logEventAttributeRequestBuilder; + + public DefaultSpanRequestBuilder( + ResultSetRequestBuilder resultSetRequestBuilder, + LogEventAttributeRequestBuilder logEventAttributeRequestBuilder) { + this.resultSetRequestBuilder = resultSetRequestBuilder; + this.logEventAttributeRequestBuilder = logEventAttributeRequestBuilder; + } + + @Override + public Single> build( + GraphQlRequestContext context, + String requestScope, + Map arguments, + DataFetchingFieldSelectionSet selectionSet) { + return zip( + resultSetRequestBuilder.build( + context, requestScope, arguments, selectionSet, OrderArgument.class), + logEventAttributeRequestBuilder.buildAttributeRequest(context, selectionSet), + (resultSetRequest, logEventAttributeRequest) -> + Single.just(new DefaultSpanRequest<>(resultSetRequest, logEventAttributeRequest))) + .flatMap(single -> single); + } + + @Value + @Accessors(fluent = true) + private static class DefaultSpanRequest implements SpanRequest { + ResultSetRequest spanEventsRequest; + Collection logEventAttributes; + } + + @Value + @Accessors(fluent = true) + private static class DefaultResultSetRequest + implements ResultSetRequest { + GraphQlRequestContext context; + Collection attributes; + AttributeRequest idAttribute; + TimeRangeArgument timeRange; + int limit; + int offset; + List> orderArguments; + Collection> filterArguments; + Optional spaceId; + } + + @Value + @Accessors(fluent = true) + private static class DefaultLogEventRequest implements LogEventRequest { + GraphQlRequestContext context; + Collection attributes; + TimeRangeArgument timeRange; + int limit; + int offset; + List> orderArguments; + Collection> filterArguments; + } +} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java new file mode 100644 index 00000000..5be8afef --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java @@ -0,0 +1,51 @@ +package org.hypertrace.core.graphql.span.request; + +import static org.hypertrace.core.graphql.common.schema.results.ResultSet.RESULT_SET_RESULTS_NAME; +import static org.hypertrace.core.graphql.span.schema.Span.LOG_EVENT_KEY; + +import graphql.schema.DataFetchingFieldSelectionSet; +import graphql.schema.SelectedField; +import io.reactivex.rxjava3.core.Single; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.inject.Inject; +import org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.request.AttributeRequestBuilder; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.utils.schema.GraphQlSelectionFinder; +import org.hypertrace.core.graphql.utils.schema.SelectionQuery; + +class LogEventAttributeRequestBuilder { + + private final GraphQlSelectionFinder selectionFinder; + private final AttributeRequestBuilder attributeRequestBuilder; + + @Inject + LogEventAttributeRequestBuilder( + GraphQlSelectionFinder selectionFinder, AttributeRequestBuilder attributeRequestBuilder) { + this.selectionFinder = selectionFinder; + this.attributeRequestBuilder = attributeRequestBuilder; + } + + Single> buildAttributeRequest( + GraphQlRequestContext context, DataFetchingFieldSelectionSet selectionSet) { + return attributeRequestBuilder + .buildForAttributeQueryableFieldsAndId( + context, + HypertraceCoreAttributeScopeString.LOG_EVENT, + getLogEventSelectionFields(selectionSet)) + .collect(Collectors.toUnmodifiableSet()); + } + + private Stream getLogEventSelectionFields( + DataFetchingFieldSelectionSet selectionSet) { + return this.selectionFinder.findSelections( + selectionSet, + SelectionQuery.builder() + .selectionPath(List.of(RESULT_SET_RESULTS_NAME, LOG_EVENT_KEY)) + .build()); + } +} 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 new file mode 100644 index 00000000..8eced116 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequest.java @@ -0,0 +1,12 @@ +package org.hypertrace.core.graphql.span.request; + +import java.util.Collection; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.request.ResultSetRequest; +import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; + +public interface SpanRequest { + ResultSetRequest spanEventsRequest(); + + Collection logEventAttributes(); +} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java new file mode 100644 index 00000000..0e63c0a4 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java @@ -0,0 +1,16 @@ +package org.hypertrace.core.graphql.span.request; + +import graphql.schema.DataFetchingFieldSelectionSet; +import io.reactivex.rxjava3.core.Single; +import java.util.Map; +import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; + +public interface SpanRequestBuilder { + + Single> build( + GraphQlRequestContext context, + String requestScope, + Map arguments, + DataFetchingFieldSelectionSet selectionSet); +} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestModule.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestModule.java new file mode 100644 index 00000000..443db05c --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestModule.java @@ -0,0 +1,25 @@ +package org.hypertrace.core.graphql.span.request; + +import com.google.inject.AbstractModule; +import org.hypertrace.core.graphql.attributes.AttributeStore; +import org.hypertrace.core.graphql.common.request.AttributeRequestBuilder; +import org.hypertrace.core.graphql.common.request.FilterRequestBuilder; +import org.hypertrace.core.graphql.common.utils.attributes.AttributeAssociator; +import org.hypertrace.core.graphql.common.utils.attributes.AttributeScopeStringTranslator; +import org.hypertrace.core.graphql.deserialization.ArgumentDeserializer; +import org.hypertrace.core.graphql.utils.schema.GraphQlSelectionFinder; + +public class SpanRequestModule extends AbstractModule { + + @Override + protected void configure() { + bind(SpanRequestBuilder.class).to(DefaultSpanRequestBuilder.class); + requireBinding(ArgumentDeserializer.class); + requireBinding(AttributeRequestBuilder.class); + requireBinding(FilterRequestBuilder.class); + requireBinding(AttributeStore.class); + requireBinding(AttributeAssociator.class); + requireBinding(GraphQlSelectionFinder.class); + requireBinding(AttributeScopeStringTranslator.class); + } +} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java index fe11ac6b..0b0c15d2 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java @@ -1,10 +1,18 @@ package org.hypertrace.core.graphql.span.schema; +import graphql.annotations.annotationTypes.GraphQLField; import graphql.annotations.annotationTypes.GraphQLName; +import java.util.List; import org.hypertrace.core.graphql.common.schema.attributes.AttributeQueryable; import org.hypertrace.core.graphql.common.schema.id.Identifiable; +import org.hypertrace.core.graphql.log.event.schema.LogEvent; @GraphQLName(Span.TYPE_NAME) public interface Span extends AttributeQueryable, Identifiable { String TYPE_NAME = "Span"; + String LOG_EVENT_KEY = "logEvents"; + + @GraphQLField + @GraphQLName(LOG_EVENT_KEY) + List logEvents(); } From 33ed5daf38274b98be9e6ffb8fa9a130c7abec09 Mon Sep 17 00:00:00 2001 From: rish691 Date: Tue, 27 Apr 2021 00:45:48 +0530 Subject: [PATCH 2/9] Fix binding --- .../org/hypertrace/core/graphql/span/SpanSchemaModule.java | 2 ++ .../org/hypertrace/core/graphql/span/dao/SpanDaoModule.java | 4 ++++ .../hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java | 3 +-- .../core/graphql/span/request/DefaultSpanRequestBuilder.java | 2 ++ .../graphql/span/request/LogEventAttributeRequestBuilder.java | 2 +- .../core/graphql/span/request/SpanRequestModule.java | 1 + 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/SpanSchemaModule.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/SpanSchemaModule.java index 5f69f194..bbc21668 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/SpanSchemaModule.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/SpanSchemaModule.java @@ -4,6 +4,7 @@ import com.google.inject.multibindings.Multibinder; import org.hypertrace.core.graphql.common.request.ResultSetRequestBuilder; import org.hypertrace.core.graphql.span.dao.SpanDaoModule; +import org.hypertrace.core.graphql.span.request.SpanRequestModule; import org.hypertrace.core.graphql.spi.schema.GraphQlSchemaFragment; public class SpanSchemaModule extends AbstractModule { @@ -15,5 +16,6 @@ protected void configure() { requireBinding(ResultSetRequestBuilder.class); install(new SpanDaoModule()); + install(new SpanRequestModule()); } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java index d011ede7..59cce71b 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java @@ -11,10 +11,12 @@ import java.util.Set; import org.hypertrace.core.graphql.common.request.AttributeAssociation; import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.request.FilterRequestBuilder; import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.common.utils.BiConverter; import org.hypertrace.core.graphql.common.utils.Converter; +import org.hypertrace.core.graphql.deserialization.ArgumentDeserializer; import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig; import org.hypertrace.core.graphql.utils.grpc.GraphQlGrpcContextBuilder; import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry; @@ -36,6 +38,8 @@ protected void configure() { requireBinding(GraphQlServiceConfig.class); requireBinding(GraphQlGrpcContextBuilder.class); requireBinding(GrpcChannelRegistry.class); + requireBinding(FilterRequestBuilder.class); + requireBinding(ArgumentDeserializer.class); requireBinding( Key.get(new TypeLiteral, Set>>() {})); diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java index 130740a2..acf19958 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java @@ -12,7 +12,6 @@ import java.util.Set; import java.util.stream.Collectors; import javax.inject.Inject; -import javax.inject.Singleton; import lombok.experimental.Accessors; import org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString; import org.hypertrace.core.graphql.common.request.AttributeAssociation; @@ -36,7 +35,6 @@ import org.hypertrace.gateway.service.v1.log.events.LogEventsResponse; import org.hypertrace.gateway.service.v1.span.SpansResponse; -@Singleton class SpanLogEventFetcher { private static final int DEFAULT_DEADLINE_SEC = 10; @@ -183,6 +181,7 @@ private Single convert( @Accessors(fluent = true) private static class ConvertedLogEvent implements org.hypertrace.core.graphql.log.event.schema.LogEvent { + Map attributeValues; @Override 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 b400c101..6f947cdd 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 @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import javax.inject.Inject; import lombok.Value; import lombok.experimental.Accessors; import org.hypertrace.core.graphql.common.request.AttributeAssociation; @@ -25,6 +26,7 @@ public class DefaultSpanRequestBuilder implements SpanRequestBuilder { private final ResultSetRequestBuilder resultSetRequestBuilder; private final LogEventAttributeRequestBuilder logEventAttributeRequestBuilder; + @Inject public DefaultSpanRequestBuilder( ResultSetRequestBuilder resultSetRequestBuilder, LogEventAttributeRequestBuilder logEventAttributeRequestBuilder) { diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java index 5be8afef..434f08d4 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java @@ -33,7 +33,7 @@ class LogEventAttributeRequestBuilder { Single> buildAttributeRequest( GraphQlRequestContext context, DataFetchingFieldSelectionSet selectionSet) { return attributeRequestBuilder - .buildForAttributeQueryableFieldsAndId( + .buildForAttributeQueryableFields( context, HypertraceCoreAttributeScopeString.LOG_EVENT, getLogEventSelectionFields(selectionSet)) diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestModule.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestModule.java index 443db05c..a1d5a39d 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestModule.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestModule.java @@ -21,5 +21,6 @@ protected void configure() { requireBinding(AttributeAssociator.class); requireBinding(GraphQlSelectionFinder.class); requireBinding(AttributeScopeStringTranslator.class); + requireBinding(AttributeRequestBuilder.class); } } From 2a839e593d45b28df9175c0f7d5e95e1eac23f1a Mon Sep 17 00:00:00 2001 From: rish691 Date: Tue, 27 Apr 2021 01:26:43 +0530 Subject: [PATCH 3/9] Fix npe --- .../hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java index acf19958..7489d1ea 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java @@ -117,7 +117,7 @@ private Single>> buildLogEventsQueryFi .map( v -> v.getAttributesMap() - .get(gqlRequest.spanEventsRequest().idAttribute().attribute().key()) + .get(gqlRequest.spanEventsRequest().idAttribute().attribute().id()) .getString()) .collect(Collectors.toList()); Map argMap = From 2bb21ca38228f8cc3ac7a5effdabc4007586922f Mon Sep 17 00:00:00 2001 From: rish691 Date: Tue, 27 Apr 2021 23:12:32 +0530 Subject: [PATCH 4/9] review comment --- .../span/dao/GatewayServiceSpanDao.java | 7 ++- .../graphql/span/dao/SpanLogEventFetcher.java | 58 ++++++++----------- .../request/DefaultSpanRequestBuilder.java | 2 +- .../core/graphql/span/schema/Span.java | 2 + 4 files changed, 32 insertions(+), 37 deletions(-) diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java index 0878aa26..9d62ed0e 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java @@ -25,7 +25,7 @@ class GatewayServiceSpanDao implements SpanDao { @Inject GatewayServiceSpanDao( - GatewayServiceFutureStubProvider gatewayServiceFutureStubProvider, + GatewayServiceFutureStub gatewayServiceFutureStub, GraphQlGrpcContextBuilder grpcContextBuilder, GatewayServiceSpanRequestBuilder requestBuilder, GatewayServiceSpanConverter spanConverter, @@ -34,7 +34,7 @@ class GatewayServiceSpanDao implements SpanDao { this.requestBuilder = requestBuilder; this.spanConverter = spanConverter; this.spanLogEventFetcher = spanLogEventFetcher; - this.gatewayServiceStub = gatewayServiceFutureStubProvider.get(); + this.gatewayServiceStub = gatewayServiceFutureStub; } @Override @@ -44,7 +44,8 @@ public Single getSpans(SpanRequest request) { .flatMap( serverRequest -> this.makeRequest(request.spanEventsRequest().context(), serverRequest)) .flatMap(serverResponse -> spanLogEventFetcher.fetchLogEvents(request, serverResponse)) - .flatMap(serverResponse -> this.spanConverter.convert(request, serverResponse)); + .flatMap( + spanLogEventsResponse -> this.spanConverter.convert(request, spanLogEventsResponse)); } private Single makeRequest(GraphQlRequestContext context, SpansRequest request) { diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java index 7489d1ea..78496dc1 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java @@ -6,7 +6,6 @@ import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -17,6 +16,7 @@ import org.hypertrace.core.graphql.common.request.AttributeAssociation; import org.hypertrace.core.graphql.common.request.AttributeRequest; import org.hypertrace.core.graphql.common.request.FilterRequestBuilder; +import org.hypertrace.core.graphql.common.schema.attributes.AttributeScope; import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterOperatorType; import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterType; @@ -24,7 +24,6 @@ import org.hypertrace.core.graphql.common.utils.BiConverter; import org.hypertrace.core.graphql.common.utils.Converter; import org.hypertrace.core.graphql.context.GraphQlRequestContext; -import org.hypertrace.core.graphql.deserialization.ArgumentDeserializer; import org.hypertrace.core.graphql.span.request.SpanRequest; import org.hypertrace.core.graphql.utils.grpc.GraphQlGrpcContextBuilder; import org.hypertrace.gateway.service.GatewayServiceGrpc.GatewayServiceFutureStub; @@ -44,7 +43,6 @@ class SpanLogEventFetcher { private final Converter>, Filter> filterConverter; private final BiConverter, Map, Map> attributeMapConverter; - private final ArgumentDeserializer argumentDeserializer; private final FilterRequestBuilder filterRequestBuilder; private final GatewayServiceFutureStub gatewayServiceStub; private final GraphQlGrpcContextBuilder grpcContextBuilder; @@ -55,16 +53,14 @@ class SpanLogEventFetcher { Converter>, Filter> filterConverter, BiConverter, Map, Map> attributeMapConverter, - ArgumentDeserializer argumentDeserializer, FilterRequestBuilder filterRequestBuilder, - GatewayServiceFutureStubProvider gatewayServiceFutureStubProvider, + GatewayServiceFutureStub gatewayServiceFutureStub, GraphQlGrpcContextBuilder grpcContextBuilder) { this.attributeConverter = attributeConverter; this.filterConverter = filterConverter; this.attributeMapConverter = attributeMapConverter; - this.argumentDeserializer = argumentDeserializer; this.filterRequestBuilder = filterRequestBuilder; - this.gatewayServiceStub = gatewayServiceFutureStubProvider.get(); + this.gatewayServiceStub = gatewayServiceFutureStub; this.grpcContextBuilder = grpcContextBuilder; } @@ -115,36 +111,17 @@ private Single>> buildLogEventsQueryFi List spanIds = spansResponse.getSpansList().stream() .map( - v -> - v.getAttributesMap() + spanEvent -> + spanEvent + .getAttributesMap() .get(gqlRequest.spanEventsRequest().idAttribute().attribute().id()) .getString()) .collect(Collectors.toList()); - Map argMap = - Map.of( - FilterArgument.ARGUMENT_NAME, - List.of( - Map.of( - FilterArgument.FILTER_ARGUMENT_KEY, - LOG_EVENT_SPAN_ID_ATTRIBUTE, - FilterArgument.FILTER_ARGUMENT_OPERATOR, - FilterOperatorType.IN, - FilterArgument.FILTER_ARGUMENT_TYPE, - FilterType.ATTRIBUTE, - FilterArgument.FILTER_ARGUMENT_VALUE, - spanIds, - FilterArgument.FILTER_ARGUMENT_ID_SCOPE, - HypertraceCoreAttributeScopeString.LOG_EVENT))); - - List requestedFilters = - this.argumentDeserializer - .deserializeObjectList(argMap, FilterArgument.class) - .orElse(Collections.emptyList()); return filterRequestBuilder.build( gqlRequest.spanEventsRequest().context(), HypertraceCoreAttributeScopeString.LOG_EVENT, - requestedFilters); + Set.of(new LogEventFilter(spanIds))); } private Single makeRequest( @@ -164,9 +141,13 @@ private Single buildResponse( SpansResponse spansResponse, LogEventsResponse logEventsResponse) { return Observable.fromIterable(logEventsResponse.getLogEventsList()) - .concatMapSingle(logEvent -> this.convert(attributeRequests, logEvent)) - .collect(Collectors.groupingBy(v -> (String) v.attribute(LOG_EVENT_SPAN_ID_ATTRIBUTE))) - .map(v -> new SpanLogEventsResponse(spansResponse, v)); + .concatMapSingle( + logEventsResponseVar -> this.convert(attributeRequests, logEventsResponseVar)) + .collect( + Collectors.groupingBy( + logEvent -> (String) logEvent.attribute(LOG_EVENT_SPAN_ID_ATTRIBUTE))) + .map( + spanIdVsLogEventsMap -> new SpanLogEventsResponse(spansResponse, spanIdVsLogEventsMap)); } private Single convert( @@ -189,4 +170,15 @@ public Object attribute(String key) { return this.attributeValues.get(key); } } + + @lombok.Value + @Accessors(fluent = true) + private static class LogEventFilter implements FilterArgument { + FilterType type = FilterType.ATTRIBUTE; + String key = LOG_EVENT_SPAN_ID_ATTRIBUTE; + FilterOperatorType operator = FilterOperatorType.IN; + Collection value; + AttributeScope idType = null; + String idScope = HypertraceCoreAttributeScopeString.LOG_EVENT; + } } 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 6f947cdd..1ec4e470 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 @@ -21,7 +21,7 @@ import org.hypertrace.core.graphql.context.GraphQlRequestContext; import org.hypertrace.core.graphql.log.event.request.LogEventRequest; -public class DefaultSpanRequestBuilder implements SpanRequestBuilder { +class DefaultSpanRequestBuilder implements SpanRequestBuilder { private final ResultSetRequestBuilder resultSetRequestBuilder; private final LogEventAttributeRequestBuilder logEventAttributeRequestBuilder; diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java index 0b0c15d2..d55d3bfb 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java @@ -2,6 +2,7 @@ import graphql.annotations.annotationTypes.GraphQLField; import graphql.annotations.annotationTypes.GraphQLName; +import graphql.annotations.annotationTypes.GraphQLNonNull; import java.util.List; import org.hypertrace.core.graphql.common.schema.attributes.AttributeQueryable; import org.hypertrace.core.graphql.common.schema.id.Identifiable; @@ -13,6 +14,7 @@ public interface Span extends AttributeQueryable, Identifiable { String LOG_EVENT_KEY = "logEvents"; @GraphQLField + @GraphQLNonNull @GraphQLName(LOG_EVENT_KEY) List logEvents(); } From 4def0bc6a271b931d9312e9c35fbb11528fca3b9 Mon Sep 17 00:00:00 2001 From: rish691 Date: Wed, 28 Apr 2021 00:06:52 +0530 Subject: [PATCH 5/9] move GatewayServiceFutureStubProvider --- .../build.gradle.kts | 1 + .../GatewayServiceFutureStubProvider.java | 2 +- .../utils/gateway/GatewayUtilsModule.java | 6 ++++ .../core/graphql/span/dao/SpanDaoModule.java | 5 +-- .../request/DefaultSpanRequestBuilder.java | 33 ------------------- 5 files changed, 9 insertions(+), 38 deletions(-) rename {hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao => hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway}/GatewayServiceFutureStubProvider.java (95%) diff --git a/hypertrace-core-graphql-gateway-service-utils/build.gradle.kts b/hypertrace-core-graphql-gateway-service-utils/build.gradle.kts index 7c93ca31..ad696b43 100644 --- a/hypertrace-core-graphql-gateway-service-utils/build.gradle.kts +++ b/hypertrace-core-graphql-gateway-service-utils/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { api(project(":hypertrace-core-graphql-attribute-store")) api("io.reactivex.rxjava3:rxjava") api(project(":hypertrace-core-graphql-common-schema")) + implementation(project(":hypertrace-core-graphql-grpc-utils")) testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.mockito:mockito-core") diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceFutureStubProvider.java b/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayServiceFutureStubProvider.java similarity index 95% rename from hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceFutureStubProvider.java rename to hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayServiceFutureStubProvider.java index 644f91cc..55363260 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceFutureStubProvider.java +++ b/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayServiceFutureStubProvider.java @@ -1,4 +1,4 @@ -package org.hypertrace.core.graphql.span.dao; +package org.hypertrace.core.graphql.utils.gateway; import io.grpc.CallCredentials; import javax.inject.Inject; diff --git a/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java b/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java index 3bbfcc31..bc57c149 100644 --- a/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java +++ b/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java @@ -2,6 +2,7 @@ import com.google.inject.AbstractModule; import com.google.inject.Key; +import com.google.inject.Singleton; import com.google.inject.TypeLiteral; import java.util.Collection; import java.util.List; @@ -15,6 +16,7 @@ import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderDirection; import org.hypertrace.core.graphql.common.utils.BiConverter; import org.hypertrace.core.graphql.common.utils.Converter; +import org.hypertrace.gateway.service.GatewayServiceGrpc.GatewayServiceFutureStub; import org.hypertrace.gateway.service.v1.common.ColumnIdentifier; import org.hypertrace.gateway.service.v1.common.Expression; import org.hypertrace.gateway.service.v1.common.Filter; @@ -62,5 +64,9 @@ protected void configure() { bind(Key.get(new TypeLiteral>() {})) .to(SortOrderConverter.class); + + bind(GatewayServiceFutureStub.class) + .toProvider(GatewayServiceFutureStubProvider.class) + .in(Singleton.class); } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java index 59cce71b..8dd9976f 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java @@ -2,7 +2,6 @@ import com.google.inject.AbstractModule; import com.google.inject.Key; -import com.google.inject.Singleton; import com.google.inject.TypeLiteral; import io.grpc.CallCredentials; import java.util.Collection; @@ -31,9 +30,7 @@ public class SpanDaoModule extends AbstractModule { @Override protected void configure() { bind(SpanDao.class).to(GatewayServiceSpanDao.class); - bind(GatewayServiceFutureStub.class) - .toProvider(GatewayServiceFutureStubProvider.class) - .in(Singleton.class); + requireBinding(GatewayServiceFutureStub.class); requireBinding(CallCredentials.class); requireBinding(GraphQlServiceConfig.class); requireBinding(GraphQlGrpcContextBuilder.class); 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 1ec4e470..3b90ef5b 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 @@ -5,21 +5,15 @@ import graphql.schema.DataFetchingFieldSelectionSet; import io.reactivex.rxjava3.core.Single; import java.util.Collection; -import java.util.List; import java.util.Map; -import java.util.Optional; import javax.inject.Inject; import lombok.Value; import lombok.experimental.Accessors; -import org.hypertrace.core.graphql.common.request.AttributeAssociation; import org.hypertrace.core.graphql.common.request.AttributeRequest; import org.hypertrace.core.graphql.common.request.ResultSetRequest; import org.hypertrace.core.graphql.common.request.ResultSetRequestBuilder; -import org.hypertrace.core.graphql.common.schema.arguments.TimeRangeArgument; -import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.context.GraphQlRequestContext; -import org.hypertrace.core.graphql.log.event.request.LogEventRequest; class DefaultSpanRequestBuilder implements SpanRequestBuilder { @@ -55,31 +49,4 @@ private static class DefaultSpanRequest implements Span ResultSetRequest spanEventsRequest; Collection logEventAttributes; } - - @Value - @Accessors(fluent = true) - private static class DefaultResultSetRequest - implements ResultSetRequest { - GraphQlRequestContext context; - Collection attributes; - AttributeRequest idAttribute; - TimeRangeArgument timeRange; - int limit; - int offset; - List> orderArguments; - Collection> filterArguments; - Optional spaceId; - } - - @Value - @Accessors(fluent = true) - private static class DefaultLogEventRequest implements LogEventRequest { - GraphQlRequestContext context; - Collection attributes; - TimeRangeArgument timeRange; - int limit; - int offset; - List> orderArguments; - Collection> filterArguments; - } } From 558da9615c2b3b948b259c01a23fd6378c511811 Mon Sep 17 00:00:00 2001 From: rish691 Date: Wed, 28 Apr 2021 02:50:58 +0530 Subject: [PATCH 6/9] address few comments, introduced a few issues --- .../scopes/HypertraceCoreAttributeScope.java | 3 +- .../HypertraceCoreAttributeScopeModule.java | 4 ++- .../span/dao/GatewayServiceSpanConverter.java | 19 ++++++++--- .../span/dao/GatewayServiceSpanDao.java | 3 +- .../dao/GatewayServiceSpanRequestBuilder.java | 2 +- .../core/graphql/span/dao/SpanDao.java | 3 +- .../core/graphql/span/dao/SpanDaoModule.java | 2 ++ .../graphql/span/dao/SpanLogEventFetcher.java | 32 +++++++++++++------ .../request/DefaultSpanRequestBuilder.java | 8 ++--- .../graphql/span/request/SpanRequest.java | 4 +-- .../span/request/SpanRequestBuilder.java | 2 +- .../core/graphql/span/schema/Span.java | 5 ++- 12 files changed, 57 insertions(+), 30 deletions(-) diff --git a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScope.java b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScope.java index 84dd191a..b71f44aa 100644 --- a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScope.java +++ b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScope.java @@ -4,7 +4,8 @@ enum HypertraceCoreAttributeScope implements AttributeScope { TRACE(HypertraceCoreAttributeScopeString.TRACE), - SPAN(HypertraceCoreAttributeScopeString.SPAN); + SPAN(HypertraceCoreAttributeScopeString.SPAN), + LOG_EVENT(HypertraceCoreAttributeScopeString.LOG_EVENT); private final String scope; diff --git a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java index 342f29b2..558d9095 100644 --- a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java +++ b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java @@ -2,6 +2,7 @@ import static org.hypertrace.core.graphql.attributes.IdMapping.forForeignId; import static org.hypertrace.core.graphql.attributes.IdMapping.forId; +import static org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString.LOG_EVENT; import static org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString.SPAN; import static org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString.TRACE; @@ -21,7 +22,8 @@ protected void configure() { Multibinder idBinder = Multibinder.newSetBinder(binder(), IdMapping.class); idBinder.addBinding().toInstance(forId(SPAN, "id")); idBinder.addBinding().toInstance(forForeignId(SPAN, TRACE, "traceId")); - + idBinder.addBinding().toInstance(forForeignId(LOG_EVENT, SPAN, "spanId")); + idBinder.addBinding().toInstance(forId(LOG_EVENT, "spanId")); idBinder.addBinding().toInstance(forId(TRACE, "id")); } } 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 4f8a0502..25f43029 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 @@ -3,6 +3,7 @@ import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import javax.inject.Inject; @@ -10,6 +11,7 @@ import org.hypertrace.core.graphql.common.request.AttributeRequest; import org.hypertrace.core.graphql.common.utils.BiConverter; import org.hypertrace.core.graphql.log.event.schema.LogEvent; +import org.hypertrace.core.graphql.log.event.schema.LogEventResultSet; import org.hypertrace.core.graphql.span.request.SpanRequest; import org.hypertrace.core.graphql.span.schema.Span; import org.hypertrace.core.graphql.span.schema.SpanResultSet; @@ -28,7 +30,7 @@ class GatewayServiceSpanConverter { this.attributeMapConverter = attributeMapConverter; } - public Single convert(SpanRequest request, SpanLogEventsResponse response) { + public Single convert(SpanRequest request, SpanLogEventsResponse response) { int total = response.spansResponse().getTotal(); return Observable.fromIterable(response.spansResponse().getSpansList()) @@ -38,7 +40,7 @@ public Single convert(SpanRequest request, SpanLogEventsRespon } private Single convert( - SpanRequest request, SpanEvent spanEvent, Map> spanIdToLogEvents) { + SpanRequest request, SpanEvent spanEvent, Map> spanIdToLogEvents) { return this.attributeMapConverter .convert(request.spanEventsRequest().attributes(), spanEvent.getAttributesMap()) .map( @@ -64,8 +66,9 @@ public Object attribute(String key) { } @Override - public List logEvents() { - return spanIdToLogEvents.get(id); + public LogEventResultSet logEvents() { + List list = spanIdToLogEvents.getOrDefault(id, Collections.emptyList()); + return new ConvertedLogEventResultSet(list, list.size(), list.size()); } } @@ -76,4 +79,12 @@ private static class ConvertedSpanResultSet implements SpanResultSet { long total; long count; } + + @lombok.Value + @Accessors(fluent = true) + private static class ConvertedLogEventResultSet implements LogEventResultSet { + List results; + long total; + long count; + } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java index 9d62ed0e..85e0be39 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java @@ -5,7 +5,6 @@ import io.reactivex.rxjava3.core.Single; import javax.inject.Inject; import javax.inject.Singleton; -import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.context.GraphQlRequestContext; import org.hypertrace.core.graphql.span.request.SpanRequest; import org.hypertrace.core.graphql.span.schema.SpanResultSet; @@ -38,7 +37,7 @@ class GatewayServiceSpanDao implements SpanDao { } @Override - public Single getSpans(SpanRequest request) { + public Single getSpans(SpanRequest request) { return this.requestBuilder .buildRequest(request) .flatMap( 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 f7fe6f9e..48798841 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 @@ -35,7 +35,7 @@ class GatewayServiceSpanRequestBuilder { this.attributeConverter = attributeConverter; } - Single buildRequest(SpanRequest gqlRequest) { + Single buildRequest(SpanRequest gqlRequest) { return zip( this.attributeConverter.convert(gqlRequest.spanEventsRequest().attributes()), this.orderConverter.convert(gqlRequest.spanEventsRequest().orderArguments()), diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDao.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDao.java index ad938394..7e55f74b 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDao.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDao.java @@ -1,11 +1,10 @@ package org.hypertrace.core.graphql.span.dao; import io.reactivex.rxjava3.core.Single; -import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.span.request.SpanRequest; import org.hypertrace.core.graphql.span.schema.SpanResultSet; public interface SpanDao { - Single getSpans(SpanRequest request); + Single getSpans(SpanRequest request); } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java index 8dd9976f..64eaa410 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanDaoModule.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.hypertrace.core.graphql.attributes.AttributeStore; import org.hypertrace.core.graphql.common.request.AttributeAssociation; import org.hypertrace.core.graphql.common.request.AttributeRequest; import org.hypertrace.core.graphql.common.request.FilterRequestBuilder; @@ -37,6 +38,7 @@ protected void configure() { requireBinding(GrpcChannelRegistry.class); requireBinding(FilterRequestBuilder.class); requireBinding(ArgumentDeserializer.class); + requireBinding(AttributeStore.class); requireBinding( Key.get(new TypeLiteral, Set>>() {})); diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java index 78496dc1..d84ced5a 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java @@ -12,6 +12,7 @@ import java.util.stream.Collectors; import javax.inject.Inject; import lombok.experimental.Accessors; +import org.hypertrace.core.graphql.attributes.AttributeStore; import org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString; import org.hypertrace.core.graphql.common.request.AttributeAssociation; import org.hypertrace.core.graphql.common.request.AttributeRequest; @@ -37,7 +38,6 @@ class SpanLogEventFetcher { private static final int DEFAULT_DEADLINE_SEC = 10; - private static final String LOG_EVENT_SPAN_ID_ATTRIBUTE = "spanId"; private final Converter, Set> attributeConverter; private final Converter>, Filter> filterConverter; @@ -46,6 +46,7 @@ class SpanLogEventFetcher { private final FilterRequestBuilder filterRequestBuilder; private final GatewayServiceFutureStub gatewayServiceStub; private final GraphQlGrpcContextBuilder grpcContextBuilder; + private final AttributeStore attributeStore; @Inject SpanLogEventFetcher( @@ -55,13 +56,15 @@ class SpanLogEventFetcher { attributeMapConverter, FilterRequestBuilder filterRequestBuilder, GatewayServiceFutureStub gatewayServiceFutureStub, - GraphQlGrpcContextBuilder grpcContextBuilder) { + GraphQlGrpcContextBuilder grpcContextBuilder, + AttributeStore attributeStore) { this.attributeConverter = attributeConverter; this.filterConverter = filterConverter; this.attributeMapConverter = attributeMapConverter; this.filterRequestBuilder = filterRequestBuilder; this.gatewayServiceStub = gatewayServiceFutureStub; this.grpcContextBuilder = grpcContextBuilder; + this.attributeStore = attributeStore; } /** @@ -87,7 +90,11 @@ Single fetchLogEvents( makeRequest(gqlRequest.spanEventsRequest().context(), logEventsRequest)) .flatMap( logEventsResponse -> - buildResponse(gqlRequest.logEventAttributes(), spansResponse, logEventsResponse)); + buildResponse( + gqlRequest.spanEventsRequest().context(), + gqlRequest.logEventAttributes(), + spansResponse, + logEventsResponse)); } private Single buildLogEventsRequest( @@ -137,15 +144,22 @@ private Single makeRequest( } private Single buildResponse( + GraphQlRequestContext graphQlRequestContext, Collection attributeRequests, SpansResponse spansResponse, LogEventsResponse logEventsResponse) { + String key = + attributeStore + .getForeignIdAttribute( + graphQlRequestContext, + HypertraceCoreAttributeScopeString.LOG_EVENT, + HypertraceCoreAttributeScopeString.SPAN) + .blockingGet() + .key(); return Observable.fromIterable(logEventsResponse.getLogEventsList()) .concatMapSingle( logEventsResponseVar -> this.convert(attributeRequests, logEventsResponseVar)) - .collect( - Collectors.groupingBy( - logEvent -> (String) logEvent.attribute(LOG_EVENT_SPAN_ID_ATTRIBUTE))) + .collect(Collectors.groupingBy(logEvent -> (String) logEvent.attribute(key))) .map( spanIdVsLogEventsMap -> new SpanLogEventsResponse(spansResponse, spanIdVsLogEventsMap)); } @@ -174,11 +188,11 @@ public Object attribute(String key) { @lombok.Value @Accessors(fluent = true) private static class LogEventFilter implements FilterArgument { - FilterType type = FilterType.ATTRIBUTE; - String key = LOG_EVENT_SPAN_ID_ATTRIBUTE; + FilterType type = FilterType.ID; + String key = null; FilterOperatorType operator = FilterOperatorType.IN; Collection value; AttributeScope idType = null; - String idScope = HypertraceCoreAttributeScopeString.LOG_EVENT; + String idScope = HypertraceCoreAttributeScopeString.SPAN; } } 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 3b90ef5b..06869569 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 @@ -29,7 +29,7 @@ public DefaultSpanRequestBuilder( } @Override - public Single> build( + public Single build( GraphQlRequestContext context, String requestScope, Map arguments, @@ -39,14 +39,14 @@ public Single> build( context, requestScope, arguments, selectionSet, OrderArgument.class), logEventAttributeRequestBuilder.buildAttributeRequest(context, selectionSet), (resultSetRequest, logEventAttributeRequest) -> - Single.just(new DefaultSpanRequest<>(resultSetRequest, logEventAttributeRequest))) + Single.just(new DefaultSpanRequest(resultSetRequest, logEventAttributeRequest))) .flatMap(single -> single); } @Value @Accessors(fluent = true) - private static class DefaultSpanRequest implements SpanRequest { - ResultSetRequest spanEventsRequest; + private static class DefaultSpanRequest implements SpanRequest { + ResultSetRequest spanEventsRequest; Collection logEventAttributes; } } 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 8eced116..73312ca9 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 @@ -5,8 +5,8 @@ import org.hypertrace.core.graphql.common.request.ResultSetRequest; import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; -public interface SpanRequest { - ResultSetRequest spanEventsRequest(); +public interface SpanRequest { + ResultSetRequest spanEventsRequest(); Collection logEventAttributes(); } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java index 0e63c0a4..fbcf5b0d 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java @@ -8,7 +8,7 @@ public interface SpanRequestBuilder { - Single> build( + Single build( GraphQlRequestContext context, String requestScope, Map arguments, diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java index d55d3bfb..c591e167 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java @@ -3,10 +3,9 @@ import graphql.annotations.annotationTypes.GraphQLField; import graphql.annotations.annotationTypes.GraphQLName; import graphql.annotations.annotationTypes.GraphQLNonNull; -import java.util.List; import org.hypertrace.core.graphql.common.schema.attributes.AttributeQueryable; import org.hypertrace.core.graphql.common.schema.id.Identifiable; -import org.hypertrace.core.graphql.log.event.schema.LogEvent; +import org.hypertrace.core.graphql.log.event.schema.LogEventResultSet; @GraphQLName(Span.TYPE_NAME) public interface Span extends AttributeQueryable, Identifiable { @@ -16,5 +15,5 @@ public interface Span extends AttributeQueryable, Identifiable { @GraphQLField @GraphQLNonNull @GraphQLName(LOG_EVENT_KEY) - List logEvents(); + LogEventResultSet logEvents(); } From f70a90f600cbb4e4e9aca728639c1b0b39f28d96 Mon Sep 17 00:00:00 2001 From: rish691 Date: Wed, 28 Apr 2021 16:00:59 +0530 Subject: [PATCH 7/9] . --- .../scopes/HypertraceCoreAttributeScope.java | 3 +-- .../HypertraceCoreAttributeScopeModule.java | 4 +--- .../build.gradle.kts | 3 +++ ...tewayServiceLogEventsRequestBuilderTest.java | 17 ++++++++++++++++- ...ayServiceLogEventsResponseConverterTest.java | 17 ++++++++++++++++- .../span/dao/GatewayServiceSpanConverter.java | 5 +++-- .../graphql/span/dao/SpanLogEventFetcher.java | 7 +++---- .../span/request/SpanRequestBuilder.java | 1 - .../core/graphql/span/schema/Span.java | 5 +++-- 9 files changed, 46 insertions(+), 16 deletions(-) diff --git a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScope.java b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScope.java index b71f44aa..84dd191a 100644 --- a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScope.java +++ b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScope.java @@ -4,8 +4,7 @@ enum HypertraceCoreAttributeScope implements AttributeScope { TRACE(HypertraceCoreAttributeScopeString.TRACE), - SPAN(HypertraceCoreAttributeScopeString.SPAN), - LOG_EVENT(HypertraceCoreAttributeScopeString.LOG_EVENT); + SPAN(HypertraceCoreAttributeScopeString.SPAN); private final String scope; diff --git a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java index 558d9095..342f29b2 100644 --- a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java +++ b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java @@ -2,7 +2,6 @@ import static org.hypertrace.core.graphql.attributes.IdMapping.forForeignId; import static org.hypertrace.core.graphql.attributes.IdMapping.forId; -import static org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString.LOG_EVENT; import static org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString.SPAN; import static org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString.TRACE; @@ -22,8 +21,7 @@ protected void configure() { Multibinder idBinder = Multibinder.newSetBinder(binder(), IdMapping.class); idBinder.addBinding().toInstance(forId(SPAN, "id")); idBinder.addBinding().toInstance(forForeignId(SPAN, TRACE, "traceId")); - idBinder.addBinding().toInstance(forForeignId(LOG_EVENT, SPAN, "spanId")); - idBinder.addBinding().toInstance(forId(LOG_EVENT, "spanId")); + idBinder.addBinding().toInstance(forId(TRACE, "id")); } } diff --git a/hypertrace-core-graphql-log-event-schema/build.gradle.kts b/hypertrace-core-graphql-log-event-schema/build.gradle.kts index 5323b844..9b844437 100644 --- a/hypertrace-core-graphql-log-event-schema/build.gradle.kts +++ b/hypertrace-core-graphql-log-event-schema/build.gradle.kts @@ -28,6 +28,9 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("com.fasterxml.jackson.core:jackson-databind") testImplementation(project(":hypertrace-core-graphql-gateway-service-utils")) + testImplementation("org.mockito:mockito-core") + testImplementation("org.mockito:mockito-junit-jupiter") + testAnnotationProcessor("org.projectlombok:lombok") testCompileOnly("org.projectlombok:lombok") } diff --git a/hypertrace-core-graphql-log-event-schema/src/test/java/org/hypertrace/core/graphql/log/event/dao/GatewayServiceLogEventsRequestBuilderTest.java b/hypertrace-core-graphql-log-event-schema/src/test/java/org/hypertrace/core/graphql/log/event/dao/GatewayServiceLogEventsRequestBuilderTest.java index ba021f17..53aa4bff 100644 --- a/hypertrace-core-graphql-log-event-schema/src/test/java/org/hypertrace/core/graphql/log/event/dao/GatewayServiceLogEventsRequestBuilderTest.java +++ b/hypertrace-core-graphql-log-event-schema/src/test/java/org/hypertrace/core/graphql/log/event/dao/GatewayServiceLogEventsRequestBuilderTest.java @@ -1,11 +1,14 @@ package org.hypertrace.core.graphql.log.event.dao; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.TypeLiteral; +import io.grpc.CallCredentials; import java.time.Duration; import java.time.Instant; import java.util.Collection; @@ -18,7 +21,9 @@ import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.common.utils.Converter; +import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig; import org.hypertrace.core.graphql.utils.gateway.GatewayUtilsModule; +import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry; import org.hypertrace.gateway.service.v1.common.Expression; import org.hypertrace.gateway.service.v1.common.Filter; import org.hypertrace.gateway.service.v1.common.OrderByExpression; @@ -32,7 +37,17 @@ class GatewayServiceLogEventsRequestBuilderTest extends BaseDaoTest { @BeforeEach void setup() { - Injector injector = Guice.createInjector(new GatewayUtilsModule()); + Injector injector = + Guice.createInjector( + new GatewayUtilsModule(), + new AbstractModule() { + @Override + protected void configure() { + bind(CallCredentials.class).toInstance(mock(CallCredentials.class)); + bind(GraphQlServiceConfig.class).toInstance(mock(GraphQlServiceConfig.class)); + bind(GrpcChannelRegistry.class).toInstance(mock(GrpcChannelRegistry.class)); + } + }); Converter>, Filter> filterConverter = injector.getInstance( diff --git a/hypertrace-core-graphql-log-event-schema/src/test/java/org/hypertrace/core/graphql/log/event/dao/GatewayServiceLogEventsResponseConverterTest.java b/hypertrace-core-graphql-log-event-schema/src/test/java/org/hypertrace/core/graphql/log/event/dao/GatewayServiceLogEventsResponseConverterTest.java index cbf93a9a..f8255252 100644 --- a/hypertrace-core-graphql-log-event-schema/src/test/java/org/hypertrace/core/graphql/log/event/dao/GatewayServiceLogEventsResponseConverterTest.java +++ b/hypertrace-core-graphql-log-event-schema/src/test/java/org/hypertrace/core/graphql/log/event/dao/GatewayServiceLogEventsResponseConverterTest.java @@ -1,11 +1,14 @@ package org.hypertrace.core.graphql.log.event.dao; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.TypeLiteral; +import io.grpc.CallCredentials; import java.time.Duration; import java.time.Instant; import java.util.Collection; @@ -16,7 +19,9 @@ import org.hypertrace.core.graphql.common.request.AttributeRequest; import org.hypertrace.core.graphql.common.utils.BiConverter; import org.hypertrace.core.graphql.log.event.schema.LogEventResultSet; +import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig; import org.hypertrace.core.graphql.utils.gateway.GatewayUtilsModule; +import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry; import org.hypertrace.gateway.service.v1.common.Value; import org.hypertrace.gateway.service.v1.common.ValueType; import org.hypertrace.gateway.service.v1.log.events.LogEvent; @@ -30,7 +35,17 @@ class GatewayServiceLogEventsResponseConverterTest extends BaseDaoTest { @BeforeEach void setup() { - Injector injector = Guice.createInjector(new GatewayUtilsModule()); + Injector injector = + Guice.createInjector( + new GatewayUtilsModule(), + new AbstractModule() { + @Override + protected void configure() { + bind(CallCredentials.class).toInstance(mock(CallCredentials.class)); + bind(GraphQlServiceConfig.class).toInstance(mock(GraphQlServiceConfig.class)); + bind(GrpcChannelRegistry.class).toInstance(mock(GrpcChannelRegistry.class)); + } + }); BiConverter, Map, Map> attributeMapConverter = injector.getInstance( 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 25f43029..ea01b80b 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 @@ -66,9 +66,10 @@ public Object attribute(String key) { } @Override - public LogEventResultSet logEvents() { + public List logEvents() { List list = spanIdToLogEvents.getOrDefault(id, Collections.emptyList()); - return new ConvertedLogEventResultSet(list, list.size(), list.size()); + return list; + // return new ConvertedLogEventResultSet(list, list.size(), list.size()); } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java index d84ced5a..c4a5b954 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java @@ -21,7 +21,6 @@ import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterOperatorType; import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterType; -import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.common.utils.BiConverter; import org.hypertrace.core.graphql.common.utils.Converter; import org.hypertrace.core.graphql.context.GraphQlRequestContext; @@ -78,7 +77,7 @@ class SpanLogEventFetcher { * */ Single fetchLogEvents( - SpanRequest gqlRequest, SpansResponse spansResponse) { + SpanRequest gqlRequest, SpansResponse spansResponse) { if (null == gqlRequest.spanEventsRequest().idAttribute() || null == gqlRequest.logEventAttributes() || gqlRequest.logEventAttributes().isEmpty()) { @@ -98,7 +97,7 @@ Single fetchLogEvents( } private Single buildLogEventsRequest( - SpanRequest gqlRequest, SpansResponse spansResponse) { + SpanRequest gqlRequest, SpansResponse spansResponse) { return zip( this.attributeConverter.convert(gqlRequest.logEventAttributes()), buildLogEventsQueryFilter(gqlRequest, spansResponse).flatMap(filterConverter::convert), @@ -114,7 +113,7 @@ private Single buildLogEventsRequest( } private Single>> buildLogEventsQueryFilter( - SpanRequest gqlRequest, SpansResponse spansResponse) { + SpanRequest gqlRequest, SpansResponse spansResponse) { List spanIds = spansResponse.getSpansList().stream() .map( diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java index fbcf5b0d..c3e62eac 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/SpanRequestBuilder.java @@ -3,7 +3,6 @@ import graphql.schema.DataFetchingFieldSelectionSet; import io.reactivex.rxjava3.core.Single; import java.util.Map; -import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; import org.hypertrace.core.graphql.context.GraphQlRequestContext; public interface SpanRequestBuilder { diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java index c591e167..d55d3bfb 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java @@ -3,9 +3,10 @@ import graphql.annotations.annotationTypes.GraphQLField; import graphql.annotations.annotationTypes.GraphQLName; import graphql.annotations.annotationTypes.GraphQLNonNull; +import java.util.List; import org.hypertrace.core.graphql.common.schema.attributes.AttributeQueryable; import org.hypertrace.core.graphql.common.schema.id.Identifiable; -import org.hypertrace.core.graphql.log.event.schema.LogEventResultSet; +import org.hypertrace.core.graphql.log.event.schema.LogEvent; @GraphQLName(Span.TYPE_NAME) public interface Span extends AttributeQueryable, Identifiable { @@ -15,5 +16,5 @@ public interface Span extends AttributeQueryable, Identifiable { @GraphQLField @GraphQLNonNull @GraphQLName(LOG_EVENT_KEY) - LogEventResultSet logEvents(); + List logEvents(); } From 563abae53663921630981b5098558fa6e90fe333 Mon Sep 17 00:00:00 2001 From: rish691 Date: Wed, 28 Apr 2021 19:39:38 +0530 Subject: [PATCH 8/9] fix build failure --- .../build.gradle.kts | 14 ++ .../span/dao/GatewayServiceSpanConverter.java | 6 +- .../span/dao/GatewayServiceSpanDao.java | 8 +- .../graphql/span/dao/SpanLogEventDao.java | 79 +++++++ .../graphql/span/dao/SpanLogEventFetcher.java | 197 ---------------- .../span/dao/SpanLogEventRequestBuilder.java | 88 +++++++ .../dao/SpanLogEventResponseConverter.java | 76 ++++++ .../LogEventAttributeRequestBuilder.java | 2 +- .../core/graphql/span/schema/Span.java | 5 +- .../core/graphql/span/dao/BaseDaoTest.java | 220 ++++++++++++++++++ .../dao/SpanLogEventRequestBuilderTest.java | 147 ++++++++++++ .../SpanLogEventResponseConverterTest.java | 73 ++++++ .../LogEventAttributeRequestBuilderTest.java | 59 +++++ 13 files changed, 766 insertions(+), 208 deletions(-) create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventDao.java delete mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilder.java create mode 100644 hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverter.java create mode 100644 hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/BaseDaoTest.java create mode 100644 hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilderTest.java create mode 100644 hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverterTest.java create mode 100644 hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilderTest.java diff --git a/hypertrace-core-graphql-span-schema/build.gradle.kts b/hypertrace-core-graphql-span-schema/build.gradle.kts index e2613cfb..ab5ed343 100644 --- a/hypertrace-core-graphql-span-schema/build.gradle.kts +++ b/hypertrace-core-graphql-span-schema/build.gradle.kts @@ -25,4 +25,18 @@ dependencies { implementation(project(":hypertrace-core-graphql-log-event-schema")) implementation(project(":hypertrace-core-graphql-deserialization")) implementation(project(":hypertrace-core-graphql-schema-utils")) + implementation(project(":hypertrace-core-graphql-attribute-scope-constants")) + + testImplementation("org.junit.jupiter:junit-jupiter") + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation(project(":hypertrace-core-graphql-gateway-service-utils")) + testImplementation("org.mockito:mockito-core") + testImplementation("org.mockito:mockito-junit-jupiter") + + testAnnotationProcessor("org.projectlombok:lombok") + testCompileOnly("org.projectlombok:lombok") +} + +tasks.test { + useJUnitPlatform() } 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 ea01b80b..68cef857 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 @@ -66,10 +66,10 @@ public Object attribute(String key) { } @Override - public List logEvents() { + public LogEventResultSet logEvents() { List list = spanIdToLogEvents.getOrDefault(id, Collections.emptyList()); - return list; - // return new ConvertedLogEventResultSet(list, list.size(), list.size()); + // return list; + return new ConvertedLogEventResultSet(list, list.size(), list.size()); } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java index 85e0be39..f6d93a1a 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/GatewayServiceSpanDao.java @@ -20,7 +20,7 @@ class GatewayServiceSpanDao implements SpanDao { private final GraphQlGrpcContextBuilder grpcContextBuilder; private final GatewayServiceSpanRequestBuilder requestBuilder; private final GatewayServiceSpanConverter spanConverter; - private final SpanLogEventFetcher spanLogEventFetcher; + private final SpanLogEventDao spanLogEventDao; @Inject GatewayServiceSpanDao( @@ -28,11 +28,11 @@ class GatewayServiceSpanDao implements SpanDao { GraphQlGrpcContextBuilder grpcContextBuilder, GatewayServiceSpanRequestBuilder requestBuilder, GatewayServiceSpanConverter spanConverter, - SpanLogEventFetcher spanLogEventFetcher) { + SpanLogEventDao spanLogEventDao) { this.grpcContextBuilder = grpcContextBuilder; this.requestBuilder = requestBuilder; this.spanConverter = spanConverter; - this.spanLogEventFetcher = spanLogEventFetcher; + this.spanLogEventDao = spanLogEventDao; this.gatewayServiceStub = gatewayServiceFutureStub; } @@ -42,7 +42,7 @@ public Single getSpans(SpanRequest request) { .buildRequest(request) .flatMap( serverRequest -> this.makeRequest(request.spanEventsRequest().context(), serverRequest)) - .flatMap(serverResponse -> spanLogEventFetcher.fetchLogEvents(request, serverResponse)) + .flatMap(serverResponse -> spanLogEventDao.fetchLogEvents(request, serverResponse)) .flatMap( spanLogEventsResponse -> this.spanConverter.convert(request, spanLogEventsResponse)); } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventDao.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventDao.java new file mode 100644 index 00000000..ff9b168d --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventDao.java @@ -0,0 +1,79 @@ +package org.hypertrace.core.graphql.span.dao; + +import static java.util.concurrent.TimeUnit.SECONDS; + +import io.reactivex.rxjava3.core.Single; +import java.util.Map; +import javax.inject.Inject; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.span.request.SpanRequest; +import org.hypertrace.core.graphql.utils.grpc.GraphQlGrpcContextBuilder; +import org.hypertrace.gateway.service.GatewayServiceGrpc.GatewayServiceFutureStub; +import org.hypertrace.gateway.service.v1.log.events.LogEventsRequest; +import org.hypertrace.gateway.service.v1.log.events.LogEventsResponse; +import org.hypertrace.gateway.service.v1.span.SpansResponse; + +class SpanLogEventDao { + + private static final int DEFAULT_DEADLINE_SEC = 10; + + private final GatewayServiceFutureStub gatewayServiceStub; + private final GraphQlGrpcContextBuilder grpcContextBuilder; + private final SpanLogEventRequestBuilder spanLogEventRequestBuilder; + private final SpanLogEventResponseConverter spanLogEventResponseConverter; + + @Inject + SpanLogEventDao( + GatewayServiceFutureStub gatewayServiceFutureStub, + GraphQlGrpcContextBuilder grpcContextBuilder, + SpanLogEventRequestBuilder spanLogEventRequestBuilder, + SpanLogEventResponseConverter spanLogEventResponseConverter) { + this.gatewayServiceStub = gatewayServiceFutureStub; + this.grpcContextBuilder = grpcContextBuilder; + this.spanLogEventRequestBuilder = spanLogEventRequestBuilder; + this.spanLogEventResponseConverter = spanLogEventResponseConverter; + } + + /** + * + * + *
    + *
  • 1. Fetch log event attributes from {@code gqlRequest} + *
  • 2. Build log event request using attribute and spanIds as filter + *
  • 3. Query log events + *
  • 4. Processed log events response to build mapping from spanId to logEvent + *
+ */ + Single fetchLogEvents( + SpanRequest gqlRequest, SpansResponse spansResponse) { + if (null == gqlRequest.spanEventsRequest().idAttribute() + || null == gqlRequest.logEventAttributes() + || gqlRequest.logEventAttributes().isEmpty()) { + return Single.just(new SpanLogEventsResponse(spansResponse, Map.of())); + } + return spanLogEventRequestBuilder + .buildLogEventsRequest(gqlRequest, spansResponse) + .flatMap( + logEventsRequest -> + makeRequest(gqlRequest.spanEventsRequest().context(), logEventsRequest)) + .flatMap( + logEventsResponse -> + spanLogEventResponseConverter.buildResponse( + gqlRequest.spanEventsRequest().context(), + gqlRequest.logEventAttributes(), + spansResponse, + logEventsResponse)); + } + + private Single makeRequest( + GraphQlRequestContext context, LogEventsRequest request) { + return Single.fromFuture( + this.grpcContextBuilder + .build(context) + .callInContext( + () -> + this.gatewayServiceStub + .withDeadlineAfter(DEFAULT_DEADLINE_SEC, SECONDS) + .getLogEvents(request))); + } +} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java deleted file mode 100644 index c4a5b954..00000000 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventFetcher.java +++ /dev/null @@ -1,197 +0,0 @@ -package org.hypertrace.core.graphql.span.dao; - -import static io.reactivex.rxjava3.core.Single.zip; -import static java.util.concurrent.TimeUnit.SECONDS; - -import io.reactivex.rxjava3.core.Observable; -import io.reactivex.rxjava3.core.Single; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import javax.inject.Inject; -import lombok.experimental.Accessors; -import org.hypertrace.core.graphql.attributes.AttributeStore; -import org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString; -import org.hypertrace.core.graphql.common.request.AttributeAssociation; -import org.hypertrace.core.graphql.common.request.AttributeRequest; -import org.hypertrace.core.graphql.common.request.FilterRequestBuilder; -import org.hypertrace.core.graphql.common.schema.attributes.AttributeScope; -import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; -import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterOperatorType; -import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterType; -import org.hypertrace.core.graphql.common.utils.BiConverter; -import org.hypertrace.core.graphql.common.utils.Converter; -import org.hypertrace.core.graphql.context.GraphQlRequestContext; -import org.hypertrace.core.graphql.span.request.SpanRequest; -import org.hypertrace.core.graphql.utils.grpc.GraphQlGrpcContextBuilder; -import org.hypertrace.gateway.service.GatewayServiceGrpc.GatewayServiceFutureStub; -import org.hypertrace.gateway.service.v1.common.Expression; -import org.hypertrace.gateway.service.v1.common.Filter; -import org.hypertrace.gateway.service.v1.common.Value; -import org.hypertrace.gateway.service.v1.log.events.LogEventsRequest; -import org.hypertrace.gateway.service.v1.log.events.LogEventsResponse; -import org.hypertrace.gateway.service.v1.span.SpansResponse; - -class SpanLogEventFetcher { - - private static final int DEFAULT_DEADLINE_SEC = 10; - - private final Converter, Set> attributeConverter; - private final Converter>, Filter> filterConverter; - private final BiConverter, Map, Map> - attributeMapConverter; - private final FilterRequestBuilder filterRequestBuilder; - private final GatewayServiceFutureStub gatewayServiceStub; - private final GraphQlGrpcContextBuilder grpcContextBuilder; - private final AttributeStore attributeStore; - - @Inject - SpanLogEventFetcher( - Converter, Set> attributeConverter, - Converter>, Filter> filterConverter, - BiConverter, Map, Map> - attributeMapConverter, - FilterRequestBuilder filterRequestBuilder, - GatewayServiceFutureStub gatewayServiceFutureStub, - GraphQlGrpcContextBuilder grpcContextBuilder, - AttributeStore attributeStore) { - this.attributeConverter = attributeConverter; - this.filterConverter = filterConverter; - this.attributeMapConverter = attributeMapConverter; - this.filterRequestBuilder = filterRequestBuilder; - this.gatewayServiceStub = gatewayServiceFutureStub; - this.grpcContextBuilder = grpcContextBuilder; - this.attributeStore = attributeStore; - } - - /** - * - * - *
    - *
  • 1. Fetch log event attributes from {@code gqlRequest} - *
  • 2. Build log event request using attribute and spanIds as filter - *
  • 3. Query log events - *
  • 4. Processed log events response to build mapping from spanId to logEvent - *
- */ - Single fetchLogEvents( - SpanRequest gqlRequest, SpansResponse spansResponse) { - if (null == gqlRequest.spanEventsRequest().idAttribute() - || null == gqlRequest.logEventAttributes() - || gqlRequest.logEventAttributes().isEmpty()) { - return Single.just(new SpanLogEventsResponse(spansResponse, Map.of())); - } - return buildLogEventsRequest(gqlRequest, spansResponse) - .flatMap( - logEventsRequest -> - makeRequest(gqlRequest.spanEventsRequest().context(), logEventsRequest)) - .flatMap( - logEventsResponse -> - buildResponse( - gqlRequest.spanEventsRequest().context(), - gqlRequest.logEventAttributes(), - spansResponse, - logEventsResponse)); - } - - private Single buildLogEventsRequest( - SpanRequest gqlRequest, SpansResponse spansResponse) { - return zip( - this.attributeConverter.convert(gqlRequest.logEventAttributes()), - buildLogEventsQueryFilter(gqlRequest, spansResponse).flatMap(filterConverter::convert), - (selections, filter) -> - LogEventsRequest.newBuilder() - .setStartTimeMillis( - gqlRequest.spanEventsRequest().timeRange().startTime().toEpochMilli()) - .setEndTimeMillis( - gqlRequest.spanEventsRequest().timeRange().endTime().toEpochMilli()) - .addAllSelection(selections) - .setFilter(filter) - .build()); - } - - private Single>> buildLogEventsQueryFilter( - SpanRequest gqlRequest, SpansResponse spansResponse) { - List spanIds = - spansResponse.getSpansList().stream() - .map( - spanEvent -> - spanEvent - .getAttributesMap() - .get(gqlRequest.spanEventsRequest().idAttribute().attribute().id()) - .getString()) - .collect(Collectors.toList()); - - return filterRequestBuilder.build( - gqlRequest.spanEventsRequest().context(), - HypertraceCoreAttributeScopeString.LOG_EVENT, - Set.of(new LogEventFilter(spanIds))); - } - - private Single makeRequest( - GraphQlRequestContext context, LogEventsRequest request) { - return Single.fromFuture( - this.grpcContextBuilder - .build(context) - .callInContext( - () -> - this.gatewayServiceStub - .withDeadlineAfter(DEFAULT_DEADLINE_SEC, SECONDS) - .getLogEvents(request))); - } - - private Single buildResponse( - GraphQlRequestContext graphQlRequestContext, - Collection attributeRequests, - SpansResponse spansResponse, - LogEventsResponse logEventsResponse) { - String key = - attributeStore - .getForeignIdAttribute( - graphQlRequestContext, - HypertraceCoreAttributeScopeString.LOG_EVENT, - HypertraceCoreAttributeScopeString.SPAN) - .blockingGet() - .key(); - return Observable.fromIterable(logEventsResponse.getLogEventsList()) - .concatMapSingle( - logEventsResponseVar -> this.convert(attributeRequests, logEventsResponseVar)) - .collect(Collectors.groupingBy(logEvent -> (String) logEvent.attribute(key))) - .map( - spanIdVsLogEventsMap -> new SpanLogEventsResponse(spansResponse, spanIdVsLogEventsMap)); - } - - private Single convert( - Collection request, - org.hypertrace.gateway.service.v1.log.events.LogEvent logEvent) { - return this.attributeMapConverter - .convert(request, logEvent.getAttributesMap()) - .map(ConvertedLogEvent::new); - } - - @lombok.Value - @Accessors(fluent = true) - private static class ConvertedLogEvent - implements org.hypertrace.core.graphql.log.event.schema.LogEvent { - - Map attributeValues; - - @Override - public Object attribute(String key) { - return this.attributeValues.get(key); - } - } - - @lombok.Value - @Accessors(fluent = true) - private static class LogEventFilter implements FilterArgument { - FilterType type = FilterType.ID; - String key = null; - FilterOperatorType operator = FilterOperatorType.IN; - Collection value; - AttributeScope idType = null; - String idScope = HypertraceCoreAttributeScopeString.SPAN; - } -} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilder.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilder.java new file mode 100644 index 00000000..46d1d4f1 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilder.java @@ -0,0 +1,88 @@ +package org.hypertrace.core.graphql.span.dao; + +import static io.reactivex.rxjava3.core.Single.zip; + +import io.reactivex.rxjava3.core.Single; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javax.inject.Inject; +import lombok.experimental.Accessors; +import org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString; +import org.hypertrace.core.graphql.common.request.AttributeAssociation; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.request.FilterRequestBuilder; +import org.hypertrace.core.graphql.common.schema.attributes.AttributeScope; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterOperatorType; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterType; +import org.hypertrace.core.graphql.common.utils.Converter; +import org.hypertrace.core.graphql.span.request.SpanRequest; +import org.hypertrace.gateway.service.v1.common.Expression; +import org.hypertrace.gateway.service.v1.common.Filter; +import org.hypertrace.gateway.service.v1.log.events.LogEventsRequest; +import org.hypertrace.gateway.service.v1.span.SpansResponse; + +class SpanLogEventRequestBuilder { + + private final Converter, Set> attributeConverter; + private final Converter>, Filter> filterConverter; + private final FilterRequestBuilder filterRequestBuilder; + + @Inject + SpanLogEventRequestBuilder( + Converter, Set> attributeConverter, + Converter>, Filter> filterConverter, + FilterRequestBuilder filterRequestBuilder) { + this.attributeConverter = attributeConverter; + this.filterConverter = filterConverter; + this.filterRequestBuilder = filterRequestBuilder; + } + + Single buildLogEventsRequest( + SpanRequest gqlRequest, SpansResponse spansResponse) { + return zip( + this.attributeConverter.convert(gqlRequest.logEventAttributes()), + buildLogEventsQueryFilter(gqlRequest, spansResponse).flatMap(filterConverter::convert), + (selections, filter) -> + LogEventsRequest.newBuilder() + .setStartTimeMillis( + gqlRequest.spanEventsRequest().timeRange().startTime().toEpochMilli()) + .setEndTimeMillis( + gqlRequest.spanEventsRequest().timeRange().endTime().toEpochMilli()) + .addAllSelection(selections) + .setFilter(filter) + .build()); + } + + private Single>> buildLogEventsQueryFilter( + SpanRequest gqlRequest, SpansResponse spansResponse) { + List spanIds = + spansResponse.getSpansList().stream() + .map( + spanEvent -> + spanEvent + .getAttributesMap() + .get(gqlRequest.spanEventsRequest().idAttribute().attribute().id()) + .getString()) + .collect(Collectors.toList()); + + return filterRequestBuilder.build( + gqlRequest.spanEventsRequest().context(), + HypertraceCoreAttributeScopeString.LOG_EVENT, + Set.of(new LogEventFilter(spanIds))); + } + + @lombok.Value + @Accessors(fluent = true) + private static class LogEventFilter implements FilterArgument { + + FilterType type = FilterType.ID; + String key = null; + FilterOperatorType operator = FilterOperatorType.IN; + Collection value; + AttributeScope idType = null; + String idScope = HypertraceCoreAttributeScopeString.SPAN; + } +} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverter.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverter.java new file mode 100644 index 00000000..83c64172 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverter.java @@ -0,0 +1,76 @@ +package org.hypertrace.core.graphql.span.dao; + +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Single; +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; +import javax.inject.Inject; +import lombok.experimental.Accessors; +import org.hypertrace.core.graphql.attributes.AttributeStore; +import org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.utils.BiConverter; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.log.event.schema.LogEvent; +import org.hypertrace.gateway.service.v1.common.Value; +import org.hypertrace.gateway.service.v1.log.events.LogEventsResponse; +import org.hypertrace.gateway.service.v1.span.SpansResponse; + +class SpanLogEventResponseConverter { + + private final BiConverter, Map, Map> + attributeMapConverter; + private final AttributeStore attributeStore; + + @Inject + SpanLogEventResponseConverter( + BiConverter, Map, Map> + attributeMapConverter, + AttributeStore attributeStore) { + this.attributeMapConverter = attributeMapConverter; + this.attributeStore = attributeStore; + } + + Single buildResponse( + GraphQlRequestContext graphQlRequestContext, + Collection attributeRequests, + SpansResponse spansResponse, + LogEventsResponse logEventsResponse) { + String key = + attributeStore + .getForeignIdAttribute( + graphQlRequestContext, + HypertraceCoreAttributeScopeString.LOG_EVENT, + HypertraceCoreAttributeScopeString.SPAN) + .blockingGet() + .key(); + return Observable.fromIterable(logEventsResponse.getLogEventsList()) + .concatMapSingle( + logEventsResponseVar -> this.convert(attributeRequests, logEventsResponseVar)) + .collect(Collectors.groupingBy(logEvent -> (String) logEvent.attribute(key))) + .map( + spanIdVsLogEventsMap -> new SpanLogEventsResponse(spansResponse, spanIdVsLogEventsMap)); + } + + private Single convert( + Collection request, + org.hypertrace.gateway.service.v1.log.events.LogEvent logEvent) { + return this.attributeMapConverter + .convert(request, logEvent.getAttributesMap()) + .map(v -> new ConvertedLogEvent(v)); + } + + @lombok.Value + @Accessors(fluent = true) + private static class ConvertedLogEvent + implements org.hypertrace.core.graphql.log.event.schema.LogEvent { + + Map attributeValues; + + @Override + public Object attribute(String key) { + return this.attributeValues.get(key); + } + } +} diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java index 434f08d4..3e311fc3 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilder.java @@ -45,7 +45,7 @@ private Stream getLogEventSelectionFields( return this.selectionFinder.findSelections( selectionSet, SelectionQuery.builder() - .selectionPath(List.of(RESULT_SET_RESULTS_NAME, LOG_EVENT_KEY)) + .selectionPath(List.of(RESULT_SET_RESULTS_NAME, LOG_EVENT_KEY, RESULT_SET_RESULTS_NAME)) .build()); } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java index d55d3bfb..c591e167 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/schema/Span.java @@ -3,10 +3,9 @@ import graphql.annotations.annotationTypes.GraphQLField; import graphql.annotations.annotationTypes.GraphQLName; import graphql.annotations.annotationTypes.GraphQLNonNull; -import java.util.List; import org.hypertrace.core.graphql.common.schema.attributes.AttributeQueryable; import org.hypertrace.core.graphql.common.schema.id.Identifiable; -import org.hypertrace.core.graphql.log.event.schema.LogEvent; +import org.hypertrace.core.graphql.log.event.schema.LogEventResultSet; @GraphQLName(Span.TYPE_NAME) public interface Span extends AttributeQueryable, Identifiable { @@ -16,5 +15,5 @@ public interface Span extends AttributeQueryable, Identifiable { @GraphQLField @GraphQLNonNull @GraphQLName(LOG_EVENT_KEY) - List logEvents(); + LogEventResultSet logEvents(); } diff --git a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/BaseDaoTest.java b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/BaseDaoTest.java new file mode 100644 index 00000000..0e3562bf --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/BaseDaoTest.java @@ -0,0 +1,220 @@ +package org.hypertrace.core.graphql.span.dao; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.time.Instant; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import lombok.Value; +import lombok.experimental.Accessors; +import org.hypertrace.core.graphql.attributes.AttributeModel; +import org.hypertrace.core.graphql.attributes.AttributeModelMetricAggregationType; +import org.hypertrace.core.graphql.attributes.AttributeModelType; +import org.hypertrace.core.graphql.common.request.AttributeAssociation; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.request.ResultSetRequest; +import org.hypertrace.core.graphql.common.schema.arguments.TimeRangeArgument; +import org.hypertrace.core.graphql.common.schema.attributes.AttributeScope; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterOperatorType; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterType; +import org.hypertrace.core.graphql.common.schema.results.arguments.order.OrderArgument; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.span.request.SpanRequest; +import org.hypertrace.gateway.service.v1.common.ValueType; +import org.hypertrace.gateway.service.v1.log.events.LogEvent; +import org.hypertrace.gateway.service.v1.log.events.LogEventsResponse; +import org.hypertrace.gateway.service.v1.span.SpanEvent; +import org.hypertrace.gateway.service.v1.span.SpansResponse; + +class BaseDaoTest { + + @Value + @Accessors(fluent = true) + static class DefaultAttributeRequest implements AttributeRequest { + + AttributeModel attribute; + + @Override + public String alias() { + return attribute.id(); + } + } + + @Value + @Accessors(fluent = true) + static class DefaultAttributeModel implements AttributeModel { + + String id; + String scope; + String key; + String displayName; + AttributeModelType type; + String units; + boolean onlySupportsGrouping; + boolean onlySupportsAggregation; + List supportedMetricAggregationTypes; + boolean groupable; + } + + @Value + @Accessors(fluent = true) + static class NormalizedFilter implements FilterArgument { + + FilterType type = FilterType.ATTRIBUTE; + String key; + FilterOperatorType operator; + Object value; + String idScope = null; + AttributeScope idType = null; + } + + @Value + @Accessors(fluent = true) + static class DefaultSpanRequest implements SpanRequest { + + ResultSetRequest spanEventsRequest; + Collection logEventAttributes; + } + + @Value + @Accessors(fluent = true) + static class DefaultResultSetRequest implements ResultSetRequest { + + GraphQlRequestContext context; + Collection attributes; + TimeRangeArgument timeRange; + AttributeRequest idAttribute; + int limit; + int offset; + List orderArguments; + Collection> filterArguments; + Optional spaceId; + } + + @Value + @Accessors(fluent = true) + class DefaultTimeRange implements TimeRangeArgument { + + @JsonProperty(TIME_RANGE_ARGUMENT_START_TIME) + Instant startTime; + + @JsonProperty(TIME_RANGE_ARGUMENT_END_TIME) + Instant endTime; + } + + static AttributeRequest traceIdAttribute = + new DefaultAttributeRequest( + new DefaultAttributeModel( + "traceId", + "LOG_EVENT", + "traceId", + "Trace Id", + AttributeModelType.STRING, + "", + false, + false, + Collections.emptyList(), + false)); + + static AttributeRequest spanIdAttribute = + new DefaultAttributeRequest( + new DefaultAttributeModel( + "spanId", + "LOG_EVENT", + "spanId", + "Span Id", + AttributeModelType.STRING, + "", + false, + false, + Collections.emptyList(), + false)); + + static AttributeRequest attributesAttribute = + new DefaultAttributeRequest( + new DefaultAttributeModel( + "attributes", + "LOG_EVENT", + "attributes", + "Attributes", + AttributeModelType.STRING, + "", + false, + false, + Collections.emptyList(), + false)); + + static AttributeRequest eventIdAttribute = + new DefaultAttributeRequest( + new DefaultAttributeModel( + "id", + "EVENT", + "id", + "Id", + AttributeModelType.STRING, + "", + false, + false, + Collections.emptyList(), + false)); + + static SpansResponse spansResponse = + SpansResponse.newBuilder() + .addSpans( + SpanEvent.newBuilder() + .putAllAttributes(Map.of("id", getValue("span1"), "traceId", getValue("trace1"))) + .build()) + .addSpans( + SpanEvent.newBuilder() + .putAllAttributes(Map.of("id", getValue("span2"), "traceId", getValue("trace1"))) + .build()) + .addSpans( + SpanEvent.newBuilder() + .putAllAttributes(Map.of("id", getValue("span3"), "traceId", getValue("trace1"))) + .build()) + .build(); + + static LogEventsResponse logEventsResponse = + LogEventsResponse.newBuilder() + .addLogEvents( + LogEvent.newBuilder() + .putAllAttributes( + Map.of( + "traceId", + getValue("trace1"), + "attributes", + getValue("event: error"), + "spanId", + getValue("span1")))) + .addLogEvents( + LogEvent.newBuilder() + .putAllAttributes( + Map.of( + "traceId", + getValue("trace1"), + "attributes", + getValue("event: error"), + "spanId", + getValue("span1")))) + .addLogEvents( + LogEvent.newBuilder() + .putAllAttributes( + Map.of( + "traceId", + getValue("trace1"), + "attributes", + getValue("event: error"), + "spanId", + getValue("span2")))) + .build(); + + static org.hypertrace.gateway.service.v1.common.Value getValue(String value) { + return org.hypertrace.gateway.service.v1.common.Value.newBuilder() + .setValueType(ValueType.STRING) + .setString(value) + .build(); + } +} 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 new file mode 100644 index 00000000..26488978 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventRequestBuilderTest.java @@ -0,0 +1,147 @@ +package org.hypertrace.core.graphql.span.dao; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; +import io.grpc.CallCredentials; +import io.reactivex.rxjava3.core.Single; +import java.time.Duration; +import java.time.Instant; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.hypertrace.core.graphql.common.request.AttributeAssociation; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.request.FilterRequestBuilder; +import org.hypertrace.core.graphql.common.request.ResultSetRequest; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; +import org.hypertrace.core.graphql.common.utils.Converter; +import org.hypertrace.core.graphql.span.request.SpanRequest; +import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig; +import org.hypertrace.core.graphql.utils.gateway.GatewayUtilsModule; +import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry; +import org.hypertrace.gateway.service.v1.common.Expression; +import org.hypertrace.gateway.service.v1.common.Filter; +import org.hypertrace.gateway.service.v1.common.Operator; +import org.hypertrace.gateway.service.v1.log.events.LogEventsRequest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class SpanLogEventRequestBuilderTest extends BaseDaoTest { + + @Mock private FilterRequestBuilder filterRequestBuilder; + + private SpanLogEventRequestBuilder spanLogEventRequestBuilder; + + @BeforeEach + void beforeEach() { + Injector injector = + Guice.createInjector( + new GatewayUtilsModule(), + new AbstractModule() { + @Override + protected void configure() { + bind(CallCredentials.class).toInstance(mock(CallCredentials.class)); + bind(GraphQlServiceConfig.class).toInstance(mock(GraphQlServiceConfig.class)); + bind(GrpcChannelRegistry.class).toInstance(mock(GrpcChannelRegistry.class)); + } + }); + + Converter>, Filter> filterConverter = + injector.getInstance( + Key.get( + new TypeLiteral< + Converter>, Filter>>() {})); + + Converter, Set> attributeConverter = + injector.getInstance( + Key.get( + new TypeLiteral, Set>>() {})); + + spanLogEventRequestBuilder = + new SpanLogEventRequestBuilder(attributeConverter, filterConverter, filterRequestBuilder); + } + + @Test + void testBuildRequest() { + doAnswer( + invocation -> { + Set filterArguments = invocation.getArgument(2, Set.class); + FilterArgument filterArgument = filterArguments.iterator().next(); + return Single.just( + List.of( + AttributeAssociation.of( + spanIdAttribute.attribute(), + new NormalizedFilter( + spanIdAttribute.attribute().key(), + filterArgument.operator(), + filterArgument.value())))); + }) + .when(filterRequestBuilder) + .build(any(), any(), anyCollection()); + + long startTime = System.currentTimeMillis(); + long endTime = System.currentTimeMillis() + Duration.ofHours(1).toMillis(); + + Collection logAttributeRequests = + List.of(spanIdAttribute, traceIdAttribute, attributesAttribute); + ResultSetRequest resultSetRequest = + new DefaultResultSetRequest( + null, + List.of(eventIdAttribute), + new DefaultTimeRange(Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime)), + eventIdAttribute, + 0, + 0, + List.of(), + Collections.emptyList(), + Optional.empty()); + SpanRequest spanRequest = new DefaultSpanRequest(resultSetRequest, logAttributeRequests); + + LogEventsRequest logEventsRequest = + spanLogEventRequestBuilder.buildLogEventsRequest(spanRequest, spansResponse).blockingGet(); + + assertEquals(Operator.IN, logEventsRequest.getFilter().getChildFilter(0).getOperator()); + assertEquals( + spanIdAttribute.attribute().id(), + logEventsRequest + .getFilter() + .getChildFilter(0) + .getLhs() + .getColumnIdentifier() + .getColumnName()); + assertEquals( + List.of("span1", "span2", "span3"), + logEventsRequest + .getFilter() + .getChildFilter(0) + .getRhs() + .getLiteral() + .getValue() + .getStringArrayList() + .stream() + .collect(Collectors.toList())); + assertEquals(startTime, logEventsRequest.getStartTimeMillis()); + assertEquals(endTime, logEventsRequest.getEndTimeMillis()); + assertEquals( + Set.of("attributes", "traceId", "spanId"), + logEventsRequest.getSelectionList().stream() + .map(v -> v.getColumnIdentifier().getColumnName()) + .collect(Collectors.toSet())); + } +} diff --git a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverterTest.java b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverterTest.java new file mode 100644 index 00000000..2019b435 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverterTest.java @@ -0,0 +1,73 @@ +package org.hypertrace.core.graphql.span.dao; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; + +import io.reactivex.rxjava3.core.Single; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.stream.Collectors; +import org.hypertrace.core.graphql.attributes.AttributeStore; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.utils.BiConverter; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.gateway.service.v1.common.Value; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class SpanLogEventResponseConverterTest extends BaseDaoTest { + + @Mock + BiConverter, Map, Map> + attributeMapConverter; + + @Mock AttributeStore attributeStore; + @Mock GraphQlRequestContext requestContext; + + private SpanLogEventResponseConverter spanLogEventResponseConverter; + + @BeforeEach + void beforeEach() { + spanLogEventResponseConverter = + new SpanLogEventResponseConverter(attributeMapConverter, attributeStore); + } + + @Test + void testBuildResponse() { + Collection attributeRequests = + List.of(spanIdAttribute, traceIdAttribute, attributesAttribute); + + when(attributeStore.getForeignIdAttribute(any(), anyString(), anyString())) + .thenReturn(Single.just(spanIdAttribute.attribute())); + + doAnswer( + invocation -> { + Map map = invocation.getArgument(1, Map.class); + return Single.just( + map.entrySet().stream() + .collect(Collectors.toMap(Entry::getKey, v -> v.getValue().getString()))); + }) + .when(attributeMapConverter) + .convert(anyCollection(), anyMap()); + + SpanLogEventsResponse response = + spanLogEventResponseConverter + .buildResponse(requestContext, attributeRequests, spansResponse, logEventsResponse) + .blockingGet(); + + assertEquals(spansResponse, response.spansResponse()); + assertEquals(Set.of("span1", "span2"), response.spanIdToLogEvents().keySet()); + } +} diff --git a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilderTest.java b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilderTest.java new file mode 100644 index 00000000..d5efcca0 --- /dev/null +++ b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/request/LogEventAttributeRequestBuilderTest.java @@ -0,0 +1,59 @@ +package org.hypertrace.core.graphql.span.request; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import graphql.schema.DataFetchingFieldSelectionSet; +import graphql.schema.SelectedField; +import io.reactivex.rxjava3.core.Observable; +import java.util.Set; +import java.util.stream.Stream; +import org.hypertrace.core.graphql.common.request.AttributeRequest; +import org.hypertrace.core.graphql.common.request.AttributeRequestBuilder; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.utils.schema.GraphQlSelectionFinder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class LogEventAttributeRequestBuilderTest { + + @Mock GraphQlRequestContext mockContext; + @Mock GraphQlSelectionFinder mockSelectionFinder; + @Mock AttributeRequestBuilder mockAttributeRequestBuilder; + @Mock DataFetchingFieldSelectionSet mockSelectionSet; + @Mock Stream mockAttributeQueryableStream; + @Mock AttributeRequest mockFooAttributeRequest; + @Mock AttributeRequest mockBarAttributeRequest; + + private LogEventAttributeRequestBuilder requestBuilder; + + @BeforeEach + void beforeEach() { + this.requestBuilder = + new LogEventAttributeRequestBuilder( + this.mockSelectionFinder, this.mockAttributeRequestBuilder); + } + + @Test + void canBuildRequest() { + when(this.mockSelectionFinder.findSelections(eq(this.mockSelectionSet), any())) + .thenReturn(mockAttributeQueryableStream); + when(this.mockAttributeRequestBuilder.buildForAttributeQueryableFields( + any(), any(), eq(this.mockAttributeQueryableStream))) + .thenReturn(Observable.just(this.mockFooAttributeRequest, this.mockBarAttributeRequest)); + + Set request = + this.requestBuilder + .buildAttributeRequest(this.mockContext, this.mockSelectionSet) + .blockingGet(); + + Assertions.assertEquals( + Set.of(this.mockBarAttributeRequest, this.mockFooAttributeRequest), request); + } +} From 5ebe7730a4370a15b0212ac95e374ba018d9f79a Mon Sep 17 00:00:00 2001 From: rish691 Date: Wed, 28 Apr 2021 20:19:16 +0530 Subject: [PATCH 9/9] review comments --- .../HypertraceCoreAttributeScopeModule.java | 3 ++- .../span/dao/GatewayServiceSpanConverter.java | 1 - .../dao/SpanLogEventResponseConverter.java | 27 ++++++++++++------- .../{BaseDaoTest.java => DaoTestUtil.java} | 4 +-- .../dao/SpanLogEventRequestBuilderTest.java | 14 +++++++--- .../SpanLogEventResponseConverterTest.java | 7 ++++- 6 files changed, 38 insertions(+), 18 deletions(-) rename hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/{BaseDaoTest.java => DaoTestUtil.java} (98%) diff --git a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java index 342f29b2..30e6478d 100644 --- a/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java +++ b/hypertrace-core-graphql-attribute-scope/src/main/java/org/hypertrace/core/graphql/atttributes/scopes/HypertraceCoreAttributeScopeModule.java @@ -2,6 +2,7 @@ import static org.hypertrace.core.graphql.attributes.IdMapping.forForeignId; import static org.hypertrace.core.graphql.attributes.IdMapping.forId; +import static org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString.LOG_EVENT; import static org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString.SPAN; import static org.hypertrace.core.graphql.atttributes.scopes.HypertraceCoreAttributeScopeString.TRACE; @@ -21,7 +22,7 @@ protected void configure() { Multibinder idBinder = Multibinder.newSetBinder(binder(), IdMapping.class); idBinder.addBinding().toInstance(forId(SPAN, "id")); idBinder.addBinding().toInstance(forForeignId(SPAN, TRACE, "traceId")); - + idBinder.addBinding().toInstance(forForeignId(LOG_EVENT, SPAN, "spanId")); idBinder.addBinding().toInstance(forId(TRACE, "id")); } } 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 68cef857..25f43029 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 @@ -68,7 +68,6 @@ public Object attribute(String key) { @Override public LogEventResultSet logEvents() { List list = spanIdToLogEvents.getOrDefault(id, Collections.emptyList()); - // return list; return new ConvertedLogEventResultSet(list, list.size(), list.size()); } } diff --git a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverter.java b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverter.java index 83c64172..5b9a59ce 100644 --- a/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverter.java +++ b/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverter.java @@ -37,18 +37,25 @@ Single buildResponse( Collection attributeRequests, SpansResponse spansResponse, LogEventsResponse logEventsResponse) { - String key = - attributeStore - .getForeignIdAttribute( - graphQlRequestContext, - HypertraceCoreAttributeScopeString.LOG_EVENT, - HypertraceCoreAttributeScopeString.SPAN) - .blockingGet() - .key(); + return this.attributeStore + .getForeignIdAttribute( + graphQlRequestContext, + HypertraceCoreAttributeScopeString.LOG_EVENT, + HypertraceCoreAttributeScopeString.SPAN) + .flatMap( + spanId -> + buildResponse(spanId.key(), attributeRequests, spansResponse, logEventsResponse)); + } + + private Single buildResponse( + String foreignIdAttribute, + Collection attributeRequests, + SpansResponse spansResponse, + LogEventsResponse logEventsResponse) { return Observable.fromIterable(logEventsResponse.getLogEventsList()) .concatMapSingle( logEventsResponseVar -> this.convert(attributeRequests, logEventsResponseVar)) - .collect(Collectors.groupingBy(logEvent -> (String) logEvent.attribute(key))) + .collect(Collectors.groupingBy(logEvent -> (String) logEvent.attribute(foreignIdAttribute))) .map( spanIdVsLogEventsMap -> new SpanLogEventsResponse(spansResponse, spanIdVsLogEventsMap)); } @@ -58,7 +65,7 @@ private Single convert( org.hypertrace.gateway.service.v1.log.events.LogEvent logEvent) { return this.attributeMapConverter .convert(request, logEvent.getAttributesMap()) - .map(v -> new ConvertedLogEvent(v)); + .map(ConvertedLogEvent::new); } @lombok.Value diff --git a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/BaseDaoTest.java b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/DaoTestUtil.java similarity index 98% rename from hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/BaseDaoTest.java rename to hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/DaoTestUtil.java index 0e3562bf..cb626826 100644 --- a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/BaseDaoTest.java +++ b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/DaoTestUtil.java @@ -29,7 +29,7 @@ import org.hypertrace.gateway.service.v1.span.SpanEvent; import org.hypertrace.gateway.service.v1.span.SpansResponse; -class BaseDaoTest { +class DaoTestUtil { @Value @Accessors(fluent = true) @@ -96,7 +96,7 @@ static class DefaultResultSetRequest implements ResultSetRequest { @Value @Accessors(fluent = true) - class DefaultTimeRange implements TimeRangeArgument { + static class DefaultTimeRange implements TimeRangeArgument { @JsonProperty(TIME_RANGE_ARGUMENT_START_TIME) Instant startTime; 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 26488978..3e1db88a 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 @@ -1,5 +1,9 @@ package org.hypertrace.core.graphql.span.dao; +import static org.hypertrace.core.graphql.span.dao.DaoTestUtil.attributesAttribute; +import static org.hypertrace.core.graphql.span.dao.DaoTestUtil.spanIdAttribute; +import static org.hypertrace.core.graphql.span.dao.DaoTestUtil.spansResponse; +import static org.hypertrace.core.graphql.span.dao.DaoTestUtil.traceIdAttribute; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyCollection; @@ -27,6 +31,10 @@ import org.hypertrace.core.graphql.common.request.ResultSetRequest; import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; import org.hypertrace.core.graphql.common.utils.Converter; +import org.hypertrace.core.graphql.span.dao.DaoTestUtil.DefaultResultSetRequest; +import org.hypertrace.core.graphql.span.dao.DaoTestUtil.DefaultSpanRequest; +import org.hypertrace.core.graphql.span.dao.DaoTestUtil.DefaultTimeRange; +import org.hypertrace.core.graphql.span.dao.DaoTestUtil.NormalizedFilter; import org.hypertrace.core.graphql.span.request.SpanRequest; import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig; import org.hypertrace.core.graphql.utils.gateway.GatewayUtilsModule; @@ -42,7 +50,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -class SpanLogEventRequestBuilderTest extends BaseDaoTest { +class SpanLogEventRequestBuilderTest { @Mock private FilterRequestBuilder filterRequestBuilder; @@ -103,9 +111,9 @@ void testBuildRequest() { ResultSetRequest resultSetRequest = new DefaultResultSetRequest( null, - List.of(eventIdAttribute), + List.of(DaoTestUtil.eventIdAttribute), new DefaultTimeRange(Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime)), - eventIdAttribute, + DaoTestUtil.eventIdAttribute, 0, 0, List.of(), diff --git a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverterTest.java b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverterTest.java index 2019b435..c980e441 100644 --- a/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverterTest.java +++ b/hypertrace-core-graphql-span-schema/src/test/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverterTest.java @@ -1,5 +1,10 @@ package org.hypertrace.core.graphql.span.dao; +import static org.hypertrace.core.graphql.span.dao.DaoTestUtil.attributesAttribute; +import static org.hypertrace.core.graphql.span.dao.DaoTestUtil.logEventsResponse; +import static org.hypertrace.core.graphql.span.dao.DaoTestUtil.spanIdAttribute; +import static org.hypertrace.core.graphql.span.dao.DaoTestUtil.spansResponse; +import static org.hypertrace.core.graphql.span.dao.DaoTestUtil.traceIdAttribute; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyCollection; @@ -27,7 +32,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -class SpanLogEventResponseConverterTest extends BaseDaoTest { +class SpanLogEventResponseConverterTest { @Mock BiConverter, Map, Map>