You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whirr.apache.org by ph...@apache.org on 2010/09/30 22:19:17 UTC

svn commit: r1003237 - in /incubator/whirr/trunk: ./ cli/src/main/java/org/apache/whirr/cli/command/ cli/src/test/java/org/apache/whirr/cli/command/

Author: phunt
Date: Thu Sep 30 20:19:17 2010
New Revision: 1003237

URL: http://svn.apache.org/viewvc?rev=1003237&view=rev
Log:
WHIRR-102. unknown service NPEs cli, should print the bad service to console

Added:
    incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/AbstractClusterSpecCommand.java
    incubator/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/AbstractClusterSpecCommandTest.java
Removed:
    incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ClusterSpecCommand.java
    incubator/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/ClusterSpecCommandTest.java
Modified:
    incubator/whirr/trunk/CHANGES.txt
    incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java
    incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java

Modified: incubator/whirr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/CHANGES.txt?rev=1003237&r1=1003236&r2=1003237&view=diff
==============================================================================
--- incubator/whirr/trunk/CHANGES.txt (original)
+++ incubator/whirr/trunk/CHANGES.txt Thu Sep 30 20:19:17 2010
@@ -25,6 +25,9 @@ Trunk (unreleased changes)
     WHIRR-97. Lucid is not stable on EC2. Default is now the Amazon Linux AMI
     on EC2. (tomwhite)
 
+    WHIRR-102. unknown service NPEs cli, should print the bad service
+    to console (phunt)
+
 Release 0.1.0 - 2010-09-02
 
   INCOMPATIBLE CHANGES

Added: incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/AbstractClusterSpecCommand.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/AbstractClusterSpecCommand.java?rev=1003237&view=auto
==============================================================================
--- incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/AbstractClusterSpecCommand.java (added)
+++ incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/AbstractClusterSpecCommand.java Thu Sep 30 20:19:17 2010
@@ -0,0 +1,117 @@
+/**
+ * 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.cli.command;
+
+import static org.apache.whirr.service.ClusterSpec.Property.CLUSTER_NAME;
+import static org.apache.whirr.service.ClusterSpec.Property.IDENTITY;
+import static org.apache.whirr.service.ClusterSpec.Property.SERVICE_NAME;
+
+import java.util.EnumSet;
+import java.util.Map;
+
+import joptsimple.ArgumentAcceptingOptionSpec;
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.whirr.cli.Command;
+import org.apache.whirr.service.ClusterSpec;
+import org.apache.whirr.service.ClusterSpec.Property;
+import org.apache.whirr.service.Service;
+import org.apache.whirr.service.ServiceFactory;
+
+import com.google.common.collect.Maps;
+
+/**
+ * An abstract command for interacting with clusters.
+ */
+public abstract class AbstractClusterSpecCommand extends Command {
+
+  protected ServiceFactory factory;
+
+  protected OptionParser parser = new OptionParser();
+  private Map<Property, OptionSpec> optionSpecs;
+  private OptionSpec<String> configOption = parser.accepts("config")
+    .withRequiredArg().ofType(String.class);
+
+  public AbstractClusterSpecCommand(String name, String description, ServiceFactory factory) {
+    super(name, description);
+    this.factory = factory;
+
+    optionSpecs = Maps.newHashMap();
+    for (Property property : EnumSet.allOf(Property.class)) {
+      ArgumentAcceptingOptionSpec<?> spec = parser.accepts(property.getSimpleName())
+        .withRequiredArg()
+        .ofType(property.getType());
+      if (property.hasMultipleArguments()) {
+        spec.withValuesSeparatedBy(',');
+      }
+      optionSpecs.put(property, spec);
+    }
+  }
+
+  protected ClusterSpec getClusterSpec(OptionSet optionSet) throws ConfigurationException {
+    Configuration optionsConfig = new PropertiesConfiguration();
+    for (Map.Entry<Property, OptionSpec> entry : optionSpecs.entrySet()) {
+      Property property = entry.getKey();
+      OptionSpec option = entry.getValue();
+      if (property.hasMultipleArguments()) {
+        optionsConfig.setProperty(property.getConfigName(),
+            optionSet.valuesOf(option));
+      } else {
+        optionsConfig.setProperty(property.getConfigName(),
+            optionSet.valueOf(option));
+      }
+    }
+    CompositeConfiguration config = new CompositeConfiguration();
+    config.addConfiguration(optionsConfig);
+    if (optionSet.has(configOption)) {
+      Configuration defaults = new PropertiesConfiguration(optionSet.valueOf(configOption));
+      config.addConfiguration(defaults);
+    }
+
+    for (Property required : EnumSet.of(SERVICE_NAME, CLUSTER_NAME, IDENTITY)) {
+      if (config.getString(required.getConfigName()) == null) {
+        throw new IllegalArgumentException(String.format("Option '%s' not set.",
+            required.getSimpleName()));
+      }
+    }
+    return new ClusterSpec(config);
+  }
+
+  /**
+   * Create the specified service
+   * @param serviceName
+   * @return
+   * @throws IllegalArgumentException if serviceName is not found
+   */
+  protected Service createService(String serviceName) {
+    Service service = factory.create(serviceName);
+    if (service == null) {
+      throw new IllegalArgumentException("Unable to find service "
+          + serviceName + ", exiting");
+    }
+    return service;
+  }
+
+}

