Skip to content

add span processing schema #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hypertrace-graphql-platform/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ dependencies {
api("org.hypertrace.config.service:spaces-config-service-api:0.1.1")
api("org.hypertrace.config.service:labels-config-service-api:0.1.15")
api("org.hypertrace.config.service:label-application-rule-config-service-api:0.1.16")
api("org.hypertrace.config.service:span-processing-config-service-api:0.1.23")
}
}
24 changes: 24 additions & 0 deletions hypertrace-graphql-span-processing-schema/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
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-common-schema")
api("org.hypertrace.core.graphql:hypertrace-core-graphql-spi")
api("io.github.graphql-java:graphql-java-annotations")

annotationProcessor("org.projectlombok:lombok")
compileOnly("org.projectlombok:lombok")

implementation(project(":hypertrace-graphql-service-config"))
implementation("org.hypertrace.config.service:span-processing-config-service-api")
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-deserialization")
implementation("org.slf4j:slf4j-api")
implementation("io.reactivex.rxjava3:rxjava")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import javax.annotation.Nullable;
import org.hypertrace.core.graphql.spi.schema.GraphQlSchemaFragment;
import org.hypertrace.graphql.spanprocessing.schema.mutation.SpanProcessingMutationSchema;
import org.hypertrace.graphql.spanprocessing.schema.query.SpanProcessingQuerySchema;

