package com.constellio.model.services.records; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.List; import org.junit.Before; import org.junit.Test; import com.constellio.data.dao.dto.records.RecordDTO; import com.constellio.data.dao.services.bigVault.RecordDaoException.NoSuchRecordWithId; import com.constellio.model.entities.Taxonomy; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.Transaction; import com.constellio.model.entities.schemas.Schemas; import com.constellio.model.services.records.reindexing.ReindexationMode; import com.constellio.model.services.schemas.MetadataSchemasManager; import com.constellio.model.services.schemas.builders.MetadataSchemaBuilder; import com.constellio.model.services.schemas.builders.MetadataSchemaTypeBuilder; import com.constellio.model.services.schemas.builders.MetadataSchemaTypesBuilder; import com.constellio.sdk.tests.ConstellioTest; import com.constellio.sdk.tests.TestRecord; import com.constellio.sdk.tests.schemas.MetadataSchemaTypesConfigurator; import com.constellio.sdk.tests.schemas.TestsSchemasSetup; import com.constellio.sdk.tests.schemas.TestsSchemasSetup.AnotherSchemaMetadatas; import com.constellio.sdk.tests.schemas.TestsSchemasSetup.ZeSchemaMetadatas; import com.constellio.sdk.tests.setups.Users; public class CounterIndexAcceptanceTest extends ConstellioTest { List<String> noAncestors = new ArrayList<>(); String childOfReference = "childOfReference"; String anotherSchemaReferenceToItself = "anotherSchemaReferenceToItself"; String anotherSchemaReferenceToZeSchema = "anotherSchemaReferenceToZeSchema"; String zeSchemaReferenceToItself = "zeSchemaReferenceToItself"; TestsSchemasSetup zeCollectionSetup = new TestsSchemasSetup(zeCollection); ZeSchemaMetadatas zeCollectionSchema = zeCollectionSetup.new ZeSchemaMetadatas(); AnotherSchemaMetadatas anotherCollectionSchema = zeCollectionSetup.new AnotherSchemaMetadatas(); RecordServices recordServices; Users users = new Users(); @Before public void setUp() throws Exception { givenDisabledAfterTestValidations(); prepareSystem( withZeCollection().withAllTest(users) ); inCollection(zeCollection).giveWriteAccessTo(dakota, edouard); recordServices = getModelLayerFactory().newRecordServices(); } @Test public void givenASchemasWithParentRelationshipWhenARecordIsMovedThenCounterIndexNotModifiedSinceTheParentChildRelationIsExcluded_singlevalued() throws Exception { defineSchemasManager().using(zeCollectionSetup.with(childOfReferenceToSelfAndAnotherReferenceToSelf(false, false))); Transaction transaction = new Transaction(); transaction.add(new TestRecord(zeCollectionSchema, "record1")); transaction.add(new TestRecord(zeCollectionSchema, "record2")); Record record3 = transaction.add(new TestRecord(zeCollectionSchema, "record3")) .set(zeCollectionSchema.metadata(childOfReference), "record1"); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record1", 0, noAncestors); assertCounterIndexForRecordWithValue("record2", 0, noAncestors); assertCounterIndexForRecordWithValue("record3", 0, asList("record1")); recordServices.update(record3.set(zeCollectionSchema.metadata(childOfReference), "record2")); assertCounterIndexForRecordWithValue("record1", 0, noAncestors); assertCounterIndexForRecordWithValue("record2", 0, noAncestors); assertCounterIndexForRecordWithValue("record3", 0, asList("record2")); } @Test public void givenASchemasWithParentRelationshipWhenARecordIsMovedThenCounterIndexNotModifiedSinceTheParentChildRelationIsExcluded_multivalued() throws Exception { defineSchemasManager().using(zeCollectionSetup.with(childOfReferenceToSelfAndAnotherReferenceToSelf(false, true))); Transaction transaction = new Transaction(); transaction.add(new TestRecord(zeCollectionSchema, "record1")); transaction.add(new TestRecord(zeCollectionSchema, "record2")); Record record3 = transaction.add(new TestRecord(zeCollectionSchema, "record3")) .set(zeCollectionSchema.metadata(childOfReference), "record1"); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record1", 0, noAncestors); assertCounterIndexForRecordWithValue("record2", 0, noAncestors); assertCounterIndexForRecordWithValue("record3", 0, asList("record1")); recordServices.update(record3.set(zeCollectionSchema.metadata(childOfReference), "record2")); assertCounterIndexForRecordWithValue("record1", 0, noAncestors); assertCounterIndexForRecordWithValue("record2", 0, noAncestors); assertCounterIndexForRecordWithValue("record3", 0, asList("record2")); } @Test public void givenTwoSchemasWithParentRelationshipWhenARecordIsMovedThenCounterIndexNotModifiedSinceTheParentChildRelationIsExcluded_singlevalued() throws Exception { defineSchemasManager().using(zeCollectionSetup.with(childOfReferenceToSelfAndAnotherReferenceToSelf(false, false))); Transaction transaction = new Transaction(); transaction.add(new TestRecord(zeCollectionSchema, "record1")); transaction.add(new TestRecord(zeCollectionSchema, "record2")); Record record3 = transaction.add(new TestRecord(anotherCollectionSchema, "record3")) .set(anotherCollectionSchema.metadata(childOfReference), "record1"); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record1", 0, noAncestors); assertCounterIndexForRecordWithValue("record2", 0, noAncestors); assertCounterIndexForRecordWithValue("record3", 0, asList("record1")); recordServices.update(record3.set(anotherCollectionSchema.metadata(childOfReference), "record2")); assertCounterIndexForRecordWithValue("record1", 0, noAncestors); assertCounterIndexForRecordWithValue("record2", 0, noAncestors); assertCounterIndexForRecordWithValue("record3", 0, asList("record2")); } @Test public void givenASchemasWithTaxonomyRelationshipWhenARecordIsMovedThenCounterIndexNotModifiedSinceTheParentChildRelationIsExcluded_singlevalued() throws Exception { defineSchemasManager().using(zeCollectionSetup.with(childOfReferenceToSelfAndAnotherReferenceToSelf(true, false))); MetadataSchemasManager manager = getModelLayerFactory().getMetadataSchemasManager(); getModelLayerFactory().getTaxonomiesManager() .addTaxonomy(new Taxonomy("ze", "ze", zeCollection, zeCollectionSchema.typeCode()), manager); Transaction transaction = new Transaction(); Record record0 = transaction.add(new TestRecord(zeCollectionSchema, "record0")); Record record1 = transaction.add(new TestRecord(zeCollectionSchema, "record1")); Record record2 = transaction.add(new TestRecord(zeCollectionSchema, "record2")); Record record3 = transaction.add(new TestRecord(anotherCollectionSchema, "record3")) .set(anotherCollectionSchema.metadata(childOfReference), "record1") .set(anotherCollectionSchema.metadata(anotherSchemaReferenceToZeSchema), "record0"); Record record4 = transaction.add(new TestRecord(anotherCollectionSchema, "record4")) .set(anotherCollectionSchema.metadata(anotherSchemaReferenceToItself), "record3"); Record record5 = transaction.add(new TestRecord(zeCollectionSchema, "record5")) .set(zeCollectionSchema.metadata(zeSchemaReferenceToItself), "record2"); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 1, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record1")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); recordServices.update(record3.set(anotherCollectionSchema.metadata(childOfReference), "record2")); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 0, asList("ze")); assertCounterIndexForRecordWithValue("record2", 2, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record2")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); transaction = new Transaction(); transaction.update(record3.set(anotherCollectionSchema.metadata(childOfReference), "record1")); transaction.update(record1.set(Schemas.TITLE, "New title!")); transaction.update(record2.set(Schemas.TITLE, "New title!")); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 1, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record1")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); recordServices.update(record3.set(Schemas.TITLE, "New title!")); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 1, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record1")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); recordServices.update(record3.set(anotherCollectionSchema.metadata(childOfReference), null)); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 0, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, noAncestors); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); } @Test public void givenASchemasWithTaxonomyRelationshipWhenARecordIsMovedThenCounterIndexNotModifiedSinceTheParentChildRelationIsExcluded_multivalued() throws Exception { defineSchemasManager().using(zeCollectionSetup.with(childOfReferenceToSelfAndAnotherReferenceToSelf(true, true))); MetadataSchemasManager manager = getModelLayerFactory().getMetadataSchemasManager(); getModelLayerFactory().getTaxonomiesManager() .addTaxonomy(new Taxonomy("ze", "ze", zeCollection, zeCollectionSchema.typeCode()), manager); Transaction transaction = new Transaction(); Record record0 = transaction.add(new TestRecord(zeCollectionSchema, "record0")); Record record1 = transaction.add(new TestRecord(zeCollectionSchema, "record1")); Record record2 = transaction.add(new TestRecord(zeCollectionSchema, "record2")); Record record3 = transaction.add(new TestRecord(anotherCollectionSchema, "record3")) .set(anotherCollectionSchema.metadata(childOfReference), asList("record1", "record1")) .set(anotherCollectionSchema.metadata(anotherSchemaReferenceToZeSchema), "record0"); Record record4 = transaction.add(new TestRecord(anotherCollectionSchema, "record4")) .set(anotherCollectionSchema.metadata(anotherSchemaReferenceToItself), "record3"); Record record5 = transaction.add(new TestRecord(zeCollectionSchema, "record5")) .set(zeCollectionSchema.metadata(zeSchemaReferenceToItself), "record2"); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 1, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record1")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); recordServices.update(record3.set(anotherCollectionSchema.metadata(childOfReference), asList("record1"))); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 1, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record1")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); recordServices.update(record3.set(anotherCollectionSchema.metadata(childOfReference), asList("record2", "record2"))); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 0, asList("ze")); assertCounterIndexForRecordWithValue("record2", 2, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record2")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); transaction = new Transaction(); transaction.update(record3.set(anotherCollectionSchema.metadata(childOfReference), asList("record1"))); transaction.update(record1.set(Schemas.TITLE, "New title!")); transaction.update(record2.set(Schemas.TITLE, "New title!")); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 1, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record1")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); transaction = new Transaction(); transaction.update(record3.set(anotherCollectionSchema.metadata(childOfReference), asList("record1", "record1"))); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 1, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record1")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); recordServices.update(record3.set(Schemas.TITLE, "New title!")); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 1, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, asList("ze", "record1")); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); recordServices.update(record3.set(anotherCollectionSchema.metadata(childOfReference), new ArrayList<>())); assertCounterIndexForRecordWithValue("record0", 1, asList("ze")); assertCounterIndexForRecordWithValue("record1", 0, asList("ze")); assertCounterIndexForRecordWithValue("record2", 1, asList("ze")); assertCounterIndexForRecordWithValue("record3", 1, noAncestors); assertCounterIndexForRecordWithValue("record4", 0, noAncestors); assertCounterIndexForRecordWithValue("record5", 0, asList("ze")); } @Test public void givenASchemasWithPrincipalTaxonomyRelationshipWhenARecordIsMovedThenCounterIndexNotModifiedSinceTheParentChildRelationIsExcluded_singlevalued() throws Exception { defineSchemasManager().using(zeCollectionSetup.with(childOfReferenceToSelfAndAnotherReferenceToSelf(true, false))); MetadataSchemasManager manager = getModelLayerFactory().getMetadataSchemasManager(); Taxonomy taxonomy = new Taxonomy("ze", "ze", zeCollection, zeCollectionSchema.typeCode()); getModelLayerFactory().getTaxonomiesManager().addTaxonomy(taxonomy, manager); getModelLayerFactory().getTaxonomiesManager().setPrincipalTaxonomy(taxonomy, manager); Transaction transaction = new Transaction(); Record record1 = transaction.add(new TestRecord(zeCollectionSchema, "record1")); Record record2 = transaction.add(new TestRecord(zeCollectionSchema, "record2")); Record record3 = transaction.add(new TestRecord(anotherCollectionSchema, "record3")) .set(anotherCollectionSchema.metadata(childOfReference), "record1"); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record1", 0, asList("ze")); assertCounterIndexForRecordWithValue("record2", 0, asList("ze")); assertCounterIndexForRecordWithValue("record3", 0, asList("ze", "record1")); recordServices.update(record3.set(anotherCollectionSchema.metadata(childOfReference), "record2")); assertCounterIndexForRecordWithValue("record1", 0, asList("ze")); assertCounterIndexForRecordWithValue("record2", 0, asList("ze")); assertCounterIndexForRecordWithValue("record3", 0, asList("ze", "record2")); transaction = new Transaction(); transaction.update(record3.set(anotherCollectionSchema.metadata(childOfReference), "record1")); transaction.update(record1.set(Schemas.TITLE, "New title!")); transaction.update(record2.set(Schemas.TITLE, "New title!")); recordServices.execute(transaction); assertCounterIndexForRecordWithValue("record1", 0, asList("ze")); assertCounterIndexForRecordWithValue("record2", 0, asList("ze")); assertCounterIndexForRecordWithValue("record3", 0, asList("ze", "record1")); recordServices.update(record3.set(Schemas.TITLE, "New title!")); assertCounterIndexForRecordWithValue("record1", 0, asList("ze")); assertCounterIndexForRecordWithValue("record2", 0, asList("ze")); assertCounterIndexForRecordWithValue("record3", 0, asList("ze", "record1")); recordServices.update(record3.set(anotherCollectionSchema.metadata(childOfReference), null)); assertCounterIndexForRecordWithValue("record1", 0, asList("ze")); assertCounterIndexForRecordWithValue("record2", 0, asList("ze")); assertCounterIndexForRecordWithValue("record3", 0, noAncestors); } @Test public void givenModificationsToRecordsThenCounterIndexUpdated() throws Exception { defineSchemasManager().using(zeCollectionSetup.withAStringMetadata()); Record zeRecord = new TestRecord(zeCollectionSchema, "zeRecord"); zeRecord.set(zeCollectionSchema.stringMetadata(), "1"); recordServices.add(zeRecord); assertCounterIndexForRecordWithValue(users.dakotaIn(zeCollection).getId(), 0, noAncestors); assertCounterIndexForRecordWithValue(users.bobIn(zeCollection).getId(), 0, noAncestors); Transaction transaction = new Transaction().setUser(users.dakotaLIndienIn(zeCollection)); zeRecord.set(zeCollectionSchema.stringMetadata(), "2"); transaction.add(zeRecord); recordServices.execute(transaction); assertThat(withId("zeRecord").get(Schemas.MODIFIED_BY)).isEqualTo(users.dakotaIn(zeCollection).getId()); assertCounterIndexForRecordWithValue(users.dakotaIn(zeCollection).getId(), 1, noAncestors); assertCounterIndexForRecordWithValue(users.edouardIn(zeCollection).getId(), 0, noAncestors); transaction = new Transaction().setUser(users.edouardIn(zeCollection)); zeRecord.set(zeCollectionSchema.stringMetadata(), "3"); transaction.add(zeRecord); recordServices.execute(transaction); assertThat(withId("zeRecord").get(Schemas.MODIFIED_BY)).isEqualTo(users.edouardIn(zeCollection).getId()); assertCounterIndexForRecordWithValue(users.dakotaIn(zeCollection).getId(), 0, noAncestors); assertCounterIndexForRecordWithValue(users.edouardIn(zeCollection).getId(), 1, noAncestors); transaction = new Transaction().setUser(null); zeRecord.set(zeCollectionSchema.stringMetadata(), "4"); transaction.add(zeRecord); recordServices.execute(transaction); assertThat(withId("zeRecord").get(Schemas.MODIFIED_BY)).isNull(); assertCounterIndexForRecordWithValue(users.dakotaIn(zeCollection).getId(), 0, noAncestors); assertCounterIndexForRecordWithValue(users.edouardIn(zeCollection).getId(), 0, noAncestors); getModelLayerFactory().newReindexingServices().reindexCollections(ReindexationMode.RECALCULATE_AND_REWRITE); assertCounterIndexForRecordWithValue(users.dakotaIn(zeCollection).getId(), 0, noAncestors); assertCounterIndexForRecordWithValue(users.edouardIn(zeCollection).getId(), 0, noAncestors); } //TODO Test with multivalue private void assertCounterIndexForRecordWithValue(String recordId, double expectedValue, List<String> expectedAncestors) { try { RecordDTO recordDTO = getDataLayerFactory().newRecordDao().get("idx_rfc_" + recordId); Double wasValue = (Double) recordDTO.getFields().get("refs_d"); assertThat(wasValue).isEqualTo(expectedValue); List<String> ancestors = (List) recordDTO.getFields().get("ancestors_ss"); if (ancestors == null) { ancestors = new ArrayList<>(); } assertThat(ancestors).isEqualTo(expectedAncestors); } catch (NoSuchRecordWithId noSuchRecordWithId) { fail("No counter index for record id '" + recordId + "'"); } } private MetadataSchemaTypesConfigurator childOfReferenceToSelfAndAnotherReferenceToSelf(final boolean taxonomyRelation, final boolean multivalued) { return new MetadataSchemaTypesConfigurator() { @Override public void configure(MetadataSchemaTypesBuilder schemaTypes) { MetadataSchemaTypeBuilder zeSchemaType = schemaTypes.getSchemaType("zeSchemaType"); MetadataSchemaTypeBuilder anotherSchemaType = schemaTypes.getSchemaType("anotherSchemaType"); MetadataSchemaBuilder zeSchema = zeSchemaType.getDefaultSchema(); MetadataSchemaBuilder anotherSchema = anotherSchemaType.getDefaultSchema(); zeSchema.create(childOfReference).defineChildOfRelationshipToType(zeSchemaType); zeSchema.create(zeSchemaReferenceToItself).defineReferencesTo(zeSchemaType); anotherSchema.create(anotherSchemaReferenceToItself).defineReferencesTo(anotherSchemaType); anotherSchema.create(anotherSchemaReferenceToZeSchema).defineReferencesTo(zeSchemaType); if (taxonomyRelation) { anotherSchema.create(childOfReference).defineTaxonomyRelationshipToType(zeSchemaType) .setMultivalue(multivalued); } else { anotherSchema.create(childOfReference).defineChildOfRelationshipToType(zeSchemaType); } } }; } }