Package com.splout.db.engine

Source Code of com.splout.db.engine.EmbeddedMySQL$EmbeddedMySQLConfig

package com.splout.db.engine;

/*
* #%L
* Splout SQL commons
* %%
* Copyright (C) 2012 - 2013 Datasalt Systems S.L.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.common.io.Files;
import com.mysql.management.MysqldResource;
import com.mysql.management.MysqldResourceI;

/**
* An interface to use MySQL(d) from Java in an embedded way. This actually starts Mysqld in a separate process with its
* own PID.
* <p>
* Classes used: http://dev.mysql.com/doc/connector-mxj/en/connector-mxj-configuration-java-object.html
*/
public class EmbeddedMySQL {

  public static final String DRIVER = "com.mysql.jdbc.Driver";

  private final static Log log = LogFactory.getLog(EmbeddedMySQL.class);

  public static class EmbeddedMySQLConfig {

    public final static int DEFAULT_PORT = 4567;
    public final static String DEFAULT_USER = "splout";
    public final static String DEFAULT_PASS = "splout";
    public final static File DEFAULT_RESIDENT_FOLDER = new File(System.getProperty("java.io.tmpdir"),
        "mysql-splout");

    final int port;
    final String user;
    final String pass;
    final File residentFolder;
    final Map<String, Object> customConfig;

    public EmbeddedMySQLConfig() {
      this(DEFAULT_PORT, DEFAULT_USER, DEFAULT_PASS, DEFAULT_RESIDENT_FOLDER, null);
    }

    public EmbeddedMySQLConfig(int port, String user, String pass, File residentFolder,
        Map<String, Object> customConfig) {
      this.port = port;
      this.user = user;
      this.pass = pass;
      this.residentFolder = residentFolder;
      this.customConfig = customConfig;
    }

    public Map<String, Object> getCustomConfig() {
      return customConfig;
    }

    public String getPass() {
      return pass;
    }

    public int getPort() {
      return port;
    }

    public File getResidentFolder() {
      return residentFolder;
    }

    public String getUser() {
      return user;
    }

    /**
     * Normal JDBC connection string to localhost with "createDatabaseIfNotExist"
     */
    public String getLocalJDBCConnection(String dbName) {
      return "jdbc:mysql://localhost:" + port + "/" + dbName + "?createDatabaseIfNotExist=true";
    }

    @Override
    public String toString() {
      return ReflectionToStringBuilder.toString(this);
    }
  };

  final EmbeddedMySQLConfig config;
  MysqldResource resource = null;

  public EmbeddedMySQL() {
    this(new EmbeddedMySQLConfig());
  }

  public EmbeddedMySQLConfig getConfig() {
    return config;
  }

  public EmbeddedMySQL(EmbeddedMySQLConfig config) {
    this.config = config;
  }

  /**
   * It's ok to call this multiple times (redundant times will be ignored).
   */
  public void stop() {
    if(resource != null) {
      if(resource.isRunning()) {
        resource.shutdown();
        resource = null;
      }
    } else {
      log.warn("Nothing to stop.");
    }
  }

  /**
   * TODO MySQL Hangs if port is busy, we should perform a timeout in a separate thred.
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public void start(boolean deleteFilesIfExist) throws IOException, InterruptedException {
    if(deleteFilesIfExist && config.residentFolder.exists()) {
      File pidFile = new File(config.residentFolder, "data/MysqldResource.pid");
      if(pidFile.exists()) {
        // Issue "kill -9" if process is still alive
        String pid = Files.toString(pidFile, Charset.defaultCharset());
        log.info("Killing existing process: " + pid);
        Runtime.getRuntime().exec("kill -9 " + pid).waitFor();
      }
      log.info("Deleting contents of: " + config.residentFolder);
      FileUtils.deleteDirectory(config.residentFolder);
    }
    log.info("Using config: " + config);
    MysqldResource mysqldResource = new MysqldResource(config.residentFolder);
    Map database_options = new HashMap();
    database_options.put(MysqldResourceI.PORT, Integer.toString(config.port));
    database_options.put(MysqldResourceI.INITIALIZE_USER, "true");
    database_options.put(MysqldResourceI.INITIALIZE_USER_NAME, config.user);
    database_options.put(MysqldResourceI.INITIALIZE_PASSWORD, config.pass);
    log.info("Using user: " + System.getProperty("user.name"));
    database_options.put("user", System.getProperty("user.name"));
    if(config.customConfig != null) {
      for(Map.Entry<String, Object> entry : config.customConfig.entrySet()) {
        database_options.put(entry.getKey(), entry.getValue());
      }
    }
    // I have to do this checking myself, otherwise in some cases mysqldResource will block undefinitely...
    try {
      ServerSocket serverSocket = new ServerSocket(config.port);
      serverSocket.close();
    } catch(IOException e) {
      throw new RuntimeException("Port already in use: " + config.port);
    }
    if(mysqldResource.isRunning()) {
      throw new RuntimeException("MySQL already running!");
    }
    mysqldResource.start("test-mysqld-thread", database_options);
    if(!mysqldResource.isRunning()) {
      throw new RuntimeException("MySQL did not start successfully!");
    }
    log.info("MySQL is running.");
    resource = mysqldResource;
  }
}
TOP

Related Classes of com.splout.db.engine.EmbeddedMySQL$EmbeddedMySQLConfig

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.