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

com.lordofthejars.nosqlunit.elasticsearch.ManagedElasticsearchLifecycleManager Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.lordofthejars.nosqlunit.elasticsearch;

import static com.lordofthejars.nosqlunit.core.IOUtils.deleteDir;

import java.io.File;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lordofthejars.nosqlunit.core.AbstractLifecycleManager;
import com.lordofthejars.nosqlunit.core.CommandLineExecutor;
import com.lordofthejars.nosqlunit.core.OperatingSystem;
import com.lordofthejars.nosqlunit.core.OperatingSystemFamily;
import com.lordofthejars.nosqlunit.core.OperatingSystemResolver;
import com.lordofthejars.nosqlunit.core.OsNameSystemPropertyOperatingSystemResolver;
import com.lordofthejars.nosqlunit.env.SystemEnvironmentVariables;

public class ManagedElasticsearchLifecycleManager extends AbstractLifecycleManager {

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

	public ManagedElasticsearchLifecycleManager() {
		super();
	}

	private static final String LOCALHOST = "localhost";

	protected static final String FOREGROUND_OPTION = "-f";
	protected static final String DEFAULT_ELASTICSEARCH_TARGET_PATH = "target" + File.separatorChar
			+ "elasticsearch-temp";
	protected static final String ELASTICSEARCH_BINARY_DIRECTORY = "bin";

	protected static final String ELASTICSEARC_EXECUTABLE_X = "elasticsearch";
	protected static final String ELASTICSEARC_EXECUTABLE_W = "elasticsearch.bat";

	protected static final int DEFAULT_PORT = 9300;

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

	private CommandLineExecutor commandLineExecutor = new CommandLineExecutor();
	private OperatingSystemResolver operatingSystemResolver = new OsNameSystemPropertyOperatingSystemResolver();
	private LowLevelElasticSearchOperations lowLevelElasticSearchOperations = new LowLevelElasticSearchOperations();

	private String elasticsearchPath = SystemEnvironmentVariables.getEnvironmentOrPropertyVariable("ES_HOME");
	private int port = DEFAULT_PORT;

	private String targetPath = DEFAULT_ELASTICSEARCH_TARGET_PATH;

	private ProcessRunnable processRunnable;

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

	@Override
	public int getPort() {
		return port;
	}

	@Override
	public void doStart() throws Throwable {

		LOGGER.info("Starting {} Elasticsearch instance.", elasticsearchPath);

		File dbPath = ensureDbPathDoesNotExitsAndReturnCompositePath();

		if (dbPath.mkdirs()) {
			startElasticsearchAsADaemon();
			boolean isServerUp = this.lowLevelElasticSearchOperations.assertThatConnectionToElasticsearchIsPossible(LOCALHOST, DEFAULT_PORT);

			if (!isServerUp) {
				throw new IllegalStateException("Couldn't establish a connection with " + this.elasticsearchPath
						+ " server at /127.0.0.1:" + port);
			}

		} else {
			throw new IllegalStateException("Db Path " + dbPath + " could not be created.");
		}

		LOGGER.info("Started {} Elasticsearch instance.", elasticsearchPath);
	}


	private void startElasticsearchAsADaemon() throws InterruptedException {
		CountDownLatch processIsReady = new CountDownLatch(1);
		processRunnable = new ProcessRunnable(processIsReady);
		Thread thread = new Thread(processRunnable);
		thread.start();
		processIsReady.await();
	}

	@Override
	public void doStop() {
		LOGGER.info("Stopping {} Elasticsearch instance.", elasticsearchPath);

		try {
			if(this.processRunnable != null) {
				this.processRunnable.destroyProcess();
			}
		} finally {
			ensureDbPathDoesNotExitsAndReturnCompositePath();
		}

		LOGGER.info("Stopped {} Elasticsearch instance.", elasticsearchPath);
	}

	private List buildOperationSystemProgramAndArguments() {

		List programAndArguments = new ArrayList();

		programAndArguments.add(getExecutablePath());

		if (isXBased()) {
			programAndArguments.add(FOREGROUND_OPTION);
		}

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

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

		return programAndArguments;

	}

	private boolean isXBased() {
		OperatingSystemFamily family = this.operatingSystemResolver.currentOperatingSystem().getFamily();
		return family != OperatingSystemFamily.WINDOWS;
	}

	private String getExecutablePath() {
		return this.elasticsearchPath + File.separatorChar + ELASTICSEARCH_BINARY_DIRECTORY + File.separatorChar
				+ elasticsearchExecutable();
	}

	private File ensureDbPathDoesNotExitsAndReturnCompositePath() {
		File dbPath = new File(targetPath);
		if (dbPath.exists()) {
			deleteDir(dbPath);
		}
		return dbPath;
	}

	private String elasticsearchExecutable() {
		OperatingSystem operatingSystem = this.operatingSystemResolver.currentOperatingSystem();

		switch (operatingSystem.getFamily()) {
		case WINDOWS:
			return ELASTICSEARC_EXECUTABLE_W;
		default:
			return ELASTICSEARC_EXECUTABLE_X;
		}

	}

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

	public void setElasticsearchPath(String elasticsearchPath) {
		this.elasticsearchPath = elasticsearchPath;
	}

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

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

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

	public String getElasticsearchPath() {
		return elasticsearchPath;
	}

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

	protected void setOperatingSystemResolver(OperatingSystemResolver operatingSystemResolver) {
		this.operatingSystemResolver = operatingSystemResolver;
	}

	protected void setLowLevelElasticSearchOperations(LowLevelElasticSearchOperations lowLevelElasticSearchOperations) {
		this.lowLevelElasticSearchOperations = lowLevelElasticSearchOperations;
	}

	public class ProcessRunnable implements Runnable {

		private CountDownLatch processIsReady;

		private Process process;

		public ProcessRunnable(CountDownLatch processIsReady) {
			this.processIsReady = processIsReady;
		}

		@Override
		public void run() {
			try {
				process = startProcess();
			} catch (IOException e) {
				throw prepareException(e);
			} finally {
				processIsReady.countDown();
			}

			try {
				process.waitFor();

			} catch (InterruptedException ie) {
				throw prepareException(ie);
			}

		}

		public void destroyProcess() {
			if (this.process != null) {
				this.process.destroy();
			}
		}

		private IllegalStateException prepareException(Exception e) {
			return new IllegalStateException("Elasticsearch [" + elasticsearchPath
					+ "] could not be started. Next console message was thrown: " + e.getMessage());
		}

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

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy