/*
* Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.test.infrastructure.process;
import org.mule.runtime.core.api.config.MuleProperties;
import org.mule.runtime.core.util.UUID;
import org.mule.tck.junit4.rule.FreePortFinder;
import org.mule.test.infrastructure.deployment.FakeMuleServer;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MuleContextProcessBuilder implements Cloneable, ConfigurableProcessBuilder {
protected transient final static Logger logger = LoggerFactory.getLogger(MuleContextProcessBuilder.class);
public static final String MULE_CONTEXT_CONFIGURATION_ID_KEY = MuleProperties.SYSTEM_PROPERTY_PREFIX + "serverId";
public static final String CONFIG_FILE_KEY = "configFile";
public static final String TIMEOUT_IN_SECONDS = "processTimeout";
public static final String LOG_PORT_PROPERTY = "test.log.port";
public static final String COMMAND_PORT_PROPERTY = "test.command.port";
public static final String MULE_CORE_EXTENSIONS_PROPERTY = "test.mule.coreextension";
public static final int DEFAULT_DEBUG_PORT = 5005;
private final File testDirectory;
private String muleAppClass;
private String instanceId = "unknown";
private Map<String, String> systemProperties = new HashMap<String, String>();
private FreePortFinder freePortFinder = new FreePortFinder(8000, 60000);
private List<ProcessBuilderConfigurer> processBuilderConfigurers = new ArrayList<ProcessBuilderConfigurer>();
public MuleContextProcessBuilder(File testDirectory) {
this.testDirectory = testDirectory;
systemProperties.put(MULE_CONTEXT_CONFIGURATION_ID_KEY, UUID.getUUID());
systemProperties.put(TIMEOUT_IN_SECONDS, "120");
systemProperties.put(FakeMuleServer.FAKE_SERVER_DISABLE_LOG_REPOSITORY_SELECTOR, "true");
}
public MuleContextProcessBuilder(MuleContextProcessBuilder clusteredMuleContextProcessBuilder) {
this.testDirectory = clusteredMuleContextProcessBuilder.testDirectory;
this.muleAppClass = clusteredMuleContextProcessBuilder.muleAppClass;
this.systemProperties = new HashMap<String, String>(clusteredMuleContextProcessBuilder.systemProperties);
}
public MuleContextProcessBuilder setApplicationConfigFile(String appConfigFile) {
this.systemProperties.put("configFile", appConfigFile);
return this;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return new MuleContextProcessBuilder(this);
}
public TestProcess buildInstance(int instanceId) {
MuleContextProcessBuilder clusteredMuleContextProcessBuilder = new MuleContextProcessBuilder(this);
clusteredMuleContextProcessBuilder.instanceId = String.valueOf(instanceId);
clusteredMuleContextProcessBuilder.addConfigurationAttribute(MULE_CONTEXT_CONFIGURATION_ID_KEY,
getMuleContextConfigurationId());
clusteredMuleContextProcessBuilder.addConfigurationAttribute(MuleProperties.MULE_HOME_DIRECTORY_PROPERTY,
getMuleHomeDirectoryFor(instanceId));
clusteredMuleContextProcessBuilder.addConfigurationAttribute(LOG_PORT_PROPERTY, freePortFinder.find().toString());
clusteredMuleContextProcessBuilder.addConfigurationAttribute(COMMAND_PORT_PROPERTY, freePortFinder.find().toString());
for (ProcessBuilderConfigurer processBuilderConfigurer : processBuilderConfigurers) {
processBuilderConfigurer.configure(clusteredMuleContextProcessBuilder.instanceId, clusteredMuleContextProcessBuilder);
}
return clusteredMuleContextProcessBuilder.build();
}
public String getMuleHomeDirectoryFor(int instanceId) {
return testDirectory.getAbsolutePath() + File.separator + "mule-home-" + instanceId;
}
private TestProcess build() {
List<String> command = new ArrayList<String>();
command.add("java");
command.add("-cp");
command.add(System.getProperty("java.class.path"));
if (Boolean.getBoolean("debug")) {
command.add("-Xdebug");
int debugPort = getDebugPort();
command.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=" + debugPort);
logger.info(String.format("To connect to process %s for debugging use port %d", instanceId, debugPort));
}
for (String systemPropertyKey : systemProperties.keySet()) {
command.add(String.format("-D%s=%s", systemPropertyKey, systemProperties.get(systemPropertyKey)));
}
if (muleAppClass == null) {
command.add("org.mule.test.infrastructure.process.MuleContextProcessApplication");
} else {
command.add(muleAppClass);
}
ProcessBuilder processBuilder = new ProcessBuilder(command);
try {
TestProcess testProcess = new TestProcess(instanceId, Integer.valueOf(systemProperties.get(LOG_PORT_PROPERTY)),
Integer.valueOf(systemProperties.get(COMMAND_PORT_PROPERTY)));
Process process = processBuilder.start();
testProcess.setProcess(process);
return testProcess;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private int getDebugPort() {
return (DEFAULT_DEBUG_PORT + Integer.valueOf(instanceId));
}
public String getMuleContextConfigurationId() {
return systemProperties.get(MULE_CONTEXT_CONFIGURATION_ID_KEY);
}
@Override
public ConfigurableProcessBuilder addConfigurationAttribute(String propertyName, String propertyValue) {
this.systemProperties.put(propertyName, propertyValue);
return this;
}
public MuleContextProcessBuilder addProcessBuilderConfigurer(ProcessBuilderConfigurer processBuilderConfigurer) {
processBuilderConfigurers.add(processBuilderConfigurer);
return this;
}
}