Skip to content

Added support to query labels on entity schema - #101

Merged
saxenakshitiz merged 13 commits into
mainfrom
ENG-11241_1
Sep 9, 2021
Merged

saxenakshitiz merged 13 commits into
mainfrom
ENG-11241_1

Conversation

@saxenakshitiz

@saxenakshitiz saxenakshitiz commented Sep 3, 2021 •

Copy link
Copy Markdown
Contributor

No description provided.

@codecov

codecov Bot commented Sep 3, 2021 •

Copy link
Copy Markdown

Codecov Report

Merging #101 (d04f5dc) into main (143b977) will decrease coverage by 0.55%.
The diff coverage is 1.75%.

Impacted file tree graph

@@             Coverage Diff              @@
##               main     #101      +/-   ##
============================================
- Coverage     22.22%   21.67%   -0.56%     
  Complexity       67       67              
============================================
  Files            64       64              
  Lines          1615     1661      +46     
  Branches         50       54       +4     
============================================
+ Hits            359      360       +1     
- Misses         1248     1293      +45     
  Partials          8        8              
Flag Coverage Δ
unit 21.67% <1.75%> (-0.56%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...hypertrace/graphql/entity/dao/EntityDaoModule.java 0.00% <0.00%> (ø)
...phql/entity/dao/GatewayServiceEntityConverter.java 0.00% <0.00%> (ø)
...ce/graphql/entity/dao/GatewayServiceEntityDao.java 0.00% <0.00%> (ø)
...entity/dao/GatewayServiceEntityRequestBuilder.java 0.00% <0.00%> (ø)
...ql/entity/request/DefaultEntityRequestBuilder.java 0.00% <0.00%> (ø)
...entity/request/NeighborEntitiesRequestBuilder.java 0.00% <0.00%> (ø)
...phql/entity/joiner/DefaultEntityJoinerBuilder.java 89.18% <100.00%> (+0.09%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 143b977...d04f5dc. Read the comment docs.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

EntityRequest request,
EntitiesResponse response,
BaselineEntitiesResponse baselineResponse,
Map<String, String> labelsMap) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am guessing the value in the map is the label key. Instead, the value in the map should be the entire server Label response

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is to map. Since the response is not per entity, I had converted it once and passed it as an argument.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anyways the logic is now moved to converter

return EMPTY_LABEL_RESULT_SET;
}
Value value =
entity.getAttributeOrDefault(request.labelsAttributeRequest().attribute().id(), null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering, should we use something like

, to map the foreign id keys between label id and label ids stored in entities?

A similar example case happens for tying up log event with a span https://github.com/hypertrace/hypertrace-core-graphql/blob/e6a3738f459a45bd45eb73ebd8f326de23dac2d0/hypertrace-core-graphql-span-schema/src/main/java/org/hypertrace/core/graphql/span/dao/SpanLogEventResponseConverter.java#L41

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as we discussed this is probably not needed

org.hypertrace.gateway.service.v1.entity.Entity entity,
EntityRequest request,
Map<String, String> labelsMap) {
if (labelsMap.isEmpty()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is a need for this check anyways, since it would be automatically taken care of as we are streaming labelsMap on L151

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to return a static empty result set instead of creating an empty result set each time.

@github-actions

This comment has been minimized.

@skjindal93 skjindal93 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Can you please unit tests mostly for the request and response converters?

@github-actions

This comment has been minimized.

EntityRequest request,
EntitiesResponse response,
BaselineEntitiesResponse baselineResponse,
Optional<GetLabelsResponse> labelsResponse) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually you don't want to pass optionals as arguments (more of a return mechanism, since an optional argument is better represented by an overload). Sometimes it can be a pain, but here we could just as easily provide an empty response.

implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-attribute-store")
implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-deserialization")
implementation("org.hypertrace.core.graphql:hypertrace-core-graphql-rx-utils")
implementation("org.hypertrace.config.service:labels-config-service-api")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uh oh

labelResultSet));
}

private LabelResultSet buildLabelResultSet(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like repetition with the label's own response building - the labels in an entity response are no different than the stand alone label api. The responsibility for building labels should be delegated to the existing label converter (LabelResponseConverter should implemented the Converter interface and bind it so this service can inject a Converter<GetLabelsResponse, LabelResultSet>.

The real difference comes in the fact that you want to split up that result set and map it back to entities that requested each label. That use case is identical to what we do with entity joining, so looking at it may be helpful - it collects the entity IDs from an arbitrary source, fetches them together, then maps the result back on to the original requests.

Anyway, no matter how you do it - the label schema should be responsible for everything from building the label request all the way through mapping it back to the graphql label object. The cardinal rule we're breaking here is that no other schema should be aware of the underlying implementation of labels (that is, implementation("org.hypertrace.config.service:labels-config-service-api") cannot be a dependency of this schema).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me look in to this. We didn't go joiner route as we are not fetching label ids based on entities labels. We are fetching all and then filtering based on respective entity's labels.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

server-side vs in-memory filtering is a bit of an implementation detail - it's more about separating out the actual join glue (and deduping it since we'll want to join in other spots like explorer, too). Anyway, the big thing is keeping the server side of labels encapsulated within the label schema.

serviceConfig.getGatewayServiceHost(), serviceConfig.getGatewayServicePort()))
.withCallCredentials(credentials);

this.labelConfigServiceStub =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented above - delegate to the other schema, rather than implementing a separate dependency to the label service.

EdgeSetGroupRequest incomingEdgeRequests = new EmptyEdgeSetGroupRequest();
EdgeSetGroupRequest outgoingEdgeRequests = new EmptyEdgeSetGroupRequest();
boolean includeInactive = true; // When joining we want the entity regardless of time range
Optional<LabelRequest> labelRequest = Optional.empty();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

labels can't be fetched here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me pick it up in next PR

return this.argumentDeserializer.deserializePrimitive(arguments, SpaceArgument.class);
}

private Optional<LabelRequest> buildLabelRequest(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would suggest pulling this outside - a boolean that turns into an optional empty could just as easily (and with more clarity) be done above.

false,
false));
false,
Optional.empty()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also should be supported here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will pick it up in next PR

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@aaron-steinfeld aaron-steinfeld left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly nits - only two things I think we need to address before merge is logging the errors.

@github-actions

This comment has been minimized.

return entity -> {
Value labelAttributeValue =
entity.getAttributeOrDefault(
request.labelRequest().get().labelIdArrayAttributeRequest().attribute().id(), null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this is the same behavior as just a regular .get

@aaron-steinfeld
aaron-steinfeld self-requested a review September 9, 2021 18:51

@aaron-steinfeld aaron-steinfeld left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like I can't even remove my own approval now without requesting changes. great job github. Code looks fine, but can we get tests added for the new stuff?

@saxenakshitiz
saxenakshitiz merged commit 90f694e into main Sep 9, 2021
@saxenakshitiz
saxenakshitiz deleted the ENG-11241_1 branch September 9, 2021 19:04
@github-actions

github-actions Bot commented Sep 9, 2021

Copy link
Copy Markdown

Unit Test Results

10 files  ±0  10 suites  ±0   10s ⏱️ -7s
20 tests ±0  20 ✔️ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 90f694e. ± Comparison against base commit 143b977.

@saxenakshitiz

Copy link
Copy Markdown
Contributor Author

Will add tests in a separate PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants