You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whirr.apache.org by fr...@apache.org on 2012/05/09 13:18:49 UTC

svn commit: r1336098 - in /whirr/trunk: ./ core/src/main/java/org/apache/whirr/util/ core/src/main/resources/functions/ recipes/ services/solr/ services/solr/src/ services/solr/src/main/ services/solr/src/main/java/ services/solr/src/main/java/org/ ser...

Author: frankscholten
Date: Wed May  9 11:18:48 2012
New Revision: 1336098

URL: http://svn.apache.org/viewvc?rev=1336098&view=rev
Log:
WHIRR-465. Add solr as a service

Added:
    whirr/trunk/core/src/main/java/org/apache/whirr/util/Tarball.java
    whirr/trunk/core/src/main/resources/functions/install_tarball_no_md5.sh
    whirr/trunk/recipes/solr-ec2.properties
    whirr/trunk/services/solr/
    whirr/trunk/services/solr/pom.xml
    whirr/trunk/services/solr/src/
    whirr/trunk/services/solr/src/main/
    whirr/trunk/services/solr/src/main/java/
    whirr/trunk/services/solr/src/main/java/org/
    whirr/trunk/services/solr/src/main/java/org/apache/
    whirr/trunk/services/solr/src/main/java/org/apache/whirr/
    whirr/trunk/services/solr/src/main/java/org/apache/whirr/service/
    whirr/trunk/services/solr/src/main/java/org/apache/whirr/service/solr/
    whirr/trunk/services/solr/src/main/java/org/apache/whirr/service/solr/SolrClusterActionHandler.java
    whirr/trunk/services/solr/src/main/resources/
    whirr/trunk/services/solr/src/main/resources/META-INF/
    whirr/trunk/services/solr/src/main/resources/META-INF/services/
    whirr/trunk/services/solr/src/main/resources/META-INF/services/org.apache.whirr.service.ClusterActionHandler
    whirr/trunk/services/solr/src/main/resources/functions/
    whirr/trunk/services/solr/src/main/resources/functions/configure_solr.sh
    whirr/trunk/services/solr/src/main/resources/functions/install_solr.sh
    whirr/trunk/services/solr/src/main/resources/functions/start_solr.sh
    whirr/trunk/services/solr/src/main/resources/functions/stop_solr.sh
    whirr/trunk/services/solr/src/main/resources/whirr-solr-default.properties
    whirr/trunk/services/solr/src/test/
    whirr/trunk/services/solr/src/test/java/
    whirr/trunk/services/solr/src/test/java/org/
    whirr/trunk/services/solr/src/test/java/org/apache/
    whirr/trunk/services/solr/src/test/java/org/apache/whirr/
    whirr/trunk/services/solr/src/test/java/org/apache/whirr/service/
    whirr/trunk/services/solr/src/test/java/org/apache/whirr/service/solr/
    whirr/trunk/services/solr/src/test/java/org/apache/whirr/service/solr/integration/
    whirr/trunk/services/solr/src/test/java/org/apache/whirr/service/solr/integration/SolrServiceTest.java
    whirr/trunk/services/solr/src/test/resources/
    whirr/trunk/services/solr/src/test/resources/conf/
    whirr/trunk/services/solr/src/test/resources/conf/core0/
    whirr/trunk/services/solr/src/test/resources/conf/core0/conf/
    whirr/trunk/services/solr/src/test/resources/conf/core0/conf/schema.xml
    whirr/trunk/services/solr/src/test/resources/conf/core0/conf/solrconfig.xml
    whirr/trunk/services/solr/src/test/resources/conf/solr.xml
    whirr/trunk/services/solr/src/test/resources/log4j.xml
    whirr/trunk/services/solr/src/test/resources/whirr-solr-test.properties
Modified:
    whirr/trunk/CHANGES.txt

Modified: whirr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/whirr/trunk/CHANGES.txt?rev=1336098&r1=1336097&r2=1336098&view=diff
==============================================================================
--- whirr/trunk/CHANGES.txt (original)
+++ whirr/trunk/CHANGES.txt Wed May  9 11:18:48 2012
@@ -4,6 +4,8 @@ Trunk (unreleased changes)
 
   NEW FEATURES
 
+    WHIRR-465. Add Solr as a service.
+
     WHIRR-500. Let users control which hardware is used for each 
     instance template (Karel Vervaeke via asavu)
 

Added: whirr/trunk/core/src/main/java/org/apache/whirr/util/Tarball.java
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/util/Tarball.java?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/util/Tarball.java (added)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/util/Tarball.java Wed May  9 11:18:48 2012
@@ -0,0 +1,108 @@
+/**
+ * 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.
+ */
+
+package org.apache.whirr.util;
+
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.io.IOUtils;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Tarball utility.
+ */
+public class Tarball {
+
+  /**
+   * Creates a tarball from the source directory and writes it into the target directory.
+   *
+   * @param sourceDirectory directory whose files will be added to the tarball
+   * @param targetName      directory where tarball will be written to
+   * @throws IOException when an exception occurs on creating the tarball
+   */
+  public static void createFromDirectory(String sourceDirectory, String targetName) throws IOException {
+    FileOutputStream fileOutputStream = null;
+    BufferedOutputStream bufferedOutputStream = null;
+    GzipCompressorOutputStream gzipOutputStream = null;
+    TarArchiveOutputStream tarArchiveOutputStream = null;
+
+    try {
+      fileOutputStream = new FileOutputStream(new File(targetName));
+      bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
+      gzipOutputStream = new GzipCompressorOutputStream(bufferedOutputStream);
+      tarArchiveOutputStream = new TarArchiveOutputStream(gzipOutputStream);
+
+      addFilesInDirectory(tarArchiveOutputStream, sourceDirectory);
+    } finally {
+      if (tarArchiveOutputStream != null) {
+        tarArchiveOutputStream.finish();
+      }
+      if (tarArchiveOutputStream != null) {
+        tarArchiveOutputStream.close();
+      }
+      if (gzipOutputStream != null) {
+        gzipOutputStream.close();
+      }
+      if (bufferedOutputStream != null) {
+        bufferedOutputStream.close();
+      }
+      if (fileOutputStream != null) {
+        fileOutputStream.close();
+      }
+    }
+  }
+
+  private static void addFilesInDirectory(TarArchiveOutputStream tarOutputStream, String path) throws IOException {
+    File file = new File(path);
+    File[] children = file.listFiles();
+
+    if (children != null) {
+      for (File child : children) {
+        addFile(tarOutputStream, child.getAbsolutePath(), "/");
+      }
+    }
+  }
+
+  private static void addFile(TarArchiveOutputStream tarOutputStream, String path, String base) throws IOException {
+    File file = new File(path);
+    String entryName = base + file.getName();
+    TarArchiveEntry tarEntry = new TarArchiveEntry(file, entryName);
+
+    tarOutputStream.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
+    tarOutputStream.putArchiveEntry(tarEntry);
+
+    if (file.isFile()) {
+      IOUtils.copy(new FileInputStream(file), tarOutputStream);
+      tarOutputStream.closeArchiveEntry();
+    } else {
+      tarOutputStream.closeArchiveEntry();
+      File[] children = file.listFiles();
+      if (children != null) {
+        for (File child : children) {
+          addFile(tarOutputStream, child.getAbsolutePath(), entryName + "/");
+        }
+      }
+    }
+  }
+}

Added: whirr/trunk/core/src/main/resources/functions/install_tarball_no_md5.sh
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/resources/functions/install_tarball_no_md5.sh?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/core/src/main/resources/functions/install_tarball_no_md5.sh (added)
+++ whirr/trunk/core/src/main/resources/functions/install_tarball_no_md5.sh Wed May  9 11:18:48 2012
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+function install_tarball_no_md5() {
+  if [[ "$1" != "" ]]; then
+    # Download a .tar.gz file and extract to target dir
+
+    local tar_url=$1
+    local tar_file=`basename $tar_url`
+
+    local target=${2:-/usr/local/}
+    mkdir -p $target
+
+    local curl="curl -L --silent --show-error --fail --connect-timeout 10 --max-time 600 --retry 5"
+    # any download should take less than 10 minutes
+
+    for retry_count in `seq 1 3`;
+    do
+      $curl -O $tar_url || true
+
+      if [ ! $retry_count -eq "3" ]; then
+        sleep 10
+      fi
+    done
+
+    if [ ! -e $tar_file ]; then
+      echo "Failed to download $tar_file. Aborting."
+      exit 1
+    fi
+
+    tar xzf $tar_file -C $target
+    rm -f $tar_file
+  fi
+}

Added: whirr/trunk/recipes/solr-ec2.properties
URL: http://svn.apache.org/viewvc/whirr/trunk/recipes/solr-ec2.properties?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/recipes/solr-ec2.properties (added)
+++ whirr/trunk/recipes/solr-ec2.properties Wed May  9 11:18:48 2012
@@ -0,0 +1,32 @@
+#   Licensed 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.
+#
+whirr.cluster-name=solr
+whirr.instance-templates=1 solr
+
+# Solr specifics
+whirr.solr.jetty.port=8983
+whirr.solr.jetty.stop.port=8982
+whirr.solr.jetty.stop.secret=this is a secret string
+
+# For EC2 set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.
+#whirr.provider=aws-ec2
+#whirr.identity=${env:AWS_ACCESS_KEY_ID}
+#whirr.credential=${env:AWS_SECRET_ACCESS_KEY}
+
+whirr.solr.tarball=http://www.apache.org/dist/lucene/solr/3.5.0/apache-solr-3.5.0.tgz
+whirr.solr.config.tarball.url=file:///${sys:user.dir}/target/solrconfig.tar.gz
+whirr.solr.java.opts=-DXmx512m -Dsolr.data.dir=data
+
+# By default use the user system SSH keys. Override them here.
+# whirr.private-key-file=${sys:user.home}/.ssh/id_rsa
+# whirr.public-key-file=${whirr.private-key-file}.pub

