Skip to content
This repository has been archived by the owner on Mar 31, 2022. It is now read-only.

Commit

Permalink
Change Tracker: check if changed field is indexed in case of directly…
Browse files Browse the repository at this point in the history
… indexed entity #71
  • Loading branch information
Gavrilov-Ivan committed Oct 20, 2021
1 parent 51f1458 commit 298b745
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ public boolean isAffectedEntityClass(Class<?> entityClass) {
return registry.isEntityClassRegistered(entityClass);
}

/**
* Gets local property names of provided entity involved into index update process
*
* @param entityClass entity class
* @return set of property names
*/
public Set<String> getLocalPropertyNamesAffectedByUpdate(Class<?> entityClass) {
return registry.getLocalPropertyNamesAffectedByUpdate(entityClass);
}

/**
* Gets metadata of entities dependent on updated main entity and its changed properties.
*
Expand Down Expand Up @@ -311,6 +321,11 @@ Set<MetaPropertyPath> getBackRefPropertiesForDelete(Class<?> entityClass) {
return referentiallyAffectedPropertiesForDelete.get(entityClass);
}

Set<String> getLocalPropertyNamesAffectedByUpdate(Class<?> entityClass) {
Map<String, Set<MetaPropertyPath>> updateMetadata = referentiallyAffectedPropertiesForUpdate.get(entityClass);
return updateMetadata == null ? Collections.emptySet() : updateMetadata.keySet();
}

Collection<String> getAllIndexedEntities() {
return indexConfigurationsByEntityName.keySet();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,21 +144,25 @@ protected void processEntityChangedEvent(EntityChangedEvent<?> event) {
EntityChangedEvent.Type eventType = event.getType();
String entityName = metaClass.getName();

if (indexConfigurationManager.isDirectlyIndexed(entityName)) { //todo check dirty fields
AttributeChanges changes = event.getChanges();
if (indexConfigurationManager.isDirectlyIndexed(entityName)) {
log.debug("{} is directly indexed", entityId);

switch (eventType) {
case CREATED:
case UPDATED:
indexingQueueManager.enqueueIndexByEntityId(entityId);
break;
case UPDATED:
if (isUpdateRequired(entityClass, changes)) {
indexingQueueManager.enqueueIndexByEntityId(entityId);
}
break;
case DELETED:
indexingQueueManager.enqueueDeleteByEntityId(entityId);
break;
}
}

AttributeChanges changes = event.getChanges();
if (EntityChangedEvent.Type.UPDATED.equals(eventType)) {
Set<Id<?>> dependentEntityIds = getEntityIdsDependentOnUpdatedEntity(entityId, metaClass, changes);

Expand All @@ -174,6 +178,13 @@ protected void processEntityChangedEvent(EntityChangedEvent<?> event) {
}
}

protected boolean isUpdateRequired(Class<?> entityClass, AttributeChanges changes) {
Set<String> affectedLocalPropertyNames = indexConfigurationManager.getLocalPropertyNamesAffectedByUpdate(entityClass);
return changes.getAttributes()
.stream()
.anyMatch(affectedLocalPropertyNames::contains);
}

protected boolean isChangeTrackingEnabled() {
return searchProperties.isChangedEntitiesIndexingEnabled();
}
Expand Down
132 changes: 132 additions & 0 deletions search/src/test/java/change_tracking/EntityChangeTrackingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,138 @@ public void updateLocalPropertyOfIndexedEntityHardDelete() {
Assert.assertTrue(enqueued);
}

@Test
@DisplayName("Update of indexed value within local embedded property leads to queue item enqueueing (Soft Delete)")
public void updateIndexedValueWithinLocalEmbeddedProperty() {
TestEmbeddableEntity embedded = metadata.create(TestEmbeddableEntity.class);
embedded.setEnumValue(TestEnum.OPEN);
embedded.setTextValue("V1");
embedded.setIntValue(1);

TestEmbTrackRootEntity rootEntity = metadata.create(TestEmbTrackRootEntity.class);
rootEntity.setTextValue("V1");
rootEntity.setEmbedded(embedded);

dataManager.save(rootEntity);

indexingQueueItemsTracker.clear();

rootEntity = dataManager.load(Id.of(rootEntity)).one();
rootEntity.getEmbedded().setTextValue("V2");
dataManager.save(rootEntity);

boolean enqueued = indexingQueueItemsTracker.containsQueueItemsForEntityAndOperation(rootEntity, IndexingOperation.INDEX, 1);
Assert.assertTrue(enqueued);
}

@Test
@DisplayName("Update of indexed value within local embedded property leads to queue item enqueueing (Hard Delete)")
public void updateIndexedValueWithinLocalEmbeddedPropertyHardDelete() {
TestEmbeddableEntity embedded = metadata.create(TestEmbeddableEntity.class);
embedded.setEnumValue(TestEnum.OPEN);
embedded.setTextValue("V1");
embedded.setIntValue(1);

TestEmbTrackRootEntityHD rootEntity = metadata.create(TestEmbTrackRootEntityHD.class);
rootEntity.setTextValue("V1");
rootEntity.setEmbedded(embedded);

dataManager.save(rootEntity);

indexingQueueItemsTracker.clear();

rootEntity = dataManager.load(Id.of(rootEntity)).one();
rootEntity.getEmbedded().setTextValue("V2");
dataManager.save(rootEntity);

boolean enqueued = indexingQueueItemsTracker.containsQueueItemsForEntityAndOperation(rootEntity, IndexingOperation.INDEX, 1);
Assert.assertTrue(enqueued);
}

@Test
@DisplayName("Update of not-indexed local property of indexed entity doesn't lead to queue item enqueueing (Soft Delete)")
public void updateNotIndexedLocalPropertyOfIndexedEntity() {
TestEmbTrackRootEntity rootEntity = metadata.create(TestEmbTrackRootEntity.class);
rootEntity.setTextValue("V1");

dataManager.save(rootEntity);

indexingQueueItemsTracker.clear();

rootEntity = dataManager.load(Id.of(rootEntity)).one();
rootEntity.setTextValue("V2");
dataManager.save(rootEntity);

boolean enqueued = indexingQueueItemsTracker.containsQueueItemsForEntityAndOperation(rootEntity, IndexingOperation.INDEX, 0);
Assert.assertTrue(enqueued);
}

@Test
@DisplayName("Update of not-indexed local property of indexed entity doesn't lead to queue item enqueueing (Hard Delete)")
public void updateNotIndexedLocalPropertyOfIndexedEntityHardDelete() {
TestEmbTrackRootEntityHD rootEntity = metadata.create(TestEmbTrackRootEntityHD.class);
rootEntity.setTextValue("V1");

dataManager.save(rootEntity);

indexingQueueItemsTracker.clear();

rootEntity = dataManager.load(Id.of(rootEntity)).one();
rootEntity.setTextValue("V2");
dataManager.save(rootEntity);

boolean enqueued = indexingQueueItemsTracker.containsQueueItemsForEntityAndOperation(rootEntity, IndexingOperation.INDEX, 0);
Assert.assertTrue(enqueued);
}

@Test
@DisplayName("Update of not-indexed value within local embedded property of indexed entity doesn't lead to queue item enqueueing (Soft Delete)")
public void updateNotIndexedValueWithinLocalEmbeddedPropertyOfIndexedEntity() {
TestEmbeddableEntity embedded = metadata.create(TestEmbeddableEntity.class);
embedded.setEnumValue(TestEnum.OPEN);
embedded.setTextValue("V1");
embedded.setIntValue(1);

TestEmbTrackRootEntity rootEntity = metadata.create(TestEmbTrackRootEntity.class);
rootEntity.setTextValue("V1");
rootEntity.setEmbedded(embedded);

dataManager.save(rootEntity);

indexingQueueItemsTracker.clear();

rootEntity = dataManager.load(Id.of(rootEntity)).one();
rootEntity.getEmbedded().setEnumValue(TestEnum.CLOSED);
dataManager.save(rootEntity);

boolean enqueued = indexingQueueItemsTracker.containsQueueItemsForEntityAndOperation(rootEntity, IndexingOperation.INDEX, 0);
Assert.assertTrue(enqueued);
}

@Test
@DisplayName("Update of not-indexed value within local embedded property of indexed entity doesn't lead to queue item enqueueing (Hard Delete)")
public void updateNotIndexedValueWithinLocalEmbeddedPropertyOfIndexedEntityHardDelete() {
TestEmbeddableEntity embedded = metadata.create(TestEmbeddableEntity.class);
embedded.setEnumValue(TestEnum.OPEN);
embedded.setTextValue("V1");
embedded.setIntValue(1);

TestEmbTrackRootEntityHD rootEntity = metadata.create(TestEmbTrackRootEntityHD.class);
rootEntity.setTextValue("V1");
rootEntity.setEmbedded(embedded);

dataManager.save(rootEntity);

indexingQueueItemsTracker.clear();

rootEntity = dataManager.load(Id.of(rootEntity)).one();
rootEntity.getEmbedded().setEnumValue(TestEnum.CLOSED);
dataManager.save(rootEntity);

boolean enqueued = indexingQueueItemsTracker.containsQueueItemsForEntityAndOperation(rootEntity, IndexingOperation.INDEX, 0);
Assert.assertTrue(enqueued);
}

@Test
@DisplayName("Deletion of indexed entity leads to queue item enqueueing (Soft Delete)")
public void deleteIndexedEntity() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ public interface TestEmbTrackRootEntityHDIndexDefinition {

@AutoMappedField(includeProperties = {
"name",
"textValue",
"embedded.textValue",
"references.name",
"references.textValue",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public interface TestEmbTrackRootEntityIndexDefinition {

@AutoMappedField(includeProperties = {
"name",
"textValue",
"embedded.textValue",
"references.name",
"references.textValue",
Expand Down

0 comments on commit 298b745

Please sign in to comment.