Modified: incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java?rev=1003237&r1=1003236&r2=1003237&view=diff
==============================================================================
--- incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java (original)
+++ incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java Thu Sep 30 20:19:17 2010
@@ -33,7 +33,7 @@ import org.apache.whirr.service.ServiceF
 /**
  * A command to destroy a running cluster (terminate and cleanup).
  */
-public class DestroyClusterCommand extends ClusterSpecCommand {
+public class DestroyClusterCommand extends AbstractClusterSpecCommand {
 
   public DestroyClusterCommand() throws IOException {
     this(new ServiceFactory());
@@ -56,7 +56,7 @@ public class DestroyClusterCommand exten
     try {
       ClusterSpec clusterSpec = getClusterSpec(optionSet);
 
-      Service service = factory.create(clusterSpec.getServiceName());
+      Service service = createService(clusterSpec.getServiceName());
       service.destroyCluster(clusterSpec);
       return 0;
     } catch (IllegalArgumentException e) {

Modified: incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java?rev=1003237&r1=1003236&r2=1003237&view=diff
==============================================================================
--- incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java (original)
+++ incubator/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java Thu Sep 30 20:19:17 2010
@@ -34,7 +34,7 @@ import org.apache.whirr.service.ServiceF
 /**
  * A command to launch a new cluster.
  */
-public class LaunchClusterCommand extends ClusterSpecCommand {
+public class LaunchClusterCommand extends AbstractClusterSpecCommand {
 
   public LaunchClusterCommand() throws IOException {
     this(new ServiceFactory());
@@ -57,7 +57,7 @@ public class LaunchClusterCommand extend
     
     try {
       ClusterSpec clusterSpec = getClusterSpec(optionSet);
-      Service service = factory.create(clusterSpec.getServiceName());
+      Service service = createService(clusterSpec.getServiceName());
       Cluster cluster = service.launchCluster(clusterSpec);
       out.printf("Started cluster of %s instances\n",
           cluster.getInstances().size());

Added: incubator/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/AbstractClusterSpecCommandTest.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/AbstractClusterSpecCommandTest.java?rev=1003237&view=auto
==============================================================================
--- incubator/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/AbstractClusterSpecCommandTest.java (added)
+++ incubator/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/AbstractClusterSpecCommandTest.java Thu Sep 30 20:19:17 2010
@@ -0,0 +1,76 @@
+/**
+ * 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.cli.command;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import joptsimple.OptionSet;
+
+import org.apache.whirr.service.ClusterSpec;
+import org.apache.whirr.service.ServiceFactory;
+import org.junit.Test;
+
+public class AbstractClusterSpecCommandTest {
+
+  @Test
+  public void testOverrides() throws Exception {
+    AbstractClusterSpecCommand clusterSpecCommand = new AbstractClusterSpecCommand("name",
+        "description", new ServiceFactory()) {
+      @Override
+      public int run(InputStream in, PrintStream out, PrintStream err,
+          List<String> args) throws Exception {
+        return 0;
+      }
+    };
+
+    OptionSet optionSet = clusterSpecCommand.parser.parse(
+        "--service-name", "overridden-test-service",
+        "--config", "whirr-override-test.properties");
+    ClusterSpec clusterSpec = clusterSpecCommand.getClusterSpec(optionSet);
+    assertThat(clusterSpec.getServiceName(), is("overridden-test-service"));
+    assertThat(clusterSpec.getClusterName(), is("test-cluster"));
+  }
+
+  /**
+   * Ensure that an invalid service name causes failure
+   */
+  @Test(expected=IllegalArgumentException.class)
+  public void testCreateServer_InvalidServiceName() throws Exception {
+    AbstractClusterSpecCommand clusterSpecCommand = new AbstractClusterSpecCommand("name",
+        "description", new ServiceFactory()) {
+      @Override
+      public int run(InputStream in, PrintStream out, PrintStream err,
+          List<String> args) throws Exception {
+        return 0;
+      }
+    };
+
+    OptionSet optionSet = clusterSpecCommand.parser.parse(
+        "--service-name", "foo",
+        "--config", "whirr-override-test.properties");
+    ClusterSpec clusterSpec = clusterSpecCommand.getClusterSpec(optionSet);
+    // this should fail - non-existent service
+    clusterSpecCommand.createService("bar");
+  }
+}