diff --git a/hypertrace-graphql-impl/build.gradle.kts b/hypertrace-graphql-impl/build.gradle.kts index d2f0db11..90c3d9fb 100644 --- a/hypertrace-graphql-impl/build.gradle.kts +++ b/hypertrace-graphql-impl/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { implementation(project(":hypertrace-graphql-explorer-context")) implementation(project(":hypertrace-graphql-entity-type")) implementation(project(":hypertrace-graphql-spaces-schema")) + implementation(project(":hypertrace-graphql-labels-schema")) implementation("org.slf4j:slf4j-api") implementation("com.google.inject:guice") diff --git a/hypertrace-graphql-impl/src/main/java/org/hypertrace/graphql/impl/GraphQlModule.java b/hypertrace-graphql-impl/src/main/java/org/hypertrace/graphql/impl/GraphQlModule.java index c68f36db..72e21f4a 100644 --- a/hypertrace-graphql-impl/src/main/java/org/hypertrace/graphql/impl/GraphQlModule.java +++ b/hypertrace-graphql-impl/src/main/java/org/hypertrace/graphql/impl/GraphQlModule.java @@ -26,6 +26,7 @@ import org.hypertrace.graphql.entity.HypertraceEntityModule; import org.hypertrace.graphql.explorer.ExplorerSchemaModule; import org.hypertrace.graphql.explorer.context.HypertraceExplorerContextModule; +import org.hypertrace.graphql.label.LabelSchemaModule; import org.hypertrace.graphql.metric.MetricModule; import org.hypertrace.graphql.spaces.SpacesSchemaModule; import org.hypertrace.graphql.utils.metrics.gateway.GatewayMetricUtilsModule; @@ -71,5 +72,6 @@ protected void configure() { install(new EntityIdModule()); install(new SpacesSchemaModule()); install(new RequestTransformationModule()); + install(new LabelSchemaModule()); } } diff --git a/hypertrace-graphql-labels-schema/build.gradle.kts b/hypertrace-graphql-labels-schema/build.gradle.kts new file mode 100644 index 00000000..9775a5bd --- /dev/null +++ b/hypertrace-graphql-labels-schema/build.gradle.kts @@ -0,0 +1,33 @@ +plugins { + `java-library` + jacoco + id("org.hypertrace.jacoco-report-plugin") +} + +dependencies { + api("com.google.inject:guice") + api("com.graphql-java:graphql-java") + api("org.hypertrace.core.graphql:hypertrace-core-graphql-spi") + api("io.github.graphql-java:graphql-java-annotations") + api("org.hypertrace.core.graphql:hypertrace-core-graphql-common-schema") + + annotationProcessor("org.projectlombok:lombok") + compileOnly("org.projectlombok:lombok") + + implementation("org.slf4j:slf4j-api") + implementation("io.reactivex.rxjava3:rxjava") + implementation("org.hypertrace.config.service:labels-config-service-api") + implementation("com.google.protobuf:protobuf-java-util") + implementation("com.google.guava:guava") + + implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-context") + implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-grpc-utils") + implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-schema-utils") + implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-rx-utils") + + implementation(project(":hypertrace-graphql-service-config")) +} + +tasks.test { + useJUnitPlatform() +} diff --git a/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/LabelSchemaFragment.java b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/LabelSchemaFragment.java new file mode 100644 index 00000000..308341e8 --- /dev/null +++ b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/LabelSchemaFragment.java @@ -0,0 +1,17 @@ +package org.hypertrace.graphql.label; + +import org.hypertrace.core.graphql.spi.schema.GraphQlSchemaFragment; +import org.hypertrace.graphql.label.schema.LabelSchema; + +class LabelSchemaFragment implements GraphQlSchemaFragment { + + @Override + public String fragmentName() { + return "Label schema"; + } + + @Override + public Class annotatedQueryClass() { + return LabelSchema.class; + } +} diff --git a/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/LabelSchemaModule.java b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/LabelSchemaModule.java new file mode 100644 index 00000000..ae19ea9c --- /dev/null +++ b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/LabelSchemaModule.java @@ -0,0 +1,17 @@ +package org.hypertrace.graphql.label; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import org.hypertrace.core.graphql.spi.schema.GraphQlSchemaFragment; +import org.hypertrace.graphql.label.dao.LabelDaoModule; + +public class LabelSchemaModule extends AbstractModule { + @Override + protected void configure() { + Multibinder.newSetBinder(binder(), GraphQlSchemaFragment.class) + .addBinding() + .to(LabelSchemaFragment.class); + + install(new LabelDaoModule()); + } +} diff --git a/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelConfigServiceDao.java b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelConfigServiceDao.java new file mode 100644 index 00000000..ff253627 --- /dev/null +++ b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelConfigServiceDao.java @@ -0,0 +1,60 @@ +package org.hypertrace.graphql.label.dao; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import io.grpc.CallCredentials; +import io.reactivex.rxjava3.core.Single; +import javax.inject.Inject; +import org.hypertrace.core.graphql.common.request.ContextualRequest; +import org.hypertrace.core.graphql.context.GraphQlRequestContext; +import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry; +import org.hypertrace.core.graphql.utils.grpc.GrpcContextBuilder; +import org.hypertrace.graphql.config.HypertraceGraphQlServiceConfig; +import org.hypertrace.graphql.label.schema.LabelResultSet; +import org.hypertrace.label.config.service.v1.GetLabelsRequest; +import org.hypertrace.label.config.service.v1.GetLabelsResponse; +import org.hypertrace.label.config.service.v1.LabelsConfigServiceGrpc; +import org.hypertrace.label.config.service.v1.LabelsConfigServiceGrpc.LabelsConfigServiceFutureStub; + +class LabelConfigServiceDao implements LabelDao { + private final LabelsConfigServiceFutureStub labelConfigServiceStub; + private final GrpcContextBuilder grpcContextBuilder; + private final HypertraceGraphQlServiceConfig serviceConfig; + private final LabelResponseConverter converter; + + @Inject + LabelConfigServiceDao( + HypertraceGraphQlServiceConfig serviceConfig, + CallCredentials credentials, + GrpcContextBuilder grpcContextBuilder, + GrpcChannelRegistry grpcChannelRegistry, + LabelResponseConverter converter) { + this.grpcContextBuilder = grpcContextBuilder; + this.serviceConfig = serviceConfig; + this.converter = converter; + this.labelConfigServiceStub = + LabelsConfigServiceGrpc.newFutureStub( + grpcChannelRegistry.forAddress( + serviceConfig.getConfigServiceHost(), serviceConfig.getConfigServicePort())) + .withCallCredentials(credentials); + } + + @Override + public Single getLabels(ContextualRequest request) { + return this.makeRequest(request.context(), GetLabelsRequest.getDefaultInstance()) + .flatMap(serverResponse -> converter.convert(serverResponse)); + } + + private Single makeRequest( + GraphQlRequestContext context, GetLabelsRequest request) { + return Single.fromFuture( + this.grpcContextBuilder + .build(context) + .call( + () -> + this.labelConfigServiceStub + .withDeadlineAfter( + serviceConfig.getConfigServiceTimeout().toMillis(), MILLISECONDS) + .getLabels(request))); + } +} diff --git a/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelDao.java b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelDao.java new file mode 100644 index 00000000..1312efbd --- /dev/null +++ b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelDao.java @@ -0,0 +1,10 @@ +package org.hypertrace.graphql.label.dao; + +import io.reactivex.rxjava3.core.Single; +import org.hypertrace.core.graphql.common.request.ContextualRequest; +import org.hypertrace.graphql.label.schema.LabelResultSet; + +public interface LabelDao { + + Single getLabels(ContextualRequest request); +} diff --git a/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelDaoModule.java b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelDaoModule.java new file mode 100644 index 00000000..ccfd7590 --- /dev/null +++ b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelDaoModule.java @@ -0,0 +1,19 @@ +package org.hypertrace.graphql.label.dao; + +import com.google.inject.AbstractModule; +import io.grpc.CallCredentials; +import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig; +import org.hypertrace.core.graphql.utils.grpc.GrpcChannelRegistry; +import org.hypertrace.core.graphql.utils.grpc.GrpcContextBuilder; + +public class LabelDaoModule extends AbstractModule { + + @Override + protected void configure() { + bind(LabelDao.class).to(LabelConfigServiceDao.class); + requireBinding(CallCredentials.class); + requireBinding(GraphQlServiceConfig.class); + requireBinding(GrpcChannelRegistry.class); + requireBinding(GrpcContextBuilder.class); + } +} diff --git a/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelResponseConverter.java b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelResponseConverter.java new file mode 100644 index 00000000..7b621a26 --- /dev/null +++ b/hypertrace-graphql-labels-schema/src/main/java/org/hypertrace/graphql/label/dao/LabelResponseConverter.java @@ -0,0 +1,36 @@ +package org.hypertrace.graphql.label.dao; + +import io.reactivex.rxjava3.core.Single; +import java.util.List; +import java.util.stream.Collectors; +import lombok.Value; +import lombok.experimental.Accessors; +import org.hypertrace.graphql.label.schema.Label; +import org.hypertrace.graphql.label.schema.LabelResultSet; +import org.hypertrace.label.config.service.v1.GetLabelsResponse; + +class LabelResponseConverter { + + Single convert(GetLabelsResponse response) { + List