33import static io .reactivex .rxjava3 .core .Single .zip ;
44
55import graphql .schema .SelectedField ;
6+ import io .grpc .Status ;
67import io .reactivex .rxjava3 .core .Single ;
78import java .util .Collection ;
89import java .util .List ;
1617import javax .inject .Provider ;
1718import lombok .Value ;
1819import lombok .experimental .Accessors ;
20+ import org .hypertrace .core .graphql .common .request .AttributeAssociation ;
1921import org .hypertrace .core .graphql .common .request .AttributeRequest ;
2022import org .hypertrace .core .graphql .common .request .AttributeRequestBuilder ;
23+ import org .hypertrace .core .graphql .common .request .FilterRequestBuilder ;
2124import org .hypertrace .core .graphql .common .schema .arguments .TimeRangeArgument ;
2225import org .hypertrace .core .graphql .common .schema .attributes .arguments .AttributeExpression ;
2326import org .hypertrace .core .graphql .common .schema .results .ResultSet ;
27+ import org .hypertrace .core .graphql .common .schema .results .arguments .filter .FilterArgument ;
2428import org .hypertrace .core .graphql .context .GraphQlRequestContext ;
2529import org .hypertrace .core .graphql .deserialization .ArgumentDeserializer ;
2630import org .hypertrace .core .graphql .utils .schema .GraphQlSelectionFinder ;
3337import org .hypertrace .graphql .metric .request .MetricAggregationRequestBuilder ;
3438
3539class EdgeRequestBuilder {
40+
3641 private final String INCOMING_ENTITY_ID_KEY = "fromEntityId" ;
3742 private final String INCOMING_ENTITY_TYPE_KEY = "fromEntityType" ;
3843 private final String OUTGOING_ENTITY_ID_KEY = "toEntityId" ;
3944 private final String OUTGOING_ENTITY_TYPE_KEY = "toEntityType" ;
4045 private final ArgumentDeserializer argumentDeserializer ;
4146 private final GraphQlSelectionFinder selectionFinder ;
4247 private final MetricAggregationRequestBuilder metricAggregationRequestBuilder ;
48+ private final FilterRequestBuilder filterRequestBuilder ;
4349 private final AttributeRequestBuilder attributeRequestBuilder ;
4450 // Use provider to avoid cycle
4551 private final Provider <NeighborEntitiesRequestBuilder > neighborEntitiesRequestBuilderProvider ;
@@ -49,40 +55,49 @@ class EdgeRequestBuilder {
4955 ArgumentDeserializer argumentDeserializer ,
5056 GraphQlSelectionFinder selectionFinder ,
5157 MetricAggregationRequestBuilder metricAggregationRequestBuilder ,
58+ FilterRequestBuilder filterRequestBuilder ,
5259 AttributeRequestBuilder attributeRequestBuilder ,
5360 Provider <NeighborEntitiesRequestBuilder > neighborEntitiesRequestBuilderProvider ) {
5461 this .argumentDeserializer = argumentDeserializer ;
5562 this .selectionFinder = selectionFinder ;
5663 this .metricAggregationRequestBuilder = metricAggregationRequestBuilder ;
5764 this .attributeRequestBuilder = attributeRequestBuilder ;
5865 this .neighborEntitiesRequestBuilderProvider = neighborEntitiesRequestBuilderProvider ;
66+ this .filterRequestBuilder = filterRequestBuilder ;
5967 }
6068
6169 Single <EdgeSetGroupRequest > buildIncomingEdgeRequest (
6270 GraphQlRequestContext context ,
6371 TimeRangeArgument timeRange ,
6472 Optional <String > space ,
6573 Stream <SelectedField > edgeSetFields ) {
66- return this .buildEdgeRequest (
67- context , timeRange , space , this .getEdgesByType (edgeSetFields ), EdgeType .INCOMING );
74+ return this .buildEdgeRequest (context , timeRange , space , edgeSetFields , EdgeType .INCOMING );
6875 }
6976
7077 Single <EdgeSetGroupRequest > buildOutgoingEdgeRequest (
7178 GraphQlRequestContext context ,
7279 TimeRangeArgument timeRange ,
7380 Optional <String > space ,
7481 Stream <SelectedField > edgeSetFields ) {
75- return this .buildEdgeRequest (
76- context , timeRange , space , this .getEdgesByType (edgeSetFields ), EdgeType .OUTGOING );
82+ return this .buildEdgeRequest (context , timeRange , space , edgeSetFields , EdgeType .OUTGOING );
7783 }
7884
7985 private Single <EdgeSetGroupRequest > buildEdgeRequest (
8086 GraphQlRequestContext context ,
8187 TimeRangeArgument timeRange ,
8288 Optional <String > space ,
83- Map < String , Set < SelectedField >> edgesByType ,
89+ Stream < SelectedField > edgeSetFields ,
8490 EdgeType edgeType ) {
91+ Set <SelectedField > edgeFields = edgeSetFields .collect (Collectors .toUnmodifiableSet ());
92+ List <FilterArgument > filterArguments = this .getFilters (edgeFields );
93+
94+ if (!filterArguments .isEmpty () && edgeFields .size () > 1 ) {
95+ throw Status .UNIMPLEMENTED
96+ .withDescription ("Cannot specify more than one edge type with edge filters" )
97+ .asRuntimeException ();
98+ }
8599
100+ Map <String , Set <SelectedField >> edgesByType = this .getEdgesByType (edgeFields .stream ());
86101 Set <SelectedField > allEdges =
87102 edgesByType .values ().stream ()
88103 .flatMap (Collection ::stream )
@@ -94,7 +109,9 @@ private Single<EdgeSetGroupRequest> buildEdgeRequest(
94109 this .getNeighborTypeAttribute (context , edgeType ),
95110 this .metricAggregationRequestBuilder .build (
96111 context , HypertraceAttributeScopeString .INTERACTION , allEdges .stream ()),
97- (attributeRequests , neighborIdRequest , neighborTypeRequest , metricRequests ) ->
112+ this .filterRequestBuilder .build (
113+ context , HypertraceAttributeScopeString .INTERACTION , filterArguments ),
114+ (attributeRequests , neighborIdRequest , neighborTypeRequest , metricRequests , filters ) ->
98115 new DefaultEdgeSetGroupRequest (
99116 edgesByType .keySet (),
100117 attributeRequests ,
@@ -110,7 +127,8 @@ private Single<EdgeSetGroupRequest> buildEdgeRequest(
110127 timeRange ,
111128 space ,
112129 neighborIds ,
113- edgesByType .get (entityType ))));
130+ edgesByType .get (entityType )),
131+ filters ));
114132 }
115133
116134 private Map <String , Set <SelectedField >> getEdgesByType (Stream <SelectedField > edgeSetStream ) {
@@ -165,6 +183,17 @@ private Single<AttributeRequest> getNeighborIdAttribute(
165183 }
166184 }
167185
186+ private List <FilterArgument > getFilters (Set <SelectedField > selectedFields ) {
187+ return selectedFields .stream ()
188+ .map (
189+ selectedField ->
190+ this .argumentDeserializer .deserializeObjectList (
191+ selectedField .getArguments (), FilterArgument .class ))
192+ .flatMap (Optional ::stream )
193+ .flatMap (Collection ::stream )
194+ .collect (Collectors .toUnmodifiableList ());
195+ }
196+
168197 private Single <AttributeRequest > getNeighborTypeAttribute (
169198 GraphQlRequestContext context , EdgeType edgeType ) {
170199 switch (edgeType ) {
@@ -191,12 +220,14 @@ private enum EdgeType {
191220 @ Value
192221 @ Accessors (fluent = true )
193222 private static class DefaultEdgeSetGroupRequest implements EdgeSetGroupRequest {
223+
194224 Set <String > entityTypes ;
195225 Collection <AttributeRequest > attributeRequests ;
196226 Collection <MetricAggregationRequest > metricAggregationRequests ;
197227 AttributeRequest neighborIdAttribute ;
198228 AttributeRequest neighborTypeAttribute ;
199229 BiFunction <String , Collection <String >, Single <EntityRequest >> neighborRequestBuilder ;
230+ Collection <AttributeAssociation <FilterArgument >> filterArguments ;
200231
201232 @ Override
202233 public Single <EntityRequest > buildNeighborRequest (
0 commit comments