From aa7ef2250cc5d32a491314d50cc298347b57a93d Mon Sep 17 00:00:00 2001 From: Ragnar Mellbin Date: Mon, 14 May 2018 17:02:59 +0200 Subject: [PATCH] Test and fix supplied index provider --- .../checking/index/IndexAccessors.java | 4 +- .../full/FullCheckIntegrationTest.java | 9 +- .../internal/kernel/api/SchemaWrite.java | 26 +++++ .../neo4j/kernel/api/KernelTransaction.java | 5 +- .../neo4j/kernel/api/index/IndexProvider.java | 10 +- .../schema/index/StoreIndexDescriptor.java | 3 +- .../api/KernelTransactionImplementation.java | 4 +- .../impl/api/index/IndexProviderMap.java | 44 ++++++- .../impl/api/index/IndexProxyCreator.java | 4 +- .../impl/api/index/IndexingService.java | 4 +- .../api/state/ConstraintIndexCreator.java | 17 +-- .../neo4j/kernel/impl/newapi/Operations.java | 31 +++-- .../recordstorage/RecordStorageEngine.java | 2 +- .../state/DefaultIndexProviderMap.java | 43 +++++-- .../internal/BatchInserterImpl.java | 6 +- .../builtinprocs/StubKernelTransaction.java | 2 +- .../ConstraintIndexCreatorTest.java | 49 ++++++-- .../neo4j/kernel/impl/api/index/IndexIT.java | 3 +- .../KernelIntegrationTest.java | 7 +- .../impl/newapi/OperationsLockTest.java | 4 +- .../state/DefaultIndexProviderMapTest.java | 5 +- .../impl/index/schema/IndexCreateIT.java | 109 ++++++++++++++++++ .../neo4j/locking/QueryExecutionLocksIT.java | 4 +- .../builtinprocs/StubKernelTransaction.java | 2 +- .../index/schema/IndexCreateEnterpriseIT.java | 52 +++++++++ 25 files changed, 370 insertions(+), 79 deletions(-) create mode 100644 community/neo4j/src/test/java/org/neo4j/kernel/impl/index/schema/IndexCreateIT.java create mode 100644 enterprise/neo4j-enterprise/src/test/java/org/neo4j/kernel/impl/index/schema/IndexCreateEnterpriseIT.java diff --git a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/index/IndexAccessors.java b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/index/IndexAccessors.java index e5817867464f8..0b47fd19c50a2 100644 --- a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/index/IndexAccessors.java +++ b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/index/IndexAccessors.java @@ -32,12 +32,12 @@ import org.neo4j.internal.kernel.api.InternalIndexState; import org.neo4j.kernel.api.index.IndexAccessor; import org.neo4j.kernel.api.index.IndexProvider; +import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; import org.neo4j.kernel.impl.api.index.IndexProviderMap; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; import org.neo4j.kernel.impl.store.RecordStore; import org.neo4j.kernel.impl.store.SchemaStorage; import org.neo4j.kernel.impl.store.record.DynamicRecord; -import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; public class IndexAccessors implements Closeable { @@ -98,7 +98,7 @@ public IndexAccessors( IndexProviderMap providers, private IndexProvider provider( IndexProviderMap providers, StoreIndexDescriptor indexRule ) { - return providers.apply( indexRule.providerDescriptor() ); + return providers.lookup( indexRule.providerDescriptor() ); } public Collection notOnlineRules() diff --git a/community/consistency-check/src/test/java/org/neo4j/consistency/checking/full/FullCheckIntegrationTest.java b/community/consistency-check/src/test/java/org/neo4j/consistency/checking/full/FullCheckIntegrationTest.java index 5c1e487a095de..c65270a3f259e 100644 --- a/community/consistency-check/src/test/java/org/neo4j/consistency/checking/full/FullCheckIntegrationTest.java +++ b/community/consistency-check/src/test/java/org/neo4j/consistency/checking/full/FullCheckIntegrationTest.java @@ -73,9 +73,7 @@ import org.neo4j.kernel.api.labelscan.LabelScanStore; import org.neo4j.kernel.api.labelscan.LabelScanWriter; import org.neo4j.kernel.api.labelscan.NodeLabelUpdate; -import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptorFactory; -import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.annotations.Documented; @@ -138,7 +136,6 @@ import static org.neo4j.kernel.api.schema.SchemaDescriptorFactory.forLabel; import static org.neo4j.kernel.api.schema.index.IndexDescriptorFactory.forSchema; import static org.neo4j.kernel.api.schema.index.IndexDescriptorFactory.uniqueForSchema; -import static org.neo4j.kernel.api.schema.index.TestIndexDescriptorFactory.uniqueForLabel; import static org.neo4j.kernel.impl.store.AbstractDynamicStore.readFullByteArrayFromHeavyRecords; import static org.neo4j.kernel.impl.store.DynamicArrayStore.allocateFromNumbers; import static org.neo4j.kernel.impl.store.DynamicArrayStore.getRightArray; @@ -456,7 +453,7 @@ public void shouldNotReportIndexInconsistenciesIfIndexIsFailed() throws Exceptio { StoreIndexDescriptor rule = rules.next(); IndexSamplingConfig samplingConfig = new IndexSamplingConfig( Config.defaults() ); - IndexPopulator populator = storeAccess.indexes().apply( rule.providerDescriptor() ) + IndexPopulator populator = storeAccess.indexes().lookup( rule.providerDescriptor() ) .getPopulator( rule, samplingConfig ); populator.markAsFailed( "Oh noes! I was a shiny index and then I was failed" ); populator.close( false ); @@ -566,7 +563,7 @@ public void shouldReportNodesThatAreNotIndexed() throws Exception { StoreIndexDescriptor indexDescriptor = indexDescriptorIterator.next(); IndexAccessor accessor = fixture.directStoreAccess().indexes(). - apply( indexDescriptor.providerDescriptor() ).getOnlineAccessor( indexDescriptor, samplingConfig ); + lookup( indexDescriptor.providerDescriptor() ).getOnlineAccessor( indexDescriptor, samplingConfig ); try ( IndexUpdater updater = accessor.newUpdater( IndexUpdateMode.ONLINE ) ) { for ( long nodeId : indexedNodes ) @@ -600,7 +597,7 @@ public void shouldReportNodesWithDuplicatePropertyValueInUniqueIndex() throws Ex while ( indexRuleIterator.hasNext() ) { StoreIndexDescriptor indexRule = indexRuleIterator.next(); - IndexAccessor accessor = fixture.directStoreAccess().indexes().apply( indexRule.providerDescriptor() ) + IndexAccessor accessor = fixture.directStoreAccess().indexes().lookup( indexRule.providerDescriptor() ) .getOnlineAccessor( indexRule, samplingConfig ); IndexUpdater updater = accessor.newUpdater( IndexUpdateMode.ONLINE ); updater.process( IndexEntryUpdate.add( 42, indexRule.schema(), values( indexRule ) ) ); diff --git a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaWrite.java b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaWrite.java index 7058b2f4a2d56..b710b115d1fc5 100644 --- a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaWrite.java +++ b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaWrite.java @@ -40,6 +40,14 @@ public interface SchemaWrite */ IndexReference indexCreate( SchemaDescriptor descriptor ) throws SchemaKernelException; + /** + * Create index from schema descriptor + * + * @param descriptor description of the index + * @param provider name of the desired index provider implementation + * @param name name of the index + * @return the newly created index + */ IndexReference indexCreate( SchemaDescriptor descriptor, Optional provider, Optional name ) throws SchemaKernelException; @@ -58,6 +66,15 @@ IndexReference indexCreate( SchemaDescriptor descriptor, */ ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor descriptor ) throws SchemaKernelException; + /** + * Create unique property constraint + * + * @param descriptor description of the constraint + * @param provider name of the desired index provider implementation + */ + ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor descriptor, + Optional provider ) throws SchemaKernelException; + /** * Create node key constraint * @@ -65,6 +82,15 @@ IndexReference indexCreate( SchemaDescriptor descriptor, */ ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descriptor ) throws SchemaKernelException; + /** + * Create node key constraint + * + * @param descriptor description of the constraint + * @param provider name of the desired index provider implementation + */ + ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descriptor, + Optional provider ) throws SchemaKernelException; + /** * Create node property existence constraint * diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/KernelTransaction.java b/community/kernel/src/main/java/org/neo4j/kernel/api/KernelTransaction.java index c06e8f68c3bcf..edf1bcd80b214 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/KernelTransaction.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/KernelTransaction.java @@ -19,6 +19,8 @@ */ package org.neo4j.kernel.api; +import java.util.Optional; + import org.neo4j.graphdb.NotInTransactionException; import org.neo4j.internal.kernel.api.NodeCursor; import org.neo4j.internal.kernel.api.PropertyCursor; @@ -59,9 +61,10 @@ interface CloseListener * Create unique index which will be used to support uniqueness constraint. * * @param schema schema to create unique index for. + * @param provider * @return IndexDescriptor for the index to be created. */ - IndexDescriptor indexUniqueCreate( SchemaDescriptor schema ); + IndexDescriptor indexUniqueCreate( SchemaDescriptor schema, Optional provider ); /** * @return the security context this transaction is currently executing in. diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/index/IndexProvider.java b/community/kernel/src/main/java/org/neo4j/kernel/api/index/IndexProvider.java index 7d0131b140271..72fcd0d45101a 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/index/IndexProvider.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/index/IndexProvider.java @@ -26,8 +26,8 @@ import org.neo4j.internal.kernel.api.InternalIndexState; import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.pagecache.PageCache; -import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; import org.neo4j.kernel.api.schema.index.IndexDescriptor; +import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; import org.neo4j.kernel.impl.api.index.IndexingService; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; import org.neo4j.kernel.impl.storemigration.StoreMigrationParticipant; @@ -303,6 +303,14 @@ public String getVersion() return version; } + /** + * @return a combination of {@link #getKey()} and {@link #getVersion()} with a '-' in between. + */ + public String name() + { + return key + "-" + version; + } + @Override public int hashCode() { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/schema/index/StoreIndexDescriptor.java b/community/kernel/src/main/java/org/neo4j/kernel/api/schema/index/StoreIndexDescriptor.java index cff3d2eed9323..e1e1e18b557bf 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/schema/index/StoreIndexDescriptor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/schema/index/StoreIndexDescriptor.java @@ -21,7 +21,6 @@ import org.neo4j.graphdb.Label; import org.neo4j.internal.kernel.api.IndexCapability; -import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.impl.api.index.IndexProviderMap; import org.neo4j.storageengine.api.schema.SchemaRule; @@ -137,7 +136,7 @@ public CapableIndexDescriptor withoutCapabilities() public CapableIndexDescriptor withCapabilities( IndexProviderMap indexProviderMap ) { - IndexCapability capability = indexProviderMap.apply( providerDescriptor ).getCapability(); + IndexCapability capability = indexProviderMap.lookup( providerDescriptor ).getCapability(); return new CapableIndexDescriptor( this, capability ); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementation.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementation.java index 5705bf6d1029d..fdcf45093424a 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementation.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementation.java @@ -396,9 +396,9 @@ public KernelStatement acquireStatement() } @Override - public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema ) + public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema, Optional provider ) { - return operations.indexUniqueCreate( schema ); + return operations.indexUniqueCreate( schema, provider ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderMap.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderMap.java index 217a6ca39d512..fdd61d248db5d 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderMap.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProviderMap.java @@ -20,23 +20,57 @@ package org.neo4j.kernel.impl.api.index; import java.util.function.Consumer; -import java.util.function.Function; import org.neo4j.kernel.api.index.IndexProvider; -public interface IndexProviderMap extends Function +/** + * Contains mapping from {@link IndexProvider.Descriptor} or provider name to {@link IndexProvider}. + */ +public interface IndexProviderMap { - @Override - IndexProvider apply( IndexProvider.Descriptor descriptor ) throws IndexProviderNotFoundException; + /** + * Looks up and returns the {@link IndexProvider} for the given {@link IndexProvider.Descriptor}. + * + * @param providerDescriptor the descriptor identifying the {@link IndexProvider}. + * @return the {@link IndexProvider} with the given {@link IndexProvider.Descriptor}. + * @throws IndexProviderNotFoundException if no such {@link IndexProvider} was found. + */ + IndexProvider lookup( IndexProvider.Descriptor providerDescriptor ) throws IndexProviderNotFoundException; + + /** + * Looks up and returns the {@link IndexProvider} for the given index provider name. The name is what + * an {@link IndexProvider.Descriptor#name()} call would return. + * + * @param providerDescriptorName the descriptor name identifying the {@link IndexProvider}. + * @return the {@link IndexProvider} with the given name. + * @throws IndexProviderNotFoundException if no such {@link IndexProvider} was found. + */ + IndexProvider lookup( String providerDescriptorName ) throws IndexProviderNotFoundException; + /** + * There's always a default {@link IndexProvider}, this method returns it. + * + * @return the default index provider for this instance. + */ IndexProvider getDefaultProvider(); + /** + * Visits all the {@link IndexProvider} with the visitor. + * + * @param visitor {@link Consumer} visiting all the {@link IndexProvider index providers} in this map. + */ void accept( Consumer visitor ); IndexProviderMap EMPTY = new IndexProviderMap() { @Override - public IndexProvider apply( IndexProvider.Descriptor descriptor ) throws IndexProviderNotFoundException + public IndexProvider lookup( IndexProvider.Descriptor descriptor ) throws IndexProviderNotFoundException + { + return IndexProvider.EMPTY; + } + + @Override + public IndexProvider lookup( String providerDescriptorName ) throws IndexProviderNotFoundException { return IndexProvider.EMPTY; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProxyCreator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProxyCreator.java index 01faa9fd8d6d0..d7d4988131078 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProxyCreator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexProxyCreator.java @@ -145,13 +145,13 @@ private String indexUserDescription( final StoreIndexDescriptor descriptor ) private IndexPopulator populatorFromProvider( StoreIndexDescriptor descriptor, IndexSamplingConfig samplingConfig ) { - IndexProvider indexProvider = providerMap.apply( descriptor.providerDescriptor() ); + IndexProvider indexProvider = providerMap.lookup( descriptor.providerDescriptor() ); return indexProvider.getPopulator( descriptor, samplingConfig ); } private IndexAccessor onlineAccessorFromProvider( StoreIndexDescriptor descriptor, IndexSamplingConfig samplingConfig ) throws IOException { - IndexProvider indexProvider = providerMap.apply( descriptor.providerDescriptor() ); + IndexProvider indexProvider = providerMap.lookup( descriptor.providerDescriptor() ); return indexProvider.getOnlineAccessor( descriptor, samplingConfig ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexingService.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexingService.java index e53f83abcca8e..fbb1e8401cafb 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexingService.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/IndexingService.java @@ -54,11 +54,11 @@ import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.api.index.IndexUpdater; import org.neo4j.kernel.api.schema.index.IndexDescriptor; +import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; import org.neo4j.kernel.impl.api.SchemaState; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingController; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingMode; import org.neo4j.kernel.impl.store.UnderlyingStorageException; -import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; import org.neo4j.kernel.impl.transaction.state.IndexUpdates; import org.neo4j.kernel.lifecycle.LifecycleAdapter; import org.neo4j.logging.Log; @@ -202,7 +202,7 @@ public void init() IndexProxy indexProxy; IndexProvider.Descriptor providerDescriptor = indexDescriptor.providerDescriptor(); - IndexProvider provider = providerMap.apply( providerDescriptor ); + IndexProvider provider = providerMap.lookup( providerDescriptor ); InternalIndexState initialState = provider.getInitialState( indexDescriptor ); indexStates.computeIfAbsent( initialState, internalIndexState -> new ArrayList<>() ) .add( new IndexLogRecord( indexDescriptor ) ); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/ConstraintIndexCreator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/ConstraintIndexCreator.java index 8c604810e7a79..6182f641f5643 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/ConstraintIndexCreator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/ConstraintIndexCreator.java @@ -20,6 +20,7 @@ package org.neo4j.kernel.impl.api.state; import java.io.IOException; +import java.util.Optional; import java.util.function.Supplier; import org.neo4j.internal.kernel.api.IndexReference; @@ -89,8 +90,8 @@ public ConstraintIndexCreator( Supplier kernelSupplier, IndexingService * and this tx committed, which will create the uniqueness constraint * */ - public long createUniquenessConstraintIndex( KernelTransactionImplementation transaction, - SchemaDescriptor descriptor ) throws TransactionFailureException, CreateConstraintFailureException, + public long createUniquenessConstraintIndex( KernelTransactionImplementation transaction, SchemaDescriptor descriptor, Optional provider ) + throws TransactionFailureException, CreateConstraintFailureException, UniquePropertyValueValidationException, AlreadyConstrainedException { UniquenessConstraintDescriptor constraint = ConstraintDescriptorFactory.uniqueForSchema( descriptor ); @@ -99,7 +100,7 @@ public long createUniquenessConstraintIndex( KernelTransactionImplementation tra SchemaRead schemaRead = transaction.schemaRead(); try { - index = getOrCreateUniquenessConstraintIndex( schemaRead, transaction.tokenRead(), descriptor ); + index = getOrCreateUniquenessConstraintIndex( schemaRead, transaction.tokenRead(), descriptor, provider ); } catch ( AlreadyConstrainedException e ) { @@ -226,8 +227,8 @@ private void awaitConstrainIndexPopulation( UniquenessConstraintDescriptor const } } - private IndexReference getOrCreateUniquenessConstraintIndex( SchemaRead schemaRead, - TokenRead tokenRead, SchemaDescriptor schema ) + private IndexReference getOrCreateUniquenessConstraintIndex( SchemaRead schemaRead, TokenRead tokenRead, SchemaDescriptor schema, + Optional provider ) throws SchemaKernelException, IndexNotFoundKernelException { IndexReference descriptor = schemaRead.index( schema.keyId(), schema.getPropertyIds() ); @@ -250,19 +251,19 @@ private IndexReference getOrCreateUniquenessConstraintIndex( SchemaRead schemaRe // There's already an index for this schema descriptor, which isn't of the type we're after. throw new AlreadyIndexedException( schema, CONSTRAINT_CREATION ); } - IndexDescriptor indexDescriptor = createConstraintIndex( schema ); + IndexDescriptor indexDescriptor = createConstraintIndex( schema, provider ); IndexProxy indexProxy = indexingService.getIndexProxy( indexDescriptor.schema() ); return indexProxy.getDescriptor(); } - public IndexDescriptor createConstraintIndex( final SchemaDescriptor schema ) + public IndexDescriptor createConstraintIndex( final SchemaDescriptor schema, Optional provider ) { try ( Session session = kernelSupplier.get().beginSession( AUTH_DISABLED ); Transaction transaction = session.beginTransaction( Transaction.Type.implicit ); //TODO remove statement? Statement ignore = ((KernelTransaction)transaction).acquireStatement() ) { - IndexDescriptor index = ((KernelTransaction)transaction).indexUniqueCreate( schema ); + IndexDescriptor index = ((KernelTransaction) transaction).indexUniqueCreate( schema, provider ); transaction.success(); return index; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java index e5b13ba2a7bd7..40a565c513c16 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java @@ -72,7 +72,6 @@ import org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException; import org.neo4j.kernel.api.explicitindex.AutoIndexing; import org.neo4j.kernel.api.index.IndexProvider; -import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptorFactory; import org.neo4j.kernel.api.schema.constaints.IndexBackedConstraintDescriptor; import org.neo4j.kernel.api.schema.constaints.NodeKeyConstraintDescriptor; @@ -898,9 +897,9 @@ public IndexReference indexCreate( SchemaDescriptor descriptor, } // Note: this will be sneakily executed by an internal transaction, so no additional locking is required. - public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema ) + public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema, Optional provider ) { - IndexProvider.Descriptor providerDescriptor = ktx.indexProviderForOrDefault( Optional.empty() ); + IndexProvider.Descriptor providerDescriptor = ktx.indexProviderForOrDefault( provider ); IndexDescriptor index = IndexDescriptorFactory.uniqueForSchema( schema, Optional.empty(), @@ -944,6 +943,13 @@ public void indexDrop( IndexReference indexReference ) throws SchemaKernelExcept @Override public ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor descriptor ) throws SchemaKernelException + { + return uniquePropertyConstraintCreate( descriptor, Optional.empty() ); + } + + @Override + public ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor descriptor, Optional provider ) + throws SchemaKernelException { //Lock acquireExclusiveLabelLock( descriptor.keyId() ); @@ -957,12 +963,18 @@ public ConstraintDescriptor uniquePropertyConstraintCreate( SchemaDescriptor des assertIndexDoesNotExist( SchemaKernelException.OperationContext.CONSTRAINT_CREATION, descriptor ); // Create constraints - indexBackedConstraintCreate( constraint ); + indexBackedConstraintCreate( constraint, provider ); return constraint; } @Override public ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descriptor ) throws SchemaKernelException + { + return nodeKeyConstraintCreate( descriptor, Optional.empty() ); + } + + @Override + public ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descriptor, Optional provider ) throws SchemaKernelException { //Lock acquireExclusiveLabelLock( descriptor.getLabelId() ); @@ -983,7 +995,7 @@ public ConstraintDescriptor nodeKeyConstraintCreate( LabelSchemaDescriptor descr } //create constraint - indexBackedConstraintCreate( constraint ); + indexBackedConstraintCreate( constraint, provider ); return constraint; } @@ -1207,12 +1219,7 @@ private void assertValidDescriptor( SchemaDescriptor descriptor, SchemaKernelExc } } - private org.neo4j.kernel.api.schema.LabelSchemaDescriptor labelDescriptor( IndexReference index ) - { - return SchemaDescriptorFactory.forLabel( index.label(), index.properties() ); - } - - private void indexBackedConstraintCreate( IndexBackedConstraintDescriptor constraint ) + private void indexBackedConstraintCreate( IndexBackedConstraintDescriptor constraint, Optional provider ) throws CreateConstraintFailureException { SchemaDescriptor descriptor = constraint.schema(); @@ -1237,7 +1244,7 @@ private void indexBackedConstraintCreate( IndexBackedConstraintDescriptor constr return; } } - long indexId = constraintIndexCreator.createUniquenessConstraintIndex( ktx, descriptor ); + long indexId = constraintIndexCreator.createUniquenessConstraintIndex( ktx, descriptor, provider ); if ( !allStoreHolder.constraintExists( constraint ) ) { // This looks weird, but since we release the label lock while awaiting population of the index diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/RecordStorageEngine.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/RecordStorageEngine.java index aa2a9efcff6c5..37dfefa7385d3 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/RecordStorageEngine.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/RecordStorageEngine.java @@ -253,7 +253,7 @@ public IndexProvider.Descriptor indexProviderForOrDefault( Optional prov { if ( providerName.isPresent() ) { - throw new UnsupportedOperationException( "not implemented" ); + return indexProviderMap.lookup( providerName.get() ).getProviderDescriptor(); } return indexProviderMap.getDefaultProvider().getProviderDescriptor(); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMap.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMap.java index b35939a91cf15..b62ad326c380c 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMap.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMap.java @@ -28,11 +28,13 @@ import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.api.index.IndexProvider.Descriptor; import org.neo4j.kernel.impl.api.index.IndexProviderMap; +import org.neo4j.kernel.impl.api.index.IndexProviderNotFoundException; public class DefaultIndexProviderMap implements IndexProviderMap { private final IndexProvider defaultIndexProvider; private final Map indexProviders = new HashMap<>(); + private final Map indexProvidersByName = new HashMap<>(); public DefaultIndexProviderMap( IndexProvider defaultIndexProvider ) { @@ -40,15 +42,15 @@ public DefaultIndexProviderMap( IndexProvider defaultIndexProvider ) } public DefaultIndexProviderMap( IndexProvider defaultIndexProvider, - Iterable additionalIndexProviders ) + Iterable additionalIndexProviders ) { this.defaultIndexProvider = defaultIndexProvider; - indexProviders.put( defaultIndexProvider.getProviderDescriptor(), defaultIndexProvider ); + put( defaultIndexProvider.getProviderDescriptor(), defaultIndexProvider ); for ( IndexProvider provider : additionalIndexProviders ) { Descriptor providerDescriptor = provider.getProviderDescriptor(); Objects.requireNonNull( providerDescriptor ); - IndexProvider existing = indexProviders.putIfAbsent( providerDescriptor, provider ); + IndexProvider existing = put( providerDescriptor, provider ); if ( existing != null ) { throw new IllegalArgumentException( "Tried to load multiple schema index providers with the same provider descriptor " + @@ -57,6 +59,13 @@ public DefaultIndexProviderMap( IndexProvider defaultIndexProvider, } } + private IndexProvider put( Descriptor providerDescriptor, IndexProvider provider ) + { + IndexProvider existing = indexProviders.putIfAbsent( providerDescriptor, provider ); + indexProvidersByName.put( providerDescriptor.name(), provider ); + return existing; + } + @Override public IndexProvider getDefaultProvider() { @@ -64,17 +73,33 @@ public IndexProvider getDefaultProvider() } @Override - public IndexProvider apply( IndexProvider.Descriptor descriptor ) + public IndexProvider lookup( IndexProvider.Descriptor providerDescriptor ) { - IndexProvider provider = indexProviders.get( descriptor ); + IndexProvider provider = indexProviders.get( providerDescriptor ); if ( provider != null ) { return provider; } - throw new IllegalArgumentException( "Tried to get index provider for an existing index with provider " + - descriptor + " whereas available providers in this session being " + indexProviders + - ", and default being " + defaultIndexProvider ); + throw notFound( providerDescriptor ); + } + + @Override + public IndexProvider lookup( String providerDescriptorName ) throws IndexProviderNotFoundException + { + IndexProvider provider = indexProvidersByName.get( providerDescriptorName ); + if ( provider != null ) + { + return provider; + } + + throw notFound( providerDescriptorName ); + } + + private IllegalArgumentException notFound( Object key ) + { + return new IllegalArgumentException( "Tried to get index provider for an existing index with provider " + key + + " whereas available providers in this session being " + indexProviders + ", and default being " + defaultIndexProvider ); } @Override @@ -82,4 +107,4 @@ public void accept( Consumer visitor ) { indexProviders.values().forEach( visitor ); } -} +} \ No newline at end of file diff --git a/community/kernel/src/main/java/org/neo4j/unsafe/batchinsert/internal/BatchInserterImpl.java b/community/kernel/src/main/java/org/neo4j/unsafe/batchinsert/internal/BatchInserterImpl.java index 43b620f0f5b8a..c4dac239eb015 100644 --- a/community/kernel/src/main/java/org/neo4j/unsafe/batchinsert/internal/BatchInserterImpl.java +++ b/community/kernel/src/main/java/org/neo4j/unsafe/batchinsert/internal/BatchInserterImpl.java @@ -74,6 +74,7 @@ import org.neo4j.kernel.api.schema.constaints.IndexBackedConstraintDescriptor; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; +import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.extension.KernelExtensionFactory; import org.neo4j.kernel.extension.KernelExtensions; @@ -128,7 +129,6 @@ import org.neo4j.kernel.impl.store.id.validation.IdValidator; import org.neo4j.kernel.impl.store.record.ConstraintRule; import org.neo4j.kernel.impl.store.record.DynamicRecord; -import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; import org.neo4j.kernel.impl.store.record.LabelTokenRecord; import org.neo4j.kernel.impl.store.record.NodeRecord; import org.neo4j.kernel.impl.store.record.PrimitiveRecord; @@ -499,7 +499,7 @@ private void repopulateAllIndexes() throws IOException, IndexEntryConflictExcept { StoreIndexDescriptor index = indexDescriptors[i]; descriptors[i] = index.schema(); - IndexPopulator populator = indexProviderMap.apply( index.providerDescriptor() ) + IndexPopulator populator = indexProviderMap.lookup( index.providerDescriptor() ) .getPopulator( index, new IndexSamplingConfig( config ) ); populator.create(); populators.add( new IndexPopulatorWithSchema( populator, index ) ); @@ -586,7 +586,7 @@ private StoreIndexDescriptor[] getIndexesNeedingPopulation() List indexesNeedingPopulation = new ArrayList<>(); for ( StoreIndexDescriptor rule : schemaCache.indexRules() ) { - IndexProvider provider = indexProviderMap.apply( rule.providerDescriptor() ); + IndexProvider provider = indexProviderMap.lookup( rule.providerDescriptor() ); if ( provider.getInitialState( rule ) != InternalIndexState.FAILED ) { indexesNeedingPopulation.add( rule ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/StubKernelTransaction.java b/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/StubKernelTransaction.java index 991e000a60291..de81dfc18df48 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/StubKernelTransaction.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/StubKernelTransaction.java @@ -60,7 +60,7 @@ public Statement acquireStatement() } @Override - public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema ) + public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema, Optional provider ) { throw new UnsupportedOperationException( "not implemented" ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintIndexCreatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintIndexCreatorTest.java index 675f206a024c1..789ec8c47d04b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintIndexCreatorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintIndexCreatorTest.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.internal.kernel.api.Kernel; @@ -43,6 +44,7 @@ import org.neo4j.kernel.api.exceptions.index.IndexPopulationFailedKernelException; import org.neo4j.kernel.api.exceptions.schema.AlreadyConstrainedException; import org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException; +import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.api.index.PropertyAccessor; import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.kernel.api.schema.index.IndexDescriptor; @@ -50,7 +52,6 @@ import org.neo4j.kernel.api.schema.index.TestIndexDescriptorFactory; import org.neo4j.kernel.api.txstate.TransactionState; import org.neo4j.kernel.impl.api.KernelTransactionImplementation; -import org.neo4j.kernel.impl.api.StatementOperationParts; import org.neo4j.kernel.impl.api.TransactionHeaderInformation; import org.neo4j.kernel.impl.api.index.IndexProxy; import org.neo4j.kernel.impl.api.index.IndexingService; @@ -75,7 +76,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; -import static org.neo4j.kernel.impl.api.StatementOperationsTestHelper.mockedParts; public class ConstraintIndexCreatorTest { @@ -105,7 +105,7 @@ public void shouldCreateIndexInAnotherTransaction() throws Exception new ConstraintIndexCreator( () -> kernel, indexingService, propertyAccessor ); // when - long indexId = creator.createUniquenessConstraintIndex( createTransaction(), descriptor ); + long indexId = creator.createUniquenessConstraintIndex( createTransaction(), descriptor, Optional.empty() ); // then assertEquals( INDEX_ID, indexId ); @@ -144,7 +144,7 @@ public void shouldDropIndexIfPopulationFails() throws Exception KernelTransactionImplementation transaction = createTransaction(); try { - creator.createUniquenessConstraintIndex( transaction, descriptor ); + creator.createUniquenessConstraintIndex( transaction, descriptor, Optional.empty() ); fail( "expected exception" ); } @@ -157,7 +157,7 @@ public void shouldDropIndexIfPopulationFails() throws Exception assertEquals( 2, kernel.transactions.size() ); KernelTransactionImplementation tx1 = kernel.transactions.get( 0 ); SchemaDescriptor newIndex = index.schema(); - verify( tx1 ).indexUniqueCreate( eq( newIndex ) ); + verify( tx1 ).indexUniqueCreate( eq( newIndex ), eq( Optional.empty() ) ); verify( schemaRead ).indexGetCommittedId( indexReference ); verify( schemaRead, times( 2 ) ).index( LABEL_ID, PROPERTY_KEY_ID ); verifyNoMoreInteractions( schemaRead ); @@ -207,7 +207,7 @@ public void shouldReleaseLabelLockWhileAwaitingIndexPopulation() throws Exceptio // when KernelTransactionImplementation transaction = createTransaction(); - creator.createUniquenessConstraintIndex( transaction, descriptor ); + creator.createUniquenessConstraintIndex( transaction, descriptor, Optional.empty() ); // then verify( transaction.statementLocks().pessimistic() ) @@ -237,7 +237,7 @@ public void shouldReuseExistingOrphanedConstraintIndex() throws Exception // when KernelTransactionImplementation transaction = createTransaction(); - long indexId = creator.createUniquenessConstraintIndex( transaction, descriptor ); + long indexId = creator.createUniquenessConstraintIndex( transaction, descriptor, Optional.empty() ); // then assertEquals( orphanedConstraintIndexId, indexId ); @@ -254,8 +254,6 @@ public void shouldReuseExistingOrphanedConstraintIndex() throws Exception public void shouldFailOnExistingOwnedConstraintIndex() throws Exception { // given - StatementOperationParts indexCreationContext = mockedParts(); - IndexingService indexingService = mock( IndexingService.class ); StubKernel kernel = new StubKernel(); @@ -277,7 +275,7 @@ public void shouldFailOnExistingOwnedConstraintIndex() throws Exception try { KernelTransactionImplementation transaction = createTransaction(); - creator.createUniquenessConstraintIndex( transaction, descriptor ); + creator.createUniquenessConstraintIndex( transaction, descriptor, Optional.empty() ); fail( "Should've failed" ); } catch ( AlreadyConstrainedException e ) @@ -293,6 +291,35 @@ public void shouldFailOnExistingOwnedConstraintIndex() throws Exception verifyNoMoreInteractions( schemaRead ); } + @Test + public void shouldCreateConstraintIndexForSpecifiedProvider() throws Exception + { + // given + IndexingService indexingService = mock( IndexingService.class ); + StubKernel kernel = new StubKernel(); + + when( schemaRead.indexGetCommittedId( indexReference ) ).thenReturn( INDEX_ID ); + IndexProxy indexProxy = mock( IndexProxy.class ); + when( indexingService.getIndexProxy( INDEX_ID ) ).thenReturn( indexProxy ); + when( indexingService.getIndexProxy( descriptor ) ).thenReturn( indexProxy ); + PropertyAccessor propertyAccessor = mock( PropertyAccessor.class ); + ConstraintIndexCreator creator = new ConstraintIndexCreator( () -> kernel, indexingService, propertyAccessor ); + IndexProvider.Descriptor providerDescriptor = new IndexProvider.Descriptor( "Groovy", "1.2" ); + + // when + KernelTransactionImplementation transaction = createTransaction(); + creator.createUniquenessConstraintIndex( transaction, descriptor, Optional.of( providerDescriptor.name() ) ); + + // then + assertEquals( 1, kernel.transactions.size() ); + KernelTransactionImplementation transactionInstance = kernel.transactions.get( 0 ); + verify( transactionInstance ).indexUniqueCreate( eq( descriptor ), eq( Optional.of( providerDescriptor.name() ) ) ); + verify( schemaRead ).index( LABEL_ID, PROPERTY_KEY_ID ); + verify( schemaRead ).indexGetCommittedId( any() ); + verifyNoMoreInteractions( schemaRead ); + } + + private class StubKernel implements Kernel, Session { private final List transactions = new ArrayList<>(); @@ -367,7 +394,7 @@ private KernelTransactionImplementation createTransaction() when( transaction.schemaWrite() ).thenReturn( schemaWrite ); TransactionState transactionState = mock( TransactionState.class ); when( transaction.txState() ).thenReturn( transactionState ); - when( transaction.indexUniqueCreate( any( SchemaDescriptor.class ) ) ).thenAnswer( + when( transaction.indexUniqueCreate( any( SchemaDescriptor.class ), any( Optional.class ) ) ).thenAnswer( i -> IndexDescriptorFactory.uniqueForSchema( i.getArgument( 0 ) ) ); } catch ( InvalidTransactionTypeKernelException e ) diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexIT.java index 5c0d12cd98bbe..1f4ec84183b56 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexIT.java @@ -24,6 +24,7 @@ import org.junit.Test; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -180,7 +181,7 @@ public void shouldBeAbleToRemoveAConstraintIndexWithoutOwner() throws Exception PropertyAccessor propertyAccessor = mock( PropertyAccessor.class ); ConstraintIndexCreator creator = new ConstraintIndexCreator( () -> kernel, indexingService, propertyAccessor ); - IndexDescriptor constraintIndex = creator.createConstraintIndex( descriptor ); + IndexDescriptor constraintIndex = creator.createConstraintIndex( descriptor, Optional.empty() ); // then Transaction transaction = newTransaction(); assertEquals( emptySet(), asSet( transaction.schemaRead().constraintsGetForLabel( labelId ) ) ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/KernelIntegrationTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/KernelIntegrationTest.java index 3195ee705c308..890262a1d5f5c 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/KernelIntegrationTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/KernelIntegrationTest.java @@ -177,11 +177,16 @@ protected void startDb() protected GraphDatabaseService createGraphDatabase() { - GraphDatabaseBuilder graphDatabaseBuilder = new TestGraphDatabaseFactory().setFileSystem( fileSystemRule.get() ) + GraphDatabaseBuilder graphDatabaseBuilder = createGraphDatabaseFactory().setFileSystem( fileSystemRule.get() ) .newEmbeddedDatabaseBuilder( testDir.graphDbDir() ); return configure( graphDatabaseBuilder ).newGraphDatabase(); } + protected TestGraphDatabaseFactory createGraphDatabaseFactory() + { + return new TestGraphDatabaseFactory(); + } + protected GraphDatabaseBuilder configure( GraphDatabaseBuilder graphDatabaseBuilder ) { return graphDatabaseBuilder; diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/OperationsLockTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/OperationsLockTest.java index 3c49d3f3ec921..19fd7bdbdac69 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/OperationsLockTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/OperationsLockTest.java @@ -43,13 +43,11 @@ import org.neo4j.internal.kernel.api.security.SecurityContext; import org.neo4j.kernel.api.explicitindex.AutoIndexOperations; import org.neo4j.kernel.api.explicitindex.AutoIndexing; -import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptorFactory; import org.neo4j.kernel.api.schema.constaints.RelExistenceConstraintDescriptor; import org.neo4j.kernel.api.schema.constaints.UniquenessConstraintDescriptor; import org.neo4j.kernel.api.schema.index.CapableIndexDescriptor; -import org.neo4j.kernel.api.schema.index.StoreIndexDescriptor; import org.neo4j.kernel.api.schema.index.TestIndexDescriptorFactory; import org.neo4j.kernel.api.txstate.TransactionState; import org.neo4j.kernel.impl.api.KernelTransactionImplementation; @@ -463,7 +461,7 @@ public void shouldAcquireSchemaWriteLockBeforeRemovingIndexRule() throws Excepti public void shouldAcquireSchemaWriteLockBeforeCreatingUniquenessConstraint() throws Exception { // given - when( constraintIndexCreator.createUniquenessConstraintIndex( transaction, descriptor ) ).thenReturn( 42L ); + when( constraintIndexCreator.createUniquenessConstraintIndex( transaction, descriptor, Optional.empty() ) ).thenReturn( 42L ); when( storageReader.constraintsGetForSchema( descriptor.schema() ) ).thenReturn( Collections.emptyIterator() ); // when diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMapTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMapTest.java index 546907e4ef4b5..39241a3ae0507 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMapTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/DefaultIndexProviderMapTest.java @@ -24,12 +24,11 @@ import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.impl.api.index.IndexProviderMap; +import static java.util.Arrays.asList; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static java.util.Arrays.asList; - public class DefaultIndexProviderMapTest { @Test @@ -65,7 +64,7 @@ public void shouldThrowOnLookupOnUnknownProvider() IndexProviderMap map = new DefaultIndexProviderMap( provider ); try { - new DefaultIndexProviderMap( provider ).apply( new IndexProvider.Descriptor( "provider2", "1.2" ) ); + new DefaultIndexProviderMap( provider ).lookup( new IndexProvider.Descriptor( "provider2", "1.2" ) ); fail( "Should have failed" ); } catch ( IllegalArgumentException e ) diff --git a/community/neo4j/src/test/java/org/neo4j/kernel/impl/index/schema/IndexCreateIT.java b/community/neo4j/src/test/java/org/neo4j/kernel/impl/index/schema/IndexCreateIT.java new file mode 100644 index 0000000000000..54d2a7546d9ed --- /dev/null +++ b/community/neo4j/src/test/java/org/neo4j/kernel/impl/index/schema/IndexCreateIT.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2002-2018 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.index.schema; + +import org.junit.Test; + +import java.util.Optional; + +import org.neo4j.graphdb.factory.GraphDatabaseSettings; +import org.neo4j.internal.kernel.api.SchemaWrite; +import org.neo4j.internal.kernel.api.exceptions.KernelException; +import org.neo4j.internal.kernel.api.exceptions.schema.SchemaKernelException; +import org.neo4j.internal.kernel.api.schema.LabelSchemaDescriptor; +import org.neo4j.kernel.impl.api.integrationtest.KernelIntegrationTest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.neo4j.kernel.api.schema.SchemaDescriptorFactory.forLabel; + +public class IndexCreateIT extends KernelIntegrationTest +{ + + private static final IndexCreator INDEX_CREATOR = + ( schemaWrite, descriptor, providerName ) -> schemaWrite.indexCreate( descriptor, Optional.of( providerName ), Optional.empty() ); + private static final IndexCreator UNIQUE_CONSTRAINT_CREATOR = + ( schemaWrite, descriptor, providerName ) -> schemaWrite.uniquePropertyConstraintCreate( descriptor, Optional.of( providerName ) ); + + @Test + public void shouldCreateIndexWithSpecificExistingProviderName() throws KernelException + { + shouldCreateWithSpecificExistingProviderName( INDEX_CREATOR ); + } + + @Test + public void shouldCreateUniquePropertyConstraintWithSpecificExistingProviderName() throws KernelException + { + shouldCreateWithSpecificExistingProviderName( UNIQUE_CONSTRAINT_CREATOR ); + } + + @Test + public void shouldFailCreateIndexWithNonExistentProviderName() throws KernelException + { + shouldFailWithNonExistentProviderName( INDEX_CREATOR ); + } + + @Test + public void shouldFailCreateUniquePropertyConstraintWithNonExistentProviderName() throws KernelException + { + shouldFailWithNonExistentProviderName( UNIQUE_CONSTRAINT_CREATOR ); + } + + void shouldFailWithNonExistentProviderName( IndexCreator creator ) throws KernelException + { + // given + SchemaWrite schemaWrite = schemaWriteInNewTransaction(); + + // when + try + { + schemaWrite.indexCreate( forLabel( 0, 0 ), Optional.of( "something-completely-different" ), Optional.empty() ); + fail( "Should have failed" ); + } + catch ( IllegalArgumentException e ) + { + // then good + } + } + + void shouldCreateWithSpecificExistingProviderName( IndexCreator creator ) throws KernelException + { + int labelId = 0; + for ( GraphDatabaseSettings.SchemaIndex indexSetting : GraphDatabaseSettings.SchemaIndex.values() ) + { + // given + SchemaWrite schemaWrite = schemaWriteInNewTransaction(); + String provider = indexSetting.providerName(); + LabelSchemaDescriptor descriptor = forLabel( labelId++, 0 ); + creator.create( schemaWrite, descriptor, provider ); + + // when + commit(); + + // then + assertEquals( provider, indexingService.getIndexProxy( descriptor ).getDescriptor().providerDescriptor().name() ); + } + } + + interface IndexCreator + { + void create( SchemaWrite schemaWrite, LabelSchemaDescriptor descriptor, String providerName ) throws SchemaKernelException; + } +} \ No newline at end of file diff --git a/community/neo4j/src/test/java/org/neo4j/locking/QueryExecutionLocksIT.java b/community/neo4j/src/test/java/org/neo4j/locking/QueryExecutionLocksIT.java index 3719e492d422b..589f3e0c11ba2 100644 --- a/community/neo4j/src/test/java/org/neo4j/locking/QueryExecutionLocksIT.java +++ b/community/neo4j/src/test/java/org/neo4j/locking/QueryExecutionLocksIT.java @@ -676,9 +676,9 @@ public Statement acquireStatement() } @Override - public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema ) + public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema, Optional provider ) { - return internal.indexUniqueCreate( schema ); + return internal.indexUniqueCreate( schema, Optional.empty() ); } @Override diff --git a/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/StubKernelTransaction.java b/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/StubKernelTransaction.java index 689a9d576fc22..d472d48a21fc6 100644 --- a/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/StubKernelTransaction.java +++ b/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/StubKernelTransaction.java @@ -63,7 +63,7 @@ public Statement acquireStatement() } @Override - public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema ) + public IndexDescriptor indexUniqueCreate( SchemaDescriptor schema, Optional provider ) { return null; } diff --git a/enterprise/neo4j-enterprise/src/test/java/org/neo4j/kernel/impl/index/schema/IndexCreateEnterpriseIT.java b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/kernel/impl/index/schema/IndexCreateEnterpriseIT.java new file mode 100644 index 0000000000000..73db63e094663 --- /dev/null +++ b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/kernel/impl/index/schema/IndexCreateEnterpriseIT.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2002-2018 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.index.schema; + +import org.junit.Test; + +import java.util.Optional; + +import org.neo4j.internal.kernel.api.exceptions.KernelException; +import org.neo4j.test.TestEnterpriseGraphDatabaseFactory; +import org.neo4j.test.TestGraphDatabaseFactory; + +public class IndexCreateEnterpriseIT extends IndexCreateIT +{ + private static final IndexCreator NODE_KEY_CREATOR = + ( schemaWrite, descriptor, providerName ) -> schemaWrite.nodeKeyConstraintCreate( descriptor, Optional.of( providerName ) ); + + @Override + protected TestGraphDatabaseFactory createGraphDatabaseFactory() + { + return new TestEnterpriseGraphDatabaseFactory(); + } + + @Test + public void shouldCreateNodeKeyConstraintWithSpecificExistingProviderName() throws KernelException + { + shouldCreateWithSpecificExistingProviderName( NODE_KEY_CREATOR ); + } + + @Test + public void shouldFailCreateNodeKeyWithNonExistentProviderName() throws KernelException + { + shouldFailWithNonExistentProviderName( NODE_KEY_CREATOR ); + } +} \ No newline at end of file