public class SpanProcessingSchemaFragment implements GraphQlSchemaFragment {

@Override
public String fragmentName() {
return "Span Processing schema";
}

@Override
public Class<SpanProcessingQuerySchema> annotatedQueryClass() {
return SpanProcessingQuerySchema.class;
}

@Nullable
@Override
public Class<?> annotatedMutationClass() {
return SpanProcessingMutationSchema.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
import org.hypertrace.core.graphql.spi.schema.GraphQlSchemaFragment;
import org.hypertrace.graphql.spanprocessing.dao.SpanProcessingDaoModule;
import org.hypertrace.graphql.spanprocessing.deserialization.SpanProcessingDeserializationModule;
import org.hypertrace.graphql.spanprocessing.request.mutation.SpanProcessingMutationRequestModule;

public class SpanProcessingSchemaModule extends AbstractModule {
@Override
protected void configure() {
Multibinder.newSetBinder(binder(), GraphQlSchemaFragment.class)
.addBinding()
.to(SpanProcessingSchemaFragment.class);

install(new SpanProcessingMutationRequestModule());
install(new SpanProcessingDaoModule());
install(new SpanProcessingDeserializationModule());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
package org.hypertrace.graphql.spanprocessing.dao;

import com.google.common.collect.ImmutableBiMap;
import io.reactivex.rxjava3.core.Single;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.Value;
import lombok.experimental.Accessors;
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingFilterField;
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingLogicalFilter;
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingLogicalOperator;
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingRelationalFilter;
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingRelationalOperator;
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingRuleFilter;
import org.hypertrace.span.processing.config.service.v1.Field;
import org.hypertrace.span.processing.config.service.v1.LogicalOperator;
import org.hypertrace.span.processing.config.service.v1.LogicalSpanFilterExpression;
import org.hypertrace.span.processing.config.service.v1.RelationalOperator;
import org.hypertrace.span.processing.config.service.v1.RelationalSpanFilterExpression;
import org.hypertrace.span.processing.config.service.v1.SpanFilter;
import org.hypertrace.span.processing.config.service.v1.SpanFilterValue;

public class ConfigServiceSpanFilterConverter {

private static final ImmutableBiMap<LogicalOperator, SpanProcessingLogicalOperator>
LOGICAL_OPERATOR_OPERATOR_BI_MAP =
ImmutableBiMap.of(
LogicalOperator.LOGICAL_OPERATOR_AND,
SpanProcessingLogicalOperator.AND,
LogicalOperator.LOGICAL_OPERATOR_OR,
SpanProcessingLogicalOperator.OR);

private static final ImmutableBiMap<SpanProcessingLogicalOperator, LogicalOperator>
OPERATOR_LOGICAL_OPERATOR_IMMUTABLE_BI_MAP = LOGICAL_OPERATOR_OPERATOR_BI_MAP.inverse();

private static final ImmutableBiMap<RelationalOperator, SpanProcessingRelationalOperator>
RELATIONAL_OPERATOR_OPERATOR_BI_MAP =
ImmutableBiMap.<RelationalOperator, SpanProcessingRelationalOperator>builder()
.put(
RelationalOperator.RELATIONAL_OPERATOR_CONTAINS,
SpanProcessingRelationalOperator.CONTAINS)
.put(
RelationalOperator.RELATIONAL_OPERATOR_EQUALS,
SpanProcessingRelationalOperator.EQUALS)
.put(
RelationalOperator.RELATIONAL_OPERATOR_NOT_EQUALS,
SpanProcessingRelationalOperator.NOT_EQUALS)
.put(
RelationalOperator.RELATIONAL_OPERATOR_STARTS_WITH,
SpanProcessingRelationalOperator.STARTS_WITH)
.put(
RelationalOperator.RELATIONAL_OPERATOR_ENDS_WITH,
SpanProcessingRelationalOperator.ENDS_WITH)
.put(
RelationalOperator.RELATIONAL_OPERATOR_REGEX_MATCH,
SpanProcessingRelationalOperator.REGEX_MATCH)
.build();

private static final ImmutableBiMap<SpanProcessingRelationalOperator, RelationalOperator>
OPERATOR_RELATIONAL_OPERATOR_IMMUTABLE_BI_MAP = RELATIONAL_OPERATOR_OPERATOR_BI_MAP.inverse();

private static final ImmutableBiMap<Field, SpanProcessingFilterField>
FIELD_FILTER_FIELD_IMMUTABLE_BI_MAP =
ImmutableBiMap.<Field, SpanProcessingFilterField>builder()
.put(Field.FIELD_URL, SpanProcessingFilterField.URL)
.put(Field.FIELD_SERVICE_NAME, SpanProcessingFilterField.SERVICE_NAME)
.put(Field.FIELD_ENVIRONMENT_NAME, SpanProcessingFilterField.ENVIRONMENT_NAME)
.build();

private static final ImmutableBiMap<SpanProcessingFilterField, Field>
FILTER_FIELD_FIELD_IMMUTABLE_BI_MAP = FIELD_FILTER_FIELD_IMMUTABLE_BI_MAP.inverse();

public Single<SpanProcessingRuleFilter> convert(SpanFilter filter) {
return Single.just(Objects.requireNonNull(convertFilter(filter)));
}

public SpanFilter convert(SpanProcessingRuleFilter filter) {
if (filter == null) {
return null;
}
SpanFilter.Builder spanFilterBuilder = SpanFilter.newBuilder();
if (filter.logicalSpanFilter() != null) {
spanFilterBuilder =
spanFilterBuilder.setLogicalSpanFilter(convertLogicalFilter(filter.logicalSpanFilter()));
} else if (filter.relationalSpanFilter() != null) {
spanFilterBuilder =
spanFilterBuilder.setRelationalSpanFilter(
convertRelationalFilter(filter.relationalSpanFilter()));
}
return spanFilterBuilder.build();
}

private SpanProcessingRuleFilter convertFilter(SpanFilter filter) {
if (filter.equals(SpanFilter.getDefaultInstance())) {
return null;
}
return new ConvertedSpanProcessingRuleFilter(
this.convertLogicalFilter(filter.getLogicalSpanFilter()),
this.convertRelationalFilter(filter.getRelationalSpanFilter()));
}

private SpanProcessingLogicalFilter convertLogicalFilter(
LogicalSpanFilterExpression logicalSpanFilterExpression) {
if (logicalSpanFilterExpression.equals(LogicalSpanFilterExpression.getDefaultInstance())) {
return null;
}
return new ConvertedSpanProcessingLogicalFilter(
LOGICAL_OPERATOR_OPERATOR_BI_MAP.get(logicalSpanFilterExpression.getOperator()),
logicalSpanFilterExpression.getOperandsList().stream()
.map(this::convertFilter)
.collect(Collectors.toUnmodifiableList()));
}

private LogicalSpanFilterExpression convertLogicalFilter(
SpanProcessingLogicalFilter spanProcessingLogicalFilter) {
return LogicalSpanFilterExpression.newBuilder()
.setOperator(
Objects.requireNonNull(
OPERATOR_LOGICAL_OPERATOR_IMMUTABLE_BI_MAP.get(
spanProcessingLogicalFilter.logicalOperator())))
.addAllOperands(
spanProcessingLogicalFilter.spanFilters().stream()
.map(this::convert)
.collect(Collectors.toUnmodifiableList()))
.build();
}

private SpanProcessingRelationalFilter convertRelationalFilter(
RelationalSpanFilterExpression relationalSpanFilterExpression) {
if (relationalSpanFilterExpression.equals(
RelationalSpanFilterExpression.getDefaultInstance())) {
return null;
}
return new ConvertedSpanProcessingRelationalFilter(
RELATIONAL_OPERATOR_OPERATOR_BI_MAP.get(relationalSpanFilterExpression.getOperator()),
relationalSpanFilterExpression.hasSpanAttributeKey()
? relationalSpanFilterExpression.getSpanAttributeKey()
: null,
relationalSpanFilterExpression.hasField()
? FIELD_FILTER_FIELD_IMMUTABLE_BI_MAP.get(relationalSpanFilterExpression.getField())
: null,
convertSpanFilterValue(relationalSpanFilterExpression.getRightOperand()));
}

private Object convertSpanFilterValue(SpanFilterValue spanFilterValue) {
switch (spanFilterValue.getValueCase()) {
case STRING_VALUE:
return spanFilterValue.getStringValue();
default:
throw new NoSuchElementException("Unsupported right operand type");
}
}

private RelationalSpanFilterExpression convertRelationalFilter(
SpanProcessingRelationalFilter spanProcessingRelationalFilter) {
RelationalSpanFilterExpression.Builder relationalSpanFilterExpressionBuilder =
RelationalSpanFilterExpression.newBuilder()
.setOperator(
Objects.requireNonNull(
OPERATOR_RELATIONAL_OPERATOR_IMMUTABLE_BI_MAP.get(
spanProcessingRelationalFilter.relationalOperator())))
.setRightOperand(convertToSpanFilterValue(spanProcessingRelationalFilter.value()));

if (spanProcessingRelationalFilter.key() != null) {
relationalSpanFilterExpressionBuilder =
relationalSpanFilterExpressionBuilder.setSpanAttributeKey(
spanProcessingRelationalFilter.key());
} else {
relationalSpanFilterExpressionBuilder =
relationalSpanFilterExpressionBuilder.setField(
Objects.requireNonNull(
FILTER_FIELD_FIELD_IMMUTABLE_BI_MAP.get(spanProcessingRelationalFilter.field())));
}
return relationalSpanFilterExpressionBuilder.build();
}

private SpanFilterValue convertToSpanFilterValue(Object value) {
SpanFilterValue.Builder spanFilterValueBuilder = SpanFilterValue.newBuilder();
if (String.class.equals(value.getClass())) {
spanFilterValueBuilder = spanFilterValueBuilder.setStringValue(value.toString());
}
return spanFilterValueBuilder.build();
}

@Value
@Accessors(fluent = true)
private static class ConvertedSpanProcessingRelationalFilter
implements SpanProcessingRelationalFilter {
SpanProcessingRelationalOperator relationalOperator;
String key;
SpanProcessingFilterField field;
Object value;
}

@Value
@Accessors(fluent = true)
private static class ConvertedSpanProcessingLogicalFilter implements SpanProcessingLogicalFilter {
SpanProcessingLogicalOperator logicalOperator;
List<SpanProcessingRuleFilter> spanFilters;
}

@Value
@Accessors(fluent = true)
private static class ConvertedSpanProcessingRuleFilter implements SpanProcessingRuleFilter {
SpanProcessingLogicalFilter logicalSpanFilter;
SpanProcessingRelationalFilter relationalSpanFilter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.hypertrace.graphql.spanprocessing.dao;

import javax.inject.Inject;
import org.hypertrace.graphql.spanprocessing.request.mutation.ExcludeSpanCreateRuleRequest;
import org.hypertrace.graphql.spanprocessing.request.mutation.ExcludeSpanDeleteRuleRequest;
import org.hypertrace.graphql.spanprocessing.request.mutation.ExcludeSpanUpdateRuleRequest;
import org.hypertrace.graphql.spanprocessing.schema.mutation.ExcludeSpanRuleCreate;
import org.hypertrace.graphql.spanprocessing.schema.mutation.ExcludeSpanRuleUpdate;
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingRuleFilter;
import org.hypertrace.span.processing.config.service.v1.CreateExcludeSpanRuleRequest;
import org.hypertrace.span.processing.config.service.v1.DeleteExcludeSpanRuleRequest;
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRuleInfo;
import org.hypertrace.span.processing.config.service.v1.UpdateExcludeSpanRule;
import org.hypertrace.span.processing.config.service.v1.UpdateExcludeSpanRuleRequest;

public class ConfigServiceSpanProcessingRequestConverter {

private final ConfigServiceSpanFilterConverter filterConverter;

@Inject
ConfigServiceSpanProcessingRequestConverter(ConfigServiceSpanFilterConverter filterConverter) {
this.filterConverter = filterConverter;
}

CreateExcludeSpanRuleRequest convert(ExcludeSpanCreateRuleRequest request) {
return CreateExcludeSpanRuleRequest.newBuilder()
.setRuleInfo(convertInput(request.createInput()))
.build();
}

private ExcludeSpanRuleInfo convertInput(ExcludeSpanRuleCreate excludeSpanRuleCreate) {
return ExcludeSpanRuleInfo.newBuilder()
.setName(excludeSpanRuleCreate.name())
.setFilter(this.filterConverter.convert(excludeSpanRuleCreate.spanFilter()))
.build();
}

UpdateExcludeSpanRuleRequest convert(ExcludeSpanUpdateRuleRequest request) {
return UpdateExcludeSpanRuleRequest.newBuilder()
.setRule(convertInput(request.updateInput()))
.build();
}

private UpdateExcludeSpanRule convertInput(ExcludeSpanRuleUpdate excludeSpanRuleUpdate) {
UpdateExcludeSpanRule.Builder updateExcludeSpanRuleBuilder =
UpdateExcludeSpanRule.newBuilder().setId(excludeSpanRuleUpdate.id());
String name = excludeSpanRuleUpdate.name();
SpanProcessingRuleFilter filter = excludeSpanRuleUpdate.spanFilter();
if (name != null) {
updateExcludeSpanRuleBuilder =
updateExcludeSpanRuleBuilder.setName(excludeSpanRuleUpdate.name());
}
if (filter != null) {
updateExcludeSpanRuleBuilder =
updateExcludeSpanRuleBuilder.setFilter(
this.filterConverter.convert(excludeSpanRuleUpdate.spanFilter()));
}
return updateExcludeSpanRuleBuilder.build();
}

DeleteExcludeSpanRuleRequest convert(ExcludeSpanDeleteRuleRequest request) {
return DeleteExcludeSpanRuleRequest.newBuilder().setId(request.id()).build();
}
}
Loading