ace-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject svn commit: r1464071 - in /ace/trunk: org.apache.ace.nodelauncher.amazon/ org.apache.ace.nodelauncher.api/ org.apache.ace.nodelauncher.ui/ org.apache.ace.nodelauncher/ org.apache.ace.nodelauncher/.settings/ org.apache.ace.nodelauncher/resources/ org.ap...
Date Wed, 03 Apr 2013 15:33:03 GMT
Author: marrs
Date: Wed Apr  3 15:33:02 2013
New Revision: 1464071

URL: http://svn.apache.org/r1464071
Log:
ACE-333 Merged the nodelauncher.

Added:
    ace/trunk/org.apache.ace.nodelauncher/
    ace/trunk/org.apache.ace.nodelauncher/.classpath
    ace/trunk/org.apache.ace.nodelauncher/.project
    ace/trunk/org.apache.ace.nodelauncher/.settings/
    ace/trunk/org.apache.ace.nodelauncher/.settings/org.eclipse.jdt.core.prefs
    ace/trunk/org.apache.ace.nodelauncher/amazon.bnd
    ace/trunk/org.apache.ace.nodelauncher/api.bnd
    ace/trunk/org.apache.ace.nodelauncher/bnd.bnd
    ace/trunk/org.apache.ace.nodelauncher/build.xml
    ace/trunk/org.apache.ace.nodelauncher/generate-build-path.groovy
    ace/trunk/org.apache.ace.nodelauncher/generate-lib-includes.groovy
    ace/trunk/org.apache.ace.nodelauncher/generate-serviceloader-files.groovy
    ace/trunk/org.apache.ace.nodelauncher/resources/
    ace/trunk/org.apache.ace.nodelauncher/resources/org.jclouds.apis.ApiMetadata
    ace/trunk/org.apache.ace.nodelauncher/src/
    ace/trunk/org.apache.ace.nodelauncher/src/org/
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncher.java
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncherConfig.java
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/Activator.java
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/packageinfo
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/packageinfo
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/Activator.java
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodeLauncherPanelFactory.java
    ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodePanel.java
    ace/trunk/org.apache.ace.nodelauncher/test/
    ace/trunk/org.apache.ace.nodelauncher/test/org/
    ace/trunk/org.apache.ace.nodelauncher/test/org/apache/
    ace/trunk/org.apache.ace.nodelauncher/test/org/apache/ace/
    ace/trunk/org.apache.ace.nodelauncher/test/org/apache/ace/nodelauncher/
    ace/trunk/org.apache.ace.nodelauncher/test/org/apache/ace/nodelauncher/amazon/
    ace/trunk/org.apache.ace.nodelauncher/test/org/apache/ace/nodelauncher/amazon/PortParseTest.java
    ace/trunk/org.apache.ace.nodelauncher/ui.bnd
Removed:
    ace/trunk/org.apache.ace.nodelauncher.amazon/
    ace/trunk/org.apache.ace.nodelauncher.api/
    ace/trunk/org.apache.ace.nodelauncher.ui/

Added: ace/trunk/org.apache.ace.nodelauncher/.classpath
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/.classpath?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/.classpath (added)
+++ ace/trunk/org.apache.ace.nodelauncher/.classpath Wed Apr  3 15:33:02 2013
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: ace/trunk/org.apache.ace.nodelauncher/.project
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/.project?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/.project (added)
+++ ace/trunk/org.apache.ace.nodelauncher/.project Wed Apr  3 15:33:02 2013
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.apache.ace.nodelauncher</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>

Added: ace/trunk/org.apache.ace.nodelauncher/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/.settings/org.eclipse.jdt.core.prefs?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/.settings/org.eclipse.jdt.core.prefs (added)
+++ ace/trunk/org.apache.ace.nodelauncher/.settings/org.eclipse.jdt.core.prefs Wed Apr  3 15:33:02 2013
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6

Added: ace/trunk/org.apache.ace.nodelauncher/amazon.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/amazon.bnd?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/amazon.bnd (added)
+++ ace/trunk/org.apache.ace.nodelauncher/amazon.bnd Wed Apr  3 15:33:02 2013
@@ -0,0 +1,50 @@
+Private-Package: \
+	META-INF.services,\
+	META-INF.maven.*,\
+	functions,\
+	org.jclouds.*,\
+	com.google.*,\
+	net.schmizz.*,\
+	org.nnsoft.*,\
+	org.aopalliance.*,\
+	net.oauth.*,\
+	org.apache.commons.io.*,\
+	javax.inject,\
+	com.jcraft.*,\
+	javax.annotation.*,\
+	javax.ws.*,\
+	org.slf4j.*,\
+	org.bouncycastle.*,\
+	com.sun.jersey.*
+Bundle-Activator: \
+	org.apache.ace.nodelauncher.amazon.Activator
+Import-Package: \
+	!com.google.*,\
+	!junit.*,\
+	!javax.mail.*,\
+	!javax.inject.*,\
+	!javax.ws.*,\
+	!com.jamesmurty.utils,\
+	!com.jcraft.jzlib,\
+	!javax.swing*,\
+	!org.apache.commons.io.*,\
+	!org.bouncycastle.*,\
+	!sun.misc,\
+	!com.sun.*,\
+	!org.slf4j.*,\
+	!COM.jrockit.reflect,\
+	!COM.newmonics.PercClassLoader,\
+	!jrockit.vm,\
+	!net.sf.cglib.asm.util,\
+	!org.apache.bsf,\
+	!org.apache.bsf.*,\
+	!org.apache.tools.ant,\
+	!org.apache.tools.ant.types,\
+	!sun.reflect,\
+	*
+Export-Package: \
+	org.jclouds.compute.domain,\
+	org.apache.ace.nodelauncher.amazon
+Include-Resource:\
+	META-INF/services/org.jclouds.apis.ApiMetadata=resources/org.jclouds.apis.ApiMetadata
+Bundle-Version: 1.0.0

Added: ace/trunk/org.apache.ace.nodelauncher/api.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/api.bnd?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/api.bnd (added)
+++ ace/trunk/org.apache.ace.nodelauncher/api.bnd Wed Apr  3 15:33:02 2013
@@ -0,0 +1,2 @@
+Export-Package: org.apache.ace.nodelauncher
+Bundle-Version: 1.0.0

Added: ace/trunk/org.apache.ace.nodelauncher/bnd.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/bnd.bnd?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/bnd.bnd (added)
+++ ace/trunk/org.apache.ace.nodelauncher/bnd.bnd Wed Apr  3 15:33:02 2013
@@ -0,0 +1,32 @@
+-buildpath: osgi.core,\
+	osgi.cmpn,\
+	org.apache.felix.dependencymanager,\
+	org.apache.ace.test;version=latest,\
+	aopalliance;version=1.0,\
+	aws-common;version=1.5.0.beta_6,\
+	aws-ec2;version=1.5.0.beta_6,\
+	bcprov;version=1.46.0,\
+	commons-io;version=2.0,\
+	ec2;version=1.5.0.beta_6,\
+	com.google.gson;version=2.2,\
+	com.google.guava;version=12.0,\
+	com.google.inject;version=3.0,\
+	com.google.inject.assistedinject;version=3.0,\
+	com.vaadin,\
+	javax.inject;version=1,\
+	jclouds-bouncycastle;version=1.5.0.beta_6,\
+	jclouds-compute;version=1.5.0.beta_6,\
+	jclouds-core;version=1.5.0.beta_6,\
+	jclouds-scriptbuilder;version=1.5.0.beta_6,\
+	jclouds-slf4j;version=1.5.0.beta_6,\
+	jclouds-sshj;version=1.5.0.beta_6,\
+	com.sun.jersey.core;version=1.13.0,\
+	jsr250-api;version=1.0,\
+	jsr305;version=1.3.9,\
+	oauth;version=20100527,\
+	rocoto;version=6.1,\
+	net.schmizz.sshj;version=0.8.1,\
+	org.apache.ace.webui.vaadin;version=latest,\
+	org.apache.ace.client.repository.api;version=latest,\
+	slf4j.api;version=1.6.4
+-sub: *.bnd

