Skip to content

Commit 817ab0b

Browse files
add span processing schema (#130)
* add span processing schema * address review comments
1 parent 3a45bcf commit 817ab0b

File tree

45 files changed

+1466
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1466
-0
lines changed

hypertrace-graphql-platform/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ dependencies {
1313
api("org.hypertrace.config.service:spaces-config-service-api:0.1.1")
1414
api("org.hypertrace.config.service:labels-config-service-api:0.1.15")
1515
api("org.hypertrace.config.service:label-application-rule-config-service-api:0.1.16")
16+
api("org.hypertrace.config.service:span-processing-config-service-api:0.1.23")
1617
}
1718
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
plugins {
2+
`java-library`
3+
jacoco
4+
id("org.hypertrace.jacoco-report-plugin")
5+
}
6+
7+
dependencies {
8+
api("com.google.inject:guice")
9+
api("com.graphql-java:graphql-java")
10+
api("org.hypertrace.core.graphql:hypertrace-core-graphql-common-schema")
11+
api("org.hypertrace.core.graphql:hypertrace-core-graphql-spi")
12+
api("io.github.graphql-java:graphql-java-annotations")
13+
14+
annotationProcessor("org.projectlombok:lombok")
15+
compileOnly("org.projectlombok:lombok")
16+
17+
implementation(project(":hypertrace-graphql-service-config"))
18+
implementation("org.hypertrace.config.service:span-processing-config-service-api")
19+
implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-context")
20+
implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-grpc-utils")
21+
implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-deserialization")
22+
implementation("org.slf4j:slf4j-api")
23+
implementation("io.reactivex.rxjava3:rxjava")
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import javax.annotation.Nullable;
2+
import org.hypertrace.core.graphql.spi.schema.GraphQlSchemaFragment;
3+
import org.hypertrace.graphql.spanprocessing.schema.mutation.SpanProcessingMutationSchema;
4+
import org.hypertrace.graphql.spanprocessing.schema.query.SpanProcessingQuerySchema;
5+
6+
public class SpanProcessingSchemaFragment implements GraphQlSchemaFragment {
7+
8+
@Override
9+
public String fragmentName() {
10+
return "Span Processing schema";
11+
}
12+
13+
@Override
14+
public Class<SpanProcessingQuerySchema> annotatedQueryClass() {
15+
return SpanProcessingQuerySchema.class;
16+
}
17+
18+
@Nullable
19+
@Override
20+
public Class<?> annotatedMutationClass() {
21+
return SpanProcessingMutationSchema.class;
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import com.google.inject.AbstractModule;
2+
import com.google.inject.multibindings.Multibinder;
3+
import org.hypertrace.core.graphql.spi.schema.GraphQlSchemaFragment;
4+
import org.hypertrace.graphql.spanprocessing.dao.SpanProcessingDaoModule;
5+
import org.hypertrace.graphql.spanprocessing.deserialization.SpanProcessingDeserializationModule;
6+
import org.hypertrace.graphql.spanprocessing.request.mutation.SpanProcessingMutationRequestModule;
7+
8+
public class SpanProcessingSchemaModule extends AbstractModule {
9+
@Override
10+
protected void configure() {
11+
Multibinder.newSetBinder(binder(), GraphQlSchemaFragment.class)
12+
.addBinding()
13+
.to(SpanProcessingSchemaFragment.class);
14+
15+
install(new SpanProcessingMutationRequestModule());
16+
install(new SpanProcessingDaoModule());
17+
install(new SpanProcessingDeserializationModule());
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package org.hypertrace.graphql.spanprocessing.dao;
2+
3+
import com.google.common.collect.ImmutableBiMap;
4+
import io.reactivex.rxjava3.core.Single;
5+
import java.util.List;
6+
import java.util.NoSuchElementException;
7+
import java.util.Objects;
8+
import java.util.stream.Collectors;
9+
import lombok.Value;
10+
import lombok.experimental.Accessors;
11+
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingFilterField;
12+
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingLogicalFilter;
13+
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingLogicalOperator;
14+
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingRelationalFilter;
15+
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingRelationalOperator;
16+
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingRuleFilter;
17+
import org.hypertrace.span.processing.config.service.v1.Field;
18+
import org.hypertrace.span.processing.config.service.v1.LogicalOperator;
19+
import org.hypertrace.span.processing.config.service.v1.LogicalSpanFilterExpression;
20+
import org.hypertrace.span.processing.config.service.v1.RelationalOperator;
21+
import org.hypertrace.span.processing.config.service.v1.RelationalSpanFilterExpression;
22+
import org.hypertrace.span.processing.config.service.v1.SpanFilter;
23+
import org.hypertrace.span.processing.config.service.v1.SpanFilterValue;
24+
25+
public class ConfigServiceSpanFilterConverter {
26+
27+
private static final ImmutableBiMap<LogicalOperator, SpanProcessingLogicalOperator>
28+
LOGICAL_OPERATOR_OPERATOR_BI_MAP =
29+
ImmutableBiMap.of(
30+
LogicalOperator.LOGICAL_OPERATOR_AND,
31+
SpanProcessingLogicalOperator.AND,
32+
LogicalOperator.LOGICAL_OPERATOR_OR,
33+
SpanProcessingLogicalOperator.OR);
34+
35+
private static final ImmutableBiMap<SpanProcessingLogicalOperator, LogicalOperator>
36+
OPERATOR_LOGICAL_OPERATOR_IMMUTABLE_BI_MAP = LOGICAL_OPERATOR_OPERATOR_BI_MAP.inverse();
37+
38+
private static final ImmutableBiMap<RelationalOperator, SpanProcessingRelationalOperator>
39+
RELATIONAL_OPERATOR_OPERATOR_BI_MAP =
40+
ImmutableBiMap.<RelationalOperator, SpanProcessingRelationalOperator>builder()
41+
.put(
42+
RelationalOperator.RELATIONAL_OPERATOR_CONTAINS,
43+
SpanProcessingRelationalOperator.CONTAINS)
44+
.put(
45+
RelationalOperator.RELATIONAL_OPERATOR_EQUALS,
46+
SpanProcessingRelationalOperator.EQUALS)
47+
.put(
48+
RelationalOperator.RELATIONAL_OPERATOR_NOT_EQUALS,
49+
SpanProcessingRelationalOperator.NOT_EQUALS)
50+
.put(
51+
RelationalOperator.RELATIONAL_OPERATOR_STARTS_WITH,
52+
SpanProcessingRelationalOperator.STARTS_WITH)
53+
.put(
54+
RelationalOperator.RELATIONAL_OPERATOR_ENDS_WITH,
55+
SpanProcessingRelationalOperator.ENDS_WITH)
56+
.put(
57+
RelationalOperator.RELATIONAL_OPERATOR_REGEX_MATCH,
58+
SpanProcessingRelationalOperator.REGEX_MATCH)
59+
.build();
60+
61+
private static final ImmutableBiMap<SpanProcessingRelationalOperator, RelationalOperator>
62+
OPERATOR_RELATIONAL_OPERATOR_IMMUTABLE_BI_MAP = RELATIONAL_OPERATOR_OPERATOR_BI_MAP.inverse();
63+
64+
private static final ImmutableBiMap<Field, SpanProcessingFilterField>
65+
FIELD_FILTER_FIELD_IMMUTABLE_BI_MAP =
66+
ImmutableBiMap.<Field, SpanProcessingFilterField>builder()
67+
.put(Field.FIELD_URL, SpanProcessingFilterField.URL)
68+
.put(Field.FIELD_SERVICE_NAME, SpanProcessingFilterField.SERVICE_NAME)
69+
.put(Field.FIELD_ENVIRONMENT_NAME, SpanProcessingFilterField.ENVIRONMENT_NAME)
70+
.build();
71+
72+
private static final ImmutableBiMap<SpanProcessingFilterField, Field>
73+
FILTER_FIELD_FIELD_IMMUTABLE_BI_MAP = FIELD_FILTER_FIELD_IMMUTABLE_BI_MAP.inverse();
74+
75+
public Single<SpanProcessingRuleFilter> convert(SpanFilter filter) {
76+
return Single.just(Objects.requireNonNull(convertFilter(filter)));
77+
}
78+
79+
public SpanFilter convert(SpanProcessingRuleFilter filter) {
80+
if (filter == null) {
81+
return null;
82+
}
83+
SpanFilter.Builder spanFilterBuilder = SpanFilter.newBuilder();
84+
if (filter.logicalSpanFilter() != null) {
85+
spanFilterBuilder =
86+
spanFilterBuilder.setLogicalSpanFilter(convertLogicalFilter(filter.logicalSpanFilter()));
87+
} else if (filter.relationalSpanFilter() != null) {
88+
spanFilterBuilder =
89+
spanFilterBuilder.setRelationalSpanFilter(
90+
convertRelationalFilter(filter.relationalSpanFilter()));
91+
}
92+
return spanFilterBuilder.build();
93+
}
94+
95+
private SpanProcessingRuleFilter convertFilter(SpanFilter filter) {
96+
if (filter.equals(SpanFilter.getDefaultInstance())) {
97+
return null;
98+
}
99+
return new ConvertedSpanProcessingRuleFilter(
100+
this.convertLogicalFilter(filter.getLogicalSpanFilter()),
101+
this.convertRelationalFilter(filter.getRelationalSpanFilter()));
102+
}
103+
104+
private SpanProcessingLogicalFilter convertLogicalFilter(
105+
LogicalSpanFilterExpression logicalSpanFilterExpression) {
106+
if (logicalSpanFilterExpression.equals(LogicalSpanFilterExpression.getDefaultInstance())) {
107+
return null;
108+
}
109+
return new ConvertedSpanProcessingLogicalFilter(
110+
LOGICAL_OPERATOR_OPERATOR_BI_MAP.get(logicalSpanFilterExpression.getOperator()),
111+
logicalSpanFilterExpression.getOperandsList().stream()
112+
.map(this::convertFilter)
113+
.collect(Collectors.toUnmodifiableList()));
114+
}
115+
116+
private LogicalSpanFilterExpression convertLogicalFilter(
117+
SpanProcessingLogicalFilter spanProcessingLogicalFilter) {
118+
return LogicalSpanFilterExpression.newBuilder()
119+
.setOperator(
120+
Objects.requireNonNull(
121+
OPERATOR_LOGICAL_OPERATOR_IMMUTABLE_BI_MAP.get(
122+
spanProcessingLogicalFilter.logicalOperator())))
123+
.addAllOperands(
124+
spanProcessingLogicalFilter.spanFilters().stream()
125+
.map(this::convert)
126+
.collect(Collectors.toUnmodifiableList()))
127+
.build();
128+
}
129+
130+
private SpanProcessingRelationalFilter convertRelationalFilter(
131+
RelationalSpanFilterExpression relationalSpanFilterExpression) {
132+
if (relationalSpanFilterExpression.equals(
133+
RelationalSpanFilterExpression.getDefaultInstance())) {
134+
return null;
135+
}
136+
return new ConvertedSpanProcessingRelationalFilter(
137+
RELATIONAL_OPERATOR_OPERATOR_BI_MAP.get(relationalSpanFilterExpression.getOperator()),
138+
relationalSpanFilterExpression.hasSpanAttributeKey()
139+
? relationalSpanFilterExpression.getSpanAttributeKey()
140+
: null,
141+
relationalSpanFilterExpression.hasField()
142+
? FIELD_FILTER_FIELD_IMMUTABLE_BI_MAP.get(relationalSpanFilterExpression.getField())
143+
: null,
144+
convertSpanFilterValue(relationalSpanFilterExpression.getRightOperand()));
145+
}
146+
147+
private Object convertSpanFilterValue(SpanFilterValue spanFilterValue) {
148+
switch (spanFilterValue.getValueCase()) {
149+
case STRING_VALUE:
150+
return spanFilterValue.getStringValue();
151+
default:
152+
throw new NoSuchElementException("Unsupported right operand type");
153+
}
154+
}
155+
156+
private RelationalSpanFilterExpression convertRelationalFilter(
157+
SpanProcessingRelationalFilter spanProcessingRelationalFilter) {
158+
RelationalSpanFilterExpression.Builder relationalSpanFilterExpressionBuilder =
159+
RelationalSpanFilterExpression.newBuilder()
160+
.setOperator(
161+
Objects.requireNonNull(
162+
OPERATOR_RELATIONAL_OPERATOR_IMMUTABLE_BI_MAP.get(
163+
spanProcessingRelationalFilter.relationalOperator())))
164+
.setRightOperand(convertToSpanFilterValue(spanProcessingRelationalFilter.value()));
165+
166+
if (spanProcessingRelationalFilter.key() != null) {
167+
relationalSpanFilterExpressionBuilder =
168+
relationalSpanFilterExpressionBuilder.setSpanAttributeKey(
169+
spanProcessingRelationalFilter.key());
170+
} else {
171+
relationalSpanFilterExpressionBuilder =
172+
relationalSpanFilterExpressionBuilder.setField(
173+
Objects.requireNonNull(
174+
FILTER_FIELD_FIELD_IMMUTABLE_BI_MAP.get(spanProcessingRelationalFilter.field())));
175+
}
176+
return relationalSpanFilterExpressionBuilder.build();
177+
}
178+
179+
private SpanFilterValue convertToSpanFilterValue(Object value) {
180+
SpanFilterValue.Builder spanFilterValueBuilder = SpanFilterValue.newBuilder();
181+
if (String.class.equals(value.getClass())) {
182+
spanFilterValueBuilder = spanFilterValueBuilder.setStringValue(value.toString());
183+
}
184+
return spanFilterValueBuilder.build();
185+
}
186+
187+
@Value
188+
@Accessors(fluent = true)
189+
private static class ConvertedSpanProcessingRelationalFilter
190+
implements SpanProcessingRelationalFilter {
191+
SpanProcessingRelationalOperator relationalOperator;
192+
String key;
193+
SpanProcessingFilterField field;
194+
Object value;
195+
}
196+
197+
@Value
198+
@Accessors(fluent = true)
199+
private static class ConvertedSpanProcessingLogicalFilter implements SpanProcessingLogicalFilter {
200+
SpanProcessingLogicalOperator logicalOperator;
201+
List<SpanProcessingRuleFilter> spanFilters;
202+
}
203+
204+
@Value
205+
@Accessors(fluent = true)
206+
private static class ConvertedSpanProcessingRuleFilter implements SpanProcessingRuleFilter {
207+
SpanProcessingLogicalFilter logicalSpanFilter;
208+
SpanProcessingRelationalFilter relationalSpanFilter;
209+
}
210+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package org.hypertrace.graphql.spanprocessing.dao;
2+
3+
import javax.inject.Inject;
4+
import org.hypertrace.graphql.spanprocessing.request.mutation.ExcludeSpanCreateRuleRequest;
5+
import org.hypertrace.graphql.spanprocessing.request.mutation.ExcludeSpanDeleteRuleRequest;
6+
import org.hypertrace.graphql.spanprocessing.request.mutation.ExcludeSpanUpdateRuleRequest;
7+
import org.hypertrace.graphql.spanprocessing.schema.mutation.ExcludeSpanRuleCreate;
8+
import org.hypertrace.graphql.spanprocessing.schema.mutation.ExcludeSpanRuleUpdate;
9+
import org.hypertrace.graphql.spanprocessing.schema.rule.filter.SpanProcessingRuleFilter;
10+
import org.hypertrace.span.processing.config.service.v1.CreateExcludeSpanRuleRequest;
11+
import org.hypertrace.span.processing.config.service.v1.DeleteExcludeSpanRuleRequest;
12+
import org.hypertrace.span.processing.config.service.v1.ExcludeSpanRuleInfo;
13+
import org.hypertrace.span.processing.config.service.v1.UpdateExcludeSpanRule;
14+
import org.hypertrace.span.processing.config.service.v1.UpdateExcludeSpanRuleRequest;
15+
16+
public class ConfigServiceSpanProcessingRequestConverter {
17+
18+
private final ConfigServiceSpanFilterConverter filterConverter;
19+
20+
@Inject
21+
ConfigServiceSpanProcessingRequestConverter(ConfigServiceSpanFilterConverter filterConverter) {
22+
this.filterConverter = filterConverter;
23+
}
24+
25+
CreateExcludeSpanRuleRequest convert(ExcludeSpanCreateRuleRequest request) {
26+
return CreateExcludeSpanRuleRequest.newBuilder()
27+
.setRuleInfo(convertInput(request.createInput()))
28+
.build();
29+
}
30+
31+
private ExcludeSpanRuleInfo convertInput(ExcludeSpanRuleCreate excludeSpanRuleCreate) {
32+
return ExcludeSpanRuleInfo.newBuilder()
33+
.setName(excludeSpanRuleCreate.name())
34+
.setFilter(this.filterConverter.convert(excludeSpanRuleCreate.spanFilter()))
35+
.build();
36+
}
37+
38+
UpdateExcludeSpanRuleRequest convert(ExcludeSpanUpdateRuleRequest request) {
39+
return UpdateExcludeSpanRuleRequest.newBuilder()
40+
.setRule(convertInput(request.updateInput()))
41+
.build();
42+
}
43+
44+
private UpdateExcludeSpanRule convertInput(ExcludeSpanRuleUpdate excludeSpanRuleUpdate) {
45+
UpdateExcludeSpanRule.Builder updateExcludeSpanRuleBuilder =
46+
UpdateExcludeSpanRule.newBuilder().setId(excludeSpanRuleUpdate.id());
47+
String name = excludeSpanRuleUpdate.name();
48+
SpanProcessingRuleFilter filter = excludeSpanRuleUpdate.spanFilter();
49+
if (name != null) {
50+
updateExcludeSpanRuleBuilder =
51+
updateExcludeSpanRuleBuilder.setName(excludeSpanRuleUpdate.name());
52+
}
53+
if (filter != null) {
54+
updateExcludeSpanRuleBuilder =
55+
updateExcludeSpanRuleBuilder.setFilter(
56+
this.filterConverter.convert(excludeSpanRuleUpdate.spanFilter()));
57+
}
58+
return updateExcludeSpanRuleBuilder.build();
59+
}
60+
61+
DeleteExcludeSpanRuleRequest convert(ExcludeSpanDeleteRuleRequest request) {
62+
return DeleteExcludeSpanRuleRequest.newBuilder().setId(request.id()).build();
63+
}
64+
}

0 commit comments

Comments
 (0)