/* * (C) Copyright IBM Corp. 2012 * * LICENSE: Eclipse Public License v1.0 * http://www.eclipse.org/legal/epl-v10.html */ package com.ibm.gaiandb; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.regex.Pattern; public class BootstrapService { // Use PROPRIETARY notice if class contains a main() method, otherwise use COPYRIGHT notice. public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2012"; // get GAIAN_HOME, JAVA_HOME or JRE_HOME from system environment // TODO: improvement: see if dependency on these paths can be reduced private static String gaianHome = System.getenv("GAIAN_HOME"); private static String javaHome = System.getenv("JAVA_HOME"); private static String jreHome = System.getenv("JRE_HOME"); private static String gaianLibDir = gaianHome + "/lib"; private static String gaianClasspath = null; private static String processId = null; /* * Build classpath by adding all files from GAIAN_HOME/lib * Note: it means ALL dependencies for poi, 3rd party DBs need to be in GAIAN_HOME/lib * TODO: see if this can be changed to use multiple directories */ private static void addFilesInDirectoryToClasspath(File dir, StringBuffer classpath) { File[] files = dir.listFiles(); if (files != null) { for (File f : files) { if (f.isDirectory()) { addFilesInDirectoryToClasspath(f, classpath); } else { //System.out.println(f.getName()); // add to classpath classpath.append(f.getAbsolutePath()); classpath.append(isWindows() ? ";" : ":"); } } } } /* * Determine OS. Windows or not. */ public static boolean isWindows() { boolean isWindows = false; String osName = System.getProperty("os.name"); if (osName != null && Pattern.compile(Pattern.quote("win"), Pattern.CASE_INSENSITIVE).matcher(osName).find()) { isWindows = true; } return isWindows; } /* * Start has been called on the service, let's start the node with arguments collected from script */ public static void start(String args[]) throws Exception { if (gaianHome == null && (javaHome == null || jreHome == null)) { throw new Exception("GAIAN_HOME and JAVA_HOME (or JRE_HOME) are not set. Please set GAIAN_HOME and JAVA_HOME (or JRE_HOME) environment variables"); } /* Uncomment to debug incoming args for (String arg: args) { System.out.println(arg); }*/ // build classpath StringBuffer classpath = new StringBuffer(); addFilesInDirectoryToClasspath(new File(gaianLibDir), classpath); gaianClasspath = classpath.toString(); String usingJava = null; if (jreHome != null && !jreHome.equals("")) { System.out.println(jreHome); if (jreHome.endsWith("jre")) usingJava = jreHome + "/bin/java"; else usingJava = jreHome + "/jre/bin/java"; } else if (javaHome != null && !javaHome.equals("")) { System.out.println(javaHome); usingJava = javaHome + "/bin/java"; } else { System.out.println("using java.exe in the PATH"); usingJava = "java"; } // build command ArrayList<String> command = new ArrayList<String>(); command.add(usingJava); command.add("-Xmx256m"); command.add("-cp"); command.add(gaianClasspath); // find the arguments passed ArrayList<String> gaianArgs = null; String jvmArgs = null; if (args.length > 1) { // first argument is always 'start' for (int i = 1; args.length > i; i++) { String arg = args[i]; System.out.println(arg); if (arg.startsWith("-jvmargs")) { arg = args[i+1]; jvmArgs = arg.trim(); System.out.println("adding JVM arguments: " + jvmArgs); } else if (arg.startsWith("-gdbargs")){ System.out.println("Adding extra arguments: " + arg); gaianArgs = new ArrayList<String>(); boolean hasMoreArgs = true; arg = args[i+1]; System.out.println(arg); // need to tokenize the gaian args while (hasMoreArgs) { if (arg.length() > 0) { int idx = arg.indexOf(" "); if (idx > 0) { System.out.println(arg.substring(0, idx).trim()); gaianArgs.add(arg.substring(0, idx).trim()); } else { hasMoreArgs = false; } if (idx > 0) arg = arg.substring(idx).trim(); else hasMoreArgs = false; System.out.println(arg); idx = arg.indexOf(" -"); if (idx > 0) { System.out.println(arg.substring(0, idx).trim()); gaianArgs.add(arg.substring(0, idx).trim()); } else { hasMoreArgs = false; } System.out.println(arg.length()); System.out.println(idx); if (idx > 0) arg = arg.substring(idx).trim(); else { if (arg.length() > 0) gaianArgs.add(arg.trim()); hasMoreArgs = false; } } else hasMoreArgs = false; } //gaianArgs = arg.split("\\s[-]\\w+\\s"); } else { // do nothing for now, what other args could we get ? } } } // here put the -D stuff if (jvmArgs != null) command.add(jvmArgs); command.add("com.ibm.gaiandb.GaianNode"); if (gaianArgs != null) { for (String arg: gaianArgs) { command.add(arg); } } ProcessBuilder pb = new ProcessBuilder(command); File wDF = new File(gaianHome); wDF.mkdir(); pb.directory(wDF); System.out.println(" Launching Gaian Node using command: " + pb.command()); Process process = pb.start(); InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) { System.out.println("\t" + line); if (line.contains("PROCESS ID:")) { String[] split = line.split("\t"); processId = split[split.length - 1]; if (processId == null) { throw new Exception("Unable to start node. Please check the log."); } } } isr.close(); is.close(); } /* * Stop has been called from service, let's stop this node by using the processId we saved */ public static void stop(String args[]) throws Exception { if (gaianHome == null && javaHome == null) { throw new Exception("GAIAN_HOME and JAVA_HOME (or JRE_HOME) are not set. Please set GAIAN_HOME and JAVA_HOME (or JRE_HOME) environment variables"); } for (String arg : args) { System.out.println(arg); } if (gaianClasspath == null) { StringBuffer classpath = new StringBuffer(); addFilesInDirectoryToClasspath(new File(gaianLibDir), classpath); gaianClasspath = classpath.toString(); } System.out.print(" Attempting to kill node with process id: '"+ processId + "' ... "); /* * Execute the appropriate command to kill the node */ if (isWindows()) { Process proc = new ProcessBuilder("taskkill", "/f", "/pid", processId).start(); StreamSwallower errorSwallower = new StreamSwallower(proc.getErrorStream()); StreamSwallower outputSwallower = new StreamSwallower(proc.getInputStream()); errorSwallower.start(); outputSwallower.start(); } } public static class StreamSwallower extends Thread { InputStream is; BufferedReader br; public StreamSwallower(InputStream is) { this.is = is; } public StreamSwallower(BufferedReader br) { this.br = br; } public void run() { if (br == null) { InputStreamReader isr = new InputStreamReader(is); br = new BufferedReader(isr); } try { while (br.readLine() != null) { } } catch (IOException e) { e.printStackTrace(); } } } /* * Called by the gaiandb.exe with the arguments collected by the service.bat script */ public static void main(String args[]) { if (args.length > 0 && args[0].equals("stop")) { try { BootstrapService.stop(args); } catch (Exception e) { e.printStackTrace(); } } else { try { BootstrapService.start(args); } catch (Exception e) { e.printStackTrace(); } } } }