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

com.lordofthejars.nosqlunit.infinispan.ManagedInfinispanLifecycleManager Maven / Gradle / Ivy

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

import static com.lordofthejars.nosqlunit.core.IOUtils.deleteDir;
import static java.util.concurrent.TimeUnit.SECONDS;

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 java.util.concurrent.TimeUnit;

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.OperatingSystemResolver;
import com.lordofthejars.nosqlunit.core.OsNameSystemPropertyOperatingSystemResolver;
import com.lordofthejars.nosqlunit.env.SystemEnvironmentVariables;

public class ManagedInfinispanLifecycleManager extends AbstractLifecycleManager {

	private static final Logger LOGGER = LoggerFactory.getLogger(ManagedInfinispanLifecycleManager.class);
	
	Process pwd;
	
	private static final String LOCALHOST = "127.0.0.1";
	public static final int DEFAULT_PORT = 11222;
	
	protected static final String DEFAULT_INFINISPAN_TARGET_PATH = "target" + File.separatorChar + "infinispan-temp";
	protected static final String INFINISPAN_BINARY_DIRECTORY = "bin";

	protected static final String INFINISPAN_EXECUTABLE_X = "startServer.sh";
	protected static final String INFINISPAN_EXECUTABLE_W = "startServer.bat";

	protected static final String PORT_COMMAND_LINE_ARGUMENT_NAME = "--port";
	protected static final String PROTOCOL_COMMAND_LINE_ARGUMENT_NAME = "--protocol";
	protected static final String PROTOCOL_COMMAND_LINE_DEFAULT_VALUE = "hotrod";
	
	private int port = DEFAULT_PORT;
	private String protocol = PROTOCOL_COMMAND_LINE_DEFAULT_VALUE;
	
	private String targetPath = DEFAULT_INFINISPAN_TARGET_PATH;
	private String infinispanPath = SystemEnvironmentVariables.getEnvironmentOrPropertyVariable("INFINISPAN_HOME");
	
	private Map extraCommandArguments = new HashMap();
	private List singleCommandArguments = new ArrayList();

	private CommandLineExecutor commandLineExecutor = new CommandLineExecutor();
	private OperatingSystemResolver operatingSystemResolver = new OsNameSystemPropertyOperatingSystemResolver();
	
	private boolean closing = false;
	
	@Override
	public String getHost() {
		return LOCALHOST;
	}

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

	@Override
	public void doStart() throws Throwable {
		
		LOGGER.info("Starting {} Infinispan instance.", infinispanPath);
		

		File targetPathDirectory = ensureTargetPathDoesNotExitsAndReturnCompositePath();

		if (targetPathDirectory.mkdirs()) {
			startInfinispanAsDaemon();
		} else {
			throw new IllegalStateException("Target Path " + targetPathDirectory + " could not be created.");
		}
		
		LOGGER.info("Started {} Infinispan instance.", infinispanPath);
	}

	private void startInfinispanAsDaemon() {
		final CountDownLatch startupLatch = new CountDownLatch(1);
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					startInfinispanProcess();
					startupLatch.countDown();
				} catch (InterruptedException e) {
					throw new IllegalStateException(e);
				}
			}

		}).start();

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

	private List startInfinispanProcess() throws InterruptedException {
		try {
			pwd = startProcess();
			pwd.waitFor();
			if (pwd.exitValue() != 0) {
				List consoleOutput = getConsoleOutput(pwd);
				throw new IllegalStateException("Infinispan [" + infinispanPath + " at port " + port + " and protocol "+protocol
						+ "] could not be started. Next console message was thrown: " + consoleOutput);
			}
			return null;
		} catch (IOException e) {
			if(!closing) {
				throw new IllegalStateException("Infinispan [" + infinispanPath + " at port " + port + " and protocol "+protocol
					+ "] could not be started. Next console message was thrown: " + e.getMessage());
			}
			return null;
		}
	}
	
	private Process startProcess() throws IOException {
		return this.commandLineExecutor.startProcessInDirectoryAndArguments(targetPath,
				buildOperationSystemProgramAndArguments());
	}
	
	private List buildOperationSystemProgramAndArguments() {

		List programAndArguments = new ArrayList();

		programAndArguments.add(getExecutablePath());
		addPort(programAndArguments);
		addProtocol(programAndArguments);
		
		addSingleArguments(programAndArguments);
		addCommandArguments(programAndArguments);

		return programAndArguments;

	}

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

	private void addSingleArguments(List programAndArguments) {
		for (String argument : this.singleCommandArguments) {
			programAndArguments.add(argument);
		}
	}
	
	
	private void addProtocol(List programAndArguments) {
		programAndArguments.add(PROTOCOL_COMMAND_LINE_ARGUMENT_NAME);
		programAndArguments.add(PROTOCOL_COMMAND_LINE_DEFAULT_VALUE);
	}

	private void addPort(List programAndArguments) {
		programAndArguments.add(PORT_COMMAND_LINE_ARGUMENT_NAME);
		programAndArguments.add(Integer.toString(port));
	}

	
	
	private String getExecutablePath() {
		return this.infinispanPath + File.separatorChar + INFINISPAN_BINARY_DIRECTORY + File.separatorChar + infinispanExecutable();
	}

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

		switch (operatingSystem.getFamily()) {
		case WINDOWS:
			return INFINISPAN_EXECUTABLE_W;
		default:
			return INFINISPAN_EXECUTABLE_X;
		}

	}
	
	private List getConsoleOutput(Process pwd) throws IOException {
		return this.commandLineExecutor.getConsoleOutput(pwd);
	}
	
	@Override
	public void doStop() {
		
		LOGGER.info("Stopping {} Infinispan instance.", infinispanPath);
		
		try {
			closing = true;
			stopInfinispan();
		} catch (InterruptedException e) {
			throw new IllegalStateException(e);
		} finally {
			ensureTargetPathDoesNotExitsAndReturnCompositePath();
		}
		
		LOGGER.info("Stopped {} Infinispan instance.", infinispanPath);
	}

	private void stopInfinispan() throws InterruptedException {
		if (isProcessAlive()) {
			pwd.destroy();
			TimeUnit.SECONDS.sleep(2);
		}
	}

	private boolean isProcessAlive() {
		return pwd != null;
	}
	
	public void setPort(int port) {
		this.port = port;
	}
	
	public void setProtocol(String protocol) {
		this.protocol = protocol;
	}
	
	public String getProtocol() {
		return protocol;
	}
	
	public void setTargetPath(String targetPath) {
		this.targetPath = targetPath;
	}
	
	public void setInfinispanPath(String infinispanPath) {
		this.infinispanPath = infinispanPath;
	}
	
	public void addExtraCommandLineArgument(String argumentName, String argumentValue) {
		this.extraCommandArguments.put(argumentName, argumentValue);
	}

	public void addSingleCommandLineArgument(String argument) {
		this.singleCommandArguments.add(argument);
	}
	
	public void setCommandLineExecutor(CommandLineExecutor commandLineExecutor) {
		this.commandLineExecutor = commandLineExecutor;
	}
	
	public void setOperatingSystemResolver(OperatingSystemResolver operatingSystemResolver) {
		this.operatingSystemResolver = operatingSystemResolver;
	}
	
	private File ensureTargetPathDoesNotExitsAndReturnCompositePath() {
		File dbPath = new File(targetPath);
		if (dbPath.exists()) {
			deleteDir(dbPath);
		}
		return dbPath;
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy