All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lordofthejars.nosqlunit.cassandra.ManagedCassandraLifecycleManager Maven / Gradle / Ivy

package com.lordofthejars.nosqlunit.cassandra;

import static ch.lambdaj.Lambda.having;
import static ch.lambdaj.Lambda.on;
import static ch.lambdaj.Lambda.selectUnique;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.core.StringStartsWith.startsWith;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import me.prettyprint.cassandra.service.CassandraHost;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lordofthejars.nosqlunit.core.AbstractLifecycleManager;
import com.lordofthejars.nosqlunit.core.CommandLineExecutor;
import com.lordofthejars.nosqlunit.env.SystemEnvironmentVariables;

public class ManagedCassandraLifecycleManager extends AbstractLifecycleManager {

	private static final Logger LOGGER = LoggerFactory.getLogger(ManagedCassandra.class);

	private static final String MAXIUM_HEAP = "-Xmx1G";

	private static final String MINIUM_HEAP = "-Xms1G";

	private static final String ENABLE_ASSERTIONS = "-ea";

	private static final String LIB_DIRECTORY = "/lib";

	Process pwd;

	private static final String LOCALHOST = "127.0.0.1";

	protected static final String FOREGROUND_ARGUMENT_NAME = "-Dcassandra-foreground=yes";

	public static final String DEFAULT_CASSANDRA_TARGET_PATH = "target" + File.separatorChar + "cassandra-temp";
	protected static final String CASSANDRA_BINARY_DIRECTORY = "bin";

	protected String CASSANDRA_CONF_DIRECTORY = "/conf";
	protected String CASSANDRA_DAEMON_CLASS = "org.apache.cassandra.thrift.CassandraDaemon";

	protected String javaHome = System.getProperty("java.home");
	private String cassandraPath = SystemEnvironmentVariables.getEnvironmentOrPropertyVariable("CASSANDRA_HOME");

	protected static final String CASSANDRA_EXECUTABLE_X = "cassandra";
	protected static final String CASSANDRA_EXECUTABLE_W = "cassandra.bat";

	private String targetPath = DEFAULT_CASSANDRA_TARGET_PATH;
	private int port = CassandraHost.DEFAULT_PORT;

	private Map extraCommandArguments = new HashMap();
	private List singleCommandArguments = new ArrayList();

	private CommandLineExecutor commandLineExecutor = new CommandLineExecutor();

	public ManagedCassandraLifecycleManager() {
		super();
	}

	
	@Override
	public void doStart() throws Throwable {
		LOGGER.info("Starting {} Cassandra instance.", cassandraPath);
		startCassandra();
		LOGGER.info("Started {} Cassandra instance.", cassandraPath);
	}

	private void startCassandra() throws AssertionError {
		final CountDownLatch startupLatch = new CountDownLatch(1);
		new Thread(new Runnable() {
			public void run() {
				try {
					startCassandraAsDaemon();
					startupLatch.countDown();
				} catch (InterruptedException e) {
					throw new IllegalStateException(e);
				}
			}
		}).start();

		try {
			startupLatch.await(10, SECONDS);
		} catch (InterruptedException e) {
			throw new AssertionError(e);
		}
	}

	private List startCassandraAsDaemon() throws InterruptedException {

		try {
			pwd = startProcess();
			pwd.waitFor();
			if (pwd.exitValue() != 0) {
				List consoleOutput = getConsoleOutput(pwd);
				throw new IllegalStateException("Cassandra [" + cassandraPath + " at port " + port
						+ "] could not be started. Next console message was thrown: " + consoleOutput);
			}
			return null;
		} catch (IOException e) {
			throw new IllegalStateException("Cassandra [" + cassandraPath + " at port " + port
					+ "] could not be started. Next console message was thrown: ");
		}
	}

	private Process startProcess() throws IOException {
		return this.commandLineExecutor.startProcessInDirectoryAndArguments(targetPath,
				buildOperationSystemProgramAndArguments());
	}

	private List getConsoleOutput(Process pwd) throws IOException {
		return this.commandLineExecutor.getConsoleOutput(pwd);
	}

	private List buildOperationSystemProgramAndArguments() {

		File[] cassandraJarLibraries = getCassandraJarLibraries();

		List programAndArguments = new ArrayList();
		File jammJar = getJammJar(cassandraJarLibraries);

		String classpath = getCassandraClasspath(cassandraJarLibraries);

		programAndArguments.add(javaHome + "/bin/java");
		programAndArguments.add(ENABLE_ASSERTIONS);
		programAndArguments.add("-javaagent:\"" + jammJar.getAbsolutePath() + "\"");
		programAndArguments.add(MINIUM_HEAP);
		programAndArguments.add(MAXIUM_HEAP);
		programAndArguments.add(FOREGROUND_ARGUMENT_NAME);

		for (String argument : this.singleCommandArguments) {
			programAndArguments.add(argument);
		}

		for (String argumentName : this.extraCommandArguments.keySet()) {
			programAndArguments.add(argumentName);
			programAndArguments.add(this.extraCommandArguments.get(argumentName));
		}

		programAndArguments.add("-cp");
		programAndArguments.add("\"" + cassandraPath + CASSANDRA_CONF_DIRECTORY + "\";" + classpath + "");
		programAndArguments.add(CASSANDRA_DAEMON_CLASS);

		return programAndArguments;

	}

	@Override
	public void doStop() {
		LOGGER.info("Stopping {} Cassandra instance.", cassandraPath);
		
		stopCassandra();
		
		LOGGER.info("Stopped {} Cassandra instance.", cassandraPath);
	}

	private void stopCassandra() {
		pwd.destroy();
	}

	private File[] getCassandraJarLibraries() {
		File cassandraLibDirectory = new File(cassandraPath + LIB_DIRECTORY);
		File[] cassandraJars = cassandraLibDirectory.listFiles(new FilenameFilter() {
			public boolean accept(File dir, String name) {
				return name.endsWith(".jar");
			}
		});

		return cassandraJars;
	}

	private File getJammJar(File[] cassandraJars) {
		File jammJar = selectUnique(cassandraJars, having(on(File.class).getName(), startsWith("jamm")));
		return jammJar;
	}

	private String getCassandraClasspath(File[] cassandraJars) {

		StringBuilder classpathCommandLine = new StringBuilder();

		for (File cassandraJar : cassandraJars) {
			classpathCommandLine.append("\"").append(cassandraJar.getAbsolutePath()).append("\";");
		}

		return classpathCommandLine.substring(0, classpathCommandLine.length() - 1);

	}

	public void addExtraCommandLineArgument(String argumentName, String argumentValue) {
		this.extraCommandArguments.put(argumentName, argumentValue);
	}

	public void addSingleCommandLineArgument(String argument) {
		this.singleCommandArguments.add(argument);
	}

	public void setPort(int port) {
		this.port = port;
	}

	public void setTargetPath(String targetPath) {
		this.targetPath = targetPath;
	}

	public void setCassandraPath(String cassandraPath) {
		this.cassandraPath = cassandraPath;
	}

	public String getCassandraPath() {
		return cassandraPath;
	}

	public void setCommandLineExecutor(CommandLineExecutor commandLineExecutor) {
		this.commandLineExecutor = commandLineExecutor;
	}

	@Override
	protected String getHost() {
		return LOCALHOST;
	}

	@Override
	protected int getPort() {
		return this.port;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy