/*******************************************************************************
* Copyright (c) 2007 - 2010 GreenDeltaTC. All rights reserved. This program and
* the accompanying materials are made available under the terms of the Mozilla
* Public License v1.1 which accompanies this distribution, and is available at
* http://www.openlca.org/uploads/media/MPL-1.1.html
*
* Contributors: GreenDeltaTC - initial API and implementation
* www.greendeltatc.com tel.: +49 30 4849 6030 mail: gdtc@greendeltatc.com
******************************************************************************/
package org.openlca.core.database.mysql;
import java.io.File;
import java.io.InputStream;
import org.openlca.util.OS;
import org.openlca.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A class for starting and stopping an MySQL server application under Windows.
* See https://code.google.com/p/guciodb/ for a minimal MySQL package which can
* be managed by this class. It is assumed that the user is root and that there
* is no password required for the server instance.
*/
public class ServerApp {
private Logger log = LoggerFactory.getLogger(this.getClass());
private final String SEP = System.getProperty("file.separator");
private final String ADMIN_EXE = SEP + "bin" + SEP + "mysqladmin.exe";
private final String SERVER_EXE = SEP + "bin" + SEP + "mysqld-nt.exe";
private String appDir;
private String dataDir;
private int port;
public ServerApp(File appDir, File dataDir, int port) {
checkArgs(appDir);
log.trace("Init MySQL Server App");
log.trace("App - directory {}", appDir);
log.trace("Data directory {}", dataDir);
log.trace("Can write in data dir.: {}", dataDir.canWrite());
this.appDir = appDir.getAbsolutePath();
this.dataDir = dataDir.getAbsolutePath();
this.port = port;
}
private void checkArgs(File appDir) {
File admin = new File(appDir, ADMIN_EXE);
File server = new File(appDir, SERVER_EXE);
if (!admin.exists() || !server.exists()) {
throw new IllegalArgumentException("The folder " + appDir
+ " is not a MySQL application directory.");
}
}
public void shutdown() throws Exception {
assertWindows();
log.info("Shutdown server via {}", exe(ADMIN_EXE));
String[] command = new String[] { exe(ADMIN_EXE), "-u", "root",
"shutdown", "--port=" + port };
ProcessBuilder builder = new ProcessBuilder(command);
String response = startProcess(builder);
log.info("Server response: {}", response);
}
private String exe(String exe) {
return appDir + exe;
}
public boolean ping() throws Exception {
log.trace("Ping server via {}", exe(ADMIN_EXE));
boolean ping = false;
String[] command = new String[] { exe(ADMIN_EXE), "ping",
"--port=" + port };
ProcessBuilder builder = new ProcessBuilder(command);
String response = startProcess(builder);
log.trace("Server response: {}", response);
ping = response.equalsIgnoreCase("mysqld is alive");
return ping;
}
public void start() throws Exception {
assertWindows();
if (ping())
return; // already alive
log.info("Start MySQL Server {}.", exe(SERVER_EXE));
log.info("Using data directory {}", dataDir);
String[] command = new String[] { exe(SERVER_EXE), "--port=" + port,
"--datadir=" + dataDir, "--max_connections=200" };
ProcessBuilder builder = new ProcessBuilder(command);
String response = startProcess(builder);
log.info("Server response: {}", response);
waitForServer();
}
private void waitForServer() throws Exception {
int c = 0;
boolean b = ping();
while (!b && c < 10) {
try {
log.trace("Wait for server: {} second(s)", c);
Thread.sleep(1000);
} catch (Exception e) {
log.error("Waiting for server failed", e);
}
b = ping();
c++;
}
}
private String startProcess(ProcessBuilder builder) throws Exception {
builder.redirectErrorStream(true);
Process process = builder.start();
String[] result = null;
try (InputStream is = process.getInputStream()) {
result = Strings.readLines(is);
}
String res = null;
if (result != null && result.length > 0) {
res = result[0];
}
return res == null ? "" : res;
}
private void assertWindows() throws Exception {
OS os = OS.getCurrent();
if (os != OS.Windows)
throw new Exception(
"Start and shut-down of MySQL server currently not supported "
+ "on non-Windows platforms.");
}
}