From fd15f6eb33f8f49a861f7d59d2a76e8c86514241 Mon Sep 17 00:00:00 2001 From: aman bansal Date: Mon, 27 Nov 2023 12:56:13 +0530 Subject: [PATCH] chore | add support for multi filter arguments (#151) --- .../utils/gateway/GatewayUtilsModule.java | 5 ++ .../utils/gateway/MultiFilterConverter.java | 70 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/MultiFilterConverter.java diff --git a/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java b/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java index 78fa0750..d02a81e8 100644 --- a/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java +++ b/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/GatewayUtilsModule.java @@ -58,6 +58,11 @@ protected void configure() { new TypeLiteral< Converter>, Filter>>() {})) .to(FilterConverter.class); + bind(Key.get( + new TypeLiteral< + Converter< + Collection>>, Filter>>() {})) + .to(MultiFilterConverter.class); bind(Key.get(new TypeLiteral>() {})) .to(ColumnIdentifierConverter.class); diff --git a/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/MultiFilterConverter.java b/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/MultiFilterConverter.java new file mode 100644 index 00000000..da8e78a4 --- /dev/null +++ b/hypertrace-core-graphql-gateway-service-utils/src/main/java/org/hypertrace/core/graphql/utils/gateway/MultiFilterConverter.java @@ -0,0 +1,70 @@ +package org.hypertrace.core.graphql.utils.gateway; + +import static io.reactivex.rxjava3.core.Single.zip; + +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Single; +import java.util.Collection; +import java.util.stream.Collectors; +import javax.inject.Inject; +import org.hypertrace.core.graphql.common.request.AttributeAssociation; +import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument; +import org.hypertrace.core.graphql.common.utils.Converter; +import org.hypertrace.gateway.service.v1.common.Filter; +import org.hypertrace.gateway.service.v1.common.Operator; + +public class MultiFilterConverter + implements Converter>>, Filter> { + + private final AttributeExpressionConverter attributeExpressionConverter; + private final OperatorConverter operatorConverter; + private final LiteralConstantExpressionConverter literalConstantExpressionConverter; + + @Inject + MultiFilterConverter( + AttributeExpressionConverter attributeExpressionConverter, + OperatorConverter operatorConverter, + LiteralConstantExpressionConverter literalConstantExpressionConverter) { + this.attributeExpressionConverter = attributeExpressionConverter; + this.operatorConverter = operatorConverter; + this.literalConstantExpressionConverter = literalConstantExpressionConverter; + } + + @Override + public Single convert( + Collection>> filters) { + if (filters.isEmpty()) { + return Single.just(Filter.getDefaultInstance()); + } + + return Observable.fromIterable(filters) + .flatMapSingle(this::buildAndFilterOperations) + .collect(Collectors.toUnmodifiableList()) + .map( + filterList -> + Filter.newBuilder().setOperator(Operator.OR).addAllChildFilter(filterList).build()); + } + + private Single buildAndFilterOperations( + Collection> andFilters) { + return Observable.fromIterable(andFilters) + .flatMapSingle(this::buildFilter) + .collect(Collectors.toUnmodifiableList()) + .map( + filterList -> + Filter.newBuilder() + .setOperator(Operator.AND) + .addAllChildFilter(filterList) + .build()); + } + + private Single buildFilter(AttributeAssociation filter) { + return zip( + this.attributeExpressionConverter.convert( + AttributeAssociation.of(filter.attribute(), filter.value().keyExpression())), + this.operatorConverter.convert(filter.value().operator()), + this.literalConstantExpressionConverter.convert(filter.value().value()), + (key, operator, value) -> + Filter.newBuilder().setLhs(key).setOperator(operator).setRhs(value).build()); + } +}