-
Notifications
You must be signed in to change notification settings - Fork 6
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
Conversation
Codecov Report
@@ 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
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
This comment has been minimized.
This comment has been minimized.
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
Once the review comments are addressed, please also add the unit and integration tests. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this 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) { |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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)) { |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of reasons
-
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 -
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()) { |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Outdated
Show resolved
Hide resolved
...y-service-impl/src/main/java/org/hypertrace/entity/query/service/EntityQueryServiceImpl.java
Show resolved
Hide resolved
This comment has been minimized.
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); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 { |
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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); |
There was a problem hiding this comment.
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
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)); | ||
; |
There was a problem hiding this comment.
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)); | ||
; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
This comment has been minimized.
This comment has been minimized.
...rvice-impl/src/test/java/org/hypertrace/entity/query/service/EntityQueryServiceImplTest.java
Outdated
Show resolved
Hide resolved
...e/src/integrationTest/java/org/hypertrace/entity/service/service/EntityQueryServiceTest.java
Outdated
Show resolved
Hide resolved
.putEntities(entity2.getEntityId(), updateInfo2) | ||
.build(); | ||
|
||
Iterator<ResultSetChunk> resultChunkIterator = |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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)
…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>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This reverts commit 4cffb07.
No description provided.