Added: ace/trunk/org.apache.ace.nodelauncher/build.xml
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/build.xml?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/build.xml (added)
+++ ace/trunk/org.apache.ace.nodelauncher/build.xml Wed Apr  3 15:33:02 2013
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="build">
+
+	<!-- -->
+
+	<import file="../cnf/build.xml" />
+</project>

Added: ace/trunk/org.apache.ace.nodelauncher/generate-build-path.groovy
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/generate-build-path.groovy?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/generate-build-path.groovy (added)
+++ ace/trunk/org.apache.ace.nodelauncher/generate-build-path.groovy Wed Apr  3 15:33:02 2013
@@ -0,0 +1,9 @@
+def libDir = new File("lib")
+def output = new File('buildpath.txt')
+output.text = ""
+
+libDir.listFiles().each {
+	output << "lib/${it.name};version=file,\\"
+	output << '\n'
+}
+

Added: ace/trunk/org.apache.ace.nodelauncher/generate-lib-includes.groovy
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/generate-lib-includes.groovy?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/generate-lib-includes.groovy (added)
+++ ace/trunk/org.apache.ace.nodelauncher/generate-lib-includes.groovy Wed Apr  3 15:33:02 2013
@@ -0,0 +1,9 @@
+def libDir = new File("lib")
+def output = new File('libs.txt')
+output.text = ""
+
+libDir.listFiles().each {
+	output << "@lib/${it.name},\\"
+	output << '\n'
+}
+

Added: ace/trunk/org.apache.ace.nodelauncher/generate-serviceloader-files.groovy
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/generate-serviceloader-files.groovy?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/generate-serviceloader-files.groovy (added)
+++ ace/trunk/org.apache.ace.nodelauncher/generate-serviceloader-files.groovy Wed Apr  3 15:33:02 2013
@@ -0,0 +1,16 @@
+def libDir = new File("lib")
+def serviceProviders = []
+
+libDir.listFiles().each {
+	def zipFile = new java.util.zip.ZipFile(it)
+	def metaDataFile = zipFile.getEntry('META-INF/services/org.jclouds.apis.ApiMetadata')
+	if(metaDataFile) {
+		serviceProviders << zipFile.getInputStream(metaDataFile).text		
+	}
+}
+
+def output = new File('resources/org.jclouds.apis.ApiMetadata')
+serviceProviders.each {
+	output << it
+	output << '\n'
+}
\ No newline at end of file

