Skip to content

Commit

Permalink
add span processing schema (#130)
Browse files Browse the repository at this point in the history
* add span processing schema

* address review comments
  • Loading branch information
SrikarMannepalli authored Feb 18, 2022
1 parent 3a45bcf commit 817ab0b
Show file tree
Hide file tree
Showing 45 changed files with 1,466 additions and 0 deletions.
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

0 comments on commit 817ab0b

Please sign in to comment.