Skip to content

Commit 317440b

Browse files
Attribute expressions (#128)
* refactor: add support for attribute expressions * chore: temp for testing * chore: update new label code for attribute expressions * chore: update submodule * fix: remove debug logging * style: spotless * chore: rename attribute expression association
1 parent 330cb6d commit 317440b

File tree

47 files changed

+461
-255
lines changed

Some content is hidden

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

47 files changed

+461
-255
lines changed

.snyk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ ignore:
55
SNYK-JAVA-IONETTY-1042268:
66
- '*':
77
reason: No replacement available
8-
expires: 2021-12-31T00:00:00.000Z
8+
expires: 2022-03-31T00:00:00.000Z
99
patch: {}
1010

hypertrace-core-graphql

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/dao/EntityDaoModule.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.Set;
1212
import org.hypertrace.core.graphql.common.request.AttributeAssociation;
1313
import org.hypertrace.core.graphql.common.request.AttributeRequest;
14+
import org.hypertrace.core.graphql.common.schema.attributes.arguments.AttributeExpression;
1415
import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument;
1516
import org.hypertrace.core.graphql.common.utils.BiConverter;
1617
import org.hypertrace.core.graphql.common.utils.Converter;
@@ -81,19 +82,21 @@ protected void configure() {
8182
Collection<MetricRequest>,
8283
Entity,
8384
BaselineEntity,
84-
Map<String, MetricContainer>>>() {}));
85+
Map<AttributeExpression, MetricContainer>>>() {}));
8586

8687
requireBinding(
8788
Key.get(
8889
new TypeLiteral<
8990
BiConverter<
90-
Collection<AttributeRequest>, Map<String, Value>, Map<String, Object>>>() {}));
91+
Collection<AttributeRequest>,
92+
Map<String, Value>,
93+
Map<AttributeExpression, Object>>>() {}));
9194
requireBinding(
9295
Key.get(
9396
new TypeLiteral<
9497
BiConverter<
9598
Collection<MetricAggregationRequest>,
9699
Map<String, AggregatedMetricValue>,
97-
Map<String, BaselinedMetricAggregationContainer>>>() {}));
100+
Map<AttributeExpression, BaselinedMetricAggregationContainer>>>() {}));
98101
}
99102
}

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/dao/EntityNeighborMapFetcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ private Single<ImmutableSetMultimap<String, InteractionResponse>> mapInteraction
7373
private Single<Entry<String, InteractionResponse>> buildInteractionEntry(
7474
AttributeRequest neighborIdAttribute, InteractionResponse response) {
7575
return this.valueConverter
76-
.convert(response.getInteraction().getAttributeMap().get(neighborIdAttribute.alias()))
76+
.convert(response.getInteraction().getAttributeMap().get(neighborIdAttribute.asMapKey()))
7777
.map(String::valueOf)
7878
.map(id -> Map.entry(id, response));
7979
}

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/dao/GatewayServiceEntityConverter.java

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
import java.util.List;
1010
import java.util.Map;
1111
import java.util.Optional;
12+
import java.util.function.Function;
1213
import java.util.stream.Collectors;
1314
import javax.annotation.Nullable;
1415
import javax.inject.Inject;
1516
import lombok.experimental.Accessors;
1617
import org.hypertrace.core.graphql.common.request.AttributeRequest;
18+
import org.hypertrace.core.graphql.common.schema.attributes.arguments.AttributeExpression;
1719
import org.hypertrace.core.graphql.common.utils.BiConverter;
1820
import org.hypertrace.core.graphql.common.utils.TriConverter;
1921
import org.hypertrace.gateway.service.v1.baseline.BaselineEntitiesResponse;
@@ -31,26 +33,28 @@
3133
import org.hypertrace.graphql.metric.schema.MetricContainer;
3234

