Skip to content

impl for bulkupdate api #121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Aug 11, 2021
Merged

impl for bulkupdate api #121

merged 13 commits into from
Aug 11, 2021

Conversation

ankitchoudhary111
Copy link
Contributor

No description provided.

@codecov
Copy link

codecov bot commented Aug 2, 2021

Codecov Report

Merging #121 (ba5b6c6) into main (e2ae441) will increase coverage by 0.09%.
The diff coverage is 77.77%.

Impacted file tree graph

@@             Coverage Diff              @@
##               main     #121      +/-   ##
============================================
+ Coverage     59.61%   59.71%   +0.09%     
- Complexity      292      303      +11     
============================================
  Files            39       39              
  Lines          2974     3043      +69     
  Branches        368      376       +8     
============================================
+ Hits           1773     1817      +44     
- Misses         1029     1053      +24     
- Partials        172      173       +1     
Flag Coverage Δ
integration 59.71% <77.77%> (+0.09%) ⬆️
unit 40.63% <77.77%> (+0.89%) ⬆️

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

Impacted Files Coverage Δ
...e/entity/query/service/EntityQueryServiceImpl.java 77.07% <77.77%> (+0.44%) ⬆️
...query/service/client/EntityQueryServiceClient.java 0.00% <0.00%> (-83.34%) ⬇️

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 e2ae441...ba5b6c6. Read the comment docs.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@skjindal93
Copy link
Contributor

skjindal93 commented Aug 4, 2021

There are some existing review comments. Please take care of them as well. Github must have hidden them.

Screen Shot 2021-08-04 at 3 25 56 PM

@skjindal93
Copy link
Contributor

Once the review comments are addressed, please also add the unit and integration tests.

@github-actions

This comment has been minimized.

Copy link
Contributor

@aaron-steinfeld aaron-steinfeld left a comment

Choose a reason for hiding this comment

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

There's a lot of resolved comments here that aren't actually resolved. I tried to clear out my comments that had already been mentioned, but I may have repeated some stuff.

In the future @ankitchoudhary111 - generally the commenter, not the author, is responsible for resolving comments once they review with the author's fix.

@@ -35,6 +36,12 @@ public EntityQueryServiceClient(Channel channel) {
headers, () -> blockingStub.update(updateRequest));
}

public Iterator<ResultSetChunk> bulkUpdate(
BulkEntityUpdateRequest updateRequest, Map<String, String> headers) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would vote to not put this in the client (since I think we mostly use the native stubs now, anyway). Mainly, I don't want to spread the tech debt of this client in terms of exposing iterators and header maps.

@@ -290,19 +295,128 @@ private void doUpdate(RequestContext requestContext, EntityUpdateRequest request
EntityQueryConverter.convertToAttributeValue(setAttribute.getValue()).build();
String jsonValue = DocStoreJsonFormat.printer().print(attributeValue);

Map<Key, Map<String, Document>> entitiesUpdateMap = new HashMap<>();

for (String entityId : request.getEntityIdsList()) {
SingleValueKey key =
new SingleValueKey(requestContext.getTenantId().orElseThrow(), entityId);
// TODO better error reporting once doc store exposes the,
Copy link
Contributor

Choose a reason for hiding this comment

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

Still relevant with the change?

Copy link
Contributor

Choose a reason for hiding this comment

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

I am not even sure, what the current comment even means, because it's incomplete

@@ -290,19 +295,128 @@ private void doUpdate(RequestContext requestContext, EntityUpdateRequest request
EntityQueryConverter.convertToAttributeValue(setAttribute.getValue()).build();
String jsonValue = DocStoreJsonFormat.printer().print(attributeValue);

Map<Key, Map<String, Document>> entitiesUpdateMap = new HashMap<>();

for (String entityId : request.getEntityIdsList()) {
SingleValueKey key =
new SingleValueKey(requestContext.getTenantId().orElseThrow(), entityId);
// TODO better error reporting once doc store exposes the,
Copy link
Contributor

Choose a reason for hiding this comment

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

Still relevant with the change?

key,
subDocPath,
jsonValue);
if (entitiesUpdateMap.containsKey(key)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

can clean up this if/else with computeIfAbsent

BulkEntityUpdateRequest request, StreamObserver<ResultSetChunk> responseObserver) {
// Validations
RequestContext requestContext = RequestContext.CURRENT.get();
Optional<String> tenantId = requestContext.getTenantId();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit, orElse(null) this here so we don't have to optional.get() later (where we lose the context that this has been checked for presence)

}
}
try {
entitiesCollection.bulkUpdateSubDocs(entitiesUpdateMap);
Copy link
Contributor

Choose a reason for hiding this comment

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

The update method doesn't return? If not, can we make it? Seems silly (and inefficient) to have to update then query again to get the results

Copy link
Contributor

@skjindal93 skjindal93 Aug 5, 2021

Choose a reason for hiding this comment

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

Couple of reasons

  1. The bulkUpdateSubDocs method currently only returns the number of successfully updated documents.
    We just tried to follow what the existing bulkUpdate function does for entities

  2. Trying to follow what the existing update API does. I think the use case was just to avoid another GET entities query to get the projected selections

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm really asking why bulkUpdateSubDocs doesn't, since it looks like at least here we need to do the following select/get anyway. Is it that the underlying store doesn't return this anyway, so even if we returned it from the api we're making two calls, an update and a select?

Copy link
Contributor

@skjindal93 skjindal93 Aug 5, 2021

Choose a reason for hiding this comment

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

need to check the update support in the underlying store, but shouldn't the bulkUpdateSubDocs follow the same semantics as bulkUpdate?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, would make the same argument there - they both return the same object, so extending that object with the actual updated documents would affect both APIs.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, we could extend that to return the actual updated documents, but I don't think we would be able to get the projected entities with just the requested selections in that case, unless we actually pass the set of requested projections to the document store API, and then ask it to return the projected documents (as part of the same request, if Mongo/Postgres can support that)

Copy link
Contributor

@skjindal93 skjindal93 Aug 5, 2021

Choose a reason for hiding this comment

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

In fact, these are 2 APIs merged into one

  • bulk update entities
  • get projected entities (irrespective of the updated ones)

now, that I think about it, the API sounds weird. I think we should get rid of the projected selections from the bulk update API

Copy link
Contributor

Choose a reason for hiding this comment

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

So taking a glance at the impls, at least postgres (not sure about mongo) does not support this, so it would probably make sense to keep it as a distinct API - that decision should likely bubble up then so we're consistent - if entity service is forced to make two calls, then we may as well have the caller make the two calls since there are certainly cases where we don't care about the updated docs.

Copy link
Contributor

Choose a reason for hiding this comment

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

agreed.

Mongo does support that, but I would rather prefer to drop the projections support from the API, as you mentioned too

@ankitchoudhary111 Can you please get rid of the projections support from the bulk update API?

}
}

if (entitiesUpdateMap.isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't really be reachable - there should never be a successful case where we return without actually doing an update.

try {
BulkUpdateResult bulkUpdateResult = entitiesCollection.bulkUpdateSubDocs(toUpdate);
} catch (Exception e) {
LOG.warn("Failed to update entities", e);
Copy link
Contributor

Choose a reason for hiding this comment

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

So if the update fails, we catch it, log a warning and proceed on successfully? That doesn't seem right.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Copy link
Contributor

@skjindal93 skjindal93 left a comment

Choose a reason for hiding this comment

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

@github-actions

This comment has been minimized.

String jsonValue = DocStoreJsonFormat.printer().print(attributeValue);
documentMap.put(subDocPath, new JSONDocument(jsonValue));
} catch (Exception e) {
LOG.warn("Failed to put update corresponding to {} in the documentMap", subDocPath, e);
Copy link
Contributor

Choose a reason for hiding this comment

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

We should throw the exception back here

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
LOG.warn("Failed to put update corresponding to {} in the documentMap", subDocPath, e);
LOG.error("Failed to put update corresponding to {} in the documentMap", subDocPath, e);

}

@Test
public void testBulkUpdate_noTenantId() throws Exception {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you put all the bulk update tests inside a nested test class?

eqs.bulkUpdate(bulkUpdateRequest, mockResponseObserver);
return null;
});
verify(entitiesCollection, times(0)).bulkUpdateSubDocs(any());
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
verify(entitiesCollection, times(0)).bulkUpdateSubDocs(any());
verify(entitiesCollection, never()).bulkUpdateSubDocs(any());

@@ -68,7 +76,7 @@
private static final Logger LOG = LoggerFactory.getLogger(EntityQueryServiceTest.class);
private static final Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(LOG);

private static EntityQueryServiceClient entityQueryServiceClient;
private static EntityQueryServiceBlockingStub blockingStub;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
private static EntityQueryServiceBlockingStub blockingStub;
private static EntityQueryServiceBlockingStub entityQueryServiceClient;

@@ -82,6 +90,7 @@
private static final String SERVICE_ID = generateRandomUUID();

private static Map<String, String> apiAttributesMap;
private static Map<String, String> headers = Map.of("x-tenant-id", TENANT_ID);
Copy link
Contributor

Choose a reason for hiding this comment

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

statis final variables are upper cased

Suggested change
private static Map<String, String> headers = Map.of("x-tenant-id", TENANT_ID);
private static final Map<String, String> HEADERS = Map.of("x-tenant-id", TENANT_ID);

.putIdentifyingAttributes(
EntityConstants.getValue(ApiAttribute.API_ATTRIBUTE_API_TYPE),
createAttribute(API_TYPE));
;
Copy link
Contributor

Choose a reason for hiding this comment

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

dangling semi colon

.putIdentifyingAttributes(
EntityConstants.getValue(ApiAttribute.API_ATTRIBUTE_API_TYPE),
createAttribute(API_TYPE));
;
Copy link
Contributor

Choose a reason for hiding this comment

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

dangling semi colon

.putEntities(entity2.getEntityId(), updateInfo2)
.build();

Map<String, String> headers = Map.of("x-tenant-id", TENANT_ID);
Copy link
Contributor

Choose a reason for hiding this comment

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

We already have defined the headers at the class level. Can directly use them

@github-actions

This comment has been minimized.

.putEntities(entity2.getEntityId(), updateInfo2)
.build();

Iterator<ResultSetChunk> resultChunkIterator =
Copy link
Contributor

Choose a reason for hiding this comment

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

Since, we aren't using resultChunkIterator, can we get rid of this?

String jsonValue = DocStoreJsonFormat.printer().print(attributeValue);
documentMap.put(subDocPath, new JSONDocument(jsonValue));
} catch (Exception e) {
LOG.error("Failed to put update corresponding to {} in the documentMap", subDocPath, e);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please throw the exception back #121 (comment)

ankitchoudhary111 and others added 2 commits August 10, 2021 17:31
…service/EntityQueryServiceImplTest.java

Co-authored-by: SJ <48863181+skjindal93@users.noreply.github.com>
…service/service/EntityQueryServiceTest.java

Co-authored-by: SJ <48863181+skjindal93@users.noreply.github.com>
@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.

@ankitchoudhary111 ankitchoudhary111 merged commit 4cffb07 into main Aug 11, 2021
@ankitchoudhary111 ankitchoudhary111 deleted the updateapiimpl branch August 11, 2021 08:25
@github-actions
Copy link

Unit Test Results

  31 files  +1    31 suites  +1   20s ⏱️ -3s
143 tests +6  143 ✔️ +6  0 💤 ±0  0 ❌ ±0 

Results for commit 4cffb07. ± Comparison against base commit e2ae441.

skjindal93 added a commit that referenced this pull request Sep 2, 2021
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