|
76 | 76 | import lombok.NonNull;
|
77 | 77 | import lombok.Value;
|
78 | 78 | import lombok.extern.slf4j.Slf4j;
|
| 79 | +import pegasus.com.linkedin.metadata.events.IngestionAspectETag; |
| 80 | +import pegasus.com.linkedin.metadata.events.IngestionAspectETagArray; |
79 | 81 |
|
80 | 82 | import static com.linkedin.metadata.dao.utils.IngestionUtils.*;
|
81 | 83 | import static com.linkedin.metadata.dao.utils.ModelUtils.*;
|
@@ -484,7 +486,6 @@ public void setEmitAuditEvent(boolean emitAuditEvent) {
|
484 | 486 | _emitAuditEvent = emitAuditEvent;
|
485 | 487 | }
|
486 | 488 |
|
487 |
| - |
488 | 489 | /**
|
489 | 490 | * Logic common to both {@link #add(Urn, Class, Function, AuditStamp)} and {@link #delete(Urn, Class, AuditStamp, int)} methods.
|
490 | 491 | *
|
@@ -549,17 +550,44 @@ private <ASPECT extends RecordTemplate> AddResult<ASPECT> addCommon(@Nonnull URN
|
549 | 550 | return new AddResult<>(oldValue, oldValue, aspectClass);
|
550 | 551 | }
|
551 | 552 |
|
| 553 | + final AuditStamp optimisticLockAuditStamp = extractOptimisticLockForAspectFromIngestionParamsIfPossible(ingestionParams, aspectClass); |
| 554 | + |
552 | 555 | // Save the newValue as the latest version
|
553 | 556 | long largestVersion =
|
554 |
| - saveLatest(urn, aspectClass, oldValue, oldAuditStamp, newValue, auditStamp, latest.isSoftDeleted, |
555 |
| - trackingContext, ingestionParams.isTestMode()); |
| 557 | + saveLatest(urn, aspectClass, oldValue, |
| 558 | + optimisticLockAuditStamp != null ? optimisticLockAuditStamp : oldAuditStamp, |
| 559 | + newValue, auditStamp, latest.isSoftDeleted, trackingContext, ingestionParams.isTestMode()); |
556 | 560 |
|
557 | 561 | // Apply retention policy
|
558 | 562 | applyRetention(urn, aspectClass, getRetention(aspectClass), largestVersion);
|
559 | 563 |
|
560 | 564 | return new AddResult<>(oldValue, newValue, aspectClass);
|
561 | 565 | }
|
562 | 566 |
|
| 567 | + @VisibleForTesting |
| 568 | + protected <ASPECT extends RecordTemplate> AuditStamp extractOptimisticLockForAspectFromIngestionParamsIfPossible( |
| 569 | + @Nullable IngestionParams ingestionParams, @Nonnull Class<ASPECT> aspectClass) { |
| 570 | + if (ingestionParams == null) { |
| 571 | + return null; |
| 572 | + } |
| 573 | + |
| 574 | + AuditStamp optimisticLockAuditStamp = null; |
| 575 | + |
| 576 | + final IngestionAspectETagArray ingestionAspectETags = ingestionParams.getIngestionETags(); |
| 577 | + |
| 578 | + if (ingestionAspectETags != null) { |
| 579 | + for (IngestionAspectETag ingestionAspectETag: ingestionAspectETags) { |
| 580 | + if (aspectClass.getSimpleName().equalsIgnoreCase(ingestionAspectETag.getAspect_name()) |
| 581 | + && ingestionAspectETag.getETag() != null) { |
| 582 | + optimisticLockAuditStamp = new AuditStamp(); |
| 583 | + optimisticLockAuditStamp.setTime(ingestionAspectETag.getETag()); |
| 584 | + break; |
| 585 | + } |
| 586 | + } |
| 587 | + } |
| 588 | + return optimisticLockAuditStamp; |
| 589 | + } |
| 590 | + |
563 | 591 | /**
|
564 | 592 | * Adds a new version of several aspects for an entity.
|
565 | 593 | *
|
@@ -1313,15 +1341,15 @@ private <ASPECT extends RecordTemplate> void applyRetention(@Nonnull URN urn, @N
|
1313 | 1341 | * @param urn the URN for the entity the aspect is attached to
|
1314 | 1342 | * @param aspectClass the aspectClass of the aspect being saved
|
1315 | 1343 | * @param oldEntry {@link RecordTemplate} of the previous latest value of aspect, null if new value is the first version
|
1316 |
| - * @param oldAuditStamp the audit stamp of the previous latest aspect, null if new value is the first version |
| 1344 | + * @param optimisticLockAuditStamp the audit stamp of the previous latest aspect, null if new value is the first version. Used for optimistic locking. |
1317 | 1345 | * @param newEntry {@link RecordTemplate} of the new latest value of aspect
|
1318 | 1346 | * @param newAuditStamp the audit stamp for the operation
|
1319 | 1347 | * @param isSoftDeleted flag to indicate if the previous latest value of aspect was soft deleted
|
1320 | 1348 | * @param isTestMode whether the test mode is enabled or not
|
1321 | 1349 | * @return the largest version
|
1322 | 1350 | */
|
1323 | 1351 | protected abstract <ASPECT extends RecordTemplate> long saveLatest(@Nonnull URN urn,
|
1324 |
| - @Nonnull Class<ASPECT> aspectClass, @Nullable ASPECT oldEntry, @Nullable AuditStamp oldAuditStamp, |
| 1352 | + @Nonnull Class<ASPECT> aspectClass, @Nullable ASPECT oldEntry, @Nullable AuditStamp optimisticLockAuditStamp, |
1325 | 1353 | @Nullable ASPECT newEntry, @Nonnull AuditStamp newAuditStamp, boolean isSoftDeleted,
|
1326 | 1354 | @Nullable IngestionTrackingContext trackingContext, boolean isTestMode);
|
1327 | 1355 |
|
|
0 commit comments