Added: whirr/trunk/services/solr/pom.xml
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/pom.xml?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/pom.xml (added)
+++ whirr/trunk/services/solr/pom.xml Wed May  9 11:18:48 2012
@@ -0,0 +1,89 @@
+<!--
+   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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.whirr</groupId>
+    <artifactId>whirr</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+  <groupId>org.apache.whirr</groupId>
+  <artifactId>whirr-solr</artifactId>
+  <packaging>bundle</packaging>
+  <version>0.8.0-SNAPSHOT</version>
+  <name>Apache Whirr Solr</name>
+  <url>http://wiki.apache.org/solr</url>
+  <properties>
+    <osgi.import>
+      !org.apache.whirr.service.solr*,
+      org.apache.commons.configuration*;version="[1.6,2)",
+      *
+    </osgi.import>
+    <osgi.export>
+      org.apache.whirr.service.solr*;version="${project.version}"
+    </osgi.export>
+    <osgi.fragment.host>jclouds-scriptbuilder;bundle-version="${jclouds.version}"</osgi.fragment.host>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>whirr-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>whirr-core</artifactId>
+      <version>${project.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-configuration</groupId>
+      <artifactId>commons-configuration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.solr</groupId>
+      <artifactId>solr-solrj</artifactId>
+      <version>3.5.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+     </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-site-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Added: whirr/trunk/services/solr/src/main/java/org/apache/whirr/service/solr/SolrClusterActionHandler.java
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/main/java/org/apache/whirr/service/solr/SolrClusterActionHandler.java?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/main/java/org/apache/whirr/service/solr/SolrClusterActionHandler.java (added)
+++ whirr/trunk/services/solr/src/main/java/org/apache/whirr/service/solr/SolrClusterActionHandler.java Wed May  9 11:18:48 2012
@@ -0,0 +1,195 @@
+/**
+ * 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.
+ */
+
+package org.apache.whirr.service.solr;
+
+import static com.google.common.io.ByteStreams.newInputStreamSupplier;
+import static org.apache.whirr.RolePredicates.role;
+import static org.jclouds.scriptbuilder.domain.Statements.call;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.lang.StringUtils;
+import org.apache.whirr.Cluster;
+import org.apache.whirr.Cluster.Instance;
+import org.apache.whirr.ClusterSpec;
+import org.apache.whirr.service.ClusterActionEvent;
+import org.apache.whirr.service.ClusterActionHandlerSupport;
+import org.apache.whirr.service.FirewallManager.Rule;
+
+import org.jclouds.crypto.CryptoStreams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+
+public class SolrClusterActionHandler extends ClusterActionHandlerSupport {
+
+  private static final Logger LOG = LoggerFactory.getLogger(SolrClusterActionHandler.class);
+
+  public final static String SOLR_ROLE = "solr";
+
+  final static String SOLR_DEFAULT_CONFIG = "whirr-solr-default.properties";
+
+  final static String SOLR_HOME = "/usr/local/solr";
+
+  final static String SOLR_TARBALL_URL = "whirr.solr.tarball";
+  final static String SOLR_CONFIG_TARBALL_URL = "whirr.solr.config.tarball.url";
+  final static String SOLR_JETTY_PORT = "whirr.solr.jetty.port";
+  final static String SOLR_JETTY_STOP_PORT = "whirr.solr.jetty.stop.port";
+  final static String SOLR_JETTY_STOP_SECRET = "whirr.solr.jetty.stop.secret";
+  public static final String SOLR_JAVA_OPTS = "whirr.solr.java.opts";
+
+  @Override
+  public String getRole() {
+    return SOLR_ROLE;
+  }
+
+  @Override
+  protected void beforeBootstrap(ClusterActionEvent event) throws IOException {
+    Configuration config = getConfiguration(event.getClusterSpec(), SOLR_DEFAULT_CONFIG);
+
+    // Validate the config
+    int jettyPort = config.getInt(SOLR_JETTY_PORT);
+    int jettyStopPort = config.getInt(SOLR_JETTY_STOP_PORT);
+
+    if (jettyPort == 0) {
+      throw new IllegalArgumentException("Must specify Jetty's port! (" + SOLR_JETTY_PORT + ")");
+    }
+
+    if (jettyStopPort == 0) {
+      throw new IllegalArgumentException("Must specify Jetty's stop port! (" + SOLR_JETTY_STOP_PORT + ")");
+    }
+
+    if (jettyPort == jettyStopPort) {
+      throw new IllegalArgumentException("Jetty's port and the stop port must be different");
+    }
+
+    String solrConfigTarballUrl = config.getString(SOLR_CONFIG_TARBALL_URL);
+    if (StringUtils.isBlank(solrConfigTarballUrl)) {
+      throw new IllegalArgumentException("Must specify Solr config tarball! (" + SOLR_CONFIG_TARBALL_URL + ")");
+    }
+
+    String solrTarball = config.getString(SOLR_TARBALL_URL);
+    if(!solrTarball.matches("^.*apache-solr-.*(tgz|tar\\.gz)$")) {
+      throw new IllegalArgumentException("Must specify a Solr tarball");
+    }
+    // Call the installers
+    addStatement(event, call(getInstallFunction(config, "java", "install_openjdk")));
+    addStatement(event, call("install_tarball"));
+
+    String installFunc = getInstallFunction(config, getRole(), "install_" + getRole());
+
+    LOG.info("Installing Solr");
+
+    addStatement(event, call(installFunc, solrTarball, SOLR_HOME));
+  }
+
+  @Override
+  protected void beforeConfigure(ClusterActionEvent event) throws IOException {
+    LOG.info("Configure Solr");
+
+    ClusterSpec clusterSpec = event.getClusterSpec();
+    Configuration config = getConfiguration(clusterSpec, SOLR_DEFAULT_CONFIG);
+
+    int jettyPort = config.getInt(SOLR_JETTY_PORT);
+
+    // Open up Jetty port
+    event.getFirewallManager().addRule(Rule.create().destination(role(SOLR_ROLE)).port(jettyPort));
+  }
+
+  @Override
+  protected void beforeStart(ClusterActionEvent event) throws IOException {
+    ClusterSpec clusterSpec = event.getClusterSpec();
+    Configuration config = getConfiguration(clusterSpec, SOLR_DEFAULT_CONFIG);
+
+    String solrConfigTarballUrl = prepareRemoteFileUrl(event, config.getString(SOLR_CONFIG_TARBALL_URL));
+    LOG.info("Preparing solr config tarball url {}", solrConfigTarballUrl);
+    addStatement(event, call("install_tarball_no_md5", solrConfigTarballUrl, SOLR_HOME));
+
+    int jettyPort = config.getInt(SOLR_JETTY_PORT);
+    int jettyStopPort = config.getInt(SOLR_JETTY_STOP_PORT);
+
+    String startFunc = getStartFunction(config, getRole(), "start_" + getRole());
+    LOG.info("Starting up Solr");
+
+    addStatement(event, call(startFunc,
+        String.valueOf(jettyPort),
+        String.valueOf(jettyStopPort),
+        safeSecretString(config.getString(SOLR_JETTY_STOP_SECRET)),
+        SOLR_HOME,
+        SOLR_HOME + "/example/start.jar",
+        config.getString(SOLR_JAVA_OPTS, "")
+    ));
+  }
+
+  @Override
+  protected void afterStart(ClusterActionEvent event) throws IOException {
+    ClusterSpec clusterSpec = event.getClusterSpec();
+    Cluster cluster = event.getCluster();
+    Configuration config = getConfiguration(clusterSpec, SOLR_DEFAULT_CONFIG);
+    int jettyPort = config.getInt(SOLR_JETTY_PORT);
+    LOG.info("Completed configuration of {}", clusterSpec.getClusterName());
+    LOG.info("Solr Hosts: {}", getHosts(cluster.getInstancesMatching(role(SOLR_ROLE)), jettyPort));
+  }
+
+  @Override
+  protected void beforeStop(ClusterActionEvent event) throws IOException {
+    ClusterSpec clusterSpec = event.getClusterSpec();
+    Configuration config = getConfiguration(clusterSpec, SOLR_DEFAULT_CONFIG);
+    int jettyStopPort = config.getInt(SOLR_JETTY_STOP_PORT);
+    String stopFunc = getStopFunction(config, getRole(), "stop_" + getRole());
+    LOG.info("Stopping Solr");
+    addStatement(event, call(stopFunc,
+      SOLR_HOME,
+      String.valueOf(jettyStopPort),
+      safeSecretString(config.getString(SOLR_JETTY_STOP_SECRET)),
+      SOLR_HOME + "/example/start.jar"
+    ));
+  }
+
+  static List<String> getHosts(Set<Instance> instances, final int port) {
+    return Lists.transform(Lists.newArrayList(instances), new GetPublicIpFunction(port));
+  }
+
+  static String safeSecretString(String value) throws IOException {
+    return CryptoStreams.md5Hex(newInputStreamSupplier(("NaCl#" + value).getBytes()));
+  }
+
+  private static class GetPublicIpFunction implements Function<Instance, String> {
+    private final int port;
+
+    public GetPublicIpFunction(int port) {
+      this.port = port;
+    }
+
+    @Override
+    public String apply(Instance instance) {
+      try {
+        String publicIp = instance.getPublicHostName();
+        return String.format("%s:%d", publicIp, port);
+      } catch (IOException e) {
+        throw new IllegalArgumentException(e);
+      }
+    }
+  }
+}

Added: whirr/trunk/services/solr/src/main/resources/META-INF/services/org.apache.whirr.service.ClusterActionHandler
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/main/resources/META-INF/services/org.apache.whirr.service.ClusterActionHandler?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/main/resources/META-INF/services/org.apache.whirr.service.ClusterActionHandler (added)
+++ whirr/trunk/services/solr/src/main/resources/META-INF/services/org.apache.whirr.service.ClusterActionHandler Wed May  9 11:18:48 2012
@@ -0,0 +1,12 @@
+#   Licensed 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.
+org.apache.whirr.service.solr.SolrClusterActionHandler

Added: whirr/trunk/services/solr/src/main/resources/functions/configure_solr.sh
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/main/resources/functions/configure_solr.sh?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/main/resources/functions/configure_solr.sh (added)
+++ whirr/trunk/services/solr/src/main/resources/functions/configure_solr.sh Wed May  9 11:18:48 2012
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+function configure_solr() {
+  local hosts=$1
+  echo "\n# Added by Whirr configure_solr()" >> /etc/hosts
+  cat $hosts >> /etc/hosts
+}

Added: whirr/trunk/services/solr/src/main/resources/functions/install_solr.sh
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/main/resources/functions/install_solr.sh?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/main/resources/functions/install_solr.sh (added)
+++ whirr/trunk/services/solr/src/main/resources/functions/install_solr.sh Wed May  9 11:18:48 2012
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+function install_solr() {
+  # Install Solr to SOLR_HOME
+  local solr_url=$1
+  SOLR_HOME=$2
+  install_tarball $solr_url $SOLR_HOME
+
+  # Need to move the install files since the tgz drops an extra directory (e.g. apache-solr-4.0-2012-02-04_17-38-34)
+  local solr_install_dir=`ls $SOLR_HOME`
+  mv $SOLR_HOME/$solr_install_dir/* $SOLR_HOME/
+  rm -r $SOLR_HOME/$solr_install_dir
+
+  # Add to ENV
+  echo "export SOLR_HOME=$SOLR_HOME" >> /etc/profile
+  echo "Installed Solr at $SOLR_HOME"
+  exit 0
+}

Added: whirr/trunk/services/solr/src/main/resources/functions/start_solr.sh
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/main/resources/functions/start_solr.sh?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/main/resources/functions/start_solr.sh (added)
+++ whirr/trunk/services/solr/src/main/resources/functions/start_solr.sh Wed May  9 11:18:48 2012
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+function start_solr() {
+  local jetty_port=$1
+  local jetty_stop_port=$2
+  local jetty_stop_secret=$3
+  local solr_home=$4
+  local jar=$5
+  local java_opts=${6}
+  cd $solr_home
+  nohup java $java_opts \
+    -Djetty.port=$jetty_port \
+    -Djetty.home=$solr_home/example/ \
+    -DSTOP.PORT=$jetty_stop_port \
+    -DSTOP.KEY=$jetty_stop_secret \
+    -Dsolr.solr.home=. \
+    -jar $jar &> solr.log &
+}

Added: whirr/trunk/services/solr/src/main/resources/functions/stop_solr.sh
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/main/resources/functions/stop_solr.sh?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/main/resources/functions/stop_solr.sh (added)
+++ whirr/trunk/services/solr/src/main/resources/functions/stop_solr.sh Wed May  9 11:18:48 2012
@@ -0,0 +1,28 @@
+#
+# 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.
+#
+function stop_solr() {
+  local solr_home=$1
+  local jetty_stop_port=$2
+  local jetty_stop_secret=$3
+  local jar=$4
+  cd $solr_home
+  java \
+    -Djetty.home=$solr_home/example/ \
+    -DSTOP.PORT=$jetty_stop_port \
+    -DSTOP.KEY=$jetty_stop_secret \
+    -jar $jar --stop
+}

Added: whirr/trunk/services/solr/src/main/resources/whirr-solr-default.properties
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/main/resources/whirr-solr-default.properties?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/main/resources/whirr-solr-default.properties (added)
+++ whirr/trunk/services/solr/src/main/resources/whirr-solr-default.properties Wed May  9 11:18:48 2012
@@ -0,0 +1,17 @@
+#   Licensed 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.
+#
+whirr.solr.tarball=http://www.apache.org/dist/lucene/solr/3.5.0/apache-solr-3.5.0.tgz
+whirr.solr.jetty.port=8983
+whirr.solr.jetty.stop.port=8982
+whirr.solr.jetty.stop.secret=this is a secret string
+whirr.solr.java.opts=-DXmx512m

Added: whirr/trunk/services/solr/src/test/java/org/apache/whirr/service/solr/integration/SolrServiceTest.java
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/test/java/org/apache/whirr/service/solr/integration/SolrServiceTest.java?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/test/java/org/apache/whirr/service/solr/integration/SolrServiceTest.java (added)
+++ whirr/trunk/services/solr/src/test/java/org/apache/whirr/service/solr/integration/SolrServiceTest.java Wed May  9 11:18:48 2012
@@ -0,0 +1,120 @@
+/**
+ * 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.
+ */
+
+package org.apache.whirr.service.solr.integration;
+
+import com.jcraft.jsch.JSchException;
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.whirr.Cluster;
+import org.apache.whirr.ClusterController;
+import org.apache.whirr.ClusterSpec;
+import org.apache.whirr.util.BlobCache;
+import org.apache.whirr.util.Tarball;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Set;
+
+import static junit.framework.Assert.assertEquals;
+import static org.apache.whirr.RolePredicates.role;
+
+/**
+ * Installs the Solr service including configuration. Indexes a document and performs a search.
+ */
+public class SolrServiceTest {
+
+  private static final Logger LOG = LoggerFactory.getLogger(SolrServiceTest.class);
+
+  public static final String SOLR_ROLE = "solr";
+  public static final String SOLR_PORT = "8983";
+
+  private static ClusterSpec clusterSpec;
+  private static ClusterController controller;
+  private static Cluster cluster;
+
+  @BeforeClass
+  public static void beforeClass() throws ConfigurationException, JSchException, IOException, InterruptedException {
+    String solrConfigTarballDestination = "target/solrconfig.tar.gz";
+    Tarball.createFromDirectory("src/test/resources/conf", solrConfigTarballDestination);
+    LOG.info("Created Solr config tarball at "  + solrConfigTarballDestination);
+
+    CompositeConfiguration config = new CompositeConfiguration();
+    if (System.getProperty("conf") != null) {
+      config.addConfiguration(new PropertiesConfiguration(System.getProperty("conf")));
+    }
+    config.addConfiguration(new PropertiesConfiguration("whirr-solr-test.properties"));
+    clusterSpec = ClusterSpec.withTemporaryKeys(config);
+    controller = new ClusterController();
+
+    cluster = controller.launchCluster(clusterSpec);
+  }
+
+  @Test
+  public void testSolr() throws IOException, SolrServerException {
+    Set<Cluster.Instance> instances = cluster.getInstancesMatching(role(SOLR_ROLE));
+
+    for (Cluster.Instance instance : instances) {
+      String publicIp = instance.getPublicIp();
+
+      LOG.info("Adding a document to instance " + instance.getId() + " @ " + publicIp);
+      
+      CommonsHttpSolrServer solrServer = new CommonsHttpSolrServer(String.format("http://%s:%s/solr/core0", instance.getPublicHostName(), SOLR_PORT));
+
+      SolrInputDocument doc = new SolrInputDocument();
+      doc.addField("name", "Apache Whirr");
+      doc.addField("inceptionYear", "2010");
+
+      solrServer.add(doc);
+      solrServer.commit();
+
+      LOG.info("Committed document to instance " + instance.getId() + " @ " + publicIp);
+
+      LOG.info("Performing a search on instance " + instance.getId() + " @ " + publicIp);
+
+      SolrQuery query = new SolrQuery("name:whirr");
+      QueryResponse response = solrServer.query(query);
+      SolrDocumentList results = response.getResults();
+      assertEquals("Search on instance " + instance.getId() + " did NOT return a document!" , 1, results.size());
+
+      SolrDocument resultDoc = results.get(0);
+      assertEquals("name field on document of instance " + instance.getId() + " is incorrect", "Apache Whirr", resultDoc.get("name"));
+    }
+  }
+
+  @AfterClass
+  public static void after() throws IOException, InterruptedException {
+    if (controller != null) {
+      controller.destroyCluster(clusterSpec);
+    }
+
+    BlobCache.dropAndCloseAll();
+  }
+}

Added: whirr/trunk/services/solr/src/test/resources/conf/core0/conf/schema.xml
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/test/resources/conf/core0/conf/schema.xml?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/test/resources/conf/core0/conf/schema.xml (added)
+++ whirr/trunk/services/solr/src/test/resources/conf/core0/conf/schema.xml Wed May  9 11:18:48 2012
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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.
+-->
+
+<schema name="example" version="1.3">
+
+    <types>
+        <fieldType name="text" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
+            <analyzer type="index">
+                <tokenizer class="solr.WhitespaceTokenizerFactory"/>
+                <filter class="solr.LowerCaseFilterFactory"/>
+            </analyzer>
+        </fieldType>
+    </types>
+
+    <fields>
+        <field name="name" type="text" indexed="true" stored="true"/>
+        <field name="inceptionYear" type="text" indexed="true" stored="true"/>
+    </fields>
+
+    <uniqueKey>name</uniqueKey>
+
+    <defaultSearchField>name</defaultSearchField>
+
+    <solrQueryParser defaultOperator="OR"/>
+
+</schema>

Added: whirr/trunk/services/solr/src/test/resources/conf/core0/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/test/resources/conf/core0/conf/solrconfig.xml?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/test/resources/conf/core0/conf/solrconfig.xml (added)
+++ whirr/trunk/services/solr/src/test/resources/conf/core0/conf/solrconfig.xml Wed May  9 11:18:48 2012
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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.
+-->
+
+<config>
+    <abortOnConfigurationError>true</abortOnConfigurationError>
+
+    <luceneMatchVersion>LUCENE_35</luceneMatchVersion>
+
+    <dataDir>${solr.data.dir:}</dataDir>
+
+    <directoryFactory name="DirectoryFactory"
+                      class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
+    <indexDefaults>
+        <useCompoundFile>false</useCompoundFile>
+        <mergeFactor>10</mergeFactor>
+        <ramBufferSizeMB>32</ramBufferSizeMB>
+        <maxFieldLength>10000</maxFieldLength>
+        <writeLockTimeout>1000</writeLockTimeout>
+        <commitLockTimeout>10000</commitLockTimeout>
+        <lockType>native</lockType>
+    </indexDefaults>
+
+    <mainIndex>
+        <useCompoundFile>false</useCompoundFile>
+        <ramBufferSizeMB>32</ramBufferSizeMB>
+        <mergeFactor>10</mergeFactor>
+        <unlockOnStartup>false</unlockOnStartup>
+        <reopenReaders>true</reopenReaders>
+        <deletionPolicy class="solr.SolrDeletionPolicy">
+            <str name="maxCommitsToKeep">1</str>
+            <str name="maxOptimizedCommitsToKeep">0</str>
+        </deletionPolicy>
+        <infoStream file="INFOSTREAM.txt">false</infoStream>
+    </mainIndex>
+
+    <updateHandler class="solr.DirectUpdateHandler2">
+    </updateHandler>
+
+    <query>
+        <maxBooleanClauses>1024</maxBooleanClauses>
+        <filterCache class="solr.FastLRUCache"
+                     size="512"
+                     initialSize="512"
+                     autowarmCount="0"/>
+
+        <queryResultCache class="solr.LRUCache"
+                          size="512"
+                          initialSize="512"
+                          autowarmCount="0"/>
+
+        <documentCache class="solr.LRUCache"
+                       size="512"
+                       initialSize="512"
+                       autowarmCount="0"/>
+
+        <enableLazyFieldLoading>true</enableLazyFieldLoading>
+
+        <queryResultWindowSize>20</queryResultWindowSize>
+
+        <queryResultMaxDocsCached>200</queryResultMaxDocsCached>
+
+        <listener event="newSearcher" class="solr.QuerySenderListener">
+            <arr name="queries">
+            </arr>
+        </listener>
+        <listener event="firstSearcher" class="solr.QuerySenderListener">
+            <arr name="queries">
+                <lst>
+                    <str name="q">static firstSearcher warming in solrconfig.xml</str>
+                </lst>
+            </arr>
+        </listener>
+
+        <useColdSearcher>false</useColdSearcher>
+
+        <maxWarmingSearchers>2</maxWarmingSearchers>
+
+    </query>
+
+    <requestDispatcher handleSelect="true" >
+        <requestParsers enableRemoteStreaming="true"
+                        multipartUploadLimitInKB="2048000" />
+        <httpCaching never304="true" />
+    </requestDispatcher>
+
+    <requestHandler name="search" class="solr.SearchHandler" default="true">
+        <lst name="defaults">
+            <str name="echoParams">explicit</str>
+            <int name="rows">10</int>
+        </lst>
+    </requestHandler>
+
+    <requestHandler name="/update"
+                    class="solr.XmlUpdateRequestHandler">
+    </requestHandler>
+
+    <requestHandler name="/update/javabin"
+                    class="solr.BinaryUpdateRequestHandler" />
+
+    <admin>
+        <defaultQuery>*:*</defaultQuery>
+    </admin>
+
+</config>

Added: whirr/trunk/services/solr/src/test/resources/conf/solr.xml
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/test/resources/conf/solr.xml?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/test/resources/conf/solr.xml (added)
+++ whirr/trunk/services/solr/src/test/resources/conf/solr.xml Wed May  9 11:18:48 2012
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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.
+-->
+
+<solr persistent="true" sharedLib="lib">
+    <cores adminPath="/admin/cores">
+        <core name="core0" instanceDir="core0" />
+    </cores>
+</solr>

Added: whirr/trunk/services/solr/src/test/resources/log4j.xml
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/test/resources/log4j.xml?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/test/resources/log4j.xml (added)
+++ whirr/trunk/services/solr/src/test/resources/log4j.xml Wed May  9 11:18:48 2012
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!--
+    For more configuration infromation and examples see the Apache
+    Log4j website: http://logging.apache.org/log4j/
+-->
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
+                     debug="false">
+
+    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+        <param name="Threshold" value="INFO" />
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
+        </layout>
+    </appender>
+
+    <!-- A time/date based rolling appender -->
+    <appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
+        <param name="File" value="target/test-data/jclouds-wire.log" />
+        <param name="Append" value="true" />
+
+        <!-- Rollover at midnight each day -->
+        <param name="DatePattern" value="'.'yyyy-MM-dd" />
+
+        <param name="Threshold" value="TRACE" />
+
+        <layout class="org.apache.log4j.PatternLayout">
+            <!-- The default pattern: Date Priority [Category] Message\n -->
+            <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
+
+            <!--
+                The full pattern: Date MS Priority [Category]
+                (Thread:NDC) Message\n <param name="ConversionPattern"
+                value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+            -->
+        </layout>
+    </appender>
+
+    <!-- A time/date based rolling appender -->
+    <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
+        <param name="File" value="target/test-data/jclouds.log" />
+        <param name="Append" value="true" />
+
+        <!-- Rollover at midnight each day -->
+        <param name="DatePattern" value="'.'yyyy-MM-dd" />
+
+        <param name="Threshold" value="TRACE" />
+
+        <layout class="org.apache.log4j.PatternLayout">
+            <!-- The default pattern: Date Priority [Category] Message\n -->
+            <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
+
+            <!--
+                The full pattern: Date MS Priority [Category]
+                (Thread:NDC) Message\n <param name="ConversionPattern"
+                value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+            -->
+        </layout>
+    </appender>
+
+    <!-- A time/date based rolling appender -->
+    <appender name="BLOBSTOREFILE" class="org.apache.log4j.DailyRollingFileAppender">
+        <param name="File" value="target/test-data/jclouds-blobstore.log" />
+        <param name="Append" value="true" />
+        <param name="DatePattern" value="'.'yyyy-MM-dd" />
+        <param name="Threshold" value="TRACE" />
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
+        </layout>
+    </appender>
+
+
+    <!-- A time/date based rolling appender -->
+    <appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
+        <param name="File" value="target/test-data/jclouds-compute.log" />
+        <param name="Append" value="true" />
+
+        <!-- Rollover at midnight each day -->
+        <param name="DatePattern" value="'.'yyyy-MM-dd" />
+
+        <param name="Threshold" value="TRACE" />
+
+        <layout class="org.apache.log4j.PatternLayout">
+            <!-- The default pattern: Date Priority [Category] Message\n -->
+            <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
+
+            <!--
+                The full pattern: Date MS Priority [Category]
+                (Thread:NDC) Message\n <param name="ConversionPattern"
+                value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+            -->
+        </layout>
+    </appender>
+
+    <!-- A time/date based rolling appender -->
+    <appender name="WHIRRFILE" class="org.apache.log4j.DailyRollingFileAppender">
+        <param name="File" value="target/test-data/whirr.log" />
+        <param name="Append" value="true" />
+
+        <!-- Rollover at midnight each day -->
+        <param name="DatePattern" value="'.'yyyy-MM-dd" />
+
+        <param name="Threshold" value="TRACE" />
+
+        <layout class="org.apache.log4j.PatternLayout">
+            <!-- The default pattern: Date Priority [Category] Message\n -->
+            <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
+
+            <!--
+                The full pattern: Date MS Priority [Category]
+                (Thread:NDC) Message\n <param name="ConversionPattern"
+                value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+            -->
+        </layout>
+    </appender>
+
+    <!-- A time/date based rolling appender -->
+    <appender name="SSHFILE" class="org.apache.log4j.DailyRollingFileAppender">
+        <param name="File" value="target/test-data/jclouds-ssh.log" />
+        <param name="Append" value="true" />
+        <param name="DatePattern" value="'.'yyyy-MM-dd" />
+        <param name="Threshold" value="TRACE" />
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
+        </layout>
+    </appender>
+
+    <appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
+        <appender-ref ref="COMPUTEFILE" />
+    </appender>
+    <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
+        <appender-ref ref="FILE" />
+    </appender>
+
+    <appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
+        <appender-ref ref="WIREFILE" />
+    </appender>
+
+    <appender name="ASYNCBLOBSTORE" class="org.apache.log4j.AsyncAppender">
+        <appender-ref ref="BLOBSTOREFILE" />
+    </appender>
+
+    <appender name="ASYNCSSH" class="org.apache.log4j.AsyncAppender">
+        <appender-ref ref="SSHFILE" />
+    </appender>
+    <!-- ================ -->
+    <!-- Limit categories -->
+    <!-- ================ -->
+    <category name="jclouds.blobstore">
+        <priority value="DEBUG" />
+        <appender-ref ref="ASYNCBLOBSTORE" />
+    </category>
+
+    <category name="org.jclouds">
+        <priority value="DEBUG" />
+        <appender-ref ref="ASYNC" />
+    </category>
+
+    <category name="org.apache.whirr">
+        <priority value="DEBUG" />
+        <appender-ref ref="WHIRRFILE" />
+    </category>
+
+    <category name="jclouds.headers">
+        <priority value="DEBUG" />
+        <appender-ref ref="ASYNCWIRE" />
+    </category>
+    <category name="jclouds.compute">
+        <priority value="DEBUG" />
+        <appender-ref ref="ASYNCCOMPUTE" />
+    </category>
+
+    <category name="jclouds.ssh">
+        <priority value="TRACE" />
+        <appender-ref ref="ASYNCSSH" />
+    </category>
+
+    <category name="jclouds.wire">
+        <priority value="DEBUG" />
+        <appender-ref ref="ASYNCWIRE" />
+    </category><!--
+
+       <category name="jclouds.signature">
+        <priority value="DEBUG" />
+        <appender-ref ref="ASYNCWIRE" />
+    </category>
+
+
+    --><!--  ======================= -->
+    <!-- Setup the Root category -->
+    <!-- ======================= -->
+
+    <root>
+        <priority value="WARN" />
+        <appender-ref ref="CONSOLE" />
+    </root>
+
+</log4j:configuration>

Added: whirr/trunk/services/solr/src/test/resources/whirr-solr-test.properties
URL: http://svn.apache.org/viewvc/whirr/trunk/services/solr/src/test/resources/whirr-solr-test.properties?rev=1336098&view=auto
==============================================================================
--- whirr/trunk/services/solr/src/test/resources/whirr-solr-test.properties (added)
+++ whirr/trunk/services/solr/src/test/resources/whirr-solr-test.properties Wed May  9 11:18:48 2012
@@ -0,0 +1,34 @@
+#
+# 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.
+#
+whirr.cluster-name=solr-itest-${sys:whirr.test.provider}-${sys:user.name}
+whirr.instance-templates=1 solr
+
+whirr.provider=${sys:whirr.test.provider}
+whirr.identity=${sys:whirr.test.identity}
+whirr.credential=${sys:whirr.test.credential}
+
+whirr.solr.tarball=http://www.apache.org/dist/lucene/solr/3.5.0/apache-solr-3.5.0.tgz
+whirr.solr.config.tarball.url=file:///${sys:user.dir}/target/solrconfig.tar.gz
+whirr.solr.jetty.port=8983
+whirr.solr.jetty.stop.port=8982
+whirr.solr.jetty.stop.secret=this is a secret string
+whirr.solr.java.opts=-DXmx512m -Dsolr.data.dir=data
+
+# By default use the user system SSH keys. Override them here.
+whirr.private-key-file=${sys:user.home}/.ssh/id_rsa
+whirr.public-key-file=${whirr.private-key-file}.pub