3335
class GatewayServiceEntityConverter {
34-
private final BiConverter<Collection<AttributeRequest>, Map<String, Value>, Map<String, Object>>
36+
private final BiConverter<
37+
Collection<AttributeRequest>, Map<String, Value>, Map<AttributeExpression, Object>>
3538
attributeMapConverter;
3639

3740
private final TriConverter<
3841
Collection<MetricRequest>,
3942
org.hypertrace.gateway.service.v1.entity.Entity,
4043
BaselineEntity,
41-
Map<String, MetricContainer>>
44+
Map<AttributeExpression, MetricContainer>>
4245
metricContainerConverter;
4346
private final GatewayServiceEntityEdgeLookupConverter edgeLookupConverter;
4447

4548
@Inject
4649
GatewayServiceEntityConverter(
47-
BiConverter<Collection<AttributeRequest>, Map<String, Value>, Map<String, Object>>
50+
BiConverter<
51+
Collection<AttributeRequest>, Map<String, Value>, Map<AttributeExpression, Object>>
4852
attributeMapConverter,
4953
TriConverter<
5054
Collection<MetricRequest>,
5155
org.hypertrace.gateway.service.v1.entity.Entity,
5256
BaselineEntity,
53-
Map<String, MetricContainer>>
57+
Map<AttributeExpression, MetricContainer>>
5458
metricContainerConverter,
5559
GatewayServiceEntityEdgeLookupConverter edgeLookupConverter) {
5660
this.attributeMapConverter = attributeMapConverter;
@@ -103,7 +107,7 @@ private BaselineEntity getBaselineEntity(
103107
private Map<String, BaselineEntity> getBaselineEntityMap(
104108
BaselineEntitiesResponse baselineResponse) {
105109
return baselineResponse.getBaselineEntityList().stream()
106-
.collect(Collectors.toMap(BaselineEntity::getId, entity -> entity));
110+
.collect(Collectors.toMap(BaselineEntity::getId, Function.identity()));
107111
}
108112

109113
private Single<Entity> convertEntity(
@@ -121,7 +125,12 @@ private Single<Entity> convertEntity(
121125
(attrMap, containerMap) ->
122126
new ConvertedEntity(
123127
attrMap
124-
.get(entityRequest.resultSetRequest().idAttribute().attribute().key())
128+
.get(
129+
entityRequest
130+
.resultSetRequest()
131+
.idAttribute()
132+
.attributeExpressionAssociation()
133+
.value())
125134
.toString(),
126135
entityRequest.entityType(),
127136
attrMap,
@@ -136,20 +145,19 @@ private Single<Entity> convertEntity(
136145
private static class ConvertedEntity implements Entity {
137146
String id;
138147
String type;
139-
Map<String, Object> attributeValues;
140-
Map<String, MetricContainer> metricContainers;
148+
Map<AttributeExpression, Object> attributeValues;
149+
Map<AttributeExpression, MetricContainer> metricContainers;
141150
Map<String, EdgeResultSet> incomingEdges;
142151
Map<String, EdgeResultSet> outgoingEdges;
143152
LabelResultSet labels;
144153

145-
@Override
146-
public Object attribute(String key) {
147-
return this.attributeValues.get(key);
154+
public Object attribute(AttributeExpression attributeExpression) {
155+
return this.attributeValues.get(attributeExpression);
148156
}
149157

150158
@Override
151-
public MetricContainer metric(String key) {
152-
return this.metricContainers.get(key);
159+
public MetricContainer metric(AttributeExpression attributeExpression) {
160+
return this.metricContainers.get(attributeExpression);
153161
}
154162

155163
@Override

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/dao/GatewayServiceEntityDao.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import javax.inject.Inject;
1212
import javax.inject.Singleton;
1313
import lombok.extern.slf4j.Slf4j;
14+
import org.hypertrace.core.graphql.common.request.AttributeRequest;
1415
import org.hypertrace.core.graphql.context.GraphQlRequestContext;
1516
import org.hypertrace.core.graphql.rx.BoundedIoScheduler;
1617
import org.hypertrace.core.graphql.spi.config.GraphQlServiceConfig;
@@ -23,6 +24,7 @@
2324
import org.hypertrace.gateway.service.v1.entity.EntitiesResponse;
2425
import org.hypertrace.gateway.service.v1.entity.Entity;
2526
import org.hypertrace.graphql.entity.health.BaselineDao;
27+
import org.hypertrace.graphql.entity.request.EntityLabelRequest;
2628
import org.hypertrace.graphql.entity.request.EntityRequest;
2729
import org.hypertrace.graphql.entity.schema.EntityResultSet;
2830
import org.hypertrace.graphql.label.joiner.LabelJoiner;
@@ -117,21 +119,22 @@ private Single<Map<Entity, LabelResultSet>> buildLabelResultSetMap(
117119
.flatMap(
118120
joiner ->
119121
joiner.joinLabels(
120-
entitiesResponse.getEntityList(), getEntityLabelsGetter(request)));
121-
}
122-
123-
private LabelJoiner.LabelIdGetter<Entity> getEntityLabelsGetter(EntityRequest request) {
124-
return entity -> Single.just(getLabelAttributeValue(request, entity));
122+
entitiesResponse.getEntityList(),
123+
entity -> Single.just(getLabelAttributeValue(request, entity))));
125124
}
126125

127126
private List<String> getLabelAttributeValue(EntityRequest request, Entity entity) {
128-
Value labelAttributeValue =
129-
entity.getAttributeOrDefault(
130-
request.labelRequest().get().labelIdArrayAttributeRequest().attribute().id(), null);
131-
if (labelAttributeValue == null) {
132-
log.warn("Unable to fetch labels attribute for entity with id {}", entity.getId());
133-
return Collections.emptyList();
134-
}
135-
return labelAttributeValue.getStringArrayList();
127+
return request
128+
.labelRequest()
129+
.map(EntityLabelRequest::labelIdArrayAttributeRequest)
130+
.map(AttributeRequest::asMapKey)
131+
.filter(entity::containsAttribute)
132+
.map(entity::getAttributeOrThrow)
133+
.<List<String>>map(Value::getStringArrayList)
134+
.orElseGet(
135+
() -> {
136+
log.warn("Unable to fetch labels attribute for entity with id {}", entity.getId());
137+
return Collections.emptyList();
138+
});
136139
}
137140
}

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/dao/GatewayServiceEntityEdgeFetcher.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import javax.inject.Inject;
1515
import lombok.experimental.Accessors;
1616
import org.hypertrace.core.graphql.common.request.AttributeRequest;
17+
import org.hypertrace.core.graphql.common.schema.attributes.arguments.AttributeExpression;
1718
import org.hypertrace.core.graphql.common.utils.BiConverter;
1819
import org.hypertrace.core.graphql.common.utils.CollectorUtils;
1920
import org.hypertrace.gateway.service.v1.common.AggregatedMetricValue;
@@ -34,23 +35,25 @@ class GatewayServiceEntityEdgeFetcher {
3435

3536
private final EntityNeighborMapFetcher neighborMapFetcher;
3637

37-
private final BiConverter<Collection<AttributeRequest>, Map<String, Value>, Map<String, Object>>
38+
private final BiConverter<
39+
Collection<AttributeRequest>, Map<String, Value>, Map<AttributeExpression, Object>>
3840
attributeMapConverter;
3941
private final BiConverter<
4042
Collection<MetricAggregationRequest>,
4143
Map<String, AggregatedMetricValue>,
42-
Map<String, BaselinedMetricAggregationContainer>>
44+
Map<AttributeExpression, BaselinedMetricAggregationContainer>>
4345
baselineMetricAggregationContainerMapConverter;
4446

4547
@Inject
4648
GatewayServiceEntityEdgeFetcher(
4749
EntityNeighborMapFetcher neighborMapFetcher,
48-
BiConverter<Collection<AttributeRequest>, Map<String, Value>, Map<String, Object>>
50+
BiConverter<
51+
Collection<AttributeRequest>, Map<String, Value>, Map<AttributeExpression, Object>>
4952
attributeMapConverter,
5053
BiConverter<
5154
Collection<MetricAggregationRequest>,
5255
Map<String, AggregatedMetricValue>,
53-
Map<String, BaselinedMetricAggregationContainer>>
56+
Map<AttributeExpression, BaselinedMetricAggregationContainer>>
5457
baselineMetricAggregationContainerMapConverter) {
5558
this.neighborMapFetcher = neighborMapFetcher;
5659
this.attributeMapConverter = attributeMapConverter;
@@ -127,17 +130,17 @@ private Maybe<Edge> buildEdge(
127130
@Accessors(fluent = true)
128131
private static class ConvertedEdge implements Edge {
129132
Entity neighbor;
130-
Map<String, Object> attributeValues;
131-
Map<String, BaselinedMetricAggregationContainer> metricContainers;
133+
Map<AttributeExpression, Object> attributeValues;
134+
Map<AttributeExpression, BaselinedMetricAggregationContainer> metricContainers;
132135

133136
@Override
134-
public Object attribute(String key) {
135-
return this.attributeValues.get(key);
137+
public Object attribute(AttributeExpression attributeExpression) {
138+
return this.attributeValues.get(attributeExpression);
136139
}
137140

138141
@Override
139-
public BaselinedMetricAggregationContainer metric(String key) {
140-
return this.metricContainers.get(key);
142+
public BaselinedMetricAggregationContainer metric(AttributeExpression attributeExpressiony) {
143+
return this.metricContainers.get(attributeExpressiony);
141144
}
142145
}
143146

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/dao/GatewayServiceEntityEdgeTableConverter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ private Single<Map<String, Collection<InteractionResponse>>> groupInteractionsBy
5959
private Single<Entry<String, InteractionResponse>> builtInteractionTypeEntry(
6060
InteractionResponse response, AttributeRequest neighborType) {
6161

62-
return this.getEntityType(response.getInteraction().getAttributeMap().get(neighborType.alias()))
62+
return this.getEntityType(
63+
response.getInteraction().getAttributeMap().get(neighborType.asMapKey()))
6364
.map(entityType -> Map.entry(entityType, response));
6465
}
6566

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/dao/GatewayServiceEntityInteractionRequestBuilder.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.hypertrace.core.graphql.common.request.AttributeAssociation;
1414
import org.hypertrace.core.graphql.common.request.AttributeRequest;
1515
import org.hypertrace.core.graphql.common.schema.attributes.AttributeScope;
16+
import org.hypertrace.core.graphql.common.schema.attributes.arguments.AttributeExpression;
1617
import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument;
1718
import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterOperatorType;
1819
import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterType;
@@ -71,17 +72,19 @@ private Single<Filter> buildEntityTypeFilter(EdgeSetGroupRequest request) {
7172
.map(
7273
entityTypes ->
7374
AttributeAssociation.<FilterArgument>of(
74-
request.neighborTypeAttribute().attribute(),
75+
request.neighborTypeAttribute().attributeExpressionAssociation().attribute(),
7576
new EntityNeighborTypeFilter(
76-
request.neighborTypeAttribute().attribute().key(), entityTypes)))
77+
request.neighborTypeAttribute().attributeExpressionAssociation().value(),
78+
entityTypes)))
7779
.flatMap(filterAssociation -> this.filterConverter.convert(Set.of(filterAssociation)));
7880
}
7981

8082
@Value
8183
@Accessors(fluent = true)
8284
private static class EntityNeighborTypeFilter implements FilterArgument {
8385
FilterType type = FilterType.ATTRIBUTE;
84-
String key;
86+
String key = null;
87+
AttributeExpression keyExpression;
8588
FilterOperatorType operator = FilterOperatorType.IN;
8689
Collection<String> value;
8790
AttributeScope idType = null;

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/joiner/DefaultEntityJoinerBuilder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.hypertrace.core.graphql.common.request.ResultSetRequestBuilder;
4242
import org.hypertrace.core.graphql.common.schema.arguments.TimeRangeArgument;
4343
import org.hypertrace.core.graphql.common.schema.attributes.AttributeScope;
44+
import org.hypertrace.core.graphql.common.schema.attributes.arguments.AttributeExpression;
4445
import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterArgument;
4546
import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterOperatorType;
4647
import org.hypertrace.core.graphql.common.schema.results.arguments.filter.FilterType;
@@ -344,6 +345,7 @@ private static class InstantTimeRange implements TimeRangeArgument {
344345
private static class EntityIdFilter implements FilterArgument {
345346
FilterType type = FilterType.ID;
346347
String key = null;
348+
AttributeExpression keyExpression = null;
347349
FilterOperatorType operator = FilterOperatorType.IN;
348350
Collection<String> value;
349351
AttributeScope idType = null;

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/request/DefaultEntityLabelRequestBuilder.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import lombok.experimental.Accessors;
1212
import org.hypertrace.core.graphql.common.request.AttributeRequest;
1313
import org.hypertrace.core.graphql.common.request.AttributeRequestBuilder;
14+
import org.hypertrace.core.graphql.common.schema.attributes.arguments.AttributeExpression;
1415
import org.hypertrace.core.graphql.common.schema.results.ResultSet;
1516
import org.hypertrace.core.graphql.context.GraphQlRequestContext;
1617
import org.hypertrace.core.graphql.utils.schema.GraphQlSelectionFinder;
@@ -66,7 +67,8 @@ private boolean isLabelFieldRequested(
6667
private Single<Optional<EntityLabelRequest>> buildRequest(
6768
GraphQlRequestContext context, String scope) {
6869
return this.attributeRequestBuilder
69-
.buildForKey(context, scope, LABELS_ATTRIBUTE_KEY)
70+
.buildForAttributeExpression(
71+
context, scope, AttributeExpression.forAttributeKey(LABELS_ATTRIBUTE_KEY))
7072
.map(DefaultLabelRequest::new)
7173
.map(Optional::of);
7274
}

hypertrace-graphql-entity-schema/src/main/java/org/hypertrace/graphql/entity/request/EdgeRequestBuilder.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.hypertrace.core.graphql.common.request.AttributeRequest;
2020
import org.hypertrace.core.graphql.common.request.AttributeRequestBuilder;
2121
import org.hypertrace.core.graphql.common.schema.arguments.TimeRangeArgument;
22+
import org.hypertrace.core.graphql.common.schema.attributes.arguments.AttributeExpression;
2223
import org.hypertrace.core.graphql.common.schema.results.ResultSet;
2324
import org.hypertrace.core.graphql.context.GraphQlRequestContext;
2425
import org.hypertrace.core.graphql.deserialization.ArgumentDeserializer;
@@ -150,11 +151,15 @@ private Single<AttributeRequest> getNeighborIdAttribute(
150151
GraphQlRequestContext context, EdgeType edgeType) {
151152
switch (edgeType) {
152153
case INCOMING:
153-
return this.attributeRequestBuilder.buildForKey(
154-
context, HypertraceAttributeScopeString.INTERACTION, INCOMING_ENTITY_ID_KEY);
154+
return this.attributeRequestBuilder.buildForAttributeExpression(
155+
context,
156+
HypertraceAttributeScopeString.INTERACTION,
157+
AttributeExpression.forAttributeKey(INCOMING_ENTITY_ID_KEY));
155158
case OUTGOING:
156-
return this.attributeRequestBuilder.buildForKey(
157-
context, HypertraceAttributeScopeString.INTERACTION, OUTGOING_ENTITY_ID_KEY);
159+
return this.attributeRequestBuilder.buildForAttributeExpression(
160+
context,
161+
HypertraceAttributeScopeString.INTERACTION,
162+
AttributeExpression.forAttributeKey(OUTGOING_ENTITY_ID_KEY));
158163
default:
159164
return Single.error(new IllegalStateException("Unexpected value: " + edgeType));
160165
}
@@ -164,11 +169,15 @@ private Single<AttributeRequest> getNeighborTypeAttribute(
164169
GraphQlRequestContext context, EdgeType edgeType) {
165170
switch (edgeType) {
166171
case INCOMING:
167-
return this.attributeRequestBuilder.buildForKey(
168-
context, HypertraceAttributeScopeString.INTERACTION, INCOMING_ENTITY_TYPE_KEY);
172+
return this.attributeRequestBuilder.buildForAttributeExpression(
173+
context,
174+
HypertraceAttributeScopeString.INTERACTION,
175+
AttributeExpression.forAttributeKey(INCOMING_ENTITY_TYPE_KEY));
169176
case OUTGOING:
170-
return this.attributeRequestBuilder.buildForKey(
171-
context, HypertraceAttributeScopeString.INTERACTION, OUTGOING_ENTITY_TYPE_KEY);
177+
return this.attributeRequestBuilder.buildForAttributeExpression(
178+
context,
179+
HypertraceAttributeScopeString.INTERACTION,
180+
AttributeExpression.forAttributeKey(OUTGOING_ENTITY_TYPE_KEY));
172181
default:
173182
return Single.error(new IllegalStateException("Unexpected value: " + edgeType));
174183
}

0 commit comments

Comments
 (0)