Author: [email protected]
Date: Mon Jun 4 14:54:04 2012
New Revision: 2431
Log:
[AMDATUCASSANDRA-191] Added configuration of the VM in which the external
Cassandra process is launched. Also improved auto cassandra download/install.
Added:
trunk/amdatu-cassandra/cassandra-launcher/src/main/resources/conf/log4j-server.properties
Modified:
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/LauncherConfigurationService.java
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/osgi/Activator.java
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/CompressionUtil.java
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/LauncherConfigurationServiceImpl.java
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/LauncherServiceImpl.java
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/ProcessStreamListenerImpl.java
trunk/amdatu-cassandra/config/src/main/resources/amdatu.cassandra.launcher.config.xml
Modified:
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/LauncherConfigurationService.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/LauncherConfigurationService.java
(original)
+++
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/LauncherConfigurationService.java
Mon Jun 4 14:54:04 2012
@@ -89,6 +89,51 @@
String CLUSTER_NAME = "clustername";
/**
+ * Configuration key for java options to start the JVM with.
+ */
+ String JAVA_OPTS = "java_opts";
+
+ /**
+ * Configuration key for system properties to start the JVM with.
+ */
+ String SYSTEM_PROPERTIES = "system_properties";
+
+ /**
+ * Configuration key for JMX port.
+ */
+ String JMX_PORT = "jmx_port";
+
+ /**
+ * Configuration key for enabling SSL in JMX.
+ */
+ String JMX_SSL = "jmx_ssl";
+
+ /**
+ * Configuration key for enabling authentication in JMX.
+ */
+ String JMX_AUTHENTICATE = "jmx_authenticate";
+
+ /**
+ * Configuration key for the Cassandra download version.
+ */
+ String DOWNLOAD_VERSION = "download_version";
+
+ /**
+ * Configuration key for the Cassandra download url.
+ */
+ String DOWNLOAD_URL = "download_url";
+
+ /**
+ * Configuration key for the installed Cassandra version.
+ */
+ String INSTALLED_VERSION = "installed_version";
+
+ /**
+ * Configuration key for the systemlog directory.
+ */
+ String SYSTEMLOG_DIR = "systemlog_dir";
+
+ /**
* Returns the RPC address to be used by Thrift clients.
*
* @return the RPC address.
@@ -115,14 +160,90 @@
* @return the name of the cluster that this node is part of.
*/
String getClustername();
-
+
+ /**
+ * Returns the Java options for the VM in which Cassandra is launched.
+ *
+ * @return the Java options for the VM in which Cassandra is launched.
+ */
+ String getJavaOpts();
+
+ /**
+ * Returns the system properties for the VM in which Cassandra is launched.
+ *
+ * @return the system properties for the VM in which Cassandra is launched.
+ */
+ String getSystemProperties();
+
+ /**
+ * Returns the port number to enable JMX on in the VM in which Cassandra
is launched.
+ * May be -1 in which case JMX is disabled.
+ *
+ * @return the port number to enable JMX on in the VM in which Cassandra
is launched or
+ * -1 if JMX disabled
+ */
+ int getJmxPort();
+
+ /**
+ * Returns if SSL is enabled for JMX in the VM in which Cassandra is
launched.
+ *
+ * @return true if SSL is enabled for JMX in the VM in which Cassandra is
launched, false otherwise.
+ */
+ boolean isJmxSsl();
+
+ /**
+ * Returns if authentication is enabled for JMX in the VM in which
Cassandra is launched.
+ *
+ * @return true if authentication is enabled for JMX in the VM in which
Cassandra is launched, false otherwise.
+ */
+ boolean isJmxAuthenticate();
+
+ /**
+ * Returns the installed Cassandra version (may be null).
+ *
+ * @return the installed Cassandra version (may be null).
+ */
+ String getInstalledVersion();
+
+ /**
+ * Updated the installed version (invoked after a successful update).
+ *
+ * @param version the new installed version.
+ */
+ void updateInstalledVersion(String version);
+
+ /**
+ * The URL to download and install the target version from.
+ *
+ * @return The URL to download and install the target version from.
+ */
+ String getDownloadUrl();
+
+ /**
+ * Returns the Cassandra version to download and install.
+ *
+ * @return the Cassandra version to download and install.
+ */
+ String getDownloadversion();
+
+ /**
+ * Returns if a Cassandra update is required. This is the case if
Cassandra is not yet installed or
+ * the installed version does not match the download_version.
+ *
+ * @return true if a Cassandra update is required, false otherwise.
+ */
+ boolean isUpdateRequired();
+
/**
* Writes a custom cassandra.yaml to the Cassandra installation, filled
with properties from
* Config Admin.
+ *
* @param targetFile Location of the target cassandra.yaml file
* @throws IOException
* @throws URISyntaxException
* @throws TemplateException
*/
void writeCassandraYaml(File targetFile) throws IOException,
URISyntaxException, TemplateException;
+
+ void writeLog4jServerProperties(File targetFile) throws IOException,
URISyntaxException, TemplateException;
}
Modified:
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/osgi/Activator.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/osgi/Activator.java
(original)
+++
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/osgi/Activator.java
Mon Jun 4 14:54:04 2012
@@ -49,6 +49,7 @@
.setImplementation(LauncherConfigurationServiceImpl.class)
.setInterface(LauncherConfigurationService.class.getName(),
null)
.add(createServiceDependency().setService(LogService.class).setRequired(true))
+
.add(createServiceDependency().setService(ConfigurationAdmin.class).setRequired(true))
.add(createConfigurationDependency().setPid(LauncherConfigurationService.PID)));
// Register the Cassandra launcher service
Modified:
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/CompressionUtil.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/CompressionUtil.java
(original)
+++
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/CompressionUtil.java
Mon Jun 4 14:54:04 2012
@@ -41,9 +41,9 @@
* @return the decompresses file
* @throws IOException
*/
- public static File decompressGz(File file) throws IOException {
+ public static File decompressGz(File file, File targetDir) throws
IOException {
String targetFileName = file.getName().substring(0,
file.getName().lastIndexOf(".gz"));
- File targetFile = new File(file.getParentFile().getAbsolutePath(),
targetFileName);
+ File targetFile = new File(targetDir.getAbsolutePath(),
targetFileName);
GzipCompressorInputStream gzin = null;
FileOutputStream fos = null;
try {
@@ -78,9 +78,9 @@
* @return Directory containing the decompressed files
* @throws IOException
*/
- public static File decompressTar(File file) throws IOException {
+ public static File decompressTar(File file, File dir) throws IOException {
String targetFileName = file.getName().substring(0,
file.getName().lastIndexOf(".tar"));
- File targetDir = new File(file.getParentFile().getAbsolutePath(),
targetFileName);
+ File targetDir = new File(dir.getAbsolutePath(), targetFileName);
targetDir.mkdir();
TarArchiveInputStream tis = null;
try {
Modified:
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/LauncherConfigurationServiceImpl.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/LauncherConfigurationServiceImpl.java
(original)
+++
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/LauncherConfigurationServiceImpl.java
Mon Jun 4 14:54:04 2012
@@ -36,8 +36,9 @@
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.ServiceDependency;
-import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.log.LogService;
@@ -50,18 +51,34 @@
public class LauncherConfigurationServiceImpl implements
LauncherConfigurationService, ManagedService {
// Statics
private static final String STORAGE_CONF_SOURCE = "conf/cassandra.yaml";
+ private static final String LOG4J_SERVER_PROPERTIES =
"conf/log4j-server.properties";
// (Reasonable) defaults
private static final int DEFAULT_RPC_PORT = 9160;
private static final int DEFAULT_STORAGE_PORT = 9160;
private static final String DEFAULT_LISTEN_ADDRESS = "127.0.0.1";
private static final String DEFAULT_CLUSTER_NAME = "Amdatu Cluster";
+ private static final String DEFAULT_JAVA_OPTS = ""
+ + "-Xms1G -Xmx1G -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParNewGC "
+ + "-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
-XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1 "
+ + "-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly";
+ private static final String DEFAULT_SYSTEM_PROPERTIES = ""
+ + "-Dlog4j.configuration=log4j-server.properties
-Dlog4j.defaultInitOverride=true "
+ + "-Dcassandra -Dcassandra-foreground=yes";
+ private static final int DEFAULT_JMX_PORT = -1; // -1 means disabled
+ private static boolean DEFAULT_JMX_SSL = false;
+ private static boolean DEFAULT_JMX_AUTHENTICATE = false;
+ private static String DEFAULT_COMMITLOG_DIR = "work/cassandra/commitlog";
+ private static String DEFAULT_DATAFILE_DIR = "work/cassandra/data";
+ private static String DEFAULT_SAVEDCACHED_DIR =
"work/cassandra/saved_caches";
+ private static String DEFAULT_SYSTEMLOG_DIR = "work/cassandra/log";
// Reference to the LogService
private volatile LogService m_logService;
private volatile TemplateEngine m_templateEngine;
private volatile BundleContext m_bundleContext;
private volatile DependencyManager m_dm;
+ private volatile ConfigurationAdmin m_configAdmin;
// Private members
@SuppressWarnings("rawtypes")
@@ -70,6 +87,18 @@
private int m_rpcPort;
private int m_storagePort;
private String m_clusterName;
+ private String m_javaOpts;
+ private String m_systemProperties;
+ private int m_jmxPort;
+ private boolean m_jmxSsl;
+ private boolean m_jmxAuthenticate;
+ private String m_downloadVersion;
+ private String m_downloadUrl;
+ private String m_installedVersion;
+ private String m_commitLogDir;
+ private String m_dataFileDir;
+ private String m_savedCachesDir;
+ private String m_systemLogDirectory;
/**
* The init() method is invoked by the Felix dependency manager. It allows
us to initialize our service.
@@ -94,9 +123,13 @@
public void updated(final Dictionary dictionary) throws
ConfigurationException {
if (dictionary != null) {
m_properties = dictionary;
+ // FIXME: workdir can be removed????
if (dictionary.get(CONFIG_WORKDIR) == null) {
throw new ConfigurationException("Missing configuration key",
CONFIG_WORKDIR);
}
+ m_commitLogDir = getString(dictionary, COMMITLOG_DIR,
DEFAULT_COMMITLOG_DIR);
+ m_dataFileDir = getString(dictionary, DATAFILE_DIR,
DEFAULT_DATAFILE_DIR);
+ m_savedCachesDir = getString(dictionary, SAVEDCACHES_DIR,
DEFAULT_SAVEDCACHED_DIR);
m_rpcAddress = getString(dictionary, RPC_ADDRESS, "");
if (m_rpcAddress.isEmpty()) {
m_rpcAddress = getString(dictionary, LISTEN_ADDRESS,
DEFAULT_LISTEN_ADDRESS);
@@ -104,6 +137,17 @@
m_rpcPort = getInt(dictionary, RPC_PORT, DEFAULT_RPC_PORT, true);
m_storagePort = getInt(dictionary, STORAGE_PORT,
DEFAULT_STORAGE_PORT, true);
m_clusterName = getString(dictionary, CLUSTER_NAME,
DEFAULT_CLUSTER_NAME);
+ m_javaOpts = getString(dictionary, JAVA_OPTS, DEFAULT_JAVA_OPTS);
+ m_systemProperties = getString(dictionary, SYSTEM_PROPERTIES,
DEFAULT_SYSTEM_PROPERTIES);
+ m_jmxPort = getInt(dictionary, JMX_PORT, DEFAULT_JMX_PORT, false);
+ m_jmxSsl = getBoolean(dictionary, JMX_SSL, DEFAULT_JMX_SSL, false);
+ m_jmxAuthenticate = getBoolean(dictionary, JMX_AUTHENTICATE,
DEFAULT_JMX_AUTHENTICATE, false);
+ // FIXME: temp fix, config files not picked up using old
fileinstall
+ m_downloadVersion = "1.1.0"; // getString(dictionary,
DOWNLOAD_VERSION, null);
+ m_downloadUrl =
"http://apache.cs.uu.nl/dist/cassandra/1.1.0/apache-cassandra-1.1.0-bin.tar.gz";
+ // getString(dictionary, DOWNLOAD_URL, null);
+ m_installedVersion = getString(dictionary, INSTALLED_VERSION,
null);
+ m_systemLogDirectory = getString(dictionary, SYSTEMLOG_DIR,
DEFAULT_SYSTEMLOG_DIR);
}
}
@@ -119,6 +163,21 @@
}
@SuppressWarnings("rawtypes")
+ private boolean getBoolean(final Dictionary dictionary, final String key,
final boolean defaultValue,
+ final boolean log) {
+ Object value = dictionary.get(key);
+ if (value == null) {
+ if (log) {
+ String msg =
+ "No value set for property '" + key + "', switching to
default value '" + defaultValue + "'";
+ log(msg);
+ }
+ return defaultValue;
+ }
+ return "true".equalsIgnoreCase(value.toString().trim());
+ }
+
+ @SuppressWarnings("rawtypes")
private int getInt(final Dictionary dictionary, final String key, final
int defaultValue, final boolean log) {
Object value = dictionary.get(key);
if (value == null) {
@@ -157,11 +216,66 @@
return m_clusterName;
}
+ public String getJavaOpts() {
+ return m_javaOpts;
+ }
+
+ public String getSystemProperties() {
+ return m_systemProperties;
+ }
+
+ public int getJmxPort() {
+ return m_jmxPort;
+ }
+
+ public boolean isJmxSsl() {
+ return m_jmxSsl;
+ }
+
+ public boolean isJmxAuthenticate() {
+ return m_jmxAuthenticate;
+ }
+
+ public String getDownloadUrl() {
+ return m_downloadUrl;
+ }
+
+ public String getDownloadversion() {
+ return m_downloadVersion;
+ }
+
+ public String getInstalledVersion() {
+ return m_installedVersion;
+ }
+
+ public boolean isUpdateRequired() {
+ if (m_installedVersion == null ||
!m_installedVersion.trim().equals(m_downloadVersion.trim())) {
+ return true;
+ }
+
+ // If installed version is not null and equals download version,
verify that the directory exists
+ File cassandraHome = m_bundleContext.getDataFile("cassandra-" +
m_installedVersion);
+ return !cassandraHome.exists();
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public void updateInstalledVersion(String version) {
+ try {
+ Configuration config =
m_configAdmin.getConfiguration(LauncherConfigurationService.PID);
+ Dictionary properties = config.getProperties();
+ properties.put(INSTALLED_VERSION, version);
+ config.update(properties);
+ m_installedVersion = version;
+ }
+ catch (IOException e) {
+ m_logService.log(LogService.LOG_ERROR, "Could not update
installed_version.", e);
+ }
+ }
+
@SuppressWarnings("rawtypes")
public void writeCassandraYaml(File targetFile) throws IOException,
URISyntaxException, TemplateException {
// Create & fill the context
TemplateContext context = m_templateEngine.createContext();
- File sourceFile = new
File(targetFile.getParentFile().getAbsolutePath(), targetFile.getName() +
".tmp");
// Copy all properties from config admin
Enumeration keys = m_properties.keys();
@@ -171,12 +285,38 @@
context.put(key.toString(), value.toString());
}
+ // Overrule dirs to append workdir (one directory up)
+ String workDir = m_bundleContext.getDataFile("").getAbsolutePath();
+ context.put(COMMITLOG_DIR, (workDir + File.separator +
m_commitLogDir).replace("\\", "/"));
+ context.put(DATAFILE_DIR, (workDir + File.separator +
m_dataFileDir).replace("\\", "/"));
+ context.put(SAVEDCACHES_DIR, (workDir + File.separator +
m_savedCachesDir).replace("\\", "/"));
+
+ // Let the velocity processor replace the config entries and write the
result
+ processConfigFile(STORAGE_CONF_SOURCE, targetFile, context);
+ }
+
+ public void writeLog4jServerProperties(File targetFile) throws
IOException, URISyntaxException, TemplateException {
+ // Create & fill the context
+ TemplateContext context = m_templateEngine.createContext();
+ String workDir = m_bundleContext.getDataFile("").getAbsolutePath();
+ String dir =
+ (workDir + File.separator + m_systemLogDirectory + File.separator
+ "system.log").replace("\\", "/");
+ context.put(SYSTEMLOG_DIR, dir);
+
+ // Set system_log dir property
+ processConfigFile(LOG4J_SERVER_PROPERTIES, targetFile, context);
+ }
+
+ private void processConfigFile(String sourceConfig, File targetFile,
TemplateContext context)
+ throws TemplateException,
+ IOException {
// First write the source file to a temporary file
- Bundle bundle = m_bundleContext.getBundle();
- toTempFile(bundle.getResource(STORAGE_CONF_SOURCE), sourceFile);
+ File sourceFile = new
File(targetFile.getParentFile().getAbsolutePath(), targetFile.getName() +
".tmp");
+ URL sourceURL = m_bundleContext.getBundle().getResource(sourceConfig);
+ toTempFile(sourceURL, sourceFile);
// Create the processor using an input file
- TemplateProcessor processor =
m_templateEngine.createProcessor(bundle.getResource(STORAGE_CONF_SOURCE));
+ TemplateProcessor processor =
m_templateEngine.createProcessor(sourceURL);
// Process the input file and write the result to an output file
processor.generateFile(context, targetFile);
@@ -185,7 +325,8 @@
sourceFile.delete();
m_logService
- .log(LogService.LOG_INFO, "Cassandra.yaml written successfully to
'" + targetFile.getAbsolutePath());
+ .log(LogService.LOG_INFO, "Config file '" + targetFile.getName() +
"' successfully written to '"
+ + targetFile.getAbsolutePath());
}
private void toTempFile(URL url, File targetFile) throws IOException {
Modified:
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/LauncherServiceImpl.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/LauncherServiceImpl.java
(original)
+++
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/LauncherServiceImpl.java
Mon Jun 4 14:54:04 2012
@@ -24,8 +24,10 @@
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
+import java.util.List;
import org.apache.ace.processlauncher.ProcessLauncherService;
import org.apache.commons.io.FileUtils;
@@ -42,12 +44,6 @@
*/
@SuppressWarnings("unchecked")
public class LauncherServiceImpl {
- // FIXME: this URL should be configurable. This service should become a
ManagedService
- // with some new PID like 'org.amdatu.cassandra.launcher' providing all
config properties
- // for the externally launched cassandra.
- private static final String DOWNLOAD_URL =
-
"http://apache.cs.uu.nl/dist/cassandra/1.1.0/apache-cassandra-1.1.0-bin.tar.gz";
-
private volatile BundleContext m_bundleContext;
private volatile LogService m_logService;
private volatile ConfigurationAdmin m_configAdmin;
@@ -57,50 +53,36 @@
@SuppressWarnings("rawtypes")
public void start() {
- m_logService.log(LogService.LOG_INFO, "Starting Cassandra
instance...");
File dir = m_bundleContext.getDataFile("");
// Step 1. Install and configure Cassandra
// Step 1a. Find the cassandra.bat. If it is not found, we assume
Cassandra is not yet installed
// and we install it
- if (findFile(dir, "cassandra.bat") == null) {
- // Step 1b. Download and unzip the Cassandra distribution
- try {
- File downloadedFile = download(dir);
- decompress(downloadedFile);
+ if (m_configService.isUpdateRequired()) {
+ if (installUpdate()) {
+ // Step 1b. Update installed version
+
m_configService.updateInstalledVersion(m_configService.getDownloadversion());
}
- catch (IOException e) {
- m_logService.log(LogService.LOG_ERROR, "Unable to download and
decompress file from '" + DOWNLOAD_URL
- + "', Cassandra could not be started.", e);
+ else {
+ // Update failed, log error and exit
+ m_logService.log(LogService.LOG_ERROR,
+ "Installation of Cassandra version '" +
m_configService.getDownloadversion()
+ + "' failed. Cassandr acould not be started.");
return;
- }
-
- // Step 1c. Find the cassandra.yaml and update it
- File yaml = findFile(dir, "cassandra.yaml");
- try {
- m_configService.writeCassandraYaml(yaml);
- }
- catch (IOException e) {
- m_logService.log(LogService.LOG_ERROR, "Unable to update
cassandra.yaml", e);
- }
- catch (URISyntaxException e) {
- m_logService.log(LogService.LOG_ERROR, "Unable to update
cassandra.yaml", e);
- }
- catch (TemplateException e) {
- m_logService.log(LogService.LOG_ERROR, "Unable to update
cassandra.yaml", e);
- }
+ }
}
+ else {
+ m_logService.log(LogService.LOG_INFO, "Existing Cassandra
installation found. Installed version: "
+ + m_configService.getInstalledVersion());
+ }
+
+ // The target directory is 'cassandra-[installed_version]'
+ String installedVersion = m_configService.getInstalledVersion();
+ File cassandraHome = new File(dir, "cassandra-" + installedVersion);
// Step 2. Run Cassandra
// Step 2a. Setup the configuration to deploy to the Ace process
launcher
- File executable;
- if (File.separator.equals("\\")) {
- executable = findFile(dir, "cassandra.bat");
- }
- else {
- executable = findFile(dir, "cassandra.bat");
- }
- File cassandraHome = executable.getParentFile().getParentFile();
+
String exe = buildExecutable(cassandraHome.getAbsolutePath());
Dictionary properties = new Hashtable();
@@ -114,11 +96,16 @@
// Deploy the config
try {
+ m_logService.log(LogService.LOG_INFO, "Launching Cassandra...");
+ m_logService.log(LogService.LOG_DEBUG, "Executable command:");
+ m_logService.log(LogService.LOG_DEBUG, exe);
m_config =
m_configAdmin.createFactoryConfiguration(ProcessLauncherService.PID, null);
m_config.update(properties);
+ m_logService.log(LogService.LOG_INFO, "Cassandra launched
successfully.");
}
catch (IOException e) {
- m_logService.log(LogService.LOG_ERROR, "Unable to deploy
configuration to ace process launcher", e);
+ m_logService.log(LogService.LOG_ERROR,
+ "Unable to deploy configuration to ace process launcher.
Cassandra could not be launched.", e);
}
}
@@ -127,6 +114,7 @@
if (m_config != null) {
try {
m_config.delete();
+ m_logService.log(LogService.LOG_INFO, "Cassandra stopped
successfully.");
}
catch (IOException e) {
m_logService.log(LogService.LOG_ERROR, "Could not stop
Cassandra", e);
@@ -134,24 +122,103 @@
}
}
- private File download(File targetDir) throws IOException {
- String fileName =
DOWNLOAD_URL.substring(DOWNLOAD_URL.lastIndexOf("/"));
+ private boolean installUpdate() {
+ // Step 1b. Log info about the update
+ File dir = m_bundleContext.getDataFile("");
+ String downloadUrl = m_configService.getDownloadUrl();
+ String downloadVersion = m_configService.getDownloadversion();
+ String installedVersion = m_configService.getInstalledVersion();
+ String msg = "Cassandra update required. Installed version: ";
+ if (installedVersion == null) {
+ msg += "[none], ";
+ }
+ else {
+ msg += installedVersion + ", ";
+ }
+ msg += "target version: " + downloadVersion + ".";
+ m_logService.log(LogService.LOG_INFO, msg);
+
+ m_logService.log(LogService.LOG_INFO, "Downloading Cassandra from '" +
downloadUrl + "'...");
+
+ // Step 1c. Download and unzip the Cassandra distribution
+ try {
+ File downloadedFile = download(downloadUrl, dir);
+ m_logService.log(LogService.LOG_INFO, "Download finished
successfully.");
+ m_logService.log(LogService.LOG_INFO, "Deflating file...");
+
+ // The tmp directory is 'cassandra-[installed_version]-tmp'
+ File tmpDir = new File(dir, "cassandra-" + downloadVersion +
"-tmp");
+ tmpDir.mkdirs();
+ File deflatedDir = decompress(downloadedFile, tmpDir);
+
+ // Now move the deflated stuff to the proper directory
+ File srcDir = findFile(deflatedDir,
"cassandra.bat").getParentFile().getParentFile();
+
+ // The target directory is 'cassandra-[installed_version]'
+ File targetDir = new File(dir, "cassandra-" + downloadVersion);
+ srcDir.renameTo(targetDir);
+ FileUtils.deleteDirectory(tmpDir);
+ m_logService.log(LogService.LOG_INFO, "Deflating finished
successfully.");
+ }
+ catch (IOException e) {
+ m_logService.log(LogService.LOG_ERROR, "Unable to download and
decompress file from '" + downloadUrl
+ + "', Cassandra could not be started.", e);
+ return false;
+ }
+
+ // Step 1d. Find the cassandra.yaml and log4jserver.properties files
and update them
+ try {
+ File yaml = findFile(dir, "cassandra.yaml");
+ m_logService.log(LogService.LOG_INFO, "Updating
cassandra.yaml...");
+ m_configService.writeCassandraYaml(yaml);
+ m_logService.log(LogService.LOG_INFO, "Cassandra.yaml updated
successfully.");
+
+ File log4j = findFile(dir, "log4j-server.properties");
+ m_logService.log(LogService.LOG_INFO, "Updating
log4j-server.properties...");
+ m_configService.writeLog4jServerProperties(log4j);
+ m_logService.log(LogService.LOG_INFO, "log4j-server.properties
updated successfully.");
+ }
+ catch (IOException e) {
+ m_logService.log(LogService.LOG_ERROR, "Unable to update
configuration file.", e);
+ return false;
+ }
+ catch (URISyntaxException e) {
+ m_logService.log(LogService.LOG_ERROR, "Unable to update
configuration file.", e);
+ return false;
+ }
+ catch (TemplateException e) {
+ m_logService.log(LogService.LOG_ERROR, "Unable to update
configuration file.", e);
+ return false;
+ }
+
+ // If we reach this code, update is a complete success
+ return true;
+ }
+
+ private File download(String sDownloadUrl, File targetDir) throws
IOException {
+ String fileName =
sDownloadUrl.substring(sDownloadUrl.lastIndexOf("/"));
File targetFile = new File(targetDir, fileName);
- URL downloadUrl = new URL(DOWNLOAD_URL);
- m_logService.log(LogService.LOG_INFO, "Downloading '" + DOWNLOAD_URL +
"' to '" + targetFile.getAbsolutePath()
+ URL downloadUrl = new URL(sDownloadUrl);
+ m_logService.log(LogService.LOG_INFO, "Downloading '" + sDownloadUrl +
"' to '" + targetFile.getAbsolutePath()
+ "'");
FileUtils.copyURLToFile(downloadUrl, targetFile);
m_logService.log(LogService.LOG_INFO, "File downloaded successfully");
return targetFile;
}
- private File decompress(File file) throws IOException {
+ private File decompress(File file, File targetDir) throws IOException {
File currentFile = file;
+ List<File> deleteFiles = new ArrayList<File>();
if (currentFile.getName().endsWith(".tar.gz")) {
- currentFile = CompressionUtil.decompressGz(currentFile);
+ deleteFiles.add(currentFile);
+ currentFile = CompressionUtil.decompressGz(currentFile, targetDir);
}
if (currentFile.getName().endsWith(".tar")) {
- currentFile = CompressionUtil.decompressTar(currentFile);
+ deleteFiles.add(currentFile);
+ currentFile = CompressionUtil.decompressTar(currentFile,
targetDir);
+ }
+ for (File deleteFile : deleteFiles) {
+ deleteFile.delete();
}
return currentFile;
}
@@ -177,23 +244,35 @@
}
private String buildExecutable(String cassandraHome) {
- // FIXME: all these options should be configurable. This service
should become a ManagedService
- // with some new PID like 'org.amdatu.cassandra.launcher' providing
all config properties
- // for the externally launched cassandra.
+ String javaOpts = m_configService.getJavaOpts();
+ String systemProperties = m_configService.getSystemProperties();
+ int jmxPort = m_configService.getJmxPort();
+ String jmx = null;
+ if (jmxPort != -1) {
+ jmx = "-Dcom.sun.management.jmxremote.port=" + jmxPort;
+ jmx += " -Dcom.sun.management.jmxremote.ssl=" +
m_configService.isJmxSsl();
+ jmx += " -Dcom.sun.management.jmxremote.authenticate=" +
m_configService.isJmxAuthenticate();
+ }
+
+ // Prepare java executable command
String sep = File.separator;
String javaHome = System.getProperty("java.home");
StringBuffer exe = new StringBuffer();
exe.append("\"" + javaHome + sep + "bin" + sep + "java" + "\" "); //
java executable
- exe.append("-ea -javaagent:" + cassandraHome + sep + "lib" + sep +
"jamm-0.2.5.jar "); // javaagent
- exe.append("-Xms1G -Xmx1G -XX:+HeapDumpOnOutOfMemoryError "); // heap
- exe.append("-XX:+UseParNewGC -XX:+UseConcMarkSweepGC "); // garbage
collector
- exe.append("-XX:+CMSParallelRemarkEnabled -XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=1 ");
- exe.append("-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly ");
- exe.append("-Dcom.sun.management.jmxremote.port=7199
-Dcom.sun.management.jmxremote.ssl=false "); // JMX
- exe.append("-Dcom.sun.management.jmxremote.authenticate=false ");
- exe.append("-Dlog4j.configuration=log4j-server.properties
-Dlog4j.defaultInitOverride=true "); // log4j
- exe.append("-Dcassandra -Dcassandra-foreground=yes "); // cassandra
opts
- exe.append("-cp " + buildClasspath(cassandraHome));
+ exe.append("-ea -javaagent:\"" + cassandraHome + sep + "lib" + sep +
"jamm-0.2.5.jar\""); // javaagent
+
+ // Append java options
+ exe.append(" " + javaOpts);
+
+ // Append system properties
+ exe.append(" " + systemProperties);
+
+ // Append JMX options
+ if (jmx != null) {
+ exe.append(" " + jmx);
+ }
+
+ exe.append(" -cp " + buildClasspath(cassandraHome));
exe.append(" \"org.apache.cassandra.thrift.CassandraDaemon\"");
return exe.toString();
}
Modified:
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/ProcessStreamListenerImpl.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/ProcessStreamListenerImpl.java
(original)
+++
trunk/amdatu-cassandra/cassandra-launcher/src/main/java/org/amdatu/cassandra/launcher/service/ProcessStreamListenerImpl.java
Mon Jun 4 14:54:04 2012
@@ -49,7 +49,9 @@
}
private void dispatchInput() {
- // FIXME: output should be disptached to LogService instead of
System.out
+ // FIXME: output should be dispatched to LogService instead of
System.out but that will
+ // be difficult since this class is instantiated by the launcher. For
now we dispatch simply
+ // to System.out
new Thread(new Runnable() {
public void run() {
try {
Added:
trunk/amdatu-cassandra/cassandra-launcher/src/main/resources/conf/log4j-server.properties
==============================================================================
--- (empty file)
+++
trunk/amdatu-cassandra/cassandra-launcher/src/main/resources/conf/log4j-server.properties
Mon Jun 4 14:54:04 2012
@@ -0,0 +1,44 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# for production, you should probably set pattern to %c instead of %l.
+# (%l is slower.)
+
+# output messages into a rolling log file as well as stdout
+log4j.rootLogger=INFO,stdout,R
+
+# stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%5p %d{HH:mm:ss,SSS} %m%n
+
+# rolling log file
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.maxFileSize=20MB
+log4j.appender.R.maxBackupIndex=50
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern=%5p [%t] %d{ISO8601} %F (line %L)
%m%n
+# Edit the next line to point to your logs directory
+log4j.appender.R.File=${systemlog_dir}
+
+# Application logging options
+#log4j.logger.org.apache.cassandra=DEBUG
+#log4j.logger.org.apache.cassandra.db=DEBUG
+#log4j.logger.org.apache.cassandra.service.StorageProxy=DEBUG
+
+# Adding this to avoid thrift logging disconnect errors.
+log4j.logger.org.apache.thrift.server.TNonblockingServer=ERROR
+
Modified:
trunk/amdatu-cassandra/config/src/main/resources/amdatu.cassandra.launcher.config.xml
==============================================================================
---
trunk/amdatu-cassandra/config/src/main/resources/amdatu.cassandra.launcher.config.xml
(original)
+++
trunk/amdatu-cassandra/config/src/main/resources/amdatu.cassandra.launcher.config.xml
Mon Jun 4 14:54:04 2012
@@ -12,6 +12,18 @@
<AD id="rpc_address" type="STRING" cardinality="0" />
<AD id="rpc_port" type="STRING" cardinality="0" />
<AD id="storage_port" type="STRING" cardinality="0" />
+
+ <AD id="java_opts" type="STRING" cardinality="0" />
+ <AD id="system_properties" type="STRING" cardinality="0" />
+ <AD id="jmx_port" type="INTEGER" cardinality="0" default="7199"/>
+ <AD id="jmx_ssl" type="BOOLEAN" cardinality="0" default="false"/>
+ <AD id="jmx_authenticate" type="BOOLEAN" cardinality="0" default="false"/>
+
+ <AD id="installed_version" type="STRING" cardinality="0"/>
+ <AD id="download_version" type="STRING" cardinality="0" />
+ <AD id="download_url" type="STRING" cardinality="0" />
+
+ <AD id="systemlog_dir" type="STRING" cardinality="0" />
</OCD>
<Designate pid="org.amdatu.cassandra.launcher" bundle="*">
<Object ocdref="org.amdatu.cassandra.launcher">
@@ -48,6 +60,36 @@
<Attribute adref="storage_port">
<Value>7000</Value>
</Attribute>
+
+ <Attribute adref="java_opts">
+ <Value>-Xms1G -Xmx1G -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParNewGC
-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=1 -XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly</Value>
+ </Attribute>
+ <Attribute adref="system_properties">
+ <Value>-Dlog4j.configuration=log4j-server.properties
-Dlog4j.defaultInitOverride=true -Dcassandra -Dcassandra-foreground=yes</Value>
+ </Attribute>
+ <Attribute adref="jmx_port">
+ <Value>-1</Value>
+ </Attribute>
+ <Attribute adref="jmx_ssl">
+ <Value>false</Value>
+ </Attribute>
+ <Attribute adref="jmx_authenticate">
+ <Value>false</Value>
+ </Attribute>
+
+ <Attribute adref="installed_version">
+ <Value></Value>
+ </Attribute>
+ <Attribute adref="download_version">
+ <Value>1.1.0</Value>
+ </Attribute>
+ <Attribute adref="download_url">
+
<Value>http://apache.cs.uu.nl/dist/cassandra/1.1.0/apache-cassandra-1.1.0-bin.tar.gz</Value>
+ </Attribute>
+
+ <Attribute adref="systemlog_dir">
+ <Value>work/cassandra/log</Value>
+ </Attribute>
</Object>
</Designate>
</MetaData>
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits