From 808437308a598f1239d20b3191dc204aeeb2499a Mon Sep 17 00:00:00 2001 From: Hugo Firth Date: Mon, 30 Apr 2018 16:45:25 +0100 Subject: [PATCH] Akka based discovery service. *NeoServer selects discovery service back end from config. Introduce SslDiscoveryServiceFactory interface. Cluster test class has type parameter to distinguish SSL/non SSL discovery service factory. --- .../src/main/resources/Creative Commons 0 | 121 ++++++++++++++++++ .../licensing/licensing-requirements-base.xml | 4 + .../neo4j/helpers/collection/Iterators.java | 11 ++ .../configuration/ssl/SslPolicyConfig.java | 4 +- .../input/ByteBufferReadableChannel.java | 1 - .../neo4j/server/CommunityBootstrapper.java | 2 - .../ssl/EssentialEngineModifications.java | 4 +- ...ostnameVerificationEngineModification.java | 2 +- .../main/java/org/neo4j/ssl/SslPolicy.java | 5 + .../backup/impl/OnlineBackupCommandCcIT.java | 47 +++---- .../neo4j/causalclustering/BackupCoreIT.java | 6 +- .../causalclustering/BackupReadReplicaIT.java | 2 +- .../causalclustering/ClusterSeedingIT.java | 9 +- .../causalclustering/NewMemberSeedingIT.java | 7 +- .../backup_stores/AbstractStoreGenerator.java | 4 +- .../backup_stores/BackupStore.java | 2 +- .../BackupStoreWithSomeData.java | 2 +- ...StoreWithSomeDataButNoTransactionLogs.java | 2 +- .../backup_stores/EmptyBackupStore.java | 2 +- .../backup_stores/NoStore.java | 2 +- .../cluster_load/ClusterLoad.java | 2 +- .../causalclustering/cluster_load/NoLoad.java | 2 +- .../cluster_load/SmallBurst.java | 2 +- enterprise/causal-clustering/pom.xml | 8 +- .../core/CausalClusteringSettings.java | 6 + .../core/CoreGraphDatabase.java | 6 - .../core/EnterpriseCoreEditionModule.java | 4 +- .../core/consensus/LeaderInfo.java | 23 +++- .../AbstractCoreTopologyService.java | 90 +++++++++++++ .../discovery/ClientConnectorAddresses.java | 35 +++++ .../discovery/CoreServerInfo.java | 57 ++++++++- .../discovery/CoreTopology.java | 2 +- .../CoreTopologyListenerService.java | 12 +- .../discovery/DiscoveryServiceFactory.java | 2 +- .../DiscoveryServiceFactorySelector.java | 44 +++++++ ...rpriseDiscoveryServiceFactorySelector.java | 37 ++++++ .../discovery/HazelcastClient.java | 14 +- .../discovery/HazelcastClusterTopology.java | 4 +- .../HazelcastCoreTopologyService.java | 96 ++++---------- .../HazelcastDiscoveryServiceFactory.java | 2 +- .../discovery/ReadReplicaInfo.java | 39 ++++++ .../discovery/ReadReplicaTopology.java | 25 +++- .../causalclustering/discovery/RoleInfo.java | 16 --- .../discovery/TopologyDifference.java | 4 +- .../discovery/TopologyService.java | 3 + .../messaging/NetworkFlushableByteBuf.java | 1 - .../messaging/marshalling/BooleanMarshal.java | 45 +++++++ .../InputStreamReadableChannel.java | 81 ++++++++++++ .../OutputStreamWritableChannel.java | 88 +++++++++++++ .../messaging/marshalling/StringMarshal.java | 5 + .../EnterpriseReadReplicaEditionModule.java | 7 +- .../readreplica/ReadReplicaGraphDatabase.java | 5 +- .../GetRoutersForAllDatabasesProcedure.java | 2 + .../core/EnterpriseCoreEditionModuleIT.java | 2 +- .../causalclustering/discovery/Cluster.java | 66 ++-------- .../discovery/EnterpriseCluster.java | 120 +++++++++++++++++ .../discovery/HazelcastClientTest.java | 35 +++-- .../discovery/ReadReplica.java | 11 +- .../discovery/SharedDiscoveryCoreClient.java | 114 ++++++----------- .../SharedDiscoveryReadReplicaClient.java | 12 +- .../SharedDiscoveryServiceFactory.java | 2 +- .../discovery/TestTopology.java | 19 ++- .../ClusterOverviewProcedureTest.java | 8 +- .../causalclustering/helpers/DataCreator.java | 4 +- .../identity/ClusterBinderTest.java | 2 +- .../marshalling/StringMarshalTest.java | 62 +++++++++ .../GetServersProcedureV1RoutingTest.java | 6 +- .../procedure/GetServersProcedureV1Test.java | 60 ++++----- ...milyIT.java => BaseClusterIpFamilyIT.java} | 39 ++---- ...viewIT.java => BaseClusterOverviewIT.java} | 56 ++++---- ...IT.java => BaseMultiClusterRoutingIT.java} | 36 ++---- ...ringIT.java => BaseMultiClusteringIT.java} | 38 ++---- .../CausalClusteringProceduresIT.java | 2 +- .../scenarios/CausalClusteringRolesIT.java | 2 +- .../scenarios/ClusterBindingIT.java | 2 +- .../ClusterCommunityToEnterpriseIT.java | 5 +- .../scenarios/ClusterCompressionIT.java | 2 +- .../scenarios/ClusterCustomLogLocationIT.java | 2 +- .../scenarios/ClusterDiscoveryIT.java | 4 +- .../scenarios/ClusterFormationIT.java | 2 +- .../scenarios/ClusterIdReuseIT.java | 6 +- .../scenarios/ClusterIndexProcedureIT.java | 2 +- .../scenarios/ClusterLeaderStepDownIT.java | 2 +- .../scenarios/ClusterShutdownIT.java | 4 +- .../scenarios/ConsensusGroupSettingsIT.java | 2 +- .../scenarios/CorePruningIT.java | 4 +- .../scenarios/CoreReplicationIT.java | 2 +- .../scenarios/CoreToCoreCopySnapshotIT.java | 8 +- .../CoreTopologyServiceIT.java} | 39 ++++-- .../scenarios/DiscoveryServiceType.java | 22 +--- .../EnterpriseClusterIpFamilyIT.java | 60 +++++++++ .../EnterpriseClusterOverviewIT.java | 44 +++++++ .../EnterpriseMultiClusterRoutingIT.java | 60 +++++++++ .../EnterpriseMultiClusteringIT.java | 59 +++++++++ .../HazelcastCoreTopologyServiceIT.java | 31 +++++ .../InstalledProtocolsProcedureIT.java | 3 +- .../scenarios/PreElectionIT.java | 6 +- .../ReadReplicaHierarchicalCatchupIT.java | 2 +- .../scenarios/ReadReplicaReplicationIT.java | 24 ++-- .../scenarios/ReadReplicaStoreCopyIT.java | 6 +- .../ReadReplicaToReadReplicaCatchupIT.java | 6 +- .../scenarios/RecoveryIT.java | 6 +- .../causalclustering/scenarios/RestartIT.java | 10 +- .../scenarios/SampleData.java | 2 +- .../scenarios/ServerGroupsIT.java | 5 +- .../ServerPoliciesLoadBalancingIT.java | 11 +- .../SharedDiscoveryServiceIT.java | 10 +- .../scenarios/TransactionLogRecoveryIT.java | 2 +- .../scenarios/UnavailableIT.java | 2 +- .../scenarios/WillNotBecomeLeaderIT.java | 3 +- ...ConnectToRandomCoreServerStrategyTest.java | 11 +- .../UserDefinedConfigurationStrategyTest.java | 13 +- .../impl/muninn/VersionContextTrackingIT.java | 2 +- .../test/causalclustering/ClusterRule.java | 18 +-- .../test/causalclustering/ClusterRuleIT.java | 4 +- .../org/neo4j/metrics/CoreEdgeMetricsIT.java | 3 +- .../RaftMessageProcessingMetricIT.java | 2 +- .../CausalClusterInProcessBuilder.java | 21 ++- .../harness/CausalClusterInProcessRunner.java | 17 --- .../ClusterOfClustersInProcessRunner.java | 6 +- .../EnterpriseInProcessServerBuilder.java | 25 +++- .../enterprise/OpenEnterpriseNeoServer.java | 30 +++-- .../OpenEnterpriseNeoServerTest.java | 4 +- .../helpers/EnterpriseServerBuilder.java | 3 +- .../enterprise/jmx/ServerManagementIT.java | 4 +- .../scenarios/BoltCausalClusteringIT.java | 8 +- .../ConvertNonCausalClusteringStoreIT.java | 2 +- .../org/neo4j/kernel/PageCacheWarmupCcIT.java | 2 +- .../stresstests/CatchupNewReadReplica.java | 2 +- .../stresstests/ConsistencyCheck.java | 2 +- .../CreateNodesWithProperties.java | 4 +- .../causalclustering/stresstests/IdReuse.java | 10 +- .../stresstests/RepeatOnRandomCore.java | 2 +- .../stresstests/RepeatOnRandomMember.java | 2 +- .../stresstests/ReplaceRandomMember.java | 2 +- .../stresstests/Resources.java | 9 +- 136 files changed, 1691 insertions(+), 681 deletions(-) create mode 100644 build-resources/src/main/resources/Creative Commons 0 create mode 100644 enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/AbstractCoreTopologyService.java create mode 100644 enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/DiscoveryServiceFactorySelector.java create mode 100644 enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/EnterpriseDiscoveryServiceFactorySelector.java create mode 100644 enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/BooleanMarshal.java create mode 100644 enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/InputStreamReadableChannel.java create mode 100644 enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/OutputStreamWritableChannel.java create mode 100644 enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/EnterpriseCluster.java rename enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/{ClusterIpFamilyIT.java => BaseClusterIpFamilyIT.java} (68%) rename enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/{ClusterOverviewIT.java => BaseClusterOverviewIT.java} (88%) rename enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/{MultiClusterRoutingIT.java => BaseMultiClusterRoutingIT.java} (85%) rename enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/{MultiClusteringIT.java => BaseMultiClusteringIT.java} (83%) rename enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/{discovery/HazelcastCoreTopologyServiceTest.java => scenarios/CoreTopologyServiceIT.java} (65%) create mode 100644 enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseClusterIpFamilyIT.java create mode 100644 enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseClusterOverviewIT.java create mode 100644 enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseMultiClusterRoutingIT.java create mode 100644 enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseMultiClusteringIT.java create mode 100644 enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/HazelcastCoreTopologyServiceIT.java rename enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/{discovery => scenarios}/SharedDiscoveryServiceIT.java (90%) diff --git a/build-resources/src/main/resources/Creative Commons 0 b/build-resources/src/main/resources/Creative Commons 0 new file mode 100644 index 0000000000000..0e259d42c9967 --- /dev/null +++ b/build-resources/src/main/resources/Creative Commons 0 @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/build-resources/src/main/resources/licensing/licensing-requirements-base.xml b/build-resources/src/main/resources/licensing/licensing-requirements-base.xml index 6b72268fd46f6..6243a137eb4c4 100644 --- a/build-resources/src/main/resources/licensing/licensing-requirements-base.xml +++ b/build-resources/src/main/resources/licensing/licensing-requirements-base.xml @@ -37,6 +37,7 @@ Mozilla Public License, Version 2.0 SIL OFL 1.1 ISC + Creative Commons 0 @@ -143,6 +144,9 @@ Bouncy Castle Licence + + CC0 + diff --git a/community/collections/src/main/java/org/neo4j/helpers/collection/Iterators.java b/community/collections/src/main/java/org/neo4j/helpers/collection/Iterators.java index 1b37e080d8078..6b2bb4413b36d 100644 --- a/community/collections/src/main/java/org/neo4j/helpers/collection/Iterators.java +++ b/community/collections/src/main/java/org/neo4j/helpers/collection/Iterators.java @@ -23,6 +23,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.Deque; import java.util.HashSet; import java.util.Iterator; @@ -30,8 +32,10 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.Set; +import java.util.SortedSet; import java.util.Spliterator; import java.util.Spliterators; +import java.util.TreeSet; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Stream; @@ -475,6 +479,13 @@ public static Set asUniqueSet( Iterator items ) return set; } + public static SortedSet asSortedSet( Comparator comparator, T... items ) + { + TreeSet set = new TreeSet<>( comparator ); + Collections.addAll( set, items ); + return set; + } + public static Iterator asIterator( final long... array ) { return new PrefetchingIterator() diff --git a/community/kernel/src/main/java/org/neo4j/kernel/configuration/ssl/SslPolicyConfig.java b/community/kernel/src/main/java/org/neo4j/kernel/configuration/ssl/SslPolicyConfig.java index bcbbaa686dea9..17144fbe0faff 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/configuration/ssl/SslPolicyConfig.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/configuration/ssl/SslPolicyConfig.java @@ -31,7 +31,7 @@ import org.neo4j.ssl.ClientAuth; import static java.lang.String.join; -import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; import static org.neo4j.kernel.configuration.Settings.BOOLEAN; import static org.neo4j.kernel.configuration.Settings.FALSE; import static org.neo4j.kernel.configuration.Settings.NO_DEFAULT; @@ -46,7 +46,7 @@ @Group( "dbms.ssl.policy" ) public class SslPolicyConfig implements LoadableConfig { - public static final List TLS_VERSION_DEFAULTS = asList( "TLSv1.2" ); + public static final List TLS_VERSION_DEFAULTS = singletonList( "TLSv1.2" ); public static final List CIPHER_SUITES_DEFAULTS = null; @Description( "The mandatory base directory for cryptographic objects of this policy." + diff --git a/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/input/ByteBufferReadableChannel.java b/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/input/ByteBufferReadableChannel.java index d8aea366fae0d..1da00d5451236 100644 --- a/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/input/ByteBufferReadableChannel.java +++ b/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/input/ByteBufferReadableChannel.java @@ -19,7 +19,6 @@ */ package org.neo4j.unsafe.impl.batchimport.input; -import java.io.IOException; import java.nio.ByteBuffer; import org.neo4j.kernel.impl.transaction.log.ReadableClosableChannel; diff --git a/community/server/src/main/java/org/neo4j/server/CommunityBootstrapper.java b/community/server/src/main/java/org/neo4j/server/CommunityBootstrapper.java index d6710ba94f73b..4204028d34d38 100644 --- a/community/server/src/main/java/org/neo4j/server/CommunityBootstrapper.java +++ b/community/server/src/main/java/org/neo4j/server/CommunityBootstrapper.java @@ -31,7 +31,6 @@ public class CommunityBootstrapper extends ServerBootstrapper { - @Override protected NeoServer createNeoServer( Config config, GraphDatabaseDependencies dependencies, LogProvider logProvider ) @@ -45,5 +44,4 @@ protected Collection configurationValidators() { return Collections.singletonList( new ServerConfigurationValidator() ); } - } diff --git a/community/ssl/src/main/java/org/neo4j/ssl/EssentialEngineModifications.java b/community/ssl/src/main/java/org/neo4j/ssl/EssentialEngineModifications.java index a1e6e63aecacc..041d5adfe59b0 100644 --- a/community/ssl/src/main/java/org/neo4j/ssl/EssentialEngineModifications.java +++ b/community/ssl/src/main/java/org/neo4j/ssl/EssentialEngineModifications.java @@ -22,12 +22,12 @@ import java.util.function.Function; import javax.net.ssl.SSLEngine; -class EssentialEngineModifications implements Function +public class EssentialEngineModifications implements Function { private final String[] tlsVersions; private final boolean isClient; - EssentialEngineModifications( String[] tlsVersions, boolean isClient ) + public EssentialEngineModifications( String[] tlsVersions, boolean isClient ) { this.tlsVersions = tlsVersions; this.isClient = isClient; diff --git a/community/ssl/src/main/java/org/neo4j/ssl/HostnameVerificationEngineModification.java b/community/ssl/src/main/java/org/neo4j/ssl/HostnameVerificationEngineModification.java index a87373298cca7..4bc09f54d01ad 100644 --- a/community/ssl/src/main/java/org/neo4j/ssl/HostnameVerificationEngineModification.java +++ b/community/ssl/src/main/java/org/neo4j/ssl/HostnameVerificationEngineModification.java @@ -23,7 +23,7 @@ import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLParameters; -class HostnameVerificationEngineModification implements Function +public class HostnameVerificationEngineModification implements Function { /** * Apply modifications to engine to enable hostname verification (client side only) diff --git a/community/ssl/src/main/java/org/neo4j/ssl/SslPolicy.java b/community/ssl/src/main/java/org/neo4j/ssl/SslPolicy.java index 6a3030b31bc1d..dcf95fae2c499 100644 --- a/community/ssl/src/main/java/org/neo4j/ssl/SslPolicy.java +++ b/community/ssl/src/main/java/org/neo4j/ssl/SslPolicy.java @@ -176,6 +176,11 @@ public ClientAuth getClientAuth() return clientAuth; } + public boolean isVerifyHostname() + { + return verifyHostname; + } + @Override public String toString() { diff --git a/enterprise/backup/src/test/java/org/neo4j/backup/impl/OnlineBackupCommandCcIT.java b/enterprise/backup/src/test/java/org/neo4j/backup/impl/OnlineBackupCommandCcIT.java index fa9c0e1f59b45..5373d34991332 100644 --- a/enterprise/backup/src/test/java/org/neo4j/backup/impl/OnlineBackupCommandCcIT.java +++ b/enterprise/backup/src/test/java/org/neo4j/backup/impl/OnlineBackupCommandCcIT.java @@ -50,6 +50,7 @@ import org.neo4j.causalclustering.core.consensus.roles.Role; import org.neo4j.causalclustering.discovery.Cluster; import org.neo4j.causalclustering.discovery.CoreClusterMember; +import org.neo4j.causalclustering.discovery.EnterpriseCluster; import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; import org.neo4j.causalclustering.discovery.IpFamily; import org.neo4j.causalclustering.discovery.SharedDiscoveryServiceFactory; @@ -120,7 +121,7 @@ public void initialiseBackupDirectory() @Test public void backupCanBePerformedOverCcWithCustomPort() throws Exception { - Cluster cluster = startCluster( recordFormat ); + Cluster cluster = startCluster( recordFormat ); String customAddress = CausalClusteringTestHelpers.transactionAddress( clusterLeader( cluster ).database() ); assertEquals( 0, runBackupOtherJvm( customAddress, DATABASE_NAME ) ); @@ -135,7 +136,7 @@ public void backupCanBePerformedOverCcWithCustomPort() throws Exception public void dataIsInAUsableStateAfterBackup() throws Exception { // given database exists - Cluster cluster = startCluster( recordFormat ); + Cluster cluster = startCluster( recordFormat ); // and the database has indexes ClusterHelper.createIndexes( cluster.getMemberWithAnyRole( Role.LEADER ).database() ); @@ -165,7 +166,7 @@ public void backupCanBeOptionallySwitchedOnWithTheBackupConfig() throws Exceptio String value = "localhost:%d"; clusterRule = clusterRule.withSharedCoreParam( OnlineBackupSettings.online_backup_enabled, "true" ) .withInstanceCoreParam( online_backup_server, i -> format( value, backupPorts[i] ) ); - Cluster cluster = startCluster( recordFormat ); + Cluster cluster = startCluster( recordFormat ); String customAddress = "localhost:" + backupPorts[0]; // when a full backup is performed @@ -199,7 +200,7 @@ public void secondaryTransactionProtocolIsSwitchedOffCorrespondingBackupSetting( public void backupDoesntDisplayExceptionWhenSuccessful() throws Exception { // given - Cluster cluster = startCluster( recordFormat ); + Cluster cluster = startCluster( recordFormat ); String customAddress = CausalClusteringTestHelpers.transactionAddress( clusterLeader( cluster ).database() ); // when @@ -214,7 +215,7 @@ public void backupDoesntDisplayExceptionWhenSuccessful() throws Exception public void reportsProgress() throws Exception { // given - Cluster cluster = startCluster( recordFormat ); + Cluster cluster = startCluster( recordFormat ); ClusterHelper.createIndexes( cluster.getMemberWithAnyRole( Role.LEADER ).database() ); String customAddress = CausalClusteringTestHelpers.backupAddress( clusterLeader( cluster ).database() ); @@ -241,7 +242,7 @@ public void reportsProgress() throws Exception public void onlyTheLatestTransactionIsKeptAfterIncrementalBackup() throws Exception { // given database exists with data - Cluster cluster = startCluster( recordFormat ); + Cluster cluster = startCluster( recordFormat ); createSomeData( cluster ); // and backup client is told to rotate conveniently @@ -290,14 +291,14 @@ public void backupRenamesWork() throws Exception { // given a prexisting backup from a different store String backupName = "preexistingBackup_" + recordFormat; - Cluster cluster = startCluster( recordFormat ); + Cluster cluster = startCluster( recordFormat ); String firstBackupAddress = CausalClusteringTestHelpers.transactionAddress( clusterLeader( cluster ).database() ); assertEquals( 0, runBackupOtherJvm( firstBackupAddress, backupName ) ); DbRepresentation firstDatabaseRepresentation = DbRepresentation.of( clusterLeader( cluster ).database() ); // and a different database - Cluster cluster2 = startCluster2( recordFormat ); + Cluster cluster2 = startCluster2( recordFormat ); DbRepresentation secondDatabaseRepresentation = DbRepresentation.of( clusterLeader( cluster2 ).database() ); assertNotEquals( firstDatabaseRepresentation, secondDatabaseRepresentation ); String secondBackupAddress = CausalClusteringTestHelpers.transactionAddress( clusterLeader( cluster2 ).database() ); @@ -329,7 +330,7 @@ private int runBackupOtherJvm( String customAddress, String databaseName ) throw public void ipv6Enabled() throws Exception { // given - Cluster cluster = startIpv6Cluster(); + Cluster cluster = startIpv6Cluster(); try { assertNotNull( DbRepresentation.of( clusterDatabase( cluster ) ) ); @@ -416,7 +417,7 @@ public void close() }; } - private static void repeatedlyPopulateDatabase( Cluster cluster, AtomicBoolean continueFlagReference ) + private static void repeatedlyPopulateDatabase( Cluster cluster, AtomicBoolean continueFlagReference ) { while ( continueFlagReference.get() ) { @@ -424,21 +425,21 @@ private static void repeatedlyPopulateDatabase( Cluster cluster, AtomicBoolean c } } - public static CoreGraphDatabase clusterDatabase( Cluster cluster ) + public static CoreGraphDatabase clusterDatabase( Cluster cluster ) { return clusterLeader( cluster ).database(); } - private Cluster startCluster( String recordFormat ) throws Exception + private Cluster startCluster( String recordFormat ) throws Exception { ClusterRule clusterRule = this.clusterRule.withSharedCoreParam( GraphDatabaseSettings.record_format, recordFormat ) .withSharedReadReplicaParam( GraphDatabaseSettings.record_format, recordFormat ); - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); createSomeData( cluster ); return cluster; } - private Cluster startIpv6Cluster() throws ExecutionException, InterruptedException + private Cluster startIpv6Cluster() throws ExecutionException, InterruptedException { DiscoveryServiceFactory discoveryServiceFactory = new SharedDiscoveryServiceFactory(); File parentDir = testDirectory.directory( "ipv6_cluster" ); @@ -450,27 +451,27 @@ private Cluster startIpv6Cluster() throws ExecutionException, InterruptedExcepti readReplicaParams.put( GraphDatabaseSettings.record_format.name(), recordFormat ); Map> instanceReadReplicaParams = new HashMap<>(); - Cluster cluster = new Cluster( parentDir, 3, 3, discoveryServiceFactory, coreParams, instanceCoreParams, readReplicaParams, instanceReadReplicaParams, - recordFormat, IpFamily.IPV6, false ); + Cluster cluster = new EnterpriseCluster( parentDir, 3, 3, discoveryServiceFactory, coreParams, instanceCoreParams, readReplicaParams, + instanceReadReplicaParams, recordFormat, IpFamily.IPV6, false ); cluster.start(); createSomeData( cluster ); return cluster; } - private Cluster startCluster2( String recordFormat ) throws ExecutionException, InterruptedException + private Cluster startCluster2( String recordFormat ) throws ExecutionException, InterruptedException { Map sharedParams = new HashMap<>( ); sharedParams.put( GraphDatabaseSettings.record_format.name(), recordFormat ); - Cluster cluster = - new Cluster( testDirectory.directory( "cluster-b_" + recordFormat ), 3, 0, new SharedDiscoveryServiceFactory(), sharedParams, emptyMap(), - sharedParams, emptyMap(), + Cluster cluster = + new EnterpriseCluster( testDirectory.directory( "cluster-b_" + recordFormat ), 3, 0, new SharedDiscoveryServiceFactory(), + sharedParams, emptyMap(), sharedParams, emptyMap(), recordFormat, IpFamily.IPV4, false ); cluster.start(); createSomeData( cluster ); return cluster; } - private static void transactions1M( Cluster cluster ) throws Exception + private static void transactions1M( Cluster cluster ) throws Exception { int numberOfTransactions = 500; long sizeOfTransaction = (ByteUnit.mebiBytes( 1 ) / numberOfTransactions) + 1; @@ -487,7 +488,7 @@ private static void transactions1M( Cluster cluster ) throws Exception } } - public static void createSomeData( Cluster cluster ) + public static void createSomeData( Cluster cluster ) { try { @@ -499,7 +500,7 @@ public static void createSomeData( Cluster cluster ) } } - private static CoreClusterMember clusterLeader( Cluster cluster ) + private static CoreClusterMember clusterLeader( Cluster cluster ) { return cluster.getMemberWithRole( Role.LEADER ); } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/BackupCoreIT.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/BackupCoreIT.java index 5b35078cd614f..6bc8d4e51eb16 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/BackupCoreIT.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/BackupCoreIT.java @@ -63,7 +63,7 @@ public class BackupCoreIT .withNumberOfCoreMembers( 3 ) .withNumberOfReadReplicas( 0 ); - private Cluster cluster; + private Cluster cluster; private File backupsDir; @Before @@ -95,7 +95,7 @@ public void makeSureBackupCanBePerformedFromAnyInstance() throws Throwable } } - static CoreGraphDatabase createSomeData( Cluster cluster ) throws Exception + static CoreGraphDatabase createSomeData( Cluster cluster ) throws Exception { return cluster.coreTx( ( db, tx ) -> { @@ -105,7 +105,7 @@ static CoreGraphDatabase createSomeData( Cluster cluster ) throws Exception } ).database(); } - private static String backupAddress( Cluster cluster ) + private static String backupAddress( Cluster cluster ) { return cluster.getMemberWithRole( Role.LEADER ).settingValue( "causal_clustering.transaction_listen_address" ); } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/BackupReadReplicaIT.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/BackupReadReplicaIT.java index b4ec08c793038..7b6282505d110 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/BackupReadReplicaIT.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/BackupReadReplicaIT.java @@ -62,7 +62,7 @@ public class BackupReadReplicaIT .withNumberOfReadReplicas( 1 ) .withSharedReadReplicaParam( OnlineBackupSettings.online_backup_enabled, Settings.TRUE ); - private Cluster cluster; + private Cluster cluster; private File backupPath; @Before diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/ClusterSeedingIT.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/ClusterSeedingIT.java index 96882f46dbff5..fbed4abb0fa88 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/ClusterSeedingIT.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/ClusterSeedingIT.java @@ -40,6 +40,7 @@ import org.neo4j.causalclustering.backup_stores.NoStore; import org.neo4j.causalclustering.discovery.Cluster; import org.neo4j.causalclustering.discovery.CoreClusterMember; +import org.neo4j.causalclustering.discovery.EnterpriseCluster; import org.neo4j.causalclustering.discovery.IpFamily; import org.neo4j.causalclustering.discovery.SharedDiscoveryServiceFactory; import org.neo4j.graphdb.factory.GraphDatabaseSettings; @@ -71,8 +72,8 @@ public class ClusterSeedingIT @Rule public RuleChain rules = RuleChain.outerRule( fileSystemRule ).around( testDir ).around( suppressOutput ); - private Cluster backupCluster; - private Cluster cluster; + private Cluster backupCluster; + private Cluster cluster; private FileCopyDetector fileCopyDetector; private File baseBackupDir; @@ -87,11 +88,11 @@ public static Object[][] data() public void setup() { this.fileCopyDetector = new FileCopyDetector(); - backupCluster = new Cluster( testDir.directory( "cluster-for-backup" ), 3, 0, + backupCluster = new EnterpriseCluster( testDir.directory( "cluster-for-backup" ), 3, 0, new SharedDiscoveryServiceFactory(), emptyMap(), emptyMap(), emptyMap(), emptyMap(), Standard .LATEST_NAME, IpFamily.IPV4, false ); - cluster = new Cluster( testDir.directory( "cluster-b" ), 3, 0, + cluster = new EnterpriseCluster( testDir.directory( "cluster-b" ), 3, 0, new SharedDiscoveryServiceFactory(), emptyMap(), emptyMap(), emptyMap(), emptyMap(), Standard.LATEST_NAME, IpFamily.IPV4, false ); diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/NewMemberSeedingIT.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/NewMemberSeedingIT.java index b15f8e1be7d39..9df1343457c75 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/NewMemberSeedingIT.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/NewMemberSeedingIT.java @@ -44,6 +44,7 @@ import org.neo4j.causalclustering.cluster_load.SmallBurst; import org.neo4j.causalclustering.discovery.Cluster; import org.neo4j.causalclustering.discovery.CoreClusterMember; +import org.neo4j.causalclustering.discovery.EnterpriseCluster; import org.neo4j.causalclustering.discovery.IpFamily; import org.neo4j.causalclustering.discovery.SharedDiscoveryServiceFactory; import org.neo4j.kernel.impl.store.format.standard.Standard; @@ -72,7 +73,7 @@ public class NewMemberSeedingIT @Rule public RuleChain rules = RuleChain.outerRule( fileSystemRule ).around( testDir ).around( suppressOutput ); - private Cluster cluster; + private Cluster cluster; private FileCopyDetector fileCopyDetector; private File baseBackupDir; @@ -109,8 +110,8 @@ private static Iterable stores() public void setup() { this.fileCopyDetector = new FileCopyDetector(); - cluster = new Cluster( testDir.directory( "cluster-b" ), 3, 0, new SharedDiscoveryServiceFactory(), emptyMap(), emptyMap(), emptyMap(), emptyMap(), - Standard.LATEST_NAME, IpFamily.IPV4, false ); + cluster = new EnterpriseCluster( testDir.directory( "cluster-b" ), 3, 0, new SharedDiscoveryServiceFactory(), emptyMap(), emptyMap(), + emptyMap(), emptyMap(), Standard.LATEST_NAME, IpFamily.IPV4, false ); baseBackupDir = testDir.directory( "backups" ); } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/AbstractStoreGenerator.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/AbstractStoreGenerator.java index 03dd3c2ca4a5a..5b1ec3037603c 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/AbstractStoreGenerator.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/AbstractStoreGenerator.java @@ -33,12 +33,12 @@ public abstract class AbstractStoreGenerator implements BackupStore { - abstract CoreClusterMember createData( Cluster cluster ) throws Exception; + abstract CoreClusterMember createData( Cluster cluster ) throws Exception; abstract void modify( File backup ); @Override - public Optional generate( File backupDir, Cluster backupCluster ) throws Exception + public Optional generate( File backupDir, Cluster backupCluster ) throws Exception { CoreClusterMember core = createData( backupCluster ); File backupFromCore = createBackupFromCore( core, backupName(), backupDir ); diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStore.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStore.java index 968d012045834..993c45e35eb64 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStore.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStore.java @@ -29,5 +29,5 @@ public interface BackupStore { - Optional generate( File backupDir, Cluster backupCluster ) throws Exception; + Optional generate( File backupDir, Cluster backupCluster ) throws Exception; } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStoreWithSomeData.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStoreWithSomeData.java index a358ec9003d0b..c8731fcfc3db9 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStoreWithSomeData.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStoreWithSomeData.java @@ -32,7 +32,7 @@ public class BackupStoreWithSomeData extends AbstractStoreGenerator { @Override - CoreClusterMember createData( Cluster cluster ) throws Exception + CoreClusterMember createData( Cluster cluster ) throws Exception { return createEmptyNodes( cluster, 15 ); } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStoreWithSomeDataButNoTransactionLogs.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStoreWithSomeDataButNoTransactionLogs.java index 179f4fc99760a..3d007d848c040 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStoreWithSomeDataButNoTransactionLogs.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/BackupStoreWithSomeDataButNoTransactionLogs.java @@ -33,7 +33,7 @@ public class BackupStoreWithSomeDataButNoTransactionLogs extends AbstractStoreGenerator { @Override - CoreClusterMember createData( Cluster cluster ) throws Exception + CoreClusterMember createData( Cluster cluster ) throws Exception { return createEmptyNodes( cluster, 10 ); } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/EmptyBackupStore.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/EmptyBackupStore.java index 9a4522427dceb..6667d95ba7458 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/EmptyBackupStore.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/EmptyBackupStore.java @@ -30,7 +30,7 @@ public class EmptyBackupStore extends AbstractStoreGenerator { @Override - CoreClusterMember createData( Cluster cluster ) + CoreClusterMember createData( Cluster cluster ) { return cluster.coreMembers().iterator().next(); } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/NoStore.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/NoStore.java index 840273c2f00bc..10e1fb9e60c00 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/NoStore.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/backup_stores/NoStore.java @@ -30,7 +30,7 @@ public class NoStore implements BackupStore { @Override - public Optional generate( File backupDir, Cluster backupCluster ) + public Optional generate( File backupDir, Cluster backupCluster ) { return Optional.empty(); } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/ClusterLoad.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/ClusterLoad.java index e18d981f047df..0e56462423356 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/ClusterLoad.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/ClusterLoad.java @@ -26,7 +26,7 @@ public interface ClusterLoad { - void start( Cluster cluster ) throws Exception; + void start( Cluster cluster ) throws Exception; void stop(); } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/NoLoad.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/NoLoad.java index 70cd506ca8d20..3096fb3bd3a98 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/NoLoad.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/NoLoad.java @@ -27,7 +27,7 @@ public class NoLoad implements ClusterLoad { @Override - public void start( Cluster cluster ) + public void start( Cluster cluster ) { // do nothing } diff --git a/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/SmallBurst.java b/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/SmallBurst.java index 48995caa95c3c..fab645047687b 100644 --- a/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/SmallBurst.java +++ b/enterprise/backup/src/test/java/org/neo4j/causalclustering/cluster_load/SmallBurst.java @@ -28,7 +28,7 @@ public class SmallBurst implements ClusterLoad { @Override - public void start( Cluster cluster ) throws Exception + public void start( Cluster cluster ) throws Exception { DataCreator.createEmptyNodes( cluster, 10 ); } diff --git a/enterprise/causal-clustering/pom.xml b/enterprise/causal-clustering/pom.xml index 414ab0577ea19..4662de2f6b54d 100644 --- a/enterprise/causal-clustering/pom.xml +++ b/enterprise/causal-clustering/pom.xml @@ -243,6 +243,12 @@ commons-lang3 test + + + org.scalatest + scalatest_${scala.binary.version} + + - + diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/CausalClusteringSettings.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/CausalClusteringSettings.java index 21668aaed8419..132563c77cdaa 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/CausalClusteringSettings.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/CausalClusteringSettings.java @@ -29,6 +29,7 @@ import java.util.logging.Level; import org.neo4j.causalclustering.core.consensus.log.cache.InFlightCacheFactory; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactorySelector; import org.neo4j.causalclustering.discovery.DnsHostnameResolver; import org.neo4j.causalclustering.discovery.DomainNameResolverImpl; import org.neo4j.causalclustering.discovery.HostnameResolver; @@ -222,6 +223,11 @@ public HostnameResolver getHostnameResolver( LogProvider logProvider, LogProvide public static final Setting discovery_type = setting( "causal_clustering.discovery_type", options( DiscoveryType.class ), DiscoveryType.LIST.name() ); + @Description( "Select the middleware used for cluster topology discovery" ) + public static final Setting middleware_type = + setting( "causal_clustering.middleware_type", options( DiscoveryServiceFactorySelector.DiscoveryMiddleware.class ), + DiscoveryServiceFactorySelector.DEFAULT.name() ); + @Description( "Prevents the network middleware from dumping its own logs. Defaults to true." ) public static final Setting disable_middleware_logging = setting( "causal_clustering.disable_middleware_logging", BOOLEAN, TRUE ); diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/CoreGraphDatabase.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/CoreGraphDatabase.java index b0a2618053800..089eeb24835ad 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/CoreGraphDatabase.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/CoreGraphDatabase.java @@ -28,7 +28,6 @@ import org.neo4j.causalclustering.core.consensus.RaftMachine; import org.neo4j.causalclustering.core.consensus.roles.Role; import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; -import org.neo4j.causalclustering.discovery.HazelcastDiscoveryServiceFactory; import org.neo4j.graphdb.facade.GraphDatabaseFacadeFactory; import org.neo4j.graphdb.factory.module.EditionModule; import org.neo4j.graphdb.factory.module.PlatformModule; @@ -44,11 +43,6 @@ protected CoreGraphDatabase() { } - public CoreGraphDatabase( File storeDir, Config config, GraphDatabaseFacadeFactory.Dependencies dependencies ) - { - this( storeDir, config, dependencies, new HazelcastDiscoveryServiceFactory() ); - } - public CoreGraphDatabase( File storeDir, Config config, GraphDatabaseFacadeFactory.Dependencies dependencies, DiscoveryServiceFactory discoveryServiceFactory ) { diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/EnterpriseCoreEditionModule.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/EnterpriseCoreEditionModule.java index 51d7f03e95586..2e44019d211b2 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/EnterpriseCoreEditionModule.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/EnterpriseCoreEditionModule.java @@ -244,7 +244,7 @@ public EnterpriseCoreEditionModule( final PlatformModule platformModule, IdentityModule identityModule = new IdentityModule( platformModule, clusterStateDirectory.get() ); ClusteringModule clusteringModule = getClusteringModule( platformModule, discoveryServiceFactory, - clusterStateDirectory, identityModule, databaseDirectory ); + clusterStateDirectory, identityModule, dependencies, databaseDirectory ); // We need to satisfy the dependency here to keep users of it, such as BoltKernelExtension, happy. dependencies.satisfyDependency( SslPolicyLoader.create( config, logProvider ) ); @@ -369,7 +369,7 @@ private LogFiles buildLocalDatabaseLogFiles( PlatformModule platformModule, File } protected ClusteringModule getClusteringModule( PlatformModule platformModule, DiscoveryServiceFactory discoveryServiceFactory, - ClusterStateDirectory clusterStateDirectory, IdentityModule identityModule, File databaseDirectory ) + ClusterStateDirectory clusterStateDirectory, IdentityModule identityModule, Dependencies dependencies, File databaseDirectory ) { return new ClusteringModule( discoveryServiceFactory, identityModule.myself(), platformModule, clusterStateDirectory.get(), databaseDirectory ); diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/consensus/LeaderInfo.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/consensus/LeaderInfo.java index b6b972f7589dc..2c41c0a8f2d53 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/consensus/LeaderInfo.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/core/consensus/LeaderInfo.java @@ -23,12 +23,12 @@ package org.neo4j.causalclustering.core.consensus; import java.io.Serializable; +import java.util.Objects; import org.neo4j.causalclustering.identity.MemberId; public class LeaderInfo implements Serializable { - private static final long serialVersionUID = 7983780359510842910L; public static final LeaderInfo INITIAL = new LeaderInfo( null, -1 ); @@ -77,4 +77,25 @@ public String toString() { return "LeaderInfo{" + "memberId=" + memberId + ", term=" + term + '}'; } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + LeaderInfo that = (LeaderInfo) o; + return term == that.term && isSteppingDown == that.isSteppingDown && Objects.equals( memberId, that.memberId ); + } + + @Override + public int hashCode() + { + return Objects.hash( memberId, term, isSteppingDown ); + } } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/AbstractCoreTopologyService.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/AbstractCoreTopologyService.java new file mode 100644 index 0000000000000..022de583dba09 --- /dev/null +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/AbstractCoreTopologyService.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.discovery; + +import java.util.Objects; + +import org.neo4j.causalclustering.core.consensus.LeaderInfo; +import org.neo4j.causalclustering.identity.MemberId; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.lifecycle.SafeLifecycle; +import org.neo4j.logging.Log; +import org.neo4j.logging.LogProvider; + +public abstract class AbstractCoreTopologyService extends SafeLifecycle implements CoreTopologyService +{ + protected final CoreTopologyListenerService listenerService = new CoreTopologyListenerService(); + protected final Config config; + protected final MemberId myself; + protected final Log log; + protected final Log userLog; + + protected volatile LeaderInfo leaderInfo = LeaderInfo.INITIAL; + + protected AbstractCoreTopologyService( Config config, MemberId myself, LogProvider logProvider, LogProvider userLogProvider ) + { + this.config = config; + this.myself = myself; + this.log = logProvider.getLog( getClass() ); + this.userLog = userLogProvider.getLog( getClass() ); + } + + @Override + public final synchronized void addLocalCoreTopologyListener( Listener listener ) + { + this.listenerService.addCoreTopologyListener( listener ); + listener.onCoreTopologyChange( localCoreServers() ); + } + + @Override + public final void removeLocalCoreTopologyListener( Listener listener ) + { + listenerService.removeCoreTopologyListener( listener ); + } + + @Override + public final void setLeader( LeaderInfo newLeader, String dbName ) + { + if ( this.leaderInfo.term() < newLeader.term() && newLeader.memberId() != null ) + { + this.leaderInfo = newLeader; + setLeader0( newLeader, dbName ); + } + } + + protected abstract void setLeader0( LeaderInfo newLeader, String dbName ); + + @Override + public final void handleStepDown( long term, String dbName ) + { + boolean wasLeaderForTerm = Objects.equals( myself, leaderInfo.memberId() ) && term == leaderInfo.term(); + if ( wasLeaderForTerm ) + { + log.info( "Step down event detected. This topology member, with MemberId %s, was leader in term %s, now moving " + + "to follower.", myself, leaderInfo.term() ); + handleStepDown0( term, dbName ); + } + } + + protected abstract void handleStepDown0( long term, String dbName ); +} diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ClientConnectorAddresses.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ClientConnectorAddresses.java index 3d1891d3232b7..2ce8325a201b6 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ClientConnectorAddresses.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ClientConnectorAddresses.java @@ -22,6 +22,7 @@ */ package org.neo4j.causalclustering.discovery; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; @@ -31,11 +32,15 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.neo4j.causalclustering.core.state.storage.SafeChannelMarshal; +import org.neo4j.causalclustering.messaging.marshalling.StringMarshal; import org.neo4j.helpers.AdvertisedSocketAddress; import org.neo4j.kernel.configuration.BoltConnector; import org.neo4j.helpers.SocketAddressParser; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.configuration.HttpConnector.Encryption; +import org.neo4j.storageengine.api.ReadableChannel; +import org.neo4j.storageengine.api.WritableChannel; import static org.neo4j.causalclustering.discovery.ClientConnectorAddresses.Scheme.bolt; import static org.neo4j.causalclustering.discovery.ClientConnectorAddresses.Scheme.http; @@ -186,4 +191,34 @@ public int hashCode() return Objects.hash( scheme, socketAddress ); } } + + public static class Marshal extends SafeChannelMarshal + { + @Override + protected ClientConnectorAddresses unmarshal0( ReadableChannel channel ) throws IOException + { + int size = channel.getInt(); + List connectorUris = new ArrayList<>( size ); + for ( int i = 0; i < size; i++ ) + { + String schemeName = StringMarshal.unmarshal( channel ); + String hostName = StringMarshal.unmarshal( channel ); + int port = channel.getInt(); + connectorUris.add( new ConnectorUri( Scheme.valueOf( schemeName ), new AdvertisedSocketAddress( hostName, port ) ) ); + } + return new ClientConnectorAddresses( connectorUris ); + } + + @Override + public void marshal( ClientConnectorAddresses connectorUris, WritableChannel channel ) throws IOException + { + channel.putInt( connectorUris.connectorUris.size() ); + for ( ConnectorUri uri : connectorUris ) + { + StringMarshal.marshal( channel, uri.scheme.name() ); + StringMarshal.marshal( channel, uri.socketAddress.getHostname() ); + channel.putInt( uri.socketAddress.getPort() ); + } + } + } } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreServerInfo.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreServerInfo.java index b6a4472ea85a0..f1a44e63d0ed7 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreServerInfo.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreServerInfo.java @@ -22,9 +22,14 @@ */ package org.neo4j.causalclustering.discovery; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; import java.util.Set; +import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.helpers.AdvertisedSocketAddress; +import org.neo4j.kernel.configuration.Config; import static java.util.Collections.emptySet; @@ -35,21 +40,23 @@ public class CoreServerInfo implements DiscoveryServerInfo private final ClientConnectorAddresses clientConnectorAddresses; private final Set groups; private final String dbName; + private final boolean refuseToBeLeader; public CoreServerInfo( AdvertisedSocketAddress raftServer, AdvertisedSocketAddress catchupServer, - ClientConnectorAddresses clientConnectors, String dbName ) + ClientConnectorAddresses clientConnectors, String dbName, boolean refuseToBeLeader ) { - this( raftServer, catchupServer, clientConnectors, emptySet(), dbName ); + this( raftServer, catchupServer, clientConnectors, emptySet(), dbName, refuseToBeLeader ); } public CoreServerInfo( AdvertisedSocketAddress raftServer, AdvertisedSocketAddress catchupServer, - ClientConnectorAddresses clientConnectorAddresses, Set groups, String dbName ) + ClientConnectorAddresses clientConnectorAddresses, Set groups, String dbName, boolean refuseToBeLeader ) { this.raftServer = raftServer; this.catchupServer = catchupServer; this.clientConnectorAddresses = clientConnectorAddresses; this.groups = groups; this.dbName = dbName; + this.refuseToBeLeader = refuseToBeLeader; } @Override @@ -81,6 +88,11 @@ public Set groups() return groups; } + public boolean refusesToBeLeader() + { + return refuseToBeLeader; + } + @Override public String toString() { @@ -89,6 +101,45 @@ public String toString() ", catchupServer=" + catchupServer + ", clientConnectorAddresses=" + clientConnectorAddresses + ", groups=" + groups + + ", database=" + dbName + + ", refuseToBeLeader=" + refuseToBeLeader + '}'; } + + public static CoreServerInfo from( Config config ) + { + AdvertisedSocketAddress raftAddress = config.get( CausalClusteringSettings.raft_advertised_address ); + AdvertisedSocketAddress transactionSource = config.get( CausalClusteringSettings.transaction_advertised_address ); + ClientConnectorAddresses clientConnectorAddresses = ClientConnectorAddresses.extractFromConfig( config ); + String dbName = config.get( CausalClusteringSettings.database ); + List groupList = config.get( CausalClusteringSettings.server_groups ); + Set groups = new HashSet<>( groupList ); + boolean refuseToBeLeader = config.get( CausalClusteringSettings.refuse_to_be_leader ); + + return new CoreServerInfo( raftAddress, transactionSource, clientConnectorAddresses, groups, dbName, refuseToBeLeader ); + } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + CoreServerInfo that = (CoreServerInfo) o; + return refuseToBeLeader == that.refuseToBeLeader && Objects.equals( raftServer, that.raftServer ) && + Objects.equals( catchupServer, that.catchupServer ) && Objects.equals( clientConnectorAddresses, that.clientConnectorAddresses ) && + Objects.equals( groups, that.groups ) && Objects.equals( dbName, that.dbName ); + } + + @Override + public int hashCode() + { + + return Objects.hash( raftServer, catchupServer, clientConnectorAddresses, groups, dbName, refuseToBeLeader ); + } } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreTopology.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreTopology.java index 129d3b8e51da0..b99a34b924138 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreTopology.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreTopology.java @@ -36,7 +36,7 @@ public class CoreTopology implements Topology { - static final CoreTopology EMPTY = new CoreTopology( null, false, emptyMap() ); + public static final CoreTopology EMPTY = new CoreTopology( null, false, emptyMap() ); private final ClusterId clusterId; private final boolean canBeBootstrapped; diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreTopologyListenerService.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreTopologyListenerService.java index a642898eda158..a18c3e67e3e79 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreTopologyListenerService.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/CoreTopologyListenerService.java @@ -22,31 +22,29 @@ */ package org.neo4j.causalclustering.discovery; -import java.util.ArrayList; -import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -class CoreTopologyListenerService +public class CoreTopologyListenerService { private final Set listeners; - CoreTopologyListenerService() + public CoreTopologyListenerService() { this.listeners = ConcurrentHashMap.newKeySet(); } - void addCoreTopologyListener( CoreTopologyService.Listener listener ) + public void addCoreTopologyListener( CoreTopologyService.Listener listener ) { listeners.add( listener ); } - void removeCoreTopologyListener( CoreTopologyService.Listener listener ) + public void removeCoreTopologyListener( CoreTopologyService.Listener listener ) { listeners.remove( listener ); } - void notifyListeners( CoreTopology coreTopology ) + public void notifyListeners( CoreTopology coreTopology ) { for ( CoreTopologyService.Listener listener : listeners ) { diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/DiscoveryServiceFactory.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/DiscoveryServiceFactory.java index c87784d64c3f7..78d6c9091e658 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/DiscoveryServiceFactory.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/DiscoveryServiceFactory.java @@ -34,7 +34,7 @@ CoreTopologyService coreTopologyService( Config config, MemberId myself, JobSche HostnameResolver hostnameResolver, TopologyServiceRetryStrategy topologyServiceRetryStrategy, Monitors monitors ); - TopologyService topologyService( Config config, LogProvider logProvider, + TopologyService readReplicaTopologyService( Config config, LogProvider logProvider, JobScheduler jobScheduler, MemberId myself, HostnameResolver hostnameResolver, TopologyServiceRetryStrategy topologyServiceRetryStrategy ); } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/DiscoveryServiceFactorySelector.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/DiscoveryServiceFactorySelector.java new file mode 100644 index 0000000000000..35bafe3c15602 --- /dev/null +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/DiscoveryServiceFactorySelector.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.discovery; + +import org.neo4j.causalclustering.core.CausalClusteringSettings; +import org.neo4j.kernel.configuration.Config; + +public abstract class DiscoveryServiceFactorySelector +{ + public static DiscoveryMiddleware DEFAULT = DiscoveryMiddleware.hazelcast; + + public T select( Config config ) + { + DiscoveryMiddleware middleware = config.get( CausalClusteringSettings.middleware_type ); + return select( middleware ); + } + + protected abstract T select( DiscoveryMiddleware middleware ); + + public enum DiscoveryMiddleware + { + hazelcast, akka + } +} diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/EnterpriseDiscoveryServiceFactorySelector.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/EnterpriseDiscoveryServiceFactorySelector.java new file mode 100644 index 0000000000000..910d12c843eca --- /dev/null +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/EnterpriseDiscoveryServiceFactorySelector.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.discovery; + +public class EnterpriseDiscoveryServiceFactorySelector extends DiscoveryServiceFactorySelector +{ + @Override + protected DiscoveryServiceFactory select( DiscoveryMiddleware middleware ) + { + switch ( middleware ) + { + case hazelcast: return new HazelcastDiscoveryServiceFactory(); + case akka: throw new UnsupportedOperationException( "Akka based discovery is Commercial release only" ); + default: throw new IllegalArgumentException( "Should have matched a discovery service factory to " + middleware ); + } + } +} diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastClient.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastClient.java index 2bda9a8afb849..b8bf917c6d823 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastClient.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastClient.java @@ -32,7 +32,7 @@ import org.neo4j.causalclustering.identity.MemberId; import org.neo4j.helpers.AdvertisedSocketAddress; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.lifecycle.Lifecycle; +import org.neo4j.kernel.lifecycle.SafeLifecycle; import org.neo4j.logging.Log; import org.neo4j.logging.LogProvider; import org.neo4j.scheduler.JobScheduler; @@ -48,7 +48,7 @@ import static org.neo4j.causalclustering.discovery.HazelcastClusterTopology.getReadReplicaTopology; import static org.neo4j.causalclustering.discovery.HazelcastClusterTopology.refreshGroups; -public class HazelcastClient implements TopologyService, Lifecycle +public class HazelcastClient extends SafeLifecycle implements TopologyService { private final Log log; private final ClientConnectorAddresses connectorAddresses; @@ -133,7 +133,7 @@ public ReadReplicaTopology allReadReplicas() } @Override - public ReadReplicaTopology localReadReplicas() + public ReadReplicaTopology localReadReplicas() { return localReadReplicaTopology; } @@ -171,13 +171,13 @@ private void refreshRoles() throws HazelcastInstanceNotActiveException } @Override - public void init() + public void init0() { // nothing to do } @Override - public void start() + public void start0() { keepAliveJob = scheduler.scheduleRecurring( "KeepAlive", timeToLive / 3, this::keepReadReplicaAlive ); refreshTopologyJob = scheduler.scheduleRecurring( "TopologyRefresh", refreshPeriod, () -> { @@ -187,7 +187,7 @@ public void start() } @Override - public void stop() + public void stop0() { keepAliveJob.cancel( true ); refreshTopologyJob.cancel( true ); @@ -195,7 +195,7 @@ public void stop() } @Override - public void shutdown() + public void shutdown0() { // nothing to do } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastClusterTopology.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastClusterTopology.java index 0ce6995bcc082..5b6505641ccae 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastClusterTopology.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastClusterTopology.java @@ -296,7 +296,9 @@ static Map toCoreMemberMap( Set members, Log lo socketAddress( attrMap.get( RAFT_SERVER ), AdvertisedSocketAddress::new ), socketAddress( attrMap.get( TRANSACTION_SERVER ), AdvertisedSocketAddress::new ), ClientConnectorAddresses.fromString( attrMap.get( CLIENT_CONNECTOR_ADDRESSES ) ), - asSet( serverGroupsMMap.get( attrMap.get( MEMBER_UUID ) ) ), attrMap.get( MEMBER_DB_NAME ) ); + asSet( serverGroupsMMap.get( attrMap.get( MEMBER_UUID ) ) ), + attrMap.get( MEMBER_DB_NAME ), + member.getBooleanAttribute( REFUSE_TO_BE_LEADER_KEY ) ); MemberId memberId = new MemberId( UUID.fromString( attrMap.get( MEMBER_UUID ) ) ); coreMembers.put( memberId, coreServerInfo ); diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastCoreTopologyService.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastCoreTopologyService.java index 4aed4319e2295..0e7cbaaeadcd2 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastCoreTopologyService.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastCoreTopologyService.java @@ -22,15 +22,6 @@ */ package org.neo4j.causalclustering.discovery; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - import com.hazelcast.config.InterfacesConfig; import com.hazelcast.config.JoinConfig; import com.hazelcast.config.ListenerConfig; @@ -45,6 +36,14 @@ import com.hazelcast.core.MembershipListener; import com.hazelcast.nio.Address; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.causalclustering.core.consensus.LeaderInfo; import org.neo4j.causalclustering.helper.RobustJobSchedulerWrapper; @@ -54,9 +53,7 @@ import org.neo4j.helpers.ListenSocketAddress; import org.neo4j.helpers.SocketAddress; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.lifecycle.Lifecycle; import org.neo4j.kernel.monitoring.Monitors; -import org.neo4j.logging.Log; import org.neo4j.logging.LogProvider; import org.neo4j.scheduler.JobScheduler; @@ -74,7 +71,7 @@ import static org.neo4j.causalclustering.discovery.HazelcastClusterTopology.getReadReplicaTopology; import static org.neo4j.causalclustering.discovery.HazelcastClusterTopology.refreshGroups; -public class HazelcastCoreTopologyService implements CoreTopologyService, Lifecycle +public class HazelcastCoreTopologyService extends AbstractCoreTopologyService { public interface Monitor { @@ -86,11 +83,6 @@ public interface Monitor private static final long HAZELCAST_IS_HEALTHY_TIMEOUT_MS = TimeUnit.MINUTES.toMillis( 10 ); private static final int HAZELCAST_MIN_CLUSTER = 2; - private final Config config; - private final MemberId myself; - private final Log log; - private final Log userLog; - private final CoreTopologyListenerService listenerService; private final RobustJobSchedulerWrapper scheduler; private final long refreshPeriod; private final HostnameResolver hostnameResolver; @@ -105,13 +97,13 @@ public interface Monitor private volatile HazelcastInstance hazelcastInstance; - /* cached data updated during each refresh */ + private volatile Map catchupAddressMap = new HashMap<>(); + private volatile Map coreRoles = Collections.emptyMap(); + + private volatile ReadReplicaTopology readReplicaTopology = ReadReplicaTopology.EMPTY; private volatile CoreTopology coreTopology = CoreTopology.EMPTY; private volatile CoreTopology localCoreTopology = CoreTopology.EMPTY; - private volatile ReadReplicaTopology readReplicaTopology = ReadReplicaTopology.EMPTY; private volatile ReadReplicaTopology localReadReplicaTopology = ReadReplicaTopology.EMPTY; - private volatile Map catchupAddressMap = new HashMap<>(); - private volatile Map coreRoles = Collections.emptyMap(); private Thread startingThread; private volatile boolean stopped; @@ -120,30 +112,13 @@ public HazelcastCoreTopologyService( Config config, MemberId myself, JobSchedule LogProvider logProvider, LogProvider userLogProvider, HostnameResolver hostnameResolver, TopologyServiceRetryStrategy topologyServiceRetryStrategy, Monitors monitors ) { - this.config = config; - this.myself = myself; - this.listenerService = new CoreTopologyListenerService(); - this.log = logProvider.getLog( getClass() ); + super( config, myself, logProvider, userLogProvider ); + this.localDBName = config.get( CausalClusteringSettings.database ); this.scheduler = new RobustJobSchedulerWrapper( jobScheduler, log ); - this.userLog = userLogProvider.getLog( getClass() ); this.refreshPeriod = config.get( CausalClusteringSettings.cluster_topology_refresh ).toMillis(); this.hostnameResolver = hostnameResolver; this.topologyServiceRetryStrategy = topologyServiceRetryStrategy; this.monitor = monitors.newMonitor( Monitor.class ); - this.localDBName = config.get( CausalClusteringSettings.database ); - } - - @Override - public void addLocalCoreTopologyListener( Listener listener ) - { - listenerService.addCoreTopologyListener( listener ); - listener.onCoreTopologyChange( localCoreServers() ); - } - - @Override - public void removeLocalCoreTopologyListener( Listener listener ) - { - listenerService.removeCoreTopologyListener( listener ); } @Override @@ -154,7 +129,7 @@ public boolean setClusterId( ClusterId clusterId, String dbName ) throws Interru } @Override - public void setLeader( LeaderInfo newLeaderInfo, String dbName ) + public void setLeader0( LeaderInfo newLeaderInfo, String dbName ) { leaderInfo.updateAndGet( currentLeaderInfo -> { @@ -171,21 +146,9 @@ public void setLeader( LeaderInfo newLeaderInfo, String dbName ) } @Override - public void handleStepDown( long term, String dbName ) + public void handleStepDown0( long term, String dbName ) { - LeaderInfo localLeaderInfo = leaderInfo.get(); - - boolean wasLeaderForDbAndTerm = - Objects.equals( myself, localLeaderInfo.memberId() ) && - localDBName.equals( dbName ) && - term == localLeaderInfo.term(); - - if ( wasLeaderForDbAndTerm ) - { - log.info( "Step down event detected. This topology member, with MemberId %s, was leader in term %s, now moving " + - "to follower.", myself, localLeaderInfo.term() ); - stepDownInfo.set( Optional.of( localLeaderInfo.stepDown() ) ); - } + HazelcastClusterTopology.casLeaders( hazelcastInstance, leaderInfo.get().stepDown(), dbName ); } @Override @@ -195,19 +158,13 @@ public Map allCoreRoles() } @Override - public String localDBName() - { - return localDBName; - } - - @Override - public void init() + public void init0() { // nothing to do } @Override - public void start() + public void start0() { /* * We will start hazelcast in its own thread. Hazelcast blocks until the minimum cluster size is available @@ -238,7 +195,7 @@ public void start() } @Override - public void stop() + public void stop0() { log.info( String.format( "HazelcastCoreTopologyService stopping and unbinding from %s", config.get( discovery_listen_address ) ) ); @@ -267,7 +224,7 @@ public void stop() } @Override - public void shutdown() + public void shutdown0() { // nothing to do } @@ -378,12 +335,15 @@ private void logConnectionInfo( List initialMembers ) userLog.info( "Discovering other core members in initial members set: " + initialMembers ); } + @Override + public String localDBName() + { + return localDBName; + } + @Override public CoreTopology allCoreServers() { - // It is perhaps confusing (Or even error inducing) that this core Topology will always contain the cluster id - // for the database local to the host upon which this method is called. - // TODO: evaluate returning clusterId = null for global Topologies returned by allCoreServers() return coreTopology; } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastDiscoveryServiceFactory.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastDiscoveryServiceFactory.java index 252c1f603e87b..4204294b94b30 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastDiscoveryServiceFactory.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/HazelcastDiscoveryServiceFactory.java @@ -46,7 +46,7 @@ public CoreTopologyService coreTopologyService( Config config, MemberId myself, } @Override - public TopologyService topologyService( Config config, LogProvider logProvider, + public TopologyService readReplicaTopologyService( Config config, LogProvider logProvider, JobScheduler jobScheduler, MemberId myself, HostnameResolver hostnameResolver, TopologyServiceRetryStrategy topologyServiceRetryStrategy ) { diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ReadReplicaInfo.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ReadReplicaInfo.java index 023a8b0c285dc..be357860591e6 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ReadReplicaInfo.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ReadReplicaInfo.java @@ -22,9 +22,14 @@ */ package org.neo4j.causalclustering.discovery; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; import java.util.Set; +import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.helpers.AdvertisedSocketAddress; +import org.neo4j.kernel.configuration.Config; import static java.util.Collections.emptySet; @@ -82,4 +87,38 @@ public String toString() ", groups=" + groups + '}'; } + + public static ReadReplicaInfo from( Config config ) + { + AdvertisedSocketAddress transactionSource = config.get( CausalClusteringSettings.transaction_advertised_address ); + ClientConnectorAddresses clientConnectorAddresses = ClientConnectorAddresses.extractFromConfig( config ); + String dbName = config.get( CausalClusteringSettings.database ); + List groupList = config.get( CausalClusteringSettings.server_groups ); + Set groups = new HashSet<>( groupList ); + + return new ReadReplicaInfo( clientConnectorAddresses, transactionSource, groups, dbName ); + } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + ReadReplicaInfo that = (ReadReplicaInfo) o; + return Objects.equals( catchupServerAddress, that.catchupServerAddress ) && Objects.equals( clientConnectorAddresses, that.clientConnectorAddresses ) && + Objects.equals( groups, that.groups ) && Objects.equals( dbName, that.dbName ); + } + + @Override + public int hashCode() + { + + return Objects.hash( catchupServerAddress, clientConnectorAddresses, groups, dbName ); + } } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ReadReplicaTopology.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ReadReplicaTopology.java index 68bd9b0403df8..3c97aa6a678d5 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ReadReplicaTopology.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/ReadReplicaTopology.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.concurrent.ThreadLocalRandom; @@ -33,7 +34,7 @@ public class ReadReplicaTopology implements Topology { - static final ReadReplicaTopology EMPTY = new ReadReplicaTopology( emptyMap() ); + public static final ReadReplicaTopology EMPTY = new ReadReplicaTopology( emptyMap() ); private final Map readReplicaMembers; @@ -75,4 +76,26 @@ public ReadReplicaTopology filterTopologyByDb( String dbName ) return new ReadReplicaTopology( filteredMembers ); } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + ReadReplicaTopology that = (ReadReplicaTopology) o; + return Objects.equals( readReplicaMembers, that.readReplicaMembers ); + } + + @Override + public int hashCode() + { + + return Objects.hash( readReplicaMembers ); + } } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/RoleInfo.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/RoleInfo.java index e6ba5ed8c8686..080a5559d87b1 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/RoleInfo.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/RoleInfo.java @@ -29,20 +29,4 @@ public enum RoleInfo FOLLOWER, READ_REPLICA, UNKNOWN; - - @Override - public String toString() - { - switch ( this ) - { - case LEADER: - return "LEADER"; - case FOLLOWER: - return "FOLLOWER"; - case READ_REPLICA: - return "READ REPLICA"; - default: - return "UNKNOWN"; - } - } } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/TopologyDifference.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/TopologyDifference.java index 0a7901a0387e6..ca5bbad5fcb65 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/TopologyDifference.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/TopologyDifference.java @@ -24,7 +24,7 @@ import java.util.Set; -class TopologyDifference +public class TopologyDifference { private Set added; private Set removed; @@ -45,7 +45,7 @@ Set removed() return removed; } - boolean hasChanges() + public boolean hasChanges() { return added.size() > 0 || removed.size() > 0; } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/TopologyService.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/TopologyService.java index ef70d4615ec59..0e9eed169d804 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/TopologyService.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/discovery/TopologyService.java @@ -36,6 +36,9 @@ public interface TopologyService extends Lifecycle { String localDBName(); + // It is perhaps confusing (Or even error inducing) that this core Topology will always contain the cluster id + // for the database local to the host upon which this method is called. + // TODO: evaluate returning clusterId = null for global Topologies returned by allCoreServers() CoreTopology allCoreServers(); CoreTopology localCoreServers(); diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/NetworkFlushableByteBuf.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/NetworkFlushableByteBuf.java index b4294dd191c18..bf84b71b15e91 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/NetworkFlushableByteBuf.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/NetworkFlushableByteBuf.java @@ -23,7 +23,6 @@ package org.neo4j.causalclustering.messaging; import java.io.Flushable; -import java.io.IOException; import io.netty.buffer.ByteBuf; diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/BooleanMarshal.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/BooleanMarshal.java new file mode 100644 index 0000000000000..2e5ebc65de859 --- /dev/null +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/BooleanMarshal.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.messaging.marshalling; + +import java.io.IOException; + +import org.neo4j.storageengine.api.ReadableChannel; +import org.neo4j.storageengine.api.WritableChannel; + +public class BooleanMarshal +{ + private BooleanMarshal() + { + } + + public static boolean unmarshal( ReadableChannel channel ) throws IOException + { + return channel.get() != 0; + } + + public static void marshal( WritableChannel channel, boolean value ) throws IOException + { + channel.put( (byte) (value ? 1 : 0 ) ); + } +} diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/InputStreamReadableChannel.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/InputStreamReadableChannel.java new file mode 100644 index 0000000000000..4b20189a0a3a2 --- /dev/null +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/InputStreamReadableChannel.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.messaging.marshalling; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.neo4j.storageengine.api.ReadableChannel; + +public class InputStreamReadableChannel implements ReadableChannel +{ + private final DataInputStream dataInputStream; + + public InputStreamReadableChannel( InputStream inputStream ) + { + this.dataInputStream = new DataInputStream( inputStream ); + } + + @Override + public byte get() throws IOException + { + return dataInputStream.readByte(); + } + + @Override + public short getShort() throws IOException + { + return dataInputStream.readShort(); + } + + @Override + public int getInt() throws IOException + { + return dataInputStream.readInt(); + } + + @Override + public long getLong() throws IOException + { + return dataInputStream.readLong(); + } + + @Override + public float getFloat() throws IOException + { + return dataInputStream.readFloat(); + } + + @Override + public double getDouble() throws IOException + { + return dataInputStream.readDouble(); + } + + @Override + public void get( byte[] bytes, int length ) throws IOException + { + dataInputStream.read( bytes, 0, length ); + } +} diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/OutputStreamWritableChannel.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/OutputStreamWritableChannel.java new file mode 100644 index 0000000000000..2ea6b25e79ab3 --- /dev/null +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/OutputStreamWritableChannel.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.messaging.marshalling; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.neo4j.storageengine.api.WritableChannel; + +public class OutputStreamWritableChannel implements WritableChannel +{ + private final DataOutputStream dataOutputStream; + + public OutputStreamWritableChannel( OutputStream outputStream ) + { + this.dataOutputStream = new DataOutputStream( outputStream ); + } + + @Override + public WritableChannel put( byte value ) throws IOException + { + dataOutputStream.writeByte( value ); + return this; + } + + @Override + public WritableChannel putShort( short value ) throws IOException + { + dataOutputStream.writeShort( value ); + return this; + } + + @Override + public WritableChannel putInt( int value ) throws IOException + { + dataOutputStream.writeInt( value ); + return this; + } + + @Override + public WritableChannel putLong( long value ) throws IOException + { + dataOutputStream.writeLong( value ); + return this; + } + + @Override + public WritableChannel putFloat( float value ) throws IOException + { + dataOutputStream.writeFloat( value ); + return this; + } + + @Override + public WritableChannel putDouble( double value ) throws IOException + { + dataOutputStream.writeDouble( value ); + return this; + } + + @Override + public WritableChannel put( byte[] value, int length ) throws IOException + { + dataOutputStream.write( value, 0, length ); + return this; + } +} diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/StringMarshal.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/StringMarshal.java index 284d4606943b5..60d6f1741b3a9 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/StringMarshal.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/messaging/marshalling/StringMarshal.java @@ -131,6 +131,11 @@ public static String unmarshal( ReadableChannel channel ) throws IOException try { int len = channel.getInt(); + if ( len == NULL_STRING_LENGTH ) + { + return null; + } + byte[] stringBytes = new byte[len]; channel.get( stringBytes, stringBytes.length ); diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/readreplica/EnterpriseReadReplicaEditionModule.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/readreplica/EnterpriseReadReplicaEditionModule.java index ae1fec1c8f952..fb979b9ba80d6 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/readreplica/EnterpriseReadReplicaEditionModule.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/readreplica/EnterpriseReadReplicaEditionModule.java @@ -219,7 +219,12 @@ public EnterpriseReadReplicaEditionModule( final PlatformModule platformModule, configureDiscoveryService( discoveryServiceFactory, dependencies, config, logProvider ); - topologyService = discoveryServiceFactory.topologyService( config, logProvider, platformModule.jobScheduler, myself, hostnameResolver, + topologyService = discoveryServiceFactory.readReplicaTopologyService( + config, + logProvider, + platformModule.jobScheduler, + myself, + hostnameResolver, resolveStrategy( config, logProvider ) ); life.add( dependencies.satisfyDependency( topologyService ) ); diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/readreplica/ReadReplicaGraphDatabase.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/readreplica/ReadReplicaGraphDatabase.java index 0d4f18aaeeae7..fecad606f1841 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/readreplica/ReadReplicaGraphDatabase.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/readreplica/ReadReplicaGraphDatabase.java @@ -27,7 +27,6 @@ import java.util.function.Function; import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; -import org.neo4j.causalclustering.discovery.HazelcastDiscoveryServiceFactory; import org.neo4j.causalclustering.identity.MemberId; import org.neo4j.graphdb.facade.GraphDatabaseFacadeFactory; import org.neo4j.graphdb.facade.GraphDatabaseFacadeFactory.Dependencies; @@ -43,9 +42,9 @@ protected ReadReplicaGraphDatabase() { } - public ReadReplicaGraphDatabase( File storeDir, Config config, Dependencies dependencies ) + public ReadReplicaGraphDatabase( File storeDir, Config config, Dependencies dependencies, DiscoveryServiceFactory discoveryServiceFactory ) { - this( storeDir, config, dependencies, new HazelcastDiscoveryServiceFactory(), new MemberId( UUID.randomUUID() ) ); + this( storeDir, config, dependencies, discoveryServiceFactory, new MemberId( UUID.randomUUID() ) ); } public ReadReplicaGraphDatabase( File storeDir, Config config, Dependencies dependencies, diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/routing/multi_cluster/procedure/GetRoutersForAllDatabasesProcedure.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/routing/multi_cluster/procedure/GetRoutersForAllDatabasesProcedure.java index 990986299ca8b..d45da1d99ccc3 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/routing/multi_cluster/procedure/GetRoutersForAllDatabasesProcedure.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/routing/multi_cluster/procedure/GetRoutersForAllDatabasesProcedure.java @@ -30,6 +30,7 @@ import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.causalclustering.discovery.CoreServerInfo; +import org.neo4j.causalclustering.discovery.CoreTopology; import org.neo4j.causalclustering.discovery.TopologyService; import org.neo4j.causalclustering.routing.Endpoint; import org.neo4j.causalclustering.routing.multi_cluster.MultiClusterRoutingResult; @@ -85,6 +86,7 @@ public RawIterator apply( Context ctx, Object[] inp private Map> routeEndpoints() { + CoreTopology core = topologyService.allCoreServers(); Stream allCoreMemberInfo = topologyService.allCoreServers().members().values().stream(); Map> coresByDb = allCoreMemberInfo.collect( Collectors.groupingBy( CoreServerInfo::getDatabaseName ) ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/core/EnterpriseCoreEditionModuleIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/core/EnterpriseCoreEditionModuleIT.java index 71cecd06b80dd..1fe1a5504407b 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/core/EnterpriseCoreEditionModuleIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/core/EnterpriseCoreEditionModuleIT.java @@ -56,7 +56,7 @@ public class EnterpriseCoreEditionModuleIT @Test public void createBufferedIdComponentsByDefault() throws Exception { - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); CoreClusterMember leader = cluster.awaitLeader(); DependencyResolver dependencyResolver = leader.database().getDependencyResolver(); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/Cluster.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/Cluster.java index 79c47715eb913..c255c301b10b5 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/Cluster.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/Cluster.java @@ -79,7 +79,7 @@ import static org.neo4j.kernel.api.exceptions.Status.Transaction.LockSessionExpired; import static org.neo4j.util.concurrent.Futures.combine; -public class Cluster +public abstract class Cluster { private static final int DEFAULT_TIMEOUT_MS = 120_000; private static final int DEFAULT_CLUSTER_SIZE = 3; @@ -90,7 +90,7 @@ public class Cluster private final Map readReplicaParams; private final Map> instanceReadReplicaParams; private final String recordFormat; - protected final DiscoveryServiceFactory discoveryServiceFactory; + protected final T discoveryServiceFactory; protected final String listenAddress; protected final String advertisedAddress; private final Set dbNames; @@ -101,7 +101,7 @@ public class Cluster private int highestReplicaServerId; public Cluster( File parentDir, int noOfCoreMembers, int noOfReadReplicas, - DiscoveryServiceFactory discoveryServiceFactory, + T discoveryServiceFactory, Map coreParams, Map> instanceCoreParams, Map readReplicaParams, Map> instanceReadReplicaParams, String recordFormat, IpFamily ipFamily, boolean useWildcard ) @@ -112,7 +112,7 @@ public Cluster( File parentDir, int noOfCoreMembers, int noOfReadReplicas, } public Cluster( File parentDir, int noOfCoreMembers, int noOfReadReplicas, - DiscoveryServiceFactory discoveryServiceFactory, + T discoveryServiceFactory, Map coreParams, Map> instanceCoreParams, Map readReplicaParams, Map> instanceReadReplicaParams, String recordFormat, IpFamily ipFamily, boolean useWildcard, Set dbNames ) @@ -572,68 +572,20 @@ private void createCoreMembers( final int noOfCoreMembers, highestCoreServerId = noOfCoreMembers - 1; } - protected CoreClusterMember createCoreClusterMember( int serverId, - int hazelcastPort, + protected abstract CoreClusterMember createCoreClusterMember( int serverId, + int discoveryPort, int clusterSize, List initialHosts, String recordFormat, Map extraParams, - Map> instanceExtraParams ) - { - int txPort = PortAuthority.allocatePort(); - int raftPort = PortAuthority.allocatePort(); - int boltPort = PortAuthority.allocatePort(); - int httpPort = PortAuthority.allocatePort(); - int backupPort = PortAuthority.allocatePort(); - - return new CoreClusterMember( - serverId, - hazelcastPort, - txPort, - raftPort, - boltPort, - httpPort, - backupPort, - clusterSize, - initialHosts, - discoveryServiceFactory, - recordFormat, - parentDir, - extraParams, - instanceExtraParams, - listenAddress, - advertisedAddress - ); - } + Map> instanceExtraParams ); - protected ReadReplica createReadReplica( int serverId, + protected abstract ReadReplica createReadReplica( int serverId, List initialHosts, Map extraParams, Map> instanceExtraParams, String recordFormat, - Monitors monitors ) - { - int boltPort = PortAuthority.allocatePort(); - int httpPort = PortAuthority.allocatePort(); - int txPort = PortAuthority.allocatePort(); - int backupPort = PortAuthority.allocatePort(); - - return new ReadReplica( - parentDir, - serverId, - boltPort, - httpPort, - txPort, - backupPort, discoveryServiceFactory, - initialHosts, - extraParams, - instanceExtraParams, - recordFormat, - monitors, - advertisedAddress, - listenAddress - ); - } + Monitors monitors ); public void startCoreMembers() throws InterruptedException, ExecutionException { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/EnterpriseCluster.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/EnterpriseCluster.java new file mode 100644 index 0000000000000..2e55bc9887ad5 --- /dev/null +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/EnterpriseCluster.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.discovery; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.IntFunction; + +import org.neo4j.helpers.AdvertisedSocketAddress; +import org.neo4j.kernel.monitoring.Monitors; +import org.neo4j.ports.allocation.PortAuthority; + +public class EnterpriseCluster extends Cluster +{ + public EnterpriseCluster( File parentDir, int noOfCoreMembers, int noOfReadReplicas, DiscoveryServiceFactory discoveryServiceFactory, + Map coreParams, Map> instanceCoreParams, Map readReplicaParams, + Map> instanceReadReplicaParams, String recordFormat, IpFamily ipFamily, boolean useWildcard ) + { + super( parentDir, noOfCoreMembers, noOfReadReplicas, discoveryServiceFactory, coreParams, instanceCoreParams, readReplicaParams, + instanceReadReplicaParams, recordFormat, ipFamily, useWildcard ); + } + + public EnterpriseCluster( File parentDir, int noOfCoreMembers, int noOfReadReplicas, DiscoveryServiceFactory discoveryServiceFactory, + Map coreParams, Map> instanceCoreParams, Map readReplicaParams, + Map> instanceReadReplicaParams, String recordFormat, IpFamily ipFamily, boolean useWildcard, Set dbNames ) + { + super( parentDir, noOfCoreMembers, noOfReadReplicas, discoveryServiceFactory, coreParams, instanceCoreParams, readReplicaParams, + instanceReadReplicaParams, recordFormat, ipFamily, useWildcard, dbNames ); + } + + @Override + protected CoreClusterMember createCoreClusterMember( int serverId, + int discoveryPort, + int clusterSize, + List initialHosts, + String recordFormat, + Map extraParams, + Map> instanceExtraParams ) + { + int txPort = PortAuthority.allocatePort(); + int raftPort = PortAuthority.allocatePort(); + int boltPort = PortAuthority.allocatePort(); + int httpPort = PortAuthority.allocatePort(); + int backupPort = PortAuthority.allocatePort(); + + return new CoreClusterMember( + serverId, + discoveryPort, + txPort, + raftPort, + boltPort, + httpPort, + backupPort, + clusterSize, + initialHosts, + discoveryServiceFactory, + recordFormat, + parentDir, + extraParams, + instanceExtraParams, + listenAddress, + advertisedAddress + ); + } + + @Override + protected ReadReplica createReadReplica( int serverId, + List initialHosts, + Map extraParams, + Map> instanceExtraParams, + String recordFormat, + Monitors monitors ) + { + int boltPort = PortAuthority.allocatePort(); + int httpPort = PortAuthority.allocatePort(); + int txPort = PortAuthority.allocatePort(); + int backupPort = PortAuthority.allocatePort(); + int discoveryPort = PortAuthority.allocatePort(); + + return new ReadReplica( + parentDir, + serverId, + boltPort, + httpPort, + txPort, + backupPort, + discoveryPort, + discoveryServiceFactory, + initialHosts, + extraParams, + instanceExtraParams, + recordFormat, + monitors, + advertisedAddress, + listenAddress + ); + } +} diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/HazelcastClientTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/HazelcastClientTest.java index 5a9fc19b587b2..b715b2d7f242a 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/HazelcastClientTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/HazelcastClientTest.java @@ -100,7 +100,6 @@ public class HazelcastClientTest { private MemberId myself = new MemberId( UUID.randomUUID() ); - private TopologyServiceRetryStrategy topologyServiceRetryStrategy = new TopologyServiceNoRetriesStrategy(); private static final java.util.function.Supplier> DEFAULT_SETTINGS = () -> { HashMap settings = new HashMap<>(); @@ -114,13 +113,6 @@ public class HazelcastClientTest return settings; }; - private Config config( HashMap settings ) - { - HashMap defaults = DEFAULT_SETTINGS.get(); - defaults.putAll( settings ); - return Config.defaults( defaults ); - } - private Config config( String key, String value ) { HashMap defaults = DEFAULT_SETTINGS.get(); @@ -130,7 +122,6 @@ private Config config( String key, String value ) private Config config() { - return Config.defaults( DEFAULT_SETTINGS.get() ); } @@ -153,7 +144,7 @@ private HazelcastClient hzClient( OnDemandJobScheduler jobScheduler, com.hazelca return client; } - private HazelcastClient startedClientWithMembers( Set members, Config config ) + private HazelcastClient startedClientWithMembers( Set members, Config config ) throws Throwable { OnDemandJobScheduler jobScheduler = new OnDemandJobScheduler(); com.hazelcast.core.Cluster cluster = mock( Cluster.class ); @@ -161,6 +152,7 @@ private HazelcastClient startedClientWithMembers( Set members, Config co when( cluster.getMembers() ).thenReturn( members ); HazelcastClient client = hzClient( jobScheduler, cluster, config ); + client.init(); client.start(); jobScheduler.runJob(); @@ -168,7 +160,7 @@ private HazelcastClient startedClientWithMembers( Set members, Config co } @Test - public void shouldReturnTopologyUsingHazelcastMembers() + public void shouldReturnTopologyUsingHazelcastMembers() throws Throwable { // given Set members = asSet( makeMember( 1 ), makeMember( 2 ) ); @@ -182,7 +174,7 @@ public void shouldReturnTopologyUsingHazelcastMembers() } @Test - public void localAndAllTopologiesShouldMatchForSingleDBName() + public void localAndAllTopologiesShouldMatchForSingleDBName() throws Throwable { // given Set members = asSet( makeMember( 1 ), makeMember( 2 ) ); @@ -194,7 +186,7 @@ public void localAndAllTopologiesShouldMatchForSingleDBName() } @Test - public void localAndAllTopologiesShouldDifferForMultipleDBNames() + public void localAndAllTopologiesShouldDifferForMultipleDBNames() throws Throwable { // given Set members = asSet( makeMember( 1, "foo" ), makeMember( 2, "bar" ) ); @@ -207,7 +199,7 @@ public void localAndAllTopologiesShouldDifferForMultipleDBNames() } @Test - public void allTopologyShouldContainAllMembers() + public void allTopologyShouldContainAllMembers() throws Throwable { // given Set members = asSet( makeMember( 1, "foo" ), makeMember( 2, "bar" ) ); @@ -219,7 +211,7 @@ public void allTopologyShouldContainAllMembers() } @Test - public void shouldNotReconnectWhileHazelcastRemainsAvailable() + public void shouldNotReconnectWhileHazelcastRemainsAvailable() throws Throwable { // given HazelcastConnector connector = mock( HazelcastConnector.class ); @@ -242,6 +234,7 @@ public void shouldNotReconnectWhileHazelcastRemainsAvailable() when( cluster.getMembers() ).thenReturn( members ); // when + client.init(); client.start(); jobScheduler.runJob(); @@ -257,7 +250,7 @@ public void shouldNotReconnectWhileHazelcastRemainsAvailable() } @Test - public void shouldReturnEmptyTopologyIfUnableToConnectToHazelcast() + public void shouldReturnEmptyTopologyIfUnableToConnectToHazelcast() throws Throwable { // given HazelcastConnector connector = mock( HazelcastConnector.class ); @@ -283,6 +276,7 @@ public void shouldReturnEmptyTopologyIfUnableToConnectToHazelcast() when( cluster.getMembers() ).thenReturn( members ); // when + client.init(); client.start(); jobScheduler.runJob(); CoreTopology topology = client.allCoreServers(); @@ -291,7 +285,7 @@ public void shouldReturnEmptyTopologyIfUnableToConnectToHazelcast() } @Test - public void shouldRegisterReadReplicaInTopology() + public void shouldRegisterReadReplicaInTopology() throws Throwable { // given com.hazelcast.core.Cluster cluster = mock( Cluster.class ); @@ -328,6 +322,7 @@ public void shouldRegisterReadReplicaInTopology() HazelcastClient hazelcastClient = new HazelcastClient( connector, jobScheduler, NullLogProvider.getInstance(), config(), myself ); // when + hazelcastClient.init(); hazelcastClient.start(); jobScheduler.runJob(); @@ -336,7 +331,7 @@ public void shouldRegisterReadReplicaInTopology() } @Test - public void shouldRemoveReadReplicasOnGracefulShutdown() + public void shouldRemoveReadReplicasOnGracefulShutdown() throws Throwable { // given com.hazelcast.core.Cluster cluster = mock( Cluster.class ); @@ -371,6 +366,7 @@ public void shouldRemoveReadReplicasOnGracefulShutdown() OnDemandJobScheduler jobScheduler = new OnDemandJobScheduler(); HazelcastClient hazelcastClient = new HazelcastClient( connector, jobScheduler, NullLogProvider.getInstance(), config(), myself ); + hazelcastClient.init(); hazelcastClient.start(); jobScheduler.runJob(); @@ -383,7 +379,7 @@ public void shouldRemoveReadReplicasOnGracefulShutdown() } @Test - public void shouldSwallowNPEFromHazelcast() + public void shouldSwallowNPEFromHazelcast() throws Throwable { // given Endpoint endpoint = mock( Endpoint.class ); @@ -402,6 +398,7 @@ public void shouldSwallowNPEFromHazelcast() HazelcastClient hazelcastClient = new HazelcastClient( connector, jobScheduler, NullLogProvider.getInstance(), config(), myself ); + hazelcastClient.init(); hazelcastClient.start(); jobScheduler.runJob(); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/ReadReplica.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/ReadReplica.java index 976e4db45cd88..ac85aa22dac1d 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/ReadReplica.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/ReadReplica.java @@ -65,20 +65,21 @@ public class ReadReplica implements ClusterMember protected final File databasesDirectory; public ReadReplica( File parentDir, int serverId, int boltPort, int httpPort, int txPort, int backupPort, - DiscoveryServiceFactory discoveryServiceFactory, - List coreMemberHazelcastAddresses, Map extraParams, - Map> instanceExtraParams, String recordFormat, Monitors monitors, - String advertisedAddress, String listenAddress ) + int discoveryPort, DiscoveryServiceFactory discoveryServiceFactory, + List coreMemberDiscoveryAddresses, Map extraParams, + Map> instanceExtraParams, String recordFormat, Monitors monitors, + String advertisedAddress, String listenAddress ) { this.serverId = serverId; - String initialHosts = coreMemberHazelcastAddresses.stream().map( AdvertisedSocketAddress::toString ) + String initialHosts = coreMemberDiscoveryAddresses.stream().map( AdvertisedSocketAddress::toString ) .collect( joining( "," ) ); boltAdvertisedSocketAddress = advertisedAddress( advertisedAddress, boltPort ); Map config = stringMap(); config.put( "dbms.mode", "READ_REPLICA" ); config.put( CausalClusteringSettings.initial_discovery_members.name(), initialHosts ); + config.put( CausalClusteringSettings.discovery_listen_address.name(), listenAddress( listenAddress, discoveryPort ) ); config.put( GraphDatabaseSettings.store_internal_log_level.name(), Level.DEBUG.name() ); config.put( GraphDatabaseSettings.record_format.name(), recordFormat ); config.put( GraphDatabaseSettings.pagecache_memory.name(), "8m" ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryCoreClient.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryCoreClient.java index 1dcddc55cbc89..4a4b228fca261 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryCoreClient.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryCoreClient.java @@ -23,7 +23,6 @@ package org.neo4j.causalclustering.discovery; import java.util.Map; -import java.util.Objects; import java.util.Optional; import org.neo4j.causalclustering.core.CausalClusteringSettings; @@ -32,47 +31,33 @@ import org.neo4j.causalclustering.identity.MemberId; import org.neo4j.helpers.AdvertisedSocketAddress; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.lifecycle.Lifecycle; -import org.neo4j.logging.Log; import org.neo4j.logging.LogProvider; -class SharedDiscoveryCoreClient implements CoreTopologyService, Lifecycle +class SharedDiscoveryCoreClient extends AbstractCoreTopologyService implements Comparable { private final SharedDiscoveryService sharedDiscoveryService; - private final MemberId myself; private final CoreServerInfo coreServerInfo; - private final CoreTopologyListenerService listenerService; - private final Log log; - private final boolean refusesToBeLeader; private final String localDBName; - - private volatile LeaderInfo leaderInfo = LeaderInfo.INITIAL; - private volatile CoreTopology coreTopology; - private volatile ReadReplicaTopology readReplicaTopology; + private final boolean refusesToBeLeader; + private volatile ReadReplicaTopology readReplicaTopology = ReadReplicaTopology.EMPTY; + private volatile CoreTopology coreTopology = CoreTopology.EMPTY; + private volatile ReadReplicaTopology localReadReplicaTopology = ReadReplicaTopology.EMPTY; + private volatile CoreTopology localCoreTopology = CoreTopology.EMPTY; SharedDiscoveryCoreClient( SharedDiscoveryService sharedDiscoveryService, MemberId member, LogProvider logProvider, Config config ) { + super( config, member, logProvider, logProvider ); + this.localDBName = config.get( CausalClusteringSettings.database ); this.sharedDiscoveryService = sharedDiscoveryService; - this.listenerService = new CoreTopologyListenerService(); - this.myself = member; - this.coreServerInfo = extractCoreServerInfo( config ); - this.log = logProvider.getLog( getClass() ); + this.coreServerInfo = CoreServerInfo.from( config ); this.refusesToBeLeader = config.get( CausalClusteringSettings.refuse_to_be_leader ); - this.localDBName = config.get( CausalClusteringSettings.database ); } @Override - public synchronized void addLocalCoreTopologyListener( Listener listener ) + public int compareTo( SharedDiscoveryCoreClient o ) { - listenerService.addCoreTopologyListener( listener ); - listener.onCoreTopologyChange( localCoreServers() ); - } - - @Override - public void removeLocalCoreTopologyListener( Listener listener ) - { - listenerService.removeCoreTopologyListener( listener ); + return Optional.ofNullable( o ).map( c -> c.myself.getUuid().compareTo( this.myself.getUuid() ) ).orElse( -1 ); } @Override @@ -88,26 +73,24 @@ public Map allCoreRoles() } @Override - public void setLeader( LeaderInfo newLeader, String dbName ) + public void setLeader0( LeaderInfo newLeader, String dbName ) { - if ( this.leaderInfo.term() < newLeader.term() && newLeader.memberId() != null ) - { - this.leaderInfo = newLeader; - sharedDiscoveryService.casLeaders( newLeader, localDBName ); - } + sharedDiscoveryService.casLeaders( newLeader, localDBName ); } @Override - public void init() + public void init0() { // nothing to do } @Override - public void start() throws InterruptedException + public void start0() throws InterruptedException { coreTopology = sharedDiscoveryService.getCoreTopology( this ); + localCoreTopology = coreTopology.filterTopologyByDb( localDBName ); readReplicaTopology = sharedDiscoveryService.getReadReplicaTopology(); + localReadReplicaTopology = readReplicaTopology.filterTopologyByDb( localDBName ); sharedDiscoveryService.registerCoreMember( this ); log.info( "Registered core server %s", myself ); @@ -117,70 +100,61 @@ public void start() throws InterruptedException } @Override - public void stop() + public void stop0() { sharedDiscoveryService.unRegisterCoreMember( this ); log.info( "Unregistered core server %s", myself ); } @Override - public void shutdown() + public void shutdown0() { // nothing to do } @Override - public ReadReplicaTopology allReadReplicas() + public String localDBName() { - return readReplicaTopology; + return localDBName; } @Override - public ReadReplicaTopology localReadReplicas() + public CoreTopology allCoreServers() { - return allReadReplicas().filterTopologyByDb( localDBName ); + return coreTopology; } @Override - public Optional findCatchupAddress( MemberId upstream ) + public CoreTopology localCoreServers() { - return localCoreServers().find( upstream ) - .map( info -> Optional.of( info.getCatchupServer() ) ) - .orElseGet( () -> readReplicaTopology.find( upstream ) - .map( ReadReplicaInfo::getCatchupServer ) ); + return localCoreTopology; } @Override - public CoreTopology allCoreServers() + public ReadReplicaTopology allReadReplicas() { - // It is perhaps confusing (Or even error inducing) that this core Topology will always contain the cluster id - // for the database local to the host upon which this method is called. - // TODO: evaluate returning clusterId = null for global Topologies returned by allCoreServers() - return this.coreTopology; + return readReplicaTopology; } @Override - public CoreTopology localCoreServers() + public ReadReplicaTopology localReadReplicas() { - return allCoreServers().filterTopologyByDb( localDBName ); + return localReadReplicaTopology; } @Override - public void handleStepDown( long stepDownTerm, String dbName ) + public Optional findCatchupAddress( MemberId upstream ) { - boolean wasLeaderForTerm = Objects.equals( myself, leaderInfo.memberId() ) && stepDownTerm == leaderInfo.term(); - if ( wasLeaderForTerm ) - { - log.info( String.format( "Step down event detected. This topology member, with MemberId %s, was leader in term %s, now moving " + - "to follower.", myself, leaderInfo.term() ) ); - sharedDiscoveryService.casLeaders( leaderInfo.stepDown(), dbName ); - } + return localCoreServers().find( upstream ) + .map( info -> Optional.of( info.getCatchupServer() ) ) + .orElseGet( () -> readReplicaTopology.find( upstream ) + .map( ReadReplicaInfo::getCatchupServer ) ); } @Override - public String localDBName() + public void handleStepDown0( long stepDownTerm, String dbName ) { - return localDBName; + sharedDiscoveryService.casLeaders( leaderInfo.stepDown(), dbName ); } public MemberId getMemberId() @@ -193,27 +167,19 @@ public CoreServerInfo getCoreServerInfo() return coreServerInfo; } - synchronized void onCoreTopologyChange( CoreTopology coreTopology ) + void onCoreTopologyChange( CoreTopology coreTopology ) { log.info( "Notified of core topology change " + coreTopology ); this.coreTopology = coreTopology; + this.localCoreTopology = coreTopology.filterTopologyByDb( localDBName ); listenerService.notifyListeners( coreTopology ); } - synchronized void onReadReplicaTopologyChange( ReadReplicaTopology readReplicaTopology ) + void onReadReplicaTopologyChange( ReadReplicaTopology readReplicaTopology ) { log.info( "Notified of read replica topology change " + readReplicaTopology ); this.readReplicaTopology = readReplicaTopology; - } - - private static CoreServerInfo extractCoreServerInfo( Config config ) - { - AdvertisedSocketAddress raftAddress = config.get( CausalClusteringSettings.raft_advertised_address ); - AdvertisedSocketAddress transactionSource = config.get( CausalClusteringSettings.transaction_advertised_address ); - ClientConnectorAddresses clientConnectorAddresses = ClientConnectorAddresses.extractFromConfig( config ); - String dbName = config.get( CausalClusteringSettings.database ); - - return new CoreServerInfo( raftAddress, transactionSource, clientConnectorAddresses, dbName ); + this.localReadReplicaTopology = readReplicaTopology.filterTopologyByDb( localDBName ); } public boolean refusesToBeLeader() diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryReadReplicaClient.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryReadReplicaClient.java index 76dfeb7bedda5..b26ef069ff5f9 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryReadReplicaClient.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryReadReplicaClient.java @@ -29,13 +29,13 @@ import org.neo4j.causalclustering.identity.MemberId; import org.neo4j.helpers.AdvertisedSocketAddress; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.lifecycle.Lifecycle; +import org.neo4j.kernel.lifecycle.SafeLifecycle; import org.neo4j.logging.Log; import org.neo4j.logging.LogProvider; import static org.neo4j.helpers.SocketAddressParser.socketAddress; -class SharedDiscoveryReadReplicaClient implements TopologyService, Lifecycle +class SharedDiscoveryReadReplicaClient extends SafeLifecycle implements TopologyService { private final SharedDiscoveryService sharedDiscoveryService; private final ReadReplicaInfo addresses; @@ -56,26 +56,26 @@ class SharedDiscoveryReadReplicaClient implements TopologyService, Lifecycle } @Override - public void init() + public void init0() { // nothing to do } @Override - public void start() + public void start0() { sharedDiscoveryService.registerReadReplica( this ); log.info( "Registered read replica member id: %s at %s", memberId, addresses ); } @Override - public void stop() + public void stop0() { sharedDiscoveryService.unRegisterReadReplica( this ); } @Override - public void shutdown() + public void shutdown0() { // nothing to do } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryServiceFactory.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryServiceFactory.java index 1b1c33772a24e..5ccee3467c5f6 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryServiceFactory.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryServiceFactory.java @@ -42,7 +42,7 @@ public CoreTopologyService coreTopologyService( Config config, MemberId myself, } @Override - public TopologyService topologyService( Config config, LogProvider logProvider, JobScheduler jobScheduler, MemberId myself, + public TopologyService readReplicaTopologyService( Config config, LogProvider logProvider, JobScheduler jobScheduler, MemberId myself, HostnameResolver hostnameResolver, TopologyServiceRetryStrategy topologyServiceRetryStrategy ) { return new SharedDiscoveryReadReplicaClient( discoveryService, config, myself, logProvider ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/TestTopology.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/TestTopology.java index 13d4e19ceeace..ce88da932fa7a 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/TestTopology.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/TestTopology.java @@ -28,8 +28,10 @@ import java.util.function.Function; import java.util.stream.Collectors; +import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.causalclustering.identity.MemberId; import org.neo4j.helpers.AdvertisedSocketAddress; +import org.neo4j.kernel.configuration.Config; import static java.util.Collections.singletonList; import static org.neo4j.causalclustering.discovery.ClientConnectorAddresses.Scheme.bolt; @@ -46,13 +48,26 @@ private static ClientConnectorAddresses wrapAsClientConnectorAddresses( Advertis return new ClientConnectorAddresses( singletonList( new ClientConnectorAddresses.ConnectorUri( bolt, advertisedSocketAddress ) ) ); } - public static CoreServerInfo addressesForCore( int id ) + public static CoreServerInfo addressesForCore( int id, boolean refuseToBeLeader ) { AdvertisedSocketAddress raftServerAddress = new AdvertisedSocketAddress( "localhost", 3000 + id ); AdvertisedSocketAddress catchupServerAddress = new AdvertisedSocketAddress( "localhost", 4000 + id ); AdvertisedSocketAddress boltServerAddress = new AdvertisedSocketAddress( "localhost", 5000 + id ); return new CoreServerInfo( raftServerAddress, catchupServerAddress, wrapAsClientConnectorAddresses( boltServerAddress ), - asSet( "core", "core" + id ), "default" ); + asSet( "core", "core" + id ), "default", refuseToBeLeader ); + } + + public static Config configFor( CoreServerInfo coreServerInfo ) + { + return Config.builder() + .withSetting( CausalClusteringSettings.raft_advertised_address, coreServerInfo.getRaftServer().toString() ) + .withSetting( CausalClusteringSettings.transaction_advertised_address, coreServerInfo.getCatchupServer().toString() ) + .withSetting( "dbms.connector.bolt.listen_address", coreServerInfo.connectors().boltAddress().toString() ) + .withSetting( "dbms.connector.bolt.enabled", String.valueOf( true ) ) + .withSetting( CausalClusteringSettings.database, coreServerInfo.getDatabaseName() ) + .withSetting( CausalClusteringSettings.server_groups, String.join( ",", coreServerInfo.groups() ) ) + .withSetting( CausalClusteringSettings.refuse_to_be_leader, String.valueOf( coreServerInfo.refusesToBeLeader() ) ) + .build(); } public static ReadReplicaInfo addressesForReadReplica( int id ) diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/procedures/ClusterOverviewProcedureTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/procedures/ClusterOverviewProcedureTest.java index 4368a11b62481..7bff36a7c1b08 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/procedures/ClusterOverviewProcedureTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/procedures/ClusterOverviewProcedureTest.java @@ -26,7 +26,6 @@ import org.hamcrest.TypeSafeMatcher; import org.junit.Test; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -35,7 +34,6 @@ import java.util.UUID; import org.neo4j.causalclustering.core.CausalClusteringSettings; -import org.neo4j.causalclustering.core.consensus.LeaderLocator; import org.neo4j.causalclustering.discovery.CoreServerInfo; import org.neo4j.causalclustering.discovery.CoreTopology; import org.neo4j.causalclustering.discovery.CoreTopologyService; @@ -69,9 +67,9 @@ public void shouldProvideOverviewOfCoreServersAndReadReplicas() throws Exception MemberId follower1 = new MemberId( UUID.randomUUID() ); MemberId follower2 = new MemberId( UUID.randomUUID() ); - coreMembers.put( theLeader, addressesForCore( 0 ) ); - coreMembers.put( follower1, addressesForCore( 1 ) ); - coreMembers.put( follower2, addressesForCore( 2 ) ); + coreMembers.put( theLeader, addressesForCore( 0, false ) ); + coreMembers.put( follower1, addressesForCore( 1, false ) ); + coreMembers.put( follower2, addressesForCore( 2, false ) ); Map replicaMembers = new HashMap<>(); MemberId replica4 = new MemberId( UUID.randomUUID() ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/helpers/DataCreator.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/helpers/DataCreator.java index 0e2ec51cdfb05..c807429acef39 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/helpers/DataCreator.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/helpers/DataCreator.java @@ -40,7 +40,7 @@ private DataCreator() { } - public static CoreClusterMember createLabelledNodesWithProperty( Cluster cluster, int numberOfNodes, + public static CoreClusterMember createLabelledNodesWithProperty( Cluster cluster, int numberOfNodes, Label label, Supplier> propertyPair ) throws Exception { CoreClusterMember last = null; @@ -56,7 +56,7 @@ public static CoreClusterMember createLabelledNodesWithProperty( Cluster cluster return last; } - public static CoreClusterMember createEmptyNodes( Cluster cluster, int numberOfNodes ) throws Exception + public static CoreClusterMember createEmptyNodes( Cluster cluster, int numberOfNodes ) throws Exception { CoreClusterMember last = null; for ( int i = 0; i < numberOfNodes; i++ ) diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/identity/ClusterBinderTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/identity/ClusterBinderTest.java index e971e5b7e8223..f12d6015dba0c 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/identity/ClusterBinderTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/identity/ClusterBinderTest.java @@ -177,7 +177,7 @@ public void shouldBootstrapWhenBootstrappable() throws Throwable Map members = new HashMap<>(); IntStream.range(0, minCoreHosts).forEach( i -> - members.put( new MemberId( UUID.randomUUID() ), TestTopology.addressesForCore( i ) ) ); + members.put( new MemberId( UUID.randomUUID() ), TestTopology.addressesForCore( i, false ) ) ); CoreTopology bootstrappableTopology = new CoreTopology( null, true, members ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/messaging/marshalling/StringMarshalTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/messaging/marshalling/StringMarshalTest.java index 64351e078ecda..060688037ac0a 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/messaging/marshalling/StringMarshalTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/messaging/marshalling/StringMarshalTest.java @@ -26,6 +26,10 @@ import io.netty.buffer.UnpooledByteBufAllocator; import org.junit.Test; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; @@ -77,4 +81,62 @@ public void shouldSerializeAndDeserializeNull() // then assertNull( reconstructed ); } + + @Test + public void shouldSerializeAndDeserializeStringUsingChannel() throws IOException + { + // given + final String TEST_STRING = "ABC123_?"; + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWritableChannel writableChannel = new OutputStreamWritableChannel( outputStream ); + + // when + StringMarshal.marshal( writableChannel, TEST_STRING ); + + ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() ); + InputStreamReadableChannel readableChannel = new InputStreamReadableChannel( inputStream ); + String reconstructed = StringMarshal.unmarshal( readableChannel ); + + // then + assertNotSame( TEST_STRING, reconstructed ); + assertEquals( TEST_STRING, reconstructed ); + } + + @Test + public void shouldSerializeAndDeserializeEmptyStringUsingChannel() throws IOException + { + // given + final String TEST_STRING = ""; + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWritableChannel writableChannel = new OutputStreamWritableChannel( outputStream ); + + // when + StringMarshal.marshal( writableChannel, TEST_STRING ); + + ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() ); + InputStreamReadableChannel readableChannel = new InputStreamReadableChannel( inputStream ); + String reconstructed = StringMarshal.unmarshal( readableChannel ); + + // then + assertNotSame( TEST_STRING, reconstructed ); + assertEquals( TEST_STRING, reconstructed ); + } + + @Test + public void shouldSerializeAndDeserializeNullUsingChannel() throws IOException + { + // given + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWritableChannel writableChannel = new OutputStreamWritableChannel( outputStream ); + + // when + StringMarshal.marshal( writableChannel, null ); + + ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() ); + InputStreamReadableChannel readableChannel = new InputStreamReadableChannel( inputStream ); + String reconstructed = StringMarshal.unmarshal( readableChannel ); + + // then + assertNull( reconstructed ); + } } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/routing/load_balancing/procedure/GetServersProcedureV1RoutingTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/routing/load_balancing/procedure/GetServersProcedureV1RoutingTest.java index 69e366eef820d..11f00e32ffe85 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/routing/load_balancing/procedure/GetServersProcedureV1RoutingTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/routing/load_balancing/procedure/GetServersProcedureV1RoutingTest.java @@ -79,9 +79,9 @@ public void shouldReturnEndpointsInDifferentOrders() throws Exception when( leaderLocator.getLeader() ).thenReturn( member( 0 ) ); Map coreMembers = new HashMap<>(); - coreMembers.put( member( 0 ), addressesForCore( 0 ) ); - coreMembers.put( member( 1 ), addressesForCore( 1 ) ); - coreMembers.put( member( 2 ), addressesForCore( 2 ) ); + coreMembers.put( member( 0 ), addressesForCore( 0, false ) ); + coreMembers.put( member( 1 ), addressesForCore( 1, false ) ); + coreMembers.put( member( 2 ), addressesForCore( 2, false ) ); final CoreTopology clusterTopology = new CoreTopology( clusterId, false, coreMembers ); when( coreTopologyService.localCoreServers() ).thenReturn( clusterTopology ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/routing/load_balancing/procedure/GetServersProcedureV1Test.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/routing/load_balancing/procedure/GetServersProcedureV1Test.java index 174beccaeeae6..909865050ecf7 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/routing/load_balancing/procedure/GetServersProcedureV1Test.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/routing/load_balancing/procedure/GetServersProcedureV1Test.java @@ -147,7 +147,7 @@ public void shouldProvideReaderAndRouterForSingleCoreSetup() throws Exception LeaderLocator leaderLocator = mock( LeaderLocator.class ); Map coreMembers = new HashMap<>(); - coreMembers.put( member( 0 ), addressesForCore( 0 ) ); + coreMembers.put( member( 0 ), addressesForCore( 0, false ) ); final CoreTopology clusterTopology = new CoreTopology( clusterId, false, coreMembers ); when( coreTopologyService.localCoreServers() ).thenReturn( clusterTopology ); @@ -161,8 +161,8 @@ public void shouldProvideReaderAndRouterForSingleCoreSetup() throws Exception // then ClusterView.Builder builder = new ClusterView.Builder(); - builder.readAddress( addressesForCore( 0 ).connectors().boltAddress() ); - builder.routeAddress( addressesForCore( 0 ).connectors().boltAddress() ); + builder.readAddress( addressesForCore( 0, false ).connectors().boltAddress() ); + builder.routeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); assertEquals( builder.build(), clusterView ); } @@ -177,9 +177,9 @@ public void shouldReturnCoreServersWithRouteAllCoresButLeaderAsReadAndSingleWrit when( leaderLocator.getLeader() ).thenReturn( member( 0 ) ); Map coreMembers = new HashMap<>(); - coreMembers.put( member( 0 ), addressesForCore( 0 ) ); - coreMembers.put( member( 1 ), addressesForCore( 1 ) ); - coreMembers.put( member( 2 ), addressesForCore( 2 ) ); + coreMembers.put( member( 0 ), addressesForCore( 0, false ) ); + coreMembers.put( member( 1 ), addressesForCore( 1, false ) ); + coreMembers.put( member( 2 ), addressesForCore( 2, false ) ); final CoreTopology clusterTopology = new CoreTopology( clusterId, false, coreMembers ); when( coreTopologyService.localCoreServers() ).thenReturn( clusterTopology ); @@ -193,12 +193,12 @@ public void shouldReturnCoreServersWithRouteAllCoresButLeaderAsReadAndSingleWrit // then ClusterView.Builder builder = new ClusterView.Builder(); - builder.writeAddress( addressesForCore( 0 ).connectors().boltAddress() ); - builder.readAddress( addressesForCore( 1 ).connectors().boltAddress() ); - builder.readAddress( addressesForCore( 2 ).connectors().boltAddress() ); - builder.routeAddress( addressesForCore( 0 ).connectors().boltAddress() ); - builder.routeAddress( addressesForCore( 1 ).connectors().boltAddress() ); - builder.routeAddress( addressesForCore( 2 ).connectors().boltAddress() ); + builder.writeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); + builder.readAddress( addressesForCore( 1, false ).connectors().boltAddress() ); + builder.readAddress( addressesForCore( 2, false ).connectors().boltAddress() ); + builder.routeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); + builder.routeAddress( addressesForCore( 1, false ).connectors().boltAddress() ); + builder.routeAddress( addressesForCore( 2, false ).connectors().boltAddress() ); assertEquals( builder.build(), clusterView ); } @@ -213,7 +213,7 @@ public void shouldReturnSelfIfOnlyMemberOfTheCluster() throws Exception when( leaderLocator.getLeader() ).thenReturn( member( 0 ) ); Map coreMembers = new HashMap<>(); - coreMembers.put( member( 0 ), addressesForCore( 0 ) ); + coreMembers.put( member( 0 ), addressesForCore( 0, false ) ); final CoreTopology clusterTopology = new CoreTopology( clusterId, false, coreMembers ); when( coreTopologyService.localCoreServers() ).thenReturn( clusterTopology ); @@ -227,9 +227,9 @@ public void shouldReturnSelfIfOnlyMemberOfTheCluster() throws Exception // then ClusterView.Builder builder = new ClusterView.Builder(); - builder.writeAddress( addressesForCore( 0 ).connectors().boltAddress() ); - builder.readAddress( addressesForCore( 0 ).connectors().boltAddress() ); - builder.routeAddress( addressesForCore( 0 ).connectors().boltAddress() ); + builder.writeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); + builder.readAddress( addressesForCore( 0, false ).connectors().boltAddress() ); + builder.routeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); assertEquals( builder.build(), clusterView ); } @@ -242,7 +242,7 @@ public void shouldReturnTheCoreLeaderForWriteAndReadReplicasAndCoresForReads() t Map coreMembers = new HashMap<>(); MemberId theLeader = member( 0 ); - coreMembers.put( theLeader, addressesForCore( 0 ) ); + coreMembers.put( theLeader, addressesForCore( 0, false ) ); when( topologyService.localCoreServers() ).thenReturn( new CoreTopology( clusterId, false, coreMembers ) ); when( topologyService.localReadReplicas() ).thenReturn( new ReadReplicaTopology( readReplicaInfoMap( 1 ) ) ); @@ -258,13 +258,13 @@ public void shouldReturnTheCoreLeaderForWriteAndReadReplicasAndCoresForReads() t // then ClusterView.Builder builder = new ClusterView.Builder(); - builder.writeAddress( addressesForCore( 0 ).connectors().boltAddress() ); + builder.writeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); if ( expectFollowersAsReadEndPoints ) { - builder.readAddress( addressesForCore( 0 ).connectors().boltAddress() ); + builder.readAddress( addressesForCore( 0, false ).connectors().boltAddress() ); } builder.readAddress( addressesForReadReplica( 1 ).connectors().boltAddress() ); - builder.routeAddress( addressesForCore( 0 ).connectors().boltAddress() ); + builder.routeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); assertEquals( builder.build(), clusterView ); } @@ -277,7 +277,7 @@ public void shouldReturnCoreMemberAsReadServerIfNoReadReplicasAvailable() throws Map coreMembers = new HashMap<>(); MemberId theLeader = member( 0 ); - coreMembers.put( theLeader, addressesForCore( 0 ) ); + coreMembers.put( theLeader, addressesForCore( 0, false ) ); when( topologyService.localCoreServers() ).thenReturn( new CoreTopology( clusterId, false, coreMembers ) ); when( topologyService.localReadReplicas() ).thenReturn( new ReadReplicaTopology( emptyMap() ) ); @@ -293,9 +293,9 @@ public void shouldReturnCoreMemberAsReadServerIfNoReadReplicasAvailable() throws // then ClusterView.Builder builder = new ClusterView.Builder(); - builder.writeAddress( addressesForCore( 0 ).connectors().boltAddress() ); - builder.readAddress( addressesForCore( 0 ).connectors().boltAddress() ); - builder.routeAddress( addressesForCore( 0 ).connectors().boltAddress() ); + builder.writeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); + builder.readAddress( addressesForCore( 0, false ).connectors().boltAddress() ); + builder.routeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); assertEquals( builder.build(), clusterView ); } @@ -307,7 +307,7 @@ public void shouldReturnNoWriteEndpointsIfThereIsNoLeader() throws Exception final CoreTopologyService topologyService = mock( CoreTopologyService.class ); Map coreMembers = new HashMap<>(); - coreMembers.put( member( 0 ), addressesForCore( 0 ) ); + coreMembers.put( member( 0 ), addressesForCore( 0, false ) ); when( topologyService.localCoreServers() ).thenReturn( new CoreTopology( clusterId, false, coreMembers ) ); when( topologyService.localReadReplicas() ).thenReturn( new ReadReplicaTopology( emptyMap() ) ); @@ -323,8 +323,8 @@ public void shouldReturnNoWriteEndpointsIfThereIsNoLeader() throws Exception // then ClusterView.Builder builder = new ClusterView.Builder(); - builder.readAddress( addressesForCore( 0 ).connectors().boltAddress() ); - builder.routeAddress( addressesForCore( 0 ).connectors().boltAddress() ); + builder.readAddress( addressesForCore( 0, false ).connectors().boltAddress() ); + builder.routeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); assertEquals( builder.build(), clusterView ); } @@ -336,7 +336,7 @@ public void shouldReturnNoWriteEndpointsIfThereIsNoAddressForTheLeader() throws final CoreTopologyService topologyService = mock( CoreTopologyService.class ); Map coreMembers = new HashMap<>(); - coreMembers.put( member( 0 ), addressesForCore( 0 ) ); + coreMembers.put( member( 0 ), addressesForCore( 0, false ) ); when( topologyService.localCoreServers() ).thenReturn( new CoreTopology( clusterId, false, coreMembers ) ); when( topologyService.localReadReplicas() ).thenReturn( new ReadReplicaTopology( emptyMap() ) ); @@ -353,8 +353,8 @@ public void shouldReturnNoWriteEndpointsIfThereIsNoAddressForTheLeader() throws // then ClusterView.Builder builder = new ClusterView.Builder(); - builder.readAddress( addressesForCore( 0 ).connectors().boltAddress() ); - builder.routeAddress( addressesForCore( 0 ).connectors().boltAddress() ); + builder.readAddress( addressesForCore( 0, false ).connectors().boltAddress() ); + builder.routeAddress( addressesForCore( 0, false ).connectors().boltAddress() ); assertEquals( builder.build(), clusterView ); } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIpFamilyIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseClusterIpFamilyIT.java similarity index 68% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIpFamilyIT.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseClusterIpFamilyIT.java index 47f51fd3fb1ba..20f27df6537d2 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIpFamilyIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseClusterIpFamilyIT.java @@ -28,54 +28,39 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.util.Arrays; -import java.util.Collection; +import java.util.function.Supplier; +import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.causalclustering.discovery.Cluster; import org.neo4j.causalclustering.discovery.CoreClusterMember; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; import org.neo4j.causalclustering.discovery.IpFamily; import org.neo4j.causalclustering.helpers.DataCreator; import org.neo4j.test.causalclustering.ClusterRule; import static org.junit.Assert.assertEquals; import static org.neo4j.causalclustering.discovery.Cluster.dataMatchesEventually; -import static org.neo4j.causalclustering.discovery.IpFamily.IPV4; -import static org.neo4j.causalclustering.discovery.IpFamily.IPV6; import static org.neo4j.causalclustering.helpers.DataCreator.countNodes; -import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.HAZELCAST; -import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.SHARED; @RunWith( Parameterized.class ) -public class ClusterIpFamilyIT +public abstract class BaseClusterIpFamilyIT { - - @Parameterized.Parameters( name = "{0} {1} useWildcard={2}" ) - public static Collection data() - { - return Arrays.asList( new Object[][]{ - {SHARED, IPV4, false}, - {SHARED, IPV6, true}, - - {HAZELCAST, IPV4, false}, - {HAZELCAST, IPV6, false}, - - {HAZELCAST, IPV4, true}, - {HAZELCAST, IPV6, true}, - } ); - } - - public ClusterIpFamilyIT( DiscoveryServiceType discoveryServiceType, IpFamily ipFamily, boolean useWildcard ) + protected BaseClusterIpFamilyIT( Supplier discoveryServiceFactory, IpFamily ipFamily, boolean useWildcard ) { - clusterRule.withDiscoveryServiceType( discoveryServiceType ); + clusterRule.withDiscoveryServiceType( discoveryServiceFactory ); clusterRule.withIpFamily( ipFamily ).useWildcard( useWildcard ); } @Rule public final ClusterRule clusterRule = new ClusterRule() .withNumberOfCoreMembers( 3 ) - .withNumberOfReadReplicas( 3 ); + .withNumberOfReadReplicas( 3 ) + .withSharedCoreParam( CausalClusteringSettings.disable_middleware_logging, "false" ) + .withSharedReadReplicaParam( CausalClusteringSettings.disable_middleware_logging, "false" ) + .withSharedCoreParam( CausalClusteringSettings.middleware_logging_level, "0" ) + .withSharedReadReplicaParam( CausalClusteringSettings.middleware_logging_level, "0" );; - private Cluster cluster; + private Cluster cluster; @Before public void setup() throws Exception diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterOverviewIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseClusterOverviewIT.java similarity index 88% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterOverviewIT.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseClusterOverviewIT.java index 7f7c40a4fcb5b..78ef439cd8331 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterOverviewIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseClusterOverviewIT.java @@ -37,11 +37,11 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -51,6 +51,7 @@ import org.neo4j.causalclustering.discovery.Cluster; import org.neo4j.causalclustering.discovery.ClusterMember; import org.neo4j.causalclustering.discovery.CoreClusterMember; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; import org.neo4j.causalclustering.discovery.ReadReplica; import org.neo4j.causalclustering.discovery.RoleInfo; import org.neo4j.causalclustering.discovery.procedures.ClusterOverviewProcedure; @@ -80,21 +81,20 @@ import static org.neo4j.test.assertion.Assert.assertEventually; @RunWith( Parameterized.class ) -public class ClusterOverviewIT +public abstract class BaseClusterOverviewIT { @Rule public ClusterRule clusterRule = new ClusterRule() - .withSharedCoreParam( CausalClusteringSettings.cluster_topology_refresh, "5s" ); - - @Parameterized.Parameters( name = "discovery-{0}" ) - public static Collection data() - { - return Arrays.asList( DiscoveryServiceType.values() ); - } - - public ClusterOverviewIT( DiscoveryServiceType discoveryServiceType ) + .withSharedCoreParam( CausalClusteringSettings.cluster_topology_refresh, "5s" ) + .withSharedReadReplicaParam( CausalClusteringSettings.cluster_topology_refresh, "5s" ) + .withSharedCoreParam( CausalClusteringSettings.disable_middleware_logging, "false" ) + .withSharedReadReplicaParam( CausalClusteringSettings.disable_middleware_logging, "false" ) + .withSharedCoreParam( CausalClusteringSettings.middleware_logging_level, "0" ) + .withSharedReadReplicaParam( CausalClusteringSettings.middleware_logging_level, "0" ); + + protected BaseClusterOverviewIT( Supplier discoveryServiceFactory ) { - clusterRule.withDiscoveryServiceType( discoveryServiceType ); + clusterRule.withDiscoveryServiceType( discoveryServiceFactory ); } @Test @@ -106,7 +106,7 @@ public void shouldDiscoverCoreMembers() throws Exception clusterRule.withNumberOfReadReplicas( 0 ); // when - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); Matcher> expected = allOf( containsMemberAddresses( cluster.coreMembers() ), @@ -126,7 +126,7 @@ public void shouldDiscoverCoreMembersAndReadReplicas() throws Exception clusterRule.withNumberOfReadReplicas( replicaCount ); // when - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); Matcher> expected = allOf( containsAllMemberAddresses( cluster.coreMembers(), cluster.readReplicas() ), @@ -146,7 +146,7 @@ public void shouldDiscoverReadReplicasAfterRestartingCores() throws Exception clusterRule.withNumberOfReadReplicas( readReplicas ); // when - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); cluster.shutdownCoreMembers(); cluster.startCoreMembers(); @@ -166,7 +166,7 @@ public void shouldDiscoverNewCoreMembers() throws Exception clusterRule.withNumberOfCoreMembers( initialCoreMembers ); clusterRule.withNumberOfReadReplicas( 0 ); - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); // when int extraCoreMembers = 2; @@ -186,15 +186,15 @@ public void shouldDiscoverNewReadReplicas() throws Exception { // given int coreMembers = 3; - int initialReadReplicas = 3; + int initialReadReplicas = 2; clusterRule.withNumberOfCoreMembers( coreMembers ); clusterRule.withNumberOfReadReplicas( initialReadReplicas ); - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); // when - cluster.addReadReplicaWithId( 3 ).start(); - cluster.addReadReplicaWithId( 4 ).start(); + cluster.addReadReplicaWithId( initialReadReplicas ).start(); + cluster.addReadReplicaWithId( initialReadReplicas + 1 ).start(); Matcher> expected = allOf( containsAllMemberAddresses( cluster.coreMembers(), cluster.readReplicas() ), @@ -215,7 +215,7 @@ public void shouldDiscoverRemovalOfReadReplicas() throws Exception clusterRule.withNumberOfCoreMembers( coreMembers ); clusterRule.withNumberOfReadReplicas( initialReadReplicas ); - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); assertAllEventualOverviews( cluster, containsRole( READ_REPLICA, initialReadReplicas ) ); @@ -235,7 +235,7 @@ public void shouldDiscoverRemovalOfCoreMembers() throws Exception clusterRule.withNumberOfCoreMembers( coreMembers ); clusterRule.withNumberOfReadReplicas( 0 ); - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); assertAllEventualOverviews( cluster, allOf( containsRole( LEADER, 1 ), containsRole( FOLLOWER, coreMembers - 1 ) ) ); @@ -252,9 +252,9 @@ public void shouldDiscoverRemovalOfCoreMembers() throws Exception public void shouldDiscoverTimeoutBasedLeaderStepdown() throws Exception { clusterRule.withNumberOfCoreMembers( 3 ); - clusterRule.withNumberOfReadReplicas( 2 ); + clusterRule.withNumberOfReadReplicas( 0 ); - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); List followers = cluster.getAllMembersWithRole( Role.FOLLOWER ); CoreClusterMember leader = cluster.getMemberWithRole( Role.LEADER ); followers.forEach( CoreClusterMember::shutdown ); @@ -266,9 +266,9 @@ public void shouldDiscoverTimeoutBasedLeaderStepdown() throws Exception public void shouldDiscoverGreaterTermBasedLeaderStepdown() throws Exception { int originalCoreMembers = 3; - clusterRule.withNumberOfCoreMembers( originalCoreMembers ); + clusterRule.withNumberOfCoreMembers( originalCoreMembers ).withNumberOfReadReplicas( 0 ); - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); CoreClusterMember leader = cluster.awaitLeader(); leader.config().augment( CausalClusteringSettings.refuse_to_be_leader, Settings.TRUE ); @@ -283,12 +283,12 @@ public void shouldDiscoverGreaterTermBasedLeaderStepdown() throws Exception not( equalTo( preElectionOverview ) ) ), leader, "core" ); } - private void assertAllEventualOverviews( Cluster cluster, Matcher> expected ) throws KernelException, InterruptedException + private void assertAllEventualOverviews( Cluster cluster, Matcher> expected ) throws KernelException, InterruptedException { assertAllEventualOverviews( cluster, expected, Collections.emptySet(), Collections.emptySet() ); } - private void assertAllEventualOverviews( Cluster cluster, Matcher> expected, Set excludedCores, Set excludedRRs ) + private void assertAllEventualOverviews( Cluster cluster, Matcher> expected, Set excludedCores, Set excludedRRs ) throws KernelException, InterruptedException { for ( CoreClusterMember core : cluster.coreMembers() ) diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/MultiClusterRoutingIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseMultiClusterRoutingIT.java similarity index 85% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/MultiClusterRoutingIT.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseMultiClusterRoutingIT.java index f9d24125b407c..a319e62dc165b 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/MultiClusterRoutingIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseMultiClusterRoutingIT.java @@ -30,8 +30,6 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -41,6 +39,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.BiPredicate; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -48,6 +47,7 @@ import org.neo4j.causalclustering.core.consensus.roles.Role; import org.neo4j.causalclustering.discovery.Cluster; import org.neo4j.causalclustering.discovery.CoreClusterMember; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; import org.neo4j.causalclustering.routing.Endpoint; import org.neo4j.causalclustering.routing.multi_cluster.MultiClusterRoutingResult; import org.neo4j.causalclustering.routing.multi_cluster.procedure.MultiClusterRoutingResultFormat; @@ -65,42 +65,25 @@ import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertEquals; import static org.neo4j.causalclustering.routing.multi_cluster.procedure.ParameterNames.DATABASE; -import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.SHARED; -import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.HAZELCAST; import static org.neo4j.causalclustering.routing.multi_cluster.procedure.ProcedureNames.GET_ROUTERS_FOR_DATABASE; import static org.neo4j.causalclustering.routing.multi_cluster.procedure.ProcedureNames.GET_ROUTERS_FOR_ALL_DATABASES; import static org.neo4j.test.assertion.Assert.assertEventually; @RunWith( Parameterized.class ) -public class MultiClusterRoutingIT +public abstract class BaseMultiClusterRoutingIT { - private static Set DB_NAMES_1 = Stream.of( "foo", "bar" ).collect( Collectors.toSet() ); - private static Set DB_NAMES_2 = Collections.singleton( "default" ); - private static Set DB_NAMES_3 = Stream.of( "foo", "bar", "baz" ).collect( Collectors.toSet() ); - - @Parameterized.Parameters( name = "{0}" ) - public static Collection data() - { - return Arrays.asList( new Object[][] - { - { "[shared discovery, 6 core hosts, 2 databases]", 6, 0, DB_NAMES_1, SHARED }, - { "[hazelcast discovery, 6 core hosts, 2 databases]", 6, 0, DB_NAMES_1, HAZELCAST }, - { "[shared discovery, 5 core hosts, 1 database]", 5, 0, DB_NAMES_2, SHARED }, - { "[hazelcast discovery, 5 core hosts, 1 database]", 5, 0, DB_NAMES_2, HAZELCAST }, - { "[hazelcast discovery, 6 core hosts, 3 read replicas, 3 databases]", 9, 3, DB_NAMES_3, HAZELCAST }, - { "[shared discovery, 6 core hosts, 3 read replicas, 3 databases]", 8, 2, DB_NAMES_3, SHARED } - } - ); - } + protected static Set DB_NAMES_1 = Stream.of( "foo", "bar" ).collect( Collectors.toSet() ); + protected static Set DB_NAMES_2 = Collections.singleton( "default" ); + protected static Set DB_NAMES_3 = Stream.of( "foo", "bar", "baz" ).collect( Collectors.toSet() ); private final Set dbNames; private final ClusterRule clusterRule; private final DefaultFileSystemRule fileSystemRule; - private final DiscoveryServiceType discoveryType; + private final Supplier discoveryType; private final int numCores; - private Cluster cluster; + private Cluster cluster; private FileSystemAbstraction fs; @Rule @@ -109,7 +92,8 @@ public static Collection data() @Rule public Timeout globalTimeout = Timeout.seconds(300); - public MultiClusterRoutingIT( String ignoredName, int numCores, int numReplicas, Set dbNames, DiscoveryServiceType discoveryType ) + protected BaseMultiClusterRoutingIT( String ignoredName, int numCores, int numReplicas, Set dbNames, + Supplier discoveryType ) { this.dbNames = dbNames; this.discoveryType = discoveryType; diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/MultiClusteringIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseMultiClusteringIT.java similarity index 83% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/MultiClusteringIT.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseMultiClusteringIT.java index 783c1e4d8cb63..4684ad40c2396 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/MultiClusteringIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/BaseMultiClusteringIT.java @@ -31,14 +31,13 @@ import org.junit.runners.Parameterized; import java.io.File; -import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutionException; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -46,6 +45,7 @@ import org.neo4j.causalclustering.core.consensus.roles.Role; import org.neo4j.causalclustering.discovery.Cluster; import org.neo4j.causalclustering.discovery.CoreClusterMember; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; import org.neo4j.causalclustering.helpers.DataCreator; import org.neo4j.causalclustering.identity.StoreId; import org.neo4j.graphdb.Node; @@ -58,48 +58,32 @@ import static org.junit.Assert.fail; import static org.neo4j.causalclustering.TestStoreId.getStoreIds; import static org.neo4j.causalclustering.discovery.Cluster.dataMatchesEventually; -import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.HAZELCAST; -import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.SHARED; import static org.neo4j.graphdb.Label.label; @RunWith( Parameterized.class ) -public class MultiClusteringIT +public abstract class BaseMultiClusteringIT { - private static Set DB_NAMES_1 = Stream.of( "foo", "bar" ).collect( Collectors.toSet() ); - private static Set DB_NAMES_2 = Collections.singleton( "default" ); - private static Set DB_NAMES_3 = Stream.of( "foo", "bar", "baz" ).collect( Collectors.toSet() ); - - @Parameterized.Parameters( name = "{0}" ) - public static Collection data() - { - return Arrays.asList( new Object[][] - { - { "[shared discovery, 6 core hosts, 2 databases]", 6, 0, DB_NAMES_1, SHARED }, - { "[hazelcast discovery, 6 core hosts, 2 databases]", 6, 0, DB_NAMES_1, HAZELCAST }, - { "[shared discovery, 5 core hosts, 1 database]", 5, 0, DB_NAMES_2, SHARED }, - { "[hazelcast discovery, 5 core hosts, 2 databases]", 5, 0, DB_NAMES_1, HAZELCAST }, - { "[hazelcast discovery, 9 core hosts, 3 read replicas, 3 databases]", 9, 3, DB_NAMES_3, HAZELCAST }, - { "[shared discovery, 8 core hosts, 2 read replicas, 3 databases]", 8, 2, DB_NAMES_3, SHARED } - } - ); - } + protected static Set DB_NAMES_1 = Collections.singleton( "default" ); + protected static Set DB_NAMES_2 = Stream.of( "foo", "bar" ).collect( Collectors.toSet() ); + protected static Set DB_NAMES_3 = Stream.of( "foo", "bar", "baz" ).collect( Collectors.toSet() ); private final Set dbNames; private final ClusterRule clusterRule; private final DefaultFileSystemRule fileSystemRule; - private final DiscoveryServiceType discoveryType; + private final Supplier discoveryType; @Rule public final RuleChain ruleChain; - private Cluster cluster; + private Cluster cluster; private FileSystemAbstraction fs; @Rule public Timeout globalTimeout = Timeout.seconds(300); - public MultiClusteringIT( String ignoredName, int numCores, int numReplicas, Set dbNames, DiscoveryServiceType discoveryType ) + protected BaseMultiClusteringIT( String ignoredName, int numCores, int numReplicas, Set dbNames, + Supplier discoveryServiceFactory ) { this.dbNames = dbNames; - this.discoveryType = discoveryType; + this.discoveryType = discoveryServiceFactory; this.clusterRule = new ClusterRule() .withNumberOfCoreMembers( numCores ) diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CausalClusteringProceduresIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CausalClusteringProceduresIT.java index 3e2851edb1442..3f1f952bc15d6 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CausalClusteringProceduresIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CausalClusteringProceduresIT.java @@ -48,7 +48,7 @@ public class CausalClusteringProceduresIT .withNumberOfCoreMembers( 2 ) .withNumberOfReadReplicas( 1 ); - private static Cluster cluster; + private static Cluster cluster; @BeforeClass public static void setup() throws Exception diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CausalClusteringRolesIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CausalClusteringRolesIT.java index 7beaf957d798c..9371e3a90fef9 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CausalClusteringRolesIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CausalClusteringRolesIT.java @@ -46,7 +46,7 @@ public class CausalClusteringRolesIT public void readReplicasShouldRefuseWrites() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); GraphDatabaseService db = cluster.findAnyReadReplica().database(); Transaction tx = db.beginTx(); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterBindingIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterBindingIT.java index 6cbe324ec40dd..4645377ec89b3 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterBindingIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterBindingIT.java @@ -72,7 +72,7 @@ public class ClusterBindingIT @Rule public RuleChain ruleChain = RuleChain.outerRule( fileSystemRule ).around( clusterRule ); - private Cluster cluster; + private Cluster cluster; private FileSystemAbstraction fs; @Before diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCommunityToEnterpriseIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCommunityToEnterpriseIT.java index 9b859a6136705..442cdbe06e4e8 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCommunityToEnterpriseIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCommunityToEnterpriseIT.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.neo4j.causalclustering.discovery.Cluster; +import org.neo4j.causalclustering.discovery.EnterpriseCluster; import org.neo4j.causalclustering.discovery.IpFamily; import org.neo4j.causalclustering.discovery.SharedDiscoveryServiceFactory; import org.neo4j.graphdb.GraphDatabaseService; @@ -47,7 +48,7 @@ public class ClusterCommunityToEnterpriseIT { - private Cluster cluster; + private Cluster cluster; private FileSystemAbstraction fsa; @Rule @@ -60,7 +61,7 @@ public void setup() { fsa = fileSystemRule.get(); - cluster = new Cluster( testDir.directory( "cluster" ), 3, 0, + cluster = new EnterpriseCluster( testDir.directory( "cluster" ), 3, 0, new SharedDiscoveryServiceFactory(), emptyMap(), emptyMap(), emptyMap(), emptyMap(), HighLimit.NAME, IpFamily.IPV4, false ); } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCompressionIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCompressionIT.java index 1dff11b21fde8..77b0223eccda4 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCompressionIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCompressionIT.java @@ -74,7 +74,7 @@ public void shouldReplicateWithCompression() throws Exception .withSharedCoreParam( compression_implementations, modifierProtocol.implementation() ) .withSharedReadReplicaParam( compression_implementations, modifierProtocol.implementation() ); - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); // when int numberOfNodes = 10; diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCustomLogLocationIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCustomLogLocationIT.java index 799e7b5614ca4..16b76879378fc 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCustomLogLocationIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterCustomLogLocationIT.java @@ -54,7 +54,7 @@ public class ClusterCustomLogLocationIT @Test public void clusterWithCustomTransactionLogLocation() throws Exception { - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); for ( int i = 0; i < 10; i++ ) { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterDiscoveryIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterDiscoveryIT.java index fb544e53fa721..c31ad9eee5dbb 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterDiscoveryIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterDiscoveryIT.java @@ -81,7 +81,7 @@ public static Collection params() public void shouldFindReadWriteAndRouteServers() throws Exception { // when - Cluster cluster = clusterRule.withSharedCoreParams( config ).withNumberOfReadReplicas( 1 ).startCluster(); + Cluster cluster = clusterRule.withSharedCoreParams( config ).withNumberOfReadReplicas( 1 ).startCluster(); // then int cores = cluster.coreMembers().size(); @@ -106,7 +106,7 @@ public void shouldFindReadWriteAndRouteServers() throws Exception public void shouldNotBeAbleToDiscoverFromReadReplicas() throws Exception { // given - Cluster cluster = clusterRule.withSharedCoreParams( config ).withNumberOfReadReplicas( 2 ).startCluster(); + Cluster cluster = clusterRule.withSharedCoreParams( config ).withNumberOfReadReplicas( 2 ).startCluster(); try { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterFormationIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterFormationIT.java index 9a367fca5022f..4c3c9f0d31a75 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterFormationIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterFormationIT.java @@ -53,7 +53,7 @@ public class ClusterFormationIT .withNumberOfCoreMembers( 3 ) .withNumberOfReadReplicas( 0 ); - private Cluster cluster; + private Cluster cluster; @Before public void setup() throws Exception diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIdReuseIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIdReuseIT.java index 01988dc13565d..95fe9da9d3e86 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIdReuseIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIdReuseIT.java @@ -51,7 +51,7 @@ public class ClusterIdReuseIT // need to be 1 in order for the reuse count to be deterministic .withSharedCoreParam( GraphDatabaseSettings.record_id_batch_size, Integer.toString( 1 ) ) .withNumberOfReadReplicas( 0 ); - private Cluster cluster; + private Cluster cluster; @Test public void shouldReuseIdsInCluster() throws Exception @@ -200,7 +200,7 @@ private T resolveDependency( CoreClusterMember leader, Class clazz ) return leader.database().getDependencyResolver().resolveDependency( clazz ); } - private CoreClusterMember removeTwoNodes( Cluster cluster, MutableLong first, MutableLong second ) throws Exception + private CoreClusterMember removeTwoNodes( Cluster cluster, MutableLong first, MutableLong second ) throws Exception { return cluster.coreTx( ( db, tx ) -> { @@ -213,7 +213,7 @@ private CoreClusterMember removeTwoNodes( Cluster cluster, MutableLong first, Mu } ); } - private CoreClusterMember createThreeNodes( Cluster cluster, MutableLong first, MutableLong second ) throws Exception + private CoreClusterMember createThreeNodes( Cluster cluster, MutableLong first, MutableLong second ) throws Exception { return cluster.coreTx( ( db, tx ) -> { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIndexProcedureIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIndexProcedureIT.java index 6d2ebdda9d983..b059ec9312379 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIndexProcedureIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterIndexProcedureIT.java @@ -62,7 +62,7 @@ public class ClusterIndexProcedureIT .withNumberOfReadReplicas( 3 ) .withTimeout( 1000, SECONDS ); - private Cluster cluster; + private Cluster cluster; @Before public void setup() throws Exception diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterLeaderStepDownIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterLeaderStepDownIT.java index 5ade7db13cd0a..82c8092eb616a 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterLeaderStepDownIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterLeaderStepDownIT.java @@ -50,7 +50,7 @@ public class ClusterLeaderStepDownIT public void leaderShouldStepDownWhenFollowersAreGone() throws Throwable { // when - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); //Do some work to make sure the cluster is operating normally. CoreClusterMember leader = cluster.coreTx( ( db, tx ) -> diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterShutdownIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterShutdownIT.java index 86892e5419adc..925b38ad123f2 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterShutdownIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ClusterShutdownIT.java @@ -54,7 +54,7 @@ public class ClusterShutdownIT @Parameterized.Parameter() public Collection shutdownOrder; - private Cluster cluster; + private Cluster cluster; @Parameterized.Parameters( name = "shutdown order {0}" ) public static Collection> shutdownOrders() @@ -93,7 +93,7 @@ private void createANode( AtomicReference node ) throws Exception } ); } - private void shouldShutdownEvenThoughWaitingForLock0( Cluster cluster, int victimId, Collection shutdownOrder ) throws Exception + private void shouldShutdownEvenThoughWaitingForLock0( Cluster cluster, int victimId, Collection shutdownOrder ) throws Exception { final int LONG_TIME = 60_000; final int NUMBER_OF_LOCK_ACQUIRERS = 2; diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ConsensusGroupSettingsIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ConsensusGroupSettingsIT.java index d7e0e09b9cfc1..0ccbb8f5716d7 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ConsensusGroupSettingsIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ConsensusGroupSettingsIT.java @@ -45,7 +45,7 @@ public class ConsensusGroupSettingsIT .withInstanceCoreParam( CausalClusteringSettings.leader_election_timeout, value -> "1s" ) .withTimeout( 1000, SECONDS ); - private Cluster cluster; + private Cluster cluster; @Before public void setup() throws Exception diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CorePruningIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CorePruningIT.java index cf07dc81132e7..89da25b2aef32 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CorePruningIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CorePruningIT.java @@ -52,7 +52,7 @@ public class CorePruningIT public void actuallyDeletesTheFiles() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); CoreClusterMember coreGraphDatabase = null; int txs = 10; @@ -76,7 +76,7 @@ public void actuallyDeletesTheFiles() throws Exception public void shouldNotPruneUncommittedEntries() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); CoreClusterMember coreGraphDatabase = null; int txs = 1000; diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreReplicationIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreReplicationIT.java index 5a3d45f536856..0ed64c3e9d9ad 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreReplicationIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreReplicationIT.java @@ -66,7 +66,7 @@ public class CoreReplicationIT .withNumberOfReadReplicas( 0 ) .withTimeout( 1000, SECONDS ); - private Cluster cluster; + private Cluster cluster; @Before public void setup() throws Exception diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreToCoreCopySnapshotIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreToCoreCopySnapshotIT.java index 21df1f45df7bf..be6e13494b1a9 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreToCoreCopySnapshotIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreToCoreCopySnapshotIT.java @@ -65,7 +65,7 @@ public class CoreToCoreCopySnapshotIT public void shouldBeAbleToDownloadLargerFreshSnapshot() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); CoreClusterMember source = cluster.coreTx( ( db, tx ) -> { @@ -99,7 +99,7 @@ public void shouldBeAbleToDownloadToNewInstanceAfterPruning() throws Exception CausalClusteringSettings.raft_log_pruning_strategy.name(), "3 entries", CausalClusteringSettings.raft_log_rotation_size.name(), "1K" ); - Cluster cluster = clusterRule.withSharedCoreParams( params ).startCluster(); + Cluster cluster = clusterRule.withSharedCoreParams( params ).startCluster(); CoreClusterMember leader = cluster.coreTx( ( db, tx ) -> { @@ -136,7 +136,7 @@ public void shouldBeAbleToDownloadToRejoinedInstanceAfterPruning() throws Except int numberOfTransactions = 100; // start the cluster - Cluster cluster = clusterRule.withSharedCoreParams( coreParams ).startCluster(); + Cluster cluster = clusterRule.withSharedCoreParams( coreParams ).startCluster(); Timeout timeout = new Timeout( Clocks.systemClock(), 120, SECONDS ); // accumulate some log files @@ -200,7 +200,7 @@ private int getMostRecentLogIdOn( CoreClusterMember clusterMember ) throws IOExc return clusterMember.getLogFileNames().lastKey().intValue(); } - private CoreClusterMember doSomeTransactions( Cluster cluster, int count ) + private CoreClusterMember doSomeTransactions( Cluster cluster, int count ) { try { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/HazelcastCoreTopologyServiceTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreTopologyServiceIT.java similarity index 65% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/HazelcastCoreTopologyServiceTest.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreTopologyServiceIT.java index d05fbcc57bc98..88926556ec544 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/HazelcastCoreTopologyServiceTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/CoreTopologyServiceIT.java @@ -20,13 +20,23 @@ * More information is also available at: * https://neo4j.com/licensing/ */ -package org.neo4j.causalclustering.discovery; +package org.neo4j.causalclustering.scenarios; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import java.util.Arrays; +import java.util.Collection; import java.util.UUID; +import java.util.function.Supplier; import org.neo4j.causalclustering.core.CausalClusteringSettings; +import org.neo4j.causalclustering.discovery.CoreTopologyService; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; +import org.neo4j.causalclustering.discovery.HostnameResolver; +import org.neo4j.causalclustering.discovery.NoOpHostnameResolver; +import org.neo4j.causalclustering.discovery.TopologyServiceNoRetriesStrategy; import org.neo4j.causalclustering.identity.MemberId; import org.neo4j.kernel.configuration.BoltConnector; import org.neo4j.kernel.configuration.Config; @@ -38,10 +48,17 @@ import static org.neo4j.causalclustering.core.CausalClusteringSettings.initial_discovery_members; import static org.neo4j.helpers.collection.MapUtil.stringMap; -public class HazelcastCoreTopologyServiceTest +public abstract class CoreTopologyServiceIT { + private final Supplier discoveryServiceType; + + protected CoreTopologyServiceIT( Supplier discoveryServiceType ) + { + this.discoveryServiceType = discoveryServiceType; + } + @Test( timeout = 120_000 ) - public void shouldBeAbleToStartAndStoreWithoutSuccessfulJoin() + public void shouldBeAbleToStartAndStopWithoutSuccessfulJoin() throws Throwable { CentralJobScheduler jobScheduler = new CentralJobScheduler(); jobScheduler.init(); @@ -49,9 +66,11 @@ public void shouldBeAbleToStartAndStoreWithoutSuccessfulJoin() // Random members that does not exists, discovery will never succeed String initialHosts = "localhost:" + PortAuthority.allocatePort() + ",localhost:" + PortAuthority.allocatePort(); - Config config = config(); + Config config = Config.defaults(); config.augment( initial_discovery_members, initialHosts ); - HazelcastCoreTopologyService service = new HazelcastCoreTopologyService( config, + config.augment( CausalClusteringSettings.discovery_listen_address, "localhost:" + PortAuthority.allocatePort() ); + CoreTopologyService service = discoveryServiceType.get().coreTopologyService( + config, new MemberId( UUID.randomUUID() ), jobScheduler, NullLogProvider.getInstance(), @@ -59,16 +78,10 @@ public void shouldBeAbleToStartAndStoreWithoutSuccessfulJoin() hostnameResolver, new TopologyServiceNoRetriesStrategy(), new Monitors() ); + service.init(); service.start(); service.stop(); + service.shutdown(); } - private static Config config() - { - return Config.defaults( stringMap( - CausalClusteringSettings.raft_advertised_address.name(), "127.0.0.1:7000", - CausalClusteringSettings.transaction_advertised_address.name(), "127.0.0.1:7001", - new BoltConnector( "bolt" ).enabled.name(), "true", - new BoltConnector( "bolt" ).advertised_address.name(), "127.0.0.1:7002" ) ); - } } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/DiscoveryServiceType.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/DiscoveryServiceType.java index ea5fb64068276..9a498382ce74a 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/DiscoveryServiceType.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/DiscoveryServiceType.java @@ -22,28 +22,18 @@ */ package org.neo4j.causalclustering.scenarios; +import java.util.Arrays; +import java.util.List; import java.util.function.Supplier; import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; import org.neo4j.causalclustering.discovery.HazelcastDiscoveryServiceFactory; -import org.neo4j.causalclustering.discovery.SharedDiscoveryService; import org.neo4j.causalclustering.discovery.SharedDiscoveryServiceFactory; -public enum DiscoveryServiceType +public interface DiscoveryServiceType { - SHARED( SharedDiscoveryServiceFactory::new ), - HAZELCAST( HazelcastDiscoveryServiceFactory::new ); - - private final Supplier factory; - - DiscoveryServiceType( Supplier factory ) - { - this.factory = factory; - } - - public DiscoveryServiceFactory create() - { - return factory.get(); - } + Supplier SHARED = SharedDiscoveryServiceFactory::new; + Supplier HAZELCAST = HazelcastDiscoveryServiceFactory::new; + List> values = Arrays.asList( SHARED, HAZELCAST ); } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseClusterIpFamilyIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseClusterIpFamilyIT.java new file mode 100644 index 0000000000000..d964edfb559c0 --- /dev/null +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseClusterIpFamilyIT.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.scenarios; + +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Supplier; + +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; +import org.neo4j.causalclustering.discovery.IpFamily; + +import static org.neo4j.causalclustering.discovery.IpFamily.IPV4; +import static org.neo4j.causalclustering.discovery.IpFamily.IPV6; +import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.HAZELCAST; +import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.SHARED; + +public class EnterpriseClusterIpFamilyIT extends BaseClusterIpFamilyIT +{ + @Parameterized.Parameters( name = "{0} {1} useWildcard={2}" ) + public static Collection data() + { + return Arrays.asList( new Object[][]{ + {SHARED, IPV4, false}, + {SHARED, IPV6, true}, + + {HAZELCAST, IPV4, false}, + {HAZELCAST, IPV6, false}, + + {HAZELCAST, IPV4, true}, + {HAZELCAST, IPV6, true}, + } ); + } + + public EnterpriseClusterIpFamilyIT( Supplier discoveryServiceFactory, IpFamily ipFamily, boolean useWildcard ) + { + super( discoveryServiceFactory, ipFamily, useWildcard ); + } +} diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseClusterOverviewIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseClusterOverviewIT.java new file mode 100644 index 0000000000000..a74769fd9acfa --- /dev/null +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseClusterOverviewIT.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.scenarios; + +import org.junit.runners.Parameterized; + +import java.util.Collection; +import java.util.function.Supplier; + +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; + +public class EnterpriseClusterOverviewIT extends BaseClusterOverviewIT +{ + public EnterpriseClusterOverviewIT( Supplier discoveryServiceFactory ) + { + super( discoveryServiceFactory ); + } + + @Parameterized.Parameters( name = "discovery-{0}" ) + public static Collection> data() + { + return DiscoveryServiceType.values; + } +} diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseMultiClusterRoutingIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseMultiClusterRoutingIT.java new file mode 100644 index 0000000000000..47332bf199c5a --- /dev/null +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseMultiClusterRoutingIT.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.scenarios; + +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Set; +import java.util.function.Supplier; + +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; + +import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.HAZELCAST; +import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.SHARED; + +public class EnterpriseMultiClusterRoutingIT extends BaseMultiClusterRoutingIT +{ + public EnterpriseMultiClusterRoutingIT( String ignoredName, int numCores, int numReplicas, Set dbNames, + Supplier discoveryType ) + { + super( ignoredName, numCores, numReplicas, dbNames, discoveryType ); + } + + @Parameterized.Parameters( name = "{0}" ) + public static Collection data() + { + return Arrays.asList( new Object[][] + { + { "[shared discovery, 6 core hosts, 2 databases]", 6, 0, DB_NAMES_1, SHARED }, + { "[hazelcast discovery, 6 core hosts, 2 databases]", 6, 0, DB_NAMES_1, HAZELCAST }, + { "[shared discovery, 5 core hosts, 1 database]", 5, 0, DB_NAMES_2, SHARED }, + { "[hazelcast discovery, 5 core hosts, 1 database]", 5, 0, DB_NAMES_2, HAZELCAST }, + { "[hazelcast discovery, 6 core hosts, 3 read replicas, 3 databases]", 9, 3, DB_NAMES_3, HAZELCAST }, + { "[shared discovery, 6 core hosts, 3 read replicas, 3 databases]", 8, 2, DB_NAMES_3, SHARED } + } + ); + } + +} diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseMultiClusteringIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseMultiClusteringIT.java new file mode 100644 index 0000000000000..a20f0b8059362 --- /dev/null +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/EnterpriseMultiClusteringIT.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.scenarios; + +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Set; +import java.util.function.Supplier; + +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; + +import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.HAZELCAST; +import static org.neo4j.causalclustering.scenarios.DiscoveryServiceType.SHARED; + +public class EnterpriseMultiClusteringIT extends BaseMultiClusteringIT +{ + public EnterpriseMultiClusteringIT( String ignoredName, int numCores, int numReplicas, Set dbNames, + Supplier discoveryServiceFactory ) + { + super( ignoredName, numCores, numReplicas, dbNames, discoveryServiceFactory ); + } + + @Parameterized.Parameters( name = "{0}" ) + public static Collection data() + { + return Arrays.asList( new Object[][] + { + { "[shared discovery, 6 core hosts, 2 databases]", 6, 0, DB_NAMES_2, SHARED }, + { "[hazelcast discovery, 6 core hosts, 2 databases]", 6, 0, DB_NAMES_2, HAZELCAST }, + { "[shared discovery, 5 core hosts, 1 database]", 5, 0, DB_NAMES_1, SHARED }, + { "[hazelcast discovery, 5 core hosts, 2 databases]", 5, 0, DB_NAMES_2, HAZELCAST }, + { "[hazelcast discovery, 9 core hosts, 3 read replicas, 3 databases]", 9, 3, DB_NAMES_3, HAZELCAST }, + { "[shared discovery, 8 core hosts, 2 read replicas, 3 databases]", 8, 2, DB_NAMES_3, SHARED } + } + ); + } +} diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/HazelcastCoreTopologyServiceIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/HazelcastCoreTopologyServiceIT.java new file mode 100644 index 0000000000000..e36b40f399bc9 --- /dev/null +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/HazelcastCoreTopologyServiceIT.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2002-2018 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j Enterprise Edition. The included source + * code can be redistributed and/or modified under the terms of the + * GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + * (http://www.fsf.org/licensing/licenses/agpl-3.0.html) with the + * Commons Clause, as found in the associated LICENSE.txt file. + * + * 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. + * + * Neo4j object code can be licensed independently from the source + * under separate terms from the AGPL. Inquiries can be directed to: + * licensing@neo4j.com + * + * More information is also available at: + * https://neo4j.com/licensing/ + */ +package org.neo4j.causalclustering.scenarios; + +public class HazelcastCoreTopologyServiceIT extends CoreTopologyServiceIT +{ + public HazelcastCoreTopologyServiceIT() + { + super( DiscoveryServiceType.HAZELCAST ); + } +} diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/InstalledProtocolsProcedureIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/InstalledProtocolsProcedureIT.java index e87af4e41f5af..c7db2d2cfe60e 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/InstalledProtocolsProcedureIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/InstalledProtocolsProcedureIT.java @@ -30,7 +30,6 @@ import java.util.List; import java.util.Objects; import java.util.StringJoiner; -import java.util.stream.Stream; import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.causalclustering.discovery.Cluster; @@ -68,7 +67,7 @@ public class InstalledProtocolsProcedureIT .withSharedCoreParam( CausalClusteringSettings.compression_implementations, "snappy" ) .withNumberOfCoreMembers( 3 ) .withNumberOfReadReplicas( 0 ); - private Cluster cluster; + private Cluster cluster; private CoreClusterMember leader; @Before diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/PreElectionIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/PreElectionIT.java index 0dfc6d5c85064..89e55a060bc83 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/PreElectionIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/PreElectionIT.java @@ -69,7 +69,7 @@ public void shouldActuallyStartAClusterWithPreVotingAndARefuseToBeLeader() throw public void shouldNotStartAnElectionIfAMinorityOfServersHaveTimedOutOnHeartbeats() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); CoreClusterMember follower = cluster.awaitCoreMemberWithRole( Role.FOLLOWER, 1, TimeUnit.MINUTES ); // when @@ -91,7 +91,7 @@ public void shouldNotStartAnElectionIfAMinorityOfServersHaveTimedOutOnHeartbeats public void shouldStartElectionIfLeaderRemoved() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); CoreClusterMember oldLeader = cluster.awaitLeader(); // when @@ -110,7 +110,7 @@ public void shouldElectANewLeaderIfAServerRefusesToBeLeader() throws Exception clusterRule .withInstanceCoreParam( CausalClusteringSettings.refuse_to_be_leader, this::firstServerRefusesToBeLeader ) .withSharedCoreParam( CausalClusteringSettings.multi_dc_license, "true" ); - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); CoreClusterMember oldLeader = cluster.awaitLeader(); // when diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaHierarchicalCatchupIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaHierarchicalCatchupIT.java index 80073239d4263..d9db7d2d0c9a4 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaHierarchicalCatchupIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaHierarchicalCatchupIT.java @@ -75,7 +75,7 @@ public void shouldCatchupThroughHierarchy() throws Throwable .withInstanceCoreParam( CausalClusteringSettings.server_groups, id -> serverGroups.get( id ) ); // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); int numberOfNodesToCreate = 100; cluster.coreTx( ( db, tx ) -> diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaReplicationIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaReplicationIT.java index 5c29f20bd7fe6..40482e86f07b0 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaReplicationIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaReplicationIT.java @@ -123,7 +123,7 @@ public class ReadReplicaReplicationIT public void shouldNotBeAbleToWriteToReadReplica() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); ReadReplicaGraphDatabase readReplica = cluster.findAnyReadReplica().database(); @@ -146,7 +146,7 @@ public void shouldNotBeAbleToWriteToReadReplica() throws Exception public void allServersBecomeAvailable() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); // then for ( final ReadReplica readReplica : cluster.readReplicas() ) @@ -160,7 +160,7 @@ public void allServersBecomeAvailable() throws Exception public void shouldEventuallyPullTransactionDownToAllReadReplicas() throws Exception { // given - Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).startCluster(); + Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).startCluster(); int nodesBeforeReadReplicaStarts = 1; cluster.coreTx( ( db, tx ) -> @@ -240,7 +240,7 @@ private static void gatherLabelScanStoreFiles( GraphDatabaseAPI db, Set la public void shouldShutdownRatherThanPullUpdatesFromCoreMemberWithDifferentStoreIdIfLocalStoreIsNonEmpty() throws Exception { - Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).startCluster(); + Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).startCluster(); cluster.coreTx( createSomeData ); @@ -275,7 +275,7 @@ public void shouldShutdownRatherThanPullUpdatesFromCoreMemberWithDifferentStoreI public void aReadReplicShouldBeAbleToRejoinTheCluster() throws Exception { int readReplicaId = 4; - Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).startCluster(); + Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).startCluster(); cluster.coreTx( createSomeData ); @@ -307,7 +307,7 @@ public void aReadReplicShouldBeAbleToRejoinTheCluster() throws Exception public void readReplicasShouldRestartIfTheWholeClusterIsRestarted() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); // when cluster.shutdown(); @@ -329,7 +329,7 @@ public void shouldBeAbleToDownloadANewStoreAfterPruning() throws Exception GraphDatabaseSettings.logical_log_rotation_threshold.name(), "1M", GraphDatabaseSettings.check_point_interval_time.name(), "100ms" ); - Cluster cluster = clusterRule.withSharedCoreParams( params ).startCluster(); + Cluster cluster = clusterRule.withSharedCoreParams( params ).startCluster(); cluster.coreTx( ( db, tx ) -> { @@ -375,7 +375,7 @@ public void shouldBeAbleToPullTxAfterHavingDownloadedANewStoreAfterPruning() thr GraphDatabaseSettings.logical_log_rotation_threshold.name(), "1M", GraphDatabaseSettings.check_point_interval_time.name(), "100ms" ); - Cluster cluster = clusterRule.withSharedCoreParams( params ).startCluster(); + Cluster cluster = clusterRule.withSharedCoreParams( params ).startCluster(); cluster.coreTx( ( db, tx ) -> { @@ -423,7 +423,7 @@ public void shouldBeAbleToPullTxAfterHavingDownloadedANewStoreAfterPruning() thr public void transactionsShouldNotAppearOnTheReadReplicaWhilePollingIsPaused() throws Throwable { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); ReadReplicaGraphDatabase readReplicaGraphDatabase = cluster.findAnyReadReplica().database(); CatchupPollingProcess pollingClient = readReplicaGraphDatabase.getDependencyResolver() @@ -509,7 +509,7 @@ private static long lastClosedTransactionId( boolean fail, GraphDatabaseFacade d public void shouldThrowExceptionIfReadReplicaRecordFormatDiffersToCoreRecordFormat() throws Exception { // given - Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).withRecordFormat( HighLimit.NAME ).startCluster(); + Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).withRecordFormat( HighLimit.NAME ).startCluster(); // when cluster.coreTx( createSomeData ); @@ -535,7 +535,7 @@ public void shouldBeAbleToCopyStoresFromCoreToReadReplica() throws Exception CausalClusteringSettings.raft_log_pruning_frequency.name(), "500ms", CausalClusteringSettings.state_machine_flush_window_size.name(), "1", CausalClusteringSettings.raft_log_pruning_strategy.name(), "1 entries" ); - Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).withSharedCoreParams( params ) + Cluster cluster = clusterRule.withNumberOfReadReplicas( 0 ).withSharedCoreParams( params ) .withRecordFormat( HighLimit.NAME ).startCluster(); cluster.coreTx( ( db, tx ) -> @@ -592,7 +592,7 @@ private static long versionBy( File raftLogDir, BinaryOperator operator ) public void pageFaultsFromReplicationMustCountInMetrics() throws Exception { // Given initial pin counts on all members - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); Function getPageCacheCounters = ccm -> ccm.database().getDependencyResolver().resolveDependency( PageCacheCounters.class ); List countersList = diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaStoreCopyIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaStoreCopyIT.java index e5cb17f545a4f..5b2ba526d1dfd 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaStoreCopyIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaStoreCopyIT.java @@ -62,7 +62,7 @@ public class ReadReplicaStoreCopyIT @Test( timeout = 240_000 ) public void shouldNotBePossibleToStartTransactionsWhenReadReplicaCopiesStore() throws Throwable { - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); ReadReplica readReplica = cluster.findAnyReadReplica(); @@ -94,7 +94,7 @@ public void shouldNotBePossibleToStartTransactionsWhenReadReplicaCopiesStore() t } } - private static void writeSomeDataAndForceLogRotations( Cluster cluster ) throws Exception + private static void writeSomeDataAndForceLogRotations( Cluster cluster ) throws Exception { for ( int i = 0; i < 20; i++ ) { @@ -108,7 +108,7 @@ private static void writeSomeDataAndForceLogRotations( Cluster cluster ) throws } } - private static void forceLogRotationOnAllCores( Cluster cluster ) + private static void forceLogRotationOnAllCores( Cluster cluster ) { for ( CoreClusterMember core : cluster.coreMembers() ) { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaToReadReplicaCatchupIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaToReadReplicaCatchupIT.java index a1995e55daa12..0a861abef8378 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaToReadReplicaCatchupIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ReadReplicaToReadReplicaCatchupIT.java @@ -67,7 +67,7 @@ public class ReadReplicaToReadReplicaCatchupIT public void shouldEventuallyPullTransactionAcrossReadReplicas() throws Throwable { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); int numberOfNodesToCreate = 100; cluster.coreTx( ( db, tx ) -> @@ -106,7 +106,7 @@ public void shouldEventuallyPullTransactionAcrossReadReplicas() throws Throwable public void shouldCatchUpFromCoresWhenPreferredReadReplicasAreUnavailable() throws Throwable { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); int numberOfNodes = 1; int firstReadReplicaLocalMemberId = 101; @@ -150,7 +150,7 @@ public void shouldCatchUpFromCoresWhenPreferredReadReplicasAreUnavailable() thro checkDataHasReplicatedToReadReplicas( cluster, numberOfNodes * 2 ); } - static void checkDataHasReplicatedToReadReplicas( Cluster cluster, long numberOfNodes ) throws Exception + static void checkDataHasReplicatedToReadReplicas( Cluster cluster, long numberOfNodes ) throws Exception { for ( final ReadReplica server : cluster.readReplicas() ) { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/RecoveryIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/RecoveryIT.java index af744a393de2e..261caefffa69b 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/RecoveryIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/RecoveryIT.java @@ -56,7 +56,7 @@ public class RecoveryIT public void shouldBeConsistentAfterShutdown() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); fireSomeLoadAtTheCluster( cluster ); @@ -77,7 +77,7 @@ public void shouldBeConsistentAfterShutdown() throws Exception public void singleServerWithinClusterShouldBeConsistentAfterRestart() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); int clusterSize = cluster.numberOfCoreMembersReportedByTopology(); fireSomeLoadAtTheCluster( cluster ); @@ -123,7 +123,7 @@ private static void assertConsistent( File storeDir ) assertTrue( result.isSuccessful() ); } - private static void fireSomeLoadAtTheCluster( Cluster cluster ) throws Exception + private static void fireSomeLoadAtTheCluster( Cluster cluster ) throws Exception { for ( int i = 0; i < cluster.numberOfCoreMembersReportedByTopology(); i++ ) { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/RestartIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/RestartIT.java index 7795ff0260bef..4ef445b7ec1f8 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/RestartIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/RestartIT.java @@ -61,7 +61,7 @@ public class RestartIT public void restartFirstServer() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); // when cluster.removeCoreMemberWithServerId( 0 ); @@ -75,7 +75,7 @@ public void restartFirstServer() throws Exception public void restartSecondServer() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); // when cluster.removeCoreMemberWithServerId( 1 ); @@ -89,7 +89,7 @@ public void restartSecondServer() throws Exception public void restartWhileDoingTransactions() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); // when final GraphDatabaseService coreDB = cluster.getCoreMemberById( 0 ).database(); @@ -128,7 +128,7 @@ public void restartWhileDoingTransactions() throws Exception public void shouldHaveWritableClusterAfterCompleteRestart() throws Exception { // given - Cluster cluster = clusterRule.startCluster(); + Cluster cluster = clusterRule.startCluster(); cluster.shutdown(); // when @@ -150,7 +150,7 @@ public void shouldHaveWritableClusterAfterCompleteRestart() throws Exception public void readReplicaTest() throws Exception { // given - Cluster cluster = clusterRule.withNumberOfCoreMembers( 2 ).withNumberOfReadReplicas( 1 ).startCluster(); + Cluster cluster = clusterRule.withNumberOfCoreMembers( 2 ).withNumberOfReadReplicas( 1 ).startCluster(); // when CoreClusterMember last = cluster.coreTx( ( db, tx ) -> diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/SampleData.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/SampleData.java index 71437ba13498a..906cd1c4da546 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/SampleData.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/SampleData.java @@ -40,7 +40,7 @@ private SampleData() { } - public static void createSomeData( int items, Cluster cluster ) throws Exception + public static void createSomeData( int items, Cluster cluster ) throws Exception { for ( int i = 0; i < items; i++ ) { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ServerGroupsIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ServerGroupsIT.java index a157b82ca5a4b..467ca2a98ec8f 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ServerGroupsIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ServerGroupsIT.java @@ -39,6 +39,7 @@ import org.neo4j.causalclustering.core.CoreGraphDatabase; import org.neo4j.causalclustering.discovery.Cluster; import org.neo4j.causalclustering.discovery.CoreClusterMember; +import org.neo4j.causalclustering.discovery.EnterpriseCluster; import org.neo4j.causalclustering.discovery.HazelcastDiscoveryServiceFactory; import org.neo4j.causalclustering.discovery.IpFamily; import org.neo4j.graphdb.Result; @@ -63,7 +64,7 @@ public class ServerGroupsIT @Rule public DefaultFileSystemRule fsRule = new DefaultFileSystemRule(); - private Cluster cluster; + private Cluster cluster; @After public void after() @@ -89,7 +90,7 @@ public void shouldUpdateGroupsOnStart() throws Exception id -> String.join( ", ", makeReplicaGroups( suffix.get(), id ) ) ); int nServers = 3; - cluster = new Cluster( testDir.directory( "cluster" ), nServers, nServers, + cluster = new EnterpriseCluster( testDir.directory( "cluster" ), nServers, nServers, new HazelcastDiscoveryServiceFactory(), emptyMap(), instanceCoreParams, emptyMap(), instanceReplicaParams, Standard.LATEST_NAME, IpFamily.IPV4, false ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ServerPoliciesLoadBalancingIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ServerPoliciesLoadBalancingIT.java index ed61c07a60f3b..fdb3df14139f7 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ServerPoliciesLoadBalancingIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/ServerPoliciesLoadBalancingIT.java @@ -41,6 +41,7 @@ import org.neo4j.causalclustering.core.CoreGraphDatabase; import org.neo4j.causalclustering.discovery.Cluster; import org.neo4j.causalclustering.discovery.CoreClusterMember; +import org.neo4j.causalclustering.discovery.EnterpriseCluster; import org.neo4j.causalclustering.discovery.HazelcastDiscoveryServiceFactory; import org.neo4j.causalclustering.discovery.IpFamily; import org.neo4j.causalclustering.routing.Endpoint; @@ -73,7 +74,7 @@ public class ServerPoliciesLoadBalancingIT @Rule public DefaultFileSystemRule fsRule = new DefaultFileSystemRule(); - private Cluster cluster; + private Cluster cluster; @After public void after() @@ -87,7 +88,7 @@ public void after() @Test public void defaultBehaviour() throws Exception { - cluster = new Cluster( testDir.directory( "cluster" ), 3, 3, new HazelcastDiscoveryServiceFactory(), emptyMap(), + cluster = new EnterpriseCluster( testDir.directory( "cluster" ), 3, 3, new HazelcastDiscoveryServiceFactory(), emptyMap(), emptyMap(), emptyMap(), emptyMap(), Standard.LATEST_NAME, IpFamily.IPV4, false ); cluster.start(); @@ -98,7 +99,7 @@ public void defaultBehaviour() throws Exception @Test public void defaultBehaviourWithAllowReadsOnFollowers() throws Exception { - cluster = new Cluster( testDir.directory( "cluster" ), 3, 3, + cluster = new EnterpriseCluster( testDir.directory( "cluster" ), 3, 3, new HazelcastDiscoveryServiceFactory(), stringMap( CausalClusteringSettings.cluster_allow_reads_on_followers.name(), "true" ), emptyMap(), emptyMap(), emptyMap(), Standard.LATEST_NAME, IpFamily.IPV4, false ); @@ -123,7 +124,7 @@ public void shouldFallOverBetweenRules() throws Exception CausalClusteringSettings.load_balancing_config.name() + ".server_policies.default", defaultPolicy, CausalClusteringSettings.multi_dc_license.name(), "true"); - cluster = new Cluster( testDir.directory( "cluster" ), 5, 5, + cluster = new EnterpriseCluster( testDir.directory( "cluster" ), 5, 5, new HazelcastDiscoveryServiceFactory(), coreParams, instanceCoreParams, emptyMap(), instanceReplicaParams, Standard.LATEST_NAME, IpFamily.IPV4, false ); @@ -176,7 +177,7 @@ public void shouldSupportSeveralPolicies() throws Exception CausalClusteringSettings.multi_dc_license.name(), "true" ); - cluster = new Cluster( testDir.directory( "cluster" ), 3, 3, + cluster = new EnterpriseCluster( testDir.directory( "cluster" ), 3, 3, new HazelcastDiscoveryServiceFactory(), coreParams, instanceCoreParams, emptyMap(), instanceReplicaParams, Standard.LATEST_NAME, IpFamily.IPV4, false ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryServiceIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/SharedDiscoveryServiceIT.java similarity index 90% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryServiceIT.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/SharedDiscoveryServiceIT.java index cb7c67be33c22..982c198d16d81 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/discovery/SharedDiscoveryServiceIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/SharedDiscoveryServiceIT.java @@ -20,7 +20,7 @@ * More information is also available at: * https://neo4j.com/licensing/ */ -package org.neo4j.causalclustering.discovery; +package org.neo4j.causalclustering.scenarios; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -37,6 +37,13 @@ import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.causalclustering.core.consensus.RaftMachine; +import org.neo4j.causalclustering.discovery.CoreTopologyService; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; +import org.neo4j.causalclustering.discovery.HostnameResolver; +import org.neo4j.causalclustering.discovery.NoOpHostnameResolver; +import org.neo4j.causalclustering.discovery.RaftCoreTopologyConnector; +import org.neo4j.causalclustering.discovery.SharedDiscoveryServiceFactory; +import org.neo4j.causalclustering.discovery.TopologyServiceNoRetriesStrategy; import org.neo4j.causalclustering.identity.MemberId; import org.neo4j.kernel.configuration.BoltConnector; import org.neo4j.kernel.configuration.Config; @@ -123,6 +130,7 @@ private Callable sharedClientStarter( CoreTopologyService topologyService, RaftMachine raftMock = mock( RaftMachine.class ); RaftCoreTopologyConnector tc = new RaftCoreTopologyConnector( topologyService, raftMock, CausalClusteringSettings.database.getDefaultValue() ); + topologyService.init(); topologyService.start(); tc.start(); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/TransactionLogRecoveryIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/TransactionLogRecoveryIT.java index 10fedaf65edba..00124b652bfb7 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/TransactionLogRecoveryIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/TransactionLogRecoveryIT.java @@ -59,7 +59,7 @@ public class TransactionLogRecoveryIT .withNumberOfCoreMembers( 3 ) .withNumberOfReadReplicas( 3 ); - private Cluster cluster; + private Cluster cluster; private FileSystemAbstraction fs = new DefaultFileSystemAbstraction(); @Before diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/UnavailableIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/UnavailableIT.java index 647dd479c5856..adb5c29d3cc96 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/UnavailableIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/UnavailableIT.java @@ -43,7 +43,7 @@ public class UnavailableIT @Rule public final ClusterRule clusterRule = new ClusterRule().withNumberOfCoreMembers( 3 ); - private Cluster cluster; + private Cluster cluster; @Before public void setup() throws Exception diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/WillNotBecomeLeaderIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/WillNotBecomeLeaderIT.java index fbfd9a846dbc9..e9fccdb3eb987 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/WillNotBecomeLeaderIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/scenarios/WillNotBecomeLeaderIT.java @@ -30,7 +30,6 @@ import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.causalclustering.discovery.Cluster; -import org.neo4j.causalclustering.discovery.HazelcastDiscoveryServiceFactory; import org.neo4j.graphdb.Node; import org.neo4j.test.causalclustering.ClusterRule; @@ -68,7 +67,7 @@ public void clusterShouldNotElectNewLeader() throws Exception } } ); - Cluster cluster = clusterRule.createCluster(); + Cluster cluster = clusterRule.createCluster(); cluster.start(); assertEquals( leaderId, cluster.awaitLeader().serverId() ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/upstream/strategies/ConnectToRandomCoreServerStrategyTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/upstream/strategies/ConnectToRandomCoreServerStrategyTest.java index adc6984b7682e..e6bfc4970c448 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/upstream/strategies/ConnectToRandomCoreServerStrategyTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/upstream/strategies/ConnectToRandomCoreServerStrategyTest.java @@ -29,24 +29,21 @@ import java.util.Optional; import java.util.UUID; -import org.neo4j.causalclustering.discovery.ClientConnectorAddresses; import org.neo4j.causalclustering.discovery.CoreServerInfo; import org.neo4j.causalclustering.discovery.CoreTopology; +import org.neo4j.causalclustering.discovery.TestTopology; import org.neo4j.causalclustering.discovery.TopologyService; import org.neo4j.causalclustering.identity.ClusterId; import org.neo4j.causalclustering.identity.MemberId; -import org.neo4j.helpers.AdvertisedSocketAddress; import org.neo4j.kernel.configuration.Config; import org.neo4j.logging.NullLogProvider; -import static java.util.Collections.singletonList; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.core.AnyOf.anyOf; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.neo4j.helpers.collection.Iterators.asSet; public class ConnectToRandomCoreServerStrategyTest { @@ -83,11 +80,7 @@ static CoreTopology fakeCoreTopology( MemberId... memberIds ) for ( MemberId memberId : memberIds ) { - coreMembers.put( memberId, - new CoreServerInfo( new AdvertisedSocketAddress( "localhost", 5000 + offset ), new AdvertisedSocketAddress( "localhost", 6000 + offset ), - new ClientConnectorAddresses( singletonList( new ClientConnectorAddresses.ConnectorUri( ClientConnectorAddresses.Scheme.bolt, - new AdvertisedSocketAddress( "localhost", 7000 + offset ) ) ) ), asSet( "core" ), "default" ) ); - + coreMembers.put( memberId, TestTopology.addressesForCore( offset, false ) ); offset++; } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/upstream/strategies/UserDefinedConfigurationStrategyTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/upstream/strategies/UserDefinedConfigurationStrategyTest.java index 8dbe36d5fdb83..01fb302eb6b77 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/upstream/strategies/UserDefinedConfigurationStrategyTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/upstream/strategies/UserDefinedConfigurationStrategyTest.java @@ -60,6 +60,7 @@ import static org.neo4j.helpers.collection.Iterators.asSet; public class UserDefinedConfigurationStrategyTest + { @Test public void shouldPickTheFirstMatchingServerIfCore() @@ -249,27 +250,23 @@ public String localDBName() } @Override - public void init() + public void init() throws Throwable { - } @Override - public void start() + public void start() throws Throwable { - } @Override - public void stop() + public void stop() throws Throwable { - } @Override - public void shutdown() + public void shutdown() throws Throwable { - } }; } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/io/pagecache/impl/muninn/VersionContextTrackingIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/io/pagecache/impl/muninn/VersionContextTrackingIT.java index f31920e2ae3e6..37fd34348bdff 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/io/pagecache/impl/muninn/VersionContextTrackingIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/io/pagecache/impl/muninn/VersionContextTrackingIT.java @@ -58,7 +58,7 @@ public class VersionContextTrackingIT @Rule public final ClusterRule clusterRule = new ClusterRule(); private static final int NUMBER_OF_TRANSACTIONS = 3; - private Cluster cluster; + private Cluster cluster; @Before public void setup() throws Exception diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/test/causalclustering/ClusterRule.java b/enterprise/causal-clustering/src/test/java/org/neo4j/test/causalclustering/ClusterRule.java index 5abdeae26dd2e..415440040c97b 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/test/causalclustering/ClusterRule.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/test/causalclustering/ClusterRule.java @@ -34,13 +34,15 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.IntFunction; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.causalclustering.discovery.Cluster; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; +import org.neo4j.causalclustering.discovery.EnterpriseCluster; import org.neo4j.causalclustering.discovery.IpFamily; import org.neo4j.causalclustering.helpers.CausalClusteringTestHelpers; -import org.neo4j.causalclustering.scenarios.DiscoveryServiceType; import org.neo4j.graphdb.config.Setting; import org.neo4j.kernel.impl.store.format.standard.Standard; import org.neo4j.test.rule.TestDirectory; @@ -58,11 +60,11 @@ public class ClusterRule extends ExternalResource { private final TestDirectory testDirectory = TestDirectory.testDirectory(); private File clusterDirectory; - private Cluster cluster; + private Cluster cluster; private int noCoreMembers = 3; private int noReadReplicas = 3; - private DiscoveryServiceType discoveryServiceType = SHARED; + private Supplier discoveryServiceFactory = SHARED; private Map coreParams = stringMap(); private Map> instanceCoreParams = new HashMap<>(); private Map readReplicaParams = stringMap(); @@ -122,7 +124,7 @@ protected void after() * Starts cluster with the configuration provided at instantiation time. This method will not return until the * cluster is up and all members report each other as available. */ - public Cluster startCluster() throws Exception + public Cluster startCluster() throws Exception { createCluster(); cluster.start(); @@ -133,11 +135,11 @@ public Cluster startCluster() throws Exception return cluster; } - public Cluster createCluster() + public Cluster createCluster() { if ( cluster == null ) { - cluster = new Cluster( clusterDirectory, noCoreMembers, noReadReplicas, discoveryServiceType.create(), coreParams, + cluster = new EnterpriseCluster( clusterDirectory, noCoreMembers, noReadReplicas, discoveryServiceFactory.get(), coreParams, instanceCoreParams, readReplicaParams, instanceReadReplicaParams, recordFormat, ipFamily, useWildcard, dbNames ); } @@ -189,9 +191,9 @@ public ClusterRule withNumberOfReadReplicas( int noReadReplicas ) return this; } - public ClusterRule withDiscoveryServiceType( DiscoveryServiceType discoveryType ) + public ClusterRule withDiscoveryServiceType( Supplier discoveryFactory ) { - this.discoveryServiceType = discoveryType; + this.discoveryServiceFactory = discoveryFactory; return this; } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/test/causalclustering/ClusterRuleIT.java b/enterprise/causal-clustering/src/test/java/org/neo4j/test/causalclustering/ClusterRuleIT.java index d358eeb7582c3..b74ff0b2df2fe 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/test/causalclustering/ClusterRuleIT.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/test/causalclustering/ClusterRuleIT.java @@ -51,7 +51,7 @@ public class ClusterRuleIT @Test public void shouldAssignPortsToMembersAutomatically() throws Exception { - Cluster cluster = clusterRule.withNumberOfCoreMembers( 3 ).withNumberOfReadReplicas( 5 ).startCluster(); + Cluster cluster = clusterRule.withNumberOfCoreMembers( 3 ).withNumberOfReadReplicas( 5 ).startCluster(); int numberOfCoreMembers = cluster.coreMembers().size(); assertThat( numberOfCoreMembers, is( 3 ) ); @@ -66,7 +66,7 @@ public void shouldAssignPortsToMembersAutomatically() throws Exception numberOfReadReplicas * NumberOfPortsUsedByReadReplica ) ); } - private Set gatherPortsUsed( Cluster cluster ) + private Set gatherPortsUsed( Cluster cluster ) { Set portsUsed = new HashSet<>(); diff --git a/enterprise/metrics/src/test/java/org/neo4j/metrics/CoreEdgeMetricsIT.java b/enterprise/metrics/src/test/java/org/neo4j/metrics/CoreEdgeMetricsIT.java index 1178de44f7502..16328151a39f7 100644 --- a/enterprise/metrics/src/test/java/org/neo4j/metrics/CoreEdgeMetricsIT.java +++ b/enterprise/metrics/src/test/java/org/neo4j/metrics/CoreEdgeMetricsIT.java @@ -27,7 +27,6 @@ import org.junit.Test; import java.io.File; -import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -75,7 +74,7 @@ public class CoreEdgeMetricsIT .withSharedCoreParam( MetricsSettings.csvInterval, "100ms" ) .withSharedReadReplicaParam( MetricsSettings.csvInterval, "100ms" ); - private Cluster cluster; + private Cluster cluster; @After public void shutdown() diff --git a/enterprise/metrics/src/test/java/org/neo4j/metrics/RaftMessageProcessingMetricIT.java b/enterprise/metrics/src/test/java/org/neo4j/metrics/RaftMessageProcessingMetricIT.java index bbcb3253b4575..de59b70d70410 100644 --- a/enterprise/metrics/src/test/java/org/neo4j/metrics/RaftMessageProcessingMetricIT.java +++ b/enterprise/metrics/src/test/java/org/neo4j/metrics/RaftMessageProcessingMetricIT.java @@ -58,7 +58,7 @@ public class RaftMessageProcessingMetricIT .withSharedCoreParam( MetricsSettings.csvEnabled, Settings.TRUE ) .withSharedCoreParam( MetricsSettings.csvInterval, "100ms" ); - private Cluster cluster; + private Cluster cluster; @After public void shutdown() diff --git a/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/CausalClusterInProcessBuilder.java b/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/CausalClusterInProcessBuilder.java index c4343204978ba..c117365650ec2 100644 --- a/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/CausalClusterInProcessBuilder.java +++ b/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/CausalClusterInProcessBuilder.java @@ -34,6 +34,7 @@ import java.util.stream.IntStream; import org.neo4j.causalclustering.core.CausalClusteringSettings; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactorySelector; import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.harness.internal.EnterpriseInProcessServerBuilder; import org.neo4j.kernel.configuration.BoltConnector; @@ -69,6 +70,7 @@ public static class Builder implements WithCores, WithReplicas, WithLogger, With private PortPickingFactory portFactory = PortPickingFactory.DEFAULT; private final Map config = new HashMap<>(); private List databases = new ArrayList<>( Collections.singletonList( "default" ) ); + private DiscoveryServiceFactorySelector.DiscoveryMiddleware discoveryServiceFactory = DiscoveryServiceFactorySelector.DEFAULT; public WithReplicas withCores( int n ) { @@ -117,6 +119,13 @@ public Builder withOptionalDatabases( List databaseNames ) return this; } + @Override + public Builder withDiscoveryServiceFactory( DiscoveryServiceFactorySelector.DiscoveryMiddleware discoveryServiceFactory ) + { + this.discoveryServiceFactory = discoveryServiceFactory; + return this; + } + public CausalCluster build() { int nDatabases = databases.size(); @@ -158,6 +167,8 @@ interface WithOptionalDatabasesAndPorts Builder withOptionalPortsStrategy( PortPickingStrategy s ); Builder withOptionalDatabases( List databaseNames ); + + Builder withDiscoveryServiceFactory( DiscoveryServiceFactorySelector.DiscoveryMiddleware discoveryServiceFactory ); } /** @@ -245,6 +256,7 @@ static class CausalCluster private final Log log; private final PortPickingFactory portFactory; private final Map config; + private final DiscoveryServiceFactorySelector.DiscoveryMiddleware discoveryServiceFactory; private List coreControls = synchronizedList( new ArrayList<>() ); private List replicaControls = synchronizedList( new ArrayList<>() ); @@ -258,6 +270,7 @@ private CausalCluster( CausalClusterInProcessBuilder.Builder builder ) this.portFactory = builder.portFactory; this.databaseNames = builder.databases; this.config = builder.config; + this.discoveryServiceFactory = builder.discoveryServiceFactory; } private Map distributeHostsBetweenDatabases( int nHosts, List databases ) @@ -303,7 +316,7 @@ void boot() throws InterruptedException int httpsPort = portFactory.httpsCorePort( coreId ); String homeDir = "core-" + coreId; - TestServerBuilder builder = new EnterpriseInProcessServerBuilder( clusterPath.toFile(), homeDir ); + EnterpriseInProcessServerBuilder builder = new EnterpriseInProcessServerBuilder( clusterPath.toFile(), homeDir ); String homePath = Paths.get( clusterPath.toString(), homeDir ).toAbsolutePath().toString(); builder.withConfig( GraphDatabaseSettings.neo4j_home.name(), homePath ); @@ -330,6 +343,8 @@ void boot() throws InterruptedException config.forEach( builder::withConfig ); + builder.withDiscoveryServiceFactory( discoveryServiceFactory ); + int finalCoreId = coreId; Thread coreThread = new Thread( () -> { @@ -355,7 +370,7 @@ void boot() throws InterruptedException int httpsPort = portFactory.httpsReadReplicaPort( replicaId ); String homeDir = "replica-" + replicaId; - TestServerBuilder builder = new EnterpriseInProcessServerBuilder( clusterPath.toFile(), homeDir ); + EnterpriseInProcessServerBuilder builder = new EnterpriseInProcessServerBuilder( clusterPath.toFile(), homeDir ); String homePath = Paths.get( clusterPath.toString(), homeDir ).toAbsolutePath().toString(); builder.withConfig( GraphDatabaseSettings.neo4j_home.name(), homePath ); @@ -374,6 +389,8 @@ void boot() throws InterruptedException builder.withConfig( OnlineBackupSettings.online_backup_enabled, Settings.FALSE ); + builder.withDiscoveryServiceFactory( discoveryServiceFactory ); + config.forEach( builder::withConfig ); int finalReplicaId = replicaId; diff --git a/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/CausalClusterInProcessRunner.java b/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/CausalClusterInProcessRunner.java index 6510720e5b0e7..d4adc22305aea 100644 --- a/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/CausalClusterInProcessRunner.java +++ b/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/CausalClusterInProcessRunner.java @@ -24,24 +24,7 @@ import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import org.neo4j.causalclustering.core.CausalClusteringSettings; -import org.neo4j.graphdb.factory.GraphDatabaseSettings; -import org.neo4j.harness.internal.EnterpriseInProcessServerBuilder; -import org.neo4j.kernel.configuration.BoltConnector; -import org.neo4j.kernel.configuration.HttpConnector; -import org.neo4j.kernel.configuration.Settings; -import org.neo4j.kernel.impl.enterprise.configuration.EnterpriseEditionSettings; -import org.neo4j.kernel.impl.enterprise.configuration.OnlineBackupSettings; -import org.neo4j.logging.Log; -import org.neo4j.logging.LogProvider; -import org.neo4j.server.configuration.ServerSettings; - -import static java.util.Collections.synchronizedList; import static org.neo4j.logging.FormattedLogProvider.toOutputStream; /** diff --git a/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/ClusterOfClustersInProcessRunner.java b/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/ClusterOfClustersInProcessRunner.java index e97033a5b65da..8470483357d4a 100644 --- a/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/ClusterOfClustersInProcessRunner.java +++ b/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/ClusterOfClustersInProcessRunner.java @@ -40,11 +40,11 @@ public static void main( String[] args ) CausalClusterInProcessBuilder.CausalCluster cluster = CausalClusterInProcessBuilder.init() - .withCores( 6 ) - .withReplicas( 4 ) + .withCores( 9 ) + .withReplicas( 6 ) .withLogger( toOutputStream( System.out ) ) .atPath( clusterPath ) - .withOptionalDatabases( Arrays.asList("foo", "bar") ) + .withOptionalDatabases( Arrays.asList("foo", "bar", "baz") ) .build(); System.out.println( "Waiting for cluster to boot up..." ); diff --git a/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/internal/EnterpriseInProcessServerBuilder.java b/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/internal/EnterpriseInProcessServerBuilder.java index e6aee337bd988..6998fb833716b 100644 --- a/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/internal/EnterpriseInProcessServerBuilder.java +++ b/enterprise/neo4j-harness-enterprise/src/main/java/org/neo4j/harness/internal/EnterpriseInProcessServerBuilder.java @@ -25,6 +25,8 @@ import java.io.File; import java.util.Map; +import org.neo4j.causalclustering.core.CausalClusteringSettings; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactorySelector; import org.neo4j.graphdb.facade.GraphDatabaseFacadeFactory; import org.neo4j.kernel.configuration.Config; import org.neo4j.logging.FormattedLogProvider; @@ -33,6 +35,8 @@ public class EnterpriseInProcessServerBuilder extends AbstractInProcessServerBuilder { + private DiscoveryServiceFactorySelector.DiscoveryMiddleware discoveryServiceFactory = DiscoveryServiceFactorySelector.DEFAULT; + public EnterpriseInProcessServerBuilder() { this( new File( System.getProperty( "java.io.tmpdir" ) ) ); @@ -49,9 +53,26 @@ public EnterpriseInProcessServerBuilder( File workingDir, String dataSubDir ) } @Override - protected AbstractNeoServer createNeoServer( Map config, + protected AbstractNeoServer createNeoServer( Map configMap, GraphDatabaseFacadeFactory.Dependencies dependencies, FormattedLogProvider userLogProvider ) { - return new OpenEnterpriseNeoServer( Config.defaults( config ), dependencies, userLogProvider ); + Config config = Config.defaults( configMap ); + config.augment( CausalClusteringSettings.middleware_type, discoveryServiceFactory.name() ); + return new OpenEnterpriseNeoServer( config, dependencies, userLogProvider ); } + + /** + * Configure the server to use the specified service to build cluster topologies and share associated metadata. + * + * Only relevant for causal clustering. + * + * @param discoveryService + * @return this builder instance + */ + public EnterpriseInProcessServerBuilder withDiscoveryServiceFactory( DiscoveryServiceFactorySelector.DiscoveryMiddleware discoveryService ) + { + this.discoveryServiceFactory = discoveryService; + return this; + } + } diff --git a/enterprise/server-enterprise/src/main/java/org/neo4j/server/enterprise/OpenEnterpriseNeoServer.java b/enterprise/server-enterprise/src/main/java/org/neo4j/server/enterprise/OpenEnterpriseNeoServer.java index 87c54af2d87a8..bbc49713d95db 100644 --- a/enterprise/server-enterprise/src/main/java/org/neo4j/server/enterprise/OpenEnterpriseNeoServer.java +++ b/enterprise/server-enterprise/src/main/java/org/neo4j/server/enterprise/OpenEnterpriseNeoServer.java @@ -33,6 +33,8 @@ import org.neo4j.causalclustering.core.CausalClusteringSettings; import org.neo4j.causalclustering.core.CoreGraphDatabase; +import org.neo4j.causalclustering.discovery.DiscoveryServiceFactory; +import org.neo4j.causalclustering.discovery.EnterpriseDiscoveryServiceFactorySelector; import org.neo4j.causalclustering.readreplica.ReadReplicaGraphDatabase; import org.neo4j.graphdb.facade.GraphDatabaseFacadeFactory; import org.neo4j.graphdb.facade.GraphDatabaseFacadeFactory.Dependencies; @@ -83,17 +85,23 @@ public class OpenEnterpriseNeoServer extends CommunityNeoServer return new EnterpriseGraphDatabase( storeDir, config, dependencies ); }; - private static final GraphFactory CORE_FACTORY = ( config, dependencies ) -> + private static GraphFactory coreFactory( DiscoveryServiceFactory discoveryServiceFactory ) { - File storeDir = config.get( GraphDatabaseSettings.databases_root_path ); - return new CoreGraphDatabase( storeDir, config, dependencies ); - }; + return ( config, dependencies ) -> + { + File storeDir = config.get( GraphDatabaseSettings.databases_root_path ); + return new CoreGraphDatabase( storeDir, config, dependencies, discoveryServiceFactory ); + }; + } - private static final GraphFactory READ_REPLICA_FACTORY = ( config, dependencies ) -> + private static GraphFactory readReplicaFactory( DiscoveryServiceFactory discoveryServiceFactory ) { - File storeDir = config.get( GraphDatabaseSettings.databases_root_path ); - return new ReadReplicaGraphDatabase( storeDir, config, dependencies ); - }; + return ( config, dependencies ) -> + { + File storeDir = config.get( GraphDatabaseSettings.databases_root_path ); + return new ReadReplicaGraphDatabase( storeDir, config, dependencies, discoveryServiceFactory ); + }; + } public OpenEnterpriseNeoServer( Config config, Dependencies dependencies, LogProvider logProvider ) { @@ -110,6 +118,8 @@ protected static Database.Factory createDbFactory( Config config ) { final Mode mode = config.get( EnterpriseEditionSettings.mode ); + final DiscoveryServiceFactory discoveryServiceFactory = new EnterpriseDiscoveryServiceFactorySelector().select( config ); + switch ( mode ) { case HA: @@ -118,9 +128,9 @@ protected static Database.Factory createDbFactory( Config config ) // Should never reach here because this mode is handled separately by the scripts. throw new IllegalArgumentException( "The server cannot be started in ARBITER mode." ); case CORE: - return lifecycleManagingDatabase( CORE_FACTORY ); + return lifecycleManagingDatabase( coreFactory( discoveryServiceFactory ) ); case READ_REPLICA: - return lifecycleManagingDatabase( READ_REPLICA_FACTORY ); + return lifecycleManagingDatabase( readReplicaFactory( discoveryServiceFactory ) ); default: return lifecycleManagingDatabase( ENTERPRISE_FACTORY ); } diff --git a/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/OpenEnterpriseNeoServerTest.java b/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/OpenEnterpriseNeoServerTest.java index 5f3db2449e35d..0852496e60c94 100644 --- a/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/OpenEnterpriseNeoServerTest.java +++ b/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/OpenEnterpriseNeoServerTest.java @@ -53,7 +53,9 @@ void checkExpectedDatabaseDirectory() Config config = Config.builder().withServerDefaults().withSetting( mode, Mode.SINGLE.name() ) .withSetting( GraphDatabaseSettings.neo4j_home, testDirectory.storeDir().getAbsolutePath() ).build(); GraphDatabaseDependencies dependencies = GraphDatabaseDependencies.newDependencies().userLogProvider( NullLogProvider.getInstance() ); - OpenEnterpriseNeoServer server = new OpenEnterpriseNeoServer( config, dependencies, NullLogProvider.getInstance() ); + OpenEnterpriseNeoServer server = + new OpenEnterpriseNeoServer( config, dependencies, NullLogProvider.getInstance() ); + server.start(); try { diff --git a/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/helpers/EnterpriseServerBuilder.java b/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/helpers/EnterpriseServerBuilder.java index a6ff079d83ad6..f9181a7c8dfa5 100644 --- a/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/helpers/EnterpriseServerBuilder.java +++ b/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/helpers/EnterpriseServerBuilder.java @@ -92,8 +92,7 @@ private class TestEnterpriseNeoServer extends OpenEnterpriseNeoServer { private final File configFile; - TestEnterpriseNeoServer( Config config, File configFile, - GraphDatabaseFacadeFactory.Dependencies dependencies, LogProvider logProvider ) + TestEnterpriseNeoServer( Config config, File configFile, GraphDatabaseFacadeFactory.Dependencies dependencies, LogProvider logProvider ) { super( config, dependencies, logProvider ); this.configFile = configFile; diff --git a/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/jmx/ServerManagementIT.java b/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/jmx/ServerManagementIT.java index dcf8624324c8d..5eecacb414019 100644 --- a/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/jmx/ServerManagementIT.java +++ b/enterprise/server-enterprise/src/test/java/org/neo4j/server/enterprise/jmx/ServerManagementIT.java @@ -42,7 +42,6 @@ public class ServerManagementIT { - private final CleanupRule cleanup = new CleanupRule(); private final TestDirectory baseDir = TestDirectory.testDirectory(); private final SuppressOutput suppressOutput = SuppressOutput.suppressAll(); @@ -67,8 +66,7 @@ public void shouldBeAbleToRestartServer() throws Exception .build(); // When - NeoServer server = cleanup.add( new OpenEnterpriseNeoServer( config, graphDbDependencies(), NullLogProvider - .getInstance() ) ); + NeoServer server = cleanup.add( new OpenEnterpriseNeoServer( config, graphDbDependencies(), NullLogProvider.getInstance() ) ); server.start(); assertNotNull( server.getDatabase().getGraph() ); diff --git a/integrationtests/src/test/java/org/neo4j/causalclustering/scenarios/BoltCausalClusteringIT.java b/integrationtests/src/test/java/org/neo4j/causalclustering/scenarios/BoltCausalClusteringIT.java index c084c6786af58..b798484ab66f4 100644 --- a/integrationtests/src/test/java/org/neo4j/causalclustering/scenarios/BoltCausalClusteringIT.java +++ b/integrationtests/src/test/java/org/neo4j/causalclustering/scenarios/BoltCausalClusteringIT.java @@ -84,7 +84,7 @@ public class BoltCausalClusteringIT @Rule public final SuppressOutput suppressOutput = SuppressOutput.suppressAll(); - private Cluster cluster; + private Cluster cluster; @Test public void shouldExecuteReadAndWritesWhenDriverSuppliedWithAddressOfLeader() throws Exception @@ -224,7 +224,7 @@ public void shouldBeAbleToGetClusterOverview() throws Exception */ private class LeaderSwitcher implements Runnable { - private final Cluster cluster; + private final Cluster cluster; private final CountDownLatch switchCompleteLatch; private CoreClusterMember initialLeader; private CoreClusterMember currentLeader; @@ -233,7 +233,7 @@ private class LeaderSwitcher implements Runnable private boolean stopped; private Throwable throwable; - LeaderSwitcher( Cluster cluster, CountDownLatch switchCompleteLatch ) + LeaderSwitcher( Cluster cluster, CountDownLatch switchCompleteLatch ) { this.cluster = cluster; this.switchCompleteLatch = switchCompleteLatch; @@ -686,7 +686,7 @@ public void transactionsShouldNotAppearOnTheReadReplicaWhilePollingIsPaused() th GraphDatabaseSettings.check_point_interval_time.name(), "100ms", CausalClusteringSettings.cluster_allow_reads_on_followers.name(), "false"); - Cluster cluster = clusterRule.withSharedCoreParams( params ).withNumberOfReadReplicas( 1 ).startCluster(); + Cluster cluster = clusterRule.withSharedCoreParams( params ).withNumberOfReadReplicas( 1 ).startCluster(); Driver driver = GraphDatabase.driver( cluster.awaitLeader().routingURI(), AuthTokens.basic( "neo4j", "neo4j" ) ); diff --git a/integrationtests/src/test/java/org/neo4j/causalclustering/scenarios/ConvertNonCausalClusteringStoreIT.java b/integrationtests/src/test/java/org/neo4j/causalclustering/scenarios/ConvertNonCausalClusteringStoreIT.java index ad78528390a44..27262391f0d0b 100644 --- a/integrationtests/src/test/java/org/neo4j/causalclustering/scenarios/ConvertNonCausalClusteringStoreIT.java +++ b/integrationtests/src/test/java/org/neo4j/causalclustering/scenarios/ConvertNonCausalClusteringStoreIT.java @@ -82,7 +82,7 @@ public void shouldReplicateTransactionToCoreMembers() throws Throwable int classicNodeCount = 1024; File classicNeo4jStore = createNeoStore( dbDir, classicNodeCount ); - Cluster cluster = this.clusterRule.withRecordFormat( recordFormat ).createCluster(); + Cluster cluster = this.clusterRule.withRecordFormat( recordFormat ).createCluster(); try ( DefaultFileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction() ) { diff --git a/integrationtests/src/test/java/org/neo4j/kernel/PageCacheWarmupCcIT.java b/integrationtests/src/test/java/org/neo4j/kernel/PageCacheWarmupCcIT.java index ed9ef4bdaa049..1ded74cbaafa5 100644 --- a/integrationtests/src/test/java/org/neo4j/kernel/PageCacheWarmupCcIT.java +++ b/integrationtests/src/test/java/org/neo4j/kernel/PageCacheWarmupCcIT.java @@ -61,7 +61,7 @@ public class PageCacheWarmupCcIT extends PageCacheWarmupTestSupport .withSharedReadReplicaParam( CausalClusteringSettings.pull_interval, "100ms" ) .withSharedReadReplicaParam( CausalClusteringSettings.upstream_selection_strategy, LeaderOnlyStrategy.IDENTITY ); - private Cluster cluster; + private Cluster cluster; private CoreClusterMember leader; @Before diff --git a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CatchupNewReadReplica.java b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CatchupNewReadReplica.java index 9b7bd67a16b9c..7d88f75baffaf 100644 --- a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CatchupNewReadReplica.java +++ b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CatchupNewReadReplica.java @@ -50,7 +50,7 @@ class CatchupNewReadReplica extends Workload { private final Predicate isStoreClosed = new IsStoreClosed(); private final FileSystemAbstraction fs; - private Cluster cluster; + private Cluster cluster; private boolean deleteStore; CatchupNewReadReplica( Control control, Resources resources ) diff --git a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/ConsistencyCheck.java b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/ConsistencyCheck.java index d346a04a2e0b7..c7f88604ecced 100644 --- a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/ConsistencyCheck.java +++ b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/ConsistencyCheck.java @@ -34,7 +34,7 @@ */ public class ConsistencyCheck extends Validation { - private final Cluster cluster; + private final Cluster cluster; ConsistencyCheck( Resources resources ) { diff --git a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CreateNodesWithProperties.java b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CreateNodesWithProperties.java index 01432e94aaffb..80143f6be670e 100644 --- a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CreateNodesWithProperties.java +++ b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CreateNodesWithProperties.java @@ -39,7 +39,7 @@ class CreateNodesWithProperties extends Workload { private static final Label label = Label.label( "Label" ); - private final Cluster cluster; + private final Cluster cluster; private final CappedLogger txLogger; private final boolean enableIndexes; @@ -98,7 +98,7 @@ protected void doWork() txSuccessCount++; } - private static void setupIndexes( Cluster cluster ) + private static void setupIndexes( Cluster cluster ) { try { diff --git a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/IdReuse.java b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/IdReuse.java index 98fbdfbfbb83c..39bd098b66008 100644 --- a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/IdReuse.java +++ b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/IdReuse.java @@ -60,7 +60,7 @@ class IdReuse */ static class UniqueFreeIds extends Validation { - private final Cluster cluster; + private final Cluster cluster; private final FileSystemAbstraction fs; private final Log log; @@ -130,7 +130,7 @@ void visitAllIds( ClusterMember member, Consumer idConsumer ) static class IdReuseSetup extends Preparation { - private final Cluster cluster; + private final Cluster cluster; IdReuseSetup( Resources resources ) { @@ -165,7 +165,7 @@ protected void prepare() throws Exception static class InsertionWorkload extends Workload { - private Cluster cluster; + private Cluster cluster; InsertionWorkload( Control control, Resources resources ) { @@ -202,7 +202,7 @@ static class ReelectionWorkload extends Workload { private final long reelectIntervalSeconds; private final Log log; - private Cluster cluster; + private Cluster cluster; ReelectionWorkload( Control control, Resources resources, Config config ) { @@ -240,7 +240,7 @@ static class DeletionWorkload extends Workload { private final SecureRandom rnd = new SecureRandom(); private final int idHighRange; - private Cluster cluster; + private Cluster cluster; DeletionWorkload( Control control, Resources resources ) { diff --git a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/RepeatOnRandomCore.java b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/RepeatOnRandomCore.java index a61a8f5e014b2..e8e6c6a81997e 100644 --- a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/RepeatOnRandomCore.java +++ b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/RepeatOnRandomCore.java @@ -28,7 +28,7 @@ abstract class RepeatOnRandomCore extends Workload { - private final Cluster cluster; + private final Cluster cluster; RepeatOnRandomCore( Control control, Resources resources ) { diff --git a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/RepeatOnRandomMember.java b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/RepeatOnRandomMember.java index 1dcb425734133..bddd1f89ccf7d 100644 --- a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/RepeatOnRandomMember.java +++ b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/RepeatOnRandomMember.java @@ -28,7 +28,7 @@ abstract class RepeatOnRandomMember extends Workload { - private final Cluster cluster; + private final Cluster cluster; RepeatOnRandomMember( Control control, Resources resources ) { diff --git a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/ReplaceRandomMember.java b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/ReplaceRandomMember.java index 03c12ded7fe80..0c1052c05a00c 100644 --- a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/ReplaceRandomMember.java +++ b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/ReplaceRandomMember.java @@ -54,7 +54,7 @@ class ReplaceRandomMember extends RepeatOnRandomMember private static final long MAX_BACKUP_FAILURES = 5; private static final long RETRY_TIMEOUT_MILLIS = 5000; - private final Cluster cluster; + private final Cluster cluster; private final File baseBackupDir; private final FileSystemAbstraction fs; private final Log log; diff --git a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/Resources.java b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/Resources.java index 030c663d3fac2..18fe0ef9525d3 100644 --- a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/Resources.java +++ b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/Resources.java @@ -29,6 +29,7 @@ import java.util.Map; import org.neo4j.causalclustering.discovery.Cluster; +import org.neo4j.causalclustering.discovery.EnterpriseCluster; import org.neo4j.causalclustering.discovery.HazelcastDiscoveryServiceFactory; import org.neo4j.causalclustering.discovery.IpFamily; import org.neo4j.io.fs.FileSystemAbstraction; @@ -46,7 +47,7 @@ class Resources { - private final Cluster cluster; + private final Cluster cluster; private final File clusterDir; private final File backupDir; private final FileSystemAbstraction fileSystem; @@ -77,11 +78,11 @@ private Resources( FileSystemAbstraction fileSystem, PageCache pageCache, LogPro Map readReplicaParams = configureTxLogRotationAndPruning( new HashMap<>(), txPrune ); HazelcastDiscoveryServiceFactory discoveryServiceFactory = new HazelcastDiscoveryServiceFactory(); - cluster = new Cluster( clusterDir, numberOfCores, numberOfEdges, discoveryServiceFactory, coreParams, emptyMap(), readReplicaParams, emptyMap(), - Standard.LATEST_NAME, IpFamily.IPV4, false ); + cluster = new EnterpriseCluster( clusterDir, numberOfCores, numberOfEdges, discoveryServiceFactory, coreParams, emptyMap(), readReplicaParams, + emptyMap(), Standard.LATEST_NAME, IpFamily.IPV4, false ); } - public Cluster cluster() + public Cluster cluster() { return cluster; }