Skip to content

Commit fd15f6e

Browse files
authored
chore | add support for multi filter arguments (#151)
1 parent a4d5d5d commit fd15f6e

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ protected void configure() {
5858
new TypeLiteral<
5959
Converter<Collection<AttributeAssociation<FilterArgument>>, Filter>>() {}))
6060
.to(FilterConverter.class);
61+
bind(Key.get(
62+
new TypeLiteral<
63+
Converter<
64+
Collection<Collection<AttributeAssociation<FilterArgument>>>, Filter>>() {}))
65+
.to(MultiFilterConverter.class);
6166

6267
bind(Key.get(new TypeLiteral<Converter<AttributeModel, ColumnIdentifier>>() {}))
6368
.to(ColumnIdentifierConverter.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.hypertrace.core.graphql.utils.gateway;
2+
3+
import static io.reactivex.rxjava3.core.Single.zip;
4+
5+
import io.reactivex.rxjava3.core.Observable;
6+
import io.reactivex.rxjava3.core.Single;
7+
import java.util.Collection;
8+
import java.util.stream.Collectors;
9+
import javax.inject.Inject;
10+
import org.hypertrace.core.graphql.common.request.AttributeAssociation;
11+
import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument;
12+
import org.hypertrace.core.graphql.common.utils.Converter;
13+
import org.hypertrace.gateway.service.v1.common.Filter;
14+
import org.hypertrace.gateway.service.v1.common.Operator;
15+
16+
public class MultiFilterConverter
17+
implements Converter<Collection<Collection<AttributeAssociation<FilterArgument>>>, Filter> {
18+
19+
private final AttributeExpressionConverter attributeExpressionConverter;
20+
private final OperatorConverter operatorConverter;
21+
private final LiteralConstantExpressionConverter literalConstantExpressionConverter;
22+
23+
@Inject
24+
MultiFilterConverter(
25+
AttributeExpressionConverter attributeExpressionConverter,
26+
OperatorConverter operatorConverter,
27+
LiteralConstantExpressionConverter literalConstantExpressionConverter) {
28+
this.attributeExpressionConverter = attributeExpressionConverter;
29+
this.operatorConverter = operatorConverter;
30+
this.literalConstantExpressionConverter = literalConstantExpressionConverter;
31+
}
32+
33+
@Override
34+
public Single<Filter> convert(
35+
Collection<Collection<AttributeAssociation<FilterArgument>>> filters) {
36+
if (filters.isEmpty()) {
37+
return Single.just(Filter.getDefaultInstance());
38+
}
39+
40+
return Observable.fromIterable(filters)
41+
.flatMapSingle(this::buildAndFilterOperations)
42+
.collect(Collectors.toUnmodifiableList())
43+
.map(
44+
filterList ->
45+
Filter.newBuilder().setOperator(Operator.OR).addAllChildFilter(filterList).build());
46+
}
47+
48+
private Single<Filter> buildAndFilterOperations(
49+
Collection<AttributeAssociation<FilterArgument>> andFilters) {
50+
return Observable.fromIterable(andFilters)
51+
.flatMapSingle(this::buildFilter)
52+
.collect(Collectors.toUnmodifiableList())
53+
.map(
54+
filterList ->
55+
Filter.newBuilder()
56+
.setOperator(Operator.AND)
57+
.addAllChildFilter(filterList)
58+
.build());
59+
}
60+
61+
private Single<Filter> buildFilter(AttributeAssociation<FilterArgument> filter) {
62+
return zip(
63+
this.attributeExpressionConverter.convert(
64+
AttributeAssociation.of(filter.attribute(), filter.value().keyExpression())),
65+
this.operatorConverter.convert(filter.value().operator()),
66+
this.literalConstantExpressionConverter.convert(filter.value().value()),
67+
(key, operator, value) ->
68+
Filter.newBuilder().setLhs(key).setOperator(operator).setRhs(value).build());
69+
}
70+
}

0 commit comments

Comments
 (0)