From e8f870f29bfafe7b5df79fec9d6d77525e46e56d Mon Sep 17 00:00:00 2001 From: Mikhaylo Demianenko Date: Fri, 3 Jun 2016 20:47:53 +0200 Subject: [PATCH] Allow id type to be configurable, edition based configuration of id type. Allow id type reusability to be configurable during database edition configuration. Introduce enterprise edition specific configurator and settings to be able to disticnt specific settings and perform custom configuration. Allow relationship ids to be reusable in ha and enterprise editions. --- .../checking/AbstractStoreProcessor.java | 24 ++-- .../checking/AbstractStoreProcessor.java | 25 ++-- .../main/java/org/neo4j/kernel/IdType.java | 112 ++++++++++++++---- .../impl/factory/CommunityEditionModule.java | 8 +- .../store/id/BufferingIdGeneratorFactory.java | 15 +-- .../store/BatchingIdGeneratorFactory.java | 4 +- .../impl/core/JumpingIdGeneratorFactory.java | 4 +- .../kernel/impl/store/IdGeneratorTest.java | 3 +- .../id/BufferingIdGeneratorFactoryTest.java | 6 +- .../neo4j/test/impl/EphemeralIdGenerator.java | 4 +- .../org/neo4j/kernel/ha/HaRequestType210.java | 6 +- .../org/neo4j/kernel/ha/MasterClient210.java | 2 +- .../factory/HighlyAvailableEditionModule.java | 4 + .../kernel/ha/id/HaIdGeneratorFactory.java | 4 +- .../enterprise/EnterpriseEditionModule.java | 7 ++ .../EnterpriseEditionConfigurator.java | 51 ++++++++ .../EnterpriseEditionSettings.java | 39 ++++++ .../EnterpriseEditionConfiguratorTest.java | 76 ++++++++++++ 18 files changed, 325 insertions(+), 69 deletions(-) create mode 100644 enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionConfigurator.java create mode 100644 enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionSettings.java create mode 100644 enterprise/kernel/src/test/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionConfiguratorTest.java diff --git a/community/consistency-check-legacy/src/main/java/org/neo4j/legacy/consistency/checking/AbstractStoreProcessor.java b/community/consistency-check-legacy/src/main/java/org/neo4j/legacy/consistency/checking/AbstractStoreProcessor.java index 2cccbad0a7a1a..60950f3aa59bf 100644 --- a/community/consistency-check-legacy/src/main/java/org/neo4j/legacy/consistency/checking/AbstractStoreProcessor.java +++ b/community/consistency-check-legacy/src/main/java/org/neo4j/legacy/consistency/checking/AbstractStoreProcessor.java @@ -34,7 +34,6 @@ import org.neo4j.legacy.consistency.report.ConsistencyReport.NodeConsistencyReport; import static java.lang.String.format; - import static org.neo4j.legacy.consistency.checking.DynamicStore.ARRAY; import static org.neo4j.legacy.consistency.checking.DynamicStore.NODE_LABEL; import static org.neo4j.legacy.consistency.checking.DynamicStore.SCHEMA; @@ -144,25 +143,28 @@ public final void processString( RecordStore store, DynamicRecord { RecordType type; DynamicStore dereference; - switch ( idType ) + if ( IdType.STRING_BLOCK.equals( idType ) ) { - case STRING_BLOCK: type = RecordType.STRING_PROPERTY; dereference = DynamicStore.STRING; - break; - case RELATIONSHIP_TYPE_TOKEN_NAME: + } + else if ( IdType.RELATIONSHIP_TYPE_TOKEN_NAME.equals( idType ) ) + { type = RecordType.RELATIONSHIP_TYPE_NAME; dereference = DynamicStore.RELATIONSHIP_TYPE; - break; - case PROPERTY_KEY_TOKEN_NAME: + } + else if ( IdType.PROPERTY_KEY_TOKEN_NAME.equals( idType ) ) + { type = RecordType.PROPERTY_KEY_NAME; dereference = DynamicStore.PROPERTY_KEY; - break; - case LABEL_TOKEN_NAME: + } + else if ( IdType.LABEL_TOKEN_NAME.equals( idType ) ) + { type = RecordType.LABEL_NAME; dereference = DynamicStore.LABEL; - break; - default: + } + else + { throw new IllegalArgumentException( format( "The id type [%s] is not valid for String records.", idType ) ); } checkDynamic( type, store, string, new DynamicRecordCheck( store, dereference ) ); diff --git a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/AbstractStoreProcessor.java b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/AbstractStoreProcessor.java index 18c30f3d41ac7..30a1ce61fd110 100644 --- a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/AbstractStoreProcessor.java +++ b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/AbstractStoreProcessor.java @@ -34,7 +34,6 @@ import org.neo4j.kernel.impl.store.record.RelationshipTypeTokenRecord; import static java.lang.String.format; - import static org.neo4j.consistency.checking.DynamicStore.ARRAY; import static org.neo4j.consistency.checking.DynamicStore.NODE_LABEL; import static org.neo4j.consistency.checking.DynamicStore.SCHEMA; @@ -161,27 +160,31 @@ public final void processString( RecordStore store, DynamicRecord { RecordType type; DynamicStore dereference; - switch ( idType ) + if ( IdType.STRING_BLOCK.equals( idType ) ) { - case STRING_BLOCK: type = RecordType.STRING_PROPERTY; dereference = DynamicStore.STRING; - break; - case RELATIONSHIP_TYPE_TOKEN_NAME: + } + else if ( IdType.RELATIONSHIP_TYPE_TOKEN_NAME.equals( idType ) ) + { type = RecordType.RELATIONSHIP_TYPE_NAME; dereference = DynamicStore.RELATIONSHIP_TYPE; - break; - case PROPERTY_KEY_TOKEN_NAME: + } + else if ( IdType.PROPERTY_KEY_TOKEN_NAME.equals( idType ) ) + { type = RecordType.PROPERTY_KEY_NAME; dereference = DynamicStore.PROPERTY_KEY; - break; - case LABEL_TOKEN_NAME: + } + else if ( IdType.LABEL_TOKEN_NAME.equals( idType ) ) + { type = RecordType.LABEL_NAME; dereference = DynamicStore.LABEL; - break; - default: + } + else + { throw new IllegalArgumentException( format( "The id type [%s] is not valid for String records.", idType ) ); } + checkDynamic( type, store, string, new DynamicRecordCheck( store, dereference ) ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/IdType.java b/community/kernel/src/main/java/org/neo4j/kernel/IdType.java index 67e9de768a706..a9e216e093ce1 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/IdType.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/IdType.java @@ -19,42 +19,71 @@ */ package org.neo4j.kernel; -import org.neo4j.unsafe.impl.internal.dragons.FeatureToggles; +import java.util.Arrays; +import java.util.List; /** * @deprecated This will be moved to internal packages in the next major release. */ @Deprecated -public enum IdType +public class IdType { - NODE( 35, false ), - RELATIONSHIP( 35, FeatureToggles.flag( "unsupported.dbms.relationships.ids.reuse", false ) ), - PROPERTY( 36, true ), - STRING_BLOCK( 36, true ), - ARRAY_BLOCK( 36, true ), - PROPERTY_KEY_TOKEN( false ), - PROPERTY_KEY_TOKEN_NAME( false ), - RELATIONSHIP_TYPE_TOKEN( 16, false ), - RELATIONSHIP_TYPE_TOKEN_NAME( false ), - LABEL_TOKEN( false ), - LABEL_TOKEN_NAME( false ), - NEOSTORE_BLOCK( false ), - SCHEMA( 35, false ), - NODE_LABELS( 35, true ), - RELATIONSHIP_GROUP( 35, false ); + public static final IdType NODE = new IdType( 35, Name.NODE, false ); + public static final IdType RELATIONSHIP = new IdType( 35, Name.RELATIONSHIP, false ); + public static final IdType PROPERTY = new IdType( 36, Name.PROPERTY, true ); + public static final IdType STRING_BLOCK = new IdType( 36, Name.STRING_BLOCK, true ); + public static final IdType ARRAY_BLOCK = new IdType( 36, Name.ARRAY_BLOCK, true ); + public static final IdType PROPERTY_KEY_TOKEN = new IdType( Name.PROPERTY_KEY_TOKEN, false ); + public static final IdType PROPERTY_KEY_TOKEN_NAME = new IdType( Name.PROPERTY_KEY_TOKEN_NAME, false ); + public static final IdType RELATIONSHIP_TYPE_TOKEN = new IdType( 16, Name.RELATIONSHIP_TYPE_TOKEN, false ); + public static final IdType RELATIONSHIP_TYPE_TOKEN_NAME = new IdType( Name.RELATIONSHIP_TYPE_TOKEN_NAME, false ); + public static final IdType LABEL_TOKEN = new IdType( Name.LABEL_TOKEN, false ); + public static final IdType LABEL_TOKEN_NAME = new IdType( Name.LABEL_TOKEN_NAME, false ); + public static final IdType NEOSTORE_BLOCK = new IdType( Name.NEOSTORE_BLOCK, false ); + public static final IdType SCHEMA = new IdType( 35, Name.SCHEMA, false ); + public static final IdType NODE_LABELS = new IdType( 35, Name.NODE_LABELS, true ); + public static final IdType RELATIONSHIP_GROUP = new IdType( 35, Name.RELATIONSHIP_GROUP, false ); + + private static final List ALL_ID_TYPES = Arrays.asList( NODE, RELATIONSHIP, PROPERTY, STRING_BLOCK, + ARRAY_BLOCK, PROPERTY_KEY_TOKEN, PROPERTY_KEY_TOKEN_NAME, RELATIONSHIP_TYPE_TOKEN, + RELATIONSHIP_TYPE_TOKEN_NAME, LABEL_TOKEN, LABEL_TOKEN_NAME, NEOSTORE_BLOCK, + SCHEMA, NODE_LABELS, RELATIONSHIP_GROUP ); + + /** + * Get all defined id types. + * @return list of all id types. + */ + public static List getAllIdTypes() + { + return ALL_ID_TYPES; + } + + public static IdType forName(IdType.Name typeName) + { + for ( IdType idType : ALL_ID_TYPES ) + { + if ( idType.getName().equals( typeName ) ) + { + return idType; + } + } + throw new IllegalArgumentException( "IdType with requested name: " + typeName + " does not exist." ); + } private final long max; - private final boolean allowAggressiveReuse; + private boolean allowAggressiveReuse; + private Name name; - IdType( boolean allowAggressiveReuse ) + private IdType( Name name, boolean allowAggressiveReuse ) { - this( 32, allowAggressiveReuse ); + this( 32, name, allowAggressiveReuse ); } - IdType( int bits, boolean allowAggressiveReuse ) + private IdType( int bits, Name name, boolean allowAggressiveReuse ) { this.allowAggressiveReuse = allowAggressiveReuse; - this.max = (long)Math.pow( 2, bits )-1; + this.name = name; + this.max = (long) Math.pow( 2, bits ) - 1; } public long getMaxValue() @@ -62,6 +91,11 @@ public long getMaxValue() return this.max; } + public void setAllowAggressiveReuse( boolean allowAggressiveReuse ) + { + this.allowAggressiveReuse = allowAggressiveReuse; + } + public boolean allowAggressiveReuse() { return allowAggressiveReuse; @@ -71,4 +105,38 @@ public int getGrabSize() { return allowAggressiveReuse ? 50000 : 1024; } + + public Name getName() + { + return name; + } + + @Override + public String toString() + { + return "IdType{" + + "max=" + max + + ", allowAggressiveReuse=" + allowAggressiveReuse + + ", name=" + name + + '}'; + } + + public enum Name + { + NODE, + RELATIONSHIP, + PROPERTY, + STRING_BLOCK, + ARRAY_BLOCK, + PROPERTY_KEY_TOKEN, + PROPERTY_KEY_TOKEN_NAME, + RELATIONSHIP_TYPE_TOKEN, + RELATIONSHIP_TYPE_TOKEN_NAME, + LABEL_TOKEN, + LABEL_TOKEN_NAME, + NEOSTORE_BLOCK, + SCHEMA, + NODE_LABELS, + RELATIONSHIP_GROUP + } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java index 100e15f45cd5e..d2043a0928ce4 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java @@ -82,8 +82,9 @@ public CommunityEditionModule( PlatformModule platformModule ) LifeSupport life = platformModule.life; GraphDatabaseFacade graphDatabaseFacade = platformModule.graphDatabaseFacade; - lockManager = dependencies.satisfyDependency( createLockManager( config, logging ) ); + preConfigureEdition(config); + lockManager = dependencies.satisfyDependency( createLockManager( config, logging ) ); idGeneratorFactory = dependencies.satisfyDependency( createIdGeneratorFactory( fileSystem ) ); propertyKeyTokenHolder = life.add( dependencies.satisfyDependency( new DelegatingPropertyKeyTokenHolder( @@ -115,6 +116,11 @@ public CommunityEditionModule( PlatformModule platformModule ) publishEditionInfo( dependencies.resolveDependency( UsageData.class ) ); } + protected void preConfigureEdition( Config config ) + { + // empty + } + protected ConstraintSemantics createSchemaRuleVerifier() { return new StandardConstraintSemantics(); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/id/BufferingIdGeneratorFactory.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/id/BufferingIdGeneratorFactory.java index 790ad671f3249..4dede05173d6b 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/id/BufferingIdGeneratorFactory.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/id/BufferingIdGeneratorFactory.java @@ -20,6 +20,8 @@ package org.neo4j.kernel.impl.store.id; import java.io.File; +import java.util.HashMap; +import java.util.Map; import org.neo4j.function.Predicate; import org.neo4j.function.Supplier; @@ -34,8 +36,7 @@ */ public class BufferingIdGeneratorFactory extends IdGeneratorFactory.Delegate { - private final BufferingIdGenerator[/*IdType#ordinal as key*/] overriddenIdGenerators = - new BufferingIdGenerator[IdType.values().length]; + private final Map overriddenIdGenerators = new HashMap<>(); private Supplier boundaries; private Predicate safeThreshold; @@ -55,7 +56,7 @@ public boolean test( KernelTransactionsSnapshot snapshot ) return snapshot.allClosed() && eligibleForReuse.isEligible( snapshot ); } }; - for ( BufferingIdGenerator generator : overriddenIdGenerators ) + for ( BufferingIdGenerator generator : overriddenIdGenerators.values() ) { if ( generator != null ) { @@ -92,7 +93,7 @@ public IdGenerator open( File filename, int grabSize, IdType idType, long highId { bufferingGenerator.initialize( boundaries, safeThreshold ); } - overriddenIdGenerators[idType.ordinal()] = bufferingGenerator; + overriddenIdGenerators.put( idType, bufferingGenerator ); generator = bufferingGenerator; } return generator; @@ -101,13 +102,13 @@ public IdGenerator open( File filename, int grabSize, IdType idType, long highId @Override public IdGenerator get( IdType idType ) { - IdGenerator generator = overriddenIdGenerators[idType.ordinal()]; + IdGenerator generator = overriddenIdGenerators.get( idType ); return generator != null ? generator : super.get( idType ); } public void maintenance() { - for ( BufferingIdGenerator generator : overriddenIdGenerators ) + for ( BufferingIdGenerator generator : overriddenIdGenerators.values() ) { if ( generator != null ) { @@ -118,7 +119,7 @@ public void maintenance() public void clear() { - for ( BufferingIdGenerator generator : overriddenIdGenerators ) + for ( BufferingIdGenerator generator : overriddenIdGenerators.values() ) { if ( generator != null ) { diff --git a/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/store/BatchingIdGeneratorFactory.java b/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/store/BatchingIdGeneratorFactory.java index e2c0e4bd4982a..d85f3db1fbfca 100644 --- a/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/store/BatchingIdGeneratorFactory.java +++ b/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/store/BatchingIdGeneratorFactory.java @@ -20,7 +20,7 @@ package org.neo4j.unsafe.impl.batchimport.store; import java.io.File; -import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; import org.neo4j.io.fs.FileSystemAbstraction; @@ -37,7 +37,7 @@ */ public class BatchingIdGeneratorFactory implements IdGeneratorFactory { - private final Map idGenerators = new EnumMap<>( IdType.class ); + private final Map idGenerators = new HashMap<>(); private final FileSystemAbstraction fs; public BatchingIdGeneratorFactory( FileSystemAbstraction fs ) diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/core/JumpingIdGeneratorFactory.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/core/JumpingIdGeneratorFactory.java index bea7b47e932be..35adec2b15834 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/core/JumpingIdGeneratorFactory.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/core/JumpingIdGeneratorFactory.java @@ -20,7 +20,7 @@ package org.neo4j.kernel.impl.core; import java.io.File; -import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; @@ -33,7 +33,7 @@ public class JumpingIdGeneratorFactory implements IdGeneratorFactory { - private final Map generators = new EnumMap<>( IdType.class ); + private final Map generators = new HashMap<>(); private final IdGenerator forTheRest = new EphemeralIdGenerator( null ); private final int sizePerJump; diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/IdGeneratorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/IdGeneratorTest.java index 1469d154c4126..cfbd55b8a5b88 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/IdGeneratorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/IdGeneratorTest.java @@ -56,7 +56,6 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; - import static org.neo4j.graphdb.DynamicRelationshipType.withName; import static org.neo4j.helpers.collection.IteratorUtil.lastOrNull; import static org.neo4j.io.fs.FileUtils.deleteRecursively; @@ -542,7 +541,7 @@ public void testUnsignedId() @Test public void makeSureIdCapacityCannotBeExceeded() throws Exception { - for ( IdType type : IdType.values() ) + for ( IdType type : IdType.getAllIdTypes() ) { makeSureIdCapacityCannotBeExceeded( type ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/id/BufferingIdGeneratorFactoryTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/id/BufferingIdGeneratorFactoryTest.java index 83b4142cf195b..1057f4f9d06d0 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/id/BufferingIdGeneratorFactoryTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/id/BufferingIdGeneratorFactoryTest.java @@ -130,12 +130,12 @@ void setMostRecentlyReturnedSnapshotToAllClosed() private static class MockedIdGeneratorFactory implements IdGeneratorFactory { - private final IdGenerator[] generators = new IdGenerator[IdType.values().length]; + private final IdGenerator[] generators = new IdGenerator[IdType.Name.values().length]; @Override public IdGenerator open( File filename, int grabSize, IdType idType, long highId ) { - return generators[idType.ordinal()] = mock( IdGenerator.class ); + return generators[idType.getName().ordinal()] = mock( IdGenerator.class ); } @Override @@ -146,7 +146,7 @@ public void create( File filename, long highId, boolean throwIfFileExists ) @Override public IdGenerator get( IdType idType ) { - return generators[idType.ordinal()]; + return generators[idType.getName().ordinal()]; } } } diff --git a/community/kernel/src/test/java/org/neo4j/test/impl/EphemeralIdGenerator.java b/community/kernel/src/test/java/org/neo4j/test/impl/EphemeralIdGenerator.java index 108a3b344e6f0..1a3892a3d9383 100644 --- a/community/kernel/src/test/java/org/neo4j/test/impl/EphemeralIdGenerator.java +++ b/community/kernel/src/test/java/org/neo4j/test/impl/EphemeralIdGenerator.java @@ -20,7 +20,7 @@ package org.neo4j.test.impl; import java.io.File; -import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; @@ -36,7 +36,7 @@ public class EphemeralIdGenerator implements IdGenerator { public static class Factory implements IdGeneratorFactory { - protected final Map generators = new EnumMap<>( IdType.class ); + protected final Map generators = new HashMap<>(); @Override public IdGenerator open( File fileName, int grabSize, IdType idType, long highId ) diff --git a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/HaRequestType210.java b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/HaRequestType210.java index f75df8f509d94..4ec2b938960fa 100644 --- a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/HaRequestType210.java +++ b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/HaRequestType210.java @@ -19,10 +19,10 @@ */ package org.neo4j.kernel.ha; -import java.io.IOException; - import org.jboss.netty.buffer.ChannelBuffer; +import java.io.IOException; + import org.neo4j.com.ObjectSerializer; import org.neo4j.com.Protocol; import org.neo4j.com.RequestContext; @@ -58,7 +58,7 @@ public enum HaRequestType210 implements RequestType public Response call( Master master, RequestContext context, ChannelBuffer input, ChannelBuffer target ) { - IdType idType = IdType.values()[input.readByte()]; + IdType idType = IdType.forName( IdType.Name.values()[input.readByte()] ); return master.allocateIds( context, idType ); } }, new ObjectSerializer() diff --git a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/MasterClient210.java b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/MasterClient210.java index d8780ea4778a7..fd4c8ec5b2551 100644 --- a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/MasterClient210.java +++ b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/MasterClient210.java @@ -135,7 +135,7 @@ public Response allocateIds( RequestContext context, final IdType @Override public void write( ChannelBuffer buffer ) throws IOException { - buffer.writeByte( idType.ordinal() ); + buffer.writeByte( idType.getName().ordinal() ); } }, new Deserializer() { diff --git a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java index 82a1acd7f360c..2fea4b4de43cc 100644 --- a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java +++ b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java @@ -129,6 +129,7 @@ import org.neo4j.kernel.impl.core.TokenCreator; import org.neo4j.kernel.impl.enterprise.EnterpriseConstraintSemantics; import org.neo4j.kernel.impl.enterprise.EnterpriseEditionModule; +import org.neo4j.kernel.impl.enterprise.configuration.EnterpriseEditionConfigurator; import org.neo4j.kernel.impl.factory.CommunityEditionModule; import org.neo4j.kernel.impl.factory.EditionModule; import org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory; @@ -188,6 +189,9 @@ public HighlyAvailableEditionModule( final PlatformModule platformModule ) final LogService logging = platformModule.logging; final Monitors monitors = platformModule.monitors; + // configure enterprise specifics + new EnterpriseEditionConfigurator( config ).configure(); + // Set Netty logger InternalLoggerFactory.setDefaultFactory( new NettyLoggerFactory( logging.getInternalLogProvider() ) ); diff --git a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/id/HaIdGeneratorFactory.java b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/id/HaIdGeneratorFactory.java index 475e350ef8fc9..c5c6e81da28dd 100644 --- a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/id/HaIdGeneratorFactory.java +++ b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/id/HaIdGeneratorFactory.java @@ -21,7 +21,7 @@ import java.io.File; import java.util.Arrays; -import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; import org.neo4j.com.ComException; @@ -44,7 +44,7 @@ public class HaIdGeneratorFactory implements IdGeneratorFactory { - private final Map generators = new EnumMap<>( IdType.class ); + private final Map generators = new HashMap<>(); private final FileSystemAbstraction fs; private final IdGeneratorFactory localFactory; private final DelegateInvocationHandler master; diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java index b83308252ba39..1db9b702b0807 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java @@ -19,7 +19,9 @@ */ package org.neo4j.kernel.impl.enterprise; +import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.constraints.ConstraintSemantics; +import org.neo4j.kernel.impl.enterprise.configuration.EnterpriseEditionConfigurator; import org.neo4j.kernel.impl.factory.CommunityEditionModule; import org.neo4j.kernel.impl.factory.EditionModule; import org.neo4j.kernel.impl.factory.PlatformModule; @@ -35,6 +37,11 @@ public EnterpriseEditionModule( PlatformModule platformModule ) super( platformModule ); } + protected void preConfigureEdition( Config config ) + { + new EnterpriseEditionConfigurator( config ).configure(); + } + @Override protected ConstraintSemantics createSchemaRuleVerifier() { diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionConfigurator.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionConfigurator.java new file mode 100644 index 0000000000000..a563ce4c4b871 --- /dev/null +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionConfigurator.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2002-2016 "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.enterprise.configuration; + +import java.util.List; + +import org.neo4j.kernel.IdType; +import org.neo4j.kernel.configuration.Config; + +/** + * Configurer for enterprise edition specifics. + */ +public class EnterpriseEditionConfigurator +{ + + private Config config; + + public EnterpriseEditionConfigurator(Config config) + { + this.config = config; + } + + /** + * Performs specific configuration + */ + public void configure() + { + List typesToReuse = config.get( EnterpriseEditionSettings.idTypesToReuse ); + for ( String typeName : typesToReuse ) + { + IdType.forName( IdType.Name.valueOf( typeName ) ).setAllowAggressiveReuse( true ); + } + } +} diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionSettings.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionSettings.java new file mode 100644 index 0000000000000..dda4e52420669 --- /dev/null +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionSettings.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2002-2016 "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.enterprise.configuration; + + +import java.util.List; + +import org.neo4j.graphdb.config.Setting; +import org.neo4j.graphdb.factory.Description; +import org.neo4j.kernel.IdType; +import org.neo4j.kernel.configuration.Settings; + +/** + * Enterprise edition specific settings + */ +public class EnterpriseEditionSettings +{ + @Description( "Specified names of id types that should be reused." ) + static Setting> idTypesToReuse = + Settings.setting( "dbms.ids.reuse.types.override", Settings.STRING_LIST, IdType.Name.RELATIONSHIP.name() ); + +} diff --git a/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionConfiguratorTest.java b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionConfiguratorTest.java new file mode 100644 index 0000000000000..0a878c6d0dc67 --- /dev/null +++ b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/enterprise/configuration/EnterpriseEditionConfiguratorTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2002-2016 "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.enterprise.configuration; + + +import org.apache.commons.lang3.StringUtils; +import org.junit.After; +import org.junit.Test; + +import java.util.Map; + +import org.neo4j.kernel.IdType; +import org.neo4j.kernel.configuration.Config; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.neo4j.helpers.collection.MapUtil.stringMap; + +public class EnterpriseEditionConfiguratorTest +{ + + @After + public void setUp() + { + IdType.RELATIONSHIP.setAllowAggressiveReuse( false ); + IdType.SCHEMA.setAllowAggressiveReuse( false ); + } + + @Test + public void configureIdTypeToBeReusableByDefault() + { + new EnterpriseEditionConfigurator( new Config() ).configure(); + assertTrue( IdType.RELATIONSHIP.allowAggressiveReuse() ); + } + + @Test + public void skipConfigurationOfIdTypesWhenNotConfigured() + { + Config config = new Config( stringMap( EnterpriseEditionSettings.idTypesToReuse.name(), "" ) ); + new EnterpriseEditionConfigurator( config ).configure(); + assertFalse( IdType.RELATIONSHIP.allowAggressiveReuse() ); + } + + @Test + public void configureMultipleTypesToBeReusable() + { + Map configMap = getConfigWithMutipleIdTypes(); + new EnterpriseEditionConfigurator( new Config(configMap) ).configure(); + assertTrue( IdType.RELATIONSHIP.allowAggressiveReuse() ); + assertTrue( IdType.SCHEMA.allowAggressiveReuse() ); + } + + private Map getConfigWithMutipleIdTypes() + { + String[] idTypes = {IdType.RELATIONSHIP.getName().name(), IdType.SCHEMA.getName().name()}; + return stringMap( EnterpriseEditionSettings.idTypesToReuse.name(), StringUtils.join( idTypes, "," ) ); + } + +} \ No newline at end of file