Added: ace/trunk/org.apache.ace.nodelauncher/resources/org.jclouds.apis.ApiMetadata
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/resources/org.jclouds.apis.ApiMetadata?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/resources/org.jclouds.apis.ApiMetadata (added)
+++ ace/trunk/org.apache.ace.nodelauncher/resources/org.jclouds.apis.ApiMetadata Wed Apr  3 15:33:02 2013
@@ -0,0 +1,2 @@
+org.jclouds.ec2.EC2ApiMetadata
+org.jclouds.compute.stub.StubApiMetadata

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncher.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncher.java?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncher.java (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncher.java Wed Apr  3 15:33:02 2013
@@ -0,0 +1,78 @@
+/*
+ * 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.ace.nodelauncher;
+
+import java.util.Properties;
+
+/**
+ * A TargetLauncher starts, stops and interrogates named nodes. These nodes
+ * represent running JVMs in some sense; they can be provided by some
+ * cloud-provider, or running JVMs on a single machine.<br>
+ * <br>
+ * It is up to the provider to decide what to run on the given Node. This can be
+ * either a single Management Agent, which can be identified by the <code>id</code>,
+ * or a Node Manager.
+ */
+public interface NodeLauncher {
+    /**
+     * Starts a new node with the given ID. Does not check whether this ID is already in use.
+     * @param id A textual ID for the node.
+     * @throws Exception Be aware that the implementation may pass through implementation-specific exceptions.
+     */
+    void start(String id) throws Exception;
+
+    /**
+     * Starts a new node with the given ID. Does not check whether this ID is already in use.
+     * The provided properties override the configuration provided in configuration. Depending on the underlying
+     * provider this could be used to specify a node type, image id etc.
+     * @param id A textual ID for the node.
+     * @param config Configuration object to override configuration properties such as node type.
+     * @throws Exception Be aware that the implementation may pass through implementation-specific exceptions.
+     */
+    void start(String id, NodeLauncherConfig config) throws Exception;
+
+    /**
+     * Destroys the node with the given ID. Does not check whether this ID actually exists.
+     * @param id A textual ID for the node.
+     * @throws Exception Be aware that the implementation may pass through implementation-specific exceptions.
+     */
+    void stop(String id) throws Exception;
+
+    /**
+     * If available, return a default configuration object. May return null if not available in an implementation.
+     * @return Default launcher configuration, or null if not available.
+     */
+    NodeLauncherConfig getDefaultConfig();
+
+    /**
+     * @return  The currently set configuration object if available, or null if not available.
+     */
+    NodeLauncherConfig getCurrentConfig();
+    
+    /**
+     * Retrieves properties from the node. These will include, at least
+     * <ul>
+     * <li><em>ip</em> The public IP address of the node.</li>
+     * </ul>
+     * @param id The textual ID for the node.
+     * @return the properties of the node, or <code>null</code> if this node cannot be found.
+     * @throws Exception Be aware that the implementation may pass through implementation-specific exceptions.
+     */
+    Properties getProperties(String id) throws Exception;
+}

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncherConfig.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncherConfig.java?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncherConfig.java (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/NodeLauncherConfig.java Wed Apr  3 15:33:02 2013
@@ -0,0 +1,31 @@
+/*
+ * 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.ace.nodelauncher;
+
+/**
+ * Empty interface that should be implemented by NodeLauncherConfig implmentation. The interface is empty
+ * because configuration is very different for each kind of node (e.g. an embedded node vs a jclouds node) it's
+ * not possible to have a standard interface for configuration.
+ * The interface is required however so that the NodeLauncherConfig can still be independent of specific node types.
+ * Clients of this interface (e.g. UI) should cast this interface to the concrete implementation it's built for.
+ *
+ */
+public interface NodeLauncherConfig {
+
+}

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/Activator.java?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/Activator.java (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/Activator.java Wed Apr  3 15:33:02 2013
@@ -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.
+ */
+package org.apache.ace.nodelauncher.amazon;
+
+import java.util.Properties;
+
+import org.apache.ace.nodelauncher.NodeLauncher;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends DependencyActivatorBase {
+
+    @Override
+    public void init(BundleContext context, DependencyManager manager) throws Exception {
+        Properties props = new Properties();
+        props.put("osgi.command.scope", "node");
+        props.put("osgi.command.function", new String[] {"start", "stop", "properties"});
+        manager.add(createComponent()
+            .setInterface(NodeLauncher.class.getName(), props)
+            .setImplementation(AmazonNodeLauncher.class)
+            .add(createConfigurationDependency()
+                .setPid(AmazonNodeLauncher.PID)));
+    }
+
+    @Override
+    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+
+    }
+
+}

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java Wed Apr  3 15:33:02 2013
@@ -0,0 +1,411 @@
+/*
+ * 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.ace.nodelauncher.amazon;
+
+import com.google.common.io.Files;
+import org.apache.ace.nodelauncher.NodeLauncher;
+import org.apache.ace.nodelauncher.NodeLauncherConfig;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeState;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.RunScriptOptions;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.ec2.compute.options.EC2TemplateOptions;
+import org.jclouds.ec2.domain.InstanceType;
+import org.jclouds.scriptbuilder.domain.Statements;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Dictionary;
+import java.util.Properties;
+import java.util.Set;
+
+import static org.jclouds.compute.predicates.NodePredicates.runningInGroup;
+/**
+ * Simple NodeLauncher implementation that launches nodes based on a given AMI in Amazon EC2.
+ * We expect the AMI we launch to have a java on its path, at least after bootstrap.<br><br>
+ * <p/>
+ * This service is configured using Config Admin; see the constants in the class for more information
+ * about this.<br><br>
+ * <p/>
+ * After the node has been started up, this service will install a management agent on it. For this
+ * to work, there should be an ace-launcher in the OBR of the server the node should connect to.
+ */
+public class AmazonNodeLauncher implements NodeLauncher, ManagedService {
+    public static final String PID = "org.apache.ace.nodelauncher.amazon";
+
+    /**
+     * Configuration key: The ACE server the newly started nodes should connect to.
+     */
+    public static final String SERVER = "server";
+
+    /**
+     * Configuration key: The ID of the AMI to use. Note that this AMI should be available
+     * in the location ("availability zone") you configure.
+     */
+    public static final String AMI_ID = "amiId";
+
+    /**
+     * Configuration key: The ID of the AMI owner to use. You need this when you want to use your own AMIs.
+     */
+    public static final String AMI_OWNER_ID = "amiOwnerId";
+
+    /**
+     * Configuration key: The location where the node should be started; this is an Amazon "availability zone",
+     * something like "eu-west-1".
+     */
+    public static final String LOCATION = "location";
+
+    /**
+     * Configuration key: the Amazon access key ID.
+     */
+    public static final String ACCESS_KEY_ID = "accessKeyid";
+
+    /**
+     * Configuration key: The secret key that goes with your access key.
+     */
+    public static final String SECRET_ACCESS_KEY = "secretAccessKey";
+
+    /**
+     * Configuration key: The (optional) name of an existing keypair to use when creating a new node. If you
+     * do not specify it, a new keypair will be created. Specifying an existing keypair makes it easier to
+     * for example log into each node with SSH using your existing keypair.
+     */
+    public static final String KEYPAIR = "keypair";
+
+    /**
+     * Configuration key: A prefix to use for all nodes launched by this service. You can use this (a) allow
+     * multiple nodes with the same ID, but launcher from different NodeLauncher services, or (b) to more
+     * easily identify your nodes in the AWS management console.
+     */
+    public static final String TAG_PREFIX = "tagPrefix";
+
+    /**
+     * Configuration key: A piece of shell script that is run <em>before</em> the management agent is started.
+     */
+    public static final String NODE_BOOTSTRAP = "nodeBootstrap";
+
+    /**
+     * Configuration key: A set of VM options to pass to the JVM when starting the management agent, as a single string.
+     */
+    public static final String VM_OPTIONS = "vmOptions";
+
+    /**
+     * Configuration key: Any command line arguments you want to pass to the launcher; see the ace-launcher for
+     * the possible options.
+     */
+    public static final String LAUNCHER_ARGUMENTS = "launcherArguments";
+
+    /**
+     * Configuration key: Extra ports to open on the nodes, besides the default ones (see DEFAULT_PORTS).
+     */
+    public static final String EXTRA_PORTS = "extraPorts";
+
+    /**
+     * Configuration key: Should we run the process as root?
+     */
+    public static final String RUN_AS_ROOT = "runAsRoot";
+
+    /**
+     * Configuration key: The hardware ID to use for the node.
+     */
+    public static final String HARDWARE_ID = "hardwareId";
+
+    /**
+     * Default set of ports to open on a node.
+     */
+    public static final int[] DEFAULT_PORTS = new int[]{22, 80, 8080};
+
+    /**
+     * Configuration key: The (optional) name of the JAR to launch to
+     * bootstrap the OSGi framework (or whatever you want to run on the
+     * node).
+     */
+    public static final String ACE_LAUNCHER = "aceLauncher";
+
+    /**
+     * Configuration key: An additional list of artifacts that must be
+     * downloaded from the OBR when bootstrapping.
+     */
+    public static final String ADDITIONAL_OBR_DOWNLOADS = "additionalObrDownloads";
+
+    /**
+     * Configuration key: An additional list of URLs that must be downloaded when
+     * bootstrapping.
+     */
+    public static final String EXTERNAL_DOWNLOAD_URLS = "externalDownloadUrls";
+
+    /**
+     * Configuration key: The (optional) ssh user to use when connecting to the node. Uses jclouds defaults by default,
+     * which is root and ec2-user.
+     */
+    public static final String SSH_USER = "sshUser";
+
+    /**
+     * Configuration key: The (optional) private key file, which you must install on
+     * the ACE server locally if you want it to be used when creating new nodes.
+     */
+    private static final String PRIVATE_KEY_FILE = "privateKeyFile";
+
+    /**
+     * Default configuration object. Properties are read from the nodelauncher configuration file.
+     */
+    private JcloudsNodeLauncherConfig m_defaultNodeConfig;
+
+    /**
+     * Current configuration object. This reflects settings done from the UI for example.
+     * This instance is set when a node is started.
+     */
+    private JcloudsNodeLauncherConfig m_currentConfig;
+
+
+    public void start(String id) throws Exception {
+
+        start(id, m_defaultNodeConfig);
+    }
+
+    public void start(String id, NodeLauncherConfig cfg) throws Exception {
+        JcloudsNodeLauncherConfig config = (JcloudsNodeLauncherConfig) cfg;
+        m_currentConfig = config;
+
+        ComputeService computeService = config.getComputeService();
+        TemplateBuilder template = computeService.templateBuilder()
+                .imageId(config.getImageId())
+                .hardwareId(config.getHardwareId())
+                .locationId(config.getLocation());
+
+        int[] extraPorts = parseExtraPorts(config.getExtraPorts());
+        int[] inboundPorts = mergePorts(DEFAULT_PORTS, extraPorts);
+
+        TemplateOptions options = new EC2TemplateOptions()
+                .as(EC2TemplateOptions.class).inboundPorts(inboundPorts)
+                .blockOnComplete(false)
+                .runAsRoot(config.isRunAsRoot());
+
+        if (useConfiguredKeyPair(config)) {
+            options.as(EC2TemplateOptions.class).keyPair(config.getKeyPair());
+        }
+
+        template.options(options);
+
+        Set<? extends NodeMetadata> tag = computeService.createNodesInGroup(config.getTagPrefix() + id, 1, template.build());
+        if (!useConfiguredPrivateKey(config)) {
+            System.out.println("In case you need it, this is the key to ssh to " + id + ":\n" + tag.iterator().next().getCredentials().credential);
+        }
+
+        LoginCredentials.Builder loginBuilder = LoginCredentials.builder();
+
+        if (config.getSshUser() != null && config.getSshUser().length() > 0) {
+            loginBuilder.user(config.getSshUser());
+        } else {
+            loginBuilder.user("ec2-user");
+        }
+
+        if (useConfiguredPrivateKey(config)) {
+            loginBuilder.privateKey(Files.toString(new File(config.getPrivateKeyFile()), Charset.defaultCharset()));
+        }
+
+        computeService.runScriptOnNodesMatching(runningInGroup(config.getTagPrefix() + id),
+                Statements.exec(buildStartupScript(id, config)),
+                RunScriptOptions.Builder.blockOnComplete(false).overrideLoginCredentials(loginBuilder.build()));
+    }
+
+    private boolean useConfiguredPrivateKey(JcloudsNodeLauncherConfig config) {
+        return config.getPrivateKeyFile() != null && config.getPrivateKeyFile().length() > 0;
+    }
+
+    private boolean useConfiguredKeyPair(JcloudsNodeLauncherConfig config) {
+        return config.getKeyPair() != null && config.getKeyPair().length() > 0;
+    }
+
+    int[] mergePorts(int[] first, int[] last) {
+        int[] result = new int[first.length + last.length];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = (i < first.length) ? first[i] : last[i - first.length];
+        }
+        return result;
+    }
+
+    int[] parseExtraPorts(String[] extraPorts) {
+        if(extraPorts == null || extraPorts.length == 0) {
+            return new int[0];
+        }
+
+        int[] result = new int[extraPorts.length];
+
+        for (int i = 0; i < extraPorts.length; i++) {
+            result[i] = Integer.parseInt(extraPorts[i].trim());
+        }
+
+        return result;
+    }
+
+    private String buildStartupScript(String id, JcloudsNodeLauncherConfig config) throws MalformedURLException {
+        StringBuilder script = new StringBuilder("cd ~; ");
+        if (config.getNodeBootstrap() != null && config.getNodeBootstrap().length() > 0) {
+            script.append(config.getNodeBootstrap()).append(" ; ");
+        }
+
+        script.append("wget ").append(new URL(config.getServer(), "/obr/" + config.getAceLauncher())).append(" ;");
+        if (config.getAdditionalObrDownloads().length() > 0) {
+            for (String additonalDownload : config.getAdditionalObrDownloads().split(",")) {
+                script.append("wget ").append(new URL(config.getServer(), "/obr/" + additonalDownload.trim())).append(" ;");
+            }
+        }
+
+        if (config.getExternalDownloadUrls().length() > 0) {
+            for (String additonalDownload : config.getExternalDownloadUrls().split(",")) {
+                script.append("wget ").append(additonalDownload.trim()).append(" ;");
+            }
+        }
+        script.append("nohup java -jar ").append(config.getAceLauncher()).append(" ");
+        script.append("discovery=").append(config.getServer().toExternalForm()).append(" ");
+        script.append("identification=").append(id).append(" ");
+        script.append(config.getVmOptions()).append(" ");
+        script.append(config.getLauncherArguments());
+        return script.toString();
+    }
+
+    public void stop(String id) {
+
+        getActiveConfig().getComputeService().destroyNodesMatching(runningInGroup(getActiveConfig().getTagPrefix() + id));
+    }
+
+    public Properties getProperties(String id) throws Exception {
+        Properties result = new Properties();
+
+        JcloudsNodeLauncherConfig config = getActiveConfig();
+        NodeMetadata nodeMetadata = getNodeMetadataForRunningNodeWithTag(config.getTagPrefix() + id, config);
+        if (nodeMetadata == null) {
+            return null;
+        }
+        result.put("id", id);
+        result.put("node-id", nodeMetadata.getId());
+        result.put("ip", nodeMetadata.getPublicAddresses().iterator().next());
+
+        return result;
+    }
+
+    private JcloudsNodeLauncherConfig getActiveConfig() {
+        return m_currentConfig != null ? m_currentConfig : m_defaultNodeConfig;
+    }
+
+    private NodeMetadata getNodeMetadataForRunningNodeWithTag(String tag, JcloudsNodeLauncherConfig config) {
+
+        for (ComputeMetadata node : config.getComputeService().listNodes()) {
+            NodeMetadata candidate = config.getComputeService().getNodeMetadata(node.getId());
+            if (tag.equals(candidate.getGroup()) && candidate.getState().equals(NodeState.RUNNING)) {
+                return candidate;
+            }
+        }
+        return null;
+    }
+
+    public void updated(@SuppressWarnings("rawtypes") Dictionary properties) throws ConfigurationException {
+        if (properties != null) {
+            URL server;
+            try {
+                server = new URL(getConfigProperty(properties, SERVER));
+            } catch (MalformedURLException e) {
+                throw new ConfigurationException(SERVER, getConfigProperty(properties, SERVER) + " is not a valid URL.", e);
+            }
+            String amiId = getConfigProperty(properties, AMI_ID);
+            String amiOwnerId = getConfigProperty(properties, AMI_OWNER_ID, "");
+            String location = getConfigProperty(properties, LOCATION);
+            String hardwareId = getConfigProperty(properties, HARDWARE_ID, InstanceType.C1_MEDIUM);
+            String accessKeyId = getConfigProperty(properties, ACCESS_KEY_ID);
+            String secretAccessKey = getConfigProperty(properties, SECRET_ACCESS_KEY);
+            String keyPair = getConfigProperty(properties, KEYPAIR, "");
+            String privateKeyFile = getConfigProperty(properties, PRIVATE_KEY_FILE, "");
+            String vmOptions = getConfigProperty(properties, VM_OPTIONS, "");
+            String nodeBootstrap = getConfigProperty(properties, NODE_BOOTSTRAP, "");
+            String tagPrefix = getConfigProperty(properties, TAG_PREFIX, "");
+            String launcherArguments = getConfigProperty(properties, LAUNCHER_ARGUMENTS, "");
+            String extraPorts = getConfigProperty(properties, EXTRA_PORTS, "");
+            String runAsRoot = getConfigProperty(properties, RUN_AS_ROOT, "false");
+            String aceLauncher = getConfigProperty(properties, ACE_LAUNCHER, "ace-launcher.jar");
+            String additionalObrDownloads = getConfigProperty(properties, ADDITIONAL_OBR_DOWNLOADS, "");
+            String externalDownloadUrls = getConfigProperty(properties, EXTERNAL_DOWNLOAD_URLS, "");
+            String sshUser = getConfigProperty(properties, SSH_USER, "ec2-user");
+
+            m_defaultNodeConfig = new JcloudsNodeLauncherConfig()
+                    .setAccessKeyId(accessKeyId)
+                    .setSecretAccessKey(secretAccessKey)
+                    .setServer(server)
+                    .setImageId(amiId)
+                    .setImageOwnerId(amiOwnerId)
+                    .setLocation(location)
+                    .setHardwareId(hardwareId)
+                    .setKeyPair(keyPair)
+                    .setPrivateKeyFile(privateKeyFile)
+                    .setTagPrefix(tagPrefix)
+                    .setVmOptions(vmOptions)
+                    .setLauncherArguments(launcherArguments)
+                    .setExtraPorts(extraPorts)
+                    .setRunAsRoot(Boolean.parseBoolean(runAsRoot))
+                    .setAccessKeyId(accessKeyId)
+                    .setSecretAccessKey(secretAccessKey)
+                    .setNodeBootstrap(nodeBootstrap)
+                    .setAceLauncher(aceLauncher)
+                    .setAdditionalObrDownloads(additionalObrDownloads)
+                    .setExternalDownloadUrls(externalDownloadUrls)
+                    .setSshUser(sshUser);
+
+            m_defaultNodeConfig.createComputeServiceContext();
+        }
+    }
+
+
+    private String getConfigProperty(@SuppressWarnings("rawtypes") Dictionary settings, String id) throws ConfigurationException {
+        return getConfigProperty(settings, id, null);
+    }
+
+    private String getConfigProperty(@SuppressWarnings("rawtypes") Dictionary settings, String id, String defaultValue) throws ConfigurationException {
+        String result = (String) settings.get(id);
+        if (result == null) {
+            if (defaultValue == null) {
+                throw new ConfigurationException(id, "key missing");
+            } else {
+                return defaultValue;
+            }
+        }
+        return result;
+    }
+
+    public void stop() {
+        if (m_currentConfig != null) {
+            m_currentConfig.close();
+        }
+    }
+
+    public NodeLauncherConfig getDefaultConfig() {
+        return m_defaultNodeConfig;
+    }
+
+    public JcloudsNodeLauncherConfig getCurrentConfig() {
+        return m_currentConfig;
+    }
+}

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java Wed Apr  3 15:33:02 2013
@@ -0,0 +1,273 @@
+/*
+ * 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.ace.nodelauncher.amazon;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+import org.apache.ace.nodelauncher.NodeLauncherConfig;
+import org.jclouds.Context;
+import org.jclouds.ContextBuilder;
+import org.jclouds.aws.ec2.reference.AWSEC2Constants;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.ComputeServiceContextFactory;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.sshj.config.SshjSshClientModule;
+
+import java.net.URL;
+import java.util.Properties;
+import java.util.Set;
+
+public class JcloudsNodeLauncherConfig implements NodeLauncherConfig {
+    private ComputeServiceContext m_computeServiceContext;
+    
+    private URL m_server;
+    private String m_hardwareId;
+    private String m_ImageId;
+    private String m_ImageOwnerId;
+    private String m_location;
+    private String m_tagPrefix;
+    private String[] m_extraPorts;
+    private boolean m_runAsRoot;
+    private String m_keyPair;
+    private String m_privateKeyFile;
+    private String m_vmOptions;
+    private String m_launcherArguments;
+
+    private String m_accessKeyId;
+    private String m_secretAccessKey;
+    
+    private String m_nodeBootstrap;
+    private String m_aceLauncher;
+    private String m_additionalObrDownloads;
+    private String m_externalDownloadUrls;
+    private String m_sshUser;
+
+    public URL getServer() {
+        return m_server;
+    }
+
+    public JcloudsNodeLauncherConfig setServer(URL server) {
+        m_server = server;
+        return this;
+    }
+
+    public String getHardwareId() {
+        return m_hardwareId;
+    }
+
+    public JcloudsNodeLauncherConfig setHardwareId(String hardwareId) {
+        m_hardwareId = hardwareId;
+        return this;
+    }
+
+    public String getImageId() {
+        return m_ImageId;
+    }
+
+    public JcloudsNodeLauncherConfig setImageId(String m_ImageId) {
+        this.m_ImageId = m_ImageId;
+        return this;
+    }
+
+    public String getImageOwnerId() {
+        return m_ImageOwnerId;
+    }
+
+    public String getTagPrefix() {
+        return m_tagPrefix;
+    }
+
+    public JcloudsNodeLauncherConfig setTagPrefix(String tagPrefix) {
+        this.m_tagPrefix = tagPrefix;
+        return this;
+    }
+
+    public String getLocation() {
+        return m_location;
+    }
+
+    public JcloudsNodeLauncherConfig setLocation(String location) {
+        m_location = location;
+        return this;
+    }
+
+    public String[] getExtraPorts() {
+        return m_extraPorts;
+    }
+
+    public JcloudsNodeLauncherConfig setExtraPorts(String... extraPorts) {
+        m_extraPorts = extraPorts;
+        return this;
+    }
+
+    public boolean isRunAsRoot() {
+        return m_runAsRoot;
+    }
+
+    public JcloudsNodeLauncherConfig setRunAsRoot(boolean runAsRoot) {
+        m_runAsRoot = runAsRoot;
+        return this;
+    }
+
+    public String getKeyPair() {
+        return m_keyPair;
+    }
+
+    public JcloudsNodeLauncherConfig setKeyPair(String keyPair) {
+        m_keyPair = keyPair;
+        return this;
+    }
+
+    public String getPrivateKeyFile() {
+        return m_privateKeyFile;
+    }
+
+    public JcloudsNodeLauncherConfig setPrivateKeyFile(String privateKeyFile) {
+        m_privateKeyFile = privateKeyFile;
+        return this;
+    }
+
+    public String getVmOptions() {
+        return m_vmOptions;
+    }
+
+    public JcloudsNodeLauncherConfig setVmOptions(String vmOptions) {
+        m_vmOptions = vmOptions;
+        return this;
+    }
+
+    public String getLauncherArguments() {
+        return m_launcherArguments;
+    }
+
+    public JcloudsNodeLauncherConfig setLauncherArguments(String launcherArguments) {
+        m_launcherArguments = launcherArguments;
+        return this;
+    }
+
+    public Set<? extends Hardware> listHardwareIds() {
+        return m_computeServiceContext.getComputeService().listHardwareProfiles();
+    }
+
+    public Set<? extends Image> listImages() {
+        return m_computeServiceContext.getComputeService().listImages();
+    }
+
+    public JcloudsNodeLauncherConfig setImageOwnerId(String imageOwnerId) {
+        m_ImageOwnerId = imageOwnerId;
+        createComputeServiceContext();
+
+        return this;
+    }
+
+    public String getAccessKeyId() {
+        return m_accessKeyId;
+    }
+
+    public JcloudsNodeLauncherConfig setAccessKeyId(String accessKeyId) {
+        m_accessKeyId = accessKeyId;
+        return this;
+    }
+
+    public String getSecretAccessKey() {
+        return m_secretAccessKey;
+    }
+
+    public JcloudsNodeLauncherConfig setSecretAccessKey(String secretAccessKey) {
+        m_secretAccessKey = secretAccessKey;
+        return this;
+    }
+
+    public String getNodeBootstrap() {
+        return m_nodeBootstrap;
+    }
+
+    public JcloudsNodeLauncherConfig setNodeBootstrap(String nodeBootstrap) {
+        m_nodeBootstrap = nodeBootstrap;
+        return this;
+    }
+
+    public String getAceLauncher() {
+        return m_aceLauncher;
+    }
+
+    public JcloudsNodeLauncherConfig setAceLauncher(String aceLauncher) {
+        m_aceLauncher = aceLauncher;
+        return this;
+    }
+
+    public String getAdditionalObrDownloads() {
+        return m_additionalObrDownloads;
+    }
+
+    public JcloudsNodeLauncherConfig setAdditionalObrDownloads(String additionalObrDownloads) {
+        m_additionalObrDownloads = additionalObrDownloads;
+        return this;
+    }
+
+    public String getExternalDownloadUrls() {
+        return m_externalDownloadUrls;
+    }
+
+    public JcloudsNodeLauncherConfig setExternalDownloadUrls(String externalDownloadUrls) {
+        m_externalDownloadUrls = externalDownloadUrls;
+        return this;
+    }
+
+    public String getSshUser() {
+        return m_sshUser;
+    }
+
+    public JcloudsNodeLauncherConfig setSshUser(String sshUser) {
+        this.m_sshUser = sshUser;
+        return this;
+    }
+
+    /**
+     * Recreate the ComputeServiceContext. This is required after setting some properties to have an effect (e.g. changing ImageOwnerId).
+     * This is an expensive operation, only call when required.
+     */
+    public void createComputeServiceContext() {
+        if (m_computeServiceContext != null) {
+            m_computeServiceContext.close();
+        }
+
+        Properties props = new Properties();
+        if (m_ImageOwnerId != null && m_ImageOwnerId.length() > 0) {
+            props.setProperty(AWSEC2Constants.PROPERTY_EC2_AMI_QUERY, "owner-id=" + m_ImageOwnerId + ";state=available;image-type=machine;root-device-type=ebs");
+            props.setProperty(AWSEC2Constants.PROPERTY_EC2_CC_AMI_QUERY, "");
+        }
+        
+        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
+        m_computeServiceContext = ContextBuilder.newBuilder("aws-ec2").credentials(m_accessKeyId, m_secretAccessKey).modules(ImmutableSet.<Module>of(new SshjSshClientModule())).overrides(props).build(ComputeServiceContext.class);
+        //m_computeServiceContext = new ComputeServiceContextFactory().createContext("aws-ec2", m_accessKeyId, m_secretAccessKey, ImmutableSet.<Module>of(new SshjSshClientModule()), props);
+    }
+
+    public ComputeService getComputeService() {
+        return m_computeServiceContext.getComputeService();
+    }
+
+    public void close() {
+        if(m_computeServiceContext != null) {
+            m_computeServiceContext.close();
+        }
+    }
+}

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/packageinfo
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/packageinfo?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/packageinfo (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/amazon/packageinfo Wed Apr  3 15:33:02 2013
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/packageinfo
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/packageinfo?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/packageinfo (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/packageinfo Wed Apr  3 15:33:02 2013
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/Activator.java?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/Activator.java (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/Activator.java Wed Apr  3 15:33:02 2013
@@ -0,0 +1,51 @@
+/*
+ * 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.ace.nodelauncher.ui;
+
+import org.apache.ace.nodelauncher.NodeLauncher;
+import org.apache.ace.webui.UIExtensionFactory;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+
+import java.util.Properties;
+
+public class Activator extends DependencyActivatorBase {
+    @Override
+    public void init(BundleContext context, DependencyManager manager) throws Exception {
+        Properties props = new Properties();
+        props.put(UIExtensionFactory.EXTENSION_POINT_KEY, UIExtensionFactory.EXTENSION_POINT_VALUE_TARGET);
+        
+        manager.add(createComponent()
+            .setInterface(UIExtensionFactory.class.getName(), props)
+            .setImplementation(NodeLauncherPanelFactory.class)
+            .add(createServiceDependency()
+                .setService(NodeLauncher.class)
+                .setRequired(true))
+            .add(createServiceDependency()
+                .setService(LogService.class)
+                .setRequired(false)));
+    }
+
+    @Override
+    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+        
+    }
+}

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodeLauncherPanelFactory.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodeLauncherPanelFactory.java?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodeLauncherPanelFactory.java (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodeLauncherPanelFactory.java Wed Apr  3 15:33:02 2013
@@ -0,0 +1,57 @@
+/*
+ * 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.ace.nodelauncher.ui;
+
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.ace.client.repository.stateful.StatefulTargetObject;
+import org.apache.ace.nodelauncher.NodeLauncher;
+import org.apache.ace.webui.NamedObject;
+import org.apache.ace.webui.UIExtensionFactory;
+import org.osgi.service.log.LogService;
+
+import com.vaadin.ui.Panel;
+
+public class NodeLauncherPanelFactory implements UIExtensionFactory {
+    private volatile NodeLauncher m_nodeLauncher;
+    private volatile LogService m_log;
+    
+    private final ExecutorService m_executor = Executors.newCachedThreadPool();
+    
+    public Panel create(Map<String, Object> context) {
+        NamedObject namedObject = (NamedObject) context.get("object");
+        StatefulTargetObject target = (StatefulTargetObject) namedObject.getObject();
+        return new NodePanel(this, target.getID());
+    }
+    
+    NodeLauncher getCloudService() {
+        return m_nodeLauncher;
+    }
+    
+    LogService getLogService() {
+        return m_log;
+    }
+    
+    Future<?> submit(Runnable runnable) {
+        return m_executor.submit(runnable);
+    }
+}

Added: ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodePanel.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodePanel.java?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodePanel.java (added)
+++ ace/trunk/org.apache.ace.nodelauncher/src/org/apache/ace/nodelauncher/ui/NodePanel.java Wed Apr  3 15:33:02 2013
@@ -0,0 +1,427 @@
+/*
+ * 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.ace.nodelauncher.ui;
+
+import org.apache.ace.nodelauncher.amazon.JcloudsNodeLauncherConfig;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.osgi.service.log.LogService;
+import com.vaadin.data.Property;
+import com.vaadin.ui.*;
+import com.vaadin.ui.Button.ClickListener;
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+@SuppressWarnings("serial")
+public class NodePanel extends Panel {
+    private final String m_targetId;
+    private final Lock m_targetLock = new ReentrantLock();
+    private final NodeStatusHandler m_handler = new NodeStatusHandler();
+    private final NodeLauncherPanelFactory m_factory;
+    private final Map<Action, Runnable> m_runners = new HashMap<Action, Runnable>();
+    private final Runnable m_statusGetter = new StatusGetter();
+    private TextField m_locationInput;
+    private Select m_hardwareIdSelect;
+    private TextField m_ImageOwnerIdInput;
+    private Select m_ImageIdSelect;
+    private TextField m_keyPairInput;
+    private TextField m_tagPrefixInput;
+    private TextField m_extraPortsInput;
+    private CheckBox m_runAsRootCheckbox;
+    private TextField m_privateKeyFileInput;
+    private TextField m_vmOptionsInput;
+    private TextField m_launcherArgumentsInput;
+    private TextField m_nodeBootstrapInput;
+    private TextField m_aceLauncherInput;
+    private TextField m_additionalObrDownloadsInput;
+    private TextField m_externalDownloadsInput;
+    private TextField m_sshUserInput;
+
+    private JcloudsNodeLauncherConfig config;
+
+    {
+        m_runners.put(Action.Start, new StartRunner());
+        m_runners.put(Action.Stop, new StopRunner());
+    }
+
+    public NodePanel(NodeLauncherPanelFactory factory, String target) {
+        m_factory = factory;
+        m_targetId = target;
+        config = (JcloudsNodeLauncherConfig)m_factory.getCloudService().getDefaultConfig();
+        setContent();
+        setCaption(m_targetId);
+    }
+
+    private void setContent() {
+        VerticalLayout panel = new VerticalLayout();
+        setContent(panel);
+        panel.setMargin(true);
+        panel.setSpacing(true);
+        setWidth("100%");
+
+        Label status = new NodeLabel(m_handler);
+
+        Button startButton = new ActionButton(m_handler, Action.Start);
+        Button stopButton = new ActionButton(m_handler, Action.Stop);
+        HorizontalLayout buttonPanel = new HorizontalLayout();
+        buttonPanel.addComponent(startButton);
+        buttonPanel.addComponent(stopButton);
+        buttonPanel.setSpacing(true);
+        
+
+        Table propertiesTable = new PropertiesTable(m_handler);
+        propertiesTable.setWidth("100%");
+
+        panel.addComponent(status);
+        panel.addComponent(buttonPanel);
+
+        m_locationInput = new TextField("Location", config.getLocation());
+        panel.addComponent(m_locationInput);
+
+        Set<? extends Hardware> hardwares = config.listHardwareIds();
+
+        m_hardwareIdSelect = new Select("Node type");
+        createHardwareItems(hardwares);
+        panel.addComponent(m_hardwareIdSelect);
+
+        m_ImageOwnerIdInput = new TextField("Image owner ID", config.getImageOwnerId());
+
+        panel.addComponent(m_ImageOwnerIdInput);
+
+        m_ImageIdSelect = new Select("Image ID");
+        createImageItems();
+        panel.addComponent(m_ImageIdSelect);
+
+        m_ImageOwnerIdInput.addListener(new Property.ValueChangeListener() {
+            public void valueChange(Property.ValueChangeEvent valueChangeEvent) {
+                config.setImageOwnerId((String) valueChangeEvent.getProperty().getValue());
+                m_ImageIdSelect.removeAllItems();
+
+                createImageItems();
+            }
+        });
+
+
+        m_keyPairInput = new TextField("Keypair", config.getKeyPair());
+        panel.addComponent(m_keyPairInput);
+
+        m_tagPrefixInput = new TextField("Tag prefix", config.getTagPrefix());
+        panel.addComponent(m_tagPrefixInput);
+
+        String[] extraPorts = config.getExtraPorts();
+        StringBuilder extraPortsValue = new StringBuilder();
+        for (String extraPort : extraPorts) {
+            extraPortsValue.append(extraPort).append(",");
+        }
+        m_extraPortsInput = new TextField("Extra ports (comma separated", extraPortsValue.toString());
+        panel.addComponent(m_extraPortsInput);
+
+        m_runAsRootCheckbox = new CheckBox("Run as root", config.isRunAsRoot());
+        panel.addComponent(m_runAsRootCheckbox);
+
+        m_privateKeyFileInput = new TextField("Private key file", config.getPrivateKeyFile());
+        panel.addComponent(m_privateKeyFileInput);
+
+        m_vmOptionsInput = new TextField("VM options", config.getVmOptions());
+        panel.addComponent(m_vmOptionsInput);
+
+        m_launcherArgumentsInput = new TextField("Launcher arguments", config.getLauncherArguments());
+        panel.addComponent(m_launcherArgumentsInput);
+
+        m_nodeBootstrapInput = new TextField("Node bootstrap script", config.getNodeBootstrap());
+        panel.addComponent(m_nodeBootstrapInput);
+
+        m_aceLauncherInput = new TextField("ACE launcher", config.getAceLauncher());
+        panel.addComponent(m_aceLauncherInput);
+
+        m_additionalObrDownloadsInput = new TextField("Additional OBR downloads (comma separated", config.getAdditionalObrDownloads());
+        panel.addComponent(m_additionalObrDownloadsInput);
+
+        m_externalDownloadsInput = new TextField("External download urls (comman separated", config.getExternalDownloadUrls());
+        panel.addComponent(m_externalDownloadsInput);
+
+        m_sshUserInput = new TextField("SSH username", "ec2-user");
+        panel.addComponent(m_sshUserInput);
+
+        panel.addComponent(propertiesTable);
+
+        m_factory.submit(m_statusGetter);
+    }
+
+    private void createHardwareItems(Set<? extends Hardware> hardwares) {
+        for (Hardware hardware : hardwares) {
+            m_hardwareIdSelect.addItem(hardware.getId());
+            m_hardwareIdSelect.setItemCaption(hardware.getId(), hardware.getName());
+            if(hardware.getId().equals(config.getHardwareId())) {
+                m_hardwareIdSelect.select(hardware.getId());
+            }
+        }
+    }
+
+    private void createImageItems() {
+        Set<? extends Image> images = config.listImages();
+        for (Image image : images) {
+            m_ImageIdSelect.addItem(image.getId());
+            m_ImageIdSelect.setItemCaption(image.getId(), image.getName());
+            if(image.getId().endsWith(config.getImageId())) {
+                m_ImageIdSelect.select(image.getId());
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    private class ActionButton extends Button implements NodeStatusHandler.NodeStatusListener, ClickListener {
+        private final Action m_action;
+
+        public ActionButton(NodeStatusHandler handler, Action action) {
+            m_action = action;
+            handler.addListener(this);
+            addListener((ClickListener) this);
+            nodeStatusChanged(NodeStatus.UNKNOWN, null);
+            setCaption(m_action.toString());
+        }
+
+        public void nodeStatusChanged(NodeStatus status, Properties info) {
+            setEnabled(status.getNextAction().equals(m_action));
+        }
+
+        public void buttonClick(ClickEvent event) {
+            Runnable runner = m_runners.get(m_action);
+            if (runner != null) {
+                m_factory.submit(runner);
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    private static class NodeLabel extends Label implements NodeStatusHandler.NodeStatusListener {
+        public NodeLabel(NodeStatusHandler handler) {
+            handler.addListener(this);
+            nodeStatusChanged(NodeStatus.UNKNOWN, null);
+        }
+
+        public void nodeStatusChanged(NodeStatus status, Properties info) {
+            setValue(status.toString());
+        }
+    }
+
+    private static class PropertiesTable extends Table implements NodeStatusHandler.NodeStatusListener {
+        public PropertiesTable(NodeStatusHandler handler) {
+            super("Properties");
+            handler.addListener(this);
+            nodeStatusChanged(NodeStatus.UNKNOWN, null);
+            addContainerProperty("Key", String.class, null);
+            addContainerProperty("Value", String.class, null);
+            setPageLength(0);
+        }
+
+        public void nodeStatusChanged(NodeStatus status, Properties info) {
+            removeAllItems();
+            int index = 0;
+            if (info != null) {
+                Enumeration<Object> keys = info.keys();
+                while (keys.hasMoreElements()) {
+                    Object key = keys.nextElement();
+                    addItem(new Object[] {key.toString(), info.get(key).toString()}, index++);
+                }
+            }
+        }
+    }
+
+    private class StatusGetter extends LockedRunner {
+        public void doRun() {
+            try {
+                Properties properties = m_factory.getCloudService().getProperties(m_targetId);
+                if (properties != null) {
+                    m_handler.setStatus(NodeStatus.RUNNING, properties);
+                }
+                else {
+                    m_handler.setStatus(NodeStatus.STOPPED);
+                }
+            }
+            catch (Exception e) {
+                m_handler.setStatus(NodeStatus.UNKNOWN);
+                m_factory.getLogService().log(LogService.LOG_ERROR,
+                        "Error getting status for node with ID " + m_targetId ,e);
+            }
+        }
+    }
+
+    private class StartRunner extends LockedRunner {
+        @Override
+        protected void doRun() {
+            try {
+                m_handler.setStatus(NodeStatus.STARTING);
+
+                String sshUser = (String) m_sshUserInput.getValue();
+                String location = (String) m_locationInput.getValue();
+                String hardwareId = (String) m_hardwareIdSelect.getValue();
+                String imageOwnerId = (String) m_ImageOwnerIdInput.getValue();
+                String imageId = (String) m_ImageIdSelect.getValue();
+                String keyPair = (String) m_keyPairInput.getValue();
+                String tagPrefix = (String) m_tagPrefixInput.getValue();
+                String[] extraPorts = ((String)m_extraPortsInput.getValue()).split(",");
+                boolean runAsRoot = m_runAsRootCheckbox.booleanValue();
+                String privateKeyFile = (String)m_privateKeyFileInput.getValue();
+                String vmOptions = (String)m_vmOptionsInput.getValue();
+                String laucherArgs = (String)m_launcherArgumentsInput.getValue();
+                String nodeBootStrap = (String)m_nodeBootstrapInput.getValue();
+                String aceLauncher = (String)m_aceLauncherInput.getValue();
+                String additionalObrDownloads = (String)m_additionalObrDownloadsInput.getValue();
+                String externalDownloads = (String)m_externalDownloadsInput.getValue();
+
+                config.setSshUser(sshUser);
+                config.setLocation(location);
+                config.setHardwareId(hardwareId);
+
+                if(imageOwnerId.length() > 0) {
+                    config.setImageOwnerId(imageOwnerId);
+                }
+
+                config.setImageId(imageId);
+                config.setKeyPair(keyPair);
+                config.setTagPrefix(tagPrefix);
+                config.setExtraPorts(extraPorts);
+                config.setRunAsRoot(runAsRoot);
+                config.setPrivateKeyFile(privateKeyFile);
+                config.setVmOptions(vmOptions);
+                config.setLauncherArguments(laucherArgs);
+                config.setNodeBootstrap(nodeBootStrap);
+                config.setAceLauncher(aceLauncher);
+                config.setAdditionalObrDownloads(additionalObrDownloads);
+                config.setExternalDownloadUrls(externalDownloads);
+
+                m_factory.getCloudService().start(m_targetId, config);
+                m_handler.setStatus(NodeStatus.INITIALIZING);
+                disableInputFields();
+
+            }
+            catch (Exception e) {
+                m_handler.setStatus(NodeStatus.ERROR);
+                m_factory.getLogService().log(LogService.LOG_ERROR, "Error starting node with ID " + m_targetId, e);
+            }
+            m_factory.submit(m_statusGetter);
+        }
+    }
+
+    private void disableInputFields() {
+        m_locationInput.setEnabled(false);
+        m_hardwareIdSelect.setEnabled(false);
+        m_ImageOwnerIdInput.setEnabled(false);
+        m_ImageIdSelect.setEnabled(false);
+        m_keyPairInput.setEnabled(false);
+        m_tagPrefixInput.setEnabled(false);
+        m_extraPortsInput.setEnabled(false);
+        m_runAsRootCheckbox.setEnabled(false);
+        m_privateKeyFileInput.setEnabled(false);
+        m_vmOptionsInput.setEnabled(false);
+        m_launcherArgumentsInput.setEnabled(false);
+        m_nodeBootstrapInput.setEnabled(false);
+        m_aceLauncherInput.setEnabled(false);
+        m_additionalObrDownloadsInput.setEnabled(false);
+        m_externalDownloadsInput.setEnabled(false);
+    }
+
+    private class StopRunner extends LockedRunner {
+        @Override
+        protected void doRun() {
+            try {
+                m_handler.setStatus(NodeStatus.STOPPING);
+                m_factory.getCloudService().stop(m_targetId);
+            }
+            catch (Exception e) {
+                m_handler.setStatus(NodeStatus.ERROR);
+                m_factory.getLogService().log(LogService.LOG_ERROR, "Error stopping node with ID " + m_targetId, e);
+            }
+            m_factory.submit(m_statusGetter);
+        }
+    }
+    
+    private abstract class LockedRunner implements Runnable {
+        public final void run() {
+            if (m_targetLock.tryLock()) {
+                try {
+                    doRun();
+                }
+                finally {
+                    m_targetLock.unlock();
+                }
+            }
+        }
+        
+        protected abstract void doRun();
+    }
+    
+    private static class NodeStatusHandler {
+        private final List<NodeStatusListener> m_listeners = new CopyOnWriteArrayList<NodeStatusListener>();
+
+        public interface NodeStatusListener {
+            void nodeStatusChanged(NodeStatus status, Properties info);
+        }
+
+        private void addListener(NodeStatusListener listener) {
+            m_listeners.add(listener);
+        }
+
+        public void setStatus(NodeStatus status) {
+            setStatus(status, null);
+        }
+
+        public void setStatus(NodeStatus status, Properties info) {
+            for (NodeStatusListener listener : m_listeners) {
+                listener.nodeStatusChanged(status, info);
+            }
+        }
+    }
+
+    private enum NodeStatus {
+        UNKNOWN("Getting status...", Action.None),
+        ERROR("Error", Action.Start),
+        STOPPED("Stopped", Action.Start),
+        STARTING("Starting...", Action.None),
+        INITIALIZING("Initializing...", Action.None),
+        RUNNING("Running", Action.Stop),
+        STOPPING("Stopping...", Action.None);
+
+        private final String m_label;
+        private final Action m_nextAction;
+
+        NodeStatus(String label, Action nextAction) {
+            m_label = label;
+            m_nextAction = nextAction;
+        }
+
+        public String toString() {
+            return m_label;
+        }
+        
+        public Action getNextAction() {
+            return m_nextAction;
+        }
+    }
+
+    private enum Action {
+        Start,
+        Stop,
+        None;
+    }
+
+}

Added: ace/trunk/org.apache.ace.nodelauncher/test/org/apache/ace/nodelauncher/amazon/PortParseTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/test/org/apache/ace/nodelauncher/amazon/PortParseTest.java?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/test/org/apache/ace/nodelauncher/amazon/PortParseTest.java (added)
+++ ace/trunk/org.apache.ace.nodelauncher/test/org/apache/ace/nodelauncher/amazon/PortParseTest.java Wed Apr  3 15:33:02 2013
@@ -0,0 +1,42 @@
+package org.apache.ace.nodelauncher.amazon;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+
+public class PortParseTest {
+    @Test(groups = { UNIT })
+    public void testParsePortsFromString() throws Exception {
+        AmazonNodeLauncher instance = new AmazonNodeLauncher();
+        Assert.assertTrue(assertEquals(instance.parseExtraPorts(new String[] {"1", "2", "3"}), new int[] {1, 2, 3}));
+        Assert.assertTrue(assertEquals(instance.parseExtraPorts(new String[] {}), new int[] {}));
+        Assert.assertTrue(assertEquals(instance.parseExtraPorts(new String[] {"800","900"}), new int[] {800, 900}));
+    }
+    
+    @Test(groups = { UNIT })
+    public void testMergePorts() throws Exception {
+        AmazonNodeLauncher instance = new AmazonNodeLauncher();
+        Assert.assertTrue(assertEquals(instance.mergePorts(new int[] {1, 2}, new int[] {3, 4, 5}), new int[] {1, 2, 3, 4, 5}));
+        Assert.assertTrue(assertEquals(instance.mergePorts(new int[] {1}, new int[] {}), new int[] {1}));
+        Assert.assertTrue(assertEquals(instance.mergePorts(new int[] {}, new int[] {}), new int[] {}));
+        Assert.assertTrue(assertEquals(instance.mergePorts(new int[] {}, new int[] {1, 2, 3}), new int[] {1, 2, 3}));
+    }
+    
+    private boolean assertEquals(int[] a, int[] b) {
+        if (a == null && b == null) {
+            return true;
+        }
+        if (a == null) {
+            return false;
+        }
+        if (a.length != b.length) {
+            return false;
+        }
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] != b[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}

Added: ace/trunk/org.apache.ace.nodelauncher/ui.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.nodelauncher/ui.bnd?rev=1464071&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.nodelauncher/ui.bnd (added)
+++ ace/trunk/org.apache.ace.nodelauncher/ui.bnd Wed Apr  3 15:33:02 2013
@@ -0,0 +1,3 @@
+Bundle-Activator: org.apache.ace.nodelauncher.ui.Activator
+Private-Package: org.apache.ace.nodelauncher.ui
+Bundle-Version: 1.0.0



Mime
View raw message