Initial MariaDB entity, largely a clone of the existing mySQL entity. Project: http://git-wip-us.apache.org/repos/asf/brooklyn-library/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-library/commit/2e0516df Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-library/tree/2e0516df Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-library/diff/2e0516df
Branch: refs/heads/0.6.0 Commit: 2e0516df17a9597b71f6b36d1c13483cc57676e1 Parents: 25b37b3 Author: Alasdair Hodge <[email protected]> Authored: Mon Oct 28 14:01:46 2013 +0000 Committer: Alasdair Hodge <[email protected]> Committed: Mon Oct 28 19:14:01 2013 +0000 ---------------------------------------------------------------------- .../entity/database/mariadb/MariaDbDriver.java | 10 + .../entity/database/mariadb/MariaDbNode.java | 84 ++++++++ .../database/mariadb/MariaDbNodeImpl.java | 119 ++++++++++ .../database/mariadb/MariaDbSshDriver.java | 216 +++++++++++++++++++ .../brooklyn/entity/database/mariadb/my.cnf | 19 ++ .../src/main/resources/mariadb-logo-180x119.png | Bin 0 -> 9659 bytes .../mariadb/MariaDbIntegrationTest.groovy | 105 +++++++++ .../database/mariadb/MariaDbLiveEc2Test.java | 27 +++ .../mariadb/MariaDbLiveRackspaceTest.java | 80 +++++++ 9 files changed, 660 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e0516df/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbDriver.java ---------------------------------------------------------------------- diff --git a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbDriver.java b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbDriver.java new file mode 100644 index 0000000..3061f5e --- /dev/null +++ b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbDriver.java @@ -0,0 +1,10 @@ +package brooklyn.entity.database.mariadb; + +import brooklyn.entity.basic.SoftwareProcessDriver; + +/** + * The {@link SoftwareProcessDriver} for MariaDB. + */ +public interface MariaDbDriver extends SoftwareProcessDriver { + public String getStatusCmd(); +} http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e0516df/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNode.java ---------------------------------------------------------------------- diff --git a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNode.java b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNode.java new file mode 100644 index 0000000..256ce8a --- /dev/null +++ b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNode.java @@ -0,0 +1,84 @@ +package brooklyn.entity.database.mariadb; + +import brooklyn.catalog.Catalog; +import brooklyn.config.ConfigKey; +import brooklyn.entity.basic.Attributes; +import brooklyn.entity.basic.ConfigKeys; +import brooklyn.entity.basic.SoftwareProcess; +import brooklyn.entity.database.DatabaseNode; +import brooklyn.entity.proxying.ImplementedBy; +import brooklyn.entity.trait.HasShortName; +import brooklyn.event.AttributeSensor; +import brooklyn.event.basic.BasicAttributeSensorAndConfigKey; +import brooklyn.event.basic.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey; +import brooklyn.event.basic.MapConfigKey; +import brooklyn.event.basic.PortAttributeSensorAndConfigKey; +import brooklyn.event.basic.Sensors; +import brooklyn.location.basic.PortRanges; +import brooklyn.util.flags.SetFromFlag; + +@Catalog(name="MariaDB Node", description="MariaDB is an open source relational database management system (RDBMS)", iconUrl="classpath:///mariadb-logo-180x119.png") +@ImplementedBy(MariaDbNodeImpl.class) +public interface MariaDbNode extends DatabaseNode, HasShortName { + + @SetFromFlag("version") + public static final ConfigKey<String> SUGGESTED_VERSION = + ConfigKeys.newConfigKeyWithDefault(SoftwareProcess.SUGGESTED_VERSION, "5.5.33a"); + + // https://downloads.mariadb.org/interstitial/mariadb-5.5.33a/kvm-bintar-hardy-amd64/mariadb-5.5.33a-linux-x86_64.tar.gz/from/http://mirrors.coreix.net/mariadb + // above link points to a "donate" page, then ultimately downloads the artifact from: + // 64-bit: http://mirrors.coreix.net/mariadb/mariadb-5.5.33a/kvm-bintar-hardy-amd64/mariadb-5.5.33a-linux-x86_64.tar.gz + // 32-bit: http://mirrors.coreix.net/mariadb/mariadb-5.5.33a/kvm-bintar-hardy-x86/mariadb-5.5.33a-linux-i686.tar.gz + + @SetFromFlag("downloadUrl") + public static final BasicAttributeSensorAndConfigKey<String> DOWNLOAD_URL = new StringAttributeSensorAndConfigKey( + Attributes.DOWNLOAD_URL, "${driver.mirrorUrl}/mariadb-${version}/${driver.downloadParentDir}/mariadb-${version}-${driver.osTag}.tar.gz"); + + /** download mirror, if desired */ + @SetFromFlag("mirrorUrl") + public static final ConfigKey<String> MIRROR_URL = ConfigKeys.newStringConfigKey("mariadb.install.mirror.url", "URL of mirror", + "http://mirrors.coreix.net/mariadb/" + ); + + @SetFromFlag("port") + public static final PortAttributeSensorAndConfigKey MARIADB_PORT = + new PortAttributeSensorAndConfigKey("mariadb.port", "MariaDB port", PortRanges.fromString("3306, 13306+")); + + @SetFromFlag("creationScriptContents") + public static final ConfigKey<String> CREATION_SCRIPT_CONTENTS = + ConfigKeys.newStringConfigKey("mariadb.creation.script.contents", "MariaDB creation script (SQL contents)", ""); + + @SetFromFlag("creationScriptUrl") + public static final ConfigKey<String> CREATION_SCRIPT_URL = + ConfigKeys.newStringConfigKey("mariadb.creation.script.url", "URL where MariaDB creation script can be found", ""); + + @SetFromFlag("dataDir") + public static final ConfigKey<String> DATA_DIR = ConfigKeys.newStringConfigKey( + "mariadb.datadir", "Directory for writing data files", null); + + @SetFromFlag("serverConf") + public static final MapConfigKey<Object> MARIADB_SERVER_CONF = new MapConfigKey<Object>( + Object.class, "mariadb.server.conf", "Configuration options for MariaDB server"); + + public static final ConfigKey<Object> MARIADB_SERVER_CONF_LOWER_CASE_TABLE_NAMES = + MARIADB_SERVER_CONF.subKey("lower_case_table_names", "See MariaDB (or MySQL!) guide. Set 1 to ignore case in table names (useful for OS portability)"); + + @SetFromFlag("password") + public static final StringAttributeSensorAndConfigKey PASSWORD = new StringAttributeSensorAndConfigKey( + "mariadb.password", "Database admin password (or randomly generated if not set)", null); + + @SetFromFlag("socketUid") + public static final StringAttributeSensorAndConfigKey SOCKET_UID = new StringAttributeSensorAndConfigKey( + "mariadb.socketUid", "Socket uid, for use in file /tmp/mysql.sock.<uid>.3306 (or randomly generated if not set)", null); + + public static final AttributeSensor<String> MARIADB_URL = DB_URL; + + @SetFromFlag("configurationTemplateUrl") + static final BasicAttributeSensorAndConfigKey<String> TEMPLATE_CONFIGURATION_URL = new StringAttributeSensorAndConfigKey( + "mariadb.template.configuration.url", "Template file (in freemarker format) for the my.cnf file", + "classpath://brooklyn/entity/database/mariadb/my.cnf"); + + public static final AttributeSensor<Double> QUERIES_PER_SECOND_FROM_MARIADB = + Sensors.newDoubleSensor("mariadb.queries.perSec.fromMariadb"); + +} http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e0516df/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java ---------------------------------------------------------------------- diff --git a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java new file mode 100644 index 0000000..e370367 --- /dev/null +++ b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java @@ -0,0 +1,119 @@ +package brooklyn.entity.database.mariadb; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.entity.Entity; +import brooklyn.entity.basic.SoftwareProcessImpl; +import brooklyn.event.feed.ssh.SshFeed; +import brooklyn.event.feed.ssh.SshPollConfig; +import brooklyn.event.feed.ssh.SshPollValue; +import brooklyn.location.Location; +import brooklyn.location.basic.SshMachineLocation; +import brooklyn.util.collections.MutableMap; +import brooklyn.util.text.Identifiers; +import brooklyn.util.text.Strings; +import brooklyn.util.time.Duration; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; + +public class MariaDbNodeImpl extends SoftwareProcessImpl implements MariaDbNode { + + private static final Logger LOG = LoggerFactory.getLogger(MariaDbNodeImpl.class); + + private SshFeed feed; + + public MariaDbNodeImpl() { + } + + public MariaDbNodeImpl(Entity parent) { + this(MutableMap.of(), parent); + } + + public MariaDbNodeImpl(Map<?,?> flags) { + super(flags, null); + } + + public MariaDbNodeImpl(Map<?,?> flags, Entity parent) { + super(flags, parent); + } + + @Override + public Class<?> getDriverInterface() { + return MariaDbDriver.class; + } + + @Override + public MariaDbDriver getDriver() { + return (MariaDbDriver) super.getDriver(); + } + + @Override + protected void connectSensors() { + super.connectSensors(); + setAttribute(DB_URL, String.format("mysql://%s:%s/", getAttribute(HOSTNAME), getAttribute(MARIADB_PORT))); + + /* + * TODO status gives us things like: + * Uptime: 2427 Threads: 1 Questions: 581 Slow queries: 0 Opens: 53 Flush tables: 1 Open tables: 35 Queries per second avg: 0.239 + * So can extract lots of sensors from that. + */ + Location machine = Iterables.get(getLocations(), 0, null); + + if (machine instanceof SshMachineLocation) { + String cmd = getDriver().getStatusCmd(); + feed = SshFeed.builder() + .entity(this) + .period(Duration.FIVE_SECONDS) + .machine((SshMachineLocation) machine) + .poll(new SshPollConfig<Boolean>(SERVICE_UP) + .command(cmd) + .setOnSuccess(true) + .setOnFailureOrException(false)) + .poll(new SshPollConfig<Double>(QUERIES_PER_SECOND_FROM_MARIADB) + .command(cmd) + .onSuccess(new Function<SshPollValue, Double>() { + public Double apply(SshPollValue input) { + String q = Strings.getFirstWordAfter(input.getStdout(), "Queries per second avg:"); + return (q == null) ? null : Double.parseDouble(q); + }}) + .setOnFailureOrException(null) ) + .build(); + } else { + LOG.warn("Location(s) %s not an ssh-machine location, so not polling for status; setting serviceUp immediately", getLocations()); + setAttribute(SERVICE_UP, true); + } + } + + @Override + protected void disconnectSensors() { + if (feed != null) feed.stop(); + } + + public int getPort() { + return getAttribute(MARIADB_PORT); + } + + public String getSocketUid() { + String result = getAttribute(MariaDbNode.SOCKET_UID); + if (Strings.isBlank(result)) + setAttribute(MariaDbNode.SOCKET_UID, (result = Identifiers.makeRandomId(6))); + return result; + } + + public String getPassword() { + String result = getAttribute(MariaDbNode.PASSWORD); + if (Strings.isBlank(result)) + setAttribute(MariaDbNode.PASSWORD, (result = Identifiers.makeRandomId(6))); + return result; + } + + @Override + public String getShortName() { + return "MariaDB"; + } + +} http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e0516df/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java ---------------------------------------------------------------------- diff --git a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java new file mode 100644 index 0000000..5c85903 --- /dev/null +++ b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java @@ -0,0 +1,216 @@ +package brooklyn.entity.database.mariadb; + +import static brooklyn.util.GroovyJavaMethods.elvis; +import static brooklyn.util.GroovyJavaMethods.truth; +import static brooklyn.util.ssh.BashCommands.installPackage; +import static brooklyn.util.ssh.BashCommands.ok; +import static java.lang.String.format; + +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver; +import brooklyn.entity.basic.EntityInternal; +import brooklyn.entity.drivers.downloads.DownloadResolver; +import brooklyn.entity.drivers.downloads.DownloadResolverManager; +import brooklyn.location.OsDetails; +import brooklyn.location.basic.SshMachineLocation; +import brooklyn.management.ManagementContext; +import brooklyn.util.ResourceUtils; +import brooklyn.util.collections.MutableMap; +import brooklyn.util.ssh.BashCommands; +import brooklyn.util.text.Strings; + +import com.google.common.collect.ImmutableMap; + +/** + * The SSH implementation of the {@link MariaDbDriver}. + */ +public class MariaDbSshDriver extends AbstractSoftwareProcessSshDriver implements MariaDbDriver { + + public static final Logger log = LoggerFactory.getLogger(MariaDbSshDriver.class); + + private String expandedInstallDir; + + public MariaDbSshDriver(MariaDbNodeImpl entity, SshMachineLocation machine) { + super(entity, machine); + } + + public String getOsTag() { + OsDetails os = getLocation().getOsDetails(); + if (os == null) return "linux-i686"; + if (os.isLinux()) return "linux-" + (os.is64bit() ? "x86_64" : "i686"); + throw new UnsupportedOperationException("only support linux versions just now"); + } + + public String getDownloadParentDir() { + OsDetails os = getLocation().getOsDetails(); + if (os == null) return "kvm-bintar-hardy-x86"; + if (os.isLinux()) return "kvm-bintar-hardy-" + (os.is64bit() ? "amd64" : "x86"); + throw new UnsupportedOperationException("only support linux versions just now"); + } + + public String getMirrorUrl() { + return entity.getConfig(MariaDbNode.MIRROR_URL); + } + + public String getBasedir() { + return getExpandedInstallDir(); + } + + public String getDatadir() { + String result = entity.getConfig(MariaDbNode.DATA_DIR); + return (result == null) ? "." : result; + } + + public String getInstallFilename() { + return String.format("mariadb-%s-%s.tar.gz", getVersion(), getOsTag()); + } + + private String getExpandedInstallDir() { + if (expandedInstallDir == null) + throw new IllegalStateException("'expandedInstallDir' is null; most likely install was not called"); + return expandedInstallDir; + } + + @Override + public void install() { + // mariadb-${version}-${driver.osTag}.tar.gz + + ManagementContext managementContext = ((EntityInternal) entity).getManagementContext(); + DownloadResolverManager downloadManager = managementContext.getEntityDownloadsManager(); + DownloadResolver resolver = downloadManager.newDownloader( + this, ImmutableMap.of("filename", getInstallFilename())); + List<String> urls = resolver.getTargets(); + String saveAs = resolver.getFilename(); + expandedInstallDir = getInstallDir() + "/" + resolver.getUnpackedDirectoryName(format("mariadb-%s-%s", getVersion(), getOsTag())); + + List<String> commands = new LinkedList<String>(); + commands.add(BashCommands.INSTALL_TAR); + commands.add(BashCommands.INSTALL_CURL); + + commands.add("echo installing extra packages"); + commands.add(installPackage(ImmutableMap.of("yum", "libgcc_s.so.1"), null)); + commands.add(installPackage(ImmutableMap.of("yum", "libaio.so.1 libncurses.so.5", "apt", "libaio1 libaio-dev"), null)); + // these deps are needed on some OS versions but others don't need them so ignore failures (ok(...)) + commands.add(ok(installPackage(ImmutableMap.of("yum", "libaio", "apt", "ia32-libs"), null))); + commands.add("echo finished installing extra packages"); + + commands.addAll(BashCommands.commandsToDownloadUrlsAs(urls, saveAs)); + commands.add(format("tar xfvz %s", saveAs)); + + newScript(INSTALLING). + body.append(commands).execute(); + } + + public MariaDbNodeImpl getEntity() { return (MariaDbNodeImpl) super.getEntity(); } + public int getPort() { return getEntity().getPort(); } + public String getSocketUid() { return getEntity().getSocketUid(); } + public String getPassword() { return getEntity().getPassword(); } + + @Override + public void customize() { + copyDatabaseCreationScript(); + copyDatabaseConfigScript(); + + newScript(CUSTOMIZING). + updateTaskAndFailOnNonZeroResultCode(). + body.append( + "chmod 600 my.cnf", + getBasedir()+"/scripts/mysql_install_db "+ + "--basedir="+getBasedir()+" --datadir="+getDatadir()+" "+ + "--defaults-file=my.cnf", + getBasedir()+"/bin/mysqld --defaults-file=my.cnf --user=`whoami` &", //--user=root needed if we are root + "export MYSQL_PID=$!", + "sleep 20", + "echo launching mysqladmin", + getBasedir()+"/bin/mysqladmin --defaults-file=my.cnf --password= password "+getPassword(), + "sleep 20", + "echo launching mysql creation script", + getBasedir()+"/bin/mysql --defaults-file=my.cnf < creation-script.cnf", + "echo terminating mysql on customization complete", + "kill $MYSQL_PID" + ).execute(); + } + + private void copyDatabaseCreationScript() { + newScript(CUSTOMIZING). + body.append("echo copying creation script"). + execute(); //create the directory + + Reader creationScript; + String url = entity.getConfig(MariaDbNode.CREATION_SCRIPT_URL); + if (!Strings.isBlank(url)) + creationScript = new InputStreamReader(new ResourceUtils(entity).getResourceFromUrl(url)); + else creationScript = + new StringReader((String) elvis(entity.getConfig(MariaDbNode.CREATION_SCRIPT_CONTENTS), "")); + getMachine().copyTo(creationScript, getRunDir() + "/creation-script.cnf"); + } + + private void copyDatabaseConfigScript() { + newScript(CUSTOMIZING). + body.append("echo copying server config script"). + execute(); //create the directory + + String configScriptContents = processTemplate(entity.getAttribute(MariaDbNode.TEMPLATE_CONFIGURATION_URL)); + Reader configContents = new StringReader(configScriptContents); + + getMachine().copyTo(configContents, getRunDir() + "/my.cnf"); + } + + public String getMariaDbServerOptionsString() { + Map<String, Object> options = entity.getConfig(MariaDbNode.MARIADB_SERVER_CONF); + if (!truth(options)) return ""; + String result = ""; + for (Map.Entry<String, Object> entry : options.entrySet()) { + if("".equals(entry.getValue())){ + result += ""+entry.getKey()+"\n"; + }else{ + result += ""+entry.getKey()+" = "+entry.getValue()+"\n"; + } + } + return result; + } + + @Override + public void launch() { + newScript(MutableMap.of("usePidFile", true), LAUNCHING). + updateTaskAndFailOnNonZeroResultCode(). + body.append( + format("nohup %s/bin/mysqld --defaults-file=my.cnf --user=`whoami` > out.log 2> err.log < /dev/null &", getBasedir()) + ).execute(); + } + + @Override + public boolean isRunning() { + return newScript(MutableMap.of("usePidFile", false), CHECK_RUNNING) + .body.append(getStatusCmd()) + .execute() == 0; + } + + @Override + public void stop() { + newScript(MutableMap.of("usePidFile", true), STOPPING).execute(); + } + + @Override + public void kill() { + newScript(MutableMap.of("usePidFile", true), KILLING).execute(); + } + + @Override + public String getStatusCmd() { + // TODO Is this very bad, to include the password in the command being executed + // (so is in `ps` listing temporarily, and in .bash_history) + return format("%s/bin/mysqladmin --user=%s --password=%s --socket=/tmp/mysql.sock.%s.%s status", + getExpandedInstallDir(), "root", getPassword(), getSocketUid(), getPort()); + } + +} http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e0516df/software/database/src/main/resources/brooklyn/entity/database/mariadb/my.cnf ---------------------------------------------------------------------- diff --git a/software/database/src/main/resources/brooklyn/entity/database/mariadb/my.cnf b/software/database/src/main/resources/brooklyn/entity/database/mariadb/my.cnf new file mode 100644 index 0000000..f9946b1 --- /dev/null +++ b/software/database/src/main/resources/brooklyn/entity/database/mariadb/my.cnf @@ -0,0 +1,19 @@ +[client] +port = ${driver.port?c} +socket = /tmp/mysql.sock.${entity.socketUid}.${driver.port?c} +user = root +password = ${entity.password} + +# Here follows entries for some specific programs + +# The MariaDB server, which (confusingly) uses MySQL terminology for backwards compatibility +[mysqld] +port = ${driver.port?c} +socket = /tmp/mysql.sock.${entity.socketUid}.${driver.port?c} +basedir = ${driver.basedir} +datadir = ${driver.datadir} +bind-address = 0.0.0.0 +# skip-networking + +# Custom configuration options +${driver.mariaDbServerOptionsString} http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e0516df/software/database/src/main/resources/mariadb-logo-180x119.png ---------------------------------------------------------------------- diff --git a/software/database/src/main/resources/mariadb-logo-180x119.png b/software/database/src/main/resources/mariadb-logo-180x119.png new file mode 100644 index 0000000..cea7acd Binary files /dev/null and b/software/database/src/main/resources/mariadb-logo-180x119.png differ http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e0516df/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbIntegrationTest.groovy ---------------------------------------------------------------------- diff --git a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbIntegrationTest.groovy b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbIntegrationTest.groovy new file mode 100644 index 0000000..7ca7986 --- /dev/null +++ b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbIntegrationTest.groovy @@ -0,0 +1,105 @@ +package brooklyn.entity.database.mariadb + +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.testng.Assert +import org.testng.annotations.AfterMethod +import org.testng.annotations.BeforeMethod +import org.testng.annotations.Test + +import brooklyn.config.BrooklynProperties +import brooklyn.entity.basic.ApplicationBuilder +import brooklyn.entity.basic.Entities +import brooklyn.entity.database.VogellaExampleAccess +import brooklyn.entity.proxying.EntitySpec +import brooklyn.location.basic.LocalhostMachineProvisioningLocation +import brooklyn.management.ManagementContext +import brooklyn.management.internal.LocalManagementContext +import brooklyn.test.entity.TestApplication +import brooklyn.util.collections.MutableMap +import brooklyn.util.text.Strings + +/** + * Runs a slightly modified version of the popular Vogella MySQL tutorial, + * from + * http://www.vogella.de/articles/MySQLJava/article.html + */ +public class MariaDbIntegrationTest { + + public static final Logger log = LoggerFactory.getLogger(MariaDbIntegrationTest.class); + + protected BrooklynProperties brooklynProperties; + protected ManagementContext managementContext; + protected TestApplication tapp; + + @BeforeMethod(alwaysRun = true) + public void setUp() { + brooklynProperties = BrooklynProperties.Factory.newDefault(); + managementContext = new LocalManagementContext(brooklynProperties); + tapp = ApplicationBuilder.newManagedApp(TestApplication.class, managementContext); + } + + @AfterMethod(alwaysRun=true) + public void ensureShutDown() { + if (tapp != null) { + Entities.destroyAll(tapp.getManagementContext()); + tapp = null; + } + } + + // can start in AWS by running this -- or use brooklyn CLI/REST for most clouds, or programmatic/config for set of fixed IP machines + static String hostname = java.net.InetAddress.getLocalHost().getHostName() + + //from http://www.vogella.de/articles/MySQLJava/article.html + public static final String CREATION_SCRIPT = """ +CREATE DATABASE feedback; +CREATE USER 'sqluser'@'localhost' IDENTIFIED BY 'sqluserpw'; +GRANT USAGE ON *.* TO 'sqluser'@'localhost'; +GRANT ALL PRIVILEGES ON feedback.* TO 'sqluser'@'localhost'; +CREATE USER 'sqluser'@'%' IDENTIFIED BY 'sqluserpw'; +GRANT USAGE ON *.* TO 'sqluser'@'%'; +GRANT ALL PRIVILEGES ON feedback.* TO 'sqluser'@'%'; +CREATE USER 'sqluser'@'$hostname' IDENTIFIED BY 'sqluserpw'; +GRANT USAGE ON *.* TO 'sqluser'@'$hostname'; +GRANT ALL PRIVILEGES ON feedback.* TO 'sqluser'@'$hostname'; +FLUSH PRIVILEGES; +USE feedback; +CREATE TABLE COMMENTS ( + id INT NOT NULL AUTO_INCREMENT, + MYUSER VARCHAR(30) NOT NULL, + EMAIL VARCHAR(30), + WEBPAGE VARCHAR(100) NOT NULL, + DATUM DATE NOT NULL, + SUMMARY VARCHAR(40) NOT NULL, + COMMENTS VARCHAR(400) NOT NULL, + PRIMARY KEY (ID) + ); + +INSERT INTO COMMENTS values (default, 'lars', '[email protected]','http://www.vogella.de', '2009-09-14 10:33:11', 'Summary','My first comment' ); +"""; + + @Test(groups = ["Integration"]) + public void test_localhost() throws Exception { + String dataDir = "/tmp/mariadb-data-" + Strings.makeRandomId(8); + MariaDbNode mariadb = tapp.createAndManageChild(EntitySpec.create(MariaDbNode.class) + .configure(MariaDbNode.MARIADB_SERVER_CONF, MutableMap.of("skip-name-resolve","")) + .configure("creationScriptContents", CREATION_SCRIPT) + .configure("dataDir", dataDir)); + LocalhostMachineProvisioningLocation location = new LocalhostMachineProvisioningLocation(); + + tapp.start([location]); + log.info("MariaDB started"); + + new VogellaExampleAccess("com.mysql.jdbc.Driver", mariadb.getAttribute(MariaDbNode.DB_URL)).readModifyAndRevertDataBase(); + + log.info("Ran vogella MySQL example -- SUCCESS"); + + // Ensure the data directory was successfully overridden. + File dataDirFile = new File(dataDir); + File mariadbSubdirFile = new File(dataDirFile, "mysql"); + Assert.assertTrue(mariadbSubdirFile.exists()); + + // Clean up. + dataDirFile.deleteDir(); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e0516df/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java ---------------------------------------------------------------------- diff --git a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java new file mode 100644 index 0000000..a7199a0 --- /dev/null +++ b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java @@ -0,0 +1,27 @@ +package brooklyn.entity.database.mariadb; + +import org.testng.annotations.Test; + +import brooklyn.entity.AbstractEc2LiveTest; +import brooklyn.entity.database.VogellaExampleAccess; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.location.Location; + +import com.google.common.collect.ImmutableList; + +@Test(groups = { "Live" }) +public class MariaDbLiveEc2Test extends AbstractEc2LiveTest { + + @Override + protected void doTest(Location loc) throws Exception { + + MariaDbNode mariadb = app.createAndManageChild(EntitySpec.create(MariaDbNode.class) + .configure("creationScriptContents", MariaDbIntegrationTest.CREATION_SCRIPT)); + + app.start(ImmutableList.of(loc)); + + new VogellaExampleAccess("com.mysql.jdbc.Driver", mariadb.getAttribute(MariaDbNode.DB_URL)).readModifyAndRevertDataBase(); + } + +} + http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e0516df/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveRackspaceTest.java ---------------------------------------------------------------------- diff --git a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveRackspaceTest.java b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveRackspaceTest.java new file mode 100644 index 0000000..3196b6e --- /dev/null +++ b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveRackspaceTest.java @@ -0,0 +1,80 @@ +package brooklyn.entity.database.mariadb; + +import org.testng.annotations.Test; + +import brooklyn.entity.database.VogellaExampleAccess; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.location.basic.SshMachineLocation; +import brooklyn.location.jclouds.JcloudsLocation; + +import com.google.common.collect.ImmutableList; + +/** + * The MariaDbLiveTest installs MariaDb on various operating systems like Ubuntu, CentOS, Red Hat etc. To make sure that + * MariaDb works like expected on these Operating Systems. + */ +public class MariaDbLiveRackspaceTest extends MariaDbIntegrationTest { + @Test(groups = {"Live"}) + public void test_Debian_6() throws Exception { + test("Debian 6"); + } + + @Test(groups = {"Live"}) + public void test_Ubuntu_10_0() throws Exception { + test("Ubuntu 10.0"); + } + + @Test(groups = {"Live"}) + public void test_Ubuntu_11_0() throws Exception { + test("Ubuntu 11.0"); + } + + @Test(groups = {"Live", "Live-sanity"}) + public void test_Ubuntu_12_0() throws Exception { + test("Ubuntu 12.0"); + } + + @Test(groups = {"Live"}) + public void test_CentOS_6_0() throws Exception { + test("CentOS 6.0"); + } + + @Test(groups = {"Live"}) + public void test_CentOS_5_6() throws Exception { + test("CentOS 5.6"); + } + + @Test(groups = {"Live"}) + public void test_Fedora_17() throws Exception { + test("Fedora 17"); + } + + @Test(groups = {"Live"}) + public void test_Red_Hat_Enterprise_Linux_6() throws Exception { + test("Red Hat Enterprise Linux 6"); + } + + @Test(groups = {"Live"}) + public void test_localhost() throws Exception { + super.test_localhost(); + } + + public void test(String osRegex) throws Exception { + MariaDbNode mariadb = tapp.createAndManageChild(EntitySpec.create(MariaDbNode.class) + .configure("creationScriptContents", CREATION_SCRIPT)); + + brooklynProperties.put("brooklyn.jclouds.rackspace-cloudservers-uk.image-name-regex", osRegex); + brooklynProperties.remove("brooklyn.jclouds.rackspace-cloudservers-uk.image-id"); + brooklynProperties.put("inboundPorts", "22, 3306"); + JcloudsLocation jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve("jclouds:rackspace-cloudservers-uk"); + + tapp.start(ImmutableList.of(jcloudsLocation)); + + SshMachineLocation l = (SshMachineLocation) mariadb.getLocations().iterator().next(); + //hack to get the port for mysql open; is the inbounds property not respected on rackspace?? + l.exec(ImmutableList.of("iptables -I INPUT -p tcp --dport 3306 -j ACCEPT")); + + new VogellaExampleAccess("com.mysql.jdbc.Driver", mariadb.getAttribute(MariaDbNode.DB_URL)).readModifyAndRevertDataBase(); + + } +}
