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 3e477b8e6aedd..55057c221203c 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 @@ -314,16 +314,21 @@ public class CausalClusteringSettings implements LoadableConfig public static final Setting> upstream_selection_strategy = setting( "causal_clustering.upstream_selection_strategy", list( ",", STRING ), "default" ); - @Description( "The load balancing plugin to use. This must be the same for all core servers participating in the cluster." ) + @Description( "Tags for the server used when configuring load balancing and replication policies." ) + public static Setting> server_tags = + setting( "causal_clustering.server_tags", list( ",", STRING ), "" ); + + @Description( "The load balancing plugin to use." ) public static Setting load_balancing_plugin = setting( "causal_clustering.load_balancing.plugin", STRING, "server_policies" ); - @Description( "The configuration must be valid for the configured plugin." ) + @Description( "The configuration must be valid for the configured plugin and usually exists" + + "under matching subkeys, e.g. ..config.server_policies.*" + + "This is just a top-level placeholder for the plugin-specific configuration." ) public static Setting load_balancing_config = setting( "causal_clustering.load_balancing.config", STRING, "" ); - @Description( "Tags for the server used when configuring load balancing and replication policies." + - " Multiple tags can be configured by separating with a comma." ) - public static Setting> server_tags = - setting( "causal_clustering.server_tags", list( ",", STRING ), "" ); + @Description( "Enables shuffling of the returned load balancing result." ) + public static final Setting load_balancing_shuffle = + setting( "causal_clustering.load_balancing.shuffle", BOOLEAN, "true" ); } 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 eb8c78d097ae9..32ae81c7889b3 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 @@ -42,11 +42,12 @@ import org.neo4j.causalclustering.discovery.procedures.ClusterOverviewProcedure; import org.neo4j.causalclustering.discovery.procedures.CoreRoleProcedure; import org.neo4j.causalclustering.identity.MemberId; -import org.neo4j.causalclustering.load_balancing.LoadBalancingStrategy; +import org.neo4j.causalclustering.load_balancing.LoadBalancingPlugin; +import org.neo4j.causalclustering.load_balancing.plugins.ServerShufflingPlugin; +import org.neo4j.causalclustering.load_balancing.plugins.server_policies.InvalidFilterSpecification; +import org.neo4j.causalclustering.load_balancing.plugins.server_policies.ServerPoliciesPlugin; import org.neo4j.causalclustering.load_balancing.procedure.GetServersProcedureV1; import org.neo4j.causalclustering.load_balancing.procedure.GetServersProcedureV2; -import org.neo4j.causalclustering.load_balancing.strategy.AllServersStrategy; -import org.neo4j.causalclustering.load_balancing.strategy.ServerShufflingStrategy; import org.neo4j.causalclustering.logging.BetterMessageLogger; import org.neo4j.causalclustering.logging.MessageLogger; import org.neo4j.causalclustering.logging.NullMessageLogger; @@ -110,17 +111,35 @@ public enum RaftLogImplementation IN_MEMORY, SEGMENTED } + private LoadBalancingPlugin getLoadBalancingPlugin() + { + LoadBalancingPlugin plugin; + + try + { + // TODO: Select using services framework and plugin configuration. + plugin = new ServerPoliciesPlugin( topologyService, consensusModule.raftMachine(), logProvider, config ); + } + catch ( InvalidFilterSpecification e ) + { + throw new RuntimeException( e ); + } + + if ( config.get( CausalClusteringSettings.load_balancing_shuffle ) ) + { + plugin = new ServerShufflingPlugin( plugin ); + } + return plugin; + } + @Override public void registerEditionSpecificProcedures( Procedures procedures ) throws KernelException { - LoadBalancingStrategy loadBalancingStrategy = new ServerShufflingStrategy( - new AllServersStrategy( topologyService, consensusModule.raftMachine(), config ) ); - procedures.registerProcedure( EnterpriseBuiltInDbmsProcedures.class, true ); procedures.register( new GetServersProcedureV1( topologyService, consensusModule.raftMachine(), config, logProvider ) ); procedures.register( - new GetServersProcedureV2( loadBalancingStrategy ) ); + new GetServersProcedureV2( getLoadBalancingPlugin() ) ); procedures.register( new ClusterOverviewProcedure( topologyService, consensusModule.raftMachine(), logProvider ) ); procedures.register( new CoreRoleProcedure( consensusModule.raftMachine() ) ); diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingStrategy.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingPlugin.java similarity index 97% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingStrategy.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingPlugin.java index 6be0722a48bb1..9bbd508a85cdd 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingStrategy.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingPlugin.java @@ -26,7 +26,7 @@ * Defines the interface for an implementation of the GetServersV2 * cluster discovery and load balancing procedure. */ -public interface LoadBalancingStrategy +public interface LoadBalancingPlugin { interface Result { diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingResult.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingResult.java index 44a0e3f78d55f..dbf88257c80a8 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingResult.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/LoadBalancingResult.java @@ -23,10 +23,10 @@ import java.util.Objects; /** - * The outcome of applying a load balancing strategy, which will be used by client + * The outcome of applying a load balancing plugin, which will be used by client * software for scheduling work at the endpoints. */ -public class LoadBalancingResult implements LoadBalancingStrategy.Result +public class LoadBalancingResult implements LoadBalancingPlugin.Result { private final List routeEndpoints; private final List writeEndpoints; diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/AllServersStrategy.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/AllServersPlugin.java similarity index 89% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/AllServersStrategy.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/AllServersPlugin.java index 747d03ead0394..fe8c78747953c 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/AllServersStrategy.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/AllServersPlugin.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy; +package org.neo4j.causalclustering.load_balancing.plugins; import java.util.List; import java.util.Map; @@ -33,7 +33,7 @@ import org.neo4j.causalclustering.identity.MemberId; import org.neo4j.causalclustering.load_balancing.Endpoint; import org.neo4j.causalclustering.load_balancing.LoadBalancingResult; -import org.neo4j.causalclustering.load_balancing.LoadBalancingStrategy; +import org.neo4j.causalclustering.load_balancing.LoadBalancingPlugin; import org.neo4j.kernel.configuration.Config; import static java.util.Collections.emptyList; @@ -42,15 +42,15 @@ import static org.neo4j.causalclustering.load_balancing.Util.asList; /** - * This is just a simple strategy and not intended for actual use. Will be replaced. + * This is just a simple plugin and not intended for actual use. Will be replaced. */ -public class AllServersStrategy implements LoadBalancingStrategy +public class AllServersPlugin implements LoadBalancingPlugin { private final CoreTopologyService topologyService; private final LeaderLocator leaderLocator; private final Long timeToLive; - public AllServersStrategy( CoreTopologyService topologyService, LeaderLocator leaderLocator, Config config ) + public AllServersPlugin( CoreTopologyService topologyService, LeaderLocator leaderLocator, Config config ) { this.topologyService = topologyService; this.leaderLocator = leaderLocator; diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/ServerShufflingStrategy.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/ServerShufflingPlugin.java similarity index 81% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/ServerShufflingStrategy.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/ServerShufflingPlugin.java index dee9dfacfafb6..5c3bc70327c88 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/ServerShufflingStrategy.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/ServerShufflingPlugin.java @@ -17,12 +17,12 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy; +package org.neo4j.causalclustering.load_balancing.plugins; import java.util.Collections; import java.util.Map; -import org.neo4j.causalclustering.load_balancing.LoadBalancingStrategy; +import org.neo4j.causalclustering.load_balancing.LoadBalancingPlugin; /** * Shuffles the servers of the delegate around so that every client @@ -30,11 +30,11 @@ * * N.B: Lists are shuffled in place. */ -public class ServerShufflingStrategy implements LoadBalancingStrategy +public class ServerShufflingPlugin implements LoadBalancingPlugin { - private final LoadBalancingStrategy delegate; + private final LoadBalancingPlugin delegate; - public ServerShufflingStrategy( LoadBalancingStrategy delegate ) + public ServerShufflingPlugin( LoadBalancingPlugin delegate ) { this.delegate = delegate; } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/AnyTagFilter.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/AnyTagFilter.java similarity index 96% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/AnyTagFilter.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/AnyTagFilter.java index af9aaa2b0d0be..24f09aaf7def3 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/AnyTagFilter.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/AnyTagFilter.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import java.util.Objects; import java.util.Set; diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilterConfigParser.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilterConfigParser.java similarity index 98% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilterConfigParser.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilterConfigParser.java index ccf5580771386..1e4c825d44d71 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilterConfigParser.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilterConfigParser.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import java.util.ArrayList; import java.util.Arrays; diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilteringPolicy.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilteringPolicy.java similarity index 95% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilteringPolicy.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilteringPolicy.java index eceaa02e63667..20dde34fabf24 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilteringPolicy.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilteringPolicy.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import java.util.Objects; import java.util.Set; diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilteringPolicyLoader.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilteringPolicyLoader.java similarity index 80% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilteringPolicyLoader.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilteringPolicyLoader.java index 8e10869315d39..7d040af41c66c 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilteringPolicyLoader.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilteringPolicyLoader.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import java.util.Map; import java.util.Set; @@ -31,15 +31,15 @@ import static org.neo4j.causalclustering.core.CausalClusteringSettings.load_balancing_config; /** - * Loads filters under the name space of [...]config.strategy.policy_name + * Loads filters under the name space of a particular plugin. */ class FilteringPolicyLoader { - static Policies load( Config config, String strategyName, LogProvider logProvider ) throws InvalidFilterSpecification + static Policies load( Config config, String pluginName, LogProvider logProvider ) throws InvalidFilterSpecification { Policies policies = new Policies( logProvider ); - String prefix = policyPrefix( strategyName ); + String prefix = policyPrefix( pluginName ); Map rawConfig = config.getRaw(); Set configKeys = rawConfig.keySet().stream() @@ -58,8 +58,8 @@ static Policies load( Config config, String strategyName, LogProvider logProvide return policies; } - private static String policyPrefix( String strategyName ) + private static String policyPrefix( String pluginName ) { - return format( "%s.%s.", load_balancing_config.name(), strategyName ); + return format( "%s.%s.", load_balancing_config.name(), pluginName ); } } diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/InvalidFilterSpecification.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/InvalidFilterSpecification.java similarity index 88% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/InvalidFilterSpecification.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/InvalidFilterSpecification.java index f8a07d853adb6..139c221998dff 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/InvalidFilterSpecification.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/InvalidFilterSpecification.java @@ -17,9 +17,9 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; -class InvalidFilterSpecification extends Exception +public class InvalidFilterSpecification extends Exception { InvalidFilterSpecification( String message ) { diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/Policies.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/Policies.java similarity index 80% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/Policies.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/Policies.java index 5e5451fd15e51..0dbaabdd79d99 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/Policies.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/Policies.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import java.util.HashMap; import java.util.Map; @@ -31,9 +31,11 @@ class Policies { static final String POLICY_KEY = "load_balancing.policy"; // TODO: move somewhere (driver support package?) + static final String DEFAULT_POLICY_NAME = "default"; + static final Policy DEFAULT_POLICY = new FilteringPolicy( IdentityFilter.as() ); private final Map policies = new HashMap<>(); - private final Policy DEFAULT_POLICY = new FilteringPolicy( IdentityFilter.as() ); + private final Log log; Policies( LogProvider logProvider ) @@ -53,15 +55,13 @@ void addPolicy( String policyName, Policy policy ) Policy selectFor( Map context ) { String policyName = context.get( POLICY_KEY ); + policyName = (policyName != null) ? policyName : DEFAULT_POLICY_NAME; + Policy selectedPolicy = policies.get( policyName ); - if ( policyName == null ) - { - return DEFAULT_POLICY; - } - else if ( selectedPolicy == null ) + if ( selectedPolicy == null ) { - log.warn( format( "Policy '%s' could not be found. Will use default instead.", policyName ) ); + log.warn( format( "Policy definition for '%s' could not be found. Will use built-in default instead.", policyName ) ); return DEFAULT_POLICY; } else diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/Policy.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/Policy.java similarity index 92% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/Policy.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/Policy.java index a232ecc4b056f..d2fb01fb09b07 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/Policy.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/Policy.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import java.util.Set; diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/ServerInfo.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/ServerInfo.java similarity index 96% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/ServerInfo.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/ServerInfo.java index 05740cdc3380c..c34d1ee4149ab 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/ServerInfo.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/ServerInfo.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import java.util.Objects; import java.util.Set; diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/ServerPolicyStrategy.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/ServerPoliciesPlugin.java similarity index 88% rename from enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/ServerPolicyStrategy.java rename to enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/ServerPoliciesPlugin.java index 84dc800b77886..83fa14d13917f 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/ServerPolicyStrategy.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/ServerPoliciesPlugin.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import java.util.List; import java.util.Map; @@ -33,24 +33,25 @@ import org.neo4j.causalclustering.discovery.TopologyService; import org.neo4j.causalclustering.identity.MemberId; import org.neo4j.causalclustering.load_balancing.Endpoint; +import org.neo4j.causalclustering.load_balancing.LoadBalancingPlugin; import org.neo4j.causalclustering.load_balancing.LoadBalancingResult; -import org.neo4j.causalclustering.load_balancing.LoadBalancingStrategy; import org.neo4j.kernel.configuration.Config; import org.neo4j.logging.LogProvider; import static java.util.Collections.emptyList; import static org.neo4j.causalclustering.load_balancing.Util.asList; import static org.neo4j.causalclustering.load_balancing.Util.extractBoltAddress; +import static org.neo4j.causalclustering.load_balancing.plugins.server_policies.FilteringPolicyLoader.load; /** - * The server policy strategy defines policies on the server-side which + * The server policies plugin defines policies on the server-side which * can be bound to by a client by supplying a appropriately formed context. * - * An example would be to define a policy for a particular region. + * An example would be to define different policies for different regions. */ -public class ServerPolicyStrategy implements LoadBalancingStrategy +public class ServerPoliciesPlugin implements LoadBalancingPlugin { - private static final String STRATEGY_NAME = "server_policy"; + private static final String PLUGIN_NAME = "server_policies"; private final TopologyService topologyService; private final LeaderLocator leaderLocator; @@ -58,14 +59,14 @@ public class ServerPolicyStrategy implements LoadBalancingStrategy private final boolean allowReadsOnFollowers; private final Policies policies; - public ServerPolicyStrategy( TopologyService topologyService, LeaderLocator leaderLocator, + public ServerPoliciesPlugin( TopologyService topologyService, LeaderLocator leaderLocator, LogProvider logProvider, Config config ) throws InvalidFilterSpecification { this.topologyService = topologyService; this.leaderLocator = leaderLocator; this.timeToLive = config.get( CausalClusteringSettings.cluster_routing_ttl ); this.allowReadsOnFollowers = config.get( CausalClusteringSettings.cluster_allow_reads_on_followers ); - this.policies = FilteringPolicyLoader.load( config, STRATEGY_NAME, logProvider ); + this.policies = load( config, PLUGIN_NAME, logProvider ); } @Override diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/procedure/GetServersProcedureV2.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/procedure/GetServersProcedureV2.java index d3b957e550865..23db118ee31ec 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/procedure/GetServersProcedureV2.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/procedure/GetServersProcedureV2.java @@ -22,7 +22,7 @@ import java.util.Map; import org.neo4j.causalclustering.load_balancing.LoadBalancingResult; -import org.neo4j.causalclustering.load_balancing.LoadBalancingStrategy; +import org.neo4j.causalclustering.load_balancing.LoadBalancingPlugin; import org.neo4j.collection.RawIterator; import org.neo4j.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.proc.CallableProcedure; @@ -55,11 +55,11 @@ public class GetServersProcedureV2 implements CallableProcedure .description( DESCRIPTION ) .build(); - private final LoadBalancingStrategy loadBalancingStrategy; + private final LoadBalancingPlugin loadBalancingPlugin; - public GetServersProcedureV2( LoadBalancingStrategy loadBalancingStrategy ) + public GetServersProcedureV2( LoadBalancingPlugin loadBalancingPlugin ) { - this.loadBalancingStrategy = loadBalancingStrategy; + this.loadBalancingPlugin = loadBalancingPlugin; } @Override @@ -74,7 +74,7 @@ public RawIterator apply( Context ctx, Object[] inp @SuppressWarnings( "unchecked" ) Map clientContext = (Map) input[0]; - LoadBalancingStrategy.Result result = loadBalancingStrategy.run( clientContext ); + LoadBalancingPlugin.Result result = loadBalancingPlugin.run( clientContext ); return ResultFormatV1.build( new LoadBalancingResult( result.routeEndpoints(), diff --git a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/procedure/ParameterNames.java b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/procedure/ParameterNames.java index 58dbaf9179659..2a683487825ba 100644 --- a/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/procedure/ParameterNames.java +++ b/enterprise/causal-clustering/src/main/java/org/neo4j/causalclustering/load_balancing/procedure/ParameterNames.java @@ -30,7 +30,7 @@ public enum ParameterNames * * An opaque key-value map for supplying client context. * - * Refer to the specific routing strategy deployed to + * Refer to the specific routing plugin deployed to * understand which specific keys can be utilised. */ CONTEXT( "context" ), @@ -51,7 +51,7 @@ public enum ParameterNames * Defines the time-to-live of the returned information, * after which it shall be refreshed. * - * Refer to the specific routing strategy deployed to + * Refer to the specific routing plugin deployed to * understand the impact of this setting. */ TTL( "ttl" ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/ServerShufflingStrategyTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/ServerShufflingPluginTest.java similarity index 88% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/ServerShufflingStrategyTest.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/ServerShufflingPluginTest.java index b86f2841ccc17..f85e1f1108370 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/ServerShufflingStrategyTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/ServerShufflingPluginTest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy; +package org.neo4j.causalclustering.load_balancing.plugins; import org.junit.Test; @@ -27,7 +27,7 @@ import org.neo4j.causalclustering.load_balancing.Endpoint; import org.neo4j.causalclustering.load_balancing.LoadBalancingResult; -import org.neo4j.causalclustering.load_balancing.LoadBalancingStrategy; +import org.neo4j.causalclustering.load_balancing.LoadBalancingPlugin; import org.neo4j.helpers.AdvertisedSocketAddress; import static java.util.Arrays.asList; @@ -39,13 +39,13 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class ServerShufflingStrategyTest +public class ServerShufflingPluginTest { @Test public void shouldShuffleServers() throws Exception { // given - LoadBalancingStrategy delegate = mock( LoadBalancingStrategy.class ); + LoadBalancingPlugin delegate = mock( LoadBalancingPlugin.class ); List routers = asList( Endpoint.route( new AdvertisedSocketAddress( "route", 1 ) ), @@ -61,7 +61,7 @@ public void shouldShuffleServers() throws Exception Endpoint.read( new AdvertisedSocketAddress( "read", 9 ) ) ); long ttl = 1000; - LoadBalancingStrategy.Result result = new LoadBalancingResult( + LoadBalancingPlugin.Result result = new LoadBalancingResult( new ArrayList<>( routers ), new ArrayList<>( writers ), new ArrayList<>( readers ), @@ -69,13 +69,13 @@ public void shouldShuffleServers() throws Exception when( delegate.run( any() ) ).thenReturn( result ); - ServerShufflingStrategy strategy = new ServerShufflingStrategy( delegate ); + ServerShufflingPlugin plugin = new ServerShufflingPlugin( delegate ); boolean completeShuffle = false; for ( int i = 0; i < 1000; i++ ) // we try many times to make false negatives extremely unlikely { // when - LoadBalancingStrategy.Result shuffledResult = strategy.run( Collections.emptyMap() ); + LoadBalancingPlugin.Result shuffledResult = plugin.run( Collections.emptyMap() ); // then: should still contain the same endpoints assertThat( shuffledResult.routeEndpoints(), containsInAnyOrder( routers.toArray() ) ); diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/AnyTagFilterTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/AnyTagFilterTest.java similarity index 97% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/AnyTagFilterTest.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/AnyTagFilterTest.java index 8fab17fceb57a..e31bb96bccc01 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/AnyTagFilterTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/AnyTagFilterTest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import org.junit.Test; diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilterBuilder.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilterBuilder.java similarity index 96% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilterBuilder.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilterBuilder.java index 8a59bd6189afe..9b188af751ea8 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilterBuilder.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilterBuilder.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import java.util.ArrayList; import java.util.List; diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilterConfigParserTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilterConfigParserTest.java similarity index 96% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilterConfigParserTest.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilterConfigParserTest.java index fdad2fb3facf3..1d48362409198 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilterConfigParserTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilterConfigParserTest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import org.junit.Test; @@ -26,7 +26,7 @@ import static java.lang.String.format; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import static org.neo4j.causalclustering.load_balancing.strategy.server_policy.FilterBuilder.filter; +import static org.neo4j.causalclustering.load_balancing.plugins.server_policies.FilterBuilder.filter; public class FilterConfigParserTest { diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilteringPolicyLoaderTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilteringPolicyLoaderTest.java similarity index 86% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilteringPolicyLoaderTest.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilteringPolicyLoaderTest.java index 9957597589a5b..9581048d0e306 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/FilteringPolicyLoaderTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/FilteringPolicyLoaderTest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import org.junit.Test; @@ -30,7 +30,7 @@ import static java.lang.String.format; import static org.junit.Assert.assertEquals; import static org.neo4j.causalclustering.core.CausalClusteringSettings.load_balancing_config; -import static org.neo4j.causalclustering.load_balancing.strategy.server_policy.FilterBuilder.filter; +import static org.neo4j.causalclustering.load_balancing.plugins.server_policies.FilterBuilder.filter; import static org.neo4j.helpers.collection.MapUtil.stringMap; public class FilteringPolicyLoaderTest @@ -39,7 +39,7 @@ public class FilteringPolicyLoaderTest public void shouldLoadConfiguredPolicies() throws Exception { // given - String strategyName = "server_policy"; + String pluginName = "server_policies"; Object[][] input = { { @@ -74,11 +74,11 @@ public void shouldLoadConfiguredPolicies() throws Exception { String policyName = (String) row[0]; String filterSpec = (String) row[1]; - config = config.augment( stringMap( configNameFor( strategyName, policyName ), filterSpec ) ); + config = config.augment( stringMap( configNameFor( pluginName, policyName ), filterSpec ) ); } // when - Policies policies = FilteringPolicyLoader.load( config, strategyName, NullLogProvider.getInstance() ); + Policies policies = FilteringPolicyLoader.load( config, pluginName, NullLogProvider.getInstance() ); // then for ( Object[] row : input ) @@ -96,8 +96,8 @@ private static Map policyNameContext( String policyName ) return stringMap( Policies.POLICY_KEY, policyName ); } - private static String configNameFor( String strategyName, String policyName ) + private static String configNameFor( String pluginName, String policyName ) { - return format( "%s.%s.%s", load_balancing_config.name(), strategyName, policyName ); + return format( "%s.%s.%s", load_balancing_config.name(), pluginName, policyName ); } } diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/PoliciesTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/PoliciesTest.java similarity index 77% rename from enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/PoliciesTest.java rename to enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/PoliciesTest.java index aa8dddea756c3..79cb8e4e0cd15 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/strategy/server_policy/PoliciesTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/plugins/server_policies/PoliciesTest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package org.neo4j.causalclustering.load_balancing.strategy.server_policy; +package org.neo4j.causalclustering.load_balancing.plugins.server_policies; import org.junit.Test; @@ -28,6 +28,7 @@ import static java.util.Collections.emptyMap; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.neo4j.helpers.collection.Iterators.asSet; import static org.neo4j.helpers.collection.MapUtil.stringMap; @@ -50,6 +51,7 @@ public void shouldSupplyDefaultUnfilteredPolicyForEmptyContext() throws Exceptio // then assertEquals( input, output ); + assertEquals( Policies.DEFAULT_POLICY, policy ); } @Test @@ -69,6 +71,24 @@ public void shouldSupplyDefaultUnfilteredPolicyForUnknownPolicyName() throws Exc // then assertEquals( input, output ); + assertEquals( Policies.DEFAULT_POLICY, policy ); + } + + @Test + public void shouldAllowOverridingDefaultPolicy() throws Exception + { + Policies policies = new Policies( NullLogProvider.getInstance() ); + + String defaulyPolicyName = Policies.DEFAULT_POLICY_NAME; + Policy defaultPolicy = new FilteringPolicy( new AnyTagFilter( "tagA", "tagB" ) ); + + // when + policies.addPolicy( defaulyPolicyName, defaultPolicy ); + Policy selectedPolicy = policies.selectFor( emptyMap() ); + + // then + assertEquals( defaultPolicy, selectedPolicy ); + assertNotEquals( Policies.DEFAULT_POLICY, selectedPolicy ); } @Test diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/procedure/GetServersProcedureV2Test.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/procedure/GetServersProcedureV2Test.java index 0b1c3475230ff..1262d06ae1fbc 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/procedure/GetServersProcedureV2Test.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/load_balancing/procedure/GetServersProcedureV2Test.java @@ -23,12 +23,11 @@ import java.util.Map; -import org.neo4j.causalclustering.load_balancing.LoadBalancingStrategy; +import org.neo4j.causalclustering.load_balancing.LoadBalancingPlugin; import org.neo4j.kernel.api.proc.FieldSignature; import org.neo4j.kernel.api.proc.ProcedureSignature; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.any; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.mockito.Matchers.anyMap; import static org.mockito.Mockito.mock; @@ -59,18 +58,18 @@ public void shouldHaveCorrectSignature() throws Exception } @Test - public void shouldPassClientContextToStrategy() throws Exception + public void shouldPassClientContextToPlugin() throws Exception { // given - LoadBalancingStrategy strategy = mock( LoadBalancingStrategy.class ); - when( strategy.run( anyMap() ) ).thenReturn( mock( LoadBalancingStrategy.Result.class ) ); - GetServersProcedureV2 getServers = new GetServersProcedureV2( strategy ); + LoadBalancingPlugin plugin = mock( LoadBalancingPlugin.class ); + when( plugin.run( anyMap() ) ).thenReturn( mock( LoadBalancingPlugin.Result.class ) ); + GetServersProcedureV2 getServers = new GetServersProcedureV2( plugin ); Map clientContext = stringMap( "key", "value", "key2", "value2" ); // when getServers.apply( null, new Object[] { clientContext } ); // then - verify( strategy ).run( clientContext ); + verify( plugin ).run( clientContext ); } } diff --git a/packaging/standalone/standalone-enterprise/src/main/distribution/text/enterprise/conf/neo4j.conf b/packaging/standalone/standalone-enterprise/src/main/distribution/text/enterprise/conf/neo4j.conf index 878e5a00853ce..481131640a246 100644 --- a/packaging/standalone/standalone-enterprise/src/main/distribution/text/enterprise/conf/neo4j.conf +++ b/packaging/standalone/standalone-enterprise/src/main/distribution/text/enterprise/conf/neo4j.conf @@ -188,6 +188,51 @@ dbms.connector.https.enabled=true # If you don't know what value to use here, use this machines ip address. #causal_clustering.raft_listen_address=:7000 +# Defines a set of tags used to identify the server in the configuration +# for load balancing and replication policies. This is a comma-separated +# list and tags should use only alphanumericals and underscore. It usually +# makes sense to give each server a unique tag as well as one or more +# shared tags which then form logical groupings of servers. +#causal_clustering.server_tags= + +#***************************************************************** +# Causal Clustering Load Balancing +#***************************************************************** + +# N.B: Read the online documentation for a thorough explanation! + +# Selects the load balancing plugin that shall be enabled. +#causal_clustering.load_balancing.plugin=server_policies + +####### Examples for "server_policies" plugin ####### + +# Will select all available servers as the default policy, which is the +# policy used when the client does not specify a policy preference. The +# default configuration for the default policy is all(). +#causal_clustering.load_balancing.config.server_policies.default=all() + +# Will select servers with 'tag1', 'tag2' or 'tag3' under the default policy. +#causal_clustering.load_balancing.config.server_policies.default=tags(tag1,tag2,tag3) + +# Will select servers with 'tag1', 'tag2' or 'tag3', but only if there are at least 2. +# This policy will be exposed under the name of 'policyA' +#causal_clustering.load_balancing.config.server_policies.policyA=tags(tag1,tag2,tag3) + +# Will create an advanced policy named 'policyB' consisting of several rules +# yielding the following behaviour: +# +# select servers with 'tag1', 'tag2' or 'tag3', if at least 2 are available +# otherwise: select servers with 'grouptag', if at least 2 are available +# otherwise: select all servers +# +# N.B: The following configuration uses the line-continuation character \ +# which allows you to construct an easily readable rule set. +# +#causal_clustering.load_balancing.config.server_policies.policyB=\ +#tags(tag1,tag2,tag3) -> min(2);\ +#tags(grouptag) -> min(2);\ +#all() + #***************************************************************** # Causal Clustering Additional Configuration Options #*****************************************************************