Master-only creation script for MySqlCluster
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/ed4a76e9 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/ed4a76e9 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/ed4a76e9 Branch: refs/heads/master Commit: ed4a76e9975173f694381430dbb021f1762a8b58 Parents: ac7b9d1 Author: Svetoslav Neykov <[email protected]> Authored: Wed Sep 16 09:42:53 2015 +0300 Committer: Svetoslav Neykov <[email protected]> Committed: Thu Sep 17 14:15:46 2015 +0300 ---------------------------------------------------------------------- .../entity/database/mysql/MySqlCluster.java | 19 +++++++++++----- .../entity/database/mysql/MySqlClusterImpl.java | 21 +++++++++++++++++ .../mysql/MySqlClusterIntegrationTest.java | 24 ++++++++++++++++++-- .../database/mysql/MySqlClusterTestHelper.java | 13 ++++++++++- 4 files changed, 68 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ed4a76e9/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java ---------------------------------------------------------------------- diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java index d860d04..de43951 100644 --- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java +++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java @@ -25,20 +25,27 @@ import org.apache.brooklyn.api.entity.ImplementedBy; import org.apache.brooklyn.api.sensor.AttributeSensor; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigKeys; -import org.apache.brooklyn.core.sensor.Sensors; import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey; - -import com.google.common.reflect.TypeToken; - +import org.apache.brooklyn.core.sensor.Sensors; import org.apache.brooklyn.entity.database.DatastoreMixins.HasDatastoreUrl; import org.apache.brooklyn.entity.group.DynamicCluster; +import com.google.common.reflect.TypeToken; + @ImplementedBy(MySqlClusterImpl.class) @Catalog(name="MySql Master-Slave cluster", description="Sets up a cluster of MySQL nodes using master-slave relation and binary logging", iconUrl="classpath:///mysql-logo-110x57.png") public interface MySqlCluster extends DynamicCluster, HasDatastoreUrl { interface MySqlMaster { - AttributeSensor<String> MASTER_LOG_FILE = Sensors.newStringSensor("mysql.master.log_file", "The binary log file master is writing to"); - AttributeSensor<Integer> MASTER_LOG_POSITION = Sensors.newIntegerSensor("mysql.master.log_position", "The position in the log file to start replication"); + AttributeSensor<String> MASTER_LOG_FILE = Sensors.newStringSensor( + "mysql.master.log_file", "The binary log file master is writing to"); + AttributeSensor<Integer> MASTER_LOG_POSITION = Sensors.newIntegerSensor( + "mysql.master.log_position", "The position in the log file to start replication"); + + ConfigKey<String> MASTER_CREATION_SCRIPT_CONTENTS = ConfigKeys.newStringConfigKey( + "datastore.master.creation.script.contents", "Contents of creation script to initialize the master node after initializing replication"); + + ConfigKey<String> MASTER_CREATION_SCRIPT_URL = ConfigKeys.newStringConfigKey( + "datastore.master.creation.script.url", "URL of creation script to use to initialize the master node after initializing replication (ignored if creationScriptContents is specified)"); } interface MySqlSlave { AttributeSensor<Boolean> SLAVE_HEALTHY = Sensors.newBooleanSensor("mysql.slave.healthy", "Indicates that the replication state of the slave is healthy"); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ed4a76e9/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java ---------------------------------------------------------------------- diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java index 164bac4..63c5779 100644 --- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java +++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java @@ -24,6 +24,8 @@ import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import javax.annotation.Nullable; + import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntityLocal; import org.apache.brooklyn.api.entity.EntitySpec; @@ -39,16 +41,19 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpL import org.apache.brooklyn.core.sensor.DependentConfiguration; import org.apache.brooklyn.core.sensor.Sensors; import org.apache.brooklyn.enricher.stock.Enrichers; +import org.apache.brooklyn.entity.database.DatastoreMixins; import org.apache.brooklyn.entity.group.DynamicClusterImpl; import org.apache.brooklyn.feed.function.FunctionFeed; import org.apache.brooklyn.feed.function.FunctionPollConfig; import org.apache.brooklyn.util.collections.CollectionFunctionals; +import org.apache.brooklyn.util.core.ResourceUtils; import org.apache.brooklyn.util.core.task.DynamicTasks; import org.apache.brooklyn.util.core.task.TaskBuilder; import org.apache.brooklyn.util.guava.Functionals; import org.apache.brooklyn.util.guava.IfFunctions; import org.apache.brooklyn.util.text.Identifiers; import org.apache.brooklyn.util.text.StringPredicates; +import org.apache.brooklyn.util.text.Strings; import org.apache.brooklyn.util.time.Duration; import com.google.common.base.Function; @@ -310,8 +315,24 @@ public class MySqlClusterImpl extends DynamicClusterImpl implements MySqlCluster if (position != null) { ((EntityInternal)master).setAttribute(MySqlMaster.MASTER_LOG_POSITION, new Integer(position)); } + + //NOTE: Will be executed on each start, analogously to the standard CREATION_SCRIPT config + String creationScript = getDatabaseCreationScriptAsString(master); + if (creationScript != null) { + master.invoke(MySqlNode.EXECUTE_SCRIPT, ImmutableMap.of("commands", creationScript)); + } } + @Nullable private static String getDatabaseCreationScriptAsString(Entity entity) { + String url = entity.getConfig(MySqlMaster.MASTER_CREATION_SCRIPT_URL); + if (!Strings.isBlank(url)) + return new ResourceUtils(entity).getResourceAsString(url); + String contents = entity.getConfig(MySqlMaster.MASTER_CREATION_SCRIPT_CONTENTS); + if (!Strings.isBlank(contents)) + return contents; + return null; + } + private void initSlave(MySqlNode slave) { MySqlNode master = (MySqlNode) Iterables.find(cluster.getMembers(), IS_MASTER); String masterLogFile = validateSqlParam(getAttributeBlocking(master, MySqlMaster.MASTER_LOG_FILE)); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ed4a76e9/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java ---------------------------------------------------------------------- diff --git a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java index 1bf6ccb..c5e12d5 100644 --- a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java +++ b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java @@ -19,18 +19,20 @@ package org.apache.brooklyn.entity.database.mysql; import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport; import org.apache.brooklyn.util.os.Os; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; public class MySqlClusterIntegrationTest extends BrooklynAppLiveTestSupport { @Test(groups = {"Integration"}) - public void test_localhost() throws Exception { + public void testAllNodesInit() throws Exception { try { - MySqlClusterTestHelper.test(app, mgmt.getLocationRegistry().resolve("localhost")); + MySqlClusterTestHelper.test(app, getLocation()); } finally { for (Entity member : Iterables.getOnlyElement(app.getChildren()).getChildren()) { String runDir = member.getAttribute(MySqlNode.RUN_DIR); @@ -40,4 +42,22 @@ public class MySqlClusterIntegrationTest extends BrooklynAppLiveTestSupport { } } } + + @Test(groups = {"Integration"}) + public void testMasterInit() throws Exception { + try { + MySqlClusterTestHelper.testMasterInit(app, getLocation()); + } finally { + for (Entity member : Iterables.getOnlyElement(app.getChildren()).getChildren()) { + String runDir = member.getAttribute(MySqlNode.RUN_DIR); + if (runDir != null) { + Os.deleteRecursively(runDir); + } + } + } + } + + private Location getLocation() { + return mgmt.getLocationRegistry().resolve("localhost"); + } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ed4a76e9/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java ---------------------------------------------------------------------- diff --git a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java index dc13546..43a3b70 100644 --- a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java +++ b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java @@ -37,6 +37,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import org.apache.brooklyn.entity.database.VogellaExampleAccess; +import org.apache.brooklyn.entity.database.mysql.MySqlCluster.MySqlMaster; /** * Runs a slightly modified version of the popular Vogella MySQL tutorial, @@ -72,11 +73,21 @@ public class MySqlClusterTestHelper { )); public static void test(TestApplication app, Location location) throws Exception { - MySqlCluster mysql = app.createAndManageChild(EntitySpec.create(MySqlCluster.class) + test(app, location, EntitySpec.create(MySqlCluster.class) .configure(MySqlCluster.INITIAL_SIZE, 2) .configure(MySqlNode.CREATION_SCRIPT_CONTENTS, CREATION_SCRIPT) .configure(MySqlNode.MYSQL_SERVER_CONF, MutableMap.<String, Object>of("skip-name-resolve",""))); + } + + public static void testMasterInit(TestApplication app, Location location) throws Exception { + test(app, location, EntitySpec.create(MySqlCluster.class) + .configure(MySqlCluster.INITIAL_SIZE, 2) + .configure(MySqlMaster.MASTER_CREATION_SCRIPT_CONTENTS, CREATION_SCRIPT) + .configure(MySqlNode.MYSQL_SERVER_CONF, MutableMap.<String, Object>of("skip-name-resolve",""))); + } + public static void test(TestApplication app, Location location, EntitySpec<MySqlCluster> clusterSpec) throws Exception { + MySqlCluster mysql = app.createAndManageChild(clusterSpec); app.start(ImmutableList.of(location)); log.info("MySQL started");
