You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@provisionr.apache.org by as...@apache.org on 2013/04/01 10:52:24 UTC

[01/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Updated Branches:
  refs/heads/master 6559ede8b -> 6ba40c4b2


http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/org/apache/provisionr/test/ProvisionrLiveTestSupport.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/org/apache/provisionr/test/ProvisionrLiveTestSupport.java b/test-support/src/main/java/org/apache/provisionr/test/ProvisionrLiveTestSupport.java
new file mode 100644
index 0000000..4c2cdea
--- /dev/null
+++ b/test-support/src/main/java/org/apache/provisionr/test/ProvisionrLiveTestSupport.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.test;
+
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.provider.ProviderBuilder;
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Stopwatch;
+import com.google.common.io.Resources;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import javax.inject.Inject;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.osgi.framework.BundleContext;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProvisionrLiveTestSupport {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ProvisionrLiveTestSupport.class);
+
+    @Inject
+    protected BundleContext bundleContext;
+
+    protected final String provisionrId;
+
+    /**
+     * Supply the provisionrId to acquire proper credentials from System Properties.
+     *
+     * @param provisionrId
+     */
+    public ProvisionrLiveTestSupport(String provisionrId) {
+        this.provisionrId = checkNotNull(provisionrId, "provisionrId is null");
+    }
+
+    /**
+     * Retrieve a reference to an OSGi service using the class name
+     */
+    protected <T> T getOsgiService(Class<T> klass, int timeoutInMilliseconds) throws InterruptedException {
+        ServiceTracker tracker = new ServiceTracker(bundleContext,
+            klass.getCanonicalName(), null);
+        tracker.open(true);
+
+        try {
+            return (T) checkNotNull(tracker.waitForService(timeoutInMilliseconds),
+                "OSGi Service not available " + klass.getCanonicalName());
+        } finally {
+            tracker.close();
+        }
+    }
+
+    /**
+     * Collect the provider connection details from system properties
+     */
+    protected ProviderBuilder collectProviderCredentialsFromSystemProperties() {
+        return Provider.builder().id(provisionrId)
+            .accessKey(getProviderProperty("accessKey"))
+            .secretKey(getProviderProperty("secretKey"))
+            .endpoint(Optional.fromNullable(getProviderProperty("endpoint")));
+    }
+
+    /**
+     * Get a provider configuration property from system properties
+     */
+    protected String getProviderProperty(String property) {
+        return System.getProperty(String.format("test.%s.provider.%s", provisionrId, property));
+    }
+
+    /**
+     * @see #getProviderProperty
+     */
+    protected String getProviderProperty(String property, String defaultValue) {
+        return Optional.fromNullable(getProviderProperty(property)).or(defaultValue);
+    }
+
+    public String getResourceAsString(String resource) throws IOException {
+        return Resources.toString(Resources.getResource(resource), Charsets.UTF_8);
+    }
+
+    /**
+     * Must be called inside a test method to be able to access OSGi infrastructure,
+     *
+     * @param processKey
+     * @throws InterruptedException
+     */
+    public void waitForProcessDeployment(String processKey) throws InterruptedException, TimeoutException {
+        ProcessEngine engine = getOsgiService(ProcessEngine.class, 5000);
+        int iteration = 0;
+        while (iteration < 5) {
+            ProcessDefinition definition = engine.getRepositoryService()
+                .createProcessDefinitionQuery()
+                .processDefinitionKey(processKey).singleResult();
+            if (definition != null) {
+                break;
+            }
+            iteration++;
+            TimeUnit.MILLISECONDS.sleep(500);
+        }
+        if (iteration == 5) {
+            throw new TimeoutException("No process found with key: " + processKey);
+        }
+    }
+
+    public void waitForProcessEnd(String processInstanceId) throws Exception {
+        waitForProcessEnd(processInstanceId, 60000 /* milliseconds */);
+    }
+
+    public void waitForProcessEnd(final String processInstanceId, int timeoutInMilliseconds) throws Exception {
+        Stopwatch stopwatch = new Stopwatch().start();
+        while (isProcessNotEnded(processInstanceId)) {
+            if (stopwatch.elapsedMillis() > timeoutInMilliseconds) {
+                throw new TimeoutException(String.format("Process %s not ended in %d milliseconds.",
+                    processInstanceId, timeoutInMilliseconds));
+            }
+            LOG.info(String.format("Process instance %s not ended. Waiting 1s.", processInstanceId));
+            TimeUnit.SECONDS.sleep(1);
+        }
+        LOG.info(String.format("Process instance %s ended as expected in less than %d milliseconds",
+            processInstanceId, timeoutInMilliseconds));
+    }
+
+    private boolean isProcessNotEnded(final String processInstanceId) throws InterruptedException {
+        ProcessInstance localInstance = getProcessInstanceById(processInstanceId);
+        return localInstance != null && !localInstance.isEnded();
+    }
+
+    private ProcessInstance getProcessInstanceById(final String processInstanceId) throws InterruptedException {
+        ProcessEngine engine = getOsgiService(ProcessEngine.class, 5000);
+        return engine.getRuntimeService().createProcessInstanceQuery()
+            .processInstanceId(processInstanceId)
+            .singleResult();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/org/apache/provisionr/test/TestConstants.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/org/apache/provisionr/test/TestConstants.java b/test-support/src/main/java/org/apache/provisionr/test/TestConstants.java
new file mode 100644
index 0000000..32c29ec
--- /dev/null
+++ b/test-support/src/main/java/org/apache/provisionr/test/TestConstants.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.test;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Throwables;
+import com.google.common.io.Resources;
+import java.io.IOException;
+
+public class TestConstants {
+
+    static final String PUBLIC_KEY_FILE_NAME = "id_rsa_test.pub";
+    static final String PRIVATE_KEY_FILE_NAME = "id_rsa_test";
+
+    public static final String PUBLIC_KEY = loadResource(PUBLIC_KEY_FILE_NAME);
+    public static final String PRIVATE_KEY = loadResource(PRIVATE_KEY_FILE_NAME);
+
+    private static String loadResource(String fileName) {
+        try {
+            return Resources.toString(Resources.getResource(TestConstants.class, fileName), Charsets.UTF_8);
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/resources/com/axemblr/provisionr/test/id_rsa_test
----------------------------------------------------------------------
diff --git a/test-support/src/main/resources/com/axemblr/provisionr/test/id_rsa_test b/test-support/src/main/resources/com/axemblr/provisionr/test/id_rsa_test
deleted file mode 100644
index 5400f3e..0000000
--- a/test-support/src/main/resources/com/axemblr/provisionr/test/id_rsa_test
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAt3VZncmmoOV44eH3n12m8JVdPgdJCeiWXze7Ky1AgITWAWdu
-IhIdpGMjPTKWHPD1+NMOU20bmJdi6NyB/DYKM9aatPygcAmokjXOSnz+ypm1BDYI
-1srFW3vTds72rYID2cRju1WCv09tetXFSdpe+UwkGGI5lXdSPHyQPaIOh4g2j2Cy
-7oN+8mbiLJrGAZcY71TMBYvysfySyMLUmwN5o/o97nfBm4qaw6EOsen1ByaN2s1i
-gcLxynvjZqtNDs56X3FXtefAXOtaSkB4fXSTruHNCubx7Lqxu2JKqCsYXrDPRUQW
-8OT/c3+9WmYlBMk6FJ/6fJCLwlEHb9x/bHHvyQIDAQABAoIBAQCq4v6FAa7atKVz
-Er9LjTrRYvAltTeNqT9YllscDtzEWffV+vgVeHZwB4Btos89Sh50lnQDteA8tNcH
-PU8/FT9PphkZeTAg7H4/IytzKxdStPZuY768BMjtPFxvkL0qRa88i7iyaSaO+Xdr
-MfDBqE1LPmdo5yXoWesaOJVLM8cA6oSB1bfv/DyRdhg+eVjpGfLyiZTCAddyGf5X
-DAYjBfuuXJWsK5HYTaeXxpNgf+10FFB4jJXyTwzIttOfUmTzoeawkA8SY4wwKzln
-yw9+2Vdw/R5QaVU7VBt+k4jp6FoRmdabeYxK+gNZ8UuMXw8YitqnjYz+rkrXC4cc
-AuXkvdVhAoGBAPFm1kI9L+1blhVC2Id4Fs6JKn+fo9OvOvju38RwKTDmpaPh2jbu
-YvCI0MsBWS/sRt/kE/E7Gy9+mOkDB+0/P5nb3UV+UMUjr5x5WkdNoggDEfslyugc
-vk4PA1GsFQ8MQs9baF2C1yH3d5VyBUbdQ+lceXgaV/coKCDZjjGiJ1d9AoGBAMKN
-fLhHKVzG1mVYuv30VSfM2LP/Wtv0vD+GoGOUzn9OAdRC117uAZik86le4L3GTIzo
-EVIUnzmFMouWHJ4Gu78qM78kD9zJtDUaCpHuvkf15rg7e0aKcVPV6Hb6dCPVeGyJ
-t1NBffuYLSMHH34QmVa25Dk/PchR5zh2z+1bTCM9AoGAYQ/3UHTnw2lS5EOXaojn
-qq3OT7hxl9jaPmNVx9dNSKNEsKtMIVAiqhJo2Wc2ZCV9reI3/oPEf4lIlFAqrMME
-oKmdw6ZxdYLOxnyoxwi5AL2zSic8+a0s+5ffvsQRR5anelaHlSnZtIebJpTM+FxZ
-RQhwstDs06zqzaKMIPrRFMUCgYEAjYNI8umgJoHjNPijm1F8F2UjQ1o8hr2vqC2O
-wKBey668Gd88tSo+Mv/Y1JvUsXVp/RxYbPHfF4HRUEMyMagILHbQCPp8J0b4M5/r
-jFayRbmRxvRNKPROloKDgveOPvppi9loZcC/mKAKRO5Lc/Ey+CY0P4fGss0QeLvD
-Zo0ABqkCgYAIHOnxb32Mf6p2JXdGRx0fwVvTyQgVLYaI1L8HzkgYOqIowzo64Lzs
-Jl+BlvUc/4K3SziYnU+bML7YDJuhTJlJjbWKZHvXeTbfYwCghHpnITmQBzRcz9k3
-7o80fvPxKIb5NuD66CbOEx7QKUTmUhqJiDp6YzFYWTcWTEMqndxwqw==
------END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/resources/com/axemblr/provisionr/test/id_rsa_test.pub
----------------------------------------------------------------------
diff --git a/test-support/src/main/resources/com/axemblr/provisionr/test/id_rsa_test.pub b/test-support/src/main/resources/com/axemblr/provisionr/test/id_rsa_test.pub
deleted file mode 100644
index 9d55fd1..0000000
--- a/test-support/src/main/resources/com/axemblr/provisionr/test/id_rsa_test.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3dVmdyaag5Xjh4fefXabwlV0+B0kJ6JZfN7srLUCAhNYBZ24iEh2kYyM9MpYc8PX40w5TbRuYl2Lo3IH8Ngoz1pq0/KBwCaiSNc5KfP7KmbUENgjWysVbe9N2zvatggPZxGO7VYK/T2161cVJ2l75TCQYYjmVd1I8fJA9og6HiDaPYLLug37yZuIsmsYBlxjvVMwFi/Kx/JLIwtSbA3mj+j3ud8GbiprDoQ6x6fUHJo3azWKBwvHKe+Nmq00OznpfcVe158Bc61pKQHh9dJOu4c0K5vHsurG7YkqoKxhesM9FRBbw5P9zf71aZiUEyToUn/p8kIvCUQdv3H9sce/J test@axemblr.com

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/test-support/src/main/resources/features.xml b/test-support/src/main/resources/features.xml
index 34529b4..dd5cd84 100644
--- a/test-support/src/main/resources/features.xml
+++ b/test-support/src/main/resources/features.xml
@@ -21,7 +21,7 @@
 
     <feature name="provisionr-test-support" version="${project.version}">
         <bundle dependency="true">mvn:com.google.guava/guava/${guava.version}</bundle>
-        <bundle>mvn:com.axemblr.provisionr/provisionr-test-support/${project.version}</bundle>
+        <bundle>mvn:org.apache.provisionr/provisionr-test-support/${project.version}</bundle>
     </feature>
 
 </features>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/resources/org/apache/provisionr/test/id_rsa_test
----------------------------------------------------------------------
diff --git a/test-support/src/main/resources/org/apache/provisionr/test/id_rsa_test b/test-support/src/main/resources/org/apache/provisionr/test/id_rsa_test
new file mode 100644
index 0000000..5400f3e
--- /dev/null
+++ b/test-support/src/main/resources/org/apache/provisionr/test/id_rsa_test
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAt3VZncmmoOV44eH3n12m8JVdPgdJCeiWXze7Ky1AgITWAWdu
+IhIdpGMjPTKWHPD1+NMOU20bmJdi6NyB/DYKM9aatPygcAmokjXOSnz+ypm1BDYI
+1srFW3vTds72rYID2cRju1WCv09tetXFSdpe+UwkGGI5lXdSPHyQPaIOh4g2j2Cy
+7oN+8mbiLJrGAZcY71TMBYvysfySyMLUmwN5o/o97nfBm4qaw6EOsen1ByaN2s1i
+gcLxynvjZqtNDs56X3FXtefAXOtaSkB4fXSTruHNCubx7Lqxu2JKqCsYXrDPRUQW
+8OT/c3+9WmYlBMk6FJ/6fJCLwlEHb9x/bHHvyQIDAQABAoIBAQCq4v6FAa7atKVz
+Er9LjTrRYvAltTeNqT9YllscDtzEWffV+vgVeHZwB4Btos89Sh50lnQDteA8tNcH
+PU8/FT9PphkZeTAg7H4/IytzKxdStPZuY768BMjtPFxvkL0qRa88i7iyaSaO+Xdr
+MfDBqE1LPmdo5yXoWesaOJVLM8cA6oSB1bfv/DyRdhg+eVjpGfLyiZTCAddyGf5X
+DAYjBfuuXJWsK5HYTaeXxpNgf+10FFB4jJXyTwzIttOfUmTzoeawkA8SY4wwKzln
+yw9+2Vdw/R5QaVU7VBt+k4jp6FoRmdabeYxK+gNZ8UuMXw8YitqnjYz+rkrXC4cc
+AuXkvdVhAoGBAPFm1kI9L+1blhVC2Id4Fs6JKn+fo9OvOvju38RwKTDmpaPh2jbu
+YvCI0MsBWS/sRt/kE/E7Gy9+mOkDB+0/P5nb3UV+UMUjr5x5WkdNoggDEfslyugc
+vk4PA1GsFQ8MQs9baF2C1yH3d5VyBUbdQ+lceXgaV/coKCDZjjGiJ1d9AoGBAMKN
+fLhHKVzG1mVYuv30VSfM2LP/Wtv0vD+GoGOUzn9OAdRC117uAZik86le4L3GTIzo
+EVIUnzmFMouWHJ4Gu78qM78kD9zJtDUaCpHuvkf15rg7e0aKcVPV6Hb6dCPVeGyJ
+t1NBffuYLSMHH34QmVa25Dk/PchR5zh2z+1bTCM9AoGAYQ/3UHTnw2lS5EOXaojn
+qq3OT7hxl9jaPmNVx9dNSKNEsKtMIVAiqhJo2Wc2ZCV9reI3/oPEf4lIlFAqrMME
+oKmdw6ZxdYLOxnyoxwi5AL2zSic8+a0s+5ffvsQRR5anelaHlSnZtIebJpTM+FxZ
+RQhwstDs06zqzaKMIPrRFMUCgYEAjYNI8umgJoHjNPijm1F8F2UjQ1o8hr2vqC2O
+wKBey668Gd88tSo+Mv/Y1JvUsXVp/RxYbPHfF4HRUEMyMagILHbQCPp8J0b4M5/r
+jFayRbmRxvRNKPROloKDgveOPvppi9loZcC/mKAKRO5Lc/Ey+CY0P4fGss0QeLvD
+Zo0ABqkCgYAIHOnxb32Mf6p2JXdGRx0fwVvTyQgVLYaI1L8HzkgYOqIowzo64Lzs
+Jl+BlvUc/4K3SziYnU+bML7YDJuhTJlJjbWKZHvXeTbfYwCghHpnITmQBzRcz9k3
+7o80fvPxKIb5NuD66CbOEx7QKUTmUhqJiDp6YzFYWTcWTEMqndxwqw==
+-----END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/resources/org/apache/provisionr/test/id_rsa_test.pub
----------------------------------------------------------------------
diff --git a/test-support/src/main/resources/org/apache/provisionr/test/id_rsa_test.pub b/test-support/src/main/resources/org/apache/provisionr/test/id_rsa_test.pub
new file mode 100644
index 0000000..9d55fd1
--- /dev/null
+++ b/test-support/src/main/resources/org/apache/provisionr/test/id_rsa_test.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3dVmdyaag5Xjh4fefXabwlV0+B0kJ6JZfN7srLUCAhNYBZ24iEh2kYyM9MpYc8PX40w5TbRuYl2Lo3IH8Ngoz1pq0/KBwCaiSNc5KfP7KmbUENgjWysVbe9N2zvatggPZxGO7VYK/T2161cVJ2l75TCQYYjmVd1I8fJA9og6HiDaPYLLug37yZuIsmsYBlxjvVMwFi/Kx/JLIwtSbA3mj+j3ud8GbiprDoQ6x6fUHJo3azWKBwvHKe+Nmq00OznpfcVe158Bc61pKQHh9dJOu4c0K5vHsurG7YkqoKxhesM9FRBbw5P9zf71aZiUEyToUn/p8kIvCUQdv3H9sce/J test@axemblr.com


[15/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/templates/xml/XmlTemplate.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/templates/xml/XmlTemplate.java b/core/src/main/java/com/axemblr/provisionr/core/templates/xml/XmlTemplate.java
deleted file mode 100644
index e6f132e..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/templates/xml/XmlTemplate.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.templates.xml;
-
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.NetworkBuilder;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.pool.PoolBuilder;
-import com.axemblr.provisionr.api.software.Repository;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.api.software.SoftwareBuilder;
-import com.axemblr.provisionr.core.templates.PoolTemplate;
-import com.google.common.annotations.VisibleForTesting;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Throwables;
-import static com.google.common.collect.Lists.newArrayList;
-import com.google.common.io.CharStreams;
-import com.google.common.io.Closeables;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.List;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-
-/**
- * Basic representation of a pool template
- * <p/>
- * Designed to be consumed *only* by JAXB
- * <p/>
- * If you need to implement a pool template see {@code PoolTemplate}
- */
-@XmlRootElement(name = "template")
-public class XmlTemplate implements PoolTemplate {
-
-    /**
-     * @return an XmlTemplate instance resulted from parsing the content
-     */
-    public static XmlTemplate newXmlTemplate(String content) {
-        try {
-            JAXBContext context = JAXBContext.newInstance(XmlTemplate.class);
-            return (XmlTemplate) context.createUnmarshaller()
-                .unmarshal(new ByteArrayInputStream(content.getBytes()));
-
-        } catch (JAXBException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    /**
-     * @return an XmlTemplate instance resulted from parsing a file
-     */
-    public static XmlTemplate newXmlTemplate(File file) {
-        FileReader reader = null;
-        try {
-            reader = new FileReader(file);
-            return newXmlTemplate(CharStreams.toString(reader));
-
-        } catch (IOException e) {
-            throw Throwables.propagate(e);
-        } finally {
-            Closeables.closeQuietly(reader);
-        }
-    }
-
-    private String id;
-    private String description;
-    private String osVersion;
-
-    private List<String> packages = newArrayList();
-    private List<Integer> ports = newArrayList();
-
-    private List<FileEntry> files = newArrayList();
-
-    private List<RepositoryEntry> repositories = newArrayList();
-
-    public XmlTemplate() {
-    }
-
-    @Override
-    public Pool apply(Pool pool) {
-        PoolBuilder result = pool.toBuilder();
-
-        result.software(apply(pool.getSoftware()));
-        result.network(apply(pool.getNetwork()));
-
-        if (osVersion != null) {
-            result.provider(pool.getProvider().toBuilder()
-                .option("version", osVersion).createProvider());
-        }
-
-        return result.createPool();
-    }
-
-    @VisibleForTesting
-    Software apply(Software software) {
-        SoftwareBuilder result = software.toBuilder();
-
-        // Add all the new packages
-        for (String pkg : packages) {
-            result.addPackage(pkg);
-        }
-
-        // Add all the new files
-        for (FileEntry entry : files) {
-            result.file(entry.getSource(), entry.getDestination());
-        }
-
-        // Add all the new custom repositories
-        for (RepositoryEntry entry : repositories) {
-            result.repository(Repository.builder().name(entry.getId()).key(entry.getKey())
-                .entries(entry.getEntries()).createRepository());
-        }
-
-        return result.createSoftware();
-    }
-
-    @VisibleForTesting
-    Network apply(Network network) {
-        NetworkBuilder result = network.toBuilder();
-        for (int port : ports) {
-            result.addRules(Rule.builder().anySource().tcp().port(port).createRule());
-        }
-        return result.createNetwork();
-    }
-
-    @XmlAttribute(name = "id")
-    @Override
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = checkNotNull(id, "id is null");
-    }
-
-    @Override
-    public String getDescription() {
-        return description.trim();
-    }
-
-    public void setDescription(String description) {
-        this.description = checkNotNull(description, "description is null");
-    }
-
-    @XmlAttribute(name = "os-version")
-    public String getOsVersion() {
-        return osVersion;
-    }
-
-    public void setOsVersion(String osVersion) {
-        this.osVersion = checkNotNull(osVersion, "osVersion is null");
-    }
-
-    @XmlElementWrapper(name = "packages")
-    @XmlElement(name = "package")
-    public List<String> getPackages() {
-        return packages;
-    }
-
-    public void setPackages(List<String> packages) {
-        this.packages = checkNotNull(packages, "packages is null");
-    }
-
-    @XmlElementWrapper(name = "ports")
-    @XmlElement(name = "port")
-    public List<Integer> getPorts() {
-        return ports;
-    }
-
-    public void setPorts(List<Integer> ports) {
-        this.ports = checkNotNull(ports, "ports is null");
-    }
-
-    @XmlElementWrapper(name = "files")
-    @XmlElement(name = "file")
-    public List<FileEntry> getFiles() {
-        return files;
-    }
-
-    public void setFiles(List<FileEntry> files) {
-        this.files = checkNotNull(files, "files is null");
-    }
-
-    @XmlElementWrapper(name = "repositories")
-    @XmlElement(name = "repository")
-    public List<RepositoryEntry> getRepositories() {
-        return repositories;
-    }
-
-    public void setRepositories(List<RepositoryEntry> repositories) {
-        this.repositories = checkNotNull(repositories, "repositories is null");
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        XmlTemplate that = (XmlTemplate) o;
-
-        if (description != null ? !description.equals(that.description) : that.description != null) return false;
-        if (files != null ? !files.equals(that.files) : that.files != null) return false;
-        if (id != null ? !id.equals(that.id) : that.id != null) return false;
-        if (osVersion != null ? !osVersion.equals(that.osVersion) : that.osVersion != null) return false;
-        if (packages != null ? !packages.equals(that.packages) : that.packages != null) return false;
-        if (ports != null ? !ports.equals(that.ports) : that.ports != null) return false;
-        if (repositories != null ? !repositories.equals(that.repositories) : that.repositories != null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = id != null ? id.hashCode() : 0;
-        result = 31 * result + (description != null ? description.hashCode() : 0);
-        result = 31 * result + (osVersion != null ? osVersion.hashCode() : 0);
-        result = 31 * result + (packages != null ? packages.hashCode() : 0);
-        result = 31 * result + (ports != null ? ports.hashCode() : 0);
-        result = 31 * result + (files != null ? files.hashCode() : 0);
-        result = 31 * result + (repositories != null ? repositories.hashCode() : 0);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "XmlTemplate{" +
-            "id='" + id + '\'' +
-            ", description='" + description + '\'' +
-            ", osVersion='" + osVersion + '\'' +
-            ", packages=" + packages +
-            ", ports=" + ports +
-            ", files=" + files +
-            ", repositories=" + repositories +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/CoreConstants.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/CoreConstants.java b/core/src/main/java/org/apache/provisionr/core/CoreConstants.java
new file mode 100644
index 0000000..b24c111
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/CoreConstants.java
@@ -0,0 +1,10 @@
+package org.apache.provisionr.core;
+
+public class CoreConstants {
+
+    private CoreConstants() {
+    }
+
+    public static final String ACTIVITI_EXPLORER_DEFAULT_USER = "kermit";
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/CoreProcessVariables.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/CoreProcessVariables.java b/core/src/main/java/org/apache/provisionr/core/CoreProcessVariables.java
new file mode 100644
index 0000000..0fffcc7
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/CoreProcessVariables.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core;
+
+public class CoreProcessVariables {
+
+    private CoreProcessVariables() {
+        throw new RuntimeException("Should not instantiate");
+    }
+
+    /**
+     * Provider ID as returned by the Provisionr object
+     *
+     * @see org.apache.provisionr.api.Provisionr
+     */
+    public static final String PROVIDER = "provider";
+
+    /**
+     * Pool configuration description
+     *
+     * @see org.apache.provisionr.api.pool.Pool
+     */
+    public static final String POOL = "pool";
+
+    /**
+     * Contains a list of machines that are running
+     *
+     * @see org.apache.provisionr.api.pool.Machine
+     */
+    public static final String MACHINES = "machines";
+
+    /**
+     * Pool status stored as process variable
+     * <p/>
+     * This can be an arbitrary string. We will restrict the domain later on.
+     */
+    public static final String STATUS = "status";
+
+    /**
+     * Variable to store the pool business key. The key is passed as a process variable to all processes that take
+     * part in setting up the pool.
+     */
+    public static final String POOL_BUSINESS_KEY = "poolBusinessKey";
+
+    /**
+     * Configurable value for the interval of time in which to wait for the pool
+     * to become available.
+     */
+    public static final String BOOTSTRAP_TIMEOUT = "bootstrapTimeout";
+
+    /**
+     * Flag that indicates if the image the machines are being built from already has all its software
+     * installed and there's no need to download and install the packages and files.
+     */
+    public static final String IS_CACHED_IMAGE = "isCachedImage";
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/CoreSignals.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/CoreSignals.java b/core/src/main/java/org/apache/provisionr/core/CoreSignals.java
new file mode 100644
index 0000000..da71486
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/CoreSignals.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core;
+
+public class CoreSignals {
+
+    private CoreSignals() {
+    }
+
+    /**
+     * Standard event that triggers pool termination
+     */
+    public static final String TERMINATE_POOL = "terminatePoolEvent";
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/Mustache.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/Mustache.java b/core/src/main/java/org/apache/provisionr/core/Mustache.java
new file mode 100644
index 0000000..895b829
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/Mustache.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core;
+
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.MustacheFactory;
+import com.google.common.base.Charsets;
+import com.google.common.io.Resources;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringReader;
+import java.io.Writer;
+import java.net.URL;
+import java.util.Map;
+
+/**
+ * Utility functions for rendering mustache templates as strings
+ */
+public class Mustache {
+
+    private Mustache() {
+    }
+
+    public static String toString(Class<?> contextClass, String resource, Map<String, ?> scopes)
+        throws IOException {
+        return toString(Resources.getResource(contextClass, resource), scopes);
+    }
+
+    public static String toString(URL resource, Map<String, ?> scopes) throws IOException {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        Writer writer = new OutputStreamWriter(outputStream);
+
+        String content = Resources.toString(resource, Charsets.UTF_8);
+
+        MustacheFactory factory = new DefaultMustacheFactory();
+        factory.compile(new StringReader(content), resource.toString())
+            .execute(writer, scopes);
+
+        writer.close();
+        return outputStream.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/PoolStatus.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/PoolStatus.java b/core/src/main/java/org/apache/provisionr/core/PoolStatus.java
new file mode 100644
index 0000000..aef5675
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/PoolStatus.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core;
+
+/**
+ * A standard set of pool statuses
+ */
+public class PoolStatus {
+
+    private PoolStatus() {
+    }
+
+    public static String UNDEFINED = "undefined";
+
+    public static String SETUP = "setup";
+
+    public static String READY = "ready";
+
+    public static String TERMINATED = "terminated";
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/ProvisionrSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/ProvisionrSupport.java b/core/src/main/java/org/apache/provisionr/core/ProvisionrSupport.java
new file mode 100644
index 0000000..b0dbc94
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/ProvisionrSupport.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core;
+
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.provider.Provider;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.Execution;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class ProvisionrSupport implements Provisionr {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ProvisionrSupport.class);
+
+    @Override
+    public Optional<Provider> getDefaultProvider() {
+        return Optional.absent();
+    }
+
+    @Override
+    public String getStatus(String businessKey) {
+        return PoolStatus.UNDEFINED;
+    }
+
+    @Override
+    public List<Machine> getMachines(String businessKey) {
+        return ImmutableList.of();
+    }
+
+    /**
+     * Trigger a signal event on all executions for a specific business key.
+     *
+     * @see <a href="http://www.activiti.org/userguide/index.html#bpmnSignalEventDefinition" />
+     * @see CoreSignals
+     */
+    protected void triggerSignalEvent(ProcessEngine processEngine, String businessKey, String signalName) {
+        RuntimeService runtimeService = processEngine.getRuntimeService();
+
+        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
+            .processInstanceBusinessKey(businessKey).singleResult();
+
+        List<Execution> executions = runtimeService.createExecutionQuery()
+            .processInstanceId(processInstance.getProcessInstanceId())
+            .signalEventSubscriptionName(signalName).list();
+
+        if (executions.isEmpty()) {
+            throw new NoSuchElementException(String.format("No executions found waiting " +
+                "for signal '%s' on process %s", signalName, businessKey));
+        }
+        for (Execution execution : executions) {
+            LOG.info("Sending '{}' signal to execution {} for process {}",
+                new Object[]{signalName, execution.getId(), businessKey});
+            runtimeService.signalEventReceived(signalName, execution.getId());
+
+        }
+    }
+
+    /**
+     * Convert a timeout specified in seconds to a string representation that can be used
+     * inside the Activiti definitions of timeouts. 
+     * 
+     * @see http://en.wikipedia.org/wiki/ISO_8601#Durations
+     */
+    protected String convertTimeoutToISO8601TimeDuration(int bootstrapTimeoutInSeconds) {
+        StringBuilder result = new StringBuilder("PT");
+        if (bootstrapTimeoutInSeconds % 60 == 0) {
+            result.append(bootstrapTimeoutInSeconds / 60).append("M");
+        } else {
+            result.append(bootstrapTimeoutInSeconds).append("S");
+        }
+        return result.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/Ssh.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/Ssh.java b/core/src/main/java/org/apache/provisionr/core/Ssh.java
new file mode 100644
index 0000000..8905990
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/Ssh.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core;
+
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.core.logging.ErrorStreamLogger;
+import org.apache.provisionr.core.logging.InfoStreamLogger;
+import com.google.common.base.Charsets;
+import static com.google.common.base.Preconditions.checkArgument;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.PublicKey;
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.common.SecurityUtils;
+import net.schmizz.sshj.connection.channel.direct.Session;
+import net.schmizz.sshj.transport.verification.HostKeyVerifier;
+import net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile;
+import net.schmizz.sshj.xfer.InMemorySourceFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+public class Ssh {
+
+    private static final Logger LOG = LoggerFactory.getLogger(Ssh.class);
+
+    /**
+     * Fail if a connection can't be established in this amount of time
+     */
+    public static final int DEFAULT_CONNECT_TIMEOUT = 30 * 1000; /* milliseconds */
+
+    public static final int DEFAULT_READ_TIMEOUT = 10 * 60 * 1000; /* milliseconds */
+
+    private Ssh() {
+    }
+
+    /**
+     * Accept any host key from the remote machines
+     */
+    private enum AcceptAnyHostKeyVerifier implements HostKeyVerifier {
+        INSTANCE;
+
+        @Override
+        public boolean verify(String hostname, int port, PublicKey key) {
+            String fingerprint = SecurityUtils.getFingerprint(key);
+            LOG.info("Automatically accepting host key for {}:{} with fingerprint {}",
+                new Object[]{hostname, port, fingerprint});
+            return true;
+        }
+    }
+
+    public static SSHClient newClient(Machine machine, AdminAccess adminAccess) throws IOException {
+        return newClient(machine, adminAccess, DEFAULT_READ_TIMEOUT);
+    }
+
+    /**
+     * Create a new {@code SSHClient} connected to the remote machine using the
+     * AdminAccess credentials as provided
+     */
+    public static SSHClient newClient(
+        Machine machine, AdminAccess adminAccess, int timeoutInMillis
+    ) throws IOException {
+        checkArgument(timeoutInMillis >= 0, "timeoutInMillis should be positive or 0");
+
+        final SSHClient client = new SSHClient();
+        client.addHostKeyVerifier(AcceptAnyHostKeyVerifier.INSTANCE);
+
+        if (timeoutInMillis != 0) {
+            client.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
+            client.setTimeout(timeoutInMillis);
+        }
+        client.connect(machine.getPublicDnsName(), machine.getSshPort());
+
+        OpenSSHKeyFile key = new OpenSSHKeyFile();
+        key.init(adminAccess.getPrivateKey(), adminAccess.getPublicKey());
+        client.authPublickey(adminAccess.getUsername(), key);
+
+        return client;
+    }
+
+    /**
+     * Stream command output as log message for easy debugging
+     */
+    public static void logCommandOutput(Logger logger, String instanceId, Session.Command command) {
+        final Marker marker = MarkerFactory.getMarker("ssh-" + instanceId);
+
+        new InfoStreamLogger(command.getInputStream(), logger, marker)
+            .start();
+        new ErrorStreamLogger(command.getErrorStream(), logger, marker)
+            .start();
+    }
+
+    /**
+     * Create a remote file on SSH from a string
+     *
+     * @param client      ssh client instance
+     * @param content     content for the new file
+     * @param permissions unix permissions
+     * @param destination destination path
+     * @throws IOException
+     */
+    public static void createFile(
+        SSHClient client, String content, final int permissions, String destination
+    ) throws IOException {
+        final byte[] bytes = content.getBytes(Charsets.UTF_8);
+        client.newSCPFileTransfer().upload(new InMemorySourceFile() {
+            @Override
+            public String getName() {
+                return "in-memory";
+            }
+
+            @Override
+            public long getLength() {
+                return bytes.length;
+            }
+
+            @Override
+            public int getPermissions() throws IOException {
+                return permissions;
+            }
+
+            @Override
+            public InputStream getInputStream() throws IOException {
+                return new ByteArrayInputStream(bytes);
+            }
+        }, destination);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activiti/ConfigurableFailedJobCommandFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activiti/ConfigurableFailedJobCommandFactory.java b/core/src/main/java/org/apache/provisionr/core/activiti/ConfigurableFailedJobCommandFactory.java
new file mode 100644
index 0000000..ed9bfb6
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activiti/ConfigurableFailedJobCommandFactory.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activiti;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Date;
+import java.util.UUID;
+import org.activiti.engine.impl.calendar.BusinessCalendar;
+import org.activiti.engine.impl.calendar.CycleBusinessCalendar;
+import org.activiti.engine.impl.context.Context;
+import org.activiti.engine.impl.interceptor.Command;
+import org.activiti.engine.impl.interceptor.CommandContext;
+import org.activiti.engine.impl.jobexecutor.FailedJobCommandFactory;
+import org.activiti.engine.impl.persistence.entity.JobEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * We need a custom @{link FailedJobCommandFactory} implementation that allows
+ * us to customize the global number of retries per job
+ */
+public class ConfigurableFailedJobCommandFactory implements FailedJobCommandFactory {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ConfigurableFailedJobCommandFactory.class);
+
+    /**
+     * This class is a bit of a hack because there is no easy way to
+     * change @{link JobEntity.DEFAULT_RETRIES}
+     * <p/>
+     * We get the desired behaviour by incrementing the number of retries until we
+     * exceed maxNumberOfRetries + DEFAULT_RETRIES (considered to be 0)
+     * <p/>
+     * If maxNumberOfRetries is -1 (infinity) the job will be always retried.
+     */
+    public static class IncrementJobRetriesCmd implements Command<Object> {
+
+        private final String LOCK_OWNER = "job-retries-" + UUID.randomUUID().toString();
+
+        private final String jobId;
+        private final Throwable exception;
+
+        private final int maxNumberOfRetries;
+        private final int waitBetweenRetriesInSeconds;
+
+        public IncrementJobRetriesCmd(String jobId, Throwable exception, int maxNumberOfRetries,
+                                      int waitBetweenRetriesInSeconds) {
+            this.jobId = checkNotNull(jobId, "jobId is null");
+            this.exception = exception;
+
+            this.maxNumberOfRetries = maxNumberOfRetries;
+            this.waitBetweenRetriesInSeconds = waitBetweenRetriesInSeconds;
+        }
+
+        @Override
+        public Object execute(CommandContext commandContext) {
+            JobEntity job = Context.getCommandContext()
+                .getJobManager()
+                .findJobById(jobId);
+
+            updateNumberOfRetries(job);
+
+            if (exception != null) {
+                job.setExceptionMessage(exception.getMessage());
+                job.setExceptionStacktrace(getExceptionStacktrace());
+            }
+
+            return null;
+        }
+
+        private void updateNumberOfRetries(JobEntity job) {
+            if (maxNumberOfRetries == -1) {
+                job.setLockOwner(LOCK_OWNER);
+                job.setLockExpirationTime(calculateDueDate());
+                return; /* always retry without counting */
+            }
+
+            int realUpperBound = maxNumberOfRetries + JobEntity.DEFAULT_RETRIES;
+            if (job.getRetries() >= realUpperBound) {
+                LOG.warn("Job {} from process {} has no more retries left. The process will block and may " +
+                    "require human intervention.", job.getId(), job.getProcessInstanceId());
+
+                job.setRetries(0);  /* stop retrying this job */
+                job.setLockOwner(null);
+
+            } else {
+                final Date newDate = calculateDueDate();
+                LOG.info("Scheduling job {} from process {} to be retried at {}. Try {}/{}",
+                    new Object[]{job.getId(), job.getProcessInstanceId(), newDate,
+                        job.getRetries() - JobEntity.DEFAULT_RETRIES, maxNumberOfRetries});
+
+                /* I've tried to use job.setDuedate() but it doesn't work as expected */
+
+                job.setLockOwner(LOCK_OWNER);
+                job.setLockExpirationTime(newDate);
+
+                job.setRetries(job.getRetries() + 1);
+            }
+        }
+
+        /**
+         * Based on code from @{link TimerEntity.calculateDueDate}
+         */
+        private Date calculateDueDate() {
+            BusinessCalendar businessCalendar = Context
+                .getProcessEngineConfiguration()
+                .getBusinessCalendarManager()
+                .getBusinessCalendar(CycleBusinessCalendar.NAME);
+
+            return businessCalendar.resolveDuedate(
+                String.format("R/PT%dS", waitBetweenRetriesInSeconds));
+        }
+
+        private String getExceptionStacktrace() {
+            StringWriter stringWriter = new StringWriter();
+            exception.printStackTrace(new PrintWriter(stringWriter));
+            return stringWriter.toString();
+        }
+    }
+
+    private final int maxNumberOfRetries;
+    private final int waitBetweenRetriesInSeconds;
+
+    public ConfigurableFailedJobCommandFactory(int maxNumberOfRetries, int waitBetweenRetriesInSeconds) {
+        checkArgument(maxNumberOfRetries > 0 || maxNumberOfRetries == -1,
+            "Max number of retries should be a positive number or -1 (infinite)");
+        checkArgument(waitBetweenRetriesInSeconds > 0, "waitBetweenRetriesInSeconds should be positive");
+
+        this.maxNumberOfRetries = maxNumberOfRetries;
+        this.waitBetweenRetriesInSeconds = waitBetweenRetriesInSeconds;
+    }
+
+    @Override
+    public Command<Object> getCommand(String jobId, Throwable exception) {
+        return new IncrementJobRetriesCmd(jobId, exception, maxNumberOfRetries, waitBetweenRetriesInSeconds);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activiti/ConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activiti/ConfigurationFactory.java b/core/src/main/java/org/apache/provisionr/core/activiti/ConfigurationFactory.java
new file mode 100644
index 0000000..88341e1
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activiti/ConfigurationFactory.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activiti;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import javax.sql.DataSource;
+import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;
+import org.activiti.engine.impl.jobexecutor.FailedJobCommandFactory;
+import org.activiti.engine.impl.jobexecutor.JobExecutor;
+
+public class ConfigurationFactory {
+
+    private DataSource dataSource;
+    private String databaseSchemaUpdate;
+
+    private boolean jobExecutorActivate = true;
+    private JobExecutor jobExecutor;
+
+    private FailedJobCommandFactory failedJobCommandFactory;
+
+    public StandaloneProcessEngineConfiguration getConfiguration() {
+        StandaloneProcessEngineConfiguration conf = new StandaloneProcessEngineConfiguration();
+
+        conf.setDataSource(dataSource);
+        conf.setDatabaseSchemaUpdate(databaseSchemaUpdate);
+
+        conf.setJobExecutorActivate(jobExecutorActivate);
+        conf.setJobExecutor(jobExecutor);
+
+        conf.setFailedJobCommandFactory(failedJobCommandFactory);
+
+        return conf;
+    }
+
+    public void setDataSource(DataSource dataSource) {
+        this.dataSource = checkNotNull(dataSource, "dataSource is null");
+    }
+
+    public void setDatabaseSchemaUpdate(String databaseSchemaUpdate) {
+        this.databaseSchemaUpdate = checkNotNull(databaseSchemaUpdate, "databaseSchemaUpdate is null");
+    }
+
+    public void setJobExecutorActivate(boolean jobExecutorActivate) {
+        this.jobExecutorActivate = jobExecutorActivate;
+    }
+
+    public void setJobExecutor(JobExecutor jobExecutor) {
+        this.jobExecutor = checkNotNull(jobExecutor, "jobExecutor is null");
+    }
+
+    public void setFailedJobCommandFactory(FailedJobCommandFactory failedJobCommandFactory) {
+        this.failedJobCommandFactory = checkNotNull(failedJobCommandFactory, "failedJobCommandFactory is null");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activities/CheckProcessesEnded.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activities/CheckProcessesEnded.java b/core/src/main/java/org/apache/provisionr/core/activities/CheckProcessesEnded.java
new file mode 100644
index 0000000..be7a5aa
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activities/CheckProcessesEnded.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.util.List;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CheckProcessesEnded implements JavaDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CheckProcessesEnded.class);
+
+    private final RuntimeService runtimeService;
+
+    private final String variableWithProcessIds;
+    private final String resultVariable;
+
+    public CheckProcessesEnded(RuntimeService runtimeService, String variableWithProcessIds,
+                               String resultVariable) {
+        this.runtimeService = checkNotNull(runtimeService, "runtimeService is null");
+        this.variableWithProcessIds = checkNotNull(variableWithProcessIds, "variableWithProcessIds is null");
+        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
+    }
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        @SuppressWarnings("unchecked")
+        List<String> processIds = (List<String>) execution.getVariable(variableWithProcessIds);
+
+        List<String> ended = Lists.newArrayList(Iterables.filter(processIds, new Predicate<String>() {
+            @Override
+            public boolean apply(String processInstanceId) {
+                ProcessInstance instance = runtimeService.createProcessInstanceQuery()
+                    .processInstanceId(processInstanceId).singleResult();
+
+                return instance == null || instance.isEnded();
+            }
+        }));
+
+        boolean done = (processIds.size() == ended.size());
+        execution.setVariable(resultVariable, done);
+
+        if (done) {
+            LOG.info("All background processes ENDED: {}", processIds);
+        } else {
+            if (LOG.isInfoEnabled()) {
+                LOG.info("Still waiting for: {}", Sets.difference(ImmutableSet.copyOf(processIds),
+                    ImmutableSet.copyOf(ended)));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activities/DownloadFiles.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activities/DownloadFiles.java b/core/src/main/java/org/apache/provisionr/core/activities/DownloadFiles.java
new file mode 100644
index 0000000..7687b40
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activities/DownloadFiles.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.Mustache;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.Map;
+
+public class DownloadFiles extends PuppetActivity {
+
+    public static final String FILES_TEMPLATE = "/org/apache/provisionr/core/puppet/files.pp.mustache";
+
+    public DownloadFiles() {
+        super("files");
+    }
+
+    @Override
+    public String createPuppetScript(Pool pool, Machine machine) throws Exception {
+        return Mustache.toString(InstallPackages.class, FILES_TEMPLATE,
+            ImmutableMap.of("files", filesAsListOfMaps(pool.getSoftware())));
+    }
+
+    private List<Map<String, String>> filesAsListOfMaps(Software software) {
+        return Lists.newArrayList(Iterables.transform(software.getFiles().entrySet(),
+            new Function<Map.Entry<String, String>, Map<String, String>>() {
+                @Override
+                public Map<String, String> apply(Map.Entry<String, String> entry) {
+                    return ImmutableMap.of("source", entry.getKey(), "destination", entry.getValue());
+                }
+            }));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activities/InstallPackages.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activities/InstallPackages.java b/core/src/main/java/org/apache/provisionr/core/activities/InstallPackages.java
new file mode 100644
index 0000000..f92d7d5
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activities/InstallPackages.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.Mustache;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+public class InstallPackages extends PuppetActivity {
+
+    public static final String PACKAGES_TEMPLATE = "/org/apache/provisionr/core/puppet/packages.pp.mustache";
+
+    public InstallPackages() {
+        super("packages");
+    }
+
+    @Override
+    public String createPuppetScript(Pool pool, Machine machine) throws IOException {
+        return Mustache.toString(InstallPackages.class, PACKAGES_TEMPLATE,
+            ImmutableMap.of("packages", packagesAsListOfMaps(pool.getSoftware())));
+    }
+
+    private List<Map<String, String>> packagesAsListOfMaps(Software software) {
+        ImmutableList.Builder<Map<String, String>> result = ImmutableList.builder();
+        for (String pkg : software.getPackages()) {
+            result.add(ImmutableMap.of("package", pkg));
+        }
+        return result.build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activities/InstallRepositories.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activities/InstallRepositories.java b/core/src/main/java/org/apache/provisionr/core/activities/InstallRepositories.java
new file mode 100644
index 0000000..1154612
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activities/InstallRepositories.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Repository;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.Mustache;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.Map;
+
+public class InstallRepositories extends PuppetActivity {
+
+    public static final String REPOSITORIES_TEMPLATE =
+        "/org/apache/provisionr/core/puppet/repositories.pp.mustache";
+
+    public InstallRepositories() {
+        super("repositories");
+    }
+
+    @Override
+    public String createPuppetScript(Pool pool, Machine machine) throws Exception {
+        return Mustache.toString(getClass(), REPOSITORIES_TEMPLATE,
+            ImmutableMap.<String, List<Map<String, String>>>of(
+                "repositories", repositoriesAsListOfMaps(pool.getSoftware())));
+    }
+
+    private List<Map<String, String>> repositoriesAsListOfMaps(Software software) {
+        return Lists.transform(software.getRepositories(), new Function<Repository, Map<String, String>>() {
+            @Override
+            public Map<String, String> apply(Repository repository) {
+                ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String>builder()
+                    .put("name", repository.getName())
+                    .put("content", Joiner.on("\\n").join(repository.getEntries()));
+
+                if (repository.getKey().isPresent()) {
+                    builder.put("key", repository.getKey().get().replace("\n", "\\n"));
+                }
+                return builder.build();
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activities/IsMachinePortOpen.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activities/IsMachinePortOpen.java b/core/src/main/java/org/apache/provisionr/core/activities/IsMachinePortOpen.java
new file mode 100644
index 0000000..f19f542
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activities/IsMachinePortOpen.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.pool.Machine;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Check that we can connect to a specific port on a remote machine
+ * <p/>
+ * This activity expects to find an environment variable named 'machine'
+ */
+public class IsMachinePortOpen implements JavaDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(IsMachinePortOpen.class);
+
+    public static final String MACHINE = "machine";
+    public static final int TIMEOUT_IN_MILLISECONDS = 1000;
+
+    private final String resultVariable;
+    private final int port;
+
+    public IsMachinePortOpen(String resultVariable, int port) {
+        checkArgument(port > 0, "invalid port number");
+        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
+        this.port = port;
+    }
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        Machine machine = (Machine) execution.getVariable(MACHINE);
+        checkNotNull(machine, "expecting a process variable named machine (multi-instance?)");
+
+        if (isPortOpen(machine, port)) {
+            LOG.info("<< Port {} is OPEN on {}", port, machine.getPublicDnsName());
+            execution.setVariable(resultVariable, true);
+
+        } else {
+            LOG.info("<< Port {} is CLOSED on {}", port, machine.getPublicDnsName());
+            execution.setVariable(resultVariable, false);
+        }
+    }
+
+    private boolean isPortOpen(Machine machine, int port) {
+        InetSocketAddress socketAddress = new InetSocketAddress(machine.getPublicDnsName(), port);
+
+        Socket socket = null;
+        try {
+            socket = new Socket();
+            socket.setReuseAddress(false);
+            socket.setSoLinger(false, 1);
+            socket.setSoTimeout(TIMEOUT_IN_MILLISECONDS);
+            socket.connect(socketAddress, TIMEOUT_IN_MILLISECONDS);
+
+        } catch (IOException e) {
+            return false;
+        } finally {
+            if (socket != null) {
+                try {
+                    socket.close();
+                } catch (IOException ioe) {
+                    // no work to do
+                }
+            }
+        }
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activities/KillMachineSetUpProcesses.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activities/KillMachineSetUpProcesses.java b/core/src/main/java/org/apache/provisionr/core/activities/KillMachineSetUpProcesses.java
new file mode 100644
index 0000000..08b4841
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activities/KillMachineSetUpProcesses.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class KillMachineSetUpProcesses implements JavaDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(KillMachineSetUpProcesses.class);
+
+    private RuntimeService runtimeService;
+    private String variableWithProcessIds;
+
+    public KillMachineSetUpProcesses(RuntimeService runtimeService, String variableWithProcessIds) {
+        this.runtimeService = checkNotNull(runtimeService, "runtimeService is null");
+        this.variableWithProcessIds = checkNotNull(variableWithProcessIds, "variableWithProcessIds is null");
+    }
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        @SuppressWarnings("unchecked")
+        List<String> processIds = (List<String>) execution.getVariable(variableWithProcessIds);
+
+        List<String> forceEnded = Lists.newArrayList(Iterables.filter(processIds, new Predicate<String>() {
+            @Override
+            public boolean apply(String processInstanceId) {
+                ProcessInstance instance = runtimeService.createProcessInstanceQuery()
+                    .processInstanceId(processInstanceId).singleResult();
+                if (instance != null && !instance.isEnded()) {
+                    runtimeService.deleteProcessInstance(processInstanceId, "Pending process needs to be killed");
+                    return true;
+                }
+                return false;
+            }
+        }));
+        LOG.info("Killed pending machine setup processes: {}", forceEnded);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activities/PuppetActivity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activities/PuppetActivity.java b/core/src/main/java/org/apache/provisionr/core/activities/PuppetActivity.java
new file mode 100644
index 0000000..704f9e1
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activities/PuppetActivity.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.apache.provisionr.core.Ssh;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.connection.channel.direct.Session;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract activity useful for implementing activities that execute
+ * puppet scripts on pool machines
+ */
+public abstract class PuppetActivity implements JavaDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PuppetActivity.class);
+
+    /**
+     * Puppet apply had no failures during the current transaction
+     * <p/>
+     * --detailed-exitcodes Provide transaction information via exit codes. If this is
+     * enabled, an exit code of '2' means there were changes, an exit code of '4' means
+     * there were failures during the transaction, and an exit code of '6' means there
+     * were both changes and failures.
+     *
+     * @see <a href="http://docs.puppetlabs.com/man/apply.html" />
+     */
+    public static final int PUPPET_FINISHED_WITH_NO_FAILURES = 2;
+
+    private final String remoteFileName;
+
+    public PuppetActivity(String remoteFileName) {
+        this.remoteFileName = checkNotNull(remoteFileName);
+    }
+
+    /**
+     * This method creates a Puppet script for remote execution
+     */
+    public abstract String createPuppetScript(Pool pool, Machine machine) throws Exception;
+
+    /**
+     * Override this method to change the credentials used for SSH access
+     */
+    public AdminAccess overrideAdminAccess(Pool pool) {
+        return pool.getAdminAccess();
+    }
+
+    /**
+     * Map of additional files to create on the remote machine. Contains pairs of (remotePath, content)
+     */
+    public Map<String, String> createAdditionalFiles(Pool pool, Machine machine) throws Exception {
+        return ImmutableMap.of();
+    }
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        Pool pool = (Pool) execution.getVariable(CoreProcessVariables.POOL);
+        checkNotNull(pool, "Please add the pool description as a process " +
+            "variable with the name '%s'.", CoreProcessVariables.POOL);
+
+        Machine machine = (Machine) execution.getVariable("machine");
+        checkNotNull(machine, "expecting a process variable named 'machine'");
+
+        LOG.info(">> Connecting to machine {} to run puppet script", machine);
+
+        SSHClient client = Ssh.newClient(machine, overrideAdminAccess(pool));
+        try {
+            for (Map.Entry<String, String> entry : createAdditionalFiles(pool, machine).entrySet()) {
+                Ssh.createFile(client, /* content = */ entry.getValue(), 0600, /* destination= */ entry.getKey());
+            }
+
+            final String destination = "/tmp/" + remoteFileName + ".pp";
+            Ssh.createFile(client, createPuppetScript(pool, machine), 0600, destination);
+
+            Session session = client.startSession();
+            try {
+                session.allocateDefaultPTY();
+
+                // TODO: extract this loop outside of this activity (probably using a business process error)
+                final String runScriptWithWaitCommand = "while ! which puppet &> /dev/null ; " +
+                    "do echo 'Puppet command not found. Waiting for userdata.sh script to finish (10s)' " +
+                    "&& sleep 10; " +
+                    "done " +
+                    "&& sudo puppet apply --detailed-exitcodes --debug --verbose " + destination;
+                Session.Command command = session.exec(runScriptWithWaitCommand);
+
+                Ssh.logCommandOutput(LOG, machine.getExternalId(), command);
+                command.join();
+
+                final Integer exitStatus = command.getExitStatus();
+                if (exitStatus != PUPPET_FINISHED_WITH_NO_FAILURES && exitStatus != 0) {
+                    throw new RuntimeException(String.format("Failed to execute puppet. " +
+                        "Exit code: %d. Exit message: %s", exitStatus, command.getExitErrorMessage()));
+
+                } else {
+                    LOG.info("<< Command completed successfully with exit code 0");
+                }
+
+
+            } finally {
+                session.close();
+            }
+        } finally {
+            client.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/activities/SpawnProcessForEachMachine.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/activities/SpawnProcessForEachMachine.java b/core/src/main/java/org/apache/provisionr/core/activities/SpawnProcessForEachMachine.java
new file mode 100644
index 0000000..c27fd0b
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/activities/SpawnProcessForEachMachine.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreConstants;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import java.util.List;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Create an Activiti process for each machine and store the process IDs
+ */
+public class SpawnProcessForEachMachine implements JavaDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SpawnProcessForEachMachine.class);
+
+    /**
+     * Name of the process variable that stores a {@link org.apache.provisionr.api.pool.Machine Machine} object.
+     * Used inside the process to connect to that machine.
+     */
+    private static final String MACHINE = "machine";
+
+    private final ProcessEngine processEngine;
+    private final String processKey;
+    private final String type;
+    private final String resultVariable;
+
+    public SpawnProcessForEachMachine(
+        ProcessEngine processEngine, String processKey, String type, String resultVariable
+    ) {
+        this.processEngine = checkNotNull(processEngine, "processEngine is null");
+        this.processKey = checkNotNull(processKey, "processKey is null");
+        this.type = checkNotNull(type, "type is null");
+        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
+    }
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        final Pool pool = (Pool) execution.getVariable(CoreProcessVariables.POOL);
+        checkNotNull(pool, "Expecting to find a pool description as process variable");
+
+        @SuppressWarnings("unchecked")
+        List<Machine> machines = (List<Machine>) execution.getVariable(CoreProcessVariables.MACHINES);
+        checkNotNull(machines, "Expecting to find the list of machines as process variable");
+
+        final String poolBusinessKey = String.class.cast(execution.getVariable(CoreProcessVariables.POOL_BUSINESS_KEY));
+        checkNotNull(poolBusinessKey, "No way to link sub-processes to master process, poolBusinessKey is null");
+
+        /* Authenticate as kermit to make the process visible in the Explorer UI */
+        processEngine.getIdentityService().setAuthenticatedUserId(CoreConstants.ACTIVITI_EXPLORER_DEFAULT_USER);
+
+        List<String> processIds = Lists.newArrayList();
+        for (Machine machine : machines) {
+            final String perMachineProcessBusinessKey = String.format("%s-%s-%s",
+                execution.getProcessBusinessKey(), type, machine.getExternalId());
+
+            ProcessInstance perMachineProcess = processEngine.getRuntimeService().startProcessInstanceByKey(
+                processKey, perMachineProcessBusinessKey,
+                ImmutableMap.<String, Object>of(CoreProcessVariables.POOL, pool,
+                    CoreProcessVariables.POOL_BUSINESS_KEY, poolBusinessKey,
+                    CoreProcessVariables.IS_CACHED_IMAGE, pool.getSoftware().isCachedImage(),
+                    MACHINE, machine));
+
+            LOG.info("Started background '" + type + "' process {} ({}) for machine {}",
+                new Object[]{perMachineProcessBusinessKey, perMachineProcess.getId(), machine.getExternalId()});
+            processIds.add(perMachineProcess.getId());
+        }
+
+        LOG.info("Saving process IDs {} as {}", processIds, resultVariable);
+        execution.setVariable(resultVariable, processIds);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/logging/ErrorStreamLogger.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/logging/ErrorStreamLogger.java b/core/src/main/java/org/apache/provisionr/core/logging/ErrorStreamLogger.java
new file mode 100644
index 0000000..2369268
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/logging/ErrorStreamLogger.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.logging;
+
+import java.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+
+public class ErrorStreamLogger extends StreamLogger {
+
+    public ErrorStreamLogger(InputStream inputStream, Logger logger, Marker marker) {
+        super(inputStream, logger, marker);
+    }
+
+    @Override
+    protected void log(Logger logger, Marker marker, String line) {
+        logger.error(marker, line);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/logging/InfoStreamLogger.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/logging/InfoStreamLogger.java b/core/src/main/java/org/apache/provisionr/core/logging/InfoStreamLogger.java
new file mode 100644
index 0000000..810131b
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/logging/InfoStreamLogger.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.logging;
+
+import java.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+
+public class InfoStreamLogger extends StreamLogger {
+
+    public InfoStreamLogger(InputStream inputStream, Logger logger, Marker marker) {
+        super(inputStream, logger, marker);
+    }
+
+    @Override
+    protected void log(Logger logger, Marker marker, String line) {
+        logger.info(marker, line);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/logging/StreamLogger.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/logging/StreamLogger.java b/core/src/main/java/org/apache/provisionr/core/logging/StreamLogger.java
new file mode 100644
index 0000000..1e1e3eb
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/logging/StreamLogger.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.logging;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Throwables;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+
+public abstract class StreamLogger extends Thread {
+
+    private final InputStream inputStream;
+    private final Logger logger;
+    private final Marker marker;
+
+    public StreamLogger(InputStream inputStream, Logger logger, Marker marker) {
+        this.inputStream = checkNotNull(inputStream, "inputStream is null");
+        this.logger = checkNotNull(logger, "logger is null");
+        this.marker = checkNotNull(marker, "marker is null");
+
+        setName(marker.getName());
+        setDaemon(true);
+    }
+
+    /**
+     * Write the log message at a specific level including the marker
+     *
+     * @param logger reference to external logger
+     * @param marker log message marker
+     * @param line   line collected from the input stream
+     */
+    protected abstract void log(Logger logger, Marker marker, String line);
+
+
+    @Override
+    public void run() {
+        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+        try {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if (!line.isEmpty()) {
+                    log(logger, marker, line);
+                }
+            }
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/templates/PoolTemplate.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/templates/PoolTemplate.java b/core/src/main/java/org/apache/provisionr/core/templates/PoolTemplate.java
new file mode 100644
index 0000000..81b6e58
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/templates/PoolTemplate.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.templates;
+
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Function;
+
+/**
+ * Marker interface for pre-configured pools. You can use it by
+ * applying the function on an existing pool definition
+ */
+public interface PoolTemplate extends Function<Pool, Pool> {
+
+    /**
+     * Get the pre-configured pool template identifier
+     */
+    String getId();
+
+    /**
+     * A short description of this template
+     */
+    String getDescription();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/templates/PoolTemplateInstaller.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/templates/PoolTemplateInstaller.java b/core/src/main/java/org/apache/provisionr/core/templates/PoolTemplateInstaller.java
new file mode 100644
index 0000000..150becd
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/templates/PoolTemplateInstaller.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.templates;
+
+import org.apache.provisionr.core.templates.xml.XmlTemplate;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Maps;
+import java.io.File;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.felix.fileinstall.ArtifactInstaller;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Listener for pool template files
+ * <p/>
+ * When a new xml file is places under templates this class is
+ * notified and a new pool template is registered as a service
+ */
+public class PoolTemplateInstaller implements ArtifactInstaller {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PoolTemplateInstaller.class);
+
+    public static final String TEMPLATES_FOLDER = "templates";
+    public static final String TEMPLATES_EXTENSION = ".xml";
+
+    /**
+     * A bundle context provided by the OSGi framework
+     */
+    private final BundleContext bundleContext;
+
+    /**
+     * A map with all the pool templates registered by this listener
+     */
+    private final ConcurrentMap<String, ServiceRegistration> templates;
+
+    public PoolTemplateInstaller(BundleContext bundleContext) {
+        this.bundleContext = checkNotNull(bundleContext, "bundleContext is null");
+        this.templates = Maps.newConcurrentMap();
+    }
+
+    @Override
+    public boolean canHandle(File file) {
+        return TEMPLATES_FOLDER.equals(file.getParentFile().getName())
+            && file.getName().endsWith(TEMPLATES_EXTENSION);
+    }
+
+    /**
+     * Install a new pool template as a service using the file content
+     * <p/>
+     * The absolute file path is the unique identifier
+     */
+    @Override
+    public void install(File file) throws Exception {
+        final String absolutePath = file.getAbsolutePath();
+        LOG.info("Installing Pool template from  " + absolutePath);
+
+        if (!templates.containsKey(absolutePath)) {
+            PoolTemplate template = XmlTemplate.newXmlTemplate(file);
+            ServiceRegistration registration = bundleContext
+                .registerService(PoolTemplate.class.getName(), template, null);
+
+            templates.put(absolutePath, registration);
+            LOG.info("Registered new template with ID: " + template.getId());
+        }
+    }
+
+    /**
+     * Uninstall a pool description identified by the absolute file path
+     */
+    @Override
+    public void uninstall(File file) throws Exception {
+        final String absolutePath = file.getAbsolutePath();
+        LOG.info("Uninstalling Pool template for path " + absolutePath);
+
+        if (templates.containsKey(absolutePath)) {
+            templates.remove(absolutePath).unregister();
+        }
+    }
+
+    /**
+     * Update a pool template
+     * <p/>
+     * This method performs no actions if there is no pool registered for this file
+     */
+    @Override
+    public void update(File file) throws Exception {
+        if (templates.containsKey(file.getAbsolutePath())) {
+            uninstall(file);
+            install(file);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/templates/xml/FileEntry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/templates/xml/FileEntry.java b/core/src/main/java/org/apache/provisionr/core/templates/xml/FileEntry.java
new file mode 100644
index 0000000..5e5811e
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/templates/xml/FileEntry.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.templates.xml;
+
+import com.google.common.annotations.VisibleForTesting;
+import static com.google.common.base.Preconditions.checkNotNull;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * Represents a file entry from a pool template
+ * <p/>
+ * Designed to be consumed only by JAXB. It looks like this in xml:
+ * <p/>
+ * <file source="http://archive.cloudera.com/cm4/installer/latest/cloudera-manager-installer.bin"
+ * destination="/opt/cloudera-manager-installer.bin"/>
+ */
+public class FileEntry {
+
+    private String source;
+    private String destination;
+
+    public FileEntry() {
+    }
+
+    @VisibleForTesting
+    FileEntry(String source, String destination) {
+        this.source = checkNotNull(source, "source is null");
+        this.destination = checkNotNull(destination, "destination is null");
+    }
+
+    @XmlAttribute(name = "source")
+    public String getSource() {
+        return source;
+    }
+
+    public void setSource(String source) {
+        this.source = checkNotNull(source, "source is null");
+    }
+
+    @XmlAttribute(name = "destination")
+    public String getDestination() {
+        return destination;
+    }
+
+    public void setDestination(String destination) {
+        this.destination = checkNotNull(destination, "destination is null");
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        FileEntry fileEntry = (FileEntry) o;
+
+        if (destination != null ? !destination.equals(fileEntry.destination) : fileEntry.destination != null)
+            return false;
+        if (source != null ? !source.equals(fileEntry.source) : fileEntry.source != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = source != null ? source.hashCode() : 0;
+        result = 31 * result + (destination != null ? destination.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "FileEntry{" +
+            "source='" + source + '\'' +
+            ", destination='" + destination + '\'' +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/templates/xml/RepositoryEntry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/templates/xml/RepositoryEntry.java b/core/src/main/java/org/apache/provisionr/core/templates/xml/RepositoryEntry.java
new file mode 100644
index 0000000..3220298
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/templates/xml/RepositoryEntry.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.templates.xml;
+
+import com.google.common.annotations.VisibleForTesting;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Lists.newArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+
+/**
+ * Represents a custom repository entry from a pool template
+ * <p/>
+ * Designed to be consumed only by JAXB. It looks like this in xml:
+ * <p/>
+ * <repository id="cloudera-cdh3">
+ * <entries>
+ * <entry>deb http://archive.cloudera.com/debian lucid-cdh3 contrib</entry>
+ * </entries>
+ * <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK----- ]]</key>
+ * </repository>
+ */
+public class RepositoryEntry {
+
+    private String id;
+
+    private List<String> entries = newArrayList();
+
+    private String key;
+
+    public RepositoryEntry() {
+    }
+
+    @VisibleForTesting
+    RepositoryEntry(String id, List<String> entries, String key) {
+        this.id = checkNotNull(id, "id is null");
+        this.entries = checkNotNull(entries, "entries is null");
+        this.key = checkNotNull(key, "key is null");
+    }
+
+    @XmlAttribute(name = "id")
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = checkNotNull(id, "id is null");
+    }
+
+    @XmlElementWrapper(name = "entries")
+    @XmlElement(name = "entry")
+    public List<String> getEntries() {
+        return entries;
+    }
+
+    public void setEntries(List<String> entries) {
+        this.entries = checkNotNull(entries, "entries is null");
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = checkNotNull(key, "key is null");
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        RepositoryEntry that = (RepositoryEntry) o;
+
+        if (entries != null ? !entries.equals(that.entries) : that.entries != null) return false;
+        if (id != null ? !id.equals(that.id) : that.id != null) return false;
+        if (key != null ? !key.equals(that.key) : that.key != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id != null ? id.hashCode() : 0;
+        result = 31 * result + (entries != null ? entries.hashCode() : 0);
+        result = 31 * result + (key != null ? key.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "RepositoryEntry{" +
+            "id='" + id + '\'' +
+            ", entries=" + entries +
+            ", key='" + key + '\'' +
+            '}';
+    }
+}


[13/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activities/InstallRepositoriesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activities/InstallRepositoriesTest.java b/core/src/test/java/com/axemblr/provisionr/core/activities/InstallRepositoriesTest.java
deleted file mode 100644
index 0893fe4..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activities/InstallRepositoriesTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Repository;
-import com.axemblr.provisionr.api.software.Software;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class InstallRepositoriesTest {
-
-    @Test
-    public void testCreatePuppetScript() throws Exception {
-        Repository repository = Repository.builder()
-            .name("bigtop")
-            .addEntry("deb http://bigtop.s3.amazonaws.com/releases/0.5.0/ubuntu/lucid/x86_64  bigtop contrib")
-            .key("-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
-                "Version: GnuPG v1.4.10 (GNU/Linux)\n" +
-                "\n" +
-                "[....]")
-            .createRepository();
-
-        Pool pool = mock(Pool.class);
-        when(pool.getSoftware()).thenReturn(Software.builder().repository(repository).createSoftware());
-
-        PuppetActivity activity = new InstallRepositories();
-        String content = activity.createPuppetScript(pool, null);
-
-        assertThat(content).contains("apt::repository { \"bigtop\":\n" +
-            "  content => \"deb http://bigtop.s3.amazonaws.com/releases/0.5.0/ubuntu/lucid/x86_64  bigtop contrib\\n\",\n" +
-            "  key => \"-----BEGIN PGP PUBLIC KEY BLOCK-----\\nVersion: GnuPG v1.4.10 (GNU/Linux)\\n\\n[....]\"\n" +
-            "}");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activities/IsMachinePortOpenTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activities/IsMachinePortOpenTest.java b/core/src/test/java/com/axemblr/provisionr/core/activities/IsMachinePortOpenTest.java
deleted file mode 100644
index 9c2d2f1..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activities/IsMachinePortOpenTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.test.ProcessVariablesCollector;
-import java.io.IOException;
-import java.net.ServerSocket;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class IsMachinePortOpenTest {
-
-    private static final String RESULT = "result";
-
-    @Test
-    public void testWithRandomOpenPort() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-
-        when(execution.getVariable(eq(IsMachinePortOpen.MACHINE)))
-            .thenReturn(Machine.builder().localhost().createMachine());
-
-        ProcessVariablesCollector collector = new ProcessVariablesCollector();
-        collector.install(execution);
-
-        ServerSocket socket = null;
-        try {
-            socket = new ServerSocket(0);
-
-            JavaDelegate delegate = new IsMachinePortOpen(RESULT, socket.getLocalPort());
-            delegate.execute(execution);
-
-            assertThat((Boolean) collector.getVariable(RESULT)).isTrue();
-
-        } finally {
-            if (socket != null) {
-                socket.close();
-            }
-        }
-    }
-
-    @Test
-    public void testWithRandomClosedPort() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-
-        when(execution.getVariable(eq(IsMachinePortOpen.MACHINE)))
-            .thenReturn(Machine.builder().localhost().createMachine());
-
-        ProcessVariablesCollector collector = new ProcessVariablesCollector();
-        collector.install(execution);
-
-        JavaDelegate delegate = new IsMachinePortOpen(RESULT, findRandomNotUsedPort());
-        delegate.execute(execution);
-
-        assertThat((Boolean) collector.getVariable(RESULT)).isFalse();
-    }
-
-    private int findRandomNotUsedPort() throws IOException {
-        ServerSocket socket = null;
-        try {
-            socket = new ServerSocket(0);
-            return socket.getLocalPort();
-        } finally {
-            if (socket != null) {
-                socket.close();
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activities/KillMachineSetUpProcessesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activities/KillMachineSetUpProcessesTest.java b/core/src/test/java/com/axemblr/provisionr/core/activities/KillMachineSetUpProcessesTest.java
deleted file mode 100644
index 6b59891..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activities/KillMachineSetUpProcessesTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.axemblr.provisionr.test.ProcessVariablesCollector;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-import java.util.Map;
-
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.junit.Test;
-
-public class KillMachineSetUpProcessesTest extends CheckProcessesTest {
-
-    private static final String PROCESS_IDS = "process_ids";
-
-    @Test
-    public void testWithAListOfEndedProcesses() throws Exception {
-        RuntimeService runtimeService = runTest(Lists.newArrayList("1", "2"), ImmutableMap.of(
-            "1", mockProcessInstance(/* ended= */ true),
-            "2", mockProcessInstance(/* ended= */ true)
-        ));
-        verify(runtimeService, never()).deleteProcessInstance(anyString(), anyString());
-    }
-
-    @Test
-    public void testWithAListOfActiveProcesses() throws Exception {
-        RuntimeService runtimeService = runTest(Lists.newArrayList("1", "2"), ImmutableMap.of(
-            "1", mockProcessInstance(/* ended= */ false),
-            "2", mockProcessInstance(/* ended= */ false)
-        ));
-        verify(runtimeService, times(2)).deleteProcessInstance(anyString(), anyString());
-    }
-
-    @Test
-    public void testWithAListOfActiveAndInactiveProcesses() throws Exception {
-        RuntimeService runtimeService = runTest(Lists.newArrayList("1", "2"), ImmutableMap.of(
-            "1", mockProcessInstance(/* ended= */ true),
-            "2", mockProcessInstance(/* ended= */ false)
-        ));
-
-        verify(runtimeService, times(1)).deleteProcessInstance(anyString(), anyString());
-    }
-
-    @Test
-    public void testWithAListOfActiveAndInvalidProcesses() throws Exception {
-        RuntimeService runtimeService = runTest(Lists.newArrayList("1", "invalid"), ImmutableMap.of(
-            "1", mockProcessInstance(/* ended= */ false)));
-        verify(runtimeService, times(1)).deleteProcessInstance(anyString(), anyString());
-    }
-
-    private RuntimeService runTest(List<String> processIds, Map<String, ProcessInstance> processMap) throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-        when(execution.getVariable(eq(PROCESS_IDS))).thenReturn(processIds);
-
-        ProcessVariablesCollector collector = new ProcessVariablesCollector();
-        collector.install(execution);
-
-        RuntimeService runtimeService = mockRuntimeService(processMap, "invalid");
-
-        JavaDelegate delegate = new KillMachineSetUpProcesses(runtimeService, PROCESS_IDS);
-        delegate.execute(execution);
-
-        return runtimeService;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activities/SpawnProcessForEachMachineTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activities/SpawnProcessForEachMachineTest.java b/core/src/test/java/com/axemblr/provisionr/core/activities/SpawnProcessForEachMachineTest.java
deleted file mode 100644
index ccb2aa8..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activities/SpawnProcessForEachMachineTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import static org.fest.assertions.api.Assertions.assertThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.withSettings;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.axemblr.provisionr.test.ProcessVariablesCollector;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-import java.util.UUID;
-
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration;
-import org.junit.Test;
-
-public class SpawnProcessForEachMachineTest {
-
-    private static final String EMPTY_PROCESS_KEY = "empty";
-    private static final String RESULT = "result";
-
-    private static final String BUSINESS_KEY = UUID.randomUUID().toString();
-
-    @Test
-    public void testSpawnSampleProcessForLocalhost() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-        Pool pool = mock(Pool.class, withSettings().serializable());
-        Software software = mock(Software.class, withSettings().serializable());
-        when(software.isCachedImage()).thenReturn(false);
-        when(pool.getSoftware()).thenReturn(software);
-        when(execution.getVariable(eq(CoreProcessVariables.POOL))).thenReturn(pool);
-        when(execution.getVariable(eq(CoreProcessVariables.POOL_BUSINESS_KEY))).thenReturn(BUSINESS_KEY);
-
-        List<Machine> machines = Lists.newArrayList(
-            Machine.builder().localhost().createMachine(),
-            Machine.builder().localhost().externalId("local-2").createMachine()
-        );
-        when(execution.getVariable(eq(CoreProcessVariables.MACHINES))).thenReturn(machines);
-
-        ProcessVariablesCollector collector = new ProcessVariablesCollector();
-        collector.install(execution);
-
-        ProcessEngine processEngine = new StandaloneInMemProcessEngineConfiguration()
-            .setJobExecutorActivate(true).buildProcessEngine();
-        processEngine.getRepositoryService().createDeployment()
-            .addClasspathResource("diagrams/empty.bpmn20.xml").deploy();
-
-        try {
-            JavaDelegate delegate = new SpawnProcessForEachMachine(processEngine, EMPTY_PROCESS_KEY, "test", RESULT);
-            delegate.execute(execution);
-
-            @SuppressWarnings("unchecked")
-            List<String> processInstanceIds = (List<String>) collector.getVariable(RESULT);
-
-            assertThat(processInstanceIds).hasSize(2);
-
-        } finally {
-            processEngine.close();
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/logging/StreamLoggerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/logging/StreamLoggerTest.java b/core/src/test/java/com/axemblr/provisionr/core/logging/StreamLoggerTest.java
deleted file mode 100644
index a17ebda..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/logging/StreamLoggerTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.logging;
-
-import com.axemblr.provisionr.core.Ssh;
-import com.google.common.base.Charsets;
-import com.google.common.collect.Lists;
-import java.io.ByteArrayInputStream;
-import java.util.List;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-
-public class StreamLoggerTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(Ssh.class);
-
-    @Test
-    public void testStreamLogger() throws InterruptedException {
-        final List<String> lines = Lists.newCopyOnWriteArrayList();
-
-        final byte[] bytes = "line1\nline2\nline3".getBytes(Charsets.UTF_8);
-        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
-
-        final StreamLogger logger = new StreamLogger(inputStream, LOG, MarkerFactory.getMarker("test")) {
-            @Override
-            protected void log(Logger logger, Marker marker, String line) {
-                logger.info(marker, line);  /* just for visual inspection */
-                lines.add(line);
-            }
-        };
-        logger.start();
-
-        logger.join();
-        assertThat(lines).contains("line1", "line2", "line3");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/templates/PoolTemplateInstallerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/templates/PoolTemplateInstallerTest.java b/core/src/test/java/com/axemblr/provisionr/core/templates/PoolTemplateInstallerTest.java
deleted file mode 100644
index 8aaa772..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/templates/PoolTemplateInstallerTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.templates;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.Dictionary;
-import org.apache.ibatis.io.Resources;
-import org.junit.Test;
-import org.mockito.Matchers;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-public class PoolTemplateInstallerTest {
-
-    @Test
-    public void testInstallAndUninstallTemplate() throws Exception {
-        BundleContext bundleContext = mock(BundleContext.class);
-
-        ServiceRegistration registration = mock(ServiceRegistration.class);
-        when(bundleContext.registerService(eq(PoolTemplate.class.getName()), any(),
-            Matchers.<Dictionary<String, ?>>any())).thenReturn(registration);
-
-        File file = getPathToCdh3Template();
-        PoolTemplateInstaller installer = new PoolTemplateInstaller(bundleContext);
-
-        installer.install(file);
-        verify(bundleContext).registerService(eq(PoolTemplate.class.getName()),
-            any(), (Dictionary<String, ?>) isNull());
-        verifyZeroInteractions(registration);
-
-        installer.uninstall(file);
-        verify(registration).unregister();
-    }
-
-    private File getPathToCdh3Template() throws URISyntaxException, IOException {
-        return new File(Resources.getResourceURL("com/axemblr/provisionr/core/templates/cdh3.xml").toURI());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/templates/xml/XmlTemplateTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/templates/xml/XmlTemplateTest.java b/core/src/test/java/com/axemblr/provisionr/core/templates/xml/XmlTemplateTest.java
deleted file mode 100644
index fe5ef06..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/templates/xml/XmlTemplateTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.templates.xml;
-
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.core.BaseJaxbTest;
-import com.google.common.base.Charsets;
-import static com.google.common.collect.Lists.newArrayList;
-import com.google.common.io.Resources;
-import java.io.IOException;
-import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class XmlTemplateTest extends BaseJaxbTest {
-
-    public static final String DEFAULT_JENKINS_TEMPLATE = "com/axemblr/provisionr/core/templates/jenkins.xml";
-
-    public static final String DEFAULT_CDH3_TEMPLATE = "com/axemblr/provisionr/core/templates/cdh3.xml";
-
-    @Test
-    public void testLoadDefaultCdh3Template() throws Exception {
-        XmlTemplate template = XmlTemplate.newXmlTemplate(readResource(DEFAULT_CDH3_TEMPLATE));
-
-        assertThat(template.getId()).isEqualTo("cdh3");
-        assertThat(template.getPackages()).contains("hue");
-        assertThat(template.getOsVersion()).isEqualTo("10.04 LTS");
-
-        assertThat(template.getRepositories()).hasSize(2);
-        assertThat(template.getFiles()).hasSize(1);
-    }
-
-    @Test
-    public void testApplyCdh3TemplateToNetworkAndSoftware() throws Exception {
-        XmlTemplate template = XmlTemplate.newXmlTemplate(readResource(DEFAULT_CDH3_TEMPLATE));
-
-        Network network = template.apply(Network.builder().createNetwork());
-        assertThat(network.getIngress()).contains(
-            Rule.builder().anySource().tcp().port(8080).createRule());
-
-
-        Software software = template.apply(Software.builder().createSoftware());
-        assertThat(software.getPackages()).contains("hue").contains("hadoop-0.20");
-
-        assertThat(software.getFiles()).hasSize(1);
-        assertThat(software.getRepositories()).hasSize(2);
-    }
-
-    @Test
-    public void testLoadDefaultJenkinsTemplate() throws Exception {
-        XmlTemplate template = XmlTemplate.newXmlTemplate(readResource(DEFAULT_JENKINS_TEMPLATE));
-
-        assertThat(template.getPorts()).contains(8080);
-        assertThat(template.getRepositories()).hasSize(1);
-
-        assertThat(template.getPackages()).contains("jenkins").contains("git-core");
-    }
-
-    @Test
-    public void testSerializeBasicTemplateAsXml() throws Exception {
-        XmlTemplate template = new XmlTemplate();
-        template.setId("jenkins");
-
-        template.setDescription("Just testing");
-        template.setOsVersion("10.04 LTS");
-
-        template.setPackages(newArrayList("jenkins", "git-core", "subversion"));
-        template.setPorts(newArrayList(8080, 22));
-
-        template.setFiles(newArrayList(
-            new FileEntry("http://google.com", "/opt/google.html")
-        ));
-
-        template.setRepositories(newArrayList(
-            new RepositoryEntry("jenkins", newArrayList("deb ..."), "-----BEGIN PGP PUBLIC KEY BLOCK----- ...")
-        ));
-
-        String actual = asXml(template);
-        assertXMLEqual(actual, readResource("templates/test.xml"), actual);
-    }
-
-    private String readResource(String resource) throws IOException {
-        return Resources.toString(Resources.getResource(resource), Charsets.UTF_8);
-    }
-
-    @Override
-    public Class[] getContextClasses() {
-        return new Class[]{XmlTemplate.class};
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/BaseJaxbTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/BaseJaxbTest.java b/core/src/test/java/org/apache/provisionr/core/BaseJaxbTest.java
new file mode 100644
index 0000000..3c1d05e
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/BaseJaxbTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Before;
+
+public abstract class BaseJaxbTest {
+
+    protected JAXBContext jaxb;
+
+    static {
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreComments(true);
+        XMLUnit.setIgnoreAttributeOrder(true);
+    }
+
+    @Before
+    public void setUp() throws JAXBException {
+        jaxb = JAXBContext.newInstance(getContextClasses());
+    }
+
+    public abstract Class[] getContextClasses();
+
+    /**
+     * Marshal an object as XML using a standard JAXB Context
+     */
+    protected String asXml(Object obj) throws Exception {
+        ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
+        PrintStream out = new PrintStream(outBytes);
+
+        Marshaller marshaller = jaxb.createMarshaller();
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+
+        marshaller.marshal(obj, out);
+        return outBytes.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/ProvisionrSupportTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/ProvisionrSupportTest.java b/core/src/test/java/org/apache/provisionr/core/ProvisionrSupportTest.java
new file mode 100644
index 0000000..93eb226
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/ProvisionrSupportTest.java
@@ -0,0 +1,32 @@
+package org.apache.provisionr.core;
+
+import static org.fest.assertions.api.Assertions.assertThat;
+
+import org.apache.provisionr.api.pool.Pool;
+
+import org.junit.Test;
+
+public class ProvisionrSupportTest {
+
+    @Test
+    public void testConvertTimeout() {
+        ProvisionrSupport provisionr = new ProvisionrSupportTestable();
+        assertThat(provisionr.convertTimeoutToISO8601TimeDuration(600)).isEqualTo("PT10M");
+        assertThat(provisionr.convertTimeoutToISO8601TimeDuration(601)).isEqualTo("PT601S");
+        assertThat(provisionr.convertTimeoutToISO8601TimeDuration(300)).isEqualTo("PT5M");
+        assertThat(provisionr.convertTimeoutToISO8601TimeDuration(42)).isEqualTo("PT42S");
+    }
+}
+
+class ProvisionrSupportTestable extends ProvisionrSupport {
+    @Override
+    public String getId() {
+        return null;
+    }
+    @Override
+    public String startPoolManagementProcess(String businessKey, Pool pool) {
+        return null;
+    }
+    @Override
+    public void destroyPool(String businessKey) {}
+};

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/SshLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/SshLiveTest.java b/core/src/test/java/org/apache/provisionr/core/SshLiveTest.java
new file mode 100644
index 0000000..c1a002a
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/SshLiveTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core;
+
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.core.logging.StreamLogger;
+import com.google.common.collect.Lists;
+import com.google.common.io.CharStreams;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.UUID;
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.connection.channel.direct.Session;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+public class SshLiveTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SshLiveTest.class);
+
+    private final Machine localhost = Machine.builder().localhost().createMachine();
+
+    private final AdminAccess adminAccess = AdminAccess.builder()
+        .asCurrentUser().createAdminAccess();
+
+    @Test
+    public void testConnectToLocalhostAndCollectOutput() throws IOException {
+        SSHClient client = Ssh.newClient(localhost, adminAccess, 1000);
+        try {
+            Session session = client.startSession();
+            try {
+                final Session.Command command = session.exec("echo 'stdout' && echo 'stderr' 1>&2");
+
+                String stdout = CharStreams.toString(new InputStreamReader(command.getInputStream()));
+                String stderr = CharStreams.toString(new InputStreamReader(command.getErrorStream()));
+
+                command.join();
+                assertThat(command.getExitStatus()).isEqualTo(0);
+                assertThat(command.getExitErrorMessage()).isNull();
+
+                assertThat(stdout).contains("stdout");
+                assertThat(stderr).contains("stderr");
+
+            } finally {
+                session.close();
+            }
+        } finally {
+            client.close();
+        }
+    }
+
+    @Test
+    public void testConnectStreamLoggerToCommand() throws IOException, InterruptedException {
+        SSHClient client = Ssh.newClient(localhost, adminAccess, 1000);
+        try {
+            Session session = client.startSession();
+            try {
+                final Session.Command command = session.exec("echo 'line1' && echo && echo 'line2'");
+                final List<String> lines = Lists.newCopyOnWriteArrayList();
+
+                StreamLogger logger = new StreamLogger(command.getInputStream(), LOG, MarkerFactory.getMarker("live")) {
+                    @Override
+                    protected void log(Logger logger, Marker marker, String line) {
+                        logger.info(marker, line);  /* just for visual inspection */
+                        lines.add(line);
+                    }
+                };
+                logger.start();
+
+                command.join();
+                logger.join();
+
+                assertThat(lines).hasSize(2).contains("line1", "line2");
+
+            } finally {
+                session.close();
+            }
+        } finally {
+            client.close();
+        }
+    }
+
+    @Test
+    public void testCreateFileOverSsh() throws IOException {
+        SSHClient client = Ssh.newClient(localhost, adminAccess, 1000);
+        try {
+            String destination = "/tmp/" + UUID.randomUUID().toString();
+            String content = UUID.randomUUID().toString();
+
+            Ssh.createFile(client, content, 0600, destination);
+
+            /* Check the file exists and has the expected content */
+            Session session = client.startSession();
+            try {
+                final Session.Command command = session.exec("set +x +e && cat " + destination);
+
+                String output = CharStreams.toString(new InputStreamReader(command.getInputStream()));
+                command.join();
+
+                assertThat(command.getExitStatus()).isEqualTo(0);
+                assertThat(output).contains(content);
+
+            } finally {
+                session.close();
+            }
+        } finally {
+            client.close();
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activiti/AlwaysFailTask.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activiti/AlwaysFailTask.java b/core/src/test/java/org/apache/provisionr/core/activiti/AlwaysFailTask.java
new file mode 100644
index 0000000..1cc2880
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activiti/AlwaysFailTask.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activiti;
+
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AlwaysFailTask implements JavaDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AlwaysFailTask.class);
+
+    public static final AtomicInteger COUNTER = new AtomicInteger(0);
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        COUNTER.incrementAndGet();
+        throw new RuntimeException("Failing. Time is " + new Date());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activiti/ConfigurableFailedJobCommandFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activiti/ConfigurableFailedJobCommandFactoryTest.java b/core/src/test/java/org/apache/provisionr/core/activiti/ConfigurableFailedJobCommandFactoryTest.java
new file mode 100644
index 0000000..8954222
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activiti/ConfigurableFailedJobCommandFactoryTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activiti;
+
+import com.google.common.base.Stopwatch;
+import java.util.concurrent.TimeUnit;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration;
+import org.activiti.engine.impl.jobexecutor.DefaultJobExecutor;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class ConfigurableFailedJobCommandFactoryTest {
+
+    @Test
+    public void testConfigurableNumberOfRetries() throws InterruptedException {
+        DefaultJobExecutor jobExecutor = new DefaultJobExecutor();
+
+        jobExecutor.setCorePoolSize(2);
+        jobExecutor.setQueueSize(2);
+        jobExecutor.setMaxJobsPerAcquisition(5);
+        jobExecutor.setWaitTimeInMillis(50);
+        jobExecutor.setLockTimeInMillis(180000);
+
+        ProcessEngine processEngine = new StandaloneInMemProcessEngineConfiguration()
+            .setJobExecutorActivate(true)
+            .setJobExecutor(jobExecutor)
+            .setFailedJobCommandFactory(new ConfigurableFailedJobCommandFactory(2, 1))
+            .buildProcessEngine();
+
+        processEngine.getRepositoryService().createDeployment()
+            .addClasspathResource("diagrams/alwaysFail.bpmn20.xml").deploy();
+
+        Stopwatch stopwatch = new Stopwatch().start();
+        processEngine.getRuntimeService().startProcessInstanceByKey("alwaysFail");
+
+        while (AlwaysFailTask.COUNTER.get() != 3 /* = 1 normal execution + 2 retries */) {
+            TimeUnit.MILLISECONDS.sleep(100);
+        }
+
+        stopwatch.stop();
+        assertThat(stopwatch.elapsedTime(TimeUnit.SECONDS)).isGreaterThanOrEqualTo(2);
+
+        processEngine.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activities/CheckProcessesEndedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activities/CheckProcessesEndedTest.java b/core/src/test/java/org/apache/provisionr/core/activities/CheckProcessesEndedTest.java
new file mode 100644
index 0000000..f12f270
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activities/CheckProcessesEndedTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class CheckProcessesEndedTest extends CheckProcessesTest {
+
+    private static final String PROCESS_IDS = "process_ids";
+
+    private static final String RESULT = "result";
+
+    @Test
+    public void testWithAListOfEndedProcesses() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        when(execution.getVariable(eq(PROCESS_IDS))).thenReturn(Lists.newArrayList("1", "2"));
+
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        RuntimeService runtimeService = mockRuntimeService(ImmutableMap.of(
+            "1", mockProcessInstance(/* ended= */ true),
+            "2", mockProcessInstance(/* ended= */ true)
+        ));
+
+        JavaDelegate delegate = new CheckProcessesEnded(runtimeService, PROCESS_IDS, RESULT);
+        delegate.execute(execution);
+
+        assertThat((Boolean) collector.getVariable(RESULT)).isTrue();
+    }
+
+    @Test
+    public void testWithOneEndedAndOneStillRunning() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        when(execution.getVariable(eq(PROCESS_IDS))).thenReturn(Lists.newArrayList("1", "2"));
+
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        RuntimeService runtimeService = mockRuntimeService(ImmutableMap.of(
+            "1", mockProcessInstance(/* ended= */ true),
+            "2", mockProcessInstance(/* ended= */ false)
+        ));
+
+        JavaDelegate delegate = new CheckProcessesEnded(runtimeService, PROCESS_IDS, RESULT);
+        delegate.execute(execution);
+
+        assertThat((Boolean) collector.getVariable(RESULT)).isFalse();
+    }
+
+    /**
+     * We consider an invalid process instance ID as ended by default
+     */
+    @Test
+    public void testWithOneInvalidProcessId() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        when(execution.getVariable(eq(PROCESS_IDS))).thenReturn(Lists.newArrayList("1", "invalid"));
+
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        RuntimeService runtimeService = mockRuntimeService(ImmutableMap.of(
+            "1", mockProcessInstance(/* ended= */ true)), "invalid");
+
+        JavaDelegate delegate = new CheckProcessesEnded(runtimeService, PROCESS_IDS, RESULT);
+        delegate.execute(execution);
+
+        assertThat((Boolean) collector.getVariable(RESULT)).isTrue();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activities/CheckProcessesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activities/CheckProcessesTest.java b/core/src/test/java/org/apache/provisionr/core/activities/CheckProcessesTest.java
new file mode 100644
index 0000000..09e9185
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activities/CheckProcessesTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.runtime.ProcessInstanceQuery;
+
+public abstract class CheckProcessesTest {
+
+    protected RuntimeService mockRuntimeService(Map<String, ProcessInstance> instances, 
+                                              String... notFoundProcessInstanceIds) {
+        RuntimeService runtimeService = mock(RuntimeService.class);
+
+        ProcessInstanceQuery generalQuery = mock(ProcessInstanceQuery.class);
+        for (Map.Entry<String, ProcessInstance> entry : instances.entrySet()) {
+            ProcessInstanceQuery specificQuery = mock(ProcessInstanceQuery.class);
+            when(specificQuery.singleResult()).thenReturn(entry.getValue());
+
+            when(generalQuery.processInstanceId(eq(entry.getKey()))).thenReturn(specificQuery);
+        }
+        for (String notFound : notFoundProcessInstanceIds) {
+            /* create a mock that returns null for all method calls (default) */
+            when(generalQuery.processInstanceId(eq(notFound))).thenReturn(mock(ProcessInstanceQuery.class));
+        }
+        when(runtimeService.createProcessInstanceQuery()).thenReturn(generalQuery);
+
+        return runtimeService;
+    }
+
+    protected ProcessInstance mockProcessInstance(boolean ended) {
+        ProcessInstance processInstance = mock(ProcessInstance.class);
+        when(processInstance.isEnded()).thenReturn(ended);
+        return processInstance;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activities/DownloadFilesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activities/DownloadFilesTest.java b/core/src/test/java/org/apache/provisionr/core/activities/DownloadFilesTest.java
new file mode 100644
index 0000000..d8db56b
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activities/DownloadFilesTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Software;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DownloadFilesTest {
+
+    @Test
+    public void testCreatePuppetScript() throws Exception {
+        Software software = Software.builder()
+            .file("http://provisionr.incubator.apache.org/test.tar.gz", "/opt/test.tar.gz")
+            .file("http://google.com", "/opt/google.html")
+            .createSoftware();
+
+        Pool pool = mock(Pool.class);
+        when(pool.getSoftware()).thenReturn(software);
+
+        PuppetActivity activity = new DownloadFiles();
+        String content = activity.createPuppetScript(pool, null);
+
+        assertThat(content)
+            .contains("download_file {\"/opt/test.tar.gz\":\n" +
+                "  uri => \"http://provisionr.incubator.apache.org/test.tar.gz\"\n" +
+                "}")
+            .contains("download_file {\"/opt/google.html\":\n" +
+                "  uri => \"http://google.com\"\n" +
+                "}");
+
+        assertThat(activity.createAdditionalFiles(pool, null)).isEmpty();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activities/InstallPackagesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activities/InstallPackagesTest.java b/core/src/test/java/org/apache/provisionr/core/activities/InstallPackagesTest.java
new file mode 100644
index 0000000..2ec7eb6
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activities/InstallPackagesTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.activities.InstallPackages;
+import org.apache.provisionr.core.activities.PuppetActivity;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class InstallPackagesTest {
+
+    @Test
+    public void testCreatePuppetScript() throws Exception {
+        Pool pool = mock(Pool.class);
+        when(pool.getSoftware()).thenReturn(Software.builder()
+            .packages("git-core", "vim").createSoftware());
+
+        PuppetActivity activity = new InstallPackages();
+        String content = activity.createPuppetScript(pool, null);
+
+        assertThat(content).contains(
+            "Package { ensure => \"installed\" }\n" +
+                "\n" +
+                "package { \"git-core\": }\n" +
+                "package { \"vim\": }\n"
+        );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activities/InstallRepositoriesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activities/InstallRepositoriesTest.java b/core/src/test/java/org/apache/provisionr/core/activities/InstallRepositoriesTest.java
new file mode 100644
index 0000000..1f2ee5c
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activities/InstallRepositoriesTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Repository;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.activities.InstallRepositories;
+import org.apache.provisionr.core.activities.PuppetActivity;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class InstallRepositoriesTest {
+
+    @Test
+    public void testCreatePuppetScript() throws Exception {
+        Repository repository = Repository.builder()
+            .name("bigtop")
+            .addEntry("deb http://bigtop.s3.amazonaws.com/releases/0.5.0/ubuntu/lucid/x86_64  bigtop contrib")
+            .key("-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
+                "Version: GnuPG v1.4.10 (GNU/Linux)\n" +
+                "\n" +
+                "[....]")
+            .createRepository();
+
+        Pool pool = mock(Pool.class);
+        when(pool.getSoftware()).thenReturn(Software.builder().repository(repository).createSoftware());
+
+        PuppetActivity activity = new InstallRepositories();
+        String content = activity.createPuppetScript(pool, null);
+
+        assertThat(content).contains("apt::repository { \"bigtop\":\n" +
+            "  content => \"deb http://bigtop.s3.amazonaws.com/releases/0.5.0/ubuntu/lucid/x86_64  bigtop contrib\\n\",\n" +
+            "  key => \"-----BEGIN PGP PUBLIC KEY BLOCK-----\\nVersion: GnuPG v1.4.10 (GNU/Linux)\\n\\n[....]\"\n" +
+            "}");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activities/IsMachinePortOpenTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activities/IsMachinePortOpenTest.java b/core/src/test/java/org/apache/provisionr/core/activities/IsMachinePortOpenTest.java
new file mode 100644
index 0000000..0c7364f
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activities/IsMachinePortOpenTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import java.io.IOException;
+import java.net.ServerSocket;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class IsMachinePortOpenTest {
+
+    private static final String RESULT = "result";
+
+    @Test
+    public void testWithRandomOpenPort() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+
+        when(execution.getVariable(eq(IsMachinePortOpen.MACHINE)))
+            .thenReturn(Machine.builder().localhost().createMachine());
+
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        ServerSocket socket = null;
+        try {
+            socket = new ServerSocket(0);
+
+            JavaDelegate delegate = new IsMachinePortOpen(RESULT, socket.getLocalPort());
+            delegate.execute(execution);
+
+            assertThat((Boolean) collector.getVariable(RESULT)).isTrue();
+
+        } finally {
+            if (socket != null) {
+                socket.close();
+            }
+        }
+    }
+
+    @Test
+    public void testWithRandomClosedPort() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+
+        when(execution.getVariable(eq(IsMachinePortOpen.MACHINE)))
+            .thenReturn(Machine.builder().localhost().createMachine());
+
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        JavaDelegate delegate = new IsMachinePortOpen(RESULT, findRandomNotUsedPort());
+        delegate.execute(execution);
+
+        assertThat((Boolean) collector.getVariable(RESULT)).isFalse();
+    }
+
+    private int findRandomNotUsedPort() throws IOException {
+        ServerSocket socket = null;
+        try {
+            socket = new ServerSocket(0);
+            return socket.getLocalPort();
+        } finally {
+            if (socket != null) {
+                socket.close();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activities/KillMachineSetUpProcessesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activities/KillMachineSetUpProcessesTest.java b/core/src/test/java/org/apache/provisionr/core/activities/KillMachineSetUpProcessesTest.java
new file mode 100644
index 0000000..a6be2ec
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activities/KillMachineSetUpProcessesTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.Map;
+
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.junit.Test;
+
+public class KillMachineSetUpProcessesTest extends CheckProcessesTest {
+
+    private static final String PROCESS_IDS = "process_ids";
+
+    @Test
+    public void testWithAListOfEndedProcesses() throws Exception {
+        RuntimeService runtimeService = runTest(Lists.newArrayList("1", "2"), ImmutableMap.of(
+            "1", mockProcessInstance(/* ended= */ true),
+            "2", mockProcessInstance(/* ended= */ true)
+        ));
+        verify(runtimeService, never()).deleteProcessInstance(anyString(), anyString());
+    }
+
+    @Test
+    public void testWithAListOfActiveProcesses() throws Exception {
+        RuntimeService runtimeService = runTest(Lists.newArrayList("1", "2"), ImmutableMap.of(
+            "1", mockProcessInstance(/* ended= */ false),
+            "2", mockProcessInstance(/* ended= */ false)
+        ));
+        verify(runtimeService, times(2)).deleteProcessInstance(anyString(), anyString());
+    }
+
+    @Test
+    public void testWithAListOfActiveAndInactiveProcesses() throws Exception {
+        RuntimeService runtimeService = runTest(Lists.newArrayList("1", "2"), ImmutableMap.of(
+            "1", mockProcessInstance(/* ended= */ true),
+            "2", mockProcessInstance(/* ended= */ false)
+        ));
+
+        verify(runtimeService, times(1)).deleteProcessInstance(anyString(), anyString());
+    }
+
+    @Test
+    public void testWithAListOfActiveAndInvalidProcesses() throws Exception {
+        RuntimeService runtimeService = runTest(Lists.newArrayList("1", "invalid"), ImmutableMap.of(
+            "1", mockProcessInstance(/* ended= */ false)));
+        verify(runtimeService, times(1)).deleteProcessInstance(anyString(), anyString());
+    }
+
+    private RuntimeService runTest(List<String> processIds, Map<String, ProcessInstance> processMap) throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        when(execution.getVariable(eq(PROCESS_IDS))).thenReturn(processIds);
+
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        RuntimeService runtimeService = mockRuntimeService(processMap, "invalid");
+
+        JavaDelegate delegate = new KillMachineSetUpProcesses(runtimeService, PROCESS_IDS);
+        delegate.execute(execution);
+
+        return runtimeService;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/activities/SpawnProcessForEachMachineTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/activities/SpawnProcessForEachMachineTest.java b/core/src/test/java/org/apache/provisionr/core/activities/SpawnProcessForEachMachineTest.java
new file mode 100644
index 0000000..544bb0c
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/activities/SpawnProcessForEachMachineTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.activities;
+
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration;
+import org.junit.Test;
+
+public class SpawnProcessForEachMachineTest {
+
+    private static final String EMPTY_PROCESS_KEY = "empty";
+    private static final String RESULT = "result";
+
+    private static final String BUSINESS_KEY = UUID.randomUUID().toString();
+
+    @Test
+    public void testSpawnSampleProcessForLocalhost() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class, withSettings().serializable());
+        Software software = mock(Software.class, withSettings().serializable());
+        when(software.isCachedImage()).thenReturn(false);
+        when(pool.getSoftware()).thenReturn(software);
+        when(execution.getVariable(eq(CoreProcessVariables.POOL))).thenReturn(pool);
+        when(execution.getVariable(eq(CoreProcessVariables.POOL_BUSINESS_KEY))).thenReturn(BUSINESS_KEY);
+
+        List<Machine> machines = Lists.newArrayList(
+            Machine.builder().localhost().createMachine(),
+            Machine.builder().localhost().externalId("local-2").createMachine()
+        );
+        when(execution.getVariable(eq(CoreProcessVariables.MACHINES))).thenReturn(machines);
+
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        ProcessEngine processEngine = new StandaloneInMemProcessEngineConfiguration()
+            .setJobExecutorActivate(true).buildProcessEngine();
+        processEngine.getRepositoryService().createDeployment()
+            .addClasspathResource("diagrams/empty.bpmn20.xml").deploy();
+
+        try {
+            JavaDelegate delegate = new SpawnProcessForEachMachine(processEngine, EMPTY_PROCESS_KEY, "test", RESULT);
+            delegate.execute(execution);
+
+            @SuppressWarnings("unchecked")
+            List<String> processInstanceIds = (List<String>) collector.getVariable(RESULT);
+
+            assertThat(processInstanceIds).hasSize(2);
+
+        } finally {
+            processEngine.close();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/logging/StreamLoggerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/logging/StreamLoggerTest.java b/core/src/test/java/org/apache/provisionr/core/logging/StreamLoggerTest.java
new file mode 100644
index 0000000..c528afd
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/logging/StreamLoggerTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.logging;
+
+import org.apache.provisionr.core.Ssh;
+import com.google.common.base.Charsets;
+import com.google.common.collect.Lists;
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import org.apache.provisionr.core.logging.StreamLogger;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+public class StreamLoggerTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(Ssh.class);
+
+    @Test
+    public void testStreamLogger() throws InterruptedException {
+        final List<String> lines = Lists.newCopyOnWriteArrayList();
+
+        final byte[] bytes = "line1\nline2\nline3".getBytes(Charsets.UTF_8);
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+
+        final StreamLogger logger = new StreamLogger(inputStream, LOG, MarkerFactory.getMarker("test")) {
+            @Override
+            protected void log(Logger logger, Marker marker, String line) {
+                logger.info(marker, line);  /* just for visual inspection */
+                lines.add(line);
+            }
+        };
+        logger.start();
+
+        logger.join();
+        assertThat(lines).contains("line1", "line2", "line3");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/templates/PoolTemplateInstallerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/templates/PoolTemplateInstallerTest.java b/core/src/test/java/org/apache/provisionr/core/templates/PoolTemplateInstallerTest.java
new file mode 100644
index 0000000..8d89caa
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/templates/PoolTemplateInstallerTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.templates;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Dictionary;
+import org.apache.ibatis.io.Resources;
+import org.apache.provisionr.core.templates.PoolTemplate;
+import org.apache.provisionr.core.templates.PoolTemplateInstaller;
+import org.junit.Test;
+import org.mockito.Matchers;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class PoolTemplateInstallerTest {
+
+    @Test
+    public void testInstallAndUninstallTemplate() throws Exception {
+        BundleContext bundleContext = mock(BundleContext.class);
+
+        ServiceRegistration registration = mock(ServiceRegistration.class);
+        when(bundleContext.registerService(eq(PoolTemplate.class.getName()), any(),
+            Matchers.<Dictionary<String, ?>>any())).thenReturn(registration);
+
+        File file = getPathToCdh3Template();
+        PoolTemplateInstaller installer = new PoolTemplateInstaller(bundleContext);
+
+        installer.install(file);
+        verify(bundleContext).registerService(eq(PoolTemplate.class.getName()),
+            any(), (Dictionary<String, ?>) isNull());
+        verifyZeroInteractions(registration);
+
+        installer.uninstall(file);
+        verify(registration).unregister();
+    }
+
+    private File getPathToCdh3Template() throws URISyntaxException, IOException {
+        return new File(Resources.getResourceURL("org/apache/provisionr/core/templates/cdh3.xml").toURI());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/org/apache/provisionr/core/templates/xml/XmlTemplateTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/provisionr/core/templates/xml/XmlTemplateTest.java b/core/src/test/java/org/apache/provisionr/core/templates/xml/XmlTemplateTest.java
new file mode 100644
index 0000000..53b5037
--- /dev/null
+++ b/core/src/test/java/org/apache/provisionr/core/templates/xml/XmlTemplateTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.templates.xml;
+
+import com.google.common.base.Charsets;
+import static com.google.common.collect.Lists.newArrayList;
+import com.google.common.io.Resources;
+import java.io.IOException;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.BaseJaxbTest;
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class XmlTemplateTest extends BaseJaxbTest {
+
+    public static final String DEFAULT_JENKINS_TEMPLATE = "org/apache/provisionr/core/templates/jenkins.xml";
+
+    public static final String DEFAULT_CDH3_TEMPLATE = "org/apache/provisionr/core/templates/cdh3.xml";
+
+    @Test
+    public void testLoadDefaultCdh3Template() throws Exception {
+        XmlTemplate template = XmlTemplate.newXmlTemplate(readResource(DEFAULT_CDH3_TEMPLATE));
+
+        assertThat(template.getId()).isEqualTo("cdh3");
+        assertThat(template.getPackages()).contains("hue");
+        assertThat(template.getOsVersion()).isEqualTo("10.04 LTS");
+
+        assertThat(template.getRepositories()).hasSize(2);
+        assertThat(template.getFiles()).hasSize(1);
+    }
+
+    @Test
+    public void testApplyCdh3TemplateToNetworkAndSoftware() throws Exception {
+        XmlTemplate template = XmlTemplate.newXmlTemplate(readResource(DEFAULT_CDH3_TEMPLATE));
+
+        Network network = template.apply(Network.builder().createNetwork());
+        assertThat(network.getIngress()).contains(
+            Rule.builder().anySource().tcp().port(8080).createRule());
+
+
+        Software software = template.apply(Software.builder().createSoftware());
+        assertThat(software.getPackages()).contains("hue").contains("hadoop-0.20");
+
+        assertThat(software.getFiles()).hasSize(1);
+        assertThat(software.getRepositories()).hasSize(2);
+    }
+
+    @Test
+    public void testLoadDefaultJenkinsTemplate() throws Exception {
+        XmlTemplate template = XmlTemplate.newXmlTemplate(readResource(DEFAULT_JENKINS_TEMPLATE));
+
+        assertThat(template.getPorts()).contains(8080);
+        assertThat(template.getRepositories()).hasSize(1);
+
+        assertThat(template.getPackages()).contains("jenkins").contains("git-core");
+    }
+
+    @Test
+    public void testSerializeBasicTemplateAsXml() throws Exception {
+        XmlTemplate template = new XmlTemplate();
+        template.setId("jenkins");
+
+        template.setDescription("Just testing");
+        template.setOsVersion("10.04 LTS");
+
+        template.setPackages(newArrayList("jenkins", "git-core", "subversion"));
+        template.setPorts(newArrayList(8080, 22));
+
+        template.setFiles(newArrayList(
+            new FileEntry("http://google.com", "/opt/google.html")
+        ));
+
+        template.setRepositories(newArrayList(
+            new RepositoryEntry("jenkins", newArrayList("deb ..."), "-----BEGIN PGP PUBLIC KEY BLOCK----- ...")
+        ));
+
+        String actual = asXml(template);
+        assertXMLEqual(actual, readResource("templates/test.xml"), actual);
+    }
+
+    private String readResource(String resource) throws IOException {
+        return Resources.toString(Resources.getResource(resource), Charsets.UTF_8);
+    }
+
+    @Override
+    public Class[] getContextClasses() {
+        return new Class[]{XmlTemplate.class};
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/resources/diagrams/alwaysFail.bpmn20.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/diagrams/alwaysFail.bpmn20.xml b/core/src/test/resources/diagrams/alwaysFail.bpmn20.xml
index 77e61c5..8ebdf49 100644
--- a/core/src/test/resources/diagrams/alwaysFail.bpmn20.xml
+++ b/core/src/test/resources/diagrams/alwaysFail.bpmn20.xml
@@ -7,7 +7,7 @@
         <startEvent id="startevent1" name="Start"></startEvent>
         <endEvent id="endevent1" name="End"></endEvent>
         <serviceTask id="alwaysFailTask" name="Always Fail" activiti:async="true"
-                     activiti:class="com.axemblr.provisionr.core.activiti.AlwaysFailTask"></serviceTask>
+                     activiti:class="org.apache.provisionr.core.activiti.AlwaysFailTask"></serviceTask>
         <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="alwaysFailTask"></sequenceFlow>
         <sequenceFlow id="flow2" sourceRef="alwaysFailTask" targetRef="endevent1"></sequenceFlow>
     </process>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/docs/Creating Pools of Virtual Machines - ApacheCon NA 2013.pdf
----------------------------------------------------------------------
diff --git a/docs/Creating Pools of Virtual Machines - ApacheCon NA 2013.pdf b/docs/Creating Pools of Virtual Machines - ApacheCon NA 2013.pdf
deleted file mode 100644
index 789f00e..0000000
Binary files a/docs/Creating Pools of Virtual Machines - ApacheCon NA 2013.pdf and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/docs/icla.pdf
----------------------------------------------------------------------
diff --git a/docs/icla.pdf b/docs/icla.pdf
deleted file mode 100644
index 865ca56..0000000
Binary files a/docs/icla.pdf and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/pom.xml
----------------------------------------------------------------------
diff --git a/integration/rundeck/pom.xml b/integration/rundeck/pom.xml
index 4b141b4..a1031c6 100644
--- a/integration/rundeck/pom.xml
+++ b/integration/rundeck/pom.xml
@@ -17,13 +17,13 @@
 <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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Rundeck</name>
+    <name>Apache Provisionr :: Rundeck</name>
     <description>Integration with Rundeck (http://rundeck.org/). Provides a Resource Model endpoint</description>
 
     <artifactId>provisionr-rundeck</artifactId>
@@ -31,7 +31,7 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-core</artifactId>
         </dependency>
         <dependency>
@@ -121,7 +121,7 @@
                                 <descriptor>file:${project.build.directory}/classes/features.xml</descriptor>
                             </descriptors>
                             <features>
-                                <feature>axemblr-provisionr-core</feature>
+                                <feature>provisionr-core</feature>
                             </features>
                             <repository>target/features-repo</repository>
                         </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Attribute.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Attribute.java b/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Attribute.java
deleted file mode 100644
index 5419bdb..0000000
--- a/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Attribute.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.rundeck;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import javax.xml.bind.annotation.XmlAttribute;
-
-/**
- * An attribute allows you to add user-defined metadata
- *
- * @see <a href="http://rundeck.org/docs/manpages/man5/resource-v13.html#attribute" />
- */
-public class Attribute {
-
-    private String name;
-
-    private String value;
-
-    public Attribute() {
-    }
-
-    public Attribute(String name, String value) {
-        this.name = checkNotNull(name, "name is null");
-        this.value = checkNotNull(value, "value is null");
-    }
-
-    @XmlAttribute(name = "name")
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = checkNotNull(name, "name is null");
-    }
-
-    @XmlAttribute(name = "value")
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = checkNotNull(value, "value is null");
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        Attribute attribute = (Attribute) o;
-
-        if (name != null ? !name.equals(attribute.name) : attribute.name != null) return false;
-        if (value != null ? !value.equals(attribute.value) : attribute.value != null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = name != null ? name.hashCode() : 0;
-        result = 31 * result + (value != null ? value.hashCode() : 0);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "Attribute{" +
-            "name='" + name + '\'' +
-            ", value='" + value + '\'' +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Node.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Node.java b/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Node.java
deleted file mode 100644
index 7bcf319..0000000
--- a/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Node.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.rundeck;
-
-import com.google.common.base.Joiner;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Lists;
-import java.util.List;
-import java.util.Map;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-
-/**
- * A Rundeck Resource Model is nothing more than just a list of nodes
- * with a predefined set of properties and an optional list of user defined attributes
- *
- * @see <a href="http://rundeck.org/docs/manpages/man5/resource-v13.html#node" />
- */
-public class Node {
-
-    /**
-     * The node name. This is a logical identifier from the node. (required)
-     */
-    private String name;
-
-    /**
-     * The hostname or IP address of the remote host. (required)
-     */
-    private String hostname;
-
-    /**
-     * Comma separated list of filtering tags. (optional)
-     */
-    private String tags;
-
-    /**
-     * The username used for the remote connection. (required)
-     */
-    private String username;
-
-    /**
-     * User defined attributes
-     */
-    private List<Attribute> attributes;
-
-    public Node() {
-    }
-
-    public Node(String name, String hostname, String username) {
-        this.name = checkNotNull(name, "name is null");
-        this.hostname = checkNotNull(hostname, "hostname is null");
-        this.username = checkNotNull(username, "username is null");
-    }
-
-    @XmlAttribute
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = checkNotNull(name, "name is null");
-    }
-
-    @XmlAttribute
-    public String getHostname() {
-        return hostname;
-    }
-
-    public void setHostname(String hostname) {
-        this.hostname = checkNotNull(hostname, "hostname is null");
-    }
-
-    @XmlAttribute
-    public String getTags() {
-        return tags;
-    }
-
-    public void setTags(String tags) {
-        this.tags = checkNotNull(tags, "tags is null");
-    }
-
-    public void setTags(Iterable<String> tags) {
-        setTags(Joiner.on(",").join(tags));
-    }
-
-    public void setTags(String[] tags) {
-        setTags(Joiner.on(",").join(tags));
-    }
-
-    @XmlAttribute
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = checkNotNull(username, "username is null");
-    }
-
-    @XmlElement(name = "attribute")
-    public List<Attribute> getAttributes() {
-        return attributes;
-    }
-
-    public void setAttributes(List<Attribute> attributes) {
-        this.attributes = checkNotNull(attributes, "attributes is null");
-    }
-
-    public void setAttributes(Map<String, String> values) {
-        this.attributes = Lists.newArrayList();
-        for (Map.Entry<String, String> entry : values.entrySet()) {
-            this.attributes.add(new Attribute(entry.getKey(), entry.getValue()));
-        }
-    }
-
-    public void addAttribute(String name, String value) {
-        this.attributes.add(new Attribute(name, value));
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        Node node = (Node) o;
-
-        if (attributes != null ? !attributes.equals(node.attributes) : node.attributes != null) return false;
-        if (hostname != null ? !hostname.equals(node.hostname) : node.hostname != null) return false;
-        if (name != null ? !name.equals(node.name) : node.name != null) return false;
-        if (tags != null ? !tags.equals(node.tags) : node.tags != null) return false;
-        if (username != null ? !username.equals(node.username) : node.username != null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = name != null ? name.hashCode() : 0;
-        result = 31 * result + (hostname != null ? hostname.hashCode() : 0);
-        result = 31 * result + (tags != null ? tags.hashCode() : 0);
-        result = 31 * result + (username != null ? username.hashCode() : 0);
-        result = 31 * result + (attributes != null ? attributes.hashCode() : 0);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "Node{" +
-            "name='" + name + '\'' +
-            ", hostname='" + hostname + '\'' +
-            ", tags='" + tags + '\'' +
-            ", username='" + username + '\'' +
-            ", attributes=" + attributes +
-            '}';
-    }
-}


[02/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/CloudStackActivityLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/CloudStackActivityLiveTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/CloudStackActivityLiveTest.java
new file mode 100644
index 0000000..2cd33d2
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/CloudStackActivityLiveTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.cloudstack.CloudStackProvisionr;
+import org.apache.provisionr.cloudstack.ProviderOptions;
+import org.apache.provisionr.cloudstack.core.SecurityGroups;
+import org.apache.provisionr.test.Generics;
+import org.apache.provisionr.test.ProvisionrLiveTestSupport;
+import com.google.common.base.Throwables;
+import java.util.Set;
+import java.util.UUID;
+import org.jclouds.cloudstack.CloudStackAsyncClient;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.Network;
+import org.jclouds.cloudstack.domain.SecurityGroup;
+import org.jclouds.cloudstack.domain.SshKeyPair;
+import org.jclouds.cloudstack.domain.VirtualMachine;
+import org.jclouds.rest.RestContext;
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper base class for CloudStack Live tests.
+ */
+public class CloudStackActivityLiveTest<T extends CloudStackActivity> extends ProvisionrLiveTestSupport {
+
+    public CloudStackActivityLiveTest() {
+        super(CloudStackProvisionr.ID);
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(CloudStackActivityLiveTest.class);
+
+    protected final String BUSINESS_KEY = "j-" + UUID.randomUUID().toString();
+    /**
+     * Cloud provider credentials collected from system properties.
+     */
+    protected Provider provider;
+    /**
+     * Instance of CloudStackActivity being tested. Automatically created from the
+     * generic type class argument.
+     */
+    protected CloudStackActivity activity;
+
+    protected RestContext<CloudStackClient, CloudStackAsyncClient> context;
+
+    public CloudStackActivityLiveTest(String provisionrId) {
+        super(provisionrId);
+    }
+
+    protected T createCloudStackActivitiInstance() {
+        try {
+            return getCloudStackActivityClass().newInstance();
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    protected Class<T> getCloudStackActivityClass() {
+        return Generics.getTypeParameter(getClass(), CloudStackActivity.class);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        provider = collectProviderCredentialsFromSystemProperties()
+            .option(ProviderOptions.ZONE_ID, getProviderProperty(ProviderOptions.ZONE_ID))
+            .option(ProviderOptions.NETWORK_OFFERING_ID, getProviderProperty(ProviderOptions.NETWORK_OFFERING_ID))
+            .createProvider();
+        LOG.info("Using provider {}", provider);
+
+        activity = createCloudStackActivitiInstance();
+        context = activity.newCloudStackClient(provider);
+    }
+
+
+    @After
+    public void tearDown() throws Exception {
+        context.close();
+    }
+
+    protected void logSecurityGroupDetails() {
+        Set<SecurityGroup> securityGroups = SecurityGroups.getAll(context.getApi());
+        LOG.info("Security Group count is {}", securityGroups.size());
+        for (SecurityGroup securityGroup : securityGroups) {
+            LOG.info("\tSecurity Group {}", securityGroup.getName());
+        }
+    }
+
+    protected void logKeyPairs() {
+        Set<SshKeyPair> keys = context.getApi().getSSHKeyPairClient().listSSHKeyPairs();
+        LOG.info("Access Key count is {}", keys.size());
+        for (SshKeyPair keyPair : keys) {
+            LOG.info("\tKey {}", keyPair.getName());
+        }
+    }
+
+    protected void logVirtualMachines() {
+        Set<VirtualMachine> vms = context.getApi().getVirtualMachineClient().listVirtualMachines();
+        LOG.info("Virtual machines count is {}", vms.size());
+        for (VirtualMachine vm : vms) {
+            LOG.info("\tVirtual machine {}", vm.toString());
+        }
+    }
+
+    protected void logNetworks() {
+        Set<Network> networks = context.getApi().getNetworkClient().listNetworks();
+        LOG.info("Networks count is {}", networks.size());
+        for (Network network : networks) {
+            LOG.info("{}\n", network.toString());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/DeleteKeyPairLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/DeleteKeyPairLiveTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/DeleteKeyPairLiveTest.java
new file mode 100644
index 0000000..70604f0
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/DeleteKeyPairLiveTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.core.KeyPairs;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DeleteKeyPairLiveTest extends CloudStackActivityLiveTest<DeleteKeyPair> {
+
+    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        logKeyPairs();
+        context.getApi().getSSHKeyPairClient().registerSSHKeyPair(KEYPAIR_NAME, getResourceAsString("keys/test.pub"));
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+        context.getApi().getSSHKeyPairClient().deleteSSHKeyPair(KEYPAIR_NAME);
+        logKeyPairs();
+        super.tearDown();
+    }
+
+    @Test
+    public void testDeleteKeyPair() throws Exception {
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .username("admin")
+            .publicKey(getResourceAsString("keys/test.pub"))
+            .privateKey(getResourceAsString("keys/test"))
+            .createAdminAccess();
+
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+        when(pool.getProvider()).thenReturn(provider);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+
+        activity.execute(execution);
+        assertKeyNotFound(KEYPAIR_NAME);
+        /* the second call should just do nothing */
+        activity.execute(execution);
+    }
+
+    private void assertKeyNotFound(String keyName) {
+        assertThat(context.getApi().getSSHKeyPairClient().getSSHKeyPair(keyName)).isNull();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/DeleteSecurityGroupLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/DeleteSecurityGroupLiveTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/DeleteSecurityGroupLiveTest.java
new file mode 100644
index 0000000..7662abe
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/DeleteSecurityGroupLiveTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import java.util.NoSuchElementException;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.core.SecurityGroups;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.junit.After;
+import static org.junit.Assert.fail;
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeleteSecurityGroupLiveTest extends CloudStackActivityLiveTest<DeleteSecurityGroup> {
+
+    private final Logger LOG = LoggerFactory.getLogger(DeleteSecurityGroupLiveTest.class);
+    private final String SECURITY_GROUP_NAME = SecurityGroups.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        logSecurityGroupDetails();
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+        logSecurityGroupDetails();
+        super.tearDown();
+    }
+
+    @Test
+    public void testDeleteSecurityGroup() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        final Network network = Network.builder().createNetwork();
+
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getNetwork()).thenReturn(network);
+
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+
+        SecurityGroups.createSecurityGroup(context.getApi(), SECURITY_GROUP_NAME);
+
+        activity.execute(execution);
+
+        try {
+            SecurityGroups.getByName(context.getApi(), SECURITY_GROUP_NAME);
+            fail("Does not throw Exception as it should have");
+        } catch (NoSuchElementException e) {
+            LOG.info("Exception thrown. Test passed.");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureKeyPairExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureKeyPairExistsLiveTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureKeyPairExistsLiveTest.java
new file mode 100644
index 0000000..12fbb67
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureKeyPairExistsLiveTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import java.io.IOException;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.core.KeyPairs;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.jclouds.cloudstack.domain.SshKeyPair;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class EnsureKeyPairExistsLiveTest extends CloudStackActivityLiveTest<EnsureKeyPairExists> {
+
+    public static final String TEST_KEY_FINGERPRINT = "15:0b:a4:43:dd:58:19:9e:84:ca:db:31:a8:6b:b6:c3";
+    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        logKeyPairs();
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+        context.getApi().getSSHKeyPairClient().deleteSSHKeyPair(KEYPAIR_NAME);
+        logKeyPairs();
+        super.tearDown();
+    }
+
+    @Test
+    public void testEnsureKeyPairExists() throws Exception {
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .username("admin")
+            .publicKey(getResourceAsString("keys/test.pub"))
+            .privateKey(getResourceAsString("keys/test"))
+            .createAdminAccess();
+
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+
+        activity.execute(execution);
+        assertKeyPairWasImportedAsExpected();
+
+        /* the second call should just re-import the key */
+        activity.execute(execution);
+        assertKeyPairWasImportedAsExpected();
+    }
+
+    private void assertKeyPairWasImportedAsExpected() throws IOException {
+        SshKeyPair pair = context.getApi().getSSHKeyPairClient().getSSHKeyPair(KEYPAIR_NAME);
+        assertThat(pair.getFingerprint()).isEqualTo(TEST_KEY_FINGERPRINT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureNetworkExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureNetworkExistsLiveTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureNetworkExistsLiveTest.java
new file mode 100644
index 0000000..b9329e0
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureNetworkExistsLiveTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import java.util.NoSuchElementException;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.NetworkOptions;
+import org.apache.provisionr.cloudstack.ProcessVariables;
+import org.apache.provisionr.cloudstack.core.Networks;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.Network;
+import org.jclouds.cloudstack.features.NetworkClient;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnsureNetworkExistsLiveTest extends CloudStackActivityLiveTest<EnsureNetworkExists> {
+
+    private final static Logger LOG = LoggerFactory.getLogger(EnsureNetworkExistsLiveTest.class);
+    private final String networkName = Networks.formatNameFromBusinessKey(BUSINESS_KEY);
+    private DelegateExecution execution;
+    private Pool pool;
+    private ProcessVariablesCollector collector;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        logNetworks();
+        initMocks();
+    }
+
+    private void initMocks() {
+        execution = mock(DelegateExecution.class);
+        pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(pool.getNetwork()).thenReturn(org.apache.provisionr.api.network.Network.builder()
+            .type("provided")
+            .createNetwork());
+        collector = new ProcessVariablesCollector();
+        collector.install(execution);
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+        deleteNetworkIfExists();
+        logNetworks();
+        super.tearDown();
+    }
+
+    private void deleteNetworkIfExists() {
+        try {
+            Network network = Networks.getByName(context.getApi(), networkName);
+            // this will not wait for the network to be deleted. operation will fail if network is used.
+            context.getApi().getNetworkClient().deleteNetwork(network.getId());
+        } catch (NoSuchElementException e) {
+            LOG.info("Network {} does not exist", networkName);
+        }
+    }
+
+    @Test
+    public void testEnsureNetworkExistsByCreatingTheNetwork() throws Exception {
+        activity.execute(execution);
+
+        assertThat(collector.getVariable(ProcessVariables.NETWORK_ID)).isNotNull();
+
+        Network network = Networks.getByName(context.getApi(), networkName);
+        assertThat(network.getName()).isEqualToIgnoringCase(networkName);
+        String networkId = network.getId();
+        // second run should not create a new network
+        activity.execute(execution);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        network = Networks.getByName(context.getApi(), networkName);
+        assertThat(network.getId()).isEqualTo(networkId);
+    }
+
+    @Test
+    public void testEnsureNetworkExistsWithProvidedExistingNetwork() throws Exception {
+        final String networkId = "network-id-0123";
+        final CloudStackClient mockClient = mock(CloudStackClient.class);
+        final NetworkClient mockNetworkClient = mock(NetworkClient.class);
+        final Network mockNetwork = mock(Network.class);
+        final org.apache.provisionr.api.network.Network network = org.apache.provisionr.api.network.Network.builder()
+            .option(NetworkOptions.EXISTING_NETWORK_ID, networkId).createNetwork();
+
+        execution.setVariable(ProcessVariables.NETWORK_ID, networkId);
+
+        when(pool.getNetwork()).thenReturn(network);
+        when(mockClient.getNetworkClient()).thenReturn(mockNetworkClient);
+        when(mockNetworkClient.getNetwork(networkId)).thenReturn(mockNetwork);
+        when(mockNetwork.getId()).thenReturn(networkId);
+
+        activity.execute(mockClient, pool, execution);
+        assertThat(collector.getVariable(ProcessVariables.NETWORK_ID)).isEqualTo(networkId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureSecurityGroupExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureSecurityGroupExistsLiveTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureSecurityGroupExistsLiveTest.java
new file mode 100644
index 0000000..569b84a
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/EnsureSecurityGroupExistsLiveTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import java.util.NoSuchElementException;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.core.ConvertIngressRuleToRule;
+import org.apache.provisionr.cloudstack.core.SecurityGroups;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.jclouds.cloudstack.domain.SecurityGroup;
+import static org.jclouds.cloudstack.options.ListSecurityGroupsOptions.Builder.named;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnsureSecurityGroupExistsLiveTest extends CloudStackActivityLiveTest<EnsureSecurityGroupExists> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EnsureSecurityGroupExistsLiveTest.class);
+
+    private final String SECURITY_GROUP_NAME = "network-" + BUSINESS_KEY;
+
+    private final ImmutableSet<Rule> ingressRules = ImmutableSet.of(
+        Rule.builder().anySource().icmp().createRule(),
+        Rule.builder().anySource().tcp().port(22).createRule(),
+        Rule.builder().anySource().udp().port(53).createRule());
+
+    private final Network network = Network.builder().ingress(ingressRules).createNetwork();
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        logSecurityGroupDetails();
+        deleteSecurityGroupIfExists();
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+        deleteSecurityGroupIfExists();
+        logSecurityGroupDetails();
+        super.tearDown();
+    }
+
+    private void deleteSecurityGroupIfExists() {
+        try {
+            SecurityGroup securityGroup = Iterables.getOnlyElement(context.getApi()
+                .getSecurityGroupClient()
+                .listSecurityGroups(named(SECURITY_GROUP_NAME)));
+
+            context.getApi().getSecurityGroupClient().deleteSecurityGroup(securityGroup.getId());
+        } catch (NoSuchElementException e) {
+            LOG.info("Security group {} was not found", SECURITY_GROUP_NAME);
+        } catch (Exception e2) {
+            LOG.error("Exception deleting security group {}", e2);
+        }
+    }
+
+    @Test
+    public void testCreateSecurityGroup() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getNetwork()).thenReturn(network);
+
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+
+        activity.execute(execution);
+        assertSecurityGroupExistsWithRules(SecurityGroups.getByName(
+            context.getApi(), SECURITY_GROUP_NAME), ingressRules);
+    }
+
+    @Test
+    public void testCreateSecurityGroupWithExistingSecurityGroup() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+
+        // create the SecurityGroup with an extra Network Rule, then call the activity
+        when(pool.getNetwork()).thenReturn(network.toBuilder().addRules(
+            Rule.builder().anySource().tcp().port(80).createRule()).createNetwork());
+
+        activity.execute(execution);
+        // call the process again with the old network rules and check the rules
+        when(pool.getNetwork()).thenReturn(network);
+
+        activity.execute(execution);
+
+        assertSecurityGroupExistsWithRules(SecurityGroups.getByName(context.getApi(),
+            SECURITY_GROUP_NAME), ingressRules);
+    }
+
+    private void assertSecurityGroupExistsWithRules(SecurityGroup securityGroup, ImmutableSet<Rule> ingressRules) {
+        assertThat(ingressRules).containsAll(Iterables.transform(securityGroup.getIngressRules(),
+            ConvertIngressRuleToRule.FUNCTION));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/RunInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/RunInstancesLiveTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/RunInstancesLiveTest.java
new file mode 100644
index 0000000..514a038
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/activities/RunInstancesLiveTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.cloudstack.ProviderOptions;
+import org.apache.provisionr.cloudstack.core.VirtualMachines;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RunInstancesLiveTest extends CloudStackActivityLiveTest<RunInstances> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RunInstancesLiveTest.class);
+
+    private DelegateExecution execution;
+    private Pool pool;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        logSecurityGroupDetails();
+        logKeyPairs();
+        logVirtualMachines();
+        execution = mock(DelegateExecution.class);
+        pool = mock(Pool.class);
+
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .username("admin")
+            .publicKey(getResourceAsString("keys/test.pub"))
+            .privateKey(getResourceAsString("keys/test"))
+            .createAdminAccess();
+
+        final Network network = Network.builder().addRules(
+            Rule.builder().anySource().tcp().port(22).createRule()).createNetwork();
+
+        final Hardware hardware = Hardware.builder().type(getProviderProperty("serviceOffering")).createHardware();
+        final Software software = Software.builder()
+            .imageId(getProviderProperty("templateId"))
+            .createSoftware();
+
+        Map<String, String> options = ImmutableMap.of(ProviderOptions.ZONE_ID,
+            getProviderProperty("zoneId"));
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+        when(pool.getNetwork()).thenReturn(network);
+        when(pool.getHardware()).thenReturn(hardware);
+        when(pool.getSoftware()).thenReturn(software);
+        when(pool.getOptions()).thenReturn(options);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+
+        new EnsureSecurityGroupExists().execute(execution);
+        new EnsureKeyPairExists().execute(execution);
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+        new DeleteKeyPair().execute(execution);
+        new DeleteSecurityGroup().execute(execution);
+
+        logSecurityGroupDetails();
+        logKeyPairs();
+        logVirtualMachines();
+        VirtualMachines.destroyAllVirtualMachineByName(context.getApi(), BUSINESS_KEY);
+        logVirtualMachines();
+        super.tearDown();
+    }
+
+    @Test
+    @Ignore
+    public void test() throws Exception {
+        activity.execute(execution);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/CommandTestSupport.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/CommandTestSupport.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/CommandTestSupport.java
new file mode 100644
index 0000000..d8d44d2
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/CommandTestSupport.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.commands;
+
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.cloudstack.DefaultProviderConfig;
+import com.google.common.base.Optional;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.junit.Before;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Support class for CloudStack Karaf Command tests.
+ */
+public class CommandTestSupport {
+
+    protected DefaultProviderConfig defaultProviderConfig;
+    protected ByteArrayOutputStream byteArrayOutputStream;
+    protected PrintStream out;
+    protected CloudStackClient client;
+
+    @Before
+    public void setUp() throws Exception {
+        defaultProviderConfig = mock(DefaultProviderConfig.class);
+        byteArrayOutputStream = new ByteArrayOutputStream();
+        out = new PrintStream(byteArrayOutputStream);
+        client = mock(CloudStackClient.class);
+        when(defaultProviderConfig.createProvider()).thenReturn(Optional.of(mock(Provider.class)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/OfferingsCommandTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/OfferingsCommandTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/OfferingsCommandTest.java
new file mode 100644
index 0000000..bec3041
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/OfferingsCommandTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.commands;
+
+import com.google.common.collect.Sets;
+import java.util.Set;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.jclouds.cloudstack.domain.DiskOffering;
+import org.jclouds.cloudstack.domain.NetworkOffering;
+import org.jclouds.cloudstack.domain.ServiceOffering;
+import org.jclouds.cloudstack.features.OfferingClient;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class OfferingsCommandTest extends CommandTestSupport {
+
+    final Set<ServiceOffering> serviceOfferings = Sets.newHashSet(ServiceOffering.builder()
+        .id("service-1")
+        .name("service-one")
+        .build());
+
+    final Set<DiskOffering> diskOfferings = Sets.newHashSet(DiskOffering.builder()
+        .id("disk-1")
+        .name("disk-one")
+        .build());
+
+    final Set<NetworkOffering> networkOfferings = Sets.newHashSet(NetworkOffering.builder()
+        .id("network-1")
+        .name("network-one")
+        .build());
+
+    @Test
+    public void testOfferingCommandWithNoOptionSpecified() throws Exception {
+        final OfferingsCommand offeringsCommand = new OfferingsCommand(defaultProviderConfig);
+        offeringsCommand.doExecuteWithContext(client, out);
+        out.close();
+        assertThat(byteArrayOutputStream.toString()).contains("No option specified");
+    }
+
+    @Test
+    public void testOfferingCommandsPrintsServiceOfferings() throws Exception {
+        final OfferingClient offeringClient = mock(OfferingClient.class);
+        when(client.getOfferingClient()).thenReturn(offeringClient);
+        when(offeringClient.listServiceOfferings()).thenReturn(serviceOfferings);
+
+        final OfferingsCommand offeringsCommand = new OfferingsCommand(defaultProviderConfig);
+        offeringsCommand.setServiceOffering(true);
+        offeringsCommand.doExecuteWithContext(client, out);
+        out.close();
+
+        assertThat(byteArrayOutputStream.toString())
+            .contains("service-1")
+            .contains("service-one")
+            .doesNotContain("No option");
+    }
+
+    @Test
+    public void testOfferingsCommandWithAllOptions() throws Exception {
+        final OfferingClient offeringClient = mock(OfferingClient.class);
+
+        when(client.getOfferingClient()).thenReturn(offeringClient);
+        when(offeringClient.listServiceOfferings()).thenReturn(serviceOfferings);
+        when(offeringClient.listDiskOfferings()).thenReturn(diskOfferings);
+        when(offeringClient.listNetworkOfferings()).thenReturn(networkOfferings);
+
+        final OfferingsCommand offeringsCommand = new OfferingsCommand(defaultProviderConfig);
+
+        offeringsCommand.setServiceOffering(true);
+        offeringsCommand.setDiskOffering(true);
+        offeringsCommand.setNetworkOffering(true);
+
+        offeringsCommand.doExecuteWithContext(client, out);
+
+        out.close();
+
+        assertThat(byteArrayOutputStream.toString())
+            .contains("service-1")
+            .contains("service-one")
+            .contains("disk-1")
+            .contains("network-1")
+            .doesNotContain("No option");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/TemplatesCommandTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/TemplatesCommandTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/TemplatesCommandTest.java
new file mode 100644
index 0000000..9375853
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/TemplatesCommandTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.commands;
+
+import com.google.common.collect.Sets;
+import java.util.Set;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.jclouds.cloudstack.domain.Template;
+import org.jclouds.cloudstack.features.TemplateClient;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class TemplatesCommandTest extends CommandTestSupport {
+
+    final Set<Template> templates = Sets.newHashSet(Template.builder()
+        .id("template-1")
+        .name("template-one")
+        .build());
+
+    @Test
+    public void testTemplatesCommandPrintsTheTemplates() throws Exception {
+        final TemplatesCommand templatesCommand = new TemplatesCommand(defaultProviderConfig);
+        final TemplateClient templateClient = mock(TemplateClient.class);
+
+        when(client.getTemplateClient()).thenReturn(templateClient);
+        when(templateClient.listTemplates()).thenReturn(templates);
+
+        templatesCommand.doExecuteWithContext(client, out);
+        out.close();
+        assertThat(byteArrayOutputStream.toString()).contains("template-1").contains("template-one");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/ZonesCommandTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/ZonesCommandTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/ZonesCommandTest.java
new file mode 100644
index 0000000..b422dd6
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/commands/ZonesCommandTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.commands;
+
+import com.google.common.collect.Sets;
+import java.util.Set;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.jclouds.cloudstack.domain.Zone;
+import org.jclouds.cloudstack.features.ZoneClient;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ZonesCommandTest extends CommandTestSupport {
+
+    private final Set<Zone> zones = Sets.newHashSet(Zone.builder()
+        .id("zone-1")
+        .name("zone-one")
+        .securityGroupsEnabled(false)
+        .build());
+
+    @Test
+    public void testZonesCommandPrintsZones() throws Exception {
+        final ZonesCommand zonesCommand = new ZonesCommand(defaultProviderConfig);
+        final ZoneClient zoneClient = mock(ZoneClient.class);
+        when(client.getZoneClient()).thenReturn(zoneClient);
+        when(zoneClient.listZones()).thenReturn(zones);
+
+        zonesCommand.doExecuteWithContext(client, out);
+        out.close();
+
+        final String result = byteArrayOutputStream.toString();
+
+        assertThat(result)
+            .contains("zone-1")
+            .contains("zone-one")
+            .contains("false");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/core/ConversionsTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/core/ConversionsTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/core/ConversionsTest.java
new file mode 100644
index 0000000..8c08a9b
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/core/ConversionsTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.core;
+
+import org.apache.provisionr.api.network.Protocol;
+import org.apache.provisionr.api.network.Rule;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.jclouds.cloudstack.domain.IngressRule;
+import org.junit.Test;
+
+public class ConversionsTest {
+
+    @Test
+    public void testConvertIngressRuleToRuleICMP() throws Exception {
+        final IngressRule ingressRule = IngressRule.builder()
+            .id("rule1")
+            .protocol("icmp")
+            .ICMPCode(SecurityGroups.DEFAULT_ICMP_CODE)
+            .ICMPType(SecurityGroups.DEFAULT_ICMP_TYPE)
+            .CIDR("10.0.0.0/24")
+            .build();
+
+        Rule rule = ConvertIngressRuleToRule.FUNCTION.apply(ingressRule);
+        assertThat(rule.getProtocol()).isEqualTo(Protocol.ICMP);
+        assertThat(rule.getCidr()).isEqualTo(ingressRule.getCIDR());
+    }
+
+    @Test
+    public void testConvertSinglePortRangeIngressRuleToRule() throws Exception {
+        final IngressRule ingressRule = IngressRule.builder()
+            .id("rule1")
+            .protocol("tcp")
+            .startPort(22)
+            .endPort(22)
+            .CIDR("0.0.0.1/24")
+            .build();
+
+        Rule rule = ConvertIngressRuleToRule.FUNCTION.apply(ingressRule);
+        assertThat(rule.getProtocol()).isEqualTo(Protocol.TCP);
+        assertThat(rule.getCidr()).isEqualTo(ingressRule.getCIDR());
+        assertThat(rule.getPorts().lowerEndpoint()).isEqualTo(ingressRule.getStartPort());
+        assertThat(rule.getPorts().upperEndpoint()).isEqualTo(ingressRule.getEndPort());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/core/SecurityGroupsTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/core/SecurityGroupsTest.java b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/core/SecurityGroupsTest.java
new file mode 100644
index 0000000..cbc911b
--- /dev/null
+++ b/providers/cloudstack/src/test/java/org/apache/provisionr/cloudstack/core/SecurityGroupsTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.core;
+
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class SecurityGroupsTest {
+
+    @Test
+    public void testSecurityNameFromBusinessProcessKey() throws Exception {
+        assertThat(SecurityGroups.formatNameFromBusinessKey("test")).isEqualTo("network-test");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/resources/logback.xml
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/resources/logback.xml b/providers/cloudstack/src/test/resources/logback.xml
index 379a09b..8018ecc 100644
--- a/providers/cloudstack/src/test/resources/logback.xml
+++ b/providers/cloudstack/src/test/resources/logback.xml
@@ -58,7 +58,7 @@
         <level value="debug"/>
     </root>
 
-    <logger name="com.axemblr">
+    <logger name="org.apache.provisionr">
         <level value="info"/>
         <appender-ref ref="STDOUT"/>
     </logger>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/scripts/deploy.sh
----------------------------------------------------------------------
diff --git a/scripts/deploy.sh b/scripts/deploy.sh
index 30bfffb..4d0f4d5 100755
--- a/scripts/deploy.sh
+++ b/scripts/deploy.sh
@@ -6,7 +6,7 @@ if [ $# -ne 2 ]; then
 	exit 0
 fi
 rm -rf $1/provisionr
-archive=$(basename "../karaf/assembly/target/com.axemblr.provisionr-$2-SNAPSHOT.tar.gz") 
+archive=$(basename "../karaf/assembly/target/org.apache.provisionr-$2-SNAPSHOT.tar.gz") 
 cp karaf/assembly/target/$archive $1 && cd $1
 tar xvzf $archive && rm $archive
 mv "${archive%.*.*}" provisionr
@@ -14,5 +14,5 @@ cd provisionr/
 for w in "secretKey" "accessKey"
 do
         key=$(grep -E -m 1 -o "<.*amazon.*$w>(.*)</.*amazon.*$w>" ~/.m2/settings.xml | sed -e 's,.*<*.>\([^<]*\)</.*>.*,\1,g')
-        sed -i -e "s/$w = .*$/$w = $key/g" ~/provisionr/system/com/axemblr/provisionr/provisionr-amazon/0.4.0-SNAPSHOT/provisionr-amazon-0.4.0-SNAPSHOT-defaults.cfg
+        sed -i -e "s/$w = .*$/$w = $key/g" ~/provisionr/system/org/apache/provisionr/provisionr-amazon/0.4.0-SNAPSHOT/provisionr-amazon-0.4.0-SNAPSHOT-defaults.cfg
 done
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/pom.xml
----------------------------------------------------------------------
diff --git a/test-support/pom.xml b/test-support/pom.xml
index 4ca5340..837b196 100644
--- a/test-support/pom.xml
+++ b/test-support/pom.xml
@@ -18,18 +18,18 @@
 <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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Test Support</name>
+    <name>Apache Provisionr :: Test Support</name>
     <artifactId>provisionr-test-support</artifactId>
     <packaging>bundle</packaging>
 
     <properties>
-        <osgi.export>com.axemblr.provisionr.test*</osgi.export>
+        <osgi.export>org.apache.provisionr.test*</osgi.export>
         <osgi.import>
             org.mockito*;resolution:=optional,
             *
@@ -42,7 +42,7 @@
             <artifactId>org.osgi.core</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
@@ -168,7 +168,7 @@
                 </configuration>
             </plugin>
             <!--
-             features:addurl mvn:com.axemblr.provisionr/provisionr-features/0.0.1-SNAPSHOT/xml/features
+             features:addurl mvn:org.apache.provisionr/provisionr-features/0.0.1-SNAPSHOT/xml/features
              features:install <feature-name>
              -->
             <plugin>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/com/axemblr/provisionr/test/Generics.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/com/axemblr/provisionr/test/Generics.java b/test-support/src/main/java/com/axemblr/provisionr/test/Generics.java
deleted file mode 100644
index ce44e97..0000000
--- a/test-support/src/main/java/com/axemblr/provisionr/test/Generics.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.test;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Helper methods for class type parameters.
- *
- * @see <a href="https://github.com/codahale/dropwizard/blob/master/dropwizard-core/src/main/java/com/yammer/dropwizard/util/Generics.java">Generics in Codahale Dropwizard</a>
- * @see <a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html">Super Type Tokens</a>
- */
-public class Generics {
-    private Generics() { /* singleton */ }
-
-    /**
-     * Finds the type parameter for the given class which is assignable to the bound class.
-     *
-     * @param klass a parameterized class
-     * @param bound the type bound
-     * @param <T>   the type bound
-     * @return the class's type parameter
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> Class<T> getTypeParameter(Class<?> klass, Class<? super T> bound) {
-        Type t = checkNotNull(klass);
-        while (t instanceof Class<?>) {
-            t = ((Class<?>) t).getGenericSuperclass();
-        }
-        /* This is not guaranteed to work for all cases with convoluted piping
-         * of type parameters: but it can at least resolve straight-forward
-         * extension with single type parameter (as per [Issue-89]).
-         * And when it fails to do that, will indicate with specific exception.
-         */
-        if (t instanceof ParameterizedType) {
-            // should typically have one of type parameters (first one) that matches:
-            for (Type param : ((ParameterizedType) t).getActualTypeArguments()) {
-                if (param instanceof Class<?>) {
-                    final Class<?> cls = (Class<?>) param;
-                    if (bound.isAssignableFrom(cls)) {
-                        return (Class<T>) cls;
-                    }
-                }
-            }
-        }
-        throw new IllegalStateException("Cannot figure out type parameterization for " + klass.getName());
-    }
-
-    /**
-     * Finds the type parameter for the given class.
-     *
-     * @param klass a parameterized class
-     * @return the class's type parameter
-     */
-    public static Class<?> getTypeParameter(Class<?> klass) {
-        return getTypeParameter(klass, Object.class);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/com/axemblr/provisionr/test/KarafTests.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/com/axemblr/provisionr/test/KarafTests.java b/test-support/src/main/java/com/axemblr/provisionr/test/KarafTests.java
deleted file mode 100644
index 4e5bdf0..0000000
--- a/test-support/src/main/java/com/axemblr/provisionr/test/KarafTests.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.test;
-
-import java.io.File;
-import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.karafDistributionConfiguration;
-import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.keepRuntimeFolder;
-import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.logLevel;
-import org.apache.karaf.tooling.exam.options.LogLevelOption;
-import static org.ops4j.pax.exam.CoreOptions.junitBundles;
-import static org.ops4j.pax.exam.CoreOptions.maven;
-import static org.ops4j.pax.exam.CoreOptions.scanFeatures;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-import org.ops4j.pax.exam.MavenUtils;
-import org.ops4j.pax.exam.options.DefaultCompositeOption;
-import org.ops4j.pax.exam.options.MavenArtifactUrlReference;
-import org.ops4j.pax.exam.options.SystemPropertyOption;
-import org.ops4j.pax.exam.options.extra.FeaturesScannerProvisionOption;
-
-/**
- * Helper methods for Karaf integration tests
- */
-public class KarafTests {
-
-    public static final String KARAF_GROUP_ID = "org.apache.karaf";
-    public static final String KARAF_ARTIFACT_ID = "apache-karaf";
-
-    private KarafTests() {
-    }
-
-    /**
-     * Use the same Karaf version from the project for integration testing with Pax Exam
-     */
-    public static DefaultCompositeOption useDefaultKarafAsInProjectWithJunitBundles() {
-        String karafVersion = getKarafVersionAsInProject();
-
-        MavenArtifactUrlReference karafUrl = maven().groupId(KARAF_GROUP_ID)
-            .artifactId(KARAF_ARTIFACT_ID)
-            .version(karafVersion)
-            .type("tar.gz");
-
-        return new DefaultCompositeOption()
-            .add(karafDistributionConfiguration()
-                .frameworkUrl(karafUrl)
-                .karafVersion(karafVersion)
-                .name("Apache Karaf")
-                .unpackDirectory(new File("target/exam")))
-            .add(keepRuntimeFolder())
-            .add(junitBundles())
-            .add(logLevel(LogLevelOption.LogLevel.INFO));
-    }
-
-    public static String getKarafVersionAsInProject() {
-        return MavenUtils.asInProject().getVersion(KARAF_GROUP_ID, KARAF_ARTIFACT_ID);
-    }
-
-    /**
-     * Make sure all system properties with a given prefix are also available inside the container
-     */
-    public static DefaultCompositeOption passThroughAllSystemPropertiesWithPrefix(String prefix) {
-        DefaultCompositeOption options = new DefaultCompositeOption();
-        for (String name : System.getProperties().stringPropertyNames()) {
-            if (name.startsWith(prefix)) {
-                options.add(systemProperty(name).value(System.getProperty(name)));
-            }
-        }
-        return options;
-    }
-
-    /**
-     * Set the project version as a Karaf system property
-     * <p/>
-     * This method assumes that the test-support bundle has the same
-     * version as the code being tested
-     */
-    public static SystemPropertyOption projectVersionAsSystemProperty() {
-        String version = MavenUtils.asInProject()
-            .getVersion("com.axemblr.provisionr", "provisionr-test-support");
-        return systemProperty("project.version").value(version);
-    }
-
-    /**
-     * Create an option to install the test support bundle inside the PAX Exam container
-     */
-    public static FeaturesScannerProvisionOption installProvisionrTestSupportBundle() {
-        return scanFeatures(
-            maven().groupId("com.axemblr.provisionr").artifactId("provisionr-test-support")
-                .type("xml").classifier("features").versionAsInProject(),
-            "provisionr-test-support"
-        );
-    }
-
-    /**
-     * Create an option to install all the requested Provisionr features inside the PAX Exam container
-     */
-    public static FeaturesScannerProvisionOption installProvisionrFeatures(String... features) {
-        return scanFeatures(
-            maven().groupId("com.axemblr.provisionr").artifactId("provisionr-features")
-                .type("xml").classifier("features").versionAsInProject(),
-            features
-        );
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/com/axemblr/provisionr/test/ProcessVariablesCollector.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/com/axemblr/provisionr/test/ProcessVariablesCollector.java b/test-support/src/main/java/com/axemblr/provisionr/test/ProcessVariablesCollector.java
deleted file mode 100644
index 6ac7e02..0000000
--- a/test-support/src/main/java/com/axemblr/provisionr/test/ProcessVariablesCollector.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.test;
-
-import com.google.common.collect.Maps;
-import java.util.Arrays;
-import java.util.Map;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.mockito.Matchers;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ProcessVariablesCollector implements Answer<Void> {
-
-    public static final Logger LOG = LoggerFactory.getLogger(ProcessVariablesCollector.class);
-
-    private Map<String, Object> variables = Maps.newConcurrentMap();
-
-    /**
-     * Install the collector on the setVariable class
-     */
-    public void install(DelegateExecution execution) {
-        doAnswer(this).when(execution).setVariable(Matchers.<String>any(), any());
-    }
-
-    @Override
-    public Void answer(InvocationOnMock invocation) throws Throwable {
-        Object[] arguments = invocation.getArguments();
-        LOG.info("Got method call {} with arguments {}",
-            invocation.getMethod().getName(), Arrays.toString(arguments));
-
-        variables.put((String) arguments[0], arguments[1]);
-        return null;
-    }
-
-    public Object getVariable(String name) {
-        return variables.get(name);
-    }
-
-    @Override
-    public String toString() {
-        return "ProcessVariablesCollector{" +
-            "variables=" + variables +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/com/axemblr/provisionr/test/ProvisionrLiveTestSupport.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/com/axemblr/provisionr/test/ProvisionrLiveTestSupport.java b/test-support/src/main/java/com/axemblr/provisionr/test/ProvisionrLiveTestSupport.java
deleted file mode 100644
index 9d7a7d7..0000000
--- a/test-support/src/main/java/com/axemblr/provisionr/test/ProvisionrLiveTestSupport.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.test;
-
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.provider.ProviderBuilder;
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Stopwatch;
-import com.google.common.io.Resources;
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import javax.inject.Inject;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.osgi.framework.BundleContext;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ProvisionrLiveTestSupport {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ProvisionrLiveTestSupport.class);
-
-    @Inject
-    protected BundleContext bundleContext;
-
-    protected final String provisionrId;
-
-    /**
-     * Supply the provisionrId to acquire proper credentials from System Properties.
-     *
-     * @param provisionrId
-     */
-    public ProvisionrLiveTestSupport(String provisionrId) {
-        this.provisionrId = checkNotNull(provisionrId, "provisionrId is null");
-    }
-
-    /**
-     * Retrieve a reference to an OSGi service using the class name
-     */
-    protected <T> T getOsgiService(Class<T> klass, int timeoutInMilliseconds) throws InterruptedException {
-        ServiceTracker tracker = new ServiceTracker(bundleContext,
-            klass.getCanonicalName(), null);
-        tracker.open(true);
-
-        try {
-            return (T) checkNotNull(tracker.waitForService(timeoutInMilliseconds),
-                "OSGi Service not available " + klass.getCanonicalName());
-        } finally {
-            tracker.close();
-        }
-    }
-
-    /**
-     * Collect the provider connection details from system properties
-     */
-    protected ProviderBuilder collectProviderCredentialsFromSystemProperties() {
-        return Provider.builder().id(provisionrId)
-            .accessKey(getProviderProperty("accessKey"))
-            .secretKey(getProviderProperty("secretKey"))
-            .endpoint(Optional.fromNullable(getProviderProperty("endpoint")));
-    }
-
-    /**
-     * Get a provider configuration property from system properties
-     */
-    protected String getProviderProperty(String property) {
-        return System.getProperty(String.format("test.%s.provider.%s", provisionrId, property));
-    }
-
-    /**
-     * @see #getProviderProperty
-     */
-    protected String getProviderProperty(String property, String defaultValue) {
-        return Optional.fromNullable(getProviderProperty(property)).or(defaultValue);
-    }
-
-    public String getResourceAsString(String resource) throws IOException {
-        return Resources.toString(Resources.getResource(resource), Charsets.UTF_8);
-    }
-
-    /**
-     * Must be called inside a test method to be able to access OSGi infrastructure,
-     *
-     * @param processKey
-     * @throws InterruptedException
-     */
-    public void waitForProcessDeployment(String processKey) throws InterruptedException, TimeoutException {
-        ProcessEngine engine = getOsgiService(ProcessEngine.class, 5000);
-        int iteration = 0;
-        while (iteration < 5) {
-            ProcessDefinition definition = engine.getRepositoryService()
-                .createProcessDefinitionQuery()
-                .processDefinitionKey(processKey).singleResult();
-            if (definition != null) {
-                break;
-            }
-            iteration++;
-            TimeUnit.MILLISECONDS.sleep(500);
-        }
-        if (iteration == 5) {
-            throw new TimeoutException("No process found with key: " + processKey);
-        }
-    }
-
-    public void waitForProcessEnd(String processInstanceId) throws Exception {
-        waitForProcessEnd(processInstanceId, 60000 /* milliseconds */);
-    }
-
-    public void waitForProcessEnd(final String processInstanceId, int timeoutInMilliseconds) throws Exception {
-        Stopwatch stopwatch = new Stopwatch().start();
-        while (isProcessNotEnded(processInstanceId)) {
-            if (stopwatch.elapsedMillis() > timeoutInMilliseconds) {
-                throw new TimeoutException(String.format("Process %s not ended in %d milliseconds.",
-                    processInstanceId, timeoutInMilliseconds));
-            }
-            LOG.info(String.format("Process instance %s not ended. Waiting 1s.", processInstanceId));
-            TimeUnit.SECONDS.sleep(1);
-        }
-        LOG.info(String.format("Process instance %s ended as expected in less than %d milliseconds",
-            processInstanceId, timeoutInMilliseconds));
-    }
-
-    private boolean isProcessNotEnded(final String processInstanceId) throws InterruptedException {
-        ProcessInstance localInstance = getProcessInstanceById(processInstanceId);
-        return localInstance != null && !localInstance.isEnded();
-    }
-
-    private ProcessInstance getProcessInstanceById(final String processInstanceId) throws InterruptedException {
-        ProcessEngine engine = getOsgiService(ProcessEngine.class, 5000);
-        return engine.getRuntimeService().createProcessInstanceQuery()
-            .processInstanceId(processInstanceId)
-            .singleResult();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/com/axemblr/provisionr/test/TestConstants.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/com/axemblr/provisionr/test/TestConstants.java b/test-support/src/main/java/com/axemblr/provisionr/test/TestConstants.java
deleted file mode 100644
index 35c3c84..0000000
--- a/test-support/src/main/java/com/axemblr/provisionr/test/TestConstants.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.test;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Throwables;
-import com.google.common.io.Resources;
-import java.io.IOException;
-
-public class TestConstants {
-
-    static final String PUBLIC_KEY_FILE_NAME = "id_rsa_test.pub";
-    static final String PRIVATE_KEY_FILE_NAME = "id_rsa_test";
-
-    public static final String PUBLIC_KEY = loadResource(PUBLIC_KEY_FILE_NAME);
-    public static final String PRIVATE_KEY = loadResource(PRIVATE_KEY_FILE_NAME);
-
-    private static String loadResource(String fileName) {
-        try {
-            return Resources.toString(Resources.getResource(TestConstants.class, fileName), Charsets.UTF_8);
-        } catch (IOException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/org/apache/provisionr/test/Generics.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/org/apache/provisionr/test/Generics.java b/test-support/src/main/java/org/apache/provisionr/test/Generics.java
new file mode 100644
index 0000000..248fc87
--- /dev/null
+++ b/test-support/src/main/java/org/apache/provisionr/test/Generics.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.test;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Helper methods for class type parameters.
+ *
+ * @see <a href="https://github.com/codahale/dropwizard/blob/master/dropwizard-core/src/main/java/com/yammer/dropwizard/util/Generics.java">Generics in Codahale Dropwizard</a>
+ * @see <a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html">Super Type Tokens</a>
+ */
+public class Generics {
+    private Generics() { /* singleton */ }
+
+    /**
+     * Finds the type parameter for the given class which is assignable to the bound class.
+     *
+     * @param klass a parameterized class
+     * @param bound the type bound
+     * @param <T>   the type bound
+     * @return the class's type parameter
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Class<T> getTypeParameter(Class<?> klass, Class<? super T> bound) {
+        Type t = checkNotNull(klass);
+        while (t instanceof Class<?>) {
+            t = ((Class<?>) t).getGenericSuperclass();
+        }
+        /* This is not guaranteed to work for all cases with convoluted piping
+         * of type parameters: but it can at least resolve straight-forward
+         * extension with single type parameter (as per [Issue-89]).
+         * And when it fails to do that, will indicate with specific exception.
+         */
+        if (t instanceof ParameterizedType) {
+            // should typically have one of type parameters (first one) that matches:
+            for (Type param : ((ParameterizedType) t).getActualTypeArguments()) {
+                if (param instanceof Class<?>) {
+                    final Class<?> cls = (Class<?>) param;
+                    if (bound.isAssignableFrom(cls)) {
+                        return (Class<T>) cls;
+                    }
+                }
+            }
+        }
+        throw new IllegalStateException("Cannot figure out type parameterization for " + klass.getName());
+    }
+
+    /**
+     * Finds the type parameter for the given class.
+     *
+     * @param klass a parameterized class
+     * @return the class's type parameter
+     */
+    public static Class<?> getTypeParameter(Class<?> klass) {
+        return getTypeParameter(klass, Object.class);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/org/apache/provisionr/test/KarafTests.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/org/apache/provisionr/test/KarafTests.java b/test-support/src/main/java/org/apache/provisionr/test/KarafTests.java
new file mode 100644
index 0000000..c8ba29a
--- /dev/null
+++ b/test-support/src/main/java/org/apache/provisionr/test/KarafTests.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.test;
+
+import java.io.File;
+import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.karafDistributionConfiguration;
+import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.keepRuntimeFolder;
+import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.logLevel;
+import org.apache.karaf.tooling.exam.options.LogLevelOption;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.scanFeatures;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+import org.ops4j.pax.exam.MavenUtils;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
+import org.ops4j.pax.exam.options.MavenArtifactUrlReference;
+import org.ops4j.pax.exam.options.SystemPropertyOption;
+import org.ops4j.pax.exam.options.extra.FeaturesScannerProvisionOption;
+
+/**
+ * Helper methods for Karaf integration tests
+ */
+public class KarafTests {
+
+    public static final String KARAF_GROUP_ID = "org.apache.karaf";
+    public static final String KARAF_ARTIFACT_ID = "apache-karaf";
+
+    private KarafTests() {
+    }
+
+    /**
+     * Use the same Karaf version from the project for integration testing with Pax Exam
+     */
+    public static DefaultCompositeOption useDefaultKarafAsInProjectWithJunitBundles() {
+        String karafVersion = getKarafVersionAsInProject();
+
+        MavenArtifactUrlReference karafUrl = maven().groupId(KARAF_GROUP_ID)
+            .artifactId(KARAF_ARTIFACT_ID)
+            .version(karafVersion)
+            .type("tar.gz");
+
+        return new DefaultCompositeOption()
+            .add(karafDistributionConfiguration()
+                .frameworkUrl(karafUrl)
+                .karafVersion(karafVersion)
+                .name("Apache Karaf")
+                .unpackDirectory(new File("target/exam")))
+            .add(keepRuntimeFolder())
+            .add(junitBundles())
+            .add(logLevel(LogLevelOption.LogLevel.INFO));
+    }
+
+    public static String getKarafVersionAsInProject() {
+        return MavenUtils.asInProject().getVersion(KARAF_GROUP_ID, KARAF_ARTIFACT_ID);
+    }
+
+    /**
+     * Make sure all system properties with a given prefix are also available inside the container
+     */
+    public static DefaultCompositeOption passThroughAllSystemPropertiesWithPrefix(String prefix) {
+        DefaultCompositeOption options = new DefaultCompositeOption();
+        for (String name : System.getProperties().stringPropertyNames()) {
+            if (name.startsWith(prefix)) {
+                options.add(systemProperty(name).value(System.getProperty(name)));
+            }
+        }
+        return options;
+    }
+
+    /**
+     * Set the project version as a Karaf system property
+     * <p/>
+     * This method assumes that the test-support bundle has the same
+     * version as the code being tested
+     */
+    public static SystemPropertyOption projectVersionAsSystemProperty() {
+        String version = MavenUtils.asInProject()
+            .getVersion("org.apache.provisionr", "provisionr-test-support");
+        return systemProperty("project.version").value(version);
+    }
+
+    /**
+     * Create an option to install the test support bundle inside the PAX Exam container
+     */
+    public static FeaturesScannerProvisionOption installProvisionrTestSupportBundle() {
+        return scanFeatures(
+            maven().groupId("org.apache.provisionr").artifactId("provisionr-test-support")
+                .type("xml").classifier("features").versionAsInProject(),
+            "provisionr-test-support"
+        );
+    }
+
+    /**
+     * Create an option to install all the requested Provisionr features inside the PAX Exam container
+     */
+    public static FeaturesScannerProvisionOption installProvisionrFeatures(String... features) {
+        return scanFeatures(
+            maven().groupId("org.apache.provisionr").artifactId("provisionr-features")
+                .type("xml").classifier("features").versionAsInProject(),
+            features
+        );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/test-support/src/main/java/org/apache/provisionr/test/ProcessVariablesCollector.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/org/apache/provisionr/test/ProcessVariablesCollector.java b/test-support/src/main/java/org/apache/provisionr/test/ProcessVariablesCollector.java
new file mode 100644
index 0000000..6e5e5f0
--- /dev/null
+++ b/test-support/src/main/java/org/apache/provisionr/test/ProcessVariablesCollector.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.test;
+
+import com.google.common.collect.Maps;
+import java.util.Arrays;
+import java.util.Map;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.mockito.Matchers;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProcessVariablesCollector implements Answer<Void> {
+
+    public static final Logger LOG = LoggerFactory.getLogger(ProcessVariablesCollector.class);
+
+    private Map<String, Object> variables = Maps.newConcurrentMap();
+
+    /**
+     * Install the collector on the setVariable class
+     */
+    public void install(DelegateExecution execution) {
+        doAnswer(this).when(execution).setVariable(Matchers.<String>any(), any());
+    }
+
+    @Override
+    public Void answer(InvocationOnMock invocation) throws Throwable {
+        Object[] arguments = invocation.getArguments();
+        LOG.info("Got method call {} with arguments {}",
+            invocation.getMethod().getName(), Arrays.toString(arguments));
+
+        variables.put((String) arguments[0], arguments[1]);
+        return null;
+    }
+
+    public Object getVariable(String name) {
+        return variables.get(name);
+    }
+
+    @Override
+    public String toString() {
+        return "ProcessVariablesCollector{" +
+            "variables=" + variables +
+            '}';
+    }
+}


[12/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Project.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Project.java b/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Project.java
deleted file mode 100644
index a568ce2..0000000
--- a/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/Project.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.rundeck;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Lists;
-import java.util.Collections;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
-/**
- * Rundeck Resource Model Project definition
- *
- * @see <a href="http://rundeck.org/docs/manpages/man5/resource-v13.html" />
- */
-@XmlRootElement(name = "project")
-public class Project {
-
-    private List<Node> nodes = Lists.newArrayList();
-
-    public Project() {
-    }
-
-    public Project(List<Node> nodes) {
-        this.nodes = checkNotNull(nodes, "nodes is null");
-    }
-
-    @XmlElement(name = "node")
-    public List<Node> getNodes() {
-        return nodes;
-    }
-
-    public void setNodes(List<Node> nodes) {
-        this.nodes = checkNotNull(nodes, "nodes is null");
-    }
-
-    public void addNodes(Node... nodes) {
-        Collections.addAll(this.nodes, nodes);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        Project project = (Project) o;
-
-        return !(nodes != null ? !nodes.equals(project.nodes) : project.nodes != null);
-
-    }
-
-    @Override
-    public int hashCode() {
-        return nodes != null ? nodes.hashCode() : 0;
-    }
-
-    @Override
-    public String toString() {
-        return "Project{" +
-            "nodes=" + nodes +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/RundeckServlet.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/RundeckServlet.java b/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/RundeckServlet.java
deleted file mode 100644
index 1767298..0000000
--- a/integration/rundeck/src/main/java/com/axemblr/provisionr/rundeck/RundeckServlet.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.rundeck;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.List;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RundeckServlet extends HttpServlet {
-
-    private static final Logger LOG = LoggerFactory.getLogger(RundeckServlet.class);
-
-    private final ProcessEngine processEngine;
-    private final Marshaller marshaller;
-
-    public RundeckServlet(ProcessEngine processEngine) throws JAXBException {
-        this.processEngine = checkNotNull(processEngine, "processEngine is null");
-
-        this.marshaller = JAXBContext.newInstance(Project.class).createMarshaller();
-        this.marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
-    }
-
-    @Override
-    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-        response.setContentType("application/xml;charset=UTF-8");
-        writeRundeckResourceModelXmlTo(response.getWriter());
-    }
-
-    @VisibleForTesting
-    void writeRundeckResourceModelXmlTo(PrintWriter writer) {
-        final List<ProcessInstance> processes = processEngine.getRuntimeService()
-            .createProcessInstanceQuery().list();
-
-        Project project = new Project();
-        for (ProcessInstance instance : processes) {
-            final Pool pool = (Pool) processEngine.getRuntimeService()
-                .getVariable(instance.getId(), CoreProcessVariables.POOL);
-            if (pool == null) {
-                continue; /* skip - this process is not a provisionr process */
-            }
-
-            final String businessKey = (String) processEngine.getRuntimeService()
-                .getVariable(instance.getId(), CoreProcessVariables.POOL_BUSINESS_KEY);
-            if (!Objects.equal(instance.getBusinessKey(), businessKey)) {
-                continue; /* ignore - this is a process started by the main pool management process */
-            }
-
-            @SuppressWarnings("unchecked")
-            List<Machine> machines = (List<Machine>) processEngine.getRuntimeService()
-                .getVariable(instance.getId(), CoreProcessVariables.MACHINES);
-            if (machines == null) {
-                continue;   /* the list of machines is not yet available */
-            }
-
-            project.setNodes(transformMachinesToRundeckNodes(businessKey, pool, machines));
-        }
-
-        try {
-            marshaller.marshal(project, writer);
-
-        } catch (JAXBException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    @VisibleForTesting
-    List<Node> transformMachinesToRundeckNodes(String businessKey, Pool pool, List<Machine> machines) {
-        List<Node> nodes = Lists.newArrayList();
-
-        for (Machine machine : machines) {
-            Node node = new Node(machine.getExternalId(), machine.getPublicDnsName(),
-                pool.getAdminAccess().getUsername());
-
-            node.setTags(pool.getSoftware().getPackages());
-
-            node.setAttributes(ImmutableMap.<String, String>builder()
-                .put("provider", pool.getProvider().getId())
-                .put("key", businessKey)
-                .put("publicIp", machine.getPublicIp())
-                .put("privateHostname", machine.getPrivateDnsName())
-                .put("privateIp", machine.getPrivateIp())
-                .put("hardwareType", pool.getHardware().getType())
-                .build());
-
-            if (pool.getProvider().getOptions().containsKey("region")) {
-                node.addAttribute("region", pool.getProvider().getOption("region"));
-            }
-
-            nodes.add(node);
-        }
-
-        return nodes;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Attribute.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Attribute.java b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Attribute.java
new file mode 100644
index 0000000..4d00077
--- /dev/null
+++ b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Attribute.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.rundeck;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * An attribute allows you to add user-defined metadata
+ *
+ * @see <a href="http://rundeck.org/docs/manpages/man5/resource-v13.html#attribute" />
+ */
+public class Attribute {
+
+    private String name;
+
+    private String value;
+
+    public Attribute() {
+    }
+
+    public Attribute(String name, String value) {
+        this.name = checkNotNull(name, "name is null");
+        this.value = checkNotNull(value, "value is null");
+    }
+
+    @XmlAttribute(name = "name")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = checkNotNull(name, "name is null");
+    }
+
+    @XmlAttribute(name = "value")
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = checkNotNull(value, "value is null");
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Attribute attribute = (Attribute) o;
+
+        if (name != null ? !name.equals(attribute.name) : attribute.name != null) return false;
+        if (value != null ? !value.equals(attribute.value) : attribute.value != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "Attribute{" +
+            "name='" + name + '\'' +
+            ", value='" + value + '\'' +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Node.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Node.java b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Node.java
new file mode 100644
index 0000000..0fc6aa3
--- /dev/null
+++ b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Node.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.rundeck;
+
+import com.google.common.base.Joiner;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * A Rundeck Resource Model is nothing more than just a list of nodes
+ * with a predefined set of properties and an optional list of user defined attributes
+ *
+ * @see <a href="http://rundeck.org/docs/manpages/man5/resource-v13.html#node" />
+ */
+public class Node {
+
+    /**
+     * The node name. This is a logical identifier from the node. (required)
+     */
+    private String name;
+
+    /**
+     * The hostname or IP address of the remote host. (required)
+     */
+    private String hostname;
+
+    /**
+     * Comma separated list of filtering tags. (optional)
+     */
+    private String tags;
+
+    /**
+     * The username used for the remote connection. (required)
+     */
+    private String username;
+
+    /**
+     * User defined attributes
+     */
+    private List<Attribute> attributes;
+
+    public Node() {
+    }
+
+    public Node(String name, String hostname, String username) {
+        this.name = checkNotNull(name, "name is null");
+        this.hostname = checkNotNull(hostname, "hostname is null");
+        this.username = checkNotNull(username, "username is null");
+    }
+
+    @XmlAttribute
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = checkNotNull(name, "name is null");
+    }
+
+    @XmlAttribute
+    public String getHostname() {
+        return hostname;
+    }
+
+    public void setHostname(String hostname) {
+        this.hostname = checkNotNull(hostname, "hostname is null");
+    }
+
+    @XmlAttribute
+    public String getTags() {
+        return tags;
+    }
+
+    public void setTags(String tags) {
+        this.tags = checkNotNull(tags, "tags is null");
+    }
+
+    public void setTags(Iterable<String> tags) {
+        setTags(Joiner.on(",").join(tags));
+    }
+
+    public void setTags(String[] tags) {
+        setTags(Joiner.on(",").join(tags));
+    }
+
+    @XmlAttribute
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = checkNotNull(username, "username is null");
+    }
+
+    @XmlElement(name = "attribute")
+    public List<Attribute> getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(List<Attribute> attributes) {
+        this.attributes = checkNotNull(attributes, "attributes is null");
+    }
+
+    public void setAttributes(Map<String, String> values) {
+        this.attributes = Lists.newArrayList();
+        for (Map.Entry<String, String> entry : values.entrySet()) {
+            this.attributes.add(new Attribute(entry.getKey(), entry.getValue()));
+        }
+    }
+
+    public void addAttribute(String name, String value) {
+        this.attributes.add(new Attribute(name, value));
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Node node = (Node) o;
+
+        if (attributes != null ? !attributes.equals(node.attributes) : node.attributes != null) return false;
+        if (hostname != null ? !hostname.equals(node.hostname) : node.hostname != null) return false;
+        if (name != null ? !name.equals(node.name) : node.name != null) return false;
+        if (tags != null ? !tags.equals(node.tags) : node.tags != null) return false;
+        if (username != null ? !username.equals(node.username) : node.username != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (hostname != null ? hostname.hashCode() : 0);
+        result = 31 * result + (tags != null ? tags.hashCode() : 0);
+        result = 31 * result + (username != null ? username.hashCode() : 0);
+        result = 31 * result + (attributes != null ? attributes.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "Node{" +
+            "name='" + name + '\'' +
+            ", hostname='" + hostname + '\'' +
+            ", tags='" + tags + '\'' +
+            ", username='" + username + '\'' +
+            ", attributes=" + attributes +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Project.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Project.java b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Project.java
new file mode 100644
index 0000000..2fd9a61
--- /dev/null
+++ b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/Project.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.rundeck;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Lists;
+import java.util.Collections;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Rundeck Resource Model Project definition
+ *
+ * @see <a href="http://rundeck.org/docs/manpages/man5/resource-v13.html" />
+ */
+@XmlRootElement(name = "project")
+public class Project {
+
+    private List<Node> nodes = Lists.newArrayList();
+
+    public Project() {
+    }
+
+    public Project(List<Node> nodes) {
+        this.nodes = checkNotNull(nodes, "nodes is null");
+    }
+
+    @XmlElement(name = "node")
+    public List<Node> getNodes() {
+        return nodes;
+    }
+
+    public void setNodes(List<Node> nodes) {
+        this.nodes = checkNotNull(nodes, "nodes is null");
+    }
+
+    public void addNodes(Node... nodes) {
+        Collections.addAll(this.nodes, nodes);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Project project = (Project) o;
+
+        return !(nodes != null ? !nodes.equals(project.nodes) : project.nodes != null);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return nodes != null ? nodes.hashCode() : 0;
+    }
+
+    @Override
+    public String toString() {
+        return "Project{" +
+            "nodes=" + nodes +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/RundeckServlet.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/RundeckServlet.java b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/RundeckServlet.java
new file mode 100644
index 0000000..c0f7753
--- /dev/null
+++ b/integration/rundeck/src/main/java/org/apache/provisionr/rundeck/RundeckServlet.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.rundeck;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RundeckServlet extends HttpServlet {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RundeckServlet.class);
+
+    private final ProcessEngine processEngine;
+    private final Marshaller marshaller;
+
+    public RundeckServlet(ProcessEngine processEngine) throws JAXBException {
+        this.processEngine = checkNotNull(processEngine, "processEngine is null");
+
+        this.marshaller = JAXBContext.newInstance(Project.class).createMarshaller();
+        this.marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        response.setContentType("application/xml;charset=UTF-8");
+        writeRundeckResourceModelXmlTo(response.getWriter());
+    }
+
+    @VisibleForTesting
+    void writeRundeckResourceModelXmlTo(PrintWriter writer) {
+        final List<ProcessInstance> processes = processEngine.getRuntimeService()
+            .createProcessInstanceQuery().list();
+
+        Project project = new Project();
+        for (ProcessInstance instance : processes) {
+            final Pool pool = (Pool) processEngine.getRuntimeService()
+                .getVariable(instance.getId(), CoreProcessVariables.POOL);
+            if (pool == null) {
+                continue; /* skip - this process is not a provisionr process */
+            }
+
+            final String businessKey = (String) processEngine.getRuntimeService()
+                .getVariable(instance.getId(), CoreProcessVariables.POOL_BUSINESS_KEY);
+            if (!Objects.equal(instance.getBusinessKey(), businessKey)) {
+                continue; /* ignore - this is a process started by the main pool management process */
+            }
+
+            @SuppressWarnings("unchecked")
+            List<Machine> machines = (List<Machine>) processEngine.getRuntimeService()
+                .getVariable(instance.getId(), CoreProcessVariables.MACHINES);
+            if (machines == null) {
+                continue;   /* the list of machines is not yet available */
+            }
+
+            project.setNodes(transformMachinesToRundeckNodes(businessKey, pool, machines));
+        }
+
+        try {
+            marshaller.marshal(project, writer);
+
+        } catch (JAXBException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    @VisibleForTesting
+    List<Node> transformMachinesToRundeckNodes(String businessKey, Pool pool, List<Machine> machines) {
+        List<Node> nodes = Lists.newArrayList();
+
+        for (Machine machine : machines) {
+            Node node = new Node(machine.getExternalId(), machine.getPublicDnsName(),
+                pool.getAdminAccess().getUsername());
+
+            node.setTags(pool.getSoftware().getPackages());
+
+            node.setAttributes(ImmutableMap.<String, String>builder()
+                .put("provider", pool.getProvider().getId())
+                .put("key", businessKey)
+                .put("publicIp", machine.getPublicIp())
+                .put("privateHostname", machine.getPrivateDnsName())
+                .put("privateIp", machine.getPrivateIp())
+                .put("hardwareType", pool.getHardware().getType())
+                .build());
+
+            if (pool.getProvider().getOptions().containsKey("region")) {
+                node.addAttribute("region", pool.getProvider().getOption("region"));
+            }
+
+            nodes.add(node);
+        }
+
+        return nodes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/resources/OSGI-INF/blueprint/context.xml
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/resources/OSGI-INF/blueprint/context.xml b/integration/rundeck/src/main/resources/OSGI-INF/blueprint/context.xml
index 76ef884..1d16a6d 100644
--- a/integration/rundeck/src/main/resources/OSGI-INF/blueprint/context.xml
+++ b/integration/rundeck/src/main/resources/OSGI-INF/blueprint/context.xml
@@ -22,7 +22,7 @@
         <service-properties>
             <entry key="alias" value="/rundeck/machines.xml"/>
         </service-properties>
-        <bean class="com.axemblr.provisionr.rundeck.RundeckServlet">
+        <bean class="org.apache.provisionr.rundeck.RundeckServlet">
             <argument ref="processEngine"/>
         </bean>
     </service>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/main/resources/features.xml b/integration/rundeck/src/main/resources/features.xml
index cb7cb37..3a66fab 100644
--- a/integration/rundeck/src/main/resources/features.xml
+++ b/integration/rundeck/src/main/resources/features.xml
@@ -16,17 +16,17 @@
   ~ limitations under the License.
   -->
 
-<features name="axemblr-provisionr-rundeck-features-${project.version}"
+<features name="provisionr-rundeck-features-${project.version}"
           xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
 
     <repository>
-        mvn:com.axemblr.provisionr/provisionr-core/${project.version}/xml/features
+        mvn:org.apache.provisionr/provisionr-core/${project.version}/xml/features
     </repository>
 
-    <feature name="axemblr-provisionr-rundeck" version="${project.version}">
+    <feature name="provisionr-rundeck" version="${project.version}">
         <feature>http</feature>
-        <feature version="${project.version}">axemblr-provisionr-core</feature>
+        <feature version="${project.version}">provisionr-core</feature>
 
-        <bundle start="true">mvn:com.axemblr.provisionr/provisionr-rundeck/${project.version}</bundle>
+        <bundle start="true">mvn:org.apache.provisionr/provisionr-rundeck/${project.version}</bundle>
     </feature>
 </features>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/BaseJaxbTest.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/BaseJaxbTest.java b/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/BaseJaxbTest.java
deleted file mode 100644
index 6d98dff..0000000
--- a/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/BaseJaxbTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.rundeck;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.junit.Before;
-
-public abstract class BaseJaxbTest {
-
-    protected JAXBContext jaxb;
-
-    static {
-        XMLUnit.setIgnoreWhitespace(true);
-        XMLUnit.setIgnoreComments(true);
-        XMLUnit.setIgnoreAttributeOrder(true);
-    }
-
-    @Before
-    public void setUp() throws JAXBException {
-        jaxb = JAXBContext.newInstance(getContextClasses());
-    }
-
-    public abstract Class[] getContextClasses();
-
-    /**
-     * Marshal an object as XML using a standard JAXB Context
-     */
-    protected String asXml(Object obj) throws Exception {
-        ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
-        PrintStream out = new PrintStream(outBytes);
-
-        Marshaller marshaller = jaxb.createMarshaller();
-        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
-
-        marshaller.marshal(obj, out);
-        return outBytes.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/ProjectTest.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/ProjectTest.java b/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/ProjectTest.java
deleted file mode 100644
index 430874c..0000000
--- a/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/ProjectTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.rundeck;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.io.Resources;
-import java.io.IOException;
-import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
-import org.junit.Test;
-
-/**
- * A test to make sure the JAXB serialization works as expected
- */
-public class ProjectTest extends BaseJaxbTest {
-
-    @Test
-    public void testEmptyProject() throws Exception {
-        String actual = asXml(new Project());
-        assertXMLEqual(actual, "<project />", actual);
-    }
-
-    @Test
-    public void testSimpleProject() throws Exception {
-        Project project = new Project();
-
-        Node node = new Node("db-1", "db-1.example.com", "psql");
-        node.setTags(new String[]{"a", "b"});
-        node.setAttributes(ImmutableMap.of("key1", "val1", "key2", "val2"));
-
-        project.addNodes(node);
-        project.addNodes(new Node("web-1", "web-1.example.com", "django"));
-
-        String actual = asXml(project);
-        assertXMLEqual(actual, readResource("fixtures/project.xml"), actual);
-    }
-
-    private String readResource(String resource) throws IOException {
-        return Resources.toString(Resources.getResource(resource), Charsets.UTF_8);
-    }
-
-    @Override
-    public Class[] getContextClasses() {
-        return new Class[]{Project.class};
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/RundeckServletTest.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/RundeckServletTest.java b/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/RundeckServletTest.java
deleted file mode 100644
index 15b9f64..0000000
--- a/integration/rundeck/src/test/java/com/axemblr/provisionr/rundeck/RundeckServletTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.rundeck;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import javax.xml.bind.JAXBException;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration;
-import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.xml.sax.SAXException;
-
-public class RundeckServletTest {
-
-    private ByteArrayOutputStream output;
-    private PrintWriter writer;
-
-    @Before
-    public void setUp() {
-        output = new ByteArrayOutputStream();
-        writer = new PrintWriter(output);
-    }
-
-    @After
-    public void tearDown() throws IOException {
-        writer.close();
-        output.close();
-    }
-
-    @Test
-    public void testEmptyListOfMachines() throws JAXBException, IOException, SAXException {
-        ProcessEngine processEngine = new StandaloneInMemProcessEngineConfiguration().buildProcessEngine();
-        try {
-            RundeckServlet servlet = new RundeckServlet(processEngine);
-            servlet.writeRundeckResourceModelXmlTo(writer);
-
-            writer.flush();
-            assertXMLEqual(output.toString(), "<project />");
-
-        } finally {
-            processEngine.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/BaseJaxbTest.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/BaseJaxbTest.java b/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/BaseJaxbTest.java
new file mode 100644
index 0000000..67acbe9
--- /dev/null
+++ b/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/BaseJaxbTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.rundeck;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Before;
+
+public abstract class BaseJaxbTest {
+
+    protected JAXBContext jaxb;
+
+    static {
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreComments(true);
+        XMLUnit.setIgnoreAttributeOrder(true);
+    }
+
+    @Before
+    public void setUp() throws JAXBException {
+        jaxb = JAXBContext.newInstance(getContextClasses());
+    }
+
+    public abstract Class[] getContextClasses();
+
+    /**
+     * Marshal an object as XML using a standard JAXB Context
+     */
+    protected String asXml(Object obj) throws Exception {
+        ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
+        PrintStream out = new PrintStream(outBytes);
+
+        Marshaller marshaller = jaxb.createMarshaller();
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+
+        marshaller.marshal(obj, out);
+        return outBytes.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/ProjectTest.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/ProjectTest.java b/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/ProjectTest.java
new file mode 100644
index 0000000..b313858
--- /dev/null
+++ b/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/ProjectTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.rundeck;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Resources;
+import java.io.IOException;
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import org.junit.Test;
+
+/**
+ * A test to make sure the JAXB serialization works as expected
+ */
+public class ProjectTest extends BaseJaxbTest {
+
+    @Test
+    public void testEmptyProject() throws Exception {
+        String actual = asXml(new Project());
+        assertXMLEqual(actual, "<project />", actual);
+    }
+
+    @Test
+    public void testSimpleProject() throws Exception {
+        Project project = new Project();
+
+        Node node = new Node("db-1", "db-1.example.com", "psql");
+        node.setTags(new String[]{"a", "b"});
+        node.setAttributes(ImmutableMap.of("key1", "val1", "key2", "val2"));
+
+        project.addNodes(node);
+        project.addNodes(new Node("web-1", "web-1.example.com", "django"));
+
+        String actual = asXml(project);
+        assertXMLEqual(actual, readResource("fixtures/project.xml"), actual);
+    }
+
+    private String readResource(String resource) throws IOException {
+        return Resources.toString(Resources.getResource(resource), Charsets.UTF_8);
+    }
+
+    @Override
+    public Class[] getContextClasses() {
+        return new Class[]{Project.class};
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/RundeckServletTest.java
----------------------------------------------------------------------
diff --git a/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/RundeckServletTest.java b/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/RundeckServletTest.java
new file mode 100644
index 0000000..f087434
--- /dev/null
+++ b/integration/rundeck/src/test/java/org/apache/provisionr/rundeck/RundeckServletTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.rundeck;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import javax.xml.bind.JAXBException;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration;
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+public class RundeckServletTest {
+
+    private ByteArrayOutputStream output;
+    private PrintWriter writer;
+
+    @Before
+    public void setUp() {
+        output = new ByteArrayOutputStream();
+        writer = new PrintWriter(output);
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        writer.close();
+        output.close();
+    }
+
+    @Test
+    public void testEmptyListOfMachines() throws JAXBException, IOException, SAXException {
+        ProcessEngine processEngine = new StandaloneInMemProcessEngineConfiguration().buildProcessEngine();
+        try {
+            RundeckServlet servlet = new RundeckServlet(processEngine);
+            servlet.writeRundeckResourceModelXmlTo(writer);
+
+            writer.flush();
+            assertXMLEqual(output.toString(), "<project />");
+
+        } finally {
+            processEngine.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/assembly-tests/pom.xml
----------------------------------------------------------------------
diff --git a/karaf/assembly-tests/pom.xml b/karaf/assembly-tests/pom.xml
index 73f44d8..fa87017 100644
--- a/karaf/assembly-tests/pom.xml
+++ b/karaf/assembly-tests/pom.xml
@@ -18,31 +18,31 @@
 <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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Custom Karaf Distribution Tests</name>
+    <name>Apache Provisionr :: Custom Karaf Distribution Tests</name>
     <artifactId>provisionr-assembly-tests</artifactId>
     <packaging>jar</packaging>
 
     <dependencies>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-core</artifactId>
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-assembly</artifactId>
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-test-support</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/assembly-tests/src/test/java/com/axemblr/provisionr/karaf/CustomKarafDistributionTest.java
----------------------------------------------------------------------
diff --git a/karaf/assembly-tests/src/test/java/com/axemblr/provisionr/karaf/CustomKarafDistributionTest.java b/karaf/assembly-tests/src/test/java/com/axemblr/provisionr/karaf/CustomKarafDistributionTest.java
deleted file mode 100644
index f1fca5e..0000000
--- a/karaf/assembly-tests/src/test/java/com/axemblr/provisionr/karaf/CustomKarafDistributionTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.karaf;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.core.templates.PoolTemplate;
-import static com.axemblr.provisionr.test.KarafTests.getKarafVersionAsInProject;
-import com.google.common.base.Stopwatch;
-import com.google.common.io.CharStreams;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.URL;
-import java.util.concurrent.TimeUnit;
-import javax.inject.Inject;
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.FeaturesService;
-import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.karafDistributionConfiguration;
-import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.keepRuntimeFolder;
-import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.logLevel;
-import org.apache.karaf.tooling.exam.options.LogLevelOption;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import static org.ops4j.pax.exam.CoreOptions.junitBundles;
-import static org.ops4j.pax.exam.CoreOptions.maven;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.Configuration;
-import org.ops4j.pax.exam.junit.ExamReactorStrategy;
-import org.ops4j.pax.exam.junit.JUnit4TestRunner;
-import org.ops4j.pax.exam.options.MavenArtifactUrlReference;
-import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Run a set of tests on the custom Karaf distribution
- */
-@RunWith(JUnit4TestRunner.class)
-@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
-public class CustomKarafDistributionTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(CustomKarafDistributionTest.class);
-
-    public static final String ACTIVITI_EXPLORER_URL = "http://localhost:8181/activiti-explorer/";
-
-    public static final String RUNDECK_RESOURCE_URL = "http://localhost:8181/rundeck/machines.xml";
-
-    public static final String LOCALHOST = "localhost";
-
-    public static final int DEFAULT_JETTY_PORT = 8181;
-    public static final int TIMEOUT_IN_MILLISECONDS = 1000;
-
-    /**
-     * We are only starting Amazon by default. The support for cloudstack is not ready yet.
-     */
-    public static final int EXPECTED_NUMBER_OF_PROVISIONR_SERVICES = 1;
-
-    /**
-     * We only register two pool templates by default through the provisionr-core bundle
-     */
-    public static final int EXPECTED_NUMBER_OF_POOL_TEMPLATES = 3;
-
-    @Inject
-    private FeaturesService features;
-
-    @Inject
-    private BundleContext bundleContext;
-
-    @Configuration
-    public Option[] configuration() throws Exception {
-        MavenArtifactUrlReference distributionUrl = maven().groupId("com.axemblr.provisionr")
-            .artifactId("provisionr-assembly").versionAsInProject().type("tar.gz");
-
-        return new Option[]{
-            karafDistributionConfiguration()
-                .frameworkUrl(distributionUrl)
-                .karafVersion(getKarafVersionAsInProject())
-                .name("Axemblr Provisionr")
-                .unpackDirectory(new File("target/exam")),
-            keepRuntimeFolder(),
-            junitBundles(),
-            logLevel(LogLevelOption.LogLevel.INFO)
-        };
-    }
-
-    @Test
-    public void testAllFeaturesStartAsExpected() throws Exception {
-        assertFeatureInstalled("axemblr-provisionr-all");
-
-        assertAllBundlesAreActive();
-
-        assertJettyStartsInLessThan(5000 /* milliseconds */);
-
-        assertProvisionrServicesAreStartedInLessThan(5000 /* milliseconds */);
-        assertPoolTemplatesAreRegisteredInLessThan(5000 /* milliseconds */);
-
-        assertUrlContainsInLessThan(ACTIVITI_EXPLORER_URL, "Vaadin", 10000 /* milliseconds */);
-        assertUrlContainsInLessThan(RUNDECK_RESOURCE_URL, "<project", 10000 /* milliseconds */);
-    }
-
-    private void assertUrlContainsInLessThan(
-        String url, String expectedContent, int timeoutInMilliseconds
-    ) throws InterruptedException {
-
-        final Stopwatch stopwatch = new Stopwatch().start();
-        while (true) {
-            if (stopwatch.elapsedMillis() > timeoutInMilliseconds) {
-                fail(String.format("Unable to fetch url '%s' in less than %d milliseconds",
-                    url, timeoutInMilliseconds));
-            }
-
-            try {
-                String content = CharStreams.toString(new InputStreamReader(new URL(url).openStream()));
-                assertTrue(String.format("Expected to find '%s' in: %s", expectedContent, content),
-                    content.contains(expectedContent));
-
-                break;  /* test completed as expected */
-
-            } catch (Exception e) {
-                LOG.info(String.format("Unable to fetch %s (%s). Trying again in 5s.", url, e.getMessage()));
-                TimeUnit.SECONDS.sleep(5);
-            }
-        }
-    }
-
-    private void assertProvisionrServicesAreStartedInLessThan(int timeoutInMilliseconds) throws Exception {
-        assertServicesAreStartedInLessThan(Provisionr.class,
-            EXPECTED_NUMBER_OF_PROVISIONR_SERVICES, timeoutInMilliseconds);
-    }
-
-    private void assertPoolTemplatesAreRegisteredInLessThan(int timeoutInMilliseconds) throws Exception {
-        assertServicesAreStartedInLessThan(PoolTemplate.class,
-            EXPECTED_NUMBER_OF_POOL_TEMPLATES, timeoutInMilliseconds);
-
-    }
-
-    private void assertServicesAreStartedInLessThan(
-        Class<?> klass, int expectedCardinality, int timeoutInMilliseconds
-    ) throws Exception {
-        final ServiceTracker tracker = new ServiceTracker(bundleContext, klass.getName(), null);
-        tracker.open(true);
-        try {
-            final Stopwatch stopwatch = new Stopwatch().start();
-
-            while (true) {
-                Object[] services = tracker.getServices();
-                if (services == null || services.length < expectedCardinality) {
-                    final int actualCount = (services == null) ? 0 : services.length;
-                    if (stopwatch.elapsedMillis() > timeoutInMilliseconds) {
-                        fail(String.format("Expected to find %d %s services. Found only %d in %d milliseconds",
-                            expectedCardinality, klass.getSimpleName(), actualCount, timeoutInMilliseconds));
-                    }
-
-                    LOG.info(String.format("Found %d services implementing %s. Trying again in 1s.",
-                        actualCount, klass.getName()));
-                    TimeUnit.SECONDS.sleep(1);
-
-                } else if (services.length > expectedCardinality) {
-                    fail(String.format("Expected to find %d services implementing %s. Found %d (more than expected).",
-                        expectedCardinality, klass.getName(), services.length));
-
-                } else if (services.length == expectedCardinality) {
-                    break;  /* done - the test was successful */
-                }
-            }
-
-        } finally {
-            tracker.close();
-        }
-    }
-
-    private void assertAllBundlesAreActive() {
-        for (Bundle bundle : bundleContext.getBundles()) {
-            // skip fragments, they can't be started
-            if (bundle.getHeaders().get(Constants.FRAGMENT_HOST) == null) {
-                assertEquals("Bundle " + bundle.getSymbolicName() + " is not active",
-                    Bundle.ACTIVE, bundle.getState());
-            }
-        }
-    }
-
-    private void assertFeatureInstalled(String featureName) throws Exception {
-        Feature feature = features.getFeature(featureName);
-        assertTrue("Feature " + featureName + " should be installed", features.isInstalled(feature));
-    }
-
-    private void assertJettyStartsInLessThan(int timeoutInMilliseconds) throws InterruptedException {
-        Stopwatch stopwatch = new Stopwatch().start();
-        while (!isPortOpen(LOCALHOST, DEFAULT_JETTY_PORT)) {
-            if (stopwatch.elapsedMillis() > timeoutInMilliseconds) {
-                fail(String.format("Jetty did not start listening on port %d in less than %d milliseconds",
-                    DEFAULT_JETTY_PORT, timeoutInMilliseconds));
-            }
-
-            LOG.info("Waiting 1s for Jetty to listen on port 8181.");
-            TimeUnit.SECONDS.sleep(1);
-        }
-    }
-
-    private boolean isPortOpen(String hostname, int port) {
-        InetSocketAddress socketAddress = new InetSocketAddress(hostname, port);
-
-        Socket socket = null;
-        try {
-            socket = new Socket();
-            socket.setReuseAddress(false);
-            socket.setSoLinger(false, 1);
-            socket.setSoTimeout(TIMEOUT_IN_MILLISECONDS);
-            socket.connect(socketAddress, TIMEOUT_IN_MILLISECONDS);
-
-        } catch (IOException e) {
-            return false;
-
-        } finally {
-            if (socket != null) {
-                try {
-                    socket.close();
-                } catch (IOException ioe) {
-                    // no work to do
-                }
-            }
-        }
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/assembly-tests/src/test/java/org/apache/provisionr/karaf/CustomKarafDistributionTest.java
----------------------------------------------------------------------
diff --git a/karaf/assembly-tests/src/test/java/org/apache/provisionr/karaf/CustomKarafDistributionTest.java b/karaf/assembly-tests/src/test/java/org/apache/provisionr/karaf/CustomKarafDistributionTest.java
new file mode 100644
index 0000000..dc8b1e8
--- /dev/null
+++ b/karaf/assembly-tests/src/test/java/org/apache/provisionr/karaf/CustomKarafDistributionTest.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.karaf;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.io.CharStreams;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.URL;
+import java.util.concurrent.TimeUnit;
+import javax.inject.Inject;
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesService;
+import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.karafDistributionConfiguration;
+import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.keepRuntimeFolder;
+import static org.apache.karaf.tooling.exam.options.KarafDistributionOption.logLevel;
+import org.apache.karaf.tooling.exam.options.LogLevelOption;
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.core.templates.PoolTemplate;
+import static org.apache.provisionr.test.KarafTests.getKarafVersionAsInProject;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.ExamReactorStrategy;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.exam.options.MavenArtifactUrlReference;
+import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Run a set of tests on the custom Karaf distribution
+ */
+@RunWith(JUnit4TestRunner.class)
+@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
+public class CustomKarafDistributionTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CustomKarafDistributionTest.class);
+
+    public static final String ACTIVITI_EXPLORER_URL = "http://localhost:8181/activiti-explorer/";
+
+    public static final String RUNDECK_RESOURCE_URL = "http://localhost:8181/rundeck/machines.xml";
+
+    public static final String LOCALHOST = "localhost";
+
+    public static final int DEFAULT_JETTY_PORT = 8181;
+    public static final int TIMEOUT_IN_MILLISECONDS = 1000;
+
+    /**
+     * We are only starting Amazon by default. The support for cloudstack is not ready yet.
+     */
+    public static final int EXPECTED_NUMBER_OF_PROVISIONR_SERVICES = 1;
+
+    /**
+     * We only register two pool templates by default through the provisionr-core bundle
+     */
+    public static final int EXPECTED_NUMBER_OF_POOL_TEMPLATES = 3;
+
+    @Inject
+    private FeaturesService features;
+
+    @Inject
+    private BundleContext bundleContext;
+
+    @Configuration
+    public Option[] configuration() throws Exception {
+        MavenArtifactUrlReference distributionUrl = maven().groupId("org.apache.provisionr")
+            .artifactId("provisionr-assembly").versionAsInProject().type("tar.gz");
+
+        return new Option[]{
+            karafDistributionConfiguration()
+                .frameworkUrl(distributionUrl)
+                .karafVersion(getKarafVersionAsInProject())
+                .name("Apache Provisionr")
+                .unpackDirectory(new File("target/exam")),
+            keepRuntimeFolder(),
+            junitBundles(),
+            logLevel(LogLevelOption.LogLevel.INFO)
+        };
+    }
+
+    @Test
+    public void testAllFeaturesStartAsExpected() throws Exception {
+        assertFeatureInstalled("provisionr-all");
+
+        assertAllBundlesAreActive();
+
+        assertJettyStartsInLessThan(5000 /* milliseconds */);
+
+        assertProvisionrServicesAreStartedInLessThan(5000 /* milliseconds */);
+        assertPoolTemplatesAreRegisteredInLessThan(5000 /* milliseconds */);
+
+        assertUrlContainsInLessThan(ACTIVITI_EXPLORER_URL, "Vaadin", 10000 /* milliseconds */);
+        assertUrlContainsInLessThan(RUNDECK_RESOURCE_URL, "<project", 10000 /* milliseconds */);
+    }
+
+    private void assertUrlContainsInLessThan(
+        String url, String expectedContent, int timeoutInMilliseconds
+    ) throws InterruptedException {
+
+        final Stopwatch stopwatch = new Stopwatch().start();
+        while (true) {
+            if (stopwatch.elapsedMillis() > timeoutInMilliseconds) {
+                fail(String.format("Unable to fetch url '%s' in less than %d milliseconds",
+                    url, timeoutInMilliseconds));
+            }
+
+            try {
+                String content = CharStreams.toString(new InputStreamReader(new URL(url).openStream()));
+                assertTrue(String.format("Expected to find '%s' in: %s", expectedContent, content),
+                    content.contains(expectedContent));
+
+                break;  /* test completed as expected */
+
+            } catch (Exception e) {
+                LOG.info(String.format("Unable to fetch %s (%s). Trying again in 5s.", url, e.getMessage()));
+                TimeUnit.SECONDS.sleep(5);
+            }
+        }
+    }
+
+    private void assertProvisionrServicesAreStartedInLessThan(int timeoutInMilliseconds) throws Exception {
+        assertServicesAreStartedInLessThan(Provisionr.class,
+            EXPECTED_NUMBER_OF_PROVISIONR_SERVICES, timeoutInMilliseconds);
+    }
+
+    private void assertPoolTemplatesAreRegisteredInLessThan(int timeoutInMilliseconds) throws Exception {
+        assertServicesAreStartedInLessThan(PoolTemplate.class,
+            EXPECTED_NUMBER_OF_POOL_TEMPLATES, timeoutInMilliseconds);
+
+    }
+
+    private void assertServicesAreStartedInLessThan(
+        Class<?> klass, int expectedCardinality, int timeoutInMilliseconds
+    ) throws Exception {
+        final ServiceTracker tracker = new ServiceTracker(bundleContext, klass.getName(), null);
+        tracker.open(true);
+        try {
+            final Stopwatch stopwatch = new Stopwatch().start();
+
+            while (true) {
+                Object[] services = tracker.getServices();
+                if (services == null || services.length < expectedCardinality) {
+                    final int actualCount = (services == null) ? 0 : services.length;
+                    if (stopwatch.elapsedMillis() > timeoutInMilliseconds) {
+                        fail(String.format("Expected to find %d %s services. Found only %d in %d milliseconds",
+                            expectedCardinality, klass.getSimpleName(), actualCount, timeoutInMilliseconds));
+                    }
+
+                    LOG.info(String.format("Found %d services implementing %s. Trying again in 1s.",
+                        actualCount, klass.getName()));
+                    TimeUnit.SECONDS.sleep(1);
+
+                } else if (services.length > expectedCardinality) {
+                    fail(String.format("Expected to find %d services implementing %s. Found %d (more than expected).",
+                        expectedCardinality, klass.getName(), services.length));
+
+                } else if (services.length == expectedCardinality) {
+                    break;  /* done - the test was successful */
+                }
+            }
+
+        } finally {
+            tracker.close();
+        }
+    }
+
+    private void assertAllBundlesAreActive() {
+        for (Bundle bundle : bundleContext.getBundles()) {
+            // skip fragments, they can't be started
+            if (bundle.getHeaders().get(Constants.FRAGMENT_HOST) == null) {
+                assertEquals("Bundle " + bundle.getSymbolicName() + " is not active",
+                    Bundle.ACTIVE, bundle.getState());
+            }
+        }
+    }
+
+    private void assertFeatureInstalled(String featureName) throws Exception {
+        Feature feature = features.getFeature(featureName);
+        assertTrue("Feature " + featureName + " should be installed", features.isInstalled(feature));
+    }
+
+    private void assertJettyStartsInLessThan(int timeoutInMilliseconds) throws InterruptedException {
+        Stopwatch stopwatch = new Stopwatch().start();
+        while (!isPortOpen(LOCALHOST, DEFAULT_JETTY_PORT)) {
+            if (stopwatch.elapsedMillis() > timeoutInMilliseconds) {
+                fail(String.format("Jetty did not start listening on port %d in less than %d milliseconds",
+                    DEFAULT_JETTY_PORT, timeoutInMilliseconds));
+            }
+
+            LOG.info("Waiting 1s for Jetty to listen on port 8181.");
+            TimeUnit.SECONDS.sleep(1);
+        }
+    }
+
+    private boolean isPortOpen(String hostname, int port) {
+        InetSocketAddress socketAddress = new InetSocketAddress(hostname, port);
+
+        Socket socket = null;
+        try {
+            socket = new Socket();
+            socket.setReuseAddress(false);
+            socket.setSoLinger(false, 1);
+            socket.setSoTimeout(TIMEOUT_IN_MILLISECONDS);
+            socket.connect(socketAddress, TIMEOUT_IN_MILLISECONDS);
+
+        } catch (IOException e) {
+            return false;
+
+        } finally {
+            if (socket != null) {
+                try {
+                    socket.close();
+                } catch (IOException ioe) {
+                    // no work to do
+                }
+            }
+        }
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/assembly/pom.xml
----------------------------------------------------------------------
diff --git a/karaf/assembly/pom.xml b/karaf/assembly/pom.xml
index 831d199..50f6901 100644
--- a/karaf/assembly/pom.xml
+++ b/karaf/assembly/pom.xml
@@ -15,26 +15,27 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Custom Karaf Distribution</name>
+    <name>Apache Provisionr :: Custom Karaf Distribution</name>
     <description>Install all the features as a custom Karaf distribution</description>
     <artifactId>provisionr-assembly</artifactId>
 
     <dependencies>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-branding</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-features</artifactId>
             <scope>provided</scope>
         </dependency>
@@ -124,14 +125,14 @@
                                     mvn:org.apache.karaf.assemblies.features/enterprise/${karaf.version}/xml/features
                                 </descriptor>
                                 <descriptor>
-                                    mvn:com.axemblr.provisionr/provisionr-features/${project.version}/xml/features
+                                    mvn:org.apache.provisionr/provisionr-features/${project.version}/xml/features
                                 </descriptor>
                             </descriptors>
                             <features>
                                 <feature>config</feature>
                                 <feature>management</feature>
                                 <feature>webconsole</feature>
-                                <feature>axemblr-provisionr-all</feature>
+                                <feature>provisionr-all</feature>
                             </features>
                             <includeMvnBasedDescriptors>true</includeMvnBasedDescriptors>
                             <repository>target/features-repo</repository>
@@ -143,6 +144,7 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-assembly-plugin</artifactId>
+                <version>2.4</version>
                 <executions>
                     <execution>
                         <id>unix-bin</id>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/assembly/src/main/assembly/unix.xml
----------------------------------------------------------------------
diff --git a/karaf/assembly/src/main/assembly/unix.xml b/karaf/assembly/src/main/assembly/unix.xml
index 725264d..107b6a6 100644
--- a/karaf/assembly/src/main/assembly/unix.xml
+++ b/karaf/assembly/src/main/assembly/unix.xml
@@ -110,7 +110,7 @@
             <outputFileNameMapping>provisionr-version.jar</outputFileNameMapping>
             <fileMode>0644</fileMode>
             <includes>
-                <include>com.axemblr.provisionr:provisionr-branding</include>
+                <include>org.apache.provisionr:provisionr-branding</include>
             </includes>
             <useTransitiveDependencies>false</useTransitiveDependencies>
         </dependencySet>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/assembly/src/main/filtered-resources/etc/org.apache.karaf.features.cfg
----------------------------------------------------------------------
diff --git a/karaf/assembly/src/main/filtered-resources/etc/org.apache.karaf.features.cfg b/karaf/assembly/src/main/filtered-resources/etc/org.apache.karaf.features.cfg
index 4d20079..1349a71 100644
--- a/karaf/assembly/src/main/filtered-resources/etc/org.apache.karaf.features.cfg
+++ b/karaf/assembly/src/main/filtered-resources/etc/org.apache.karaf.features.cfg
@@ -20,9 +20,9 @@
 #
 # Comma separated list of features repositories to register by default
 #
-featuresRepositories=mvn:org.apache.karaf.assemblies.features/standard/${karaf.version}/xml/features,mvn:org.apache.karaf.assemblies.features/enterprise/${karaf.version}/xml/features,mvn:com.axemblr.provisionr/provisionr-features/${project.version}/xml/features
+featuresRepositories=mvn:org.apache.karaf.assemblies.features/standard/${karaf.version}/xml/features,mvn:org.apache.karaf.assemblies.features/enterprise/${karaf.version}/xml/features,mvn:org.apache.provisionr/provisionr-features/${project.version}/xml/features
 
 #
 # Comma separated list of features to install at startup
 #
-featuresBoot=config,management,webconsole,axemblr-provisionr-all
+featuresBoot=config,management,webconsole,provisionr-all

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/branding/pom.xml
----------------------------------------------------------------------
diff --git a/karaf/branding/pom.xml b/karaf/branding/pom.xml
index f411a24..bdac65e 100644
--- a/karaf/branding/pom.xml
+++ b/karaf/branding/pom.xml
@@ -15,16 +15,17 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Karaf Branding</name>
+    <name>Apache Provisionr :: Karaf Branding</name>
     <artifactId>provisionr-branding</artifactId>
     <packaging>bundle</packaging>
 

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/branding/src/main/resources/org/apache/karaf/branding/branding.properties
----------------------------------------------------------------------
diff --git a/karaf/branding/src/main/resources/org/apache/karaf/branding/branding.properties b/karaf/branding/src/main/resources/org/apache/karaf/branding/branding.properties
index 022710a..0482ec0 100644
--- a/karaf/branding/src/main/resources/org/apache/karaf/branding/branding.properties
+++ b/karaf/branding/src/main/resources/org/apache/karaf/branding/branding.properties
@@ -16,16 +16,20 @@
 #
 
 welcome = \
-\u001B[36m     ___                          __     __                      \u001B[0m\n\
-\u001B[36m   / _ |   __ __  ___   __ _    / /    / / ____                  \u001B[0m\n\
-\u001B[36m  / __ |   \\ \\ / / -_) /  ' \\  / _ \\  / / / __/              \u001B[0m\n\
-\u001B[36m /_/_|_|  /_\\_\\  \\__/ /_/_/_/ /_.__/ /_/ /_/                  \u001B[0m\n\
-\u001B[36m   / _ \\  ____  ___    _  __  (_) ___   (_) ___    ___    ____  \u001B[0m\n\
-\u001B[36m  / ___/ / __/ / _ \\  | |/ / / / (_-<  / / / _ \\  / _ \\  / __/\u001B[0m\n\
-\u001B[36m /_/    /_/    \\___/  |___/ /_/ /___/ /_/  \\___/ /_//_/ /_/    \u001B[0m\n\
+\u001B[36m    _                    _                          \u001B[0m\n\
+\u001B[36m   /_\\  _ __   __ _  ___| |__   ___                \u001B[0m\n\
+\u001B[36m  //_\\\\| '_ \\ / _` |/ __| '_ \\ / _ \\           \u001B[0m\n\
+\u001B[36m /  _  \\ |_) | (_| | (__| | | |  __/               \u001B[0m\n\
+\u001B[36m \\_/ \\_/ .__/ \\__,_|\\___|_| |_|\\___|           \u001B[0m\n\
+\u001B[36m       |_|                                          \u001B[0m\n\
+\u001B[36m    ___                _     _                      \u001B[0m\n\
+\u001B[36m   / _ \\_ __ _____   _(_)___(_) ___  _ __  _ __    \u001B[0m\n\
+\u001B[36m  / /_)/ '__/ _ \\ \\ / / / __| |/ _ \\| '_ \\| '__|\u001B[0m\n\
+\u001B[36m / ___/| | | (_) \\ V /| \\__ \\ | (_) | | | | |    \u001B[0m\n\
+\u001B[36m \\/    |_|  \\___/ \\_/ |_|___/_|\\___/|_| |_|_|   \u001B[0m\n\
 \n\
-\u001B[1m  Axemblr Provisionr \u001B[0m (${pom.version})\n\
-\u001B[36m  http://axemblr.com\u001B[0m\n\
+\u001B[1m  Apache Provisionr \u001B[0m (${pom.version})\n\
+\u001B[36m http://provisionr.incubator.apache.org/\u001B[0m\n\
 \n\
 Hit '\u001B[1m<tab>\u001B[0m' for a list of available commands\n\
    and '\u001B[1m[cmd] --help\u001B[0m' for help on a specific command.\n\

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/pom.xml
----------------------------------------------------------------------
diff --git a/karaf/commands/pom.xml b/karaf/commands/pom.xml
index 7e64413..87c1819 100644
--- a/karaf/commands/pom.xml
+++ b/karaf/commands/pom.xml
@@ -15,16 +15,17 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Karaf Commands</name>
+    <name>Apache Provisionr :: Karaf Commands</name>
     <artifactId>provisionr-commands</artifactId>
     <packaging>bundle</packaging>
 
@@ -42,11 +43,11 @@
             <artifactId>activiti-engine</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-core</artifactId>
         </dependency>
         <dependency>
@@ -102,7 +103,7 @@
                     <outputDirectory>${basedir}/target/classes</outputDirectory>
                     <instructions>
                         <Export-Package>
-                            com.axemblr.provisionr.commands
+                            org.apache.provisionr.commands
                         </Export-Package>
                         <Import-Package>
                             org.apache.felix.gogo.commands,

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreateCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreateCommand.java b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreateCommand.java
deleted file mode 100644
index 5072703..0000000
--- a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreateCommand.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package com.axemblr.provisionr.commands;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.commands.predicates.ProvisionrPredicates;
-import com.axemblr.provisionr.core.templates.PoolTemplate;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.io.Files;
-import com.google.common.util.concurrent.Service;
-
-import java.io.File;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import org.apache.felix.gogo.commands.Option;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
-
-public abstract class CreateCommand extends OsgiCommandSupport {
-
-    @Option(name = "--id", description = "Service ID (use provisionr:services)", required = true)
-    protected String id;
-
-    @Option(name = "--package", description = "Package to install by default (multi-valued)",
-            multiValued = true)
-    protected List<String> packages = Lists.newArrayList();
-
-    @Option(name = "-t", aliases = "--template", description = "Pre-configured template (packages, files)")
-    protected String template;
-
-    @Option(name = "--timeout", description = "Timeout in seconds for the command's initialization steps. " +
-            "If not specified, defaults to 600 seconds.")
-    protected int bootstrapTimeout = 600;
-
-    protected final List<Provisionr> services;
-
-    protected final List<PoolTemplate> templates;
-
-    public CreateCommand(List<Provisionr> services, List<PoolTemplate> templates) {
-        this.services = checkNotNull(services, "services is null");
-        this.templates = checkNotNull(templates, "templates is null");
-    }
-
-    @VisibleForTesting
-    void setId(String id) {
-        this.id = checkNotNull(id, "id is null");
-    }
-
-    @VisibleForTesting
-    void setPackages(List<String> packages) {
-        this.packages = ImmutableList.copyOf(packages);
-    }
-
-    @VisibleForTesting
-    void setTemplate(String template) {
-        this.template = checkNotNull(template, "template is null");
-    }
-
-    @VisibleForTesting
-    AdminAccess collectCurrentUserCredentialsForAdminAccess() {
-        String userHome = System.getProperty("user.home");
-
-        try {
-            String publicKey = Files.toString(new File(userHome, ".ssh/id_rsa.pub"), Charsets.UTF_8);
-            String privateKey = Files.toString(new File(userHome, ".ssh/id_rsa"), Charsets.UTF_8);
-
-            return AdminAccess.builder().username(System.getProperty("user.name"))
-                .publicKey(publicKey).privateKey(privateKey).createAdminAccess();
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    @VisibleForTesting
-    Pool applyTemplate(Pool pool) {
-        for (PoolTemplate candidate : templates) {
-            if (candidate.getId().equalsIgnoreCase(template)) {
-                return candidate.apply(pool);
-            }
-        }
-        throw new NoSuchElementException("No pool template found with name: " + template);
-    }
-
-    @VisibleForTesting
-    Network buildNetwork(List<Integer> ports) {
-        /* Always allow ICMP and ssh traffic by default */
-        return Network.builder().addRules(
-            Rule.builder().anySource().icmp().createRule(),
-            Rule.builder().anySource().tcp().port(22).createRule()
-        ).addRules(
-            formatPortsAsIngressRules(ports)
-        ).createNetwork();
-    }
-
-    Optional<Provider> getDefaultProvider(Provisionr service) {
-        checkArgument(service.getDefaultProvider().isPresent(), String.format("please configure a default provider " +
-            "by editing etc/com.axemblr.provisionr.%s.cfg", id));
-        return service.getDefaultProvider();
-    }
-
-    Provisionr getService() {
-        Optional<Provisionr> service = Iterables.tryFind(services, ProvisionrPredicates.withId(id));
-        if (!service.isPresent()) {
-            throw new NoSuchElementException("No provisioning service found with id: " + id);
-        }
-        return service.get();
-    }
-
-    private Set<Rule> formatPortsAsIngressRules(List<Integer> ports) {
-        ImmutableSet.Builder<Rule> rules = ImmutableSet.builder();
-        for (int port : ports) {
-            rules.add(Rule.builder().anySource().tcp().port(port).createRule());
-        }
-        return rules.build();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreateImageCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreateImageCommand.java b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreateImageCommand.java
deleted file mode 100644
index e5ec778..0000000
--- a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreateImageCommand.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.axemblr.provisionr.commands;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.hardware.HardwareBuilder;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.commands.predicates.ProvisionrPredicates;
-import com.axemblr.provisionr.core.templates.PoolTemplate;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import org.apache.felix.gogo.commands.Command;
-
-@Command(scope = "provisionr", name = "cache", description = "Create a cached golden image.")
-public class CreateImageCommand extends CreateCommand {
-
-    // TODO: remove this and use a provided parameter
-    private static final String HARDWARE_TYPE = "t1.micro";
-
-    public CreateImageCommand(List<Provisionr> services, List<PoolTemplate> templates) {
-        super(services, templates);
-    }
-
-    @Override
-    protected Object doExecute() throws Exception {
-        Provisionr service = getService();
-        final Pool pool = createPoolOfOne(service);
-        // TODO: create service.startCachingProcess(uuid, pool) in the Provisionr class
-        return null;
-    }
-
-    @VisibleForTesting
-    Pool createPoolOfOne(Provisionr service) {
-
-        final Software software = Software.builder().packages(packages).createSoftware();
-        final Hardware hardware = Hardware.builder().type(HARDWARE_TYPE).createHardware();
-
-        final Pool pool = Pool.builder()
-                .provider(getDefaultProvider(service).get())
-                .hardware(hardware)
-                .software(software)
-                .network(buildNetwork(new ArrayList<Integer>()))
-                .adminAccess(collectCurrentUserCredentialsForAdminAccess())
-                .minSize(1)
-                .expectedSize(1)
-                .bootstrapTimeInSeconds(bootstrapTimeout)
-                .createPool();
-
-        return template != null ? applyTemplate(pool) : pool;
-
-    }
-
-}


[17/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/pool/MachineBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/pool/MachineBuilder.java b/api/src/main/java/org/apache/provisionr/api/pool/MachineBuilder.java
new file mode 100644
index 0000000..74697e5
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/pool/MachineBuilder.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.pool;
+
+import org.apache.provisionr.api.util.BuilderWithOptions;
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class MachineBuilder extends BuilderWithOptions<MachineBuilder> {
+
+    private String externalId;
+    private String publicDnsName;
+    private String publicIp;
+    private String privateDnsName;
+    private String privateIp;
+    private int sshPort = 22;
+
+    @Override
+    protected MachineBuilder getThis() {
+        return this;
+    }
+
+    public MachineBuilder localhost() {
+        return externalId("local-1").publicDnsName("localhost").publicIp("127.0.0.1")
+            .privateDnsName("localhost").privateIp("127.0.0.1").sshPort(22);
+    }
+
+    public MachineBuilder externalId(String externalId) {
+        this.externalId = externalId;
+        return this;
+    }
+
+    public MachineBuilder publicDnsName(String publicDnsName) {
+        this.publicDnsName = publicDnsName;
+        return this;
+    }
+
+    public MachineBuilder publicIp(String publicIp) {
+        this.publicIp = publicIp;
+        return this;
+    }
+
+    public MachineBuilder privateDnsName(String privateDnsName) {
+        this.privateDnsName = privateDnsName;
+        return this;
+    }
+
+    public MachineBuilder privateIp(String privateIp) {
+        this.privateIp = privateIp;
+        return this;
+    }
+
+    public MachineBuilder sshPort(int sshPort) {
+        checkArgument(sshPort > 0 && sshPort < 65535, "invalid port number for ssh");
+        this.sshPort = sshPort;
+        return this;
+    }
+
+    public Machine createMachine() {
+        return new Machine(externalId, publicDnsName, publicIp,
+            privateDnsName, privateIp, sshPort, buildOptions());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/pool/Pool.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/pool/Pool.java b/api/src/main/java/org/apache/provisionr/api/pool/Pool.java
new file mode 100644
index 0000000..5b06c36
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/pool/Pool.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.pool;
+
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.api.util.WithOptions;
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Map;
+
+public class Pool extends WithOptions {
+
+    public static PoolBuilder builder() {
+        return new PoolBuilder();
+    }
+
+    private final Provider provider;
+    private final Network network;
+
+    private final AdminAccess adminAccess;
+    private final Software software;
+    private final Hardware hardware;
+
+    private final int minSize;
+    private final int expectedSize;
+
+    private final int bootstrapTimeInSeconds;
+
+    Pool(Provider provider, Network network, AdminAccess adminAccess, Software software, Hardware hardware,
+         int minSize, int expectedSize, int bootstrapTimeInSeconds,
+         Map<String, String> options
+    ) {
+        super(options);
+
+        checkArgument(minSize > 0, "minSize should be positive");
+        checkArgument(minSize <= expectedSize, "minSize should be smaller or equal to expectedSize");
+        checkArgument(bootstrapTimeInSeconds > 0, "bootstrapTimeInSeconds should be positive");
+
+        this.provider = checkNotNull(provider, "provider is null");
+        this.network = checkNotNull(network, "network is null");
+        this.adminAccess = checkNotNull(adminAccess, "adminAccess is null");
+        this.software = checkNotNull(software, "software is null");
+        this.hardware = checkNotNull(hardware, "hardware is null");
+        this.minSize = minSize;
+        this.expectedSize = expectedSize;
+        this.bootstrapTimeInSeconds = bootstrapTimeInSeconds;
+    }
+
+    public Provider getProvider() {
+        return provider;
+    }
+
+    public Network getNetwork() {
+        return network;
+    }
+
+    public AdminAccess getAdminAccess() {
+        return adminAccess;
+    }
+
+    public Software getSoftware() {
+        return software;
+    }
+
+    public Hardware getHardware() {
+        return hardware;
+    }
+
+    public int getMinSize() {
+        return minSize;
+    }
+
+    public int getExpectedSize() {
+        return expectedSize;
+    }
+
+    /**
+     * The maximum amount of time to go from 0 to minSize
+     */
+    public int getBootstrapTimeInSeconds() {
+        return bootstrapTimeInSeconds;
+    }
+
+    public PoolBuilder toBuilder() {
+        return builder().provider(provider).network(network).adminAccess(adminAccess).software(software)
+            .hardware(hardware).minSize(minSize).expectedSize(expectedSize)
+            .bootstrapTimeInSeconds(bootstrapTimeInSeconds).options(getOptions());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(provider, network, adminAccess, software, hardware,
+            minSize, expectedSize, bootstrapTimeInSeconds, getOptions());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final Pool other = (Pool) obj;
+        return Objects.equal(this.provider, other.provider) && Objects.equal(this.network, other.network)
+            && Objects.equal(this.adminAccess, other.adminAccess) && Objects.equal(this.software, other.software)
+            && Objects.equal(this.hardware, other.hardware) && Objects.equal(this.minSize, other.minSize)
+            && Objects.equal(this.expectedSize, other.expectedSize)
+            && Objects.equal(this.bootstrapTimeInSeconds, other.bootstrapTimeInSeconds)
+            && Objects.equal(this.getOptions(), other.getOptions());
+    }
+
+    @Override
+    public String toString() {
+        return "Pool{" +
+            "provider=" + provider +
+            ", network=" + network +
+            ", adminAccess=" + adminAccess +
+            ", software=" + software +
+            ", hardware=" + hardware +
+            ", minSize=" + minSize +
+            ", expectedSize=" + expectedSize +
+            ", bootstrapTimeInSeconds=" + bootstrapTimeInSeconds +
+            ", options=" + getOptions() +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/pool/PoolBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/pool/PoolBuilder.java b/api/src/main/java/org/apache/provisionr/api/pool/PoolBuilder.java
new file mode 100644
index 0000000..56462a6
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/pool/PoolBuilder.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.pool;
+
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.util.BuilderWithOptions;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class PoolBuilder extends BuilderWithOptions<PoolBuilder> {
+
+    private Provider provider;
+    private Network network;
+
+    private AdminAccess adminAccess;
+    private Software software;
+    private Hardware hardware;
+
+    private int minSize = -1;
+    private int expectedSize = -1;
+
+    private int bootstrapTimeInSeconds = 15 * 60;
+
+    @Override
+    protected PoolBuilder getThis() {
+        return this;
+    }
+
+    public PoolBuilder provider(Provider provider) {
+        this.provider = checkNotNull(provider, "provider is null");
+        return this;
+    }
+
+    public PoolBuilder network(Network network) {
+        this.network = checkNotNull(network, "network is null");
+        return this;
+    }
+
+    public PoolBuilder adminAccess(AdminAccess adminAccess) {
+        this.adminAccess = checkNotNull(adminAccess, "adminAccess is null");
+        return this;
+    }
+
+    public PoolBuilder software(Software software) {
+        this.software = checkNotNull(software, "software is null");
+        return this;
+    }
+
+    public PoolBuilder hardware(Hardware hardware) {
+        this.hardware = checkNotNull(hardware, "hardware is null");
+        return this;
+    }
+
+    public PoolBuilder minSize(int minSize) {
+        checkArgument(minSize > 0, "minSize should be positive");
+        this.minSize = minSize;
+        return this;
+    }
+
+    public PoolBuilder expectedSize(int expectedSize) {
+        checkArgument(expectedSize > 0, "expectedSize should be positive");
+        this.expectedSize = expectedSize;
+        return this;
+    }
+
+    public PoolBuilder bootstrapTimeInSeconds(int bootstrapTimeInSeconds) {
+        checkArgument(bootstrapTimeInSeconds > 0, "bootstrapTimeInSeconds should be positive");
+        this.bootstrapTimeInSeconds = bootstrapTimeInSeconds;
+        return this;
+    }
+
+    public Pool createPool() {
+        return new Pool(provider, network, adminAccess, software, hardware, minSize,
+            expectedSize, bootstrapTimeInSeconds, buildOptions());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/provider/Provider.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/provider/Provider.java b/api/src/main/java/org/apache/provisionr/api/provider/Provider.java
new file mode 100644
index 0000000..ab39c3e
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/provider/Provider.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.provider;
+
+import org.apache.provisionr.api.util.WithOptions;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Map;
+
+public class Provider extends WithOptions {
+
+    public static ProviderBuilder builder() {
+        return new ProviderBuilder();
+    }
+
+    private final String id;
+    private final Optional<String> endpoint;
+
+    private final String accessKey;
+    private final String secretKey;
+
+    Provider(String id, Optional<String> endpoint, String accessKey,
+             String secretKey, Map<String, String> options) {
+        super(options);
+        this.id = checkNotNull(id, "id is null");
+        this.endpoint = checkNotNull(endpoint, "endpoint is null");
+        this.accessKey = checkNotNull(accessKey, "accessKey is null");
+        this.secretKey = checkNotNull(secretKey, "secretKey is null");
+    }
+
+    /**
+     * Unique provider ID
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * API endpoint for this provider
+     */
+    public Optional<String> getEndpoint() {
+        return endpoint;
+    }
+
+    /**
+     * API access key
+     */
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    /**
+     * API secret key
+     */
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public ProviderBuilder toBuilder() {
+        return builder().id(id).endpoint(endpoint).accessKey(accessKey)
+            .secretKey(secretKey).options(getOptions());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(id, endpoint, accessKey, secretKey, getOptions());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final Provider other = (Provider) obj;
+        return Objects.equal(this.id, other.id)
+            && Objects.equal(this.endpoint, other.endpoint)
+            && Objects.equal(this.accessKey, other.accessKey)
+            && Objects.equal(this.secretKey, other.secretKey)
+            && Objects.equal(this.getOptions(), other.getOptions());
+    }
+
+    @Override
+    public String toString() {
+        return "Provider{" +
+            "id='" + id + '\'' +
+            ", endpoint='" + endpoint.or("") + '\'' +
+            ", accessKey='" + accessKey + '\'' +
+            ", options='" + getOptions() + '\'' +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/provider/ProviderBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/provider/ProviderBuilder.java b/api/src/main/java/org/apache/provisionr/api/provider/ProviderBuilder.java
new file mode 100644
index 0000000..44c1237
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/provider/ProviderBuilder.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.provider;
+
+import org.apache.provisionr.api.util.BuilderWithOptions;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class ProviderBuilder extends BuilderWithOptions<ProviderBuilder> {
+
+    private String id;
+    private Optional<String> endpoint = Optional.absent();
+    private String accessKey;
+    private String secretKey;
+
+    @Override
+    protected ProviderBuilder getThis() {
+        return this;
+    }
+
+    public ProviderBuilder id(String id) {
+        this.id = checkNotNull(id, "id is null");
+        return this;
+    }
+
+    public ProviderBuilder endpoint(Optional<String> endpoint) {
+        this.endpoint = checkNotNull(endpoint, "endpoint is null");
+        return this;
+    }
+
+    public ProviderBuilder endpoint(String endpoint) {
+        this.endpoint = Optional.of(endpoint);
+        return this;
+    }
+
+    public ProviderBuilder accessKey(String accessKey) {
+        this.accessKey = checkNotNull(accessKey, "accessKey is null");
+        return this;
+    }
+
+    public ProviderBuilder secretKey(String secretKey) {
+        this.secretKey = checkNotNull(secretKey, "secretKey is null");
+        return this;
+    }
+
+    public Provider createProvider() {
+        return new Provider(id, endpoint, accessKey, secretKey, buildOptions());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/software/Repository.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/software/Repository.java b/api/src/main/java/org/apache/provisionr/api/software/Repository.java
new file mode 100644
index 0000000..c9583f8
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/software/Repository.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.software;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableList;
+import java.io.Serializable;
+import java.util.List;
+
+public class Repository implements Serializable {
+
+    public static RepositoryBuilder builder() {
+        return new RepositoryBuilder();
+    }
+
+    private final String name;
+    private final List<String> entries;
+
+    private final Optional<String> key;
+
+    Repository(String name, List<String> entries, Optional<String> key) {
+        this.name = checkNotNull(name, "name is null");
+        this.entries = ImmutableList.copyOf(entries);
+        this.key = checkNotNull(key, "key is null");
+    }
+
+    /**
+     * The name of the repository
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * List of entries (text lines) used to describe this repository
+     */
+    public List<String> getEntries() {
+        return entries;
+    }
+
+    /**
+     * PGP key used for package signing. This should be the actual key
+     * and not a link to an external resource
+     */
+    public Optional<String> getKey() {
+        return key;
+    }
+
+    public RepositoryBuilder toBuilder() {
+        return builder().name(name).entries(entries).key(key);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(name, entries, key);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        final Repository other = (Repository) obj;
+        return Objects.equal(this.name, other.name) && Objects.equal(this.entries, other.entries)
+            && Objects.equal(this.key, other.key);
+    }
+
+    @Override
+    public String toString() {
+        return "Repository{" +
+            "name='" + name + '\'' +
+            ", entries=" + entries +
+            ", key='" + key + '\'' +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/software/RepositoryBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/software/RepositoryBuilder.java b/api/src/main/java/org/apache/provisionr/api/software/RepositoryBuilder.java
new file mode 100644
index 0000000..17ab7b6
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/software/RepositoryBuilder.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.software;
+
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+
+public class RepositoryBuilder {
+
+    private String name;
+    private ImmutableList.Builder<String> entries = ImmutableList.builder();
+
+    private Optional<String> key = Optional.absent();
+
+    public RepositoryBuilder name(String name) {
+        this.name = checkNotNull(name, "name is null");
+        return this;
+    }
+
+    public RepositoryBuilder entries(List<String> entries) {
+        this.entries = ImmutableList.<String>builder().addAll(entries);
+        return this;
+    }
+
+    public RepositoryBuilder addEntry(String entry) {
+        this.entries.add(entry);
+        return this;
+    }
+
+    public RepositoryBuilder key(Optional<String> key) {
+        this.key = checkNotNull(key, "key is null");
+        return this;
+    }
+
+    public RepositoryBuilder key(String key) {
+        this.key = Optional.of(key);
+        return this;
+    }
+
+    public Repository createRepository() {
+        return new Repository(name, entries.build(), key);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/software/Software.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/software/Software.java b/api/src/main/java/org/apache/provisionr/api/software/Software.java
new file mode 100644
index 0000000..56cc1c4
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/software/Software.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.software;
+
+import org.apache.provisionr.api.util.WithOptions;
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Define the software environment for all the machines in the pool
+ */
+public class Software extends WithOptions {
+
+    public static SoftwareBuilder builder() {
+        return new SoftwareBuilder();
+    }
+
+    private final String imageId;
+    private final boolean cachedImage;
+
+    private final Map<String, String> files;
+    private final List<String> packages;
+    private final List<Repository> repositories;
+
+    Software(String imageId, boolean cachedImage, Map<String, String> files, List<String> packages,
+             List<Repository> repositories, Map<String, String> options) {
+        super(options);
+        this.imageId = checkNotNull(imageId, "The supplied imageId was null");
+        this.cachedImage = cachedImage;
+        this.files = ImmutableMap.copyOf(files);
+        this.packages = ImmutableList.copyOf(packages);
+        this.repositories = ImmutableList.copyOf(repositories);
+    }
+
+    public String getImageId() {
+        return imageId;
+    }
+
+    public boolean isCachedImage() {
+        return cachedImage;
+    }
+
+    /**
+     * Map of remote files that need to be available on the local filesystem
+     */
+    public Map<String, String> getFiles() {
+        return files;
+    }
+
+    /**
+     * List of packages that should be installed
+     * <p/>
+     * This list can also include paths to local files
+     */
+    public List<String> getPackages() {
+        return packages;
+    }
+
+    /**
+     * List of custom repositories to add to the system before
+     * installing any packages
+     */
+    public List<Repository> getRepositories() {
+        return repositories;
+    }
+
+    public SoftwareBuilder toBuilder() {
+        return builder().imageId(imageId).files(files)
+            .packages(packages).repositories(repositories).options(getOptions());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(imageId, cachedImage, files, packages, repositories, getOptions());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final Software other = (Software) obj;
+        return Objects.equal(this.imageId, other.imageId)
+            && Objects.equal(this.cachedImage, other.cachedImage)
+            && Objects.equal(this.files, other.files)
+            && Objects.equal(this.packages, other.packages)
+            && Objects.equal(this.repositories, other.repositories)
+            && Objects.equal(this.getOptions(), other.getOptions());
+    }
+
+    @Override
+    public String toString() {
+        return "Software{" +
+            "imageId='" + imageId + '\'' +
+            ", cachedImage=" + cachedImage +
+            ", files=" + files +
+            ", packages=" + packages +
+            ", repositories=" + repositories +
+            ", options=" + getOptions() +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/software/SoftwareBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/software/SoftwareBuilder.java b/api/src/main/java/org/apache/provisionr/api/software/SoftwareBuilder.java
new file mode 100644
index 0000000..96e1e66
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/software/SoftwareBuilder.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.software;
+
+import org.apache.provisionr.api.util.BuilderWithOptions;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import java.util.Map;
+
+public class SoftwareBuilder extends BuilderWithOptions<SoftwareBuilder> {
+
+    private String imageId = "default";
+    private boolean cachedImage = false;
+
+    private ImmutableMap.Builder<String, String> files = ImmutableMap.builder();
+    private ImmutableList.Builder<String> packages = ImmutableList.builder();
+    private ImmutableList.Builder<Repository> repositories = ImmutableList.builder();
+
+    @Override
+    protected SoftwareBuilder getThis() {
+        return this;
+    }
+
+    public SoftwareBuilder imageId(String imageId) {
+        this.imageId = checkNotNull(imageId, "The imageId was null");
+        return this;
+    }
+
+    public SoftwareBuilder cachedImage(boolean cachedImage) {
+        this.cachedImage = cachedImage;
+        return this;
+    }
+
+    public SoftwareBuilder files(Map<String, String> files) {
+        this.files = ImmutableMap.<String, String>builder().putAll(files);
+        return this;
+    }
+
+    public SoftwareBuilder file(String sourceUrl, String destinationPath) {
+        this.files.put(sourceUrl, destinationPath);
+        return this;
+    }
+
+    public SoftwareBuilder packages(Iterable<String> packages) {
+        this.packages = ImmutableList.<String>builder().addAll(packages);
+        return this;
+    }
+
+    public SoftwareBuilder packages(String... packages) {
+        this.packages = ImmutableList.<String>builder().addAll(Lists.newArrayList(packages));
+        return this;
+    }
+
+    public SoftwareBuilder addPackage(String pkg) {
+        this.packages.add(pkg);
+        return this;
+    }
+
+    public SoftwareBuilder repositories(Iterable<Repository> repositories) {
+        this.repositories = ImmutableList.<Repository>builder().addAll(repositories);
+        return this;
+    }
+
+    public SoftwareBuilder repository(Repository repository) {
+        this.repositories.add(repository);
+        return this;
+    }
+
+    public Software createSoftware() {
+        return new Software(imageId, cachedImage, files.build(), packages.build(),
+            repositories.build(), buildOptions());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/util/BuilderWithOptions.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/util/BuilderWithOptions.java b/api/src/main/java/org/apache/provisionr/api/util/BuilderWithOptions.java
new file mode 100644
index 0000000..97c9012
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/util/BuilderWithOptions.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.util;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Closeables;
+import com.google.common.io.Resources;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Base class useful for creating builders for objects that accept
+ * an arbitrary map of options (key, value string pairs)
+ */
+public abstract class BuilderWithOptions<P extends BuilderWithOptions<P>> {
+
+    private ImmutableMap.Builder<String, String> options = ImmutableMap.builder();
+
+    /**
+     * Override this method to return 'this' to allow builder method chaining
+     */
+    protected abstract P getThis();
+
+    /**
+     * Replace options with the ones supplied as argument
+     */
+    public P options(Map<String, String> options) {
+        this.options = ImmutableMap.<String, String>builder().putAll(options);
+        return getThis();
+    }
+
+    /**
+     * Replace options with the ones extracted from the Properties object
+     */
+    public P options(Properties properties) {
+        this.options = ImmutableMap.builder();
+        for (String key : properties.stringPropertyNames()) {
+            options.put(key, properties.getProperty(key));
+        }
+        return getThis();
+    }
+
+    /**
+     * Load options from a properties file available as a resource on the classpath
+     */
+    public P optionsFromResource(String resource) {
+        Properties properties = new Properties();
+        ByteArrayInputStream in = null;
+        try {
+            in = new ByteArrayInputStream(Resources.toByteArray(Resources.getResource(resource)));
+            properties.load(in);
+            return options(properties);
+
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        } finally {
+            Closeables.closeQuietly(in);
+        }
+    }
+
+    /**
+     * Add a new option
+     */
+    public P option(String key, String value) {
+        this.options.put(key, value);
+        return getThis();
+    }
+
+    protected Map<String, String> buildOptions() {
+        return options.build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/util/WithOptions.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/util/WithOptions.java b/api/src/main/java/org/apache/provisionr/api/util/WithOptions.java
new file mode 100644
index 0000000..668b6c5
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/util/WithOptions.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.util;
+
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableMap;
+import java.io.Serializable;
+import java.util.Map;
+
+public abstract class WithOptions implements Serializable {
+
+    private final Map<String, String> options;
+
+    public WithOptions(Map<String, String> options) {
+        this.options = ImmutableMap.copyOf(options);
+    }
+
+    public Map<String, String> getOptions() {
+        return options;
+    }
+
+    public String getOption(String key) {
+        return options.get(checkNotNull(key, "key is null"));
+    }
+
+    public String getOptionOr(String key, String value) {
+        return Optional.fromNullable(getOption(key)).or(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/AssertSerializable.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/AssertSerializable.java b/api/src/test/java/com/axemblr/provisionr/api/AssertSerializable.java
deleted file mode 100644
index b05fccd..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/AssertSerializable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import static org.fest.assertions.api.Assertions.assertThat;
-
-/**
- * @see <a href="http://stackoverflow.com/questions/3840356" />
- */
-public class AssertSerializable {
-
-    public static <T extends Serializable> void assertSerializable(T instance, Class<T> klass) {
-        try {
-            assertThat(unpickle(pickle(instance), klass)).isEqualTo(instance);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    private static <T extends Serializable> byte[] pickle(T instance) throws IOException {
-        ByteArrayOutputStream backingStream = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(backingStream);
-        out.writeObject(instance);
-        out.close();
-        return backingStream.toByteArray();
-    }
-
-    private static <T extends Serializable> T unpickle(byte[] bytes, Class<T> klass) throws IOException, ClassNotFoundException {
-        ByteArrayInputStream backingStream = new ByteArrayInputStream(bytes);
-        ObjectInputStream in = new ObjectInputStream(backingStream);
-        Object o = in.readObject();
-        return klass.cast(o);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/access/AdminAccessTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/access/AdminAccessTest.java b/api/src/test/java/com/axemblr/provisionr/api/access/AdminAccessTest.java
deleted file mode 100644
index d89b0b8..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/access/AdminAccessTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.access;
-
-import static com.axemblr.provisionr.api.AssertSerializable.assertSerializable;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class AdminAccessTest {
-
-    @Test
-    public void testSerialization() {
-        AdminAccess adminAccess = AdminAccess.builder().username("admin").publicKey("ssh-rsa AAAAB3N")
-            .privateKey("-----BEGIN RSA PRIVATE KEY-----\n").createAdminAccess();
-
-        assertThat(adminAccess.getUsername()).isEqualTo("admin");
-        assertThat(adminAccess.toBuilder().createAdminAccess()).isEqualTo(adminAccess);
-
-        assertSerializable(adminAccess, AdminAccess.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/network/NetworkTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/network/NetworkTest.java b/api/src/test/java/com/axemblr/provisionr/api/network/NetworkTest.java
deleted file mode 100644
index 24a99f1..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/network/NetworkTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.network;
-
-import static com.axemblr.provisionr.api.AssertSerializable.assertSerializable;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class NetworkTest {
-
-    @Test
-    public void testSerialization() {
-        final Rule sshRule = Rule.builder().anySource().port(22).tcp().createRule();
-
-        Network network = Network.builder().type("default")
-            .addRules(
-                sshRule,
-                Rule.builder().anySource().port(80).tcp().createRule(),
-                Rule.builder().anySource().protocol(Protocol.ICMP).createRule())
-            .createNetwork();
-
-        assertThat(network.getType()).isEqualTo("default");
-        assertThat(network.getIngress()).contains(sshRule);
-        assertThat(network.toBuilder().createNetwork()).isEqualTo(network);
-
-        assertSerializable(network, Network.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/network/RuleTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/network/RuleTest.java b/api/src/test/java/com/axemblr/provisionr/api/network/RuleTest.java
deleted file mode 100644
index 5e1afac..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/network/RuleTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.network;
-
-import static com.axemblr.provisionr.api.AssertSerializable.assertSerializable;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class RuleTest {
-
-    @Test
-    public void testSerialization() {
-        Rule rule = Rule.builder().anySource().port(80).protocol(Protocol.UDP).createRule();
-        assertThat(rule.toBuilder().createRule()).isEqualTo(rule);
-        assertSerializable(rule, Rule.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/pool/MachineTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/pool/MachineTest.java b/api/src/test/java/com/axemblr/provisionr/api/pool/MachineTest.java
deleted file mode 100644
index 1f0e69d..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/pool/MachineTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.pool;
-
-import static com.axemblr.provisionr.api.AssertSerializable.assertSerializable;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class MachineTest {
-
-    @Test
-    public void testSerialization() {
-        final Machine machine = Machine.builder()
-            .externalId("i-12345")
-            .publicDnsName("machine1.example.com")
-            .publicIp("62.231.75.237")
-            .privateDnsName("something.internal")
-            .privateIp("10.0.3.45")
-            .option("key", "value")
-            .createMachine();
-
-        assertThat(machine.getPrivateIp()).startsWith("10.0");
-        assertThat(machine.getSshPort()).isEqualTo(22);
-        assertThat(machine.toBuilder().createMachine()).isEqualTo(machine);
-
-        assertSerializable(machine, Machine.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/pool/PoolTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/pool/PoolTest.java b/api/src/test/java/com/axemblr/provisionr/api/pool/PoolTest.java
deleted file mode 100644
index 583ce70..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/pool/PoolTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.pool;
-
-import static com.axemblr.provisionr.api.AssertSerializable.assertSerializable;
-import static org.fest.assertions.api.Assertions.assertThat;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.software.Software;
-
-import org.junit.Test;
-
-public class PoolTest {
-
-    @Test
-    public void testSerialization() {
-        final Provider provider = Provider.builder()
-            .id("amazon").accessKey("access").secretKey("secret")
-            .createProvider();
-
-        final Network network = Network.builder().addRules(
-            Rule.builder().anySource().port(22).tcp().createRule(),
-            Rule.builder().anySource().port(8088).tcp().createRule()
-        ).createNetwork();
-
-        final AdminAccess adminAccess = AdminAccess.builder().username("admin").publicKey("ssh-rsa AAAAB3N")
-            .privateKey("-----BEGIN RSA PRIVATE KEY-----\n").createAdminAccess();
-
-        final Software software = Software.builder()
-            .packages("hadoop-0.20", "hadoop-0.20-native").createSoftware();
-
-        Pool pool = Pool.builder()
-            .provider(provider)
-            .network(network)
-            .adminAccess(adminAccess)
-            .software(software)
-            .hardware(Hardware.builder().type("large").createHardware())
-            .minSize(20)
-            .expectedSize(25)
-            .bootstrapTimeInSeconds(60 * 15)
-            .createPool();
-
-
-        assertThat(pool.getSoftware().getPackages()).contains("hadoop-0.20");
-        assertThat(pool.toBuilder().createPool()).isEqualTo(pool);
-
-        assertSerializable(pool, Pool.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/provider/ProviderTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/provider/ProviderTest.java b/api/src/test/java/com/axemblr/provisionr/api/provider/ProviderTest.java
deleted file mode 100644
index 0e42626..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/provider/ProviderTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.provider;
-
-import static com.axemblr.provisionr.api.AssertSerializable.assertSerializable;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class ProviderTest {
-
-    @Test
-    public void testSerialization() {
-        Provider provider = Provider.builder()
-            .id("aws-ec2").accessKey("access").secretKey("secret")
-            .option("location", "eu-west-1").createProvider();
-
-        assertThat(provider.getAccessKey()).isEqualTo("access");
-        assertThat(provider.getOptions()).containsKey("location");
-        assertThat(provider.toBuilder().createProvider()).isEqualTo(provider);
-
-        assertSerializable(provider, Provider.class);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/software/RepositoryTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/software/RepositoryTest.java b/api/src/test/java/com/axemblr/provisionr/api/software/RepositoryTest.java
deleted file mode 100644
index 0712fd0..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/software/RepositoryTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.software;
-
-import static com.axemblr.provisionr.api.AssertSerializable.assertSerializable;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class RepositoryTest {
-
-    @Test
-    public void testSerialization() {
-        Repository repository = Repository.builder()
-            .name("bigtop")
-            .addEntry("deb http://bigtop.s3.amazonaws.com/releases/0.5.0/ubuntu/lucid/x86_64  bigtop contrib")
-            .key("-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
-                "Version: GnuPG v1.4.10 (GNU/Linux)\n" +
-                "\n" +
-                "[....]")
-            .createRepository();
-
-        assertThat(repository.toBuilder().createRepository()).isEqualTo(repository);
-        assertSerializable(repository, Repository.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/software/SoftwareTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/software/SoftwareTest.java b/api/src/test/java/com/axemblr/provisionr/api/software/SoftwareTest.java
deleted file mode 100644
index 7179ed7..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/software/SoftwareTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.software;
-
-import static com.axemblr.provisionr.api.AssertSerializable.assertSerializable;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class SoftwareTest {
-
-    @Test
-    public void testSerialization() {
-        final Repository repository = Repository.builder()
-            .name("bigtop")
-            .addEntry("deb http://bigtop.s3.amazonaws.com/releases/0.5.0/ubuntu/lucid/x86_64  bigtop contrib")
-            .key("-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
-                "Version: GnuPG v1.4.10 (GNU/Linux)\n" +
-                "\n" +
-                "[....]")
-            .createRepository();
-
-        Software software = Software.builder()
-            .imageId("default")
-            .repository(repository)
-            .packages("vim", "git-core", "bigtop-utils")
-            .file("http://bin.axemblr.com/something.tar.gz", "/root/something.tar.gz")
-            .option("provider", "specific")
-            .createSoftware();
-
-        assertThat(software.getImageId()).isEqualTo("default");
-        assertThat(software.toBuilder().createSoftware()).isEqualTo(software);
-
-        assertSerializable(software, Software.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/com/axemblr/provisionr/api/util/BuilderWithOptionsTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/axemblr/provisionr/api/util/BuilderWithOptionsTest.java b/api/src/test/java/com/axemblr/provisionr/api/util/BuilderWithOptionsTest.java
deleted file mode 100644
index acb4b1b..0000000
--- a/api/src/test/java/com/axemblr/provisionr/api/util/BuilderWithOptionsTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.util;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Properties;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class BuilderWithOptionsTest {
-
-    public static class TestBuilder extends BuilderWithOptions<TestBuilder> {
-        @Override
-        protected TestBuilder getThis() {
-            return this;
-        }
-    }
-
-    @Test
-    public void testSetOptionsFromMap() {
-        TestBuilder builder = new TestBuilder().options(ImmutableMap.of("K1", "V1", "K2", "V2"));
-        assertThat(builder.buildOptions()).containsKey("K2").containsValue("V1");
-    }
-
-    @Test
-    public void testSetSingleOption() {
-        TestBuilder builder = new TestBuilder().option("K1", "V1").option("K2", "V2");
-        assertThat(builder.buildOptions()).containsKey("K1").containsValue("V2");
-    }
-
-    @Test
-    public void testLoadOptionsFromProperties() {
-        Properties properties = new Properties();
-        properties.setProperty("K1", "V1");
-
-        TestBuilder builder = new TestBuilder().options(properties);
-        assertThat(builder.buildOptions()).containsKey("K1").containsValue("V1");
-    }
-
-    @Test
-    public void testLoadOptionsFromResource() {
-        TestBuilder builder = new TestBuilder().optionsFromResource("builder.properties");
-        assertThat(builder.buildOptions()).containsKey("key1").containsValue("value2");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/AssertSerializable.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/AssertSerializable.java b/api/src/test/java/org/apache/provisionr/api/AssertSerializable.java
new file mode 100644
index 0000000..0252c7b
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/AssertSerializable.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import static org.fest.assertions.api.Assertions.assertThat;
+
+/**
+ * @see <a href="http://stackoverflow.com/questions/3840356" />
+ */
+public class AssertSerializable {
+
+    public static <T extends Serializable> void assertSerializable(T instance, Class<T> klass) {
+        try {
+            assertThat(unpickle(pickle(instance), klass)).isEqualTo(instance);
+        } catch (Exception e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    private static <T extends Serializable> byte[] pickle(T instance) throws IOException {
+        ByteArrayOutputStream backingStream = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(backingStream);
+        out.writeObject(instance);
+        out.close();
+        return backingStream.toByteArray();
+    }
+
+    private static <T extends Serializable> T unpickle(byte[] bytes, Class<T> klass) throws IOException, ClassNotFoundException {
+        ByteArrayInputStream backingStream = new ByteArrayInputStream(bytes);
+        ObjectInputStream in = new ObjectInputStream(backingStream);
+        Object o = in.readObject();
+        return klass.cast(o);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/access/AdminAccessTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/access/AdminAccessTest.java b/api/src/test/java/org/apache/provisionr/api/access/AdminAccessTest.java
new file mode 100644
index 0000000..5972bf0
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/access/AdminAccessTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.access;
+
+import static org.apache.provisionr.api.AssertSerializable.assertSerializable;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class AdminAccessTest {
+
+    @Test
+    public void testSerialization() {
+        AdminAccess adminAccess = AdminAccess.builder().username("admin").publicKey("ssh-rsa AAAAB3N")
+            .privateKey("-----BEGIN RSA PRIVATE KEY-----\n").createAdminAccess();
+
+        assertThat(adminAccess.getUsername()).isEqualTo("admin");
+        assertThat(adminAccess.toBuilder().createAdminAccess()).isEqualTo(adminAccess);
+
+        assertSerializable(adminAccess, AdminAccess.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/network/NetworkTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/network/NetworkTest.java b/api/src/test/java/org/apache/provisionr/api/network/NetworkTest.java
new file mode 100644
index 0000000..acf7cf4
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/network/NetworkTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.network;
+
+import static org.apache.provisionr.api.AssertSerializable.assertSerializable;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class NetworkTest {
+
+    @Test
+    public void testSerialization() {
+        final Rule sshRule = Rule.builder().anySource().port(22).tcp().createRule();
+
+        Network network = Network.builder().type("default")
+            .addRules(
+                sshRule,
+                Rule.builder().anySource().port(80).tcp().createRule(),
+                Rule.builder().anySource().protocol(Protocol.ICMP).createRule())
+            .createNetwork();
+
+        assertThat(network.getType()).isEqualTo("default");
+        assertThat(network.getIngress()).contains(sshRule);
+        assertThat(network.toBuilder().createNetwork()).isEqualTo(network);
+
+        assertSerializable(network, Network.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/network/RuleTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/network/RuleTest.java b/api/src/test/java/org/apache/provisionr/api/network/RuleTest.java
new file mode 100644
index 0000000..b212292
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/network/RuleTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.network;
+
+import static org.apache.provisionr.api.AssertSerializable.assertSerializable;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class RuleTest {
+
+    @Test
+    public void testSerialization() {
+        Rule rule = Rule.builder().anySource().port(80).protocol(Protocol.UDP).createRule();
+        assertThat(rule.toBuilder().createRule()).isEqualTo(rule);
+        assertSerializable(rule, Rule.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/pool/MachineTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/pool/MachineTest.java b/api/src/test/java/org/apache/provisionr/api/pool/MachineTest.java
new file mode 100644
index 0000000..18e764c
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/pool/MachineTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.pool;
+
+import static org.apache.provisionr.api.AssertSerializable.assertSerializable;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class MachineTest {
+
+    @Test
+    public void testSerialization() {
+        final Machine machine = Machine.builder()
+            .externalId("i-12345")
+            .publicDnsName("machine1.example.com")
+            .publicIp("62.231.75.237")
+            .privateDnsName("something.internal")
+            .privateIp("10.0.3.45")
+            .option("key", "value")
+            .createMachine();
+
+        assertThat(machine.getPrivateIp()).startsWith("10.0");
+        assertThat(machine.getSshPort()).isEqualTo(22);
+        assertThat(machine.toBuilder().createMachine()).isEqualTo(machine);
+
+        assertSerializable(machine, Machine.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/pool/PoolTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/pool/PoolTest.java b/api/src/test/java/org/apache/provisionr/api/pool/PoolTest.java
new file mode 100644
index 0000000..3c83d31
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/pool/PoolTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.pool;
+
+import static org.apache.provisionr.api.AssertSerializable.assertSerializable;
+import static org.fest.assertions.api.Assertions.assertThat;
+
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.software.Software;
+
+import org.junit.Test;
+
+public class PoolTest {
+
+    @Test
+    public void testSerialization() {
+        final Provider provider = Provider.builder()
+            .id("amazon").accessKey("access").secretKey("secret")
+            .createProvider();
+
+        final Network network = Network.builder().addRules(
+            Rule.builder().anySource().port(22).tcp().createRule(),
+            Rule.builder().anySource().port(8088).tcp().createRule()
+        ).createNetwork();
+
+        final AdminAccess adminAccess = AdminAccess.builder().username("admin").publicKey("ssh-rsa AAAAB3N")
+            .privateKey("-----BEGIN RSA PRIVATE KEY-----\n").createAdminAccess();
+
+        final Software software = Software.builder()
+            .packages("hadoop-0.20", "hadoop-0.20-native").createSoftware();
+
+        Pool pool = Pool.builder()
+            .provider(provider)
+            .network(network)
+            .adminAccess(adminAccess)
+            .software(software)
+            .hardware(Hardware.builder().type("large").createHardware())
+            .minSize(20)
+            .expectedSize(25)
+            .bootstrapTimeInSeconds(60 * 15)
+            .createPool();
+
+
+        assertThat(pool.getSoftware().getPackages()).contains("hadoop-0.20");
+        assertThat(pool.toBuilder().createPool()).isEqualTo(pool);
+
+        assertSerializable(pool, Pool.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/provider/ProviderTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/provider/ProviderTest.java b/api/src/test/java/org/apache/provisionr/api/provider/ProviderTest.java
new file mode 100644
index 0000000..0e43d2d
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/provider/ProviderTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.provider;
+
+import static org.apache.provisionr.api.AssertSerializable.assertSerializable;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class ProviderTest {
+
+    @Test
+    public void testSerialization() {
+        Provider provider = Provider.builder()
+            .id("aws-ec2").accessKey("access").secretKey("secret")
+            .option("location", "eu-west-1").createProvider();
+
+        assertThat(provider.getAccessKey()).isEqualTo("access");
+        assertThat(provider.getOptions()).containsKey("location");
+        assertThat(provider.toBuilder().createProvider()).isEqualTo(provider);
+
+        assertSerializable(provider, Provider.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/software/RepositoryTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/software/RepositoryTest.java b/api/src/test/java/org/apache/provisionr/api/software/RepositoryTest.java
new file mode 100644
index 0000000..69009b1
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/software/RepositoryTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.software;
+
+import static org.apache.provisionr.api.AssertSerializable.assertSerializable;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class RepositoryTest {
+
+    @Test
+    public void testSerialization() {
+        Repository repository = Repository.builder()
+            .name("bigtop")
+            .addEntry("deb http://bigtop.s3.amazonaws.com/releases/0.5.0/ubuntu/lucid/x86_64  bigtop contrib")
+            .key("-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
+                "Version: GnuPG v1.4.10 (GNU/Linux)\n" +
+                "\n" +
+                "[....]")
+            .createRepository();
+
+        assertThat(repository.toBuilder().createRepository()).isEqualTo(repository);
+        assertSerializable(repository, Repository.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/software/SoftwareTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/software/SoftwareTest.java b/api/src/test/java/org/apache/provisionr/api/software/SoftwareTest.java
new file mode 100644
index 0000000..10f125b
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/software/SoftwareTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.software;
+
+import static org.apache.provisionr.api.AssertSerializable.assertSerializable;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class SoftwareTest {
+
+    @Test
+    public void testSerialization() {
+        final Repository repository = Repository.builder()
+            .name("bigtop")
+            .addEntry("deb http://bigtop.s3.amazonaws.com/releases/0.5.0/ubuntu/lucid/x86_64  bigtop contrib")
+            .key("-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
+                "Version: GnuPG v1.4.10 (GNU/Linux)\n" +
+                "\n" +
+                "[....]")
+            .createRepository();
+
+        Software software = Software.builder()
+            .imageId("default")
+            .repository(repository)
+            .packages("vim", "git-core", "bigtop-utils")
+            .file("http://provisionr.incubator.apache.org/something.tar.gz", "/root/something.tar.gz")
+            .option("provider", "specific")
+            .createSoftware();
+
+        assertThat(software.getImageId()).isEqualTo("default");
+        assertThat(software.toBuilder().createSoftware()).isEqualTo(software);
+
+        assertSerializable(software, Software.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/test/java/org/apache/provisionr/api/util/BuilderWithOptionsTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/provisionr/api/util/BuilderWithOptionsTest.java b/api/src/test/java/org/apache/provisionr/api/util/BuilderWithOptionsTest.java
new file mode 100644
index 0000000..95f37f3
--- /dev/null
+++ b/api/src/test/java/org/apache/provisionr/api/util/BuilderWithOptionsTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.util;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.Properties;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class BuilderWithOptionsTest {
+
+    public static class TestBuilder extends BuilderWithOptions<TestBuilder> {
+        @Override
+        protected TestBuilder getThis() {
+            return this;
+        }
+    }
+
+    @Test
+    public void testSetOptionsFromMap() {
+        TestBuilder builder = new TestBuilder().options(ImmutableMap.of("K1", "V1", "K2", "V2"));
+        assertThat(builder.buildOptions()).containsKey("K2").containsValue("V1");
+    }
+
+    @Test
+    public void testSetSingleOption() {
+        TestBuilder builder = new TestBuilder().option("K1", "V1").option("K2", "V2");
+        assertThat(builder.buildOptions()).containsKey("K1").containsValue("V2");
+    }
+
+    @Test
+    public void testLoadOptionsFromProperties() {
+        Properties properties = new Properties();
+        properties.setProperty("K1", "V1");
+
+        TestBuilder builder = new TestBuilder().options(properties);
+        assertThat(builder.buildOptions()).containsKey("K1").containsValue("V1");
+    }
+
+    @Test
+    public void testLoadOptionsFromResource() {
+        TestBuilder builder = new TestBuilder().optionsFromResource("builder.properties");
+        assertThat(builder.buildOptions()).containsKey("key1").containsValue("value2");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/console/pom.xml
----------------------------------------------------------------------
diff --git a/console/pom.xml b/console/pom.xml
index c0d08d3..14bee96 100644
--- a/console/pom.xml
+++ b/console/pom.xml
@@ -15,16 +15,17 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <parent>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <artifactId>provisionr-parent</artifactId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Web Console &amp; REST API</name>
+    <name>Apache Provisionr :: Web Console &amp; REST API</name>
     <description>A basic web console and a REST API</description>
 
     <artifactId>provisionr-console</artifactId>
@@ -32,11 +33,11 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-core</artifactId>
         </dependency>
     </dependencies>
@@ -74,7 +75,7 @@
                                     <classifier>features</classifier>
                                 </artifact>
                                 <artifact>
-                                    <file>${project.build.directory}/classes/com.axemblr.provisionr.console.cfg</file>
+                                    <file>${project.build.directory}/classes/org.apache.provisionr.console.cfg</file>
                                     <type>cfg</type>
                                     <classifier>defaults</classifier>
                                 </artifact>
@@ -100,7 +101,7 @@
                                 <descriptor>file:${project.build.directory}/classes/features.xml</descriptor>
                             </descriptors>
                             <features>
-                                <feature>axemblr-provisionr-console</feature>
+                                <feature>provisionr-console</feature>
                             </features>
                             <repository>target/features-repo</repository>
                         </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/console/src/main/java/com/axemblr/provisionr/client/ProvisionrClient.java
----------------------------------------------------------------------
diff --git a/console/src/main/java/com/axemblr/provisionr/client/ProvisionrClient.java b/console/src/main/java/com/axemblr/provisionr/client/ProvisionrClient.java
deleted file mode 100644
index 03be678..0000000
--- a/console/src/main/java/com/axemblr/provisionr/client/ProvisionrClient.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.client;
-
-import com.axemblr.provisionr.api.Provisionr;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.List;
-
-public class ProvisionrClient {
-
-    private final List<Provisionr> services;
-
-    public ProvisionrClient(List<Provisionr> services) {
-        this.services = checkNotNull(services, "services is null");
-    }
-
-    public List<Provisionr> getServices() {
-        return services;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/console/src/main/java/org/apache/provisionr/client/ProvisionrClient.java
----------------------------------------------------------------------
diff --git a/console/src/main/java/org/apache/provisionr/client/ProvisionrClient.java b/console/src/main/java/org/apache/provisionr/client/ProvisionrClient.java
new file mode 100644
index 0000000..64ca3d6
--- /dev/null
+++ b/console/src/main/java/org/apache/provisionr/client/ProvisionrClient.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.client;
+
+import org.apache.provisionr.api.Provisionr;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.List;
+
+public class ProvisionrClient {
+
+    private final List<Provisionr> services;
+
+    public ProvisionrClient(List<Provisionr> services) {
+        this.services = checkNotNull(services, "services is null");
+    }
+
+    public List<Provisionr> getServices() {
+        return services;
+    }
+}


[06/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/ubuntu.csv
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/org/apache/provisionr/amazon/ubuntu.csv b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/ubuntu.csv
new file mode 100644
index 0000000..1751b94
--- /dev/null
+++ b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/ubuntu.csv
@@ -0,0 +1,221 @@
+region, name, version, arch, type, release, ami-id, aki-id
+ap-northeast-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-087bc509, aki-d409a2d5
+ap-northeast-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-067bc507, aki-d209a2d3
+ap-northeast-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-e67ac4e7, aki-d409a2d5
+ap-northeast-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-8c7ac48d, aki-d209a2d3
+ap-southeast-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-240e4d76, aki-11d5aa43
+ap-southeast-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-260e4d74, aki-13d5aa41
+ap-southeast-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-220e4d70, aki-11d5aa43
+ap-southeast-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-180e4d4a, aki-13d5aa41
+eu-west-1, natty, 11.04 EOL, amd64, hvm, 20121028, ami-7b14170f, hvm
+eu-west-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-7914170d, aki-4feec43b
+eu-west-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-7f14170b, aki-4deec439
+eu-west-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-d71516a3, aki-4feec43b
+eu-west-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-23151657, aki-4deec439
+sa-east-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-d0548dcd, aki-d63ce3cb
+sa-east-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-d6548dcb, aki-863ce39b
+sa-east-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-a2548dbf, aki-d63ce3cb
+sa-east-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-b6548dab, aki-863ce39b
+us-east-1, natty, 11.04 EOL, amd64, hvm, 20121028, ami-beb10ad7, hvm
+us-east-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-bab10ad3, aki-427d952b
+us-east-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-a6b10acf, aki-407d9529
+us-east-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-1cb30875, aki-427d952b
+us-east-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-96b803ff, aki-407d9529
+us-west-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-132c0a56, aki-9ba0f1de
+us-west-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-112c0a54, aki-99a0f1dc
+us-west-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-712c0a34, aki-9ba0f1de
+us-west-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-b12f09f4, aki-99a0f1dc
+us-west-2, natty, 11.04 EOL, amd64, hvm, 20121028, ami-70b23b40, hvm
+us-west-2, natty, 11.04 EOL, amd64, ebs, 20121028, ami-0eb23b3e, aki-ace26f9c
+us-west-2, natty, 11.04 EOL, i386, ebs, 20121028, ami-0ab23b3a, aki-dce26fec
+us-west-2, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-3ab23b0a, aki-ace26f9c
+us-west-2, natty, 11.04 EOL, i386, instance-store, 20121028, ami-a2b33a92, aki-dce26fec
+ap-northeast-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-8876ca89, aki-d409a2d5
+ap-northeast-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-8676ca87, aki-d209a2d3
+ap-northeast-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-6c76ca6d, aki-d409a2d5
+ap-northeast-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-2676ca27, aki-d209a2d3
+ap-southeast-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-903575c2, aki-11d5aa43
+ap-southeast-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-923575c0, aki-13d5aa41
+ap-southeast-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-ec3575be, aki-11d5aa43
+ap-southeast-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-fe3575ac, aki-13d5aa41
+ap-southeast-2, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-9b8611a1, aki-31990e0b
+ap-southeast-2, lucid, 10.04 LTS, i386, ebs, 20120913, ami-a786119d, aki-33990e09
+ap-southeast-2, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-af861195, aki-31990e0b
+ap-southeast-2, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-49861173, aki-33990e09
+eu-west-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-5d4a4b29, aki-4feec43b
+eu-west-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-534a4b27, aki-4deec439
+eu-west-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-794a4b0d, aki-4feec43b
+eu-west-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-8f4b4afb, aki-4deec439
+sa-east-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-6ac91077, aki-d63ce3cb
+sa-east-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-68c91075, aki-863ce39b
+sa-east-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-6ec91073, aki-d63ce3cb
+sa-east-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-7ec91063, aki-863ce39b
+us-east-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-c7b202ae, aki-427d952b
+us-east-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-c5b202ac, aki-407d9529
+us-east-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-1db20274, aki-427d952b
+us-east-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-53b2023a, aki-407d9529
+us-west-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-bb88acfe, aki-9ba0f1de
+us-west-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-b988acfc, aki-99a0f1dc
+us-west-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-bd88acf8, aki-9ba0f1de
+us-west-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-a188ace4, aki-99a0f1dc
+us-west-2, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-1a4fc12a, aki-ace26f9c
+us-west-2, lucid, 10.04 LTS, i386, ebs, 20120913, ami-184fc128, aki-dce26fec
+us-west-2, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-3e4fc10e, aki-ace26f9c
+us-west-2, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-304fc100, aki-dce26fec
+ap-northeast-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-d669d6d7, aki-d069d6d1
+ap-northeast-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-ca69d6cb, aki-c469d6c5
+ap-southeast-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-f4a8e8a6, aki-f2a8e8a0
+ap-southeast-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-cca8e89e, aki-c0a8e892
+eu-west-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-897575fd, aki-877575f3
+eu-west-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-917575e5, aki-a97575dd
+sa-east-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-7008d16d, aki-7e08d163
+sa-east-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-4208d15f, aki-4a08d157
+us-east-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-3c229e55, aki-5e229e37
+us-east-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-6c229e05, aki-9c219df5
+us-west-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-3ff8df7a, aki-37f8df72
+us-west-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-2ff8df6a, aki-25f8df60
+us-west-2, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-dc31bfec, aki-d631bfe6
+us-west-2, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-ea31bfda, aki-e231bfd2
+ap-northeast-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-741dac75, aki-d409a2d5
+ap-northeast-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-721dac73, aki-d209a2d3
+ap-northeast-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-701dac71, aki-d409a2d5
+ap-northeast-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-641dac65, aki-d209a2d3
+ap-southeast-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-0e8acd5c, aki-11d5aa43
+ap-southeast-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-0a8acd58, aki-13d5aa41
+ap-southeast-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-1a8acd48, aki-11d5aa43
+ap-southeast-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-608acd32, aki-13d5aa41
+eu-west-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-c57942b1, aki-4feec43b
+eu-west-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-db7942af, aki-4deec439
+eu-west-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-df7942ab, aki-4feec43b
+eu-west-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-d57942a1, aki-4deec439
+sa-east-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-10a9770d, aki-d63ce3cb
+sa-east-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-16a9770b, aki-863ce39b
+sa-east-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-1aa97707, aki-d63ce3cb
+sa-east-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-1ea97703, aki-863ce39b
+us-east-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-d78f57be, aki-427d952b
+us-east-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-d38f57ba, aki-407d9529
+us-east-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-098f5760, aki-427d952b
+us-east-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-7b8f5712, aki-407d9529
+us-west-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-3b154e7e, aki-9ba0f1de
+us-west-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-39154e7c, aki-99a0f1dc
+us-west-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-2b154e6e, aki-9ba0f1de
+us-west-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-1d154e58, aki-99a0f1dc
+us-west-2, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-64fd7154, aki-ace26f9c
+us-west-2, maverick, 10.10 EOL, i386, ebs, 20120410, ami-62fd7152, aki-dce26fec
+us-west-2, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-7efd714e, aki-ace26f9c
+us-west-2, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-76fd7146, aki-dce26fec
+ap-northeast-1, oneiric, 11.10, amd64, ebs, 20120918, ami-9405b995, aki-ee5df7ef
+ap-northeast-1, oneiric, 11.10, i386, ebs, 20120918, ami-9205b993, aki-ec5df7ed
+ap-northeast-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-8005b981, aki-ee5df7ef
+ap-northeast-1, oneiric, 11.10, i386, instance-store, 20120918, ami-6a05b96b, aki-ec5df7ed
+ap-southeast-1, oneiric, 11.10, amd64, ebs, 20120918, ami-a86424fa, aki-aa225af8
+ap-southeast-1, oneiric, 11.10, i386, ebs, 20120918, ami-aa6424f8, aki-a4225af6
+ap-southeast-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-a46424f6, aki-aa225af8
+ap-southeast-1, oneiric, 11.10, i386, instance-store, 20120918, ami-a26424f0, aki-a4225af6
+ap-southeast-2, oneiric, 11.10, amd64, ebs, 20120918, ami-818611bb, aki-31990e0b
+ap-southeast-2, oneiric, 11.10, i386, ebs, 20120918, ami-838611b9, aki-33990e09
+ap-southeast-2, oneiric, 11.10, amd64, instance-store, 20120918, ami-5186116b, aki-31990e0b
+ap-southeast-2, oneiric, 11.10, i386, instance-store, 20120918, ami-5d861167, aki-33990e09
+eu-west-1, oneiric, 11.10, amd64, hvm, 20120918, ami-3fcacb4b, hvm
+eu-west-1, oneiric, 11.10, amd64, ebs, 20120918, ami-3dcacb49, aki-62695816
+eu-west-1, oneiric, 11.10, i386, ebs, 20120918, ami-33cacb47, aki-64695810
+eu-west-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-41cacb35, aki-62695816
+eu-west-1, oneiric, 11.10, i386, instance-store, 20120918, ami-6fcacb1b, aki-64695810
+sa-east-1, oneiric, 11.10, amd64, ebs, 20120918, ami-00f22b1d, aki-cc3ce3d1
+sa-east-1, oneiric, 11.10, i386, ebs, 20120918, ami-06f22b1b, aki-bc3ce3a1
+sa-east-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-08f22b15, aki-cc3ce3d1
+sa-east-1, oneiric, 11.10, i386, instance-store, 20120918, ami-10f22b0d, aki-bc3ce3a1
+us-east-1, oneiric, 11.10, amd64, hvm, 20120918, ami-cfc072a6, hvm
+us-east-1, oneiric, 11.10, amd64, ebs, 20120918, ami-cdc072a4, aki-825ea7eb
+us-east-1, oneiric, 11.10, i386, ebs, 20120918, ami-cbc072a2, aki-805ea7e9
+us-east-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-35c0725c, aki-825ea7eb
+us-east-1, oneiric, 11.10, i386, instance-store, 20120918, ami-71c07218, aki-805ea7e9
+us-west-1, oneiric, 11.10, amd64, ebs, 20120918, ami-fb5176be, aki-8d396bc8
+us-west-1, oneiric, 11.10, i386, ebs, 20120918, ami-ff5176ba, aki-83396bc6
+us-west-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-e95176ac, aki-8d396bc8
+us-west-1, oneiric, 11.10, i386, instance-store, 20120918, ami-d951769c, aki-83396bc6
+us-west-2, oneiric, 11.10, amd64, hvm, 20120918, ami-b67af486, hvm
+us-west-2, oneiric, 11.10, amd64, ebs, 20120918, ami-b47af484, aki-98e26fa8
+us-west-2, oneiric, 11.10, i386, ebs, 20120918, ami-b27af482, aki-c2e26ff2
+us-west-2, oneiric, 11.10, amd64, instance-store, 20120918, ami-4a7af47a, aki-98e26fa8
+us-west-2, oneiric, 11.10, i386, instance-store, 20120918, ami-447af474, aki-c2e26ff2
+ap-northeast-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-2a0fa42b, aki-260fa427
+ap-northeast-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-240fa425, aki-0a0fa40b
+ap-southeast-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-90344ac2, aki-ec344abe
+ap-southeast-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-e6344ab4, aki-e2344ab0
+eu-west-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-28b9935c, aki-20b99354
+eu-west-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-24b99350, aki-34b99340
+us-east-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-6832d801, aki-1c3dd775
+us-east-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-563dd73f, aki-c43cd6ad
+us-west-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-0af0a14f, aki-68f0a12d
+us-west-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-6ef0a12b, aki-5af0a11f
+ap-northeast-1, quantal, 12.10, amd64, ebs, 20121017, ami-3c07b83d, aki-ee5df7ef
+ap-northeast-1, quantal, 12.10, i386, ebs, 20121017, ami-3a07b83b, aki-ec5df7ed
+ap-northeast-1, quantal, 12.10, amd64, instance-store, 20121017, ami-0407b805, aki-ee5df7ef
+ap-northeast-1, quantal, 12.10, i386, instance-store, 20121017, ami-7008b771, aki-ec5df7ed
+ap-southeast-1, quantal, 12.10, amd64, ebs, 20121017, ami-8ed393dc, aki-aa225af8
+ap-southeast-1, quantal, 12.10, i386, ebs, 20121017, ami-88d393da, aki-a4225af6
+ap-southeast-1, quantal, 12.10, amd64, instance-store, 20121017, ami-e6d393b4, aki-aa225af8
+ap-southeast-1, quantal, 12.10, i386, instance-store, 20121017, ami-28d3937a, aki-a4225af6
+ap-southeast-2, quantal, 12.10, amd64, ebs, 20121017, ami-df8611e5, aki-31990e0b
+ap-southeast-2, quantal, 12.10, i386, ebs, 20121017, ami-d98611e3, aki-33990e09
+ap-southeast-2, quantal, 12.10, amd64, instance-store, 20121017, ami-db8611e1, aki-31990e0b
+ap-southeast-2, quantal, 12.10, i386, instance-store, 20121017, ami-e38611d9, aki-33990e09
+eu-west-1, quantal, 12.10, amd64, hvm, 20121017, ami-ebeded9f, hvm
+eu-west-1, quantal, 12.10, amd64, ebs, 20121017, ami-e9eded9d, aki-62695816
+eu-west-1, quantal, 12.10, i386, ebs, 20121017, ami-efeded9b, aki-64695810
+eu-west-1, quantal, 12.10, amd64, instance-store, 20121017, ami-69eded1d, aki-62695816
+eu-west-1, quantal, 12.10, i386, instance-store, 20121017, ami-b5ececc1, aki-64695810
+sa-east-1, quantal, 12.10, amd64, ebs, 20121017, ami-cc30e9d1, aki-cc3ce3d1
+sa-east-1, quantal, 12.10, i386, ebs, 20121017, ami-d230e9cf, aki-bc3ce3a1
+sa-east-1, quantal, 12.10, amd64, instance-store, 20121017, ami-d030e9cd, aki-cc3ce3d1
+sa-east-1, quantal, 12.10, i386, instance-store, 20121017, ami-b230e9af, aki-bc3ce3a1
+us-east-1, quantal, 12.10, amd64, hvm, 20121017, ami-9665dbff, hvm
+us-east-1, quantal, 12.10, amd64, ebs, 20121017, ami-9465dbfd, aki-825ea7eb
+us-east-1, quantal, 12.10, i386, ebs, 20121017, ami-9265dbfb, aki-805ea7e9
+us-east-1, quantal, 12.10, amd64, instance-store, 20121017, ami-e864da81, aki-825ea7eb
+us-east-1, quantal, 12.10, i386, instance-store, 20121017, ami-dc66d8b5, aki-805ea7e9
+us-west-1, quantal, 12.10, amd64, ebs, 20121017, ami-8f83a4ca, aki-8d396bc8
+us-west-1, quantal, 12.10, i386, ebs, 20121017, ami-8d83a4c8, aki-83396bc6
+us-west-1, quantal, 12.10, amd64, instance-store, 20121017, ami-fd83a4b8, aki-8d396bc8
+us-west-1, quantal, 12.10, i386, instance-store, 20121017, ami-0983a44c, aki-83396bc6
+us-west-2, quantal, 12.10, amd64, hvm, 20121017, ami-42f97072, hvm
+us-west-2, quantal, 12.10, amd64, ebs, 20121017, ami-40f97070, aki-98e26fa8
+us-west-2, quantal, 12.10, i386, ebs, 20121017, ami-5ef9706e, aki-c2e26ff2
+us-west-2, quantal, 12.10, amd64, instance-store, 20121017, ami-50f97060, aki-98e26fa8
+us-west-2, quantal, 12.10, i386, instance-store, 20121017, ami-00f97030, aki-c2e26ff2
+ap-northeast-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-eca719ed, aki-ee5df7ef
+ap-northeast-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-eaa719eb, aki-ec5df7ed
+ap-northeast-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-e0a719e1, aki-ee5df7ef
+ap-northeast-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-aca719ad, aki-ec5df7ed
+ap-southeast-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-fefcbcac, aki-aa225af8
+ap-southeast-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-f8fcbcaa, aki-a4225af6
+ap-southeast-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-fafcbca8, aki-aa225af8
+ap-southeast-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-d4fcbc86, aki-a4225af6
+ap-southeast-2, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-fb8611c1, aki-31990e0b
+ap-southeast-2, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-858611bf, aki-33990e09
+ap-southeast-2, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-cf8710f5, aki-31990e0b
+ap-southeast-2, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-898710b3, aki-33990e09
+eu-west-1, precise, 12.04 LTS, amd64, hvm, 20121026.1, ami-25656651, hvm
+eu-west-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-3b65664f, aki-62695816
+eu-west-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-3965664d, aki-64695810
+eu-west-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-a16665d5, aki-62695816
+eu-west-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-2966655d, aki-64695810
+sa-east-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-b45b82a9, aki-cc3ce3d1
+sa-east-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-ba5b82a7, aki-bc3ce3a1
+sa-east-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-805b829d, aki-cc3ce3d1
+sa-east-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-945b8289, aki-bc3ce3a1
+us-east-1, precise, 12.04 LTS, amd64, hvm, 20121026.1, ami-9078c0f9, hvm
+us-east-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-9c78c0f5, aki-825ea7eb
+us-east-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-9878c0f1, aki-805ea7e9
+us-east-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-9a873ff3, aki-825ea7eb
+us-east-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-52863e3b, aki-805ea7e9
+us-west-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-bb4f69fe, aki-8d396bc8
+us-west-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-b94f69fc, aki-83396bc6
+us-west-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-a34f69e6, aki-8d396bc8
+us-west-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-e34f69a6, aki-83396bc6
+us-west-2, precise, 12.04 LTS, amd64, hvm, 20121026.1, ami-60ab2250, hvm
+us-west-2, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-7eab224e, aki-98e26fa8
+us-west-2, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-7cab224c, aki-c2e26ff2
+us-west-2, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-1aab222a, aki-98e26fa8
+us-west-2, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-3aab220a, aki-c2e26ff2

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/userdata.sh
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/org/apache/provisionr/amazon/userdata.sh b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/userdata.sh
new file mode 100644
index 0000000..9009fd6
--- /dev/null
+++ b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/userdata.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+set -e -x
+export DEBIAN_FRONTEND=noninteractive
+
+# adds the distribution codename as a shell var
+. /etc/lsb-release
+
+# add the puppet package repository
+wget http://apt.puppetlabs.com/puppetlabs-release-$DISTRIB_CODENAME.deb
+dpkg -i puppetlabs-release-$DISTRIB_CODENAME.deb
+
+apt-get update
+apt-get install -y puppet-common
+
+# TODO implement a special action for global package upgrades 
+# apt-get upgrade -y
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/ProcessDefinitionSyntaxCheckTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/ProcessDefinitionSyntaxCheckTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/ProcessDefinitionSyntaxCheckTest.java
deleted file mode 100644
index a23ffab..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/ProcessDefinitionSyntaxCheckTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon;
-
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.ProcessEngineConfiguration;
-import org.activiti.engine.repository.Deployment;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ProcessDefinitionSyntaxCheckTest {
-
-    private ProcessEngine processEngine;
-
-    @Before
-    public void setUp() {
-        processEngine = ProcessEngineConfiguration
-            .createStandaloneInMemProcessEngineConfiguration().buildProcessEngine();
-    }
-
-    @After
-    public void tearDown() {
-        processEngine.close();
-    }
-
-    @Test
-    public void testDeployment() {
-        assertCanBeDeployed("OSGI-INF/activiti/amazonPoolManagement.bpmn20.xml");
-        assertCanBeDeployed("OSGI-INF/activiti/amazonMachineSetup.bpmn20.xml");
-    }
-
-    private void assertCanBeDeployed(String resource) {
-        Deployment deployment = processEngine.getRepositoryService().createDeployment()
-            .addClasspathResource(resource).deploy();
-
-        assertThat(deployment).isNotNull();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/AmazonActivityLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/AmazonActivityLiveTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/AmazonActivityLiveTest.java
deleted file mode 100644
index e0f8f56..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/AmazonActivityLiveTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DeleteSecurityGroupRequest;
-import com.axemblr.provisionr.amazon.AmazonProvisionr;
-import com.axemblr.provisionr.amazon.options.ProviderOptions;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.amazon.core.ProviderClientCacheSupplier;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.test.Generics;
-import com.axemblr.provisionr.test.ProvisionrLiveTestSupport;
-import com.google.common.base.Throwables;
-import java.lang.reflect.Constructor;
-import java.util.UUID;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.junit.After;
-import org.junit.Before;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AmazonActivityLiveTest<T extends AmazonActivity> extends ProvisionrLiveTestSupport {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AmazonActivityLiveTest.class);
-
-    protected final String BUSINESS_KEY = "j-" + UUID.randomUUID().toString();
-
-    /**
-     * Cloud provider credentials collected from system properties
-     */
-    protected Provider provider;
-
-    /**
-     * Instance of the AmazonActivity being tested. Automatically created
-     * from the generic type class argument
-     */
-    protected T activity;
-
-    /**
-     * Amazon EC2 client
-     */
-    protected AmazonEC2 client;
-
-    /**
-     * A cache of AmazonEC2 client instances by Provider
-     */
-    private ProviderClientCache clientCache;
-
-    public AmazonActivityLiveTest() {
-        super(AmazonProvisionr.ID);
-    }
-
-    /**
-     * Create an instance using the default constructor for the class type argument
-     *
-     * @param klass
-     * @param clientCache cache for AmazonEC2 client connections
-     */
-    protected <A extends AmazonActivity> A createAmazonActivityInstance(
-        Class<A> klass, ProviderClientCache clientCache
-    ) {
-        try {
-            Constructor<A> constructor = klass.getConstructor(ProviderClientCache.class);
-            return (A) constructor.newInstance(clientCache);
-
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    /**
-     * Retrieve the generic class type argument.
-     */
-    protected Class<T> getAmazonActivityClass() {
-        return Generics.getTypeParameter(getClass(), AmazonActivity.class);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        final String region = getProviderProperty(ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION);
-
-        provider = collectProviderCredentialsFromSystemProperties()
-            .option(ProviderOptions.REGION, region).createProvider();
-        LOG.info("Using provider {}", provider);
-
-        clientCache = (new ProviderClientCacheSupplier()).get();
-        client = clientCache.getUnchecked(provider);
-
-        activity = createAmazonActivityInstance(getAmazonActivityClass(), clientCache);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        client.shutdown();
-    }
-
-    protected void executeActivitiesInSequence(
-        DelegateExecution execution, Class<? extends AmazonActivity>... classes
-    ) throws Exception {
-        for (Class<? extends AmazonActivity> klass : classes) {
-            createAmazonActivityInstance(klass, clientCache).execute(execution);
-        }
-    }
-
-    protected void quietlyDeleteSecurityGroupIfExists(String groupName) {
-        try {
-            client.deleteSecurityGroup(new DeleteSecurityGroupRequest().withGroupName(groupName));
-
-        } catch (AmazonServiceException e) {
-            if (!e.getErrorCode().equals("InvalidGroup.NotFound")) {
-                throw Throwables.propagate(e);
-            }
-        }
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/CreatePoolLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/CreatePoolLiveTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/CreatePoolLiveTest.java
deleted file mode 100644
index 2bda59c..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/CreatePoolLiveTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.axemblr.provisionr.amazon.activities;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.BlockDevice;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-
-import java.util.ArrayList;
-
-import org.activiti.engine.delegate.DelegateExecution;
-
-public abstract class CreatePoolLiveTest<T extends AmazonActivity> extends AmazonActivityLiveTest<T> {
-
-    protected DelegateExecution execution;
-    protected Pool pool;
-    protected Hardware hardware;
-    protected Software software;
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        execution = mock(DelegateExecution.class);
-        pool = mock(Pool.class);
-
-        final AdminAccess adminAccess = AdminAccess.builder()
-            .username("admin")
-            .publicKey(getResourceAsString("keys/test.pub"))
-            .privateKey(getResourceAsString("keys/test"))
-            .createAdminAccess();
-
-        final Network network = Network.builder().addRules(
-            Rule.builder().anySource().tcp().port(22).createRule()).createNetwork();
-
-        hardware = mock(Hardware.class);
-        when(hardware.getType()).thenReturn("t1.micro");
-        when(hardware.getBlockDevices()).thenReturn(new ArrayList<BlockDevice>());
-
-        software = mock(Software.class);
-
-        when(pool.getProvider()).thenReturn(provider);
-        when(pool.getAdminAccess()).thenReturn(adminAccess);
-        when(pool.getNetwork()).thenReturn(network);
-
-        when(pool.getMinSize()).thenReturn(1);
-        when(pool.getExpectedSize()).thenReturn(1);
-
-        when(pool.getHardware()).thenReturn(hardware);
-
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-
-        executeActivitiesInSequence(execution,
-            EnsureKeyPairExists.class,
-            EnsureSecurityGroupExists.class
-        );
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void tearDown() throws Exception {
-        executeActivitiesInSequence(execution,
-            DeleteSecurityGroup.class,
-            DeleteKeyPair.class
-        );
-        super.tearDown();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/DeleteKeyPairLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/DeleteKeyPairLiveTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/DeleteKeyPairLiveTest.java
deleted file mode 100644
index 53a5ec7..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/DeleteKeyPairLiveTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
-import com.amazonaws.services.ec2.model.DescribeKeyPairsRequest;
-import com.amazonaws.services.ec2.model.DescribeKeyPairsResult;
-import com.amazonaws.services.ec2.model.ImportKeyPairRequest;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ErrorCodes;
-import com.axemblr.provisionr.amazon.core.KeyPairs;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import org.activiti.engine.delegate.DelegateExecution;
-import static org.fest.assertions.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class DeleteKeyPairLiveTest extends AmazonActivityLiveTest<DeleteKeyPair> {
-
-    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        client.importKeyPair(new ImportKeyPairRequest().withKeyName(KEYPAIR_NAME)
-            .withPublicKeyMaterial(getResourceAsString("keys/test.pub")));
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(KEYPAIR_NAME));
-        super.tearDown();
-    }
-
-    @Test
-    public void testDeleteKeyPair() throws Exception {
-        final AdminAccess adminAccess = AdminAccess.builder()
-            .username("admin")
-            .publicKey(getResourceAsString("keys/test.pub"))
-            .privateKey(getResourceAsString("keys/test"))
-            .createAdminAccess();
-
-        DelegateExecution execution = mock(DelegateExecution.class);
-        Pool pool = mock(Pool.class);
-
-        when(pool.getAdminAccess()).thenReturn(adminAccess);
-        when(pool.getProvider()).thenReturn(provider);
-
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-
-        activity.execute(execution);
-        assertKeyNotFound(KEYPAIR_NAME);
-
-        /* the second call should just do nothing */
-        activity.execute(execution);
-    }
-
-    public void assertKeyNotFound(String keyName) {
-        final DescribeKeyPairsRequest request = new DescribeKeyPairsRequest().withKeyNames(keyName);
-        try {
-            DescribeKeyPairsResult result = client.describeKeyPairs(request);
-            fail("Found key " + result.getKeyPairs().get(0));
-
-        } catch (AmazonServiceException e) {
-            assertThat(e.getErrorCode()).isEqualTo(ErrorCodes.KEYPAIR_NOT_FOUND);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java
deleted file mode 100644
index b931dda..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
-import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
-import com.amazonaws.services.ec2.model.SecurityGroup;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.SecurityGroups;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import org.activiti.engine.delegate.DelegateExecution;
-import static org.fest.assertions.api.Assertions.assertThat;
-import static org.fest.assertions.api.Assertions.fail;
-import org.junit.After;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeleteSecurityGroupLiveTest extends AmazonActivityLiveTest<DeleteSecurityGroup> {
-
-    private final String SECURITY_GROUP_NAME = SecurityGroups.formatNameFromBusinessKey(BUSINESS_KEY);
-
-    @After
-    public void tearDown() throws Exception {
-        quietlyDeleteSecurityGroupIfExists(SECURITY_GROUP_NAME);
-        super.tearDown();
-    }
-
-    @Test
-    public void testDeleteSecurityGroup() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-        Pool pool = mock(Pool.class);
-
-        when(pool.getProvider()).thenReturn(provider);
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-
-        client.createSecurityGroup(new CreateSecurityGroupRequest()
-            .withGroupName(SECURITY_GROUP_NAME).withDescription("Just for test"));
-
-        activity.execute(execution);
-
-        try {
-            client.describeSecurityGroups(new DescribeSecurityGroupsRequest()
-                .withGroupNames(SECURITY_GROUP_NAME));
-            fail("Did not throw AmazonServiceException as expected");
-
-        } catch (AmazonServiceException e) {
-            assertThat(e.getErrorCode()).isEqualTo("InvalidGroup.NotFound");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java
deleted file mode 100644
index 94154e1..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
-import com.amazonaws.services.ec2.model.DescribeKeyPairsRequest;
-import com.amazonaws.services.ec2.model.DescribeKeyPairsResult;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.KeyPairs;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import org.activiti.engine.delegate.DelegateExecution;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class EnsureKeyPairExistsLiveTest extends AmazonActivityLiveTest<EnsureKeyPairExists> {
-
-    /**
-     * Computed in an Amazon specific way
-     */
-    public static final String TEST_KEY_FINGERPRINT = "2f:e9:a0:bc:17:71:3a:7e:d7:c0:16:99:0d:62:8e:be";
-
-    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
-
-    @Override
-    public void tearDown() throws Exception {
-        client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(KEYPAIR_NAME));
-        super.tearDown();
-    }
-
-    @Test
-    public void testEnsureKeyPairExists() throws Exception {
-        final AdminAccess adminAccess = AdminAccess.builder()
-            .username("admin")
-            .publicKey(getResourceAsString("keys/test.pub"))
-            .privateKey(getResourceAsString("keys/test"))
-            .createAdminAccess();
-
-        DelegateExecution execution = mock(DelegateExecution.class);
-        Pool pool = mock(Pool.class);
-
-        when(pool.getProvider()).thenReturn(provider);
-        when(pool.getAdminAccess()).thenReturn(adminAccess);
-
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-
-        activity.execute(execution);
-        assertKeyPairWasImportedAsExpected();
-
-        /* the second call should just re-import the key */
-        activity.execute(execution);
-        assertKeyPairWasImportedAsExpected();
-    }
-
-    private void assertKeyPairWasImportedAsExpected() {
-        final DescribeKeyPairsRequest request = new DescribeKeyPairsRequest().withKeyNames(KEYPAIR_NAME);
-        DescribeKeyPairsResult result = client.describeKeyPairs(request);
-
-        assertThat(result.getKeyPairs()).hasSize(1);
-        assertThat(result.getKeyPairs().get(0).getKeyFingerprint()).isEqualTo(TEST_KEY_FINGERPRINT);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java
deleted file mode 100644
index d630406..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
-import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
-import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
-import com.amazonaws.services.ec2.model.IpPermission;
-import com.amazonaws.services.ec2.model.RevokeSecurityGroupIngressRequest;
-import com.amazonaws.services.ec2.model.SecurityGroup;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.SecurityGroups;
-import com.axemblr.provisionr.amazon.functions.ConvertIpPermissionToRule;
-import com.axemblr.provisionr.amazon.functions.ConvertRuleToIpPermission;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.collect.ImmutableSet;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static com.google.common.collect.Iterables.transform;
-import static com.google.common.collect.Lists.newArrayList;
-import com.google.common.collect.Sets;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import org.activiti.engine.delegate.DelegateExecution;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.After;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EnsureSecurityGroupExistsLiveTest extends AmazonActivityLiveTest<EnsureSecurityGroupExists> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EnsureSecurityGroupExistsLiveTest.class);
-
-    protected final String SECURITY_GROUP_NAME = SecurityGroups.formatNameFromBusinessKey(BUSINESS_KEY);
-
-    @After
-    public void tearDown() throws Exception {
-        quietlyDeleteSecurityGroupIfExists(SECURITY_GROUP_NAME);
-        super.tearDown();
-    }
-
-    @Test
-    public void testCreateSecurityGroup() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-
-        final ImmutableSet<Rule> ingressRules = ImmutableSet.of(
-            Rule.builder().anySource().icmp().createRule(),
-            Rule.builder().anySource().port(22).tcp().createRule(),
-            Rule.builder().anySource().port(53).udp().createRule()
-        );
-
-        final Network network = Network.builder().ingress(ingressRules).createNetwork();
-
-        Pool pool = mock(Pool.class);
-
-        when(pool.getProvider()).thenReturn(provider);
-        when(pool.getNetwork()).thenReturn(network);
-
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-
-        activity.execute(execution);
-        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, ingressRules);
-
-        /* If any permissions is removed it should converge on a second run */
-        Set<Rule> expectedAfterRevoke = revokeAnyRule(ingressRules);
-        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, expectedAfterRevoke);
-
-        activity.execute(execution);
-        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, ingressRules);
-
-        /* If any permissions is added it should converge on a second run */
-        final IpPermission permission = new IpPermission().withIpProtocol("tcp")
-            .withIpRanges("0.0.0.0/0").withFromPort(100).withToPort(120);
-
-        client.authorizeSecurityGroupIngress(new AuthorizeSecurityGroupIngressRequest()
-            .withGroupName(SECURITY_GROUP_NAME).withIpPermissions(permission));
-
-        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, Sets.<Rule>union(ingressRules,
-            ImmutableSet.of(ConvertIpPermissionToRule.FUNCTION.apply(permission))));
-
-        activity.execute(execution);
-        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, ingressRules);
-    }
-
-    private Set<Rule> revokeAnyRule(Set<Rule> ingressRules) {
-        List<IpPermission> permissions = newArrayList(transform(ingressRules, ConvertRuleToIpPermission.FUNCTION));
-        Collections.shuffle(permissions);
-
-        IpPermission permission = permissions.get(0);
-        LOG.info(">> Revoking permission {} on {} for test.", permission, SECURITY_GROUP_NAME);
-
-        client.revokeSecurityGroupIngress(new RevokeSecurityGroupIngressRequest()
-            .withGroupName(SECURITY_GROUP_NAME).withIpPermissions(permission));
-
-        return Sets.difference(ingressRules, ImmutableSet.of(ConvertIpPermissionToRule.FUNCTION.apply(permission)));
-    }
-
-    public void assertSecurityGroupExistsWithRules(String groupName, final Set<Rule> ingressRules) {
-        DescribeSecurityGroupsResult result = client.describeSecurityGroups(
-            new DescribeSecurityGroupsRequest().withGroupNames(groupName));
-
-        assertThat(result.getSecurityGroups()).hasSize(1);
-        SecurityGroup group = getOnlyElement(result.getSecurityGroups());
-
-        assertThat(group.getIpPermissions()).hasSize(ingressRules.size());
-        assertThat(ingressRules).containsAll(transform(group.getIpPermissions(),
-            ConvertIpPermissionToRule.FUNCTION));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/PublishListOfMachinesTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/PublishListOfMachinesTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/PublishListOfMachinesTest.java
deleted file mode 100644
index c560d19..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/PublishListOfMachinesTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
-import com.amazonaws.services.ec2.model.DescribeInstancesResult;
-import com.amazonaws.services.ec2.model.Instance;
-import com.amazonaws.services.ec2.model.Reservation;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.axemblr.provisionr.test.ProcessVariablesCollector;
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.activiti.engine.delegate.DelegateExecution;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import org.mockito.Matchers;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class PublishListOfMachinesTest {
-
-    @Test
-    public void testPublishListOfMachines() throws Exception {
-        AmazonEC2 client = mock(AmazonEC2.class);
-
-        ProviderClientCache clientCache = mock(ProviderClientCache.class);
-        when(clientCache.get(Matchers.<Provider>any())).thenReturn(client);
-
-        DelegateExecution execution = mock(DelegateExecution.class);
-        List<String> instanceIds = Lists.newArrayList("i-123", "i-456");
-        when(execution.getVariable(ProcessVariables.INSTANCE_IDS)).thenReturn(instanceIds);
-
-        when(client.describeInstances(Matchers.<DescribeInstancesRequest>any()))
-            .thenReturn(new DescribeInstancesResult()
-                .withReservations(new Reservation().withInstances(
-                    new Instance().withInstanceId("i-123").withPublicDnsName("i1.amazonaws.com")
-                        .withPublicIpAddress("1.2.3.4").withPrivateDnsName("i1.internal").withPrivateIpAddress("10.1.2.3"),
-                    new Instance().withInstanceId("i-456").withPublicDnsName("i2.amazonaws.com")
-                        .withPublicIpAddress("5.6.7.8").withPrivateDnsName("i2.internal").withPrivateIpAddress("10.4.5.6")
-                )));
-
-        ProcessVariablesCollector collector = new ProcessVariablesCollector();
-        collector.install(execution);
-
-        AmazonActivity activity = new PublishListOfMachines(clientCache);
-        activity.execute(client, null /* not used */, execution);
-
-        @SuppressWarnings("unchecked")
-        List<Machine> machines = (List<Machine>) collector.getVariable(CoreProcessVariables.MACHINES);
-
-        assertThat(machines).hasSize(2);
-        assertThat(machines.get(0).getPublicDnsName()).isEqualTo("i1.amazonaws.com");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java
deleted file mode 100644
index d5bb4b1..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import static org.fest.assertions.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
-import com.amazonaws.services.ec2.model.DescribeInstancesResult;
-import com.amazonaws.services.ec2.model.DescribeVolumesRequest;
-import com.amazonaws.services.ec2.model.DescribeVolumesResult;
-import com.amazonaws.services.ec2.model.Instance;
-import com.amazonaws.services.ec2.model.InstanceBlockDeviceMapping;
-import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
-import com.amazonaws.services.ec2.model.Volume;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.api.hardware.BlockDevice;
-import com.axemblr.provisionr.test.ProcessVariablesCollector;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Uninterruptibles;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.junit.Test;
-
-public class RunOnDemandInstancesLiveTest extends CreatePoolLiveTest<RunOnDemandInstances> {
-
-    private static final String UBUNTU_AMI_ID = "ami-1e831d77"; // Ubuntu 13.04 amd64
-    private ProcessVariablesCollector collector;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        collector = new ProcessVariablesCollector();
-        collector.install(execution);
-    }
-
-    @Test
-    public void testRunInstances() throws Exception {
-
-        activity.execute(execution);
-
-        verify(execution).setVariable(eq(ProcessVariables.RESERVATION_ID), anyString());
-        verify(execution).setVariable(eq(ProcessVariables.INSTANCE_IDS), any());
-
-        @SuppressWarnings("unchecked")
-        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
-
-        /* the second call should do nothing */
-        activity.execute(execution);
-
-        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
-            .withInstanceIds(instanceIds));
-
-        assertThat(result.getReservations()).hasSize(1);
-        assertThat(result.getReservations().get(0).getInstances()).hasSize(1);
-
-    }
-
-    @Test
-    public void testRunInstancesWithBlockDevices() throws Exception {
-        // TODO: maybe we should also test for spot instances
-        BlockDevice blockDevice = mock(BlockDevice.class);
-        when(blockDevice.getSize()).thenReturn(8); // TODO: understand why it doesn't work for smaller volumes
-        when(blockDevice.getName()).thenReturn("/dev/sda1");
-        BlockDevice blockDevice2 = mock(BlockDevice.class);
-        when(blockDevice2.getSize()).thenReturn(16);
-        when(blockDevice2.getName()).thenReturn("/dev/sda4");
-        when(hardware.getBlockDevices()).thenReturn(Lists.newArrayList(blockDevice, blockDevice2));
-
-        activity.execute(execution);
-
-        Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS);
-
-        @SuppressWarnings("unchecked")
-        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
-        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
-            .withInstanceIds(instanceIds));
-
-        Instance instance = result.getReservations().get(0).getInstances().get(0);
-        List<InstanceBlockDeviceMapping> bdm = instance.getBlockDeviceMappings();
-        assertThat(bdm).hasSize(2);
-        List<String> volumeIds = Lists.newArrayList();
-        for (int i = 0; i < bdm.size(); i++) {
-            assertThat(bdm.get(i).getDeviceName()).isEqualTo("/dev/sda" + ((i+1) * (i+1)));
-            assertThat(bdm.get(i).getEbs().getDeleteOnTermination()).isTrue();
-            volumeIds.add(bdm.get(i).getEbs().getVolumeId());
-        }
-
-        DescribeVolumesResult volumesResult = client.describeVolumes(
-                new DescribeVolumesRequest().withVolumeIds(volumeIds));
-        for (Volume volume : volumesResult.getVolumes()) {
-            assertThat(volume.getState()).isIn(Lists.newArrayList("creating", "available", "in-use"));
-        }
-        assertThat(volumesResult.getVolumes().get(0).getSize()).isNotEqualTo(volumesResult.getVolumes().get(1).getSize());
-    }
-
-    @Test
-    public void testRunInstancesWithABaseImageId() throws Exception {
-        when(software.getImageId()).thenReturn(UBUNTU_AMI_ID);
-        when(pool.getSoftware()).thenReturn(software);
-        activity.execute(execution);
-
-        @SuppressWarnings("unchecked")
-        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
-        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
-            .withInstanceIds(instanceIds));
-
-        Instance instance = result.getReservations().get(0).getInstances().get(0);
-        assertThat(instance.getImageId()).isEqualTo(UBUNTU_AMI_ID);
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        @SuppressWarnings("unchecked")
-        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
-        client.terminateInstances(new TerminateInstancesRequest().withInstanceIds(instanceIds));
-
-        // TODO: this behaves strangely, if it tries to delete the security group 
-        // and the instances are not yet killed, the test fails with an error
-        Uninterruptibles.sleepUninterruptibly(45, TimeUnit.SECONDS);
-        super.tearDown();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/RunSpotInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/RunSpotInstancesLiveTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/RunSpotInstancesLiveTest.java
deleted file mode 100644
index 89d7d24..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/RunSpotInstancesLiveTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-* Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
-*
-* 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.
-*/
-
-package com.axemblr.provisionr.amazon.activities;
-
-import static org.fest.assertions.api.Assertions.assertThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsRequest;
-import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsResult;
-import com.amazonaws.services.ec2.model.Filter;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.options.ProviderOptions;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.axemblr.provisionr.test.ProcessVariablesCollector;
-import com.google.common.util.concurrent.Uninterruptibles;
-
-public class RunSpotInstancesLiveTest extends CreatePoolLiveTest<RunSpotInstances> {
-
-    /**
-     * This should be set a bit higher than the on demand instance
-     * price to avoid the situation in which the test fails because
-     * the spot bid is too low. 
-     */
-    public static String AMAZON_SPOT_BID = "0.04";
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        final String region = getProviderProperty(ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION);
-        provider = collectProviderCredentialsFromSystemProperties()
-                .option(ProviderOptions.REGION, region)
-                .option(ProviderOptions.SPOT_BID, AMAZON_SPOT_BID)
-                .createProvider();
-        when(pool.getProvider()).thenReturn(provider);
-    }
-
-    @Test
-    public void testRunSpotInstances() throws Exception {
-        ProcessVariablesCollector collector = new ProcessVariablesCollector();
-        collector.install(execution);
-
-        activity.execute(execution);
-
-        @SuppressWarnings("unchecked")
-        ArgumentCaptor<List<String>> argument = (ArgumentCaptor<List<String>>) 
-                (Object) ArgumentCaptor.forClass(List.class);
-        verify(execution).setVariable(eq(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS), argument.capture());
-        when(execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS)).thenReturn(argument.getValue());
-        /* The timeout is needed because the describe calls don't return immediately. */
-        // TODO: see if we can eliminate this after adding the process variables conditions
-        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES);
-
-        // shouldn't do anything
-        activity.execute(execution);
-
-        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES);
-
-        DescribeSpotInstanceRequestsResult result = client.describeSpotInstanceRequests(
-                new DescribeSpotInstanceRequestsRequest().withFilters(new Filter()
-                    .withName("launch-group").withValues(BUSINESS_KEY)));
-
-        assertThat(result.getSpotInstanceRequests()).hasSize(1);
-        /* we also need to sleep before the teardown */
-        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void tearDown() throws Exception {
-        // cleanup any pending requests or instances
-        ArgumentCaptor<List<String>> argument = (ArgumentCaptor<List<String>>) 
-                (Object) ArgumentCaptor.forClass(List.class);
-
-        executeActivitiesInSequence(execution,
-                CancelSpotRequests.class, 
-                GetInstanceIdsFromSpotRequests.class);
-
-        verify(execution).setVariable(eq(ProcessVariables.INSTANCE_IDS), argument.capture());
-        when(execution.getVariable(ProcessVariables.INSTANCE_IDS)).thenReturn(argument.getValue());
-
-        executeActivitiesInSequence(execution, TerminateInstances.class);
-        super.tearDown();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/SetupAdminAccessTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/SetupAdminAccessTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/SetupAdminAccessTest.java
deleted file mode 100644
index 1af2038..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/SetupAdminAccessTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.activities.PuppetActivity;
-import com.axemblr.provisionr.test.TestConstants;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class SetupAdminAccessTest {
-
-    @Test
-    public void testCreatePuppetScript() throws Exception {
-        Pool pool = mock(Pool.class);
-
-        final AdminAccess adminAccess = AdminAccess.builder()
-            .privateKey(TestConstants.PRIVATE_KEY)
-            .publicKey(TestConstants.PUBLIC_KEY)
-            .username(System.getProperty("user.name"))
-            .createAdminAccess();
-
-        when(pool.getAdminAccess()).thenReturn(adminAccess);
-
-        PuppetActivity activity = new SetupAdminAccess();
-        String content = activity.createPuppetScript(pool, null);
-
-        final String username = adminAccess.getUsername();
-
-        assertThat(content).contains(username)
-            .contains(adminAccess.getPublicKey().split(" ")[1])
-            .contains(String.format("user { \"%s\":", username))
-            .contains(String.format("file { \"/home/%s/.ssh\":", username));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/TerminateInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/TerminateInstancesLiveTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/TerminateInstancesLiveTest.java
deleted file mode 100644
index 360c2d0..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/activities/TerminateInstancesLiveTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.axemblr.provisionr.test.ProcessVariablesCollector;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.junit.Test;
-import org.mockito.Matchers;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class TerminateInstancesLiveTest extends CreatePoolLiveTest<TerminateInstances> {
-
-    private ProcessVariablesCollector collector;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        collector = new ProcessVariablesCollector();
-        collector.install(execution);
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testTerminateInstances() throws Exception {
-        executeActivitiesInSequence(execution,
-                EnsureKeyPairExists.class,
-                EnsureSecurityGroupExists.class,
-                RunOnDemandInstances.class
-            );
-
-        when(execution.getVariable(ProcessVariables.INSTANCE_IDS))
-            .thenReturn(collector.getVariable(ProcessVariables.INSTANCE_IDS));
-
-        activity.execute(execution);
-
-        /* the second execution should do nothing */
-        activity.execute(execution);
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testTerminateInstancesNoIdsPresent() throws Exception {
-        executeActivitiesInSequence(execution,
-                EnsureKeyPairExists.class,
-                EnsureSecurityGroupExists.class
-            );
-        when(execution.getVariable(ProcessVariables.INSTANCE_IDS)).thenReturn(null);
-
-        // should not throw any exception and should not do anything
-        activity.execute(execution);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/config/DefaultProviderConfigTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/config/DefaultProviderConfigTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/config/DefaultProviderConfigTest.java
deleted file mode 100644
index da54a3c..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/config/DefaultProviderConfigTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.config;
-
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.base.Optional;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class DefaultProviderConfigTest {
-
-    @Test
-    public void testProviderIsAbsentIfCredentialsAreEmpty() {
-        DefaultProviderConfig config = new DefaultProviderConfig("", "", "us-east-1", "");
-        assertThat(config.createProvider().isPresent()).isFalse();
-    }
-
-    @Test
-    public void testProviderWithNoRegionAndEndpoint() {
-        DefaultProviderConfig config = new DefaultProviderConfig("access", "secret", "", "");
-
-        Optional<Provider> provider = config.createProvider();
-        assertThat(provider.isPresent()).isTrue();
-
-        assertThat(provider.get().getEndpoint().isPresent()).isFalse();
-        assertThat(provider.get().getOptions().containsKey("region")).isFalse();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/core/ImageTableQueryTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/core/ImageTableQueryTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/core/ImageTableQueryTest.java
deleted file mode 100644
index fe3470b..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/core/ImageTableQueryTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.core;
-
-import java.io.IOException;
-import org.junit.Test;
-
-public class ImageTableQueryTest {
-
-    public final ImageTable table;
-
-    public ImageTableQueryTest() throws IOException {
-        this.table = ImageTable.fromCsvResource("/com/axemblr/provisionr/amazon/ubuntu.csv");
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testQueryFailsWithMultipleResults() {
-        table.query().filterBy("region", "us-east-1").singleResult();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/core/ImageTableTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/core/ImageTableTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/core/ImageTableTest.java
deleted file mode 100644
index 8235906..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/core/ImageTableTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.core;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Table;
-import com.google.common.collect.Tables;
-import java.io.IOException;
-import java.util.Map;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class ImageTableTest {
-
-    @Test
-    public void testLoadAmiTableFromResource() throws IOException {
-        ImageTable table = ImageTable.fromCsvResource("/com/axemblr/provisionr/amazon/ubuntu.csv");
-
-        String id = table.query().filterBy("region", "us-east-1").filterBy("version", "12.04 LTS")
-            .filterBy("arch", "amd64").filterBy("type", "instance-store").singleResult();
-
-        assertThat(id).isEqualTo("ami-9a873ff3");
-    }
-
-    @Test
-    public void testExtractHeaderLine() throws Exception {
-        Iterable<String> headers = ImageTable.extractHeaders(ImmutableList.of("a,b,c", "1,2,3"));
-        assertThat(headers).containsAll(ImmutableList.of("a", "b", "c"));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testCombineHeadersWithLinePartsAsTableCells() {
-        final ImmutableList<String> headers = ImmutableList.of("a", "b");
-        final ImmutableList<String> lineParts = ImmutableList.of("1", "2");
-
-        Iterable<Table.Cell<String, String, String>> cells =
-            ImageTable.combineHeadersWithLinePartsAsTableCells(0, headers, lineParts);
-
-        assertThat(cells).contains(Tables.immutableCell("0", "a", "1"));
-    }
-
-    @Test
-    public void testZipIterators() {
-        Iterable<Map.Entry<String, String>> entries = ImageTable.zip(
-            ImmutableList.of("a", "b"), ImmutableList.of("1", "2"));
-
-        assertThat(entries).containsAll(ImmutableList.of(
-            Maps.immutableEntry("a", "1"), Maps.immutableEntry("b", "2")));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java b/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java
deleted file mode 100644
index 6531112..0000000
--- a/providers/amazon/src/test/java/com/axemblr/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.functions;
-
-import com.amazonaws.services.ec2.model.IpPermission;
-import com.axemblr.provisionr.api.network.Protocol;
-import com.axemblr.provisionr.api.network.Rule;
-import static org.fest.assertions.api.Assertions.assertThat;
-import static org.junit.Assert.assertNotNull;
-import org.junit.Test;
-
-public class ConvertIpPermissionToRuleAndBackTest {
-
-    @Test
-    public void testConvertTcpIpPermissionToRuleAndBack() {
-        IpPermission expected = new IpPermission().withFromPort(1).withToPort(1024)
-            .withIpProtocol("tcp").withIpRanges("0.0.0.0/0");
-
-        Rule rule = ConvertIpPermissionToRule.FUNCTION.apply(expected);
-        assertNotNull(rule);
-
-        assertThat(rule.getCidr()).isEqualTo("0.0.0.0/0");
-        assertThat(rule.getProtocol()).isEqualTo(Protocol.TCP);
-
-        assertThat(rule.getPorts().lowerEndpoint()).isEqualTo(1);
-        assertThat(rule.getPorts().upperEndpoint()).isEqualTo(1024);
-
-        IpPermission actual = ConvertRuleToIpPermission.FUNCTION.apply(rule);
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testConvertIcmpPermissionToRule() {
-        IpPermission expected = new IpPermission().withIpProtocol("icmp")
-            .withFromPort(-1).withToPort(-1).withIpRanges("0.0.0.0/0");
-
-        Rule rule = ConvertIpPermissionToRule.FUNCTION.apply(expected);
-        assertNotNull(rule);
-
-        assertThat(rule.getProtocol()).isEqualTo(Protocol.ICMP);
-        assertThat(rule.getCidr()).isEqualTo("0.0.0.0/0");
-
-        IpPermission actual = ConvertRuleToIpPermission.FUNCTION.apply(rule);
-        assertThat(actual).isEqualTo(expected);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/ProcessDefinitionSyntaxCheckTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/ProcessDefinitionSyntaxCheckTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/ProcessDefinitionSyntaxCheckTest.java
new file mode 100644
index 0000000..97066d0
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/ProcessDefinitionSyntaxCheckTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon;
+
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.ProcessEngineConfiguration;
+import org.activiti.engine.repository.Deployment;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ProcessDefinitionSyntaxCheckTest {
+
+    private ProcessEngine processEngine;
+
+    @Before
+    public void setUp() {
+        processEngine = ProcessEngineConfiguration
+            .createStandaloneInMemProcessEngineConfiguration().buildProcessEngine();
+    }
+
+    @After
+    public void tearDown() {
+        processEngine.close();
+    }
+
+    @Test
+    public void testDeployment() {
+        assertCanBeDeployed("OSGI-INF/activiti/amazonPoolManagement.bpmn20.xml");
+        assertCanBeDeployed("OSGI-INF/activiti/amazonMachineSetup.bpmn20.xml");
+    }
+
+    private void assertCanBeDeployed(String resource) {
+        Deployment deployment = processEngine.getRepositoryService().createDeployment()
+            .addClasspathResource(resource).deploy();
+
+        assertThat(deployment).isNotNull();
+    }
+}


[08/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ProviderClientCache.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ProviderClientCache.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ProviderClientCache.java
deleted file mode 100644
index d4a5576..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ProviderClientCache.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.core;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.cache.LoadingCache;
-
-/**
- * Marker interface only used to hide generic type arguments
- * from Apache Aries and make Blueprint DI work as expected
- */
-public interface ProviderClientCache extends LoadingCache<Provider, AmazonEC2> {
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ProviderClientCacheSupplier.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ProviderClientCacheSupplier.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ProviderClientCacheSupplier.java
deleted file mode 100644
index f1ee76e..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ProviderClientCacheSupplier.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.core;
-
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.BasicAWSCredentials;
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.AmazonEC2Client;
-import com.amazonaws.services.ec2.model.DescribeRegionsRequest;
-import com.amazonaws.services.ec2.model.DescribeRegionsResult;
-import com.axemblr.provisionr.amazon.options.ProviderOptions;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Supplier;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.ForwardingLoadingCache;
-import com.google.common.cache.LoadingCache;
-import com.google.common.cache.RemovalListener;
-import com.google.common.cache.RemovalNotification;
-import java.util.concurrent.TimeUnit;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ProviderClientCacheSupplier implements Supplier<ProviderClientCache> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ProviderClientCacheSupplier.class);
-
-    public static final String AXEMBLR_USER_AGENT = "Axemblr Provisionr aws-sdk-java/1.3.14";
-
-    public static final int MAX_CACHE_SIZE = 100;
-    public static final int EXPIRE_AFTER_WRITE_IN_HOURS = 2;
-
-    private static class ProviderClientCacheLoader extends CacheLoader<Provider, AmazonEC2> {
-
-        @Override
-        public AmazonEC2 load(Provider provider) throws Exception {
-            String region = Optional.fromNullable(provider.getOptions().get(ProviderOptions.REGION))
-                .or(ProviderOptions.DEFAULT_REGION);
-
-            AWSCredentials credentials = new BasicAWSCredentials(provider.getAccessKey(), provider.getSecretKey());
-            AmazonEC2 client = new AmazonEC2Client(credentials, new ClientConfiguration()
-                .withUserAgent(AXEMBLR_USER_AGENT));
-
-            if (provider.getEndpoint().isPresent()) {
-                LOG.info("Using endpoint {} as configured", provider.getEndpoint().get());
-                client.setEndpoint(provider.getEndpoint().get());
-
-            } else {
-                LOG.info(">> Searching endpoint for region {}", region);
-                DescribeRegionsRequest request = new DescribeRegionsRequest().withRegionNames(region);
-
-                DescribeRegionsResult result = client.describeRegions(request);
-                checkArgument(result.getRegions().size() == 1, "Invalid region name %s. Expected one result found %s",
-                    region, result.getRegions());
-
-                LOG.info("<< Using endpoint {} for region {}", result.getRegions().get(0).getEndpoint(), region);
-                client.setEndpoint(result.getRegions().get(0).getEndpoint());
-            }
-
-            return client;
-
-        }
-    }
-
-    public static class WrapLoadingCacheAsProviderClientCache extends ForwardingLoadingCache<Provider, AmazonEC2>
-        implements ProviderClientCache {
-
-        private final LoadingCache<Provider, AmazonEC2> delegate;
-
-        public WrapLoadingCacheAsProviderClientCache(LoadingCache<Provider, AmazonEC2> delegate) {
-            this.delegate = checkNotNull(delegate, "delegate is null");
-        }
-
-        @Override
-        protected LoadingCache<Provider, AmazonEC2> delegate() {
-            return delegate;
-        }
-    }
-
-    @Override
-    public ProviderClientCache get() {
-        final LoadingCache<Provider, AmazonEC2> cache = CacheBuilder.newBuilder()
-            .maximumSize(MAX_CACHE_SIZE)
-            .expireAfterWrite(EXPIRE_AFTER_WRITE_IN_HOURS, TimeUnit.HOURS)
-            .removalListener(new RemovalListener<Provider, AmazonEC2>() {
-                @Override
-                public void onRemoval(RemovalNotification<Provider, AmazonEC2> notification) {
-                    LOG.info("Closing client for provider: {}", notification.getKey());
-                    notification.getValue().shutdown();
-                }
-            })
-            .build(new ProviderClientCacheLoader());
-
-        return new WrapLoadingCacheAsProviderClientCache(cache);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/SecurityGroups.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/SecurityGroups.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/SecurityGroups.java
deleted file mode 100644
index 7d63ae5..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/SecurityGroups.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.core;
-
-public class SecurityGroups {
-
-    private SecurityGroups() {
-        /* singleton */
-    }
-
-    public static String formatNameFromBusinessKey(String businessKey) {
-        return String.format("network-%s", businessKey);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/functions/ConvertIpPermissionToRule.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/functions/ConvertIpPermissionToRule.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/functions/ConvertIpPermissionToRule.java
deleted file mode 100644
index d5d004b..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/functions/ConvertIpPermissionToRule.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.functions;
-
-import com.amazonaws.services.ec2.model.IpPermission;
-import com.axemblr.provisionr.api.network.Protocol;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.network.RuleBuilder;
-import com.google.common.base.Function;
-import static com.google.common.collect.Iterables.getOnlyElement;
-
-public enum ConvertIpPermissionToRule implements Function<IpPermission, Rule> {
-    FUNCTION;
-
-    @Override
-    public Rule apply(IpPermission ipPermission) {
-        final RuleBuilder builder = Rule.builder().cidr(getOnlyElement(ipPermission.getIpRanges()))
-            .protocol(Protocol.valueOf(ipPermission.getIpProtocol().toUpperCase()));
-
-        if (!ipPermission.getIpProtocol().equalsIgnoreCase("icmp")) {
-            builder.ports(ipPermission.getFromPort(), ipPermission.getToPort());
-        }
-
-        return builder.createRule();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/functions/ConvertRuleToIpPermission.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/functions/ConvertRuleToIpPermission.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/functions/ConvertRuleToIpPermission.java
deleted file mode 100644
index f9fe3c7..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/functions/ConvertRuleToIpPermission.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.functions;
-
-import com.amazonaws.services.ec2.model.IpPermission;
-import com.axemblr.provisionr.api.network.Rule;
-import com.google.common.base.Function;
-
-public enum ConvertRuleToIpPermission implements Function<Rule, IpPermission> {
-    FUNCTION;
-
-    @Override
-    public IpPermission apply(Rule rule) {
-        IpPermission permission = new IpPermission()
-            .withIpProtocol(rule.getProtocol().toString().toLowerCase())
-            .withIpRanges(rule.getCidr());
-
-        if (!rule.getPorts().isEmpty()) {
-            permission.withFromPort(rule.getPorts().lowerEndpoint())
-                .withToPort(rule.getPorts().upperEndpoint());
-        } else {
-            permission.withFromPort(-1).withToPort(-1);
-        }
-        return permission;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/options/ProviderOptions.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/options/ProviderOptions.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/options/ProviderOptions.java
deleted file mode 100644
index 613a8f9..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/options/ProviderOptions.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.options;
-
-import com.google.common.base.Optional;
-
-public class ProviderOptions {
-
-    private ProviderOptions() {
-        /* singleton */
-    }
-
-    public static final String REGION = "region";
-    public static final String DEFAULT_REGION = "us-east-1";
-    public static final String SPOT_BID = "spotBid";
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/options/SoftwareOptions.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/options/SoftwareOptions.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/options/SoftwareOptions.java
deleted file mode 100644
index f8a94ed..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/options/SoftwareOptions.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.options;
-
-public class SoftwareOptions {
-
-    private SoftwareOptions() {
-        /* singleton */
-    }
-
-    public static final String DEFAULT_BASE_OPERATING_SYSTEM = "ubuntu";
-
-    public static final String BASE_OPERATING_SYSTEM_VERSION = "version";
-    public static final String DEFAULT_BASE_OPERATING_SYSTEM_VERSION = "12.04 LTS";
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/AmazonProvisionr.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/AmazonProvisionr.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/AmazonProvisionr.java
new file mode 100644
index 0000000..9f52330
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/AmazonProvisionr.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon;
+
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Maps;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.provisionr.amazon.config.DefaultProviderConfig;
+import org.apache.provisionr.amazon.options.ProviderOptions;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.core.CoreConstants;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.apache.provisionr.core.CoreSignals;
+import org.apache.provisionr.core.PoolStatus;
+import org.apache.provisionr.core.ProvisionrSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AmazonProvisionr extends ProvisionrSupport {
+
+    public static final Logger LOG = LoggerFactory.getLogger(AmazonProvisionr.class);
+
+    public static final String ID = "amazon";
+    public static final String MANAGEMENT_PROCESS_KEY = "amazonPoolManagement";
+
+    private final ProcessEngine processEngine;
+    private final Optional<Provider> defaultProvider;
+
+    public AmazonProvisionr(ProcessEngine processEngine, DefaultProviderConfig defaultProviderConfig) {
+        this.processEngine = checkNotNull(processEngine, "processEngine is null");
+        this.defaultProvider = defaultProviderConfig.createProvider();
+
+        if (defaultProvider.isPresent()) {
+            LOG.info("Default provider for AmazonProvisionr is {}", defaultProvider.get());
+        } else {
+            LOG.info("No default provider configured for AmazonProvisionr");
+        }
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    @Override
+    public Optional<Provider> getDefaultProvider() {
+        return defaultProvider;
+    }
+
+    @Override
+    public String startPoolManagementProcess(String businessKey, Pool pool) {
+        Map<String, Object> arguments = Maps.newHashMap();
+
+        arguments.put(CoreProcessVariables.POOL, pool);
+        arguments.put(CoreProcessVariables.PROVIDER, getId());
+        arguments.put(CoreProcessVariables.POOL_BUSINESS_KEY, businessKey);
+        arguments.put(CoreProcessVariables.BOOTSTRAP_TIMEOUT,
+            convertTimeoutToISO8601TimeDuration(pool.getBootstrapTimeInSeconds()));
+        arguments.put(CoreProcessVariables.IS_CACHED_IMAGE, pool.getSoftware().isCachedImage());
+
+        /* needed because the Activiti EL doesn't work as expected and properties can't be read from the pool. */
+        arguments.put(ProcessVariables.SPOT_BID, pool.getProvider().getOption(ProviderOptions.SPOT_BID));
+
+        /* Authenticate as kermit to make the process visible in the Explorer UI */
+        processEngine.getIdentityService().setAuthenticatedUserId(CoreConstants.ACTIVITI_EXPLORER_DEFAULT_USER);
+
+        ProcessInstance instance = processEngine.getRuntimeService()
+            .startProcessInstanceByKey(MANAGEMENT_PROCESS_KEY, businessKey, arguments);
+
+        return instance.getProcessInstanceId();
+    }
+
+    @Override
+    public List<Machine> getMachines(String businessKey) {
+        ProcessInstance instance = processEngine.getRuntimeService().createProcessInstanceQuery()
+            .processInstanceBusinessKey(businessKey).singleResult();
+        if (instance == null) {
+            throw new NoSuchElementException("No active pool found with key: " + businessKey);
+        }
+
+        @SuppressWarnings("unchecked") List<Machine> machines = (List<Machine>) processEngine.getRuntimeService()
+            .getVariable(instance.getId(), CoreProcessVariables.MACHINES);
+
+        return Optional.fromNullable(machines).or(Collections.<Machine>emptyList());
+    }
+
+    @Override
+    public String getStatus(String businessKey) {
+        ProcessInstance instance = processEngine.getRuntimeService().createProcessInstanceQuery()
+            .processInstanceBusinessKey(businessKey).singleResult();
+        if (instance == null) {
+            throw new NoSuchElementException("No active pool found with key: " + businessKey);
+        }
+
+        String status = (String) processEngine.getRuntimeService().getVariable(instance.getId(),
+            CoreProcessVariables.STATUS);
+
+        return Optional.fromNullable(status).or(PoolStatus.UNDEFINED);
+    }
+
+    @Override
+    public void destroyPool(String businessKey) {
+        triggerSignalEvent(processEngine, businessKey, CoreSignals.TERMINATE_POOL);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/ProcessVariables.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/ProcessVariables.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/ProcessVariables.java
new file mode 100644
index 0000000..53ae9e5
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/ProcessVariables.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon;
+
+public class ProcessVariables {
+
+    private ProcessVariables() {
+        /* singleton */
+    }
+
+    /**
+     * ID of a base image from which to create the others in the pool
+     */
+    public static final String IMAGE_ID = "imageId";
+
+    /**
+     * The reservation ID for a pool as String
+     *
+     * @see org.apache.provisionr.amazon.activities.RunOnDemandInstances
+     */
+    public static final String RESERVATION_ID = "reservationId";
+
+    /**
+     * The amount the user is willing to pay for spot instances in the
+     * Amazon pool he's trying to start. If set, the request is for spot
+     * instances, if null the request is for on demand instances.
+     * 
+     * @see org.apache.provisionr.amazon.activities.RunSpotInstances
+     */
+    public static final String SPOT_BID = "spotBid";
+
+    /**
+     * Flag that gets set when the process attempts to send spot requests
+     * for the first time. Because the describe call is not consistent
+     * until a reasonable delay passes, this will be used to timeout the
+     * Activiti retries so that the requests are not resent if they were
+     * successful. 
+     * 
+     * @see org.apache.provisionr.amazon.activities.RunSpotInstances
+     */
+    public static final String SPOT_REQUESTS_SENT = "spotRequestsSent";
+
+    /**
+     * List of request IDs as returned by Amazon for spot instances. These need to 
+     * be followed up to get the actual instance IDs.
+     * 
+     * @see org.apache.provisionr.amazon.activities.RunSpotInstances
+     */
+    public static final String SPOT_INSTANCE_REQUEST_IDS = "spotInstanceRequestIds";
+
+    /**
+     * Have all spot instance requests been handled by Amazon? (none are pending)
+     * 
+     *  @see org.apache.provisionr.amazon.activities.CheckNoRequestsAreOpen
+     */
+    public static final String NO_SPOT_INSTANCE_REQUESTS_OPEN = "noSpotInstanceRequestsOpen";
+
+    /**
+     * Are all spot instance requests in an active state? (none cancelled, none terminated)
+     * 
+     * @see org.apache.provisionr.amazon.activities.CheckAllRequestsAreActive
+     */
+    public static final String ALL_SPOT_INSTANCE_REQUESTS_ACTIVE = "allSpotInstanceRequestsActive";
+
+    /**
+     * List of instance IDs as returned by Amazon
+     *
+     * @see org.apache.provisionr.amazon.activities.RunOnDemandInstances
+     */
+    public static final String INSTANCE_IDS = "instanceIds";
+
+    /**
+     * List of requested EBS volume IDs
+     * 
+     * @see org.apache.provisionr.amazon.activities.CreateEBSVolumes
+     */
+    public static final String VOLUME_IDS = "volumeIds"; 
+
+    /**
+     * Are all started instances running?
+     *
+     * @see org.apache.provisionr.amazon.activities.CheckAllInstancesAreRunning
+     */
+    public static final String ALL_INSTANCES_RUNNING = "allInstancesRunning";
+
+    /**
+     * Are all instances marked as terminated?
+     *
+     * @see org.apache.provisionr.amazon.activities.CheckAllInstancesAreTerminated
+     */
+    public static final String ALL_INSTANCES_TERMINATED = "allInstancesTerminated";
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AllInstancesMatchPredicate.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AllInstancesMatchPredicate.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AllInstancesMatchPredicate.java
new file mode 100644
index 0000000..57363a8
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AllInstancesMatchPredicate.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
+import com.amazonaws.services.ec2.model.DescribeInstancesResult;
+import com.amazonaws.services.ec2.model.Instance;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Throwables;
+import com.google.common.collect.Iterables;
+
+import java.util.List;
+
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AllInstancesMatchPredicate extends AmazonActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AllInstancesMatchPredicate.class);
+
+    private final String resultVariable;
+    private final Predicate<Instance> predicate;
+
+    protected AllInstancesMatchPredicate(ProviderClientCache cache,
+                                         String resultVariable, Predicate<Instance> predicate) {
+        super(cache);
+        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
+        this.predicate = checkNotNull(predicate, "predicate is null");
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
+        @SuppressWarnings("unchecked")
+        Optional<List<String>> instanceIds = 
+            Optional.fromNullable((List<String>) execution.getVariable(ProcessVariables.INSTANCE_IDS));
+
+        if (!instanceIds.isPresent()) {
+            LOG.warn("<< Process variable '{}' not found", ProcessVariables.INSTANCE_IDS);
+            return;
+        } else if (instanceIds.get().size() == 0) {
+            LOG.info(">> No instances are currently registered in the process.");
+            return;
+        }
+
+        try {
+            DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
+                .withInstanceIds(instanceIds.get()));
+
+            List<Instance> instances = collectInstancesFromReservations(result.getReservations());
+
+            if (Iterables.all(instances, predicate)) {
+                LOG.info(">> All {} instances match predicate {} ", instanceIds, predicate);
+                execution.setVariable(resultVariable, true);
+
+            } else {
+                LOG.info("<< Not all instances {} match predicate {}", instanceIds, predicate);
+                execution.setVariable(resultVariable, false);
+            }
+        } catch (AmazonServiceException exception) {
+            if (exception.getErrorCode().equalsIgnoreCase("InvalidInstanceID.NotFound")) {
+                LOG.warn("<< Got error InvalidInstanceID.NotFound. Assuming predicate {} is false", predicate);
+                execution.setVariable(resultVariable, false);
+            } else {
+                throw Throwables.propagate(exception);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AllSpotRequestsMatchPredicate.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AllSpotRequestsMatchPredicate.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AllSpotRequestsMatchPredicate.java
new file mode 100644
index 0000000..b02a1bd
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AllSpotRequestsMatchPredicate.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsRequest;
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsResult;
+import com.amazonaws.services.ec2.model.SpotInstanceRequest;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+public class AllSpotRequestsMatchPredicate extends AmazonActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AllSpotRequestsMatchPredicate.class);
+
+    protected final String resultVariable;
+    private final Predicate<SpotInstanceRequest> predicate;
+
+    protected AllSpotRequestsMatchPredicate(ProviderClientCache cache, String resultVariable, 
+            Predicate<SpotInstanceRequest> predicate) {
+        super(cache);
+        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
+        this.predicate = checkNotNull(predicate, "predicate is null");
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
+
+        LOG.info(">> Checking if all spot requests match predicate {}", predicate);
+
+        @SuppressWarnings("unchecked")
+        List<String> requestIds = (List<String>) execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
+        checkNotNull(requestIds, "process variable '{}' not found", ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
+
+        DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest();
+        describeRequest.setSpotInstanceRequestIds(requestIds);
+
+        // Retrieve all of the requests we want to monitor.
+        DescribeSpotInstanceRequestsResult describeResult = client.describeSpotInstanceRequests(describeRequest);
+        List<SpotInstanceRequest> requests = describeResult.getSpotInstanceRequests();
+
+        if (Iterables.all(requests, predicate)) {
+            LOG.info(">> All {} requests match predicate {} ", requests, predicate);
+            execution.setVariable(resultVariable, true);
+        } else {
+            LOG.info("<< Not all requests {} match predicate {}", requests, predicate);
+            execution.setVariable(resultVariable, false);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AmazonActivity.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AmazonActivity.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AmazonActivity.java
new file mode 100644
index 0000000..6a743aa
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/AmazonActivity.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.Instance;
+import com.amazonaws.services.ec2.model.Reservation;
+import com.google.common.base.Function;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import java.util.List;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+
+public abstract class AmazonActivity implements JavaDelegate {
+
+    private final ProviderClientCache providerClientCache;
+
+    protected AmazonActivity(ProviderClientCache providerClientCache) {
+        this.providerClientCache = checkNotNull(providerClientCache, "providerClientCache is null");
+    }
+
+    /**
+     * Amazon specific activity implementation
+     *
+     * @param client    Amazon client created using the pool provider
+     * @param pool      Virtual machines pool description
+     * @param execution Activiti execution context
+     */
+    public abstract void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception;
+
+    /**
+     * Wrap the abstract {@code execute} method with the logic that knows how to create the Amazon client
+     */
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        Pool pool = (Pool) execution.getVariable(CoreProcessVariables.POOL);
+        checkNotNull(pool, "Please add the pool description as a process " +
+            "variable with the name '%s'.", CoreProcessVariables.POOL);
+
+        execute(providerClientCache.getUnchecked(pool.getProvider()), pool, execution);
+    }
+
+    protected List<Instance> collectInstancesFromReservations(List<Reservation> reservation) {
+        /* Make a copy as an ArrayList to force lazy collection evaluation */
+        List<List<Instance>> allInstances = Lists.transform(reservation, new Function<Reservation, List<Instance>>() {
+            @Override
+            public List<Instance> apply(Reservation reservation) {
+                return reservation.getInstances();
+            }
+        });
+
+        return Lists.newArrayList(Iterables.concat(allInstances));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CancelSpotRequests.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CancelSpotRequests.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CancelSpotRequests.java
new file mode 100644
index 0000000..77e3709
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CancelSpotRequests.java
@@ -0,0 +1,36 @@
+package org.apache.provisionr.amazon.activities;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.CancelSpotInstanceRequestsRequest;
+import org.apache.provisionr.amazon.AmazonProvisionr;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+
+public class CancelSpotRequests extends AmazonActivity {
+
+    public static final Logger LOG = LoggerFactory.getLogger(AmazonProvisionr.class);
+
+    public CancelSpotRequests(ProviderClientCache providerClientCache) {
+        super(providerClientCache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
+        @SuppressWarnings("unchecked")
+        List<String> requests = (List<String>) execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
+        checkNotNull(requests, "process variable '{}' not found", ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
+        if (requests.size() > 0) {
+            client.cancelSpotInstanceRequests(new CancelSpotInstanceRequestsRequest()
+                    .withSpotInstanceRequestIds(requests));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllInstancesAreRunning.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllInstancesAreRunning.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllInstancesAreRunning.java
new file mode 100644
index 0000000..f7c5d13
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllInstancesAreRunning.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.model.Instance;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import com.google.common.base.Predicate;
+
+public class CheckAllInstancesAreRunning extends AllInstancesMatchPredicate {
+
+    public static class InstanceIsRunning implements Predicate<Instance> {
+        @Override
+        public boolean apply(Instance instance) {
+            return instance.getState().getName().equalsIgnoreCase("running");
+        }
+
+        @Override
+        public String toString() {
+            return "InstanceIsRunning{}";
+        }
+    }
+
+    public CheckAllInstancesAreRunning(ProviderClientCache cache) {
+        super(cache, ProcessVariables.ALL_INSTANCES_RUNNING, new InstanceIsRunning());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllInstancesAreTerminated.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllInstancesAreTerminated.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllInstancesAreTerminated.java
new file mode 100644
index 0000000..b2ba3da
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllInstancesAreTerminated.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.model.Instance;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import com.google.common.base.Predicate;
+
+public class CheckAllInstancesAreTerminated extends AllInstancesMatchPredicate {
+
+    public static class InstanceIsTerminated implements Predicate<Instance> {
+        @Override
+        public boolean apply(Instance instance) {
+            return instance.getState().getName().equalsIgnoreCase("terminated");
+        }
+
+        @Override
+        public String toString() {
+            return "InstanceIsTerminated{}";
+        }
+    }
+
+    public CheckAllInstancesAreTerminated(ProviderClientCache cache) {
+        super(cache, ProcessVariables.ALL_INSTANCES_TERMINATED, new InstanceIsTerminated());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllRequestsAreActive.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllRequestsAreActive.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllRequestsAreActive.java
new file mode 100644
index 0000000..1103d77
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckAllRequestsAreActive.java
@@ -0,0 +1,35 @@
+package org.apache.provisionr.amazon.activities;
+
+import org.activiti.engine.delegate.DelegateExecution;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.SpotInstanceRequest;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Predicate;
+
+public class CheckAllRequestsAreActive extends AllSpotRequestsMatchPredicate {
+
+    public static class RequestIsActive implements Predicate<SpotInstanceRequest> {
+
+        @Override
+        public boolean apply(SpotInstanceRequest request) {
+            return "active".equalsIgnoreCase(request.getState());
+        }
+
+        @Override
+        public String toString() {
+            return "RequestIsActive{}";
+        }
+    }
+
+    public CheckAllRequestsAreActive(ProviderClientCache cache) {
+        super(cache, ProcessVariables.ALL_SPOT_INSTANCE_REQUESTS_ACTIVE, new RequestIsActive());
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
+        super.execute(client, pool, execution);        
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckNoRequestsAreOpen.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckNoRequestsAreOpen.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckNoRequestsAreOpen.java
new file mode 100644
index 0000000..2eebaa2
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/CheckNoRequestsAreOpen.java
@@ -0,0 +1,26 @@
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.model.SpotInstanceRequest;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import com.google.common.base.Predicate;
+
+public class CheckNoRequestsAreOpen extends AllSpotRequestsMatchPredicate {
+
+    public static class RequestIsNotOpen implements Predicate<SpotInstanceRequest> {
+
+        @Override
+        public boolean apply(SpotInstanceRequest request) {
+            return !"open".equalsIgnoreCase(request.getState());
+        }
+
+        @Override
+        public String toString() {
+            return "RequestIsNotOpen{}";
+        }
+    }
+
+    public CheckNoRequestsAreOpen(ProviderClientCache cache) {
+        super(cache, ProcessVariables.NO_SPOT_INSTANCE_REQUESTS_OPEN, new RequestIsNotOpen());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DeleteKeyPair.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DeleteKeyPair.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DeleteKeyPair.java
new file mode 100644
index 0000000..09bb575
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DeleteKeyPair.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
+import org.apache.provisionr.amazon.core.KeyPairs;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeleteKeyPair extends AmazonActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeleteKeyPair.class);
+
+    public DeleteKeyPair(ProviderClientCache cache) {
+        super(cache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
+        String keyName = KeyPairs.formatNameFromBusinessKey(execution.getProcessBusinessKey());
+
+        LOG.info(">> Deleting key pair {}", keyName);
+        client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(keyName));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroup.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroup.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroup.java
new file mode 100644
index 0000000..427e849
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroup.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DeleteSecurityGroupRequest;
+import org.apache.provisionr.amazon.core.ErrorCodes;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.amazon.core.SecurityGroups;
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Throwables;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeleteSecurityGroup extends AmazonActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeleteSecurityGroup.class);
+
+    public DeleteSecurityGroup(ProviderClientCache cache) {
+        super(cache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
+        final String groupName = SecurityGroups.formatNameFromBusinessKey(execution.getProcessBusinessKey());
+        try {
+            LOG.info(">> Deleting Security Group {}", groupName);
+
+            client.deleteSecurityGroup(new DeleteSecurityGroupRequest().withGroupName(groupName));
+
+        } catch (AmazonServiceException e) {
+            if (e.getErrorCode().equals(ErrorCodes.SECURITY_GROUP_NOT_FOUND)) {
+                LOG.info("<< Security Group {} not found. Ignoring this error.", groupName);
+            } else {
+                throw Throwables.propagate(e);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DumpConsoleOutput.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DumpConsoleOutput.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DumpConsoleOutput.java
new file mode 100644
index 0000000..3519f53
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/DumpConsoleOutput.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.GetConsoleOutputRequest;
+import com.amazonaws.services.ec2.model.GetConsoleOutputResult;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Charsets;
+import static com.google.common.base.Preconditions.checkNotNull;
+import net.schmizz.sshj.common.Base64;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DumpConsoleOutput extends AmazonActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DumpConsoleOutput.class);
+
+    public DumpConsoleOutput(ProviderClientCache providerClientCache) {
+        super(providerClientCache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
+        Machine machine = (Machine) execution.getVariable("machine");
+        checkNotNull(machine, "expecting 'machine' as a process variable");
+
+        LOG.info(">> Requesting console output for instance {}", machine.getExternalId());
+        GetConsoleOutputResult result = client.getConsoleOutput(
+            new GetConsoleOutputRequest().withInstanceId(machine.getExternalId()));
+        if (result.getOutput() != null) {
+            String content = new String(Base64.decode(result.getOutput()), Charsets.UTF_8);
+            LOG.info("<< Console output for instance {}: {}", machine.getExternalId(), content);
+        } else {
+            LOG.warn("<< Console output was null for instance {}", machine.getExternalId());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExists.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExists.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExists.java
new file mode 100644
index 0000000..38098c6
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExists.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
+import com.amazonaws.services.ec2.model.ImportKeyPairRequest;
+import com.amazonaws.services.ec2.model.ImportKeyPairResult;
+import org.apache.provisionr.amazon.core.ErrorCodes;
+import org.apache.provisionr.amazon.core.KeyPairs;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnsureKeyPairExists extends AmazonActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EnsureKeyPairExists.class);
+
+    public EnsureKeyPairExists(ProviderClientCache cache) {
+        super(cache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
+        String keyName = KeyPairs.formatNameFromBusinessKey(execution.getProcessBusinessKey());
+        LOG.info(">> Importing admin access key pair as {}", keyName);
+
+        final String publicKey = pool.getAdminAccess().getPublicKey();
+        try {
+            importPoolPublicKeyPair(client, keyName, publicKey);
+
+        } catch (AmazonServiceException e) {
+            if (e.getErrorCode().equals(ErrorCodes.DUPLICATE_KEYPAIR)) {
+                LOG.info("<< Duplicate key pair found. Re-importing from pool description");
+
+                client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(keyName));
+                importPoolPublicKeyPair(client, keyName, publicKey);
+            }
+        }
+    }
+
+    private void importPoolPublicKeyPair(AmazonEC2 client, String keyName, String publicKey) {
+        ImportKeyPairResult result = client.importKeyPair(new ImportKeyPairRequest()
+            .withKeyName(keyName).withPublicKeyMaterial(publicKey));
+        LOG.info("<< Created remote key with fingerprint {}", result.getKeyFingerprint());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExists.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExists.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExists.java
new file mode 100644
index 0000000..e46fbd7
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExists.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
+import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
+import com.amazonaws.services.ec2.model.CreateSecurityGroupResult;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
+import com.amazonaws.services.ec2.model.IpPermission;
+import com.amazonaws.services.ec2.model.RevokeSecurityGroupIngressRequest;
+import org.apache.provisionr.amazon.core.ErrorCodes;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.amazon.core.SecurityGroups;
+import org.apache.provisionr.amazon.functions.ConvertRuleToIpPermission;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Sets.difference;
+import java.util.Set;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnsureSecurityGroupExists extends AmazonActivity {
+
+    public static final Logger LOG = LoggerFactory.getLogger(EnsureSecurityGroupExists.class);
+
+    public EnsureSecurityGroupExists(ProviderClientCache cache) {
+        super(cache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
+        final String businessKey = execution.getProcessBusinessKey();
+        final String groupName = SecurityGroups.formatNameFromBusinessKey(businessKey);
+
+        try {
+            LOG.info(">> Creating Security Group with name {}", groupName);
+            CreateSecurityGroupRequest request = new CreateSecurityGroupRequest()
+                .withGroupName(groupName).withDescription("Security Group for " + businessKey);
+
+            CreateSecurityGroupResult result = client.createSecurityGroup(request);
+            LOG.info("<< Created Security Group with ID {}", result.getGroupId());
+
+        } catch (AmazonServiceException e) {
+            if (e.getErrorCode().equals(ErrorCodes.DUPLICATE_SECURITY_GROUP)) {
+                LOG.warn(String.format("<< Security Group %s already exists. " +
+                    "Synchronizing ingress rules.", groupName), e);
+            } else {
+                throw Throwables.propagate(e);
+            }
+        }
+
+        synchronizeIngressRules(client, groupName, pool.getNetwork());
+    }
+
+    private void synchronizeIngressRules(AmazonEC2 client, String groupName, Network network) {
+        DescribeSecurityGroupsResult result = client.describeSecurityGroups(
+            new DescribeSecurityGroupsRequest().withGroupNames(groupName));
+
+        Set<IpPermission> existingPermissions = ImmutableSet.copyOf(getOnlyElement(
+            result.getSecurityGroups()).getIpPermissions());
+
+        Set<IpPermission> expectedPermissions = ImmutableSet.copyOf(
+            Iterables.transform(network.getIngress(), ConvertRuleToIpPermission.FUNCTION));
+
+        authorizeIngressRules(client, groupName, difference(expectedPermissions, existingPermissions));
+        revokeIngressRules(client, groupName, difference(existingPermissions, expectedPermissions));
+    }
+
+    private void authorizeIngressRules(AmazonEC2 client, String groupName, Set<IpPermission> ipPermissions) {
+        if (!ipPermissions.isEmpty()) {
+            LOG.info(">> Authorizing Security Group Ingress Rules {} for {}", ipPermissions, groupName);
+
+            AuthorizeSecurityGroupIngressRequest request = new AuthorizeSecurityGroupIngressRequest()
+                .withGroupName(groupName).withIpPermissions(ipPermissions);
+            client.authorizeSecurityGroupIngress(request);
+        }
+    }
+
+    private void revokeIngressRules(AmazonEC2 client, String groupName, Set<IpPermission> ipPermissions) {
+        if (!ipPermissions.isEmpty()) {
+            LOG.info(">> Revoking Security Group Ingress Rules: {} for {}", ipPermissions, groupName);
+
+            RevokeSecurityGroupIngressRequest request = new RevokeSecurityGroupIngressRequest()
+                .withGroupName(groupName).withIpPermissions(ipPermissions);
+            client.revokeSecurityGroupIngress(request);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/GetInstanceIdsFromSpotRequests.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/GetInstanceIdsFromSpotRequests.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/GetInstanceIdsFromSpotRequests.java
new file mode 100644
index 0000000..7fa9b1b
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/GetInstanceIdsFromSpotRequests.java
@@ -0,0 +1,44 @@
+package org.apache.provisionr.amazon.activities;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsRequest;
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsResult;
+import com.amazonaws.services.ec2.model.SpotInstanceRequest;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+
+public class GetInstanceIdsFromSpotRequests extends AmazonActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GetInstanceIdsFromSpotRequests.class);
+    
+    public GetInstanceIdsFromSpotRequests(ProviderClientCache providerClientCache) {
+        super(providerClientCache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
+        LOG.info(">> retrieving instance Ids from spot request Ids");
+
+        @SuppressWarnings("unchecked")
+        List<String> requestIds = 
+                (List<String>) execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
+        DescribeSpotInstanceRequestsResult result = client.describeSpotInstanceRequests(
+                new DescribeSpotInstanceRequestsRequest().withSpotInstanceRequestIds(requestIds));
+        List<String> instanceIds = new ArrayList<String>();
+        for (SpotInstanceRequest spotRequest : result.getSpotInstanceRequests()) {
+            if (spotRequest.getInstanceId() != null) {
+                instanceIds.add(spotRequest.getInstanceId());
+            }
+        }
+        execution.setVariable(ProcessVariables.INSTANCE_IDS, instanceIds);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/PublishListOfMachines.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/PublishListOfMachines.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/PublishListOfMachines.java
new file mode 100644
index 0000000..71d9bc4
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/PublishListOfMachines.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
+import com.amazonaws.services.ec2.model.DescribeInstancesResult;
+import com.amazonaws.services.ec2.model.Instance;
+import com.google.common.base.Function;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Lists;
+import java.util.List;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Use the IDs to retrieve details about the running machines and
+ * store them as a process variable (machines)
+ *
+ * @see Machine
+ */
+public class PublishListOfMachines extends AmazonActivity {
+
+    public static final Logger LOG = LoggerFactory.getLogger(PublishListOfMachines.class);
+
+    public PublishListOfMachines(ProviderClientCache providerClientCache) {
+        super(providerClientCache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
+        @SuppressWarnings("unchecked")
+        List<String> instanceIds = (List<String>) execution.getVariable(ProcessVariables.INSTANCE_IDS);
+        checkNotNull(instanceIds, "%s not found as a process variable", ProcessVariables.INSTANCE_IDS);
+
+        LOG.info(">> Describing instances {}", instanceIds);
+        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
+            .withInstanceIds(instanceIds));
+
+        LOG.info("<< Got the following reservations: {}", result.getReservations());
+
+        List<Instance> instances = collectInstancesFromReservations(result.getReservations());
+        List<Machine> machines = Lists.transform(instances,
+            new Function<Instance, Machine>() {
+                @Override
+                public Machine apply(Instance instance) {
+                    return Machine.builder()
+                        .externalId(instance.getInstanceId())
+                        .publicDnsName(instance.getPublicDnsName())
+                        .publicIp(instance.getPublicIpAddress())
+                        .privateDnsName(instance.getPrivateDnsName())
+                        .privateIp(instance.getPrivateIpAddress())
+                        .createMachine();
+                }
+            });
+
+        /* Create a new ArrayList to force evaluation for lazy collections */
+        execution.setVariable(CoreProcessVariables.MACHINES, Lists.newArrayList(machines));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunInstances.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunInstances.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunInstances.java
new file mode 100644
index 0000000..aa04a2d
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunInstances.java
@@ -0,0 +1,144 @@
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.AmazonWebServiceRequest;
+import com.amazonaws.services.ec2.model.BlockDeviceMapping;
+import com.amazonaws.services.ec2.model.EbsBlockDevice;
+import com.amazonaws.services.ec2.model.LaunchSpecification;
+import com.amazonaws.services.ec2.model.RequestSpotInstancesRequest;
+import com.amazonaws.services.ec2.model.RunInstancesRequest;
+import com.amazonaws.services.ec2.model.SpotInstanceType;
+import com.google.common.base.Charsets;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Strings;
+import com.google.common.base.Throwables;
+import com.google.common.collect.Lists;
+import com.google.common.io.Resources;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.List;
+import net.schmizz.sshj.common.Base64;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.core.ImageTable;
+import org.apache.provisionr.amazon.core.ImageTableQuery;
+import org.apache.provisionr.amazon.core.KeyPairs;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.amazon.core.SecurityGroups;
+import org.apache.provisionr.amazon.options.ProviderOptions;
+import org.apache.provisionr.amazon.options.SoftwareOptions;
+import org.apache.provisionr.api.hardware.BlockDevice;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+
+public abstract class RunInstances extends AmazonActivity {
+
+    public static final String DEFAULT_ARCH = "amd64";
+    public static final String DEFAULT_TYPE = "instance-store";
+    public static final String DEFAULT_AMI_ID = "ami-0cdf4965"; // Ubuntu 12.10 x64
+
+    protected RunInstances(ProviderClientCache providerClientCache) {
+        super(providerClientCache);
+    }
+
+    protected RunInstancesRequest createOnDemandInstancesRequest(Pool pool, DelegateExecution execution)
+        throws IOException {
+        return (RunInstancesRequest) createRequest(pool, execution, false);
+    }
+
+    protected RequestSpotInstancesRequest createSpotInstancesRequest(Pool pool, DelegateExecution execution)
+        throws IOException {
+        return (RequestSpotInstancesRequest) createRequest(pool, execution, true);
+    }
+
+    private AmazonWebServiceRequest createRequest(Pool pool, DelegateExecution execution, boolean spot)
+        throws IOException {
+        final String businessKey = execution.getProcessBusinessKey();
+
+        final String securityGroupName = SecurityGroups.formatNameFromBusinessKey(businessKey);
+        final String keyPairName = KeyPairs.formatNameFromBusinessKey(businessKey);
+
+        final String instanceType = pool.getHardware().getType();
+        final String imageId = getImageIdFromPoolConfigurationOrQueryImageTable(
+            pool, pool.getProvider(), instanceType);
+
+        final String userData = Resources.toString(Resources.getResource(RunInstances.class,
+            "/org/apache/provisionr/amazon/userdata.sh"), Charsets.UTF_8);
+
+        List<BlockDevice> blockDevices = pool.getHardware().getBlockDevices();
+        List<BlockDeviceMapping> blockDeviceMappings = Lists.newArrayList();
+        if (blockDevices != null && blockDevices.size() > 0) {
+            for (BlockDevice device : blockDevices) {
+                blockDeviceMappings.add(new BlockDeviceMapping()
+                    .withDeviceName(device.getName())
+                    .withEbs(new EbsBlockDevice()
+                        .withVolumeSize(device.getSize())
+                        .withDeleteOnTermination(true)
+                    ));
+            }
+        }
+
+        if (spot) {
+            Calendar validUntil = Calendar.getInstance();
+            validUntil.add(Calendar.MINUTE, 10);
+            final String spotPrice = checkNotNull(pool.getProvider().getOption(ProviderOptions.SPOT_BID),
+                "The bid for spot instances was not specified");
+            LaunchSpecification ls = new LaunchSpecification()
+                .withInstanceType(instanceType)
+                .withKeyName(keyPairName)
+                .withImageId(imageId)
+                .withBlockDeviceMappings(blockDeviceMappings)
+                .withSecurityGroups(Lists.newArrayList(securityGroupName))
+                .withUserData(Base64.encodeBytes(userData.getBytes(Charsets.UTF_8)));
+            return new RequestSpotInstancesRequest()
+                .withSpotPrice(spotPrice)
+                .withLaunchSpecification(ls)
+                .withLaunchGroup(businessKey)
+                .withInstanceCount(pool.getExpectedSize())
+                .withType(SpotInstanceType.OneTime)
+                .withValidUntil(validUntil.getTime());
+        } else {
+            return new RunInstancesRequest()
+                .withClientToken(businessKey)
+                .withSecurityGroups(securityGroupName)
+                .withKeyName(keyPairName)
+                .withInstanceType(instanceType)
+                .withImageId(imageId)
+                .withBlockDeviceMappings(blockDeviceMappings)
+                .withMinCount(pool.getMinSize())
+                .withMaxCount(pool.getExpectedSize())
+                .withUserData(Base64.encodeBytes(userData.getBytes(Charsets.UTF_8)));
+        }
+    }
+
+    private String getImageIdFromPoolConfigurationOrQueryImageTable(
+        Pool pool, Provider provider, String instanceType
+    ) {
+        final String imageId = pool.getSoftware().getImageId();
+        if (!Strings.isNullOrEmpty(imageId)) {
+            return "default".equals(imageId) ? DEFAULT_AMI_ID : imageId;
+        }
+
+        ImageTable imageTable;
+        try {
+            imageTable = ImageTable.fromCsvResource("/org/apache/provisionr/amazon/ubuntu.csv");
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        }
+
+        final String region = provider.getOptionOr(ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION);
+        final String version = provider.getOptionOr(SoftwareOptions.BASE_OPERATING_SYSTEM_VERSION,
+            SoftwareOptions.DEFAULT_BASE_OPERATING_SYSTEM_VERSION);
+
+        ImageTableQuery query = imageTable.query()
+            .filterBy("region", region)
+            .filterBy("version", version)
+            .filterBy("arch", DEFAULT_ARCH);
+
+        if (instanceType.equals("t1.micro")) {
+            query.filterBy("type", "ebs");
+        } else {
+            query.filterBy("type", DEFAULT_TYPE);
+        }
+
+        return query.singleResult();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunOnDemandInstances.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunOnDemandInstances.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunOnDemandInstances.java
new file mode 100644
index 0000000..b415818
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunOnDemandInstances.java
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+*
+* 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.
+*/
+
+package org.apache.provisionr.amazon.activities;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.Instance;
+import com.amazonaws.services.ec2.model.RunInstancesRequest;
+import com.amazonaws.services.ec2.model.RunInstancesResult;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+
+public class RunOnDemandInstances extends RunInstances {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RunOnDemandInstances.class);
+
+    public static final String DEFAULT_ARCH = "amd64";
+    public static final String DEFAULT_TYPE = "instance-store";
+
+    public RunOnDemandInstances(ProviderClientCache cache) {
+        super(cache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws IOException {
+
+        final RunInstancesRequest request = createOnDemandInstancesRequest(pool, execution);
+        // TODO allow for more options (e.g. monitoring & termination protection etc.)
+
+        LOG.info(">> Sending RunInstances request: {}", request);
+        RunInstancesResult result = client.runInstances(request);
+        LOG.info("<< Got RunInstances result: {}", result);
+
+        // TODO tag instances: managed-by: Apache Provisionr, business-key: ID etc.
+
+        execution.setVariable(ProcessVariables.RESERVATION_ID,
+            result.getReservation().getReservationId());
+        execution.setVariable(ProcessVariables.INSTANCE_IDS,
+            collectInstanceIdsAsList(result.getReservation().getInstances()));
+    }
+
+
+    private List<String> collectInstanceIdsAsList(List<Instance> instances) {
+        /* Make a copy as an ArrayList to force lazy collection evaluation */
+        return Lists.newArrayList(Lists.transform(instances,
+            new Function<Instance, String>() {
+                @Override
+                public String apply(Instance instance) {
+                    return instance.getInstanceId();
+                }
+            }));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunSpotInstances.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunSpotInstances.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunSpotInstances.java
new file mode 100644
index 0000000..0a1d06b
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/RunSpotInstances.java
@@ -0,0 +1,100 @@
+/*
+* Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+*
+* 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.
+*/
+package org.apache.provisionr.amazon.activities;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsRequest;
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsResult;
+import com.amazonaws.services.ec2.model.Filter;
+import com.amazonaws.services.ec2.model.RequestSpotInstancesRequest;
+import com.amazonaws.services.ec2.model.RequestSpotInstancesResult;
+import com.amazonaws.services.ec2.model.SpotInstanceRequest;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Uninterruptibles;
+
+
+public class RunSpotInstances extends RunInstances {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RunSpotInstances.class);
+    
+    public RunSpotInstances(ProviderClientCache cache) {
+        super(cache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
+        /* before sending a new request, we check to see if we already registered
+           a launch group with the process ID, if yes, we don't re-send the request */
+        final String businessKey = execution.getProcessBusinessKey();
+
+        /* we timeout if requests have already been sent - the activity is being retried. */
+        Optional<Object> alreadySent = Optional.fromNullable(
+                execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS));
+
+        if (alreadySent.isPresent()) {
+            DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest()
+                    .withFilters(new Filter()
+                        .withName("launch-group").withValues(businessKey)
+                        .withName("state").withValues("open", "active"));
+            Stopwatch stopwatch = new Stopwatch().start();
+            while (stopwatch.elapsedTime(TimeUnit.MINUTES) < 2) {
+                DescribeSpotInstanceRequestsResult result = client.describeSpotInstanceRequests(describeRequest);
+                List<SpotInstanceRequest> pending = result.getSpotInstanceRequests();
+                if (pending.size() > 0) {
+                    LOG.info("Not resending spot instance requests {} for businessKey: {}.", pending, businessKey);
+                    execution.setVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS, 
+                            collectSpotInstanceRequestIds(pending));
+                    return;
+                }
+                LOG.info("The describe call has not returned anything yet, waiting 20s and retrying.");
+                Uninterruptibles.sleepUninterruptibly(20, TimeUnit.SECONDS);
+            }
+        }
+
+        final RequestSpotInstancesRequest request = createSpotInstancesRequest(pool, execution);
+        execution.setVariable(ProcessVariables.SPOT_REQUESTS_SENT, true);
+        RequestSpotInstancesResult requestResult = client.requestSpotInstances(request);
+        List<String> spotInstanceRequestIds = collectSpotInstanceRequestIds(requestResult.getSpotInstanceRequests());
+
+        execution.setVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS, spotInstanceRequestIds);
+    }
+    
+    private List<String> collectSpotInstanceRequestIds(List<SpotInstanceRequest> requestResponses) {
+        /* Make a copy as an ArrayList to force lazy collection evaluation */
+        return Lists.newArrayList(Lists.transform(requestResponses,
+            new Function<SpotInstanceRequest, String>() {
+                @Override
+                public String apply(SpotInstanceRequest instanceRequest) {
+                    return instanceRequest.getSpotInstanceRequestId();
+                }
+            }));
+    }
+}


[05/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/AmazonActivityLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/AmazonActivityLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/AmazonActivityLiveTest.java
new file mode 100644
index 0000000..2a84985
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/AmazonActivityLiveTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DeleteSecurityGroupRequest;
+import org.apache.provisionr.amazon.AmazonProvisionr;
+import org.apache.provisionr.amazon.options.ProviderOptions;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.amazon.core.ProviderClientCacheSupplier;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.test.Generics;
+import org.apache.provisionr.test.ProvisionrLiveTestSupport;
+import com.google.common.base.Throwables;
+import java.lang.reflect.Constructor;
+import java.util.UUID;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AmazonActivityLiveTest<T extends AmazonActivity> extends ProvisionrLiveTestSupport {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AmazonActivityLiveTest.class);
+
+    protected final String BUSINESS_KEY = "j-" + UUID.randomUUID().toString();
+
+    /**
+     * Cloud provider credentials collected from system properties
+     */
+    protected Provider provider;
+
+    /**
+     * Instance of the AmazonActivity being tested. Automatically created
+     * from the generic type class argument
+     */
+    protected T activity;
+
+    /**
+     * Amazon EC2 client
+     */
+    protected AmazonEC2 client;
+
+    /**
+     * A cache of AmazonEC2 client instances by Provider
+     */
+    private ProviderClientCache clientCache;
+
+    public AmazonActivityLiveTest() {
+        super(AmazonProvisionr.ID);
+    }
+
+    /**
+     * Create an instance using the default constructor for the class type argument
+     *
+     * @param klass
+     * @param clientCache cache for AmazonEC2 client connections
+     */
+    protected <A extends AmazonActivity> A createAmazonActivityInstance(
+        Class<A> klass, ProviderClientCache clientCache
+    ) {
+        try {
+            Constructor<A> constructor = klass.getConstructor(ProviderClientCache.class);
+            return (A) constructor.newInstance(clientCache);
+
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    /**
+     * Retrieve the generic class type argument.
+     */
+    protected Class<T> getAmazonActivityClass() {
+        return Generics.getTypeParameter(getClass(), AmazonActivity.class);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        final String region = getProviderProperty(ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION);
+
+        provider = collectProviderCredentialsFromSystemProperties()
+            .option(ProviderOptions.REGION, region).createProvider();
+        LOG.info("Using provider {}", provider);
+
+        clientCache = (new ProviderClientCacheSupplier()).get();
+        client = clientCache.getUnchecked(provider);
+
+        activity = createAmazonActivityInstance(getAmazonActivityClass(), clientCache);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        client.shutdown();
+    }
+
+    protected void executeActivitiesInSequence(
+        DelegateExecution execution, Class<? extends AmazonActivity>... classes
+    ) throws Exception {
+        for (Class<? extends AmazonActivity> klass : classes) {
+            createAmazonActivityInstance(klass, clientCache).execute(execution);
+        }
+    }
+
+    protected void quietlyDeleteSecurityGroupIfExists(String groupName) {
+        try {
+            client.deleteSecurityGroup(new DeleteSecurityGroupRequest().withGroupName(groupName));
+
+        } catch (AmazonServiceException e) {
+            if (!e.getErrorCode().equals("InvalidGroup.NotFound")) {
+                throw Throwables.propagate(e);
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/CreatePoolLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/CreatePoolLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/CreatePoolLiveTest.java
new file mode 100644
index 0000000..18e0644
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/CreatePoolLiveTest.java
@@ -0,0 +1,72 @@
+package org.apache.provisionr.amazon.activities;
+
+import java.util.ArrayList;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.hardware.BlockDevice;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public abstract class CreatePoolLiveTest<T extends AmazonActivity> extends AmazonActivityLiveTest<T> {
+
+    protected DelegateExecution execution;
+    protected Pool pool;
+    protected Hardware hardware;
+    protected Software software;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        execution = mock(DelegateExecution.class);
+        pool = mock(Pool.class);
+
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .username("admin")
+            .publicKey(getResourceAsString("keys/test.pub"))
+            .privateKey(getResourceAsString("keys/test"))
+            .createAdminAccess();
+
+        final Network network = Network.builder().addRules(
+            Rule.builder().anySource().tcp().port(22).createRule()).createNetwork();
+
+        hardware = mock(Hardware.class);
+        when(hardware.getType()).thenReturn("t1.micro");
+        when(hardware.getBlockDevices()).thenReturn(new ArrayList<BlockDevice>());
+
+        software = mock(Software.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+        when(pool.getNetwork()).thenReturn(network);
+
+        when(pool.getMinSize()).thenReturn(1);
+        when(pool.getExpectedSize()).thenReturn(1);
+
+        when(pool.getHardware()).thenReturn(hardware);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+
+        executeActivitiesInSequence(execution,
+            EnsureKeyPairExists.class,
+            EnsureSecurityGroupExists.class
+        );
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void tearDown() throws Exception {
+        executeActivitiesInSequence(execution,
+            DeleteSecurityGroup.class,
+            DeleteKeyPair.class
+        );
+        super.tearDown();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteKeyPairLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteKeyPairLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteKeyPairLiveTest.java
new file mode 100644
index 0000000..5257c85
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteKeyPairLiveTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
+import com.amazonaws.services.ec2.model.DescribeKeyPairsRequest;
+import com.amazonaws.services.ec2.model.DescribeKeyPairsResult;
+import com.amazonaws.services.ec2.model.ImportKeyPairRequest;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.core.ErrorCodes;
+import org.apache.provisionr.amazon.core.KeyPairs;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DeleteKeyPairLiveTest extends AmazonActivityLiveTest<DeleteKeyPair> {
+
+    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        client.importKeyPair(new ImportKeyPairRequest().withKeyName(KEYPAIR_NAME)
+            .withPublicKeyMaterial(getResourceAsString("keys/test.pub")));
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(KEYPAIR_NAME));
+        super.tearDown();
+    }
+
+    @Test
+    public void testDeleteKeyPair() throws Exception {
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .username("admin")
+            .publicKey(getResourceAsString("keys/test.pub"))
+            .privateKey(getResourceAsString("keys/test"))
+            .createAdminAccess();
+
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+        when(pool.getProvider()).thenReturn(provider);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+
+        activity.execute(execution);
+        assertKeyNotFound(KEYPAIR_NAME);
+
+        /* the second call should just do nothing */
+        activity.execute(execution);
+    }
+
+    public void assertKeyNotFound(String keyName) {
+        final DescribeKeyPairsRequest request = new DescribeKeyPairsRequest().withKeyNames(keyName);
+        try {
+            DescribeKeyPairsResult result = client.describeKeyPairs(request);
+            fail("Found key " + result.getKeyPairs().get(0));
+
+        } catch (AmazonServiceException e) {
+            assertThat(e.getErrorCode()).isEqualTo(ErrorCodes.KEYPAIR_NOT_FOUND);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java
new file mode 100644
index 0000000..245af79
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.core.SecurityGroups;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.fest.assertions.api.Assertions.fail;
+import org.junit.After;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DeleteSecurityGroupLiveTest extends AmazonActivityLiveTest<DeleteSecurityGroup> {
+
+    private final String SECURITY_GROUP_NAME = SecurityGroups.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @After
+    public void tearDown() throws Exception {
+        quietlyDeleteSecurityGroupIfExists(SECURITY_GROUP_NAME);
+        super.tearDown();
+    }
+
+    @Test
+    public void testDeleteSecurityGroup() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+
+        client.createSecurityGroup(new CreateSecurityGroupRequest()
+            .withGroupName(SECURITY_GROUP_NAME).withDescription("Just for test"));
+
+        activity.execute(execution);
+
+        try {
+            client.describeSecurityGroups(new DescribeSecurityGroupsRequest()
+                .withGroupNames(SECURITY_GROUP_NAME));
+            fail("Did not throw AmazonServiceException as expected");
+
+        } catch (AmazonServiceException e) {
+            assertThat(e.getErrorCode()).isEqualTo("InvalidGroup.NotFound");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java
new file mode 100644
index 0000000..8eebf13
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
+import com.amazonaws.services.ec2.model.DescribeKeyPairsRequest;
+import com.amazonaws.services.ec2.model.DescribeKeyPairsResult;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.core.KeyPairs;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class EnsureKeyPairExistsLiveTest extends AmazonActivityLiveTest<EnsureKeyPairExists> {
+
+    /**
+     * Computed in an Amazon specific way
+     */
+    public static final String TEST_KEY_FINGERPRINT = "2f:e9:a0:bc:17:71:3a:7e:d7:c0:16:99:0d:62:8e:be";
+
+    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @Override
+    public void tearDown() throws Exception {
+        client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(KEYPAIR_NAME));
+        super.tearDown();
+    }
+
+    @Test
+    public void testEnsureKeyPairExists() throws Exception {
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .username("admin")
+            .publicKey(getResourceAsString("keys/test.pub"))
+            .privateKey(getResourceAsString("keys/test"))
+            .createAdminAccess();
+
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+
+        activity.execute(execution);
+        assertKeyPairWasImportedAsExpected();
+
+        /* the second call should just re-import the key */
+        activity.execute(execution);
+        assertKeyPairWasImportedAsExpected();
+    }
+
+    private void assertKeyPairWasImportedAsExpected() {
+        final DescribeKeyPairsRequest request = new DescribeKeyPairsRequest().withKeyNames(KEYPAIR_NAME);
+        DescribeKeyPairsResult result = client.describeKeyPairs(request);
+
+        assertThat(result.getKeyPairs()).hasSize(1);
+        assertThat(result.getKeyPairs().get(0).getKeyFingerprint()).isEqualTo(TEST_KEY_FINGERPRINT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java
new file mode 100644
index 0000000..d4fc69b
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
+import com.amazonaws.services.ec2.model.IpPermission;
+import com.amazonaws.services.ec2.model.RevokeSecurityGroupIngressRequest;
+import com.amazonaws.services.ec2.model.SecurityGroup;
+import com.google.common.collect.ImmutableSet;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Lists.newArrayList;
+import com.google.common.collect.Sets;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.core.SecurityGroups;
+import org.apache.provisionr.amazon.functions.ConvertIpPermissionToRule;
+import org.apache.provisionr.amazon.functions.ConvertRuleToIpPermission;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.After;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnsureSecurityGroupExistsLiveTest extends AmazonActivityLiveTest<EnsureSecurityGroupExists> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EnsureSecurityGroupExistsLiveTest.class);
+
+    protected final String SECURITY_GROUP_NAME = SecurityGroups.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @After
+    public void tearDown() throws Exception {
+        quietlyDeleteSecurityGroupIfExists(SECURITY_GROUP_NAME);
+        super.tearDown();
+    }
+
+    @Test
+    public void testCreateSecurityGroup() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+
+        final ImmutableSet<Rule> ingressRules = ImmutableSet.of(
+            Rule.builder().anySource().icmp().createRule(),
+            Rule.builder().anySource().port(22).tcp().createRule(),
+            Rule.builder().anySource().port(53).udp().createRule()
+        );
+
+        final Network network = Network.builder().ingress(ingressRules).createNetwork();
+
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getNetwork()).thenReturn(network);
+
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+
+        activity.execute(execution);
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, ingressRules);
+
+        /* If any permissions is removed it should converge on a second run */
+        Set<Rule> expectedAfterRevoke = revokeAnyRule(ingressRules);
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, expectedAfterRevoke);
+
+        activity.execute(execution);
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, ingressRules);
+
+        /* If any permissions is added it should converge on a second run */
+        final IpPermission permission = new IpPermission().withIpProtocol("tcp")
+            .withIpRanges("0.0.0.0/0").withFromPort(100).withToPort(120);
+
+        client.authorizeSecurityGroupIngress(new AuthorizeSecurityGroupIngressRequest()
+            .withGroupName(SECURITY_GROUP_NAME).withIpPermissions(permission));
+
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, Sets.<Rule>union(ingressRules,
+            ImmutableSet.of(ConvertIpPermissionToRule.FUNCTION.apply(permission))));
+
+        activity.execute(execution);
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, ingressRules);
+    }
+
+    private Set<Rule> revokeAnyRule(Set<Rule> ingressRules) {
+        List<IpPermission> permissions = newArrayList(transform(ingressRules, ConvertRuleToIpPermission.FUNCTION));
+        Collections.shuffle(permissions);
+
+        IpPermission permission = permissions.get(0);
+        LOG.info(">> Revoking permission {} on {} for test.", permission, SECURITY_GROUP_NAME);
+
+        client.revokeSecurityGroupIngress(new RevokeSecurityGroupIngressRequest()
+            .withGroupName(SECURITY_GROUP_NAME).withIpPermissions(permission));
+
+        return Sets.difference(ingressRules, ImmutableSet.of(ConvertIpPermissionToRule.FUNCTION.apply(permission)));
+    }
+
+    public void assertSecurityGroupExistsWithRules(String groupName, final Set<Rule> ingressRules) {
+        DescribeSecurityGroupsResult result = client.describeSecurityGroups(
+            new DescribeSecurityGroupsRequest().withGroupNames(groupName));
+
+        assertThat(result.getSecurityGroups()).hasSize(1);
+        SecurityGroup group = getOnlyElement(result.getSecurityGroups());
+
+        assertThat(group.getIpPermissions()).hasSize(ingressRules.size());
+        assertThat(ingressRules).containsAll(transform(group.getIpPermissions(),
+            ConvertIpPermissionToRule.FUNCTION));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/PublishListOfMachinesTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/PublishListOfMachinesTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/PublishListOfMachinesTest.java
new file mode 100644
index 0000000..e65867c
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/PublishListOfMachinesTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
+import com.amazonaws.services.ec2.model.DescribeInstancesResult;
+import com.amazonaws.services.ec2.model.Instance;
+import com.amazonaws.services.ec2.model.Reservation;
+import com.google.common.collect.Lists;
+import java.util.List;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import org.mockito.Matchers;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class PublishListOfMachinesTest {
+
+    @Test
+    public void testPublishListOfMachines() throws Exception {
+        AmazonEC2 client = mock(AmazonEC2.class);
+
+        ProviderClientCache clientCache = mock(ProviderClientCache.class);
+        when(clientCache.get(Matchers.<Provider>any())).thenReturn(client);
+
+        DelegateExecution execution = mock(DelegateExecution.class);
+        List<String> instanceIds = Lists.newArrayList("i-123", "i-456");
+        when(execution.getVariable(ProcessVariables.INSTANCE_IDS)).thenReturn(instanceIds);
+
+        when(client.describeInstances(Matchers.<DescribeInstancesRequest>any()))
+            .thenReturn(new DescribeInstancesResult()
+                .withReservations(new Reservation().withInstances(
+                    new Instance().withInstanceId("i-123").withPublicDnsName("i1.amazonaws.com")
+                        .withPublicIpAddress("1.2.3.4").withPrivateDnsName("i1.internal").withPrivateIpAddress("10.1.2.3"),
+                    new Instance().withInstanceId("i-456").withPublicDnsName("i2.amazonaws.com")
+                        .withPublicIpAddress("5.6.7.8").withPrivateDnsName("i2.internal").withPrivateIpAddress("10.4.5.6")
+                )));
+
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        AmazonActivity activity = new PublishListOfMachines(clientCache);
+        activity.execute(client, null /* not used */, execution);
+
+        @SuppressWarnings("unchecked")
+        List<Machine> machines = (List<Machine>) collector.getVariable(CoreProcessVariables.MACHINES);
+
+        assertThat(machines).hasSize(2);
+        assertThat(machines.get(0).getPublicDnsName()).isEqualTo("i1.amazonaws.com");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java
new file mode 100644
index 0000000..58745c6
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
+import com.amazonaws.services.ec2.model.DescribeInstancesResult;
+import com.amazonaws.services.ec2.model.DescribeVolumesRequest;
+import com.amazonaws.services.ec2.model.DescribeVolumesResult;
+import com.amazonaws.services.ec2.model.Instance;
+import com.amazonaws.services.ec2.model.InstanceBlockDeviceMapping;
+import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
+import com.amazonaws.services.ec2.model.Volume;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.api.hardware.BlockDevice;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Uninterruptibles;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+
+public class RunOnDemandInstancesLiveTest extends CreatePoolLiveTest<RunOnDemandInstances> {
+
+    private static final String UBUNTU_AMI_ID = "ami-1e831d77"; // Ubuntu 13.04 amd64
+    private ProcessVariablesCollector collector;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        collector = new ProcessVariablesCollector();
+        collector.install(execution);
+    }
+
+    @Test
+    public void testRunInstances() throws Exception {
+
+        activity.execute(execution);
+
+        verify(execution).setVariable(eq(ProcessVariables.RESERVATION_ID), anyString());
+        verify(execution).setVariable(eq(ProcessVariables.INSTANCE_IDS), any());
+
+        @SuppressWarnings("unchecked")
+        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
+
+        /* the second call should do nothing */
+        activity.execute(execution);
+
+        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
+            .withInstanceIds(instanceIds));
+
+        assertThat(result.getReservations()).hasSize(1);
+        assertThat(result.getReservations().get(0).getInstances()).hasSize(1);
+
+    }
+
+    @Test
+    public void testRunInstancesWithBlockDevices() throws Exception {
+        // TODO: maybe we should also test for spot instances
+        BlockDevice blockDevice = mock(BlockDevice.class);
+        when(blockDevice.getSize()).thenReturn(8); // TODO: understand why it doesn't work for smaller volumes
+        when(blockDevice.getName()).thenReturn("/dev/sda1");
+        BlockDevice blockDevice2 = mock(BlockDevice.class);
+        when(blockDevice2.getSize()).thenReturn(16);
+        when(blockDevice2.getName()).thenReturn("/dev/sda4");
+        when(hardware.getBlockDevices()).thenReturn(Lists.newArrayList(blockDevice, blockDevice2));
+
+        activity.execute(execution);
+
+        Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS);
+
+        @SuppressWarnings("unchecked")
+        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
+        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
+            .withInstanceIds(instanceIds));
+
+        Instance instance = result.getReservations().get(0).getInstances().get(0);
+        List<InstanceBlockDeviceMapping> bdm = instance.getBlockDeviceMappings();
+        assertThat(bdm).hasSize(2);
+        List<String> volumeIds = Lists.newArrayList();
+        for (int i = 0; i < bdm.size(); i++) {
+            assertThat(bdm.get(i).getDeviceName()).isEqualTo("/dev/sda" + ((i+1) * (i+1)));
+            assertThat(bdm.get(i).getEbs().getDeleteOnTermination()).isTrue();
+            volumeIds.add(bdm.get(i).getEbs().getVolumeId());
+        }
+
+        DescribeVolumesResult volumesResult = client.describeVolumes(
+                new DescribeVolumesRequest().withVolumeIds(volumeIds));
+        for (Volume volume : volumesResult.getVolumes()) {
+            assertThat(volume.getState()).isIn(Lists.newArrayList("creating", "available", "in-use"));
+        }
+        assertThat(volumesResult.getVolumes().get(0).getSize()).isNotEqualTo(volumesResult.getVolumes().get(1).getSize());
+    }
+
+    @Test
+    public void testRunInstancesWithABaseImageId() throws Exception {
+        when(software.getImageId()).thenReturn(UBUNTU_AMI_ID);
+        when(pool.getSoftware()).thenReturn(software);
+        activity.execute(execution);
+
+        @SuppressWarnings("unchecked")
+        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
+        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
+            .withInstanceIds(instanceIds));
+
+        Instance instance = result.getReservations().get(0).getInstances().get(0);
+        assertThat(instance.getImageId()).isEqualTo(UBUNTU_AMI_ID);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        @SuppressWarnings("unchecked")
+        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
+        client.terminateInstances(new TerminateInstancesRequest().withInstanceIds(instanceIds));
+
+        // TODO: this behaves strangely, if it tries to delete the security group 
+        // and the instances are not yet killed, the test fails with an error
+        Uninterruptibles.sleepUninterruptibly(45, TimeUnit.SECONDS);
+        super.tearDown();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunSpotInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunSpotInstancesLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunSpotInstancesLiveTest.java
new file mode 100644
index 0000000..0e526da
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunSpotInstancesLiveTest.java
@@ -0,0 +1,107 @@
+/*
+* Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+*
+* 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.
+*/
+
+package org.apache.provisionr.amazon.activities;
+
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsRequest;
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsResult;
+import com.amazonaws.services.ec2.model.Filter;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.options.ProviderOptions;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import com.google.common.util.concurrent.Uninterruptibles;
+
+public class RunSpotInstancesLiveTest extends CreatePoolLiveTest<RunSpotInstances> {
+
+    /**
+     * This should be set a bit higher than the on demand instance
+     * price to avoid the situation in which the test fails because
+     * the spot bid is too low. 
+     */
+    public static String AMAZON_SPOT_BID = "0.04";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        final String region = getProviderProperty(ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION);
+        provider = collectProviderCredentialsFromSystemProperties()
+                .option(ProviderOptions.REGION, region)
+                .option(ProviderOptions.SPOT_BID, AMAZON_SPOT_BID)
+                .createProvider();
+        when(pool.getProvider()).thenReturn(provider);
+    }
+
+    @Test
+    public void testRunSpotInstances() throws Exception {
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        activity.execute(execution);
+
+        @SuppressWarnings("unchecked")
+        ArgumentCaptor<List<String>> argument = (ArgumentCaptor<List<String>>) 
+                (Object) ArgumentCaptor.forClass(List.class);
+        verify(execution).setVariable(eq(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS), argument.capture());
+        when(execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS)).thenReturn(argument.getValue());
+        /* The timeout is needed because the describe calls don't return immediately. */
+        // TODO: see if we can eliminate this after adding the process variables conditions
+        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES);
+
+        // shouldn't do anything
+        activity.execute(execution);
+
+        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES);
+
+        DescribeSpotInstanceRequestsResult result = client.describeSpotInstanceRequests(
+                new DescribeSpotInstanceRequestsRequest().withFilters(new Filter()
+                    .withName("launch-group").withValues(BUSINESS_KEY)));
+
+        assertThat(result.getSpotInstanceRequests()).hasSize(1);
+        /* we also need to sleep before the teardown */
+        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void tearDown() throws Exception {
+        // cleanup any pending requests or instances
+        ArgumentCaptor<List<String>> argument = (ArgumentCaptor<List<String>>) 
+                (Object) ArgumentCaptor.forClass(List.class);
+
+        executeActivitiesInSequence(execution,
+                CancelSpotRequests.class, 
+                GetInstanceIdsFromSpotRequests.class);
+
+        verify(execution).setVariable(eq(ProcessVariables.INSTANCE_IDS), argument.capture());
+        when(execution.getVariable(ProcessVariables.INSTANCE_IDS)).thenReturn(argument.getValue());
+
+        executeActivitiesInSequence(execution, TerminateInstances.class);
+        super.tearDown();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/SetupAdminAccessTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/SetupAdminAccessTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/SetupAdminAccessTest.java
new file mode 100644
index 0000000..2f21a6f
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/SetupAdminAccessTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.activities.PuppetActivity;
+import org.apache.provisionr.test.TestConstants;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class SetupAdminAccessTest {
+
+    @Test
+    public void testCreatePuppetScript() throws Exception {
+        Pool pool = mock(Pool.class);
+
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .privateKey(TestConstants.PRIVATE_KEY)
+            .publicKey(TestConstants.PUBLIC_KEY)
+            .username(System.getProperty("user.name"))
+            .createAdminAccess();
+
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+
+        PuppetActivity activity = new SetupAdminAccess();
+        String content = activity.createPuppetScript(pool, null);
+
+        final String username = adminAccess.getUsername();
+
+        assertThat(content).contains(username)
+            .contains(adminAccess.getPublicKey().split(" ")[1])
+            .contains(String.format("user { \"%s\":", username))
+            .contains(String.format("file { \"/home/%s/.ssh\":", username));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/TerminateInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/TerminateInstancesLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/TerminateInstancesLiveTest.java
new file mode 100644
index 0000000..a095c4a
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/TerminateInstancesLiveTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import org.junit.Test;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class TerminateInstancesLiveTest extends CreatePoolLiveTest<TerminateInstances> {
+
+    private ProcessVariablesCollector collector;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        collector = new ProcessVariablesCollector();
+        collector.install(execution);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testTerminateInstances() throws Exception {
+        executeActivitiesInSequence(execution,
+                EnsureKeyPairExists.class,
+                EnsureSecurityGroupExists.class,
+                RunOnDemandInstances.class
+            );
+
+        when(execution.getVariable(ProcessVariables.INSTANCE_IDS))
+            .thenReturn(collector.getVariable(ProcessVariables.INSTANCE_IDS));
+
+        activity.execute(execution);
+
+        /* the second execution should do nothing */
+        activity.execute(execution);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testTerminateInstancesNoIdsPresent() throws Exception {
+        executeActivitiesInSequence(execution,
+                EnsureKeyPairExists.class,
+                EnsureSecurityGroupExists.class
+            );
+        when(execution.getVariable(ProcessVariables.INSTANCE_IDS)).thenReturn(null);
+
+        // should not throw any exception and should not do anything
+        activity.execute(execution);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/config/DefaultProviderConfigTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/config/DefaultProviderConfigTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/config/DefaultProviderConfigTest.java
new file mode 100644
index 0000000..394d526
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/config/DefaultProviderConfigTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.config;
+
+import org.apache.provisionr.api.provider.Provider;
+import com.google.common.base.Optional;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class DefaultProviderConfigTest {
+
+    @Test
+    public void testProviderIsAbsentIfCredentialsAreEmpty() {
+        DefaultProviderConfig config = new DefaultProviderConfig("", "", "us-east-1", "");
+        assertThat(config.createProvider().isPresent()).isFalse();
+    }
+
+    @Test
+    public void testProviderWithNoRegionAndEndpoint() {
+        DefaultProviderConfig config = new DefaultProviderConfig("access", "secret", "", "");
+
+        Optional<Provider> provider = config.createProvider();
+        assertThat(provider.isPresent()).isTrue();
+
+        assertThat(provider.get().getEndpoint().isPresent()).isFalse();
+        assertThat(provider.get().getOptions().containsKey("region")).isFalse();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableQueryTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableQueryTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableQueryTest.java
new file mode 100644
index 0000000..145c77e
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableQueryTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.core;
+
+import java.io.IOException;
+import org.junit.Test;
+
+public class ImageTableQueryTest {
+
+    public final ImageTable table;
+
+    public ImageTableQueryTest() throws IOException {
+        this.table = ImageTable.fromCsvResource("/org/apache/provisionr/amazon/ubuntu.csv");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testQueryFailsWithMultipleResults() {
+        table.query().filterBy("region", "us-east-1").singleResult();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableTest.java
new file mode 100644
index 0000000..50c7f1c
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.core;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Table;
+import com.google.common.collect.Tables;
+import java.io.IOException;
+import java.util.Map;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class ImageTableTest {
+
+    @Test
+    public void testLoadAmiTableFromResource() throws IOException {
+        ImageTable table = ImageTable.fromCsvResource("/org/apache/provisionr/amazon/ubuntu.csv");
+
+        String id = table.query().filterBy("region", "us-east-1").filterBy("version", "12.04 LTS")
+            .filterBy("arch", "amd64").filterBy("type", "instance-store").singleResult();
+
+        assertThat(id).isEqualTo("ami-9a873ff3");
+    }
+
+    @Test
+    public void testExtractHeaderLine() throws Exception {
+        Iterable<String> headers = ImageTable.extractHeaders(ImmutableList.of("a,b,c", "1,2,3"));
+        assertThat(headers).containsAll(ImmutableList.of("a", "b", "c"));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testCombineHeadersWithLinePartsAsTableCells() {
+        final ImmutableList<String> headers = ImmutableList.of("a", "b");
+        final ImmutableList<String> lineParts = ImmutableList.of("1", "2");
+
+        Iterable<Table.Cell<String, String, String>> cells =
+            ImageTable.combineHeadersWithLinePartsAsTableCells(0, headers, lineParts);
+
+        assertThat(cells).contains(Tables.immutableCell("0", "a", "1"));
+    }
+
+    @Test
+    public void testZipIterators() {
+        Iterable<Map.Entry<String, String>> entries = ImageTable.zip(
+            ImmutableList.of("a", "b"), ImmutableList.of("1", "2"));
+
+        assertThat(entries).containsAll(ImmutableList.of(
+            Maps.immutableEntry("a", "1"), Maps.immutableEntry("b", "2")));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java
new file mode 100644
index 0000000..9016344
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.functions;
+
+import com.amazonaws.services.ec2.model.IpPermission;
+import org.apache.provisionr.api.network.Protocol;
+import org.apache.provisionr.api.network.Rule;
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.junit.Assert.assertNotNull;
+import org.junit.Test;
+
+public class ConvertIpPermissionToRuleAndBackTest {
+
+    @Test
+    public void testConvertTcpIpPermissionToRuleAndBack() {
+        IpPermission expected = new IpPermission().withFromPort(1).withToPort(1024)
+            .withIpProtocol("tcp").withIpRanges("0.0.0.0/0");
+
+        Rule rule = ConvertIpPermissionToRule.FUNCTION.apply(expected);
+        assertNotNull(rule);
+
+        assertThat(rule.getCidr()).isEqualTo("0.0.0.0/0");
+        assertThat(rule.getProtocol()).isEqualTo(Protocol.TCP);
+
+        assertThat(rule.getPorts().lowerEndpoint()).isEqualTo(1);
+        assertThat(rule.getPorts().upperEndpoint()).isEqualTo(1024);
+
+        IpPermission actual = ConvertRuleToIpPermission.FUNCTION.apply(rule);
+        assertThat(actual).isEqualTo(expected);
+    }
+
+    @Test
+    public void testConvertIcmpPermissionToRule() {
+        IpPermission expected = new IpPermission().withIpProtocol("icmp")
+            .withFromPort(-1).withToPort(-1).withIpRanges("0.0.0.0/0");
+
+        Rule rule = ConvertIpPermissionToRule.FUNCTION.apply(expected);
+        assertNotNull(rule);
+
+        assertThat(rule.getProtocol()).isEqualTo(Protocol.ICMP);
+        assertThat(rule.getCidr()).isEqualTo("0.0.0.0/0");
+
+        IpPermission actual = ConvertRuleToIpPermission.FUNCTION.apply(rule);
+        assertThat(actual).isEqualTo(expected);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack-tests/pom.xml
----------------------------------------------------------------------
diff --git a/providers/cloudstack-tests/pom.xml b/providers/cloudstack-tests/pom.xml
index 9ba2f5a..b4eba7e 100644
--- a/providers/cloudstack-tests/pom.xml
+++ b/providers/cloudstack-tests/pom.xml
@@ -15,25 +15,26 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: CloudStack Integration Tests</name>
+    <name>Apache Provisionr :: CloudStack Integration Tests</name>
     <artifactId>provisionr-cloudstack-tests</artifactId>
 
-    <dependencies>    
+    <dependencies>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-cloudstack</artifactId>
         </dependency>
         <dependency>
@@ -41,12 +42,12 @@
             <artifactId>activiti-engine</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-features</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-test-support</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack-tests/src/test/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack-tests/src/test/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionrLiveTest.java b/providers/cloudstack-tests/src/test/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
deleted file mode 100644
index 2a892ed..0000000
--- a/providers/cloudstack-tests/src/test/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.software.Software;
-import static com.axemblr.provisionr.test.KarafTests.installProvisionrFeatures;
-import static com.axemblr.provisionr.test.KarafTests.installProvisionrTestSupportBundle;
-import static com.axemblr.provisionr.test.KarafTests.passThroughAllSystemPropertiesWithPrefix;
-import static com.axemblr.provisionr.test.KarafTests.useDefaultKarafAsInProjectWithJunitBundles;
-import com.axemblr.provisionr.test.ProvisionrLiveTestSupport;
-import java.security.Security;
-import java.util.UUID;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import static org.ops4j.pax.exam.CoreOptions.maven;
-import static org.ops4j.pax.exam.CoreOptions.scanFeatures;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.Configuration;
-import org.ops4j.pax.exam.junit.ExamReactorStrategy;
-import org.ops4j.pax.exam.junit.JUnit4TestRunner;
-import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
-
-@RunWith(JUnit4TestRunner.class)
-@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
-public class CloudStackProvisionrLiveTest extends ProvisionrLiveTestSupport {
-
-    public CloudStackProvisionrLiveTest() {
-        super(CloudStackProvisionr.ID);
-    }
-
-    @Configuration
-    public Option[] configuration() throws Exception {
-        return new Option[]{
-            useDefaultKarafAsInProjectWithJunitBundles(),
-            passThroughAllSystemPropertiesWithPrefix("test.cloudstack."),
-            scanFeatures(maven().groupId("org.jclouds.karaf").artifactId("jclouds-karaf")
-                .type("xml").classifier("features").versionAsInProject(), "jclouds-api-cloudstack"),
-            installProvisionrFeatures("axemblr-provisionr-cloudstack"),
-            installProvisionrTestSupportBundle()
-        };
-    }
-
-    @Test
-    public void startProvisioningProcess() throws Exception {
-        waitForProcessDeployment(CloudStackProvisionr.ID);
-        Provisionr provisionr = getOsgiService(Provisionr.class, 5000);
-
-//        listAvailableJceProviders();
-
-        final Provider provider = collectProviderCredentialsFromSystemProperties()
-            // TODO: get more options as needed for CloudStack
-            .createProvider();
-
-        final Network network = Network.builder()
-            .addRules(Rule.builder().anySource().tcp().port(22).createRule())
-            .createNetwork();
-
-        final Software software = Software.builder().imageId("ubuntu-10.04")
-            .packages("nginx").createSoftware();
-
-        final AdminAccess adminAccess = AdminAccess.builder().asCurrentUser().createAdminAccess();
-
-        final Hardware hardware = Hardware.builder().type("offering").createHardware();
-
-        final Pool pool = Pool.builder().network(network).provider(provider).adminAccess(adminAccess)
-            .software(software).hardware(hardware).minSize(1).expectedSize(1).createPool();
-
-        String processId = provisionr.startPoolManagementProcess(UUID.randomUUID().toString(), pool);
-        waitForProcessEnd(processId);
-        // TODO: check that the environment is clean
-    }
-
-    /**
-     * debug utility method for https://github.com/axemblr/axemblr-provisionr/issues/80
-     */
-    private void listAvailableJceProviders() {
-        for (java.security.Provider provider : Security.getProviders()) {
-            System.out.println(provider.toString());
-            for (java.security.Provider.Service service : provider.getServices()) {
-                System.out.println("\t" + service.toString());
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack-tests/src/test/java/org/apache/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack-tests/src/test/java/org/apache/provisionr/cloudstack/CloudStackProvisionrLiveTest.java b/providers/cloudstack-tests/src/test/java/org/apache/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
new file mode 100644
index 0000000..c77f460
--- /dev/null
+++ b/providers/cloudstack-tests/src/test/java/org/apache/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack;
+
+import java.security.Security;
+import java.util.UUID;
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.software.Software;
+import static org.apache.provisionr.test.KarafTests.installProvisionrFeatures;
+import static org.apache.provisionr.test.KarafTests.installProvisionrTestSupportBundle;
+import static org.apache.provisionr.test.KarafTests.passThroughAllSystemPropertiesWithPrefix;
+import static org.apache.provisionr.test.KarafTests.useDefaultKarafAsInProjectWithJunitBundles;
+import org.apache.provisionr.test.ProvisionrLiveTestSupport;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.scanFeatures;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.ExamReactorStrategy;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
+
+@RunWith(JUnit4TestRunner.class)
+@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
+public class CloudStackProvisionrLiveTest extends ProvisionrLiveTestSupport {
+
+    public CloudStackProvisionrLiveTest() {
+        super(CloudStackProvisionr.ID);
+    }
+
+    @Configuration
+    public Option[] configuration() throws Exception {
+        return new Option[]{
+            useDefaultKarafAsInProjectWithJunitBundles(),
+            passThroughAllSystemPropertiesWithPrefix("test.cloudstack."),
+            scanFeatures(maven().groupId("org.jclouds.karaf").artifactId("jclouds-karaf")
+                .type("xml").classifier("features").versionAsInProject(), "jclouds-api-cloudstack"),
+            installProvisionrFeatures("provisionr-cloudstack"),
+            installProvisionrTestSupportBundle()
+        };
+    }
+
+    @Test
+    public void startProvisioningProcess() throws Exception {
+        waitForProcessDeployment(CloudStackProvisionr.ID);
+        Provisionr provisionr = getOsgiService(Provisionr.class, 5000);
+
+//        listAvailableJceProviders();
+
+        final Provider provider = collectProviderCredentialsFromSystemProperties()
+            // TODO: get more options as needed for CloudStack
+            .createProvider();
+
+        final Network network = Network.builder()
+            .addRules(Rule.builder().anySource().tcp().port(22).createRule())
+            .createNetwork();
+
+        final Software software = Software.builder().imageId("ubuntu-10.04")
+            .packages("nginx").createSoftware();
+
+        final AdminAccess adminAccess = AdminAccess.builder().asCurrentUser().createAdminAccess();
+
+        final Hardware hardware = Hardware.builder().type("offering").createHardware();
+
+        final Pool pool = Pool.builder().network(network).provider(provider).adminAccess(adminAccess)
+            .software(software).hardware(hardware).minSize(1).expectedSize(1).createPool();
+
+        String processId = provisionr.startPoolManagementProcess(UUID.randomUUID().toString(), pool);
+        waitForProcessEnd(processId);
+        // TODO: check that the environment is clean
+    }
+
+    /**
+     * debug utility method
+     */
+    private void listAvailableJceProviders() {
+        for (java.security.Provider provider : Security.getProviders()) {
+            System.out.println(provider.toString());
+            for (java.security.Provider.Service service : provider.getServices()) {
+                System.out.println("\t" + service.toString());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/pom.xml
----------------------------------------------------------------------
diff --git a/providers/cloudstack/pom.xml b/providers/cloudstack/pom.xml
index 3dc93f7..f56fc9a 100644
--- a/providers/cloudstack/pom.xml
+++ b/providers/cloudstack/pom.xml
@@ -15,16 +15,17 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: CloudStack</name>
+    <name>Apache Provisionr :: CloudStack</name>
     <artifactId>provisionr-cloudstack</artifactId>
     <packaging>bundle</packaging>
 
@@ -34,15 +35,15 @@
             <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-core</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-test-support</artifactId>
             <scope>test</scope>
             <exclusions>
@@ -188,7 +189,7 @@
                                 </artifact>
                                 <artifact>
                                     <file>
-                                        ${project.build.directory}/classes/com.axemblr.provisionr.cloudstack.cfg
+                                        ${project.build.directory}/classes/org.apache.provisionr.cloudstack.cfg
                                     </file>
                                     <type>cfg</type>
                                     <classifier>defaults</classifier>
@@ -215,7 +216,7 @@
                                 <descriptor>file:${project.build.directory}/classes/features.xml</descriptor>
                             </descriptors>
                             <features>
-                                <feature>axemblr-provisionr-cloudstack</feature>
+                                <feature>provisionr-cloudstack</feature>
                             </features>
                             <repository>target/features-repo</repository>
                         </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionr.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionr.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionr.java
deleted file mode 100644
index 7c1f243..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionr.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.core.CoreConstants;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.axemblr.provisionr.core.ProvisionrSupport;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class CloudStackProvisionr extends ProvisionrSupport {
-
-    private static final Logger LOG = LoggerFactory.getLogger(CloudStackProvisionr.class);
-    public static final String ID = "cloudstack";
-    /**
-     * Process key must match the one in
-     * axemblr-provisionr/providers/cloudstack/src/main/resources/OSGI-INF/activiti/cloudstack.bpmn20.xml
-     */
-    public static final String PROCESS_KEY = "cloudstack";
-
-    private final ProcessEngine processEngine;
-    private final Optional<Provider> defaultProvider;
-
-    public CloudStackProvisionr(ProcessEngine processEngine, DefaultProviderConfig providerConfig) {
-        this.processEngine = checkNotNull(processEngine, "processEngine is null");
-        this.defaultProvider = providerConfig.createProvider();
-
-        if (defaultProvider.isPresent()) {
-            LOG.info("Default provider for CloudStackProvisionr is {}", defaultProvider.get());
-        } else {
-            LOG.info("No default provider configured for CloudStackProvisionr");
-        }
-    }
-
-    @Override
-    public String getId() {
-        return ID;
-    }
-
-    @Override
-    public Optional<Provider> getDefaultProvider() {
-        return defaultProvider;
-    }
-
-    @Override
-    public String startPoolManagementProcess(String businessKey, Pool pool) {
-        Map<String, Object> arguments = Maps.newHashMap();
-
-        arguments.put(CoreProcessVariables.POOL, pool);
-        arguments.put(CoreProcessVariables.PROVIDER, getId());
-        arguments.put(CoreProcessVariables.POOL_BUSINESS_KEY, businessKey);
-        arguments.put(CoreProcessVariables.BOOTSTRAP_TIMEOUT, 
-                convertTimeoutToISO8601TimeDuration(pool.getBootstrapTimeInSeconds()));
-
-        /* Authenticate as kermit to make the process visible in the Explorer UI */
-        processEngine.getIdentityService().setAuthenticatedUserId(CoreConstants.ACTIVITI_EXPLORER_DEFAULT_USER);
-
-        RuntimeService runtimeService = processEngine.getRuntimeService();
-        ProcessInstance instance = runtimeService.startProcessInstanceByKey(PROCESS_KEY, businessKey, arguments);
-
-        return instance.getProcessInstanceId();
-    }
-
-    @Override
-    public void destroyPool(String businessKey) {
-        LOG.info("**** CloudStack (destroyPool) id: " + businessKey);
-        // TODO use triggerSignalEvent as needed
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/DefaultProviderConfig.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/DefaultProviderConfig.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/DefaultProviderConfig.java
deleted file mode 100644
index 6dae538..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/DefaultProviderConfig.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack;
-
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class DefaultProviderConfig {
-
-    private final String endpoint;
-    private final String accessKey;
-    private final String secretKey;
-    private final String zoneId;
-    private final String templateId;
-    private final String serviceOffering;
-
-    public DefaultProviderConfig(
-        String endpoint, String accessKey, String secretKey, String zoneId, String templateId, String serviceOffering
-    ) {
-        this.endpoint = checkNotNull(endpoint, "endpoint is null");
-        this.accessKey = checkNotNull(accessKey, "access key is null");
-        this.secretKey = checkNotNull(secretKey, "secret key is null");
-        this.zoneId = checkNotNull(zoneId, "zone id is null");
-        this.templateId = checkNotNull(templateId, "template id is null");
-        this.serviceOffering = checkNotNull(serviceOffering, "service offering is null");
-    }
-
-    public Optional<Provider> createProvider() {
-        if (accessKey.isEmpty() || secretKey.isEmpty() || endpoint.isEmpty()) {
-            return Optional.absent();
-        }
-        return Optional.of(Provider.builder()
-            .id(CloudStackProvisionr.ID)
-            .endpoint(endpoint)
-            .accessKey(accessKey)
-            .secretKey(secretKey)
-            .option(ProviderOptions.ZONE_ID, zoneId)
-            .option(ProviderOptions.TEMPLATE_ID, templateId)
-            .option(ProviderOptions.SERVICE_OFFERING_ID, serviceOffering)
-            .createProvider());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/NetworkOptions.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/NetworkOptions.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/NetworkOptions.java
deleted file mode 100644
index bc256d3..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/NetworkOptions.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack;
-
-/**
- * {@link com.axemblr.provisionr.api.network.Network Network} configuration is passed via the
- * {@link com.axemblr.provisionr.api.pool.Pool Pool} object. This class stores names for those options.
- */
-public class NetworkOptions {
-
-    private NetworkOptions() {
-        throw new RuntimeException("Do not instantiate");
-    }
-
-    /**
-     * Pass this option if you wish to use an existing CloudStack network.
-     */
-    public static final String EXISTING_NETWORK_ID = "existingNetworkId";
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProcessVariables.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProcessVariables.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProcessVariables.java
deleted file mode 100644
index 97911e3..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProcessVariables.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack;
-
-public class ProcessVariables {
-
-    private ProcessVariables() {
-        // prevent instantiation
-    }
-
-    public static final String NETWORK_ID = "networkId";
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProviderOptions.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProviderOptions.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProviderOptions.java
deleted file mode 100644
index 1fa7125..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProviderOptions.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack;
-
-
-/**
- * Building a pool of VM's on CloudStack requires more knowledge of the cloud's architecture,
- * You need to know things like in what zone to build the pool, the ID's of service offerings, network offerings,
- * and more.
- * <p/>
- * All the information is passed via Provider Options. This class stores some of the option names.
- */
-public class ProviderOptions {
-
-    private ProviderOptions() {
-        throw new RuntimeException(ProviderOptions.class.getName() + " should not be instantiated");
-    }
-
-    public static final String ZONE_ID = "zoneId";
-    public static final String TEMPLATE_ID = "templateId";
-    public static final String SERVICE_OFFERING_ID = "serviceOfferingId";
-    public static final String NETWORK_OFFERING_ID = "networkOfferingId";
-}


[07/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/SetupAdminAccess.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/SetupAdminAccess.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/SetupAdminAccess.java
new file mode 100644
index 0000000..d1f3e1f
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/SetupAdminAccess.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Resources;
+import java.io.IOException;
+import java.util.Map;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.Mustache;
+import org.apache.provisionr.core.activities.PuppetActivity;
+
+public class SetupAdminAccess extends PuppetActivity {
+
+    public static final String DEFAULT_UBUNTU_AMI_USER = "ubuntu";
+
+    public static final String ADMIN_ACCESS_TEMPLATE = "/org/apache/provisionr/amazon/puppet/adminaccess.pp.mustache";
+    public static final String SSHD_CONFIG_TEMPLATE = "/org/apache/provisionr/amazon/puppet/sshd_config.mustache";
+    public static final String SUDOERS_TEMPLATE = "/org/apache/provisionr/amazon/puppet/sudoers";
+
+    public SetupAdminAccess() {
+        super("adminaccess");
+    }
+
+    @Override
+    public AdminAccess overrideAdminAccess(Pool pool) {
+        return pool.getAdminAccess().toBuilder().username(DEFAULT_UBUNTU_AMI_USER).createAdminAccess();
+    }
+
+    @Override
+    public String createPuppetScript(Pool pool, Machine machine) throws Exception {
+        return Mustache.toString(getClass(), ADMIN_ACCESS_TEMPLATE,
+            ImmutableMap.of(
+                "user", pool.getAdminAccess().getUsername(),
+                "publicKey", getRawSshKey(pool))
+        );
+    }
+
+    private String getRawSshKey(Pool pool) {
+        return pool.getAdminAccess().getPublicKey().split(" ")[1];
+    }
+
+    @Override
+    public Map<String, String> createAdditionalFiles(Pool pool, Machine machine) throws IOException {
+        return ImmutableMap.of(
+            "/tmp/sshd_config",
+            Mustache.toString(getClass(), SSHD_CONFIG_TEMPLATE,
+                ImmutableMap.of("user", pool.getAdminAccess().getUsername())),
+            "/tmp/sudoers",
+            Resources.toString(Resources.getResource(getClass(), SUDOERS_TEMPLATE), Charsets.UTF_8)
+        );
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/TerminateInstances.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/TerminateInstances.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/TerminateInstances.java
new file mode 100644
index 0000000..c2e0915
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/activities/TerminateInstances.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.activities;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Pool;
+import com.google.common.base.Optional;
+
+import java.util.List;
+
+import org.activiti.engine.delegate.DelegateExecution;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Terminate instances previously started by {@see RunOnDemandInstances}
+ */
+public class TerminateInstances extends AmazonActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TerminateInstances.class);
+
+    public TerminateInstances(ProviderClientCache cache) {
+        super(cache);
+    }
+
+    @Override
+    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
+        @SuppressWarnings("unchecked")
+        Optional<List<String>> instanceIds = 
+                Optional.fromNullable((List<String>) execution.getVariable(ProcessVariables.INSTANCE_IDS));
+
+        LOG.info(">> Terminating instances: {}", instanceIds);
+        if (instanceIds.isPresent() && instanceIds.get().size() > 0) {
+            client.terminateInstances(new TerminateInstancesRequest().withInstanceIds(instanceIds.get()));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/config/DefaultProviderConfig.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/config/DefaultProviderConfig.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/config/DefaultProviderConfig.java
new file mode 100644
index 0000000..95cab00
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/config/DefaultProviderConfig.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.config;
+
+import org.apache.provisionr.amazon.AmazonProvisionr;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.provider.ProviderBuilder;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class DefaultProviderConfig {
+
+    private final String accessKey;
+    private final String secretKey;
+    private final String region;
+    private final String endpoint;
+
+    public DefaultProviderConfig(String accessKey, String secretKey, String region, String endpoint) {
+        this.accessKey = checkNotNull(accessKey, "accessKey is null");
+        this.secretKey = checkNotNull(secretKey, "secretKey is null");
+        this.region = checkNotNull(region, "region is null");
+        this.endpoint = checkNotNull(endpoint, "endpoint is null");
+    }
+
+    public Optional<Provider> createProvider() {
+        if (accessKey.isEmpty() || secretKey.isEmpty()) {
+            return Optional.absent();
+        }
+        final ProviderBuilder builder = Provider.builder()
+            .id(AmazonProvisionr.ID)
+            .accessKey(accessKey)
+            .secretKey(secretKey);
+
+        if (!region.isEmpty()) {
+            builder.option("region", region);
+        }
+
+        if (endpoint.isEmpty()) {
+            builder.endpoint(Optional.<String>absent());
+        } else {
+            builder.endpoint(endpoint);
+        }
+
+        return Optional.of(builder.createProvider());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ErrorCodes.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ErrorCodes.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ErrorCodes.java
new file mode 100644
index 0000000..95ff810
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ErrorCodes.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.core;
+
+public class ErrorCodes {
+
+    private ErrorCodes() {
+        /* singleton */
+    }
+
+    public static final String SECURITY_GROUP_NOT_FOUND = "InvalidGroup.NotFound";
+
+    public static final String DUPLICATE_SECURITY_GROUP = "InvalidGroup.Duplicate";
+
+    public static final String DUPLICATE_KEYPAIR = "InvalidKeyPair.Duplicate";
+
+    public static final String KEYPAIR_NOT_FOUND = "InvalidKeyPair.NotFound";
+
+}                         

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ImageTable.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ImageTable.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ImageTable.java
new file mode 100644
index 0000000..7a991bb
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ImageTable.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.core;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.Iterables;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Lists.newArrayList;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Table;
+import com.google.common.collect.Tables;
+import com.google.common.io.Resources;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class ImageTable {
+
+    private static final Splitter COMMA = Splitter.on(",").trimResults();
+
+    /**
+     * Load the list of AMIs from a resource file (csv format)
+     * <p/>
+     * Note: the parser is doing only split by comma. There is no
+     * support for escaping line components
+     *
+     * @param resource path to resource
+     * @return an instance of {@see ImageTable}
+     * @throws IOException
+     */
+    public static ImageTable fromCsvResource(String resource) throws IOException {
+        checkNotNull(resource, "resource is null");
+
+        List<String> lines = Resources.readLines(Resources.getResource(ImageTable.class, resource), Charsets.UTF_8);
+        checkArgument(!lines.isEmpty(), "the resource is an empty file");
+
+        final ImmutableTable.Builder<String, String, String> table = ImmutableTable.builder();
+        final Iterable<String> headers = extractHeaders(lines);
+
+        int index = 0;
+        for (String line : Iterables.skip(lines, 1)) {
+            final Iterable<Table.Cell<String, String, String>> cells =
+                combineHeadersWithLinePartsAsTableCells(index, headers, COMMA.split(line));
+            for (Table.Cell<String, String, String> cell : cells) {
+                table.put(cell);
+            }
+            index++;
+        }
+
+        return new ImageTable(table.build());
+    }
+
+    static Iterable<Table.Cell<String, String, String>> combineHeadersWithLinePartsAsTableCells(
+        int index, Iterable<String> headers, Iterable<String> lineParts
+    ) {
+        final String rowKey = "" + index;
+        return transform(zip(headers, lineParts),
+            new Function<Map.Entry<String, String>, Table.Cell<String, String, String>>() {
+                @Override
+                public Table.Cell<String, String, String> apply(Map.Entry<String, String> entry) {
+                    return Tables.immutableCell(rowKey, entry.getKey(), entry.getValue());
+                }
+            });
+    }
+
+    static <K, V> Iterable<Map.Entry<K, V>> zip(Iterable<K> first, Iterable<V> second) {
+        checkArgument(Iterables.size(first) == Iterables.size(second), "iterables don't have the same size");
+
+        final Iterator<K> iterator = first.iterator();
+        return newArrayList(transform(second, new Function<V, Map.Entry<K, V>>() {
+            @Override
+            public Map.Entry<K, V> apply(V input) {
+                return Maps.immutableEntry(iterator.next(), input);
+            }
+        }));
+    }
+
+    static Iterable<String> extractHeaders(List<String> lines) {
+        String headerLine = Iterables.getFirst(lines, "");
+        checkArgument(!headerLine.isEmpty(), "Found an empty header line");
+
+        return COMMA.split(headerLine);
+    }
+
+    private final Table<String, String, String> table;
+
+    public ImageTable(Table<String, String, String> table) {
+        this.table = checkNotNull(table, "table is null");
+    }
+
+    Table<String, String, String> getTable() {
+        return table;
+    }
+
+    public ImageTableQuery query() {
+        return new ImageTableQuery(this);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(table);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final ImageTable other = (ImageTable) obj;
+        return Objects.equal(this.table, other.table);
+    }
+
+    @Override
+    public String toString() {
+        return "ImageTable{" +
+            "table=" + table +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ImageTableQuery.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ImageTableQuery.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ImageTableQuery.java
new file mode 100644
index 0000000..1be2615
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ImageTableQuery.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.core;
+
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import java.util.Map;
+
+public class ImageTableQuery {
+
+    private final ImageTable table;
+    private final ImmutableMap.Builder<String, String> filtersBuilder = ImmutableMap.builder();
+
+    public ImageTableQuery(ImageTable table) {
+        this.table = checkNotNull(table, "table is null");
+    }
+
+    public ImageTableQuery filterBy(String column, String value) {
+        filtersBuilder.put(column, value);
+        return this;
+    }
+
+    public String singleResult() {
+        final Map<String, String> filters = filtersBuilder.build();
+        final ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+
+        for (String row : table.getTable().rowKeySet()) {
+            if (matchesFilters(table.getTable().row(row), filters)) {
+                builder.add(table.getTable().get(row, "ami-id"));
+            }
+        }
+        return Iterables.getOnlyElement(builder.build());
+    }
+
+    boolean matchesFilters(final Map<String, String> row, Map<String, String> filters) {
+        return Iterables.all(filters.entrySet(),
+            new Predicate<Map.Entry<String, String>>() {
+                @Override
+                public boolean apply(Map.Entry<String, String> entry) {
+                    return Objects.equal(row.get(entry.getKey()), entry.getValue());
+                }
+            });
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(table, filtersBuilder);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final ImageTableQuery other = (ImageTableQuery) obj;
+        return Objects.equal(this.table, other.table) && Objects.equal(this.filtersBuilder, other.filtersBuilder);
+    }
+
+    @Override
+    public String toString() {
+        return "ImageTableQuery{" +
+            "table=" + table +
+            ", filters=" + filtersBuilder +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/KeyPairs.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/KeyPairs.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/KeyPairs.java
new file mode 100644
index 0000000..947835f
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/KeyPairs.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.core;
+
+public class KeyPairs {
+
+    private KeyPairs() {
+        /* singleton */
+    }
+
+    public static String formatNameFromBusinessKey(String businessKey) {
+        return String.format("key-%s", businessKey);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ProviderClientCache.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ProviderClientCache.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ProviderClientCache.java
new file mode 100644
index 0000000..f04c218
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ProviderClientCache.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.core;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import org.apache.provisionr.api.provider.Provider;
+import com.google.common.cache.LoadingCache;
+
+/**
+ * Marker interface only used to hide generic type arguments
+ * from Apache Aries and make Blueprint DI work as expected
+ */
+public interface ProviderClientCache extends LoadingCache<Provider, AmazonEC2> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ProviderClientCacheSupplier.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ProviderClientCacheSupplier.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ProviderClientCacheSupplier.java
new file mode 100644
index 0000000..eb0a829
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/ProviderClientCacheSupplier.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.core;
+
+import com.amazonaws.ClientConfiguration;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+import com.amazonaws.services.ec2.model.DescribeRegionsRequest;
+import com.amazonaws.services.ec2.model.DescribeRegionsResult;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.ForwardingLoadingCache;
+import com.google.common.cache.LoadingCache;
+import com.google.common.cache.RemovalListener;
+import com.google.common.cache.RemovalNotification;
+import java.util.concurrent.TimeUnit;
+import org.apache.provisionr.amazon.options.ProviderOptions;
+import org.apache.provisionr.api.provider.Provider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProviderClientCacheSupplier implements Supplier<ProviderClientCache> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ProviderClientCacheSupplier.class);
+
+    public static final String PROVISIONR_USER_AGENT = "Apache Provisionr, aws-sdk-java/1.3.14";
+
+    public static final int MAX_CACHE_SIZE = 100;
+    public static final int EXPIRE_AFTER_WRITE_IN_HOURS = 2;
+
+    private static class ProviderClientCacheLoader extends CacheLoader<Provider, AmazonEC2> {
+
+        @Override
+        public AmazonEC2 load(Provider provider) throws Exception {
+            String region = Optional.fromNullable(provider.getOptions().get(ProviderOptions.REGION))
+                .or(ProviderOptions.DEFAULT_REGION);
+
+            AWSCredentials credentials = new BasicAWSCredentials(provider.getAccessKey(), provider.getSecretKey());
+            AmazonEC2 client = new AmazonEC2Client(credentials, new ClientConfiguration()
+                .withUserAgent(PROVISIONR_USER_AGENT));
+
+            if (provider.getEndpoint().isPresent()) {
+                LOG.info("Using endpoint {} as configured", provider.getEndpoint().get());
+                client.setEndpoint(provider.getEndpoint().get());
+
+            } else {
+                LOG.info(">> Searching endpoint for region {}", region);
+                DescribeRegionsRequest request = new DescribeRegionsRequest().withRegionNames(region);
+
+                DescribeRegionsResult result = client.describeRegions(request);
+                checkArgument(result.getRegions().size() == 1, "Invalid region name %s. Expected one result found %s",
+                    region, result.getRegions());
+
+                LOG.info("<< Using endpoint {} for region {}", result.getRegions().get(0).getEndpoint(), region);
+                client.setEndpoint(result.getRegions().get(0).getEndpoint());
+            }
+
+            return client;
+
+        }
+    }
+
+    public static class WrapLoadingCacheAsProviderClientCache extends ForwardingLoadingCache<Provider, AmazonEC2>
+        implements ProviderClientCache {
+
+        private final LoadingCache<Provider, AmazonEC2> delegate;
+
+        public WrapLoadingCacheAsProviderClientCache(LoadingCache<Provider, AmazonEC2> delegate) {
+            this.delegate = checkNotNull(delegate, "delegate is null");
+        }
+
+        @Override
+        protected LoadingCache<Provider, AmazonEC2> delegate() {
+            return delegate;
+        }
+    }
+
+    @Override
+    public ProviderClientCache get() {
+        final LoadingCache<Provider, AmazonEC2> cache = CacheBuilder.newBuilder()
+            .maximumSize(MAX_CACHE_SIZE)
+            .expireAfterWrite(EXPIRE_AFTER_WRITE_IN_HOURS, TimeUnit.HOURS)
+            .removalListener(new RemovalListener<Provider, AmazonEC2>() {
+                @Override
+                public void onRemoval(RemovalNotification<Provider, AmazonEC2> notification) {
+                    LOG.info("Closing client for provider: {}", notification.getKey());
+                    notification.getValue().shutdown();
+                }
+            })
+            .build(new ProviderClientCacheLoader());
+
+        return new WrapLoadingCacheAsProviderClientCache(cache);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/SecurityGroups.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/SecurityGroups.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/SecurityGroups.java
new file mode 100644
index 0000000..4a8a257
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/core/SecurityGroups.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.core;
+
+public class SecurityGroups {
+
+    private SecurityGroups() {
+        /* singleton */
+    }
+
+    public static String formatNameFromBusinessKey(String businessKey) {
+        return String.format("network-%s", businessKey);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRule.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRule.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRule.java
new file mode 100644
index 0000000..9e20dce
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRule.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.functions;
+
+import com.amazonaws.services.ec2.model.IpPermission;
+import org.apache.provisionr.api.network.Protocol;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.network.RuleBuilder;
+import com.google.common.base.Function;
+import static com.google.common.collect.Iterables.getOnlyElement;
+
+public enum ConvertIpPermissionToRule implements Function<IpPermission, Rule> {
+    FUNCTION;
+
+    @Override
+    public Rule apply(IpPermission ipPermission) {
+        final RuleBuilder builder = Rule.builder().cidr(getOnlyElement(ipPermission.getIpRanges()))
+            .protocol(Protocol.valueOf(ipPermission.getIpProtocol().toUpperCase()));
+
+        if (!ipPermission.getIpProtocol().equalsIgnoreCase("icmp")) {
+            builder.ports(ipPermission.getFromPort(), ipPermission.getToPort());
+        }
+
+        return builder.createRule();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/functions/ConvertRuleToIpPermission.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/functions/ConvertRuleToIpPermission.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/functions/ConvertRuleToIpPermission.java
new file mode 100644
index 0000000..8984744
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/functions/ConvertRuleToIpPermission.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.functions;
+
+import com.amazonaws.services.ec2.model.IpPermission;
+import org.apache.provisionr.api.network.Rule;
+import com.google.common.base.Function;
+
+public enum ConvertRuleToIpPermission implements Function<Rule, IpPermission> {
+    FUNCTION;
+
+    @Override
+    public IpPermission apply(Rule rule) {
+        IpPermission permission = new IpPermission()
+            .withIpProtocol(rule.getProtocol().toString().toLowerCase())
+            .withIpRanges(rule.getCidr());
+
+        if (!rule.getPorts().isEmpty()) {
+            permission.withFromPort(rule.getPorts().lowerEndpoint())
+                .withToPort(rule.getPorts().upperEndpoint());
+        } else {
+            permission.withFromPort(-1).withToPort(-1);
+        }
+        return permission;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/options/ProviderOptions.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/options/ProviderOptions.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/options/ProviderOptions.java
new file mode 100644
index 0000000..b281640
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/options/ProviderOptions.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.options;
+
+public class ProviderOptions {
+
+    private ProviderOptions() {
+        /* singleton */
+    }
+
+    public static final String REGION = "region";
+    public static final String DEFAULT_REGION = "us-east-1";
+    public static final String SPOT_BID = "spotBid";
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/org/apache/provisionr/amazon/options/SoftwareOptions.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/org/apache/provisionr/amazon/options/SoftwareOptions.java b/providers/amazon/src/main/java/org/apache/provisionr/amazon/options/SoftwareOptions.java
new file mode 100644
index 0000000..bd78919
--- /dev/null
+++ b/providers/amazon/src/main/java/org/apache/provisionr/amazon/options/SoftwareOptions.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon.options;
+
+public class SoftwareOptions {
+
+    private SoftwareOptions() {
+        /* singleton */
+    }
+
+    public static final String DEFAULT_BASE_OPERATING_SYSTEM = "ubuntu";
+
+    public static final String BASE_OPERATING_SYSTEM_VERSION = "version";
+    public static final String DEFAULT_BASE_OPERATING_SYSTEM_VERSION = "12.04 LTS";
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/OSGI-INF/blueprint/context.xml
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/OSGI-INF/blueprint/context.xml b/providers/amazon/src/main/resources/OSGI-INF/blueprint/context.xml
index 5f524e3..ff93b54 100644
--- a/providers/amazon/src/main/resources/OSGI-INF/blueprint/context.xml
+++ b/providers/amazon/src/main/resources/OSGI-INF/blueprint/context.xml
@@ -18,7 +18,7 @@
            xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
            xmlns:cfg="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
 
-    <cfg:property-placeholder persistent-id="com.axemblr.provisionr.amazon"
+    <cfg:property-placeholder persistent-id="org.apache.provisionr.amazon"
                               placeholder-prefix="$(" placeholder-suffix=")" update-strategy="reload">
         <cfg:default-properties>
             <cfg:property name="accessKey" value=""/>
@@ -28,7 +28,7 @@
         </cfg:default-properties>
     </cfg:property-placeholder>
 
-    <bean id="defaultProviderConfig" class="com.axemblr.provisionr.amazon.config.DefaultProviderConfig">
+    <bean id="defaultProviderConfig" class="org.apache.provisionr.amazon.config.DefaultProviderConfig">
         <argument value="$(accessKey)"/>
         <argument value="$(secretKey)"/>
         <argument value="$(region)"/>
@@ -38,105 +38,105 @@
     <reference id="processEngine" interface="org.activiti.engine.ProcessEngine"/>
     <reference id="runtimeService" interface="org.activiti.engine.RuntimeService"/>
 
-    <bean id="amazonService" class="com.axemblr.provisionr.amazon.AmazonProvisionr">
+    <bean id="amazonService" class="org.apache.provisionr.amazon.AmazonProvisionr">
         <argument ref="processEngine"/>
         <argument ref="defaultProviderConfig"/>
     </bean>
-    <service ref="amazonService" interface="com.axemblr.provisionr.api.Provisionr"/>
+    <service ref="amazonService" interface="org.apache.provisionr.api.Provisionr"/>
 
     <!-- Initialize the cache for AmazonEC2 client instances -->
 
-    <bean id="cacheSupplier" class="com.axemblr.provisionr.amazon.core.ProviderClientCacheSupplier"/>
+    <bean id="cacheSupplier" class="org.apache.provisionr.amazon.core.ProviderClientCacheSupplier"/>
     <bean id="providerClientCache" factory-ref="cacheSupplier" factory-method="get"/>
 
     <!-- Process activities that are specific to Amazon -->
 
     <bean id="amazon_ensureSecurityGroupExists"
-          class="com.axemblr.provisionr.amazon.activities.EnsureSecurityGroupExists">
+          class="org.apache.provisionr.amazon.activities.EnsureSecurityGroupExists">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_ensureSecurityGroupExists" auto-export="interfaces"/>
 
     <bean id="amazon_deleteSecurityGroup"
-          class="com.axemblr.provisionr.amazon.activities.DeleteSecurityGroup">
+          class="org.apache.provisionr.amazon.activities.DeleteSecurityGroup">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_deleteSecurityGroup" auto-export="interfaces"/>
 
     <bean id="amazon_ensureKeyPairExists"
-          class="com.axemblr.provisionr.amazon.activities.EnsureKeyPairExists">
+          class="org.apache.provisionr.amazon.activities.EnsureKeyPairExists">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_ensureKeyPairExists" auto-export="interfaces"/>
 
     <bean id="amazon_deleteKeyPair"
-          class="com.axemblr.provisionr.amazon.activities.DeleteKeyPair">
+          class="org.apache.provisionr.amazon.activities.DeleteKeyPair">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_deleteKeyPair" auto-export="interfaces"/>
 
     <bean id="amazon_runOnDemandInstances"
-          class="com.axemblr.provisionr.amazon.activities.RunOnDemandInstances">
+          class="org.apache.provisionr.amazon.activities.RunOnDemandInstances">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_runOnDemandInstances" auto-export="interfaces"/>
 
     <bean id="amazon_terminateInstances"
-          class="com.axemblr.provisionr.amazon.activities.TerminateInstances">
+          class="org.apache.provisionr.amazon.activities.TerminateInstances">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_terminateInstances" auto-export="interfaces"/>
 
     <bean id="amazon_checkAllInstancesAreRunning"
-          class="com.axemblr.provisionr.amazon.activities.CheckAllInstancesAreRunning">
+          class="org.apache.provisionr.amazon.activities.CheckAllInstancesAreRunning">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_checkAllInstancesAreRunning" auto-export="interfaces"/>
 
     <bean id="amazon_checkAllInstancesAreTerminated"
-          class="com.axemblr.provisionr.amazon.activities.CheckAllInstancesAreTerminated">
+          class="org.apache.provisionr.amazon.activities.CheckAllInstancesAreTerminated">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_checkAllInstancesAreTerminated" auto-export="interfaces"/>
 
     <bean id="amazon_runSpotInstances"
-          class="com.axemblr.provisionr.amazon.activities.RunSpotInstances">
+          class="org.apache.provisionr.amazon.activities.RunSpotInstances">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_runSpotInstances" auto-export="interfaces"/>
 
 	<bean id="amazon_checkNoRequestsAreOpen"
-          class="com.axemblr.provisionr.amazon.activities.CheckNoRequestsAreOpen">
+          class="org.apache.provisionr.amazon.activities.CheckNoRequestsAreOpen">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_checkNoRequestsAreOpen" auto-export="interfaces"/>
 
 	<bean id="amazon_checkAllRequestsAreActive"
-          class="com.axemblr.provisionr.amazon.activities.CheckAllRequestsAreActive">
+          class="org.apache.provisionr.amazon.activities.CheckAllRequestsAreActive">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_checkAllRequestsAreActive" auto-export="interfaces"/>
 
     <bean id="amazon_cancelSpotRequests"
-          class="com.axemblr.provisionr.amazon.activities.CancelSpotRequests">
+          class="org.apache.provisionr.amazon.activities.CancelSpotRequests">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_cancelSpotRequests" auto-export="interfaces"/>
 
     <bean id="amazon_getInstanceIdsFromSpotRequests"
-          class="com.axemblr.provisionr.amazon.activities.GetInstanceIdsFromSpotRequests">
+          class="org.apache.provisionr.amazon.activities.GetInstanceIdsFromSpotRequests">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_getInstanceIdsFromSpotRequests" auto-export="interfaces"/>
 
     <bean id="amazon_publishListOfMachines"
-          class="com.axemblr.provisionr.amazon.activities.PublishListOfMachines">
+          class="org.apache.provisionr.amazon.activities.PublishListOfMachines">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_publishListOfMachines" auto-export="interfaces"/>
 
     <bean id="amazon_spawnMachineSetupProcesses"
-          class="com.axemblr.provisionr.core.activities.SpawnProcessForEachMachine">
+          class="org.apache.provisionr.core.activities.SpawnProcessForEachMachine">
         <argument ref="processEngine"/>
         <argument value="amazonMachineSetup"/>
         <argument value="setup"/>
@@ -145,7 +145,7 @@
     <service ref="amazon_spawnMachineSetupProcesses" auto-export="interfaces"/>
 
     <bean id="amazon_checkSetupProcessesEnded"
-          class="com.axemblr.provisionr.core.activities.CheckProcessesEnded">
+          class="org.apache.provisionr.core.activities.CheckProcessesEnded">
         <argument ref="runtimeService"/>
         <argument value="amazonMachineSetupProcessIds"/>
         <argument value="setupProcessesEnded"/>
@@ -153,18 +153,18 @@
     <service ref="amazon_checkSetupProcessesEnded" auto-export="interfaces"/>
 
     <bean id="amazon_killMachineSetUpProcesses"
-          class="com.axemblr.provisionr.core.activities.KillMachineSetUpProcesses">
+          class="org.apache.provisionr.core.activities.KillMachineSetUpProcesses">
           <argument ref="runtimeService" />
           <argument value="amazonMachineSetupProcessIds"/>
     </bean>
     <service ref="amazon_killMachineSetUpProcesses" auto-export="interfaces"/>
 
     <bean id="amazon_setupAdminAccess"
-          class="com.axemblr.provisionr.amazon.activities.SetupAdminAccess"/>
+          class="org.apache.provisionr.amazon.activities.SetupAdminAccess"/>
     <service ref="amazon_setupAdminAccess" auto-export="interfaces"/>
 
     <bean id="amazon_dumpConsoleOutput"
-          class="com.axemblr.provisionr.amazon.activities.DumpConsoleOutput">
+          class="org.apache.provisionr.amazon.activities.DumpConsoleOutput">
         <argument ref="providerClientCache"/>
     </bean>
     <service ref="amazon_dumpConsoleOutput" auto-export="interfaces"/>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/com.axemblr.provisionr.amazon.cfg
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/com.axemblr.provisionr.amazon.cfg b/providers/amazon/src/main/resources/com.axemblr.provisionr.amazon.cfg
deleted file mode 100644
index d5837d6..0000000
--- a/providers/amazon/src/main/resources/com.axemblr.provisionr.amazon.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-
-# Amazon provisioning service configuration
-
-accessKey = access
-secretKey = secret
-
-region = us-east-1

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/README
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/README b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/README
deleted file mode 100644
index 0a95ad9..0000000
--- a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/README
+++ /dev/null
@@ -1,3 +0,0 @@
-
-ubuntu.csv was collected from:
-http://cloud-images.ubuntu.com/locator/ec2/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/adminaccess.pp.mustache
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/adminaccess.pp.mustache b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/adminaccess.pp.mustache
deleted file mode 100644
index 8551619..0000000
--- a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/adminaccess.pp.mustache
+++ /dev/null
@@ -1,62 +0,0 @@
-
-#
-# Make sure only a single user can access the machines over ssh
-# Note: this script assumes a Debian / Ubuntu system 
-# 
-
-user { "{{user}}":
-  groups => ['adm','dialout','cdrom', 'floppy','audio','dip','video','plugdev','netdev','admin','sudo'],
-  ensure => 'present',
-  managehome => 'true',
-  shell => '/bin/bash',
-  membership => 'inclusive',
-  system => 'false'
-}
-  
-file { "/home/{{user}}/.ssh":
-	ensure => 'directory',
-	require => User['{{user}}'],
-	owner => '{{user}}',
-	mode => '700'
-}
-
-ssh_authorized_key { '{{user}}-rsa-key':
-	ensure => 'present',
-	key => '{{publicKey}}',
-	type => 'rsa',
-	user => '{{user}}',
-	require => File['/home/{{user}}/.ssh']
-}  
-  
-file { "/etc/ssh/sshd_config":
-  owner => "root",
-  group => "root",
-  mode => 644,
-  replace => "true",
-  notify => Service["ssh"],
-  require => Package["openssh-server"],
-  source => "/tmp/sshd_config"
-}
-
-file { "/etc/sudoers":
-  owner => "root",
-  group => "root",
-  mode => 440,
-  replace => "true",
-  source => "/tmp/sudoers"
-}
-
-package { "openssh-server":
-  ensure => installed
-}
-
-service { "ssh":
-  ensure => running,
-  provider => 'upstart',
-  hasrestart => 'true',
-  hasstatus  => 'true',
-  require => [
-    File["/etc/ssh/sshd_config"],
-    Package["openssh-server"]
-  ]
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/sshd_config.mustache
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/sshd_config.mustache b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/sshd_config.mustache
deleted file mode 100644
index 68eb68f..0000000
--- a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/sshd_config.mustache
+++ /dev/null
@@ -1,83 +0,0 @@
-# Package generated configuration file
-# See the sshd_config(5) manpage for details
-
-# What ports, IPs and protocols we listen for
-Port 22
-
-# Use these options to restrict which interfaces/protocols sshd will bind to
-#ListenAddress ::
-#ListenAddress 0.0.0.0
-
-Protocol 2
-# HostKeys for protocol version 2
-HostKey /etc/ssh/ssh_host_rsa_key
-HostKey /etc/ssh/ssh_host_dsa_key
-HostKey /etc/ssh/ssh_host_ecdsa_key
-
-#Privilege Separation is turned on for security
-UsePrivilegeSeparation yes
-
-# Lifetime and size of ephemeral version 1 server key
-KeyRegenerationInterval 3600
-ServerKeyBits 768
-
-# Logging
-SyslogFacility AUTH
-LogLevel INFO
-
-# Authentication:
-LoginGraceTime 120
-PermitRootLogin no
-StrictModes yes
-
-RSAAuthentication yes
-PubkeyAuthentication yes
-#AuthorizedKeysFile     %h/.ssh/authorized_keys
-
-AllowUsers {{user}}
-
-# Don't read the user's ~/.rhosts and ~/.shosts files
-IgnoreRhosts yes
-# For this to work you will also need host keys in /etc/ssh_known_hosts
-RhostsRSAAuthentication no
-# similar for protocol version 2
-HostbasedAuthentication no
-# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
-#IgnoreUserKnownHosts yes
-
-# To enable empty passwords, change to yes (NOT RECOMMENDED)
-PermitEmptyPasswords no
-
-# Change to yes to enable challenge-response passwords (beware issues with
-# some PAM modules and threads)
-ChallengeResponseAuthentication no
-
-# Change to no to disable tunnelled clear text passwords
-PasswordAuthentication no
-
-X11Forwarding no
-X11DisplayOffset 10
-PrintMotd no
-PrintLastLog yes
-TCPKeepAlive yes
-#UseLogin no
-
-#MaxStartups 10:30:60
-#Banner /etc/issue.net
-
-# Allow client to pass locale environment variables
-# AcceptEnv LANG LC_*
-
-Subsystem sftp /usr/lib/openssh/sftp-server
-
-# Set this to 'yes' to enable PAM authentication, account processing,
-# and session processing. If this is enabled, PAM authentication will
-# be allowed through the ChallengeResponseAuthentication and
-# PasswordAuthentication.  Depending on your PAM configuration,
-# PAM authentication via ChallengeResponseAuthentication may bypass
-# the setting of "PermitRootLogin without-password".
-# If you just want the PAM account and session checks to run without
-# PAM authentication, then enable this but set PasswordAuthentication
-# and ChallengeResponseAuthentication to 'no'.
-
-UsePAM yes
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/sudoers
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/sudoers b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/sudoers
deleted file mode 100644
index 2292dce..0000000
--- a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/puppet/sudoers
+++ /dev/null
@@ -1,28 +0,0 @@
-# This file MUST be edited with the 'visudo' command as root.
-#
-# Please consider adding local content in /etc/sudoers.d/ instead of
-# directly modifying this file.
-#
-# See the man page for details on how to write a sudoers file.
-#
-Defaults	env_reset
-Defaults	secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-
-# Host alias specification
-
-# User alias specification
-
-# Cmnd alias specification
-
-# User privilege specification
-root	ALL=(ALL:ALL) ALL
-
-# Members of the admin group may gain root privileges
-%admin ALL=(ALL) ALL
-
-# Allow members of group sudo to execute any command
-%sudo	ALL=(ALL:ALL) NOPASSWD: ALL
-
-# See sudoers(5) for more information on "#include" directives:
-
-#includedir /etc/sudoers.d

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/ubuntu.csv
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/ubuntu.csv b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/ubuntu.csv
deleted file mode 100644
index 1751b94..0000000
--- a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/ubuntu.csv
+++ /dev/null
@@ -1,221 +0,0 @@
-region, name, version, arch, type, release, ami-id, aki-id
-ap-northeast-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-087bc509, aki-d409a2d5
-ap-northeast-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-067bc507, aki-d209a2d3
-ap-northeast-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-e67ac4e7, aki-d409a2d5
-ap-northeast-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-8c7ac48d, aki-d209a2d3
-ap-southeast-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-240e4d76, aki-11d5aa43
-ap-southeast-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-260e4d74, aki-13d5aa41
-ap-southeast-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-220e4d70, aki-11d5aa43
-ap-southeast-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-180e4d4a, aki-13d5aa41
-eu-west-1, natty, 11.04 EOL, amd64, hvm, 20121028, ami-7b14170f, hvm
-eu-west-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-7914170d, aki-4feec43b
-eu-west-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-7f14170b, aki-4deec439
-eu-west-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-d71516a3, aki-4feec43b
-eu-west-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-23151657, aki-4deec439
-sa-east-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-d0548dcd, aki-d63ce3cb
-sa-east-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-d6548dcb, aki-863ce39b
-sa-east-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-a2548dbf, aki-d63ce3cb
-sa-east-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-b6548dab, aki-863ce39b
-us-east-1, natty, 11.04 EOL, amd64, hvm, 20121028, ami-beb10ad7, hvm
-us-east-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-bab10ad3, aki-427d952b
-us-east-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-a6b10acf, aki-407d9529
-us-east-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-1cb30875, aki-427d952b
-us-east-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-96b803ff, aki-407d9529
-us-west-1, natty, 11.04 EOL, amd64, ebs, 20121028, ami-132c0a56, aki-9ba0f1de
-us-west-1, natty, 11.04 EOL, i386, ebs, 20121028, ami-112c0a54, aki-99a0f1dc
-us-west-1, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-712c0a34, aki-9ba0f1de
-us-west-1, natty, 11.04 EOL, i386, instance-store, 20121028, ami-b12f09f4, aki-99a0f1dc
-us-west-2, natty, 11.04 EOL, amd64, hvm, 20121028, ami-70b23b40, hvm
-us-west-2, natty, 11.04 EOL, amd64, ebs, 20121028, ami-0eb23b3e, aki-ace26f9c
-us-west-2, natty, 11.04 EOL, i386, ebs, 20121028, ami-0ab23b3a, aki-dce26fec
-us-west-2, natty, 11.04 EOL, amd64, instance-store, 20121028, ami-3ab23b0a, aki-ace26f9c
-us-west-2, natty, 11.04 EOL, i386, instance-store, 20121028, ami-a2b33a92, aki-dce26fec
-ap-northeast-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-8876ca89, aki-d409a2d5
-ap-northeast-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-8676ca87, aki-d209a2d3
-ap-northeast-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-6c76ca6d, aki-d409a2d5
-ap-northeast-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-2676ca27, aki-d209a2d3
-ap-southeast-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-903575c2, aki-11d5aa43
-ap-southeast-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-923575c0, aki-13d5aa41
-ap-southeast-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-ec3575be, aki-11d5aa43
-ap-southeast-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-fe3575ac, aki-13d5aa41
-ap-southeast-2, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-9b8611a1, aki-31990e0b
-ap-southeast-2, lucid, 10.04 LTS, i386, ebs, 20120913, ami-a786119d, aki-33990e09
-ap-southeast-2, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-af861195, aki-31990e0b
-ap-southeast-2, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-49861173, aki-33990e09
-eu-west-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-5d4a4b29, aki-4feec43b
-eu-west-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-534a4b27, aki-4deec439
-eu-west-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-794a4b0d, aki-4feec43b
-eu-west-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-8f4b4afb, aki-4deec439
-sa-east-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-6ac91077, aki-d63ce3cb
-sa-east-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-68c91075, aki-863ce39b
-sa-east-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-6ec91073, aki-d63ce3cb
-sa-east-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-7ec91063, aki-863ce39b
-us-east-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-c7b202ae, aki-427d952b
-us-east-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-c5b202ac, aki-407d9529
-us-east-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-1db20274, aki-427d952b
-us-east-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-53b2023a, aki-407d9529
-us-west-1, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-bb88acfe, aki-9ba0f1de
-us-west-1, lucid, 10.04 LTS, i386, ebs, 20120913, ami-b988acfc, aki-99a0f1dc
-us-west-1, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-bd88acf8, aki-9ba0f1de
-us-west-1, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-a188ace4, aki-99a0f1dc
-us-west-2, lucid, 10.04 LTS, amd64, ebs, 20120913, ami-1a4fc12a, aki-ace26f9c
-us-west-2, lucid, 10.04 LTS, i386, ebs, 20120913, ami-184fc128, aki-dce26fec
-us-west-2, lucid, 10.04 LTS, amd64, instance-store, 20120913, ami-3e4fc10e, aki-ace26f9c
-us-west-2, lucid, 10.04 LTS, i386, instance-store, 20120913, ami-304fc100, aki-dce26fec
-ap-northeast-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-d669d6d7, aki-d069d6d1
-ap-northeast-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-ca69d6cb, aki-c469d6c5
-ap-southeast-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-f4a8e8a6, aki-f2a8e8a0
-ap-southeast-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-cca8e89e, aki-c0a8e892
-eu-west-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-897575fd, aki-877575f3
-eu-west-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-917575e5, aki-a97575dd
-sa-east-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-7008d16d, aki-7e08d163
-sa-east-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-4208d15f, aki-4a08d157
-us-east-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-3c229e55, aki-5e229e37
-us-east-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-6c229e05, aki-9c219df5
-us-west-1, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-3ff8df7a, aki-37f8df72
-us-west-1, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-2ff8df6a, aki-25f8df60
-us-west-2, hardy, 8.04 LTS, amd64, instance-store, 20121003, ami-dc31bfec, aki-d631bfe6
-us-west-2, hardy, 8.04 LTS, i386, instance-store, 20121003, ami-ea31bfda, aki-e231bfd2
-ap-northeast-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-741dac75, aki-d409a2d5
-ap-northeast-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-721dac73, aki-d209a2d3
-ap-northeast-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-701dac71, aki-d409a2d5
-ap-northeast-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-641dac65, aki-d209a2d3
-ap-southeast-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-0e8acd5c, aki-11d5aa43
-ap-southeast-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-0a8acd58, aki-13d5aa41
-ap-southeast-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-1a8acd48, aki-11d5aa43
-ap-southeast-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-608acd32, aki-13d5aa41
-eu-west-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-c57942b1, aki-4feec43b
-eu-west-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-db7942af, aki-4deec439
-eu-west-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-df7942ab, aki-4feec43b
-eu-west-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-d57942a1, aki-4deec439
-sa-east-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-10a9770d, aki-d63ce3cb
-sa-east-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-16a9770b, aki-863ce39b
-sa-east-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-1aa97707, aki-d63ce3cb
-sa-east-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-1ea97703, aki-863ce39b
-us-east-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-d78f57be, aki-427d952b
-us-east-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-d38f57ba, aki-407d9529
-us-east-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-098f5760, aki-427d952b
-us-east-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-7b8f5712, aki-407d9529
-us-west-1, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-3b154e7e, aki-9ba0f1de
-us-west-1, maverick, 10.10 EOL, i386, ebs, 20120410, ami-39154e7c, aki-99a0f1dc
-us-west-1, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-2b154e6e, aki-9ba0f1de
-us-west-1, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-1d154e58, aki-99a0f1dc
-us-west-2, maverick, 10.10 EOL, amd64, ebs, 20120410, ami-64fd7154, aki-ace26f9c
-us-west-2, maverick, 10.10 EOL, i386, ebs, 20120410, ami-62fd7152, aki-dce26fec
-us-west-2, maverick, 10.10 EOL, amd64, instance-store, 20120410, ami-7efd714e, aki-ace26f9c
-us-west-2, maverick, 10.10 EOL, i386, instance-store, 20120410, ami-76fd7146, aki-dce26fec
-ap-northeast-1, oneiric, 11.10, amd64, ebs, 20120918, ami-9405b995, aki-ee5df7ef
-ap-northeast-1, oneiric, 11.10, i386, ebs, 20120918, ami-9205b993, aki-ec5df7ed
-ap-northeast-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-8005b981, aki-ee5df7ef
-ap-northeast-1, oneiric, 11.10, i386, instance-store, 20120918, ami-6a05b96b, aki-ec5df7ed
-ap-southeast-1, oneiric, 11.10, amd64, ebs, 20120918, ami-a86424fa, aki-aa225af8
-ap-southeast-1, oneiric, 11.10, i386, ebs, 20120918, ami-aa6424f8, aki-a4225af6
-ap-southeast-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-a46424f6, aki-aa225af8
-ap-southeast-1, oneiric, 11.10, i386, instance-store, 20120918, ami-a26424f0, aki-a4225af6
-ap-southeast-2, oneiric, 11.10, amd64, ebs, 20120918, ami-818611bb, aki-31990e0b
-ap-southeast-2, oneiric, 11.10, i386, ebs, 20120918, ami-838611b9, aki-33990e09
-ap-southeast-2, oneiric, 11.10, amd64, instance-store, 20120918, ami-5186116b, aki-31990e0b
-ap-southeast-2, oneiric, 11.10, i386, instance-store, 20120918, ami-5d861167, aki-33990e09
-eu-west-1, oneiric, 11.10, amd64, hvm, 20120918, ami-3fcacb4b, hvm
-eu-west-1, oneiric, 11.10, amd64, ebs, 20120918, ami-3dcacb49, aki-62695816
-eu-west-1, oneiric, 11.10, i386, ebs, 20120918, ami-33cacb47, aki-64695810
-eu-west-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-41cacb35, aki-62695816
-eu-west-1, oneiric, 11.10, i386, instance-store, 20120918, ami-6fcacb1b, aki-64695810
-sa-east-1, oneiric, 11.10, amd64, ebs, 20120918, ami-00f22b1d, aki-cc3ce3d1
-sa-east-1, oneiric, 11.10, i386, ebs, 20120918, ami-06f22b1b, aki-bc3ce3a1
-sa-east-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-08f22b15, aki-cc3ce3d1
-sa-east-1, oneiric, 11.10, i386, instance-store, 20120918, ami-10f22b0d, aki-bc3ce3a1
-us-east-1, oneiric, 11.10, amd64, hvm, 20120918, ami-cfc072a6, hvm
-us-east-1, oneiric, 11.10, amd64, ebs, 20120918, ami-cdc072a4, aki-825ea7eb
-us-east-1, oneiric, 11.10, i386, ebs, 20120918, ami-cbc072a2, aki-805ea7e9
-us-east-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-35c0725c, aki-825ea7eb
-us-east-1, oneiric, 11.10, i386, instance-store, 20120918, ami-71c07218, aki-805ea7e9
-us-west-1, oneiric, 11.10, amd64, ebs, 20120918, ami-fb5176be, aki-8d396bc8
-us-west-1, oneiric, 11.10, i386, ebs, 20120918, ami-ff5176ba, aki-83396bc6
-us-west-1, oneiric, 11.10, amd64, instance-store, 20120918, ami-e95176ac, aki-8d396bc8
-us-west-1, oneiric, 11.10, i386, instance-store, 20120918, ami-d951769c, aki-83396bc6
-us-west-2, oneiric, 11.10, amd64, hvm, 20120918, ami-b67af486, hvm
-us-west-2, oneiric, 11.10, amd64, ebs, 20120918, ami-b47af484, aki-98e26fa8
-us-west-2, oneiric, 11.10, i386, ebs, 20120918, ami-b27af482, aki-c2e26ff2
-us-west-2, oneiric, 11.10, amd64, instance-store, 20120918, ami-4a7af47a, aki-98e26fa8
-us-west-2, oneiric, 11.10, i386, instance-store, 20120918, ami-447af474, aki-c2e26ff2
-ap-northeast-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-2a0fa42b, aki-260fa427
-ap-northeast-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-240fa425, aki-0a0fa40b
-ap-southeast-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-90344ac2, aki-ec344abe
-ap-southeast-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-e6344ab4, aki-e2344ab0
-eu-west-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-28b9935c, aki-20b99354
-eu-west-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-24b99350, aki-34b99340
-us-east-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-6832d801, aki-1c3dd775
-us-east-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-563dd73f, aki-c43cd6ad
-us-west-1, karmic, 9.10 EOL, amd64, instance-store, 20100826, ami-0af0a14f, aki-68f0a12d
-us-west-1, karmic, 9.10 EOL, i386, instance-store, 20100826, ami-6ef0a12b, aki-5af0a11f
-ap-northeast-1, quantal, 12.10, amd64, ebs, 20121017, ami-3c07b83d, aki-ee5df7ef
-ap-northeast-1, quantal, 12.10, i386, ebs, 20121017, ami-3a07b83b, aki-ec5df7ed
-ap-northeast-1, quantal, 12.10, amd64, instance-store, 20121017, ami-0407b805, aki-ee5df7ef
-ap-northeast-1, quantal, 12.10, i386, instance-store, 20121017, ami-7008b771, aki-ec5df7ed
-ap-southeast-1, quantal, 12.10, amd64, ebs, 20121017, ami-8ed393dc, aki-aa225af8
-ap-southeast-1, quantal, 12.10, i386, ebs, 20121017, ami-88d393da, aki-a4225af6
-ap-southeast-1, quantal, 12.10, amd64, instance-store, 20121017, ami-e6d393b4, aki-aa225af8
-ap-southeast-1, quantal, 12.10, i386, instance-store, 20121017, ami-28d3937a, aki-a4225af6
-ap-southeast-2, quantal, 12.10, amd64, ebs, 20121017, ami-df8611e5, aki-31990e0b
-ap-southeast-2, quantal, 12.10, i386, ebs, 20121017, ami-d98611e3, aki-33990e09
-ap-southeast-2, quantal, 12.10, amd64, instance-store, 20121017, ami-db8611e1, aki-31990e0b
-ap-southeast-2, quantal, 12.10, i386, instance-store, 20121017, ami-e38611d9, aki-33990e09
-eu-west-1, quantal, 12.10, amd64, hvm, 20121017, ami-ebeded9f, hvm
-eu-west-1, quantal, 12.10, amd64, ebs, 20121017, ami-e9eded9d, aki-62695816
-eu-west-1, quantal, 12.10, i386, ebs, 20121017, ami-efeded9b, aki-64695810
-eu-west-1, quantal, 12.10, amd64, instance-store, 20121017, ami-69eded1d, aki-62695816
-eu-west-1, quantal, 12.10, i386, instance-store, 20121017, ami-b5ececc1, aki-64695810
-sa-east-1, quantal, 12.10, amd64, ebs, 20121017, ami-cc30e9d1, aki-cc3ce3d1
-sa-east-1, quantal, 12.10, i386, ebs, 20121017, ami-d230e9cf, aki-bc3ce3a1
-sa-east-1, quantal, 12.10, amd64, instance-store, 20121017, ami-d030e9cd, aki-cc3ce3d1
-sa-east-1, quantal, 12.10, i386, instance-store, 20121017, ami-b230e9af, aki-bc3ce3a1
-us-east-1, quantal, 12.10, amd64, hvm, 20121017, ami-9665dbff, hvm
-us-east-1, quantal, 12.10, amd64, ebs, 20121017, ami-9465dbfd, aki-825ea7eb
-us-east-1, quantal, 12.10, i386, ebs, 20121017, ami-9265dbfb, aki-805ea7e9
-us-east-1, quantal, 12.10, amd64, instance-store, 20121017, ami-e864da81, aki-825ea7eb
-us-east-1, quantal, 12.10, i386, instance-store, 20121017, ami-dc66d8b5, aki-805ea7e9
-us-west-1, quantal, 12.10, amd64, ebs, 20121017, ami-8f83a4ca, aki-8d396bc8
-us-west-1, quantal, 12.10, i386, ebs, 20121017, ami-8d83a4c8, aki-83396bc6
-us-west-1, quantal, 12.10, amd64, instance-store, 20121017, ami-fd83a4b8, aki-8d396bc8
-us-west-1, quantal, 12.10, i386, instance-store, 20121017, ami-0983a44c, aki-83396bc6
-us-west-2, quantal, 12.10, amd64, hvm, 20121017, ami-42f97072, hvm
-us-west-2, quantal, 12.10, amd64, ebs, 20121017, ami-40f97070, aki-98e26fa8
-us-west-2, quantal, 12.10, i386, ebs, 20121017, ami-5ef9706e, aki-c2e26ff2
-us-west-2, quantal, 12.10, amd64, instance-store, 20121017, ami-50f97060, aki-98e26fa8
-us-west-2, quantal, 12.10, i386, instance-store, 20121017, ami-00f97030, aki-c2e26ff2
-ap-northeast-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-eca719ed, aki-ee5df7ef
-ap-northeast-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-eaa719eb, aki-ec5df7ed
-ap-northeast-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-e0a719e1, aki-ee5df7ef
-ap-northeast-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-aca719ad, aki-ec5df7ed
-ap-southeast-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-fefcbcac, aki-aa225af8
-ap-southeast-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-f8fcbcaa, aki-a4225af6
-ap-southeast-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-fafcbca8, aki-aa225af8
-ap-southeast-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-d4fcbc86, aki-a4225af6
-ap-southeast-2, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-fb8611c1, aki-31990e0b
-ap-southeast-2, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-858611bf, aki-33990e09
-ap-southeast-2, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-cf8710f5, aki-31990e0b
-ap-southeast-2, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-898710b3, aki-33990e09
-eu-west-1, precise, 12.04 LTS, amd64, hvm, 20121026.1, ami-25656651, hvm
-eu-west-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-3b65664f, aki-62695816
-eu-west-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-3965664d, aki-64695810
-eu-west-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-a16665d5, aki-62695816
-eu-west-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-2966655d, aki-64695810
-sa-east-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-b45b82a9, aki-cc3ce3d1
-sa-east-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-ba5b82a7, aki-bc3ce3a1
-sa-east-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-805b829d, aki-cc3ce3d1
-sa-east-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-945b8289, aki-bc3ce3a1
-us-east-1, precise, 12.04 LTS, amd64, hvm, 20121026.1, ami-9078c0f9, hvm
-us-east-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-9c78c0f5, aki-825ea7eb
-us-east-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-9878c0f1, aki-805ea7e9
-us-east-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-9a873ff3, aki-825ea7eb
-us-east-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-52863e3b, aki-805ea7e9
-us-west-1, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-bb4f69fe, aki-8d396bc8
-us-west-1, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-b94f69fc, aki-83396bc6
-us-west-1, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-a34f69e6, aki-8d396bc8
-us-west-1, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-e34f69a6, aki-83396bc6
-us-west-2, precise, 12.04 LTS, amd64, hvm, 20121026.1, ami-60ab2250, hvm
-us-west-2, precise, 12.04 LTS, amd64, ebs, 20121026.1, ami-7eab224e, aki-98e26fa8
-us-west-2, precise, 12.04 LTS, i386, ebs, 20121026.1, ami-7cab224c, aki-c2e26ff2
-us-west-2, precise, 12.04 LTS, amd64, instance-store, 20121026.1, ami-1aab222a, aki-98e26fa8
-us-west-2, precise, 12.04 LTS, i386, instance-store, 20121026.1, ami-3aab220a, aki-c2e26ff2

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/userdata.sh
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/userdata.sh b/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/userdata.sh
deleted file mode 100644
index 9009fd6..0000000
--- a/providers/amazon/src/main/resources/com/axemblr/provisionr/amazon/userdata.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-set -e -x
-export DEBIAN_FRONTEND=noninteractive
-
-# adds the distribution codename as a shell var
-. /etc/lsb-release
-
-# add the puppet package repository
-wget http://apt.puppetlabs.com/puppetlabs-release-$DISTRIB_CODENAME.deb
-dpkg -i puppetlabs-release-$DISTRIB_CODENAME.deb
-
-apt-get update
-apt-get install -y puppet-common
-
-# TODO implement a special action for global package upgrades 
-# apt-get upgrade -y
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/features.xml b/providers/amazon/src/main/resources/features.xml
index a246b7c..0a4567e 100644
--- a/providers/amazon/src/main/resources/features.xml
+++ b/providers/amazon/src/main/resources/features.xml
@@ -16,15 +16,15 @@
   ~ limitations under the License.
   -->
 
-<features name="axemblr-provisionr-amazon-features-${project.version}"
+<features name="provisionr-amazon-features-${project.version}"
           xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
 
     <repository>
-        mvn:com.axemblr.provisionr/provisionr-core/${project.version}/xml/features
+        mvn:org.apache.provisionr/provisionr-core/${project.version}/xml/features
     </repository>
 
-    <feature name="axemblr-provisionr-amazon" version="${project.version}">
-        <feature version="${project.version}">axemblr-provisionr-core</feature>
+    <feature name="provisionr-amazon" version="${project.version}">
+        <feature version="${project.version}">provisionr-core</feature>
         <bundle dependency="true">
             mvn:org.jbundle.util.osgi.wrapped/org.jbundle.util.osgi.wrapped.org.apache.http.client/${http-client.version}
         </bundle>
@@ -34,10 +34,10 @@
         <bundle dependency="true">
             mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aws-java-sdk/${aws.sdk.version}
         </bundle>
-        <bundle start="true">mvn:com.axemblr.provisionr/provisionr-amazon/${project.version}</bundle>
+        <bundle start="true">mvn:org.apache.provisionr/provisionr-amazon/${project.version}</bundle>
 
-        <configfile finalname="/etc/com.axemblr.provisionr.amazon.cfg">
-            mvn:com.axemblr.provisionr/provisionr-amazon/${project.version}/cfg/defaults
+        <configfile finalname="/etc/org.apache.provisionr.amazon.cfg">
+            mvn:org.apache.provisionr/provisionr-amazon/${project.version}/cfg/defaults
         </configfile>
     </feature>
 

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/org.apache.provisionr.amazon.cfg
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/org.apache.provisionr.amazon.cfg b/providers/amazon/src/main/resources/org.apache.provisionr.amazon.cfg
new file mode 100644
index 0000000..d5837d6
--- /dev/null
+++ b/providers/amazon/src/main/resources/org.apache.provisionr.amazon.cfg
@@ -0,0 +1,7 @@
+
+# Amazon provisioning service configuration
+
+accessKey = access
+secretKey = secret
+
+region = us-east-1

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/README
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/org/apache/provisionr/amazon/README b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/README
new file mode 100644
index 0000000..0a95ad9
--- /dev/null
+++ b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/README
@@ -0,0 +1,3 @@
+
+ubuntu.csv was collected from:
+http://cloud-images.ubuntu.com/locator/ec2/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/adminaccess.pp.mustache
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/adminaccess.pp.mustache b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/adminaccess.pp.mustache
new file mode 100644
index 0000000..8551619
--- /dev/null
+++ b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/adminaccess.pp.mustache
@@ -0,0 +1,62 @@
+
+#
+# Make sure only a single user can access the machines over ssh
+# Note: this script assumes a Debian / Ubuntu system 
+# 
+
+user { "{{user}}":
+  groups => ['adm','dialout','cdrom', 'floppy','audio','dip','video','plugdev','netdev','admin','sudo'],
+  ensure => 'present',
+  managehome => 'true',
+  shell => '/bin/bash',
+  membership => 'inclusive',
+  system => 'false'
+}
+  
+file { "/home/{{user}}/.ssh":
+	ensure => 'directory',
+	require => User['{{user}}'],
+	owner => '{{user}}',
+	mode => '700'
+}
+
+ssh_authorized_key { '{{user}}-rsa-key':
+	ensure => 'present',
+	key => '{{publicKey}}',
+	type => 'rsa',
+	user => '{{user}}',
+	require => File['/home/{{user}}/.ssh']
+}  
+  
+file { "/etc/ssh/sshd_config":
+  owner => "root",
+  group => "root",
+  mode => 644,
+  replace => "true",
+  notify => Service["ssh"],
+  require => Package["openssh-server"],
+  source => "/tmp/sshd_config"
+}
+
+file { "/etc/sudoers":
+  owner => "root",
+  group => "root",
+  mode => 440,
+  replace => "true",
+  source => "/tmp/sudoers"
+}
+
+package { "openssh-server":
+  ensure => installed
+}
+
+service { "ssh":
+  ensure => running,
+  provider => 'upstart',
+  hasrestart => 'true',
+  hasstatus  => 'true',
+  require => [
+    File["/etc/ssh/sshd_config"],
+    Package["openssh-server"]
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/sshd_config.mustache
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/sshd_config.mustache b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/sshd_config.mustache
new file mode 100644
index 0000000..68eb68f
--- /dev/null
+++ b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/sshd_config.mustache
@@ -0,0 +1,83 @@
+# Package generated configuration file
+# See the sshd_config(5) manpage for details
+
+# What ports, IPs and protocols we listen for
+Port 22
+
+# Use these options to restrict which interfaces/protocols sshd will bind to
+#ListenAddress ::
+#ListenAddress 0.0.0.0
+
+Protocol 2
+# HostKeys for protocol version 2
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_ecdsa_key
+
+#Privilege Separation is turned on for security
+UsePrivilegeSeparation yes
+
+# Lifetime and size of ephemeral version 1 server key
+KeyRegenerationInterval 3600
+ServerKeyBits 768
+
+# Logging
+SyslogFacility AUTH
+LogLevel INFO
+
+# Authentication:
+LoginGraceTime 120
+PermitRootLogin no
+StrictModes yes
+
+RSAAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile     %h/.ssh/authorized_keys
+
+AllowUsers {{user}}
+
+# Don't read the user's ~/.rhosts and ~/.shosts files
+IgnoreRhosts yes
+# For this to work you will also need host keys in /etc/ssh_known_hosts
+RhostsRSAAuthentication no
+# similar for protocol version 2
+HostbasedAuthentication no
+# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
+#IgnoreUserKnownHosts yes
+
+# To enable empty passwords, change to yes (NOT RECOMMENDED)
+PermitEmptyPasswords no
+
+# Change to yes to enable challenge-response passwords (beware issues with
+# some PAM modules and threads)
+ChallengeResponseAuthentication no
+
+# Change to no to disable tunnelled clear text passwords
+PasswordAuthentication no
+
+X11Forwarding no
+X11DisplayOffset 10
+PrintMotd no
+PrintLastLog yes
+TCPKeepAlive yes
+#UseLogin no
+
+#MaxStartups 10:30:60
+#Banner /etc/issue.net
+
+# Allow client to pass locale environment variables
+# AcceptEnv LANG LC_*
+
+Subsystem sftp /usr/lib/openssh/sftp-server
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication and
+# PasswordAuthentication.  Depending on your PAM configuration,
+# PAM authentication via ChallengeResponseAuthentication may bypass
+# the setting of "PermitRootLogin without-password".
+# If you just want the PAM account and session checks to run without
+# PAM authentication, then enable this but set PasswordAuthentication
+# and ChallengeResponseAuthentication to 'no'.
+
+UsePAM yes
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/sudoers
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/sudoers b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/sudoers
new file mode 100644
index 0000000..2292dce
--- /dev/null
+++ b/providers/amazon/src/main/resources/org/apache/provisionr/amazon/puppet/sudoers
@@ -0,0 +1,28 @@
+# This file MUST be edited with the 'visudo' command as root.
+#
+# Please consider adding local content in /etc/sudoers.d/ instead of
+# directly modifying this file.
+#
+# See the man page for details on how to write a sudoers file.
+#
+Defaults	env_reset
+Defaults	secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+
+# Host alias specification
+
+# User alias specification
+
+# Cmnd alias specification
+
+# User privilege specification
+root	ALL=(ALL:ALL) ALL
+
+# Members of the admin group may gain root privileges
+%admin ALL=(ALL) ALL
+
+# Allow members of group sudo to execute any command
+%sudo	ALL=(ALL:ALL) NOPASSWD: ALL
+
+# See sudoers(5) for more information on "#include" directives:
+
+#includedir /etc/sudoers.d


[20/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/StartActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/StartActivitiCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/StartActivitiCommand.java
deleted file mode 100644
index 00b437a..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/StartActivitiCommand.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-package org.activiti.karaf.commands;
-
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.apache.felix.gogo.commands.Argument;
-import org.apache.felix.gogo.commands.Command;
-
-/**
- * @author Srinivasan Chikkala
- */
-@Command(scope = "activiti", name = "start",
-    description = "Starts the Activiti process instance from a deployed process definition")
-public class StartActivitiCommand extends ActivitiCommand {
-
-    @Argument(index = 0, name = "definitionID", required = true, multiValued = false,
-        description = "Activiti Process definition ID to start an instance of it.")
-    private String definitionID;
-
-    @Override
-    protected Object doExecute() throws Exception {
-        ProcessEngine pe = this.getProcessEngine();
-        if (pe == null) {
-            out().println("Process Engine NOT Found!");
-            return null;
-        }
-
-        RuntimeService rt = pe.getRuntimeService();
-        if (definitionID != null) {
-            ProcessInstance pi = rt.startProcessInstanceById(definitionID);
-            out().printf("Process instance %s Started\n", pi.getProcessInstanceId());
-        }
-
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/UndeployActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/UndeployActivitiCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/UndeployActivitiCommand.java
deleted file mode 100644
index 19f7b6f..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/UndeployActivitiCommand.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-package org.activiti.karaf.commands;
-
-import java.util.List;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.repository.Deployment;
-import org.apache.felix.gogo.commands.Argument;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-/**
- * @author Srinivasan Chikkala
- */
-@Command(scope = "activiti", name = "undeploy", description = "Undeploys the Activiti Deployments " +
-    "(Process definition, images, bar files etc")
-public class UndeployActivitiCommand extends ActivitiCommand {
-
-    @Argument(index = 0, name = "deploymentIDs", description = "Deployment IDs of the Activiti deployments " +
-        "for undeploying", required = false, multiValued = true)
-    private String[] deploymentIDs;
-
-    @Option(name = "-a", aliases = "--all", description = "Undeploys all Activiti deployments ")
-    private boolean undeployAll;
-
-    @Option(name = "-c", aliases = "--cascade", description = "Deletes the given deployment and cascade deletion to " +
-        "process instances, history process instances and jobs.")
-    private boolean cascade;
-
-
-    @Override
-    protected Object doExecute() throws Exception {
-        ProcessEngine engine = this.getProcessEngine();
-        if (engine == null) {
-            out().println("Process Engine NOT Found!");
-            return null;
-        }
-
-        RepositoryService repo = engine.getRepositoryService();
-
-        if (this.deploymentIDs != null && this.deploymentIDs.length > 0) {
-            for (String deploymentID : this.deploymentIDs) {
-                repo.deleteDeployment(deploymentID, this.cascade);
-                out().printf("Undeployed %s \n", deploymentID);
-            }
-            return null;
-        }
-
-        if (!undeployAll) {
-            out().println("Activiti Deployment IDs required or use the command with -a or --all " +
-                "option for all undeployments");
-            return null;
-        } else {
-            out().println("Undeploying all Activiti deployments...");
-            List<Deployment> depList = repo.createDeploymentQuery().orderByDeploymenTime().asc().list();
-            for (Deployment dep : depList) {
-                String deploymentID = dep.getId();
-                repo.deleteDeployment(deploymentID, this.cascade);
-                out().printf("Undeployed %s \n", deploymentID);
-            }
-        }
-
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/AbstractActivitiPrintHandler.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/AbstractActivitiPrintHandler.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/AbstractActivitiPrintHandler.java
deleted file mode 100644
index 352b8f2..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/AbstractActivitiPrintHandler.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-
-package org.activiti.karaf.commands.handlers;
-
-import java.io.PrintWriter;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.activiti.engine.ActivitiException;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.history.HistoricActivityInstance;
-import org.activiti.engine.history.HistoricDetail;
-import org.activiti.engine.history.HistoricProcessInstance;
-import org.activiti.engine.history.HistoricVariableUpdate;
-import org.activiti.karaf.commands.util.Commands;
-
-/**
- * Abstract class that provides most of the implementation required to print process variable using
- * print handler.
- *
- * @author Srinivasan Chikkala
- * @see DefaultActivitiPrintHandler
- */
-public abstract class AbstractActivitiPrintHandler implements ActivitiPrintHandler {
-
-    public static final String PROCESS_DEFINITION_PROP = "bpm.process.definition";
-    public static final String PROCESS_VARS_PROP = "bpm.process.variables";
-
-    private static final Logger LOG = Logger.getLogger(AbstractActivitiPrintHandler.class.getName());
-
-    private boolean verbose;
-    private boolean quiet;
-    private ProcessEngine processEngine;
-
-    public boolean isQuiet() {
-        return quiet;
-    }
-
-    public void setQuiet(boolean quiet) {
-        this.quiet = quiet;
-    }
-
-    public boolean isVerbose() {
-        return verbose;
-    }
-
-    public void setVerbose(boolean verbose) {
-        this.verbose = verbose;
-    }
-
-    public ProcessEngine getProcessEngine() {
-        return processEngine;
-    }
-
-    public void setProcessEngine(ProcessEngine processEngine) {
-        this.processEngine = processEngine;
-    }
-
-    /**
-     * Extended class can implement this method to print the variable specific information.
-     */
-    protected abstract void printVariable(PrintWriter out, String varName, Object varValue);
-
-    protected void printVariable(PrintWriter out, HistoricVariableUpdate var) {
-
-        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
-        // nvMap.put("Variable Type", var.getVariableTypeName());
-        if (this.isVerbose()) {
-            nvMap.put("Variable ID", var.getId());
-            nvMap.put("Revision", "" + var.getRevision());
-            nvMap.put("Updated Time", Commands.UTIL.formatDate(var.getTime()));
-        }
-        nvMap.put("Variable Name", var.getVariableName());
-        Object value = var.getValue();
-        String simpleValue = Commands.UTIL.valueOf(value);
-        if (simpleValue != null) {
-            nvMap.put("Value", simpleValue);
-        } else {
-            nvMap.put("Value", "");
-        }
-        Commands.UTIL.printNameValues(out, nvMap);
-
-        if (simpleValue == null) {
-            // print the value in a json serialization format.
-            printVariable(out, var.getVariableName(), value);
-        }
-        out.println();
-    }
-
-    protected void printVariables(PrintWriter out, Map<String, HistoricVariableUpdate> vars) {
-        for (HistoricVariableUpdate var : vars.values()) {
-            printVariable(out, var);
-        }
-    }
-
-    protected void printVariables(PrintWriter out, List<HistoricDetail> varList) {
-        Map<String, HistoricVariableUpdate> varMap = new TreeMap<String, HistoricVariableUpdate>();
-        // filter revisions
-        for (HistoricDetail detail : varList) {
-            HistoricVariableUpdate varDetail = (HistoricVariableUpdate) detail;
-            String varName = varDetail.getVariableName();
-            // expects the varList is sorted in a descending order of time.
-            if (!varMap.containsKey(varName)) {
-                varMap.put(varName, varDetail);
-            } else {
-                LOG.info("#### " + varName + " has multiple updates!!! "
-                    + Commands.UTIL.formatDate(varDetail.getTime()) + " Revision= "
-                    + varDetail.getRevision());
-            }
-        }
-        printVariables(out, varMap);
-    }
-
-    @Override
-    public void printInstanceData(PrintWriter out, boolean verbose, boolean quite, HistoricProcessInstance hpi) {
-        this.setVerbose(verbose);
-        this.setQuiet(quite);
-
-        List<HistoricDetail> varList = null;
-        try {
-            varList = this.processEngine.getHistoryService().createHistoricDetailQuery()
-                .variableUpdates().processInstanceId(hpi.getId()).orderByTime().desc().list();
-        } catch (ActivitiException ex) {
-            // silent about the error. and log it.
-            LOG.log(Level.INFO, "Error in getting process variables. " + ex.getMessage(), ex);
-        }
-        if (varList != null && varList.size() > 0) {
-            out.println("-------- Instance Variables ");
-            printVariables(out, varList);
-        } else {
-            LOG.info("------ No Instance Variables! for " + hpi.getId());
-        }
-    }
-
-    @Override
-    public void printActivityData(PrintWriter out, boolean verbose, boolean quite,
-                                  HistoricActivityInstance actInst) {
-        this.setVerbose(verbose);
-        this.setQuiet(quite);
-        if (quite) {
-            // don't print activity variable update per activity
-            return;
-        }
-        List<HistoricDetail> varList = null;
-        try {
-            varList = this.processEngine.getHistoryService().createHistoricDetailQuery()
-                .variableUpdates().activityInstanceId(actInst.getId()).orderByTime().desc().list();
-        } catch (ActivitiException ex) {
-            //silent about the error. and log it.
-            LOG.log(Level.INFO, "Error in getting process variables. " + ex.getMessage(), ex);
-        }
-
-        if (varList != null && varList.size() > 0) {
-            out.println("-------- Task Variables");
-            printVariables(out, varList);
-        } else {
-            LOG.info("------ No Task Variables! for " + actInst.getActivityId());
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/ActivitiPrintHandler.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/ActivitiPrintHandler.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/ActivitiPrintHandler.java
deleted file mode 100644
index d5ff680..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/ActivitiPrintHandler.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-
-package org.activiti.karaf.commands.handlers;
-
-import java.io.PrintWriter;
-import org.activiti.engine.history.HistoricActivityInstance;
-import org.activiti.engine.history.HistoricProcessInstance;
-
-/**
- * Service interface whose implementations can handle process variables printing as part of bpm:info cmd.
- * service providers can register implementation of this interface as a OSGi service which the bpm:info cmd
- * can lookup and use to print a bpmn process specific variable information.
- * <p/>
- * Each OSGi service registered can have the following set of properties
- * process-definition=<process-definition-id> - which handles all process instances variable printing for this
- * process definition.
- * process-var-name=<name-of-the-var> - which handles all process instances that contains this variable name
- * useful when you want to handles any process definitions that contains this variable.
- *
- * @author Srinivasan Chikkala
- */
-public interface ActivitiPrintHandler {
-
-    /**
-     * Print instance level Activiti process variable data
-     */
-    void printInstanceData(PrintWriter out, boolean verbose, boolean quiet, HistoricProcessInstance hpi);
-
-    /**
-     * Print activity level Activiti process variable data
-     */
-    void printActivityData(PrintWriter out, boolean verbose, boolean quiet, HistoricActivityInstance actInst);
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/DefaultActivitiPrintHandler.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/DefaultActivitiPrintHandler.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/DefaultActivitiPrintHandler.java
deleted file mode 100644
index 82c7897..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/handlers/DefaultActivitiPrintHandler.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-
-package org.activiti.karaf.commands.handlers;
-
-import java.io.PrintWriter;
-import java.io.StringReader;
-import java.lang.reflect.Modifier;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import org.activiti.karaf.commands.util.Commands;
-
-/**
- * Default implementation of the process variable print handler.
- *
- * @author Srinivasan Chikkala
- */
-public class DefaultActivitiPrintHandler extends AbstractActivitiPrintHandler {
-
-    private static final Logger LOG = Logger.getLogger(DefaultActivitiPrintHandler.class.getName());
-
-    protected void printVariable(PrintWriter out, String varName, Object varValue) {
-        Gson gson = new GsonBuilder()
-            .setPrettyPrinting()
-            .serializeNulls()
-            .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
-            .create();
-
-        LOG.info("Printing var " + varName);
-        String jsonText = null;
-        try {
-            jsonText = gson.toJson(varValue);
-        } catch (Exception ex) {
-            jsonText = "{\n  " + varValue + "\n}"; // use default toString object            
-            LOG.log(Level.SEVERE, "Serializing Activiti Variable. " + ex.getMessage(), ex);
-        }
-
-        Commands.UTIL.printText(out, new StringReader(jsonText), " ");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/util/Commands.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/util/Commands.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/util/Commands.java
deleted file mode 100644
index 6ed8283..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/util/Commands.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-
-package org.activiti.karaf.commands.util;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Map;
-import java.util.TimeZone;
-
-/**
- * This class provides common utils for commands processing
- *
- * @author Srinivasan Chikkala
- */
-public class Commands {
-
-    public static final Commands UTIL = new Commands();
-
-    public void printNameValues(PrintWriter out, Map<String, String> nvMap) {
-        String fmt = "  %-16.16s %-20.60s\n";
-        for (String key : nvMap.keySet()) {
-            String value = nvMap.get(key);
-            out.printf(fmt, key + ":", value);
-        }
-    }
-
-    public String formatDate(Date date) {
-        String dateTxt = "--";
-        if (date != null) {
-            dateTxt = DateFormat.getDateTimeInstance().format(date);
-        }
-        return dateTxt;
-    }
-
-    public String formatDuration(Long duration) {
-        String dTxt = "--";
-        if (duration != null) {
-            SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss:SSS");
-            format.setTimeZone(TimeZone.getTimeZone("GMT"));
-            dTxt = format.format(new Date(duration));
-        }
-        return dTxt;
-    }
-
-    public void printText(PrintWriter out, Reader txtReader, String tabSpace) {
-        BufferedReader in = new BufferedReader(txtReader);
-        String line = null;
-        try {
-            while ((line = in.readLine()) != null) {
-                out.printf("  %-16.16s %s\n", tabSpace, line);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Convert a simple object to string.
-     *
-     * @param obj object .
-     * @return string if the object is simple. else return null.
-     */
-    public String valueOf(Object obj) {
-        String value = null;
-        if (obj == null) {
-            value = "NULL";
-        } else if (obj.getClass().isPrimitive()
-            || obj.getClass().isEnum()
-            || obj instanceof java.lang.String) {
-            value = obj.toString();
-        } else if (obj instanceof Date) {
-            value = formatDate((Date) obj);
-        } else {
-            value = null;
-        }
-        return value;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/util/TextTable.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/util/TextTable.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/util/TextTable.java
deleted file mode 100644
index 00be544..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/util/TextTable.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-package org.activiti.karaf.commands.util;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Srinivasan Chikkala
- */
-public class TextTable {
-
-    private static final int DEFAULT_WIDTH = 3;
-    private int col;
-
-    private List<String> columnHeaders;
-    private List<Integer> columnWidths;
-    private List<List<String>> rows;
-
-    public TextTable(int col) {
-        this.col = col;
-        this.columnHeaders = new ArrayList<String>();
-        this.columnWidths = new ArrayList<Integer>();
-        this.rows = new ArrayList<List<String>>();
-    }
-
-    public void addHeaders(String... headers) {
-        for (String header : headers) {
-            this.columnHeaders.add(header);
-            this.columnWidths.add(DEFAULT_WIDTH);
-        }
-    }
-
-    public void addRow(String... colValues) {
-        List<String> row = new ArrayList<String>();
-        rows.add(row);
-        if (colValues != null && colValues.length > this.col) {
-            throw new IllegalArgumentException("Number of Column values passed are more than the tables " +
-                "column cound " + this.col);
-        }
-        for (int i = 0; i < this.col; ++i) {
-            String colValue = "";
-            if ((i < colValues.length) && (colValues[i] != null)) {
-                colValue = colValues[i];
-                Integer colWidth = this.columnWidths.get(i);
-                if (colWidth < colValue.length()) {
-                    this.columnWidths.set(i, colValue.length());
-                }
-            }
-            row.add(colValue);
-        }
-    }
-
-    public void print(PrintStream stremaOut) {
-        PrintWriter out = new PrintWriter(stremaOut, true);
-        print(out);
-    }
-
-    public void print(PrintWriter out) {
-        StringBuilder hdrFmtBuff = new StringBuilder();
-        StringBuilder rowFmtBuff = new StringBuilder();
-        // " %-20.20s   %-20.20s [%-20.20s]\n";
-        // "[%-20.20s] [%-20.20s] [%-20.20s]\n";
-        for (Integer width : this.columnWidths) {
-            hdrFmtBuff.append(" %-").append(width).append(".").append(width).append("s ");
-            rowFmtBuff.append("[%-").append(width).append(".").append(width).append("s]");
-        }
-        hdrFmtBuff.append("\n");
-        rowFmtBuff.append("\n");
-        String hdrFmt = hdrFmtBuff.toString();
-        String rowFmt = rowFmtBuff.toString();
-
-        out.printf(hdrFmt, this.columnHeaders.toArray());
-        for (List<String> row : this.rows) {
-            out.printf(rowFmt, row.toArray());
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ActivitiCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ActivitiCommand.java
new file mode 100644
index 0000000..a9adc40
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ActivitiCommand.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.io.PrintWriter;
+import org.activiti.engine.ProcessEngine;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+
+/**
+ * Base class for implementing Activiti Karaf commands
+ *
+ * @author Srinivasan Chikkala
+ */
+public abstract class ActivitiCommand extends OsgiCommandSupport {
+
+    /**
+     * By default write normal messages to stdout
+     */
+    private PrintWriter out = new PrintWriter(System.out, true);
+
+    /**
+     * By default write error messages to stderr
+     */
+    private PrintWriter err = new PrintWriter(System.err, true);
+
+    private ProcessEngine processEngine;
+
+    public ProcessEngine getProcessEngine() {
+        return processEngine;
+    }
+
+    public void setProcessEngine(ProcessEngine processEngine) {
+        this.processEngine = processEngine;
+    }
+
+    public PrintWriter out() {
+        return out;
+    }
+
+    public void setOut(PrintWriter out) {
+        this.out = out;
+    }
+
+    public PrintWriter err() {
+        return err;
+    }
+
+    public void setErr(PrintWriter err) {
+        this.err = err;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/AddGroupCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/AddGroupCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/AddGroupCommand.java
new file mode 100644
index 0000000..f4b4a08
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/AddGroupCommand.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import com.google.common.annotations.VisibleForTesting;
+import static com.google.common.base.Preconditions.checkNotNull;
+import org.activiti.engine.IdentityService;
+import org.activiti.engine.identity.Group;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+@Command(scope = "activiti", name = "add-group", description = "Create new user group")
+public class AddGroupCommand extends ActivitiCommand {
+
+    @Option(name = "-i", aliases = "--id", description = "Group ID", required = true)
+    private String id;
+
+    @Option(name = "-n", aliases = "--name", description = "Group Name", required = true)
+    private String name;
+
+    @Option(name = "-t", aliases = "--type", description = "Group Type")
+    private String type = "security-role";
+
+    @Override
+    protected Object doExecute() throws Exception {
+        IdentityService identityService = getProcessEngine().getIdentityService();
+
+        Group group = identityService.newGroup(id);
+        group.setName(name);
+        group.setType(type);
+        identityService.saveGroup(group);
+
+        return null;
+    }
+
+    @VisibleForTesting
+    void setId(String id) {
+        this.id = checkNotNull(id, "id is null");
+    }
+
+    @VisibleForTesting
+    void setName(String name) {
+        this.name = checkNotNull(name, "name is null");
+    }
+
+    @VisibleForTesting
+    void setType(String type) {
+        this.type = checkNotNull(type, "type is null");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/AddUserCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/AddUserCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/AddUserCommand.java
new file mode 100644
index 0000000..e94d54c
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/AddUserCommand.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import org.activiti.engine.IdentityService;
+import org.activiti.engine.identity.User;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+@Command(scope = "activiti", name = "add-user", description = "Create a new Activiti user")
+public class AddUserCommand extends ActivitiCommand {
+
+    @Option(name = "-i", aliases = "--id", description = "User ID", required = true)
+    private String id;
+
+    @Option(name = "-p", aliases = "--password", description = "User password", required = true)
+    private String password;
+
+    @Option(name = "-g", aliases = "--group", description = "Group ID", required = true)
+    private String groupId;
+
+    @Option(name = "-e", aliases = "--email", description = "User email")
+    private String email = "";
+
+    @Override
+    protected Object doExecute() throws Exception {
+        if (getProcessEngine() == null) {
+            throw new NullPointerException("Please configure a processEngine instance for this command");
+        }
+        IdentityService identityService = getProcessEngine().getIdentityService();
+
+        User user = identityService.newUser(id);
+        user.setEmail(password);
+        identityService.saveUser(user);
+
+        identityService.createMembership(id, groupId);
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/CleanHistoryActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/CleanHistoryActivitiCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/CleanHistoryActivitiCommand.java
new file mode 100644
index 0000000..59bcfc6
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/CleanHistoryActivitiCommand.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.util.List;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+@Command(scope = "activiti", name = "clean-history", description = "Removes history of the Activiti process instances")
+public class CleanHistoryActivitiCommand extends ActivitiCommand {
+
+    @Argument(index = 0, name = "instanceIDs", description = "Instance IDs to remove from history",
+        required = false, multiValued = true)
+    private String[] instanceIDs;
+
+    @Option(name = "-a", aliases = "--all", description = "Remove all Activiti Processes from history")
+    private boolean cleanAll;
+
+    @Option(name = "-pd", aliases = "--definitions", required = false, multiValued = true,
+        description = "Removes history of process instances started from the definitions")
+    private String[] definitionIDs;
+
+    @Override
+    protected Object doExecute() throws Exception {
+        ProcessEngine engine = this.getProcessEngine();
+        if (engine == null) {
+            out().println("Process Engine NOT Found!");
+            return null;
+        }
+        HistoryService historyService = engine.getHistoryService();
+
+        // order of priority if instnaceIDs or definitionIDs and all on the list
+        // process instnaceID and exist or process definitionIDs and exit or process all 
+        // TODO figure out how to add mutually exclusive options - instanceIDs | definitions | all
+
+        if (this.instanceIDs != null && this.instanceIDs.length > 0) {
+            this.cleanProcessInstanceHistory(historyService, this.instanceIDs);
+            return null;
+        }
+
+        if (this.definitionIDs != null && this.definitionIDs.length > 0) {
+            this.cleanProcessDefinitionHistory(historyService, this.definitionIDs);
+            return null;
+        }
+
+        // clean all history
+        if (!cleanAll) {
+            out().println("Process instance IDs required or use the command with -a " +
+                "or --all option to clean all history");
+            return null;
+        } else {
+            cleanAllHistory(historyService);
+        }
+
+        return null;
+    }
+
+    private void cleanAllHistory(HistoryService hs) {
+        out().println("Cleaning History of All Process Instances...");
+        List<HistoricProcessInstance> hpiList = hs.createHistoricProcessInstanceQuery()
+            .orderByProcessDefinitionId().asc().list();
+        if (hpiList == null || hpiList.size() == 0) {
+            out().println("No Process History found! ");
+            return;
+        }
+        for (HistoricProcessInstance hpi : hpiList) {
+            String processId = hpi.getId();
+            hs.deleteHistoricProcessInstance(hpi.getId());
+            out().printf("History removed for process instance %s \n", processId);
+        }
+    }
+
+    private void cleanProcessInstanceHistory(HistoryService hs, String... instances) {
+        for (String instanceId : instances) {
+            // query and if exists delete.
+            HistoricProcessInstance hpi = hs.createHistoricProcessInstanceQuery()
+                .processInstanceId(instanceId).singleResult();
+            if (hpi != null) {
+                hs.deleteHistoricProcessInstance(hpi.getId());
+                out().printf("History removed for process instance %s \n", hpi.getId());
+            } else {
+                out().printf("No History found for process instance %s \n", instanceId);
+            }
+        }
+    }
+
+    private void cleanProcessDefinitionHistory(HistoryService hs, String... definitions) {
+
+        for (String definitionId : definitions) {
+            List<HistoricProcessInstance> hpiList = hs.createHistoricProcessInstanceQuery()
+                .processDefinitionId(definitionId)
+                .orderByProcessDefinitionId().asc().list();
+            if (hpiList == null || hpiList.size() == 0) {
+                out().printf("No History found for process definition %s \n", definitionId);
+                break;
+            }
+            for (HistoricProcessInstance hpi : hpiList) {
+                String processId = hpi.getId();
+                hs.deleteHistoricProcessInstance(hpi.getId());
+                out().printf("History removed for process instance %s with definition %s\n", processId,
+                    definitionId);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/DeleteGroupCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/DeleteGroupCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/DeleteGroupCommand.java
new file mode 100644
index 0000000..950f433
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/DeleteGroupCommand.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+@Command(scope = "activiti", name = "delete-group", description = "Delete Group")
+public class DeleteGroupCommand extends ActivitiCommand {
+
+    @Option(name = "-i", aliases = "--id", description = "Group ID", required = true)
+    private String id;
+
+    @Override
+    protected Object doExecute() throws Exception {
+        getProcessEngine().getIdentityService().deleteGroup(id);
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/DeleteUserCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/DeleteUserCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/DeleteUserCommand.java
new file mode 100644
index 0000000..1171572
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/DeleteUserCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import org.activiti.engine.IdentityService;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+@Command(scope = "activiti", name = "delete-user", description = "Delete existing Activiti user")
+public class DeleteUserCommand extends ActivitiCommand {
+
+    @Option(name = "--id", description = "User ID")
+    private String id;
+
+    @Override
+    protected Object doExecute() throws Exception {
+        if (getProcessEngine() == null) {
+            throw new NullPointerException("Please configure a processEngine instance for this command");
+        }
+        IdentityService identityService = getProcessEngine().getIdentityService();
+        identityService.deleteUser(id);
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/InfoActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/InfoActivitiCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/InfoActivitiCommand.java
new file mode 100644
index 0000000..3a0b357
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/InfoActivitiCommand.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.io.PrintWriter;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.repository.Deployment;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.provisionr.activiti.karaf.commands.handlers.ActivitiPrintHandler;
+import org.apache.provisionr.activiti.karaf.commands.handlers.DefaultActivitiPrintHandler;
+import org.apache.provisionr.activiti.karaf.commands.util.Commands;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+/**
+ * karaf command class that prints the details about the bpmn process inlcuding deployment, definition,
+ * instance and process varaible details.
+ *
+ * @author Srinivasan Chikkala
+ */
+@Command(scope = "activiti", name = "info", description = "Provides details about the Activiti process instance")
+public class InfoActivitiCommand extends ActivitiCommand {
+
+    private static final Logger LOG = Logger.getLogger(InfoActivitiCommand.class.getName());
+
+    @Argument(index = 0, name = "instanceID", description = "Instance ID for which the details should " +
+        "be displayed", required = true, multiValued = false)
+    private String instanceID;
+
+    @Option(name = "-v", aliases = "--verbose", description = "Full details of the process instance")
+    private boolean verbose;
+
+    @Option(name = "-q", aliases = "--quiet", description = "Show minimum required details of the process instance")
+    private boolean quiet;
+
+    private ActivitiPrintHandler printHandler;
+
+    public boolean isVerbose() {
+        return verbose;
+    }
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+
+    public boolean isQuiet() {
+        return quiet;
+    }
+
+    public void setQuiet(boolean quiet) {
+        this.quiet = quiet;
+    }
+
+    public String getInstanceID() {
+        return instanceID;
+    }
+
+    public void setInstanceID(String instanceID) {
+        this.instanceID = instanceID;
+    }
+
+    public ActivitiPrintHandler getPrintHandler() {
+        return printHandler;
+    }
+
+    public void setPrintHandler(ActivitiPrintHandler printHandler) {
+        this.printHandler = printHandler;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        Object obj = null;
+        try {
+            obj = executeCommand();
+        } catch (Exception ex) {
+            out().println(ex.getMessage());
+            LOG.log(Level.INFO, ex.getMessage(), ex);
+        }
+        return obj;
+    }
+
+    protected Object executeCommand() throws Exception {
+        ProcessEngine pe = this.getProcessEngine();
+        if (pe == null) {
+            out().println("Process Engine NOT Found!");
+            return null;
+        }
+        if (this.instanceID == null || this.instanceID.trim().length() == 0) {
+            out().println("Instance ID required to show the information about the instance");
+            return null;
+        }
+
+        this.printHandler = this.findBPMPrintHandler();
+
+        printDetails(this.instanceID.trim());
+        return null;
+    }
+
+    protected ActivitiPrintHandler findBPMPrintHandler() {
+        ActivitiPrintHandler handler;
+        List<ActivitiPrintHandler> hList = null;
+        try {
+            String filter = null; // add the filter here per process.
+            hList = this.getAllServices(ActivitiPrintHandler.class, filter);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        if (hList == null || hList.size() == 0) {
+            DefaultActivitiPrintHandler defHandler = new DefaultActivitiPrintHandler();
+            defHandler.setProcessEngine(this.getProcessEngine());
+            handler = defHandler;
+        } else {
+            handler = hList.get(0); // first one that matches.
+        }
+        return handler;
+    }
+
+    protected void printDeploymentInfo(Deployment depInfo) {
+        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
+        nvMap.put("Deployment ID", depInfo.getId());
+        nvMap.put("Deployment Name", depInfo.getName());
+        nvMap.put("Deployment Time", Commands.UTIL.formatDate(depInfo.getDeploymentTime()));
+        Commands.UTIL.printNameValues(new PrintWriter(out(), true), nvMap);
+    }
+
+    protected void printProcessDefinitionInfo(ProcessDefinition pd) {
+        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
+        nvMap.put("Definition ID", pd.getId());
+        nvMap.put("Definition Name", pd.getName());
+        nvMap.put("Version", Integer.toString(pd.getVersion()));
+        nvMap.put("Resource Name", pd.getResourceName());
+        Commands.UTIL.printNameValues(new PrintWriter(out(), true), nvMap);
+
+    }
+
+    protected void printProcessInstanceInfo(HistoricProcessInstance hpi) {
+        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
+        nvMap.put("Instance ID", hpi.getId());
+        nvMap.put("Start Activity", hpi.getStartActivityId());
+        nvMap.put("End Activity", hpi.getEndActivityId());
+        nvMap.put("Start Time", Commands.UTIL.formatDate(hpi.getStartTime()));
+        nvMap.put("End Time", Commands.UTIL.formatDate(hpi.getEndTime()));
+        if (!this.isQuiet()) {
+            nvMap.put("Duration", Commands.UTIL.formatDuration(hpi.getDurationInMillis()));
+        }
+
+        PrintWriter out = new PrintWriter(out(), true);
+        Commands.UTIL.printNameValues(out, nvMap);
+        // print instance data
+        this.getPrintHandler().printInstanceData(out, this.isVerbose(), this.isQuiet(), hpi);
+    }
+
+    protected void printActivityInstanceInfo(HistoricActivityInstance actInst) {
+
+        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
+        nvMap.put("Activity ID", actInst.getActivityId());
+        if (!this.isQuiet()) {
+            nvMap.put("Activity Type", actInst.getActivityType());
+        }
+        nvMap.put("Activity Name", actInst.getActivityName());
+        if (!this.isQuiet()) {
+            nvMap.put("Execution ID", actInst.getExecutionId());
+        }
+        nvMap.put("Start Time", Commands.UTIL.formatDate(actInst.getStartTime()));
+        nvMap.put("End Time", Commands.UTIL.formatDate(actInst.getEndTime()));
+        if (!this.isQuiet()) {
+            nvMap.put("Duration", Commands.UTIL.formatDuration(actInst.getDurationInMillis()));
+        }
+
+        PrintWriter out = new PrintWriter(out(), true);
+        Commands.UTIL.printNameValues(out, nvMap);
+        // print activity vars
+        this.getPrintHandler().printActivityData(out, this.isVerbose(), this.isQuiet(), actInst);
+        out().println("-------------");
+    }
+
+    protected void printDetails(String pid) {
+        ProcessEngine pe = this.getProcessEngine();
+        RepositoryService repo = pe.getRepositoryService();
+        RuntimeService rt = pe.getRuntimeService();
+        HistoryService hs = pe.getHistoryService();
+
+        ProcessInstance pi = rt.createProcessInstanceQuery().processInstanceId(pid).singleResult();
+        HistoricProcessInstance hpi = hs.createHistoricProcessInstanceQuery().processInstanceId(pid)
+            .singleResult();
+        if (pi == null && hpi == null) {
+            // both null means. no process with that id.
+            out().printf("No process details found with process id %s \n", pid);
+            return;
+        }
+
+        String pdId = null;
+        if (pi != null) {
+            pdId = pi.getProcessDefinitionId();
+        } else if (hpi != null) {
+            pdId = hpi.getProcessDefinitionId();
+        }
+
+        ProcessDefinition pd = repo.createProcessDefinitionQuery().processDefinitionId(pdId).singleResult();
+        Deployment depInfo = repo.createDeploymentQuery().deploymentId(pd.getDeploymentId()).singleResult();
+        // print
+        if (isVerbose()) {
+            out().println("======== Deployment Details");
+            printDeploymentInfo(depInfo);
+
+            out().println("======== Process Definition Details");
+            printProcessDefinitionInfo(pd);
+        }
+
+        out().println("======== Process Instance Details");
+        printProcessInstanceInfo(hpi);
+
+        List<HistoricActivityInstance> actInstList = hs.createHistoricActivityInstanceQuery()
+            .processInstanceId(hpi.getId()).orderByHistoricActivityInstanceStartTime().asc().list();
+        if (actInstList != null && actInstList.size() > 0) {
+            out().println("======== Activity Execution Details");
+            for (HistoricActivityInstance actInst : actInstList) {
+                printActivityInstanceInfo(actInst);
+            }
+        } else {
+            LOG.info("No Activity execution details");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/KillActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/KillActivitiCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/KillActivitiCommand.java
new file mode 100644
index 0000000..9ad47c1
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/KillActivitiCommand.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.util.List;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+@Command(scope = "activiti", name = "kill", description = "Kills any active Activiti process instances")
+public class KillActivitiCommand extends ActivitiCommand {
+
+    @Argument(index = 0, name = "instanceIDs", description = "Instance IDs to kill set of active process instances",
+        required = false, multiValued = true)
+    private String[] instanceIDs;
+
+    @Option(name = "-a", aliases = "--all", description = "Kill all active process instances")
+    private boolean killAll;
+
+    @Override
+    protected Object doExecute() throws Exception {
+        ProcessEngine processEngine = this.getProcessEngine();
+        if (processEngine == null) {
+            out().println("Process Engine NOT Found!");
+            return null;
+        }
+
+        RuntimeService runtimeService = processEngine.getRuntimeService();
+
+        if (this.instanceIDs != null && this.instanceIDs.length > 0) {
+            for (String instanceID : instanceIDs) {
+                runtimeService.deleteProcessInstance(instanceID, "Forcefully terminating the instance");
+                out().printf("Process instance %s terminated\n", instanceID);
+            }
+            return null;
+        }
+
+        if (!killAll) {
+            out().println("Process instance IDs required or use the command with -a or --all option");
+            return null;
+        } else {
+            out().println("Signalling all executions in all active process instances...");
+            List<ProcessInstance> piList = runtimeService.createProcessInstanceQuery().orderByProcessInstanceId().asc().list();
+            for (ProcessInstance pi : piList) {
+                String instanceID = pi.getProcessInstanceId();
+                runtimeService.deleteProcessInstance(instanceID, "Forcefully terminating the instance");
+                out().printf("Process instance %s terminated\n", instanceID);
+            }
+        }
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListActivitiCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListActivitiCommand.java
new file mode 100644
index 0000000..ee149ae
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListActivitiCommand.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.io.PrintWriter;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.repository.Deployment;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.Execution;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.provisionr.activiti.karaf.commands.util.TextTable;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+@Command(scope = "activiti", name = "list", description = "Displays information about Activiti active " +
+    "process instances, process definitions, history of process instances")
+public class ListActivitiCommand extends ActivitiCommand {
+
+    @Option(name = "-pi", aliases = "--active", description = "Display information about all active process instances")
+    private boolean active;
+
+    @Option(name = "-pd", aliases = "--definitions", description = "Display information about all process definitions")
+    private boolean definitions;
+
+    @Option(name = "-h", aliases = "--history", description = "Display information about history of all process instances")
+    private boolean history;
+
+    @Option(name = "-d", aliases = "--deployments", description = "Display information about all Activiti deployments")
+    private boolean deployments;
+
+
+    @Override
+    protected Object doExecute() throws Exception {
+        ProcessEngine pe = this.getProcessEngine();
+
+        if (pe == null) {
+            out().println("Process Engine NOT Found!");
+            return null;
+        }
+
+        if (!(this.active || this.definitions || this.history || this.deployments)) {
+            // none of them set, display everything 
+            // set all to true;
+            this.active = this.definitions = this.history = this.deployments = true;
+        }
+
+        if (this.deployments) {
+            RepositoryService repo = pe.getRepositoryService();
+            printDeployments(out(), repo);
+        }
+
+        if (this.definitions) {
+            RepositoryService repo = pe.getRepositoryService();
+            printProcessDefinitions(out(), repo);
+        }
+
+        if (this.history) {
+            HistoryService his = pe.getHistoryService();
+            boolean printActive = !this.active; // if we show active process, dont print then in history 
+            printHistoricProcessInstances(out(), his, printActive);
+        }
+
+        if (this.active) {
+            RuntimeService rt = pe.getRuntimeService();
+            printActiveProcessInstances(out(), rt);
+        }
+
+
+        return null;
+    }
+
+    private String formatDate(Date date) {
+        String dateTxt = "";
+        if (date != null) {
+            dateTxt = DateFormat.getDateTimeInstance().format(date);
+        }
+        return dateTxt;
+    }
+
+    private String formatBpmResource(String bpmResource) {
+        if (bpmResource.startsWith("bundleresource:")) {
+            return bpmResource.substring("bundleresource:".length());
+        } else {
+            return bpmResource;
+        }
+    }
+
+    private void printDeployments(PrintWriter out, RepositoryService repo) {
+
+        List<Deployment> depList = repo.createDeploymentQuery().orderByDeploymenTime().asc().list();
+
+        out.println();
+        out.println("Activiti Deployments");
+        out.println("--------------------");
+        if (depList.isEmpty()) {
+            out.println("No Activiti Deployments Found.");
+            return;
+        }
+
+        TextTable txtTable = new TextTable(3);
+
+        txtTable.addHeaders("ID", "Name", "Deployment Time");
+        for (Deployment dep : depList) {
+            txtTable.addRow(dep.getId(), dep.getName(), formatDate(dep.getDeploymentTime()));
+        }
+        txtTable.print(out);
+    }
+
+    private void printProcessDefinitions(PrintWriter out, RepositoryService repo) {
+        List<ProcessDefinition> pdList = repo.createProcessDefinitionQuery()
+            .orderByDeploymentId().asc().list();
+
+        out.println();
+        out.println("Activiti Process Definitions");
+        out.println("----------------------------");
+        if (pdList.isEmpty()) {
+            out.println("No Activiti Process Definitions Found.");
+            return;
+        }
+
+        TextTable txtTable = new TextTable(4);
+
+        txtTable.addHeaders("Definition ID", "Name", "Version", "Resource");
+        for (ProcessDefinition pd : pdList) {
+            Integer ver = pd.getVersion();
+            txtTable.addRow(pd.getId(), pd.getName(), ver.toString(), formatBpmResource(pd.getResourceName()));
+        }
+        txtTable.print(out);
+    }
+
+    private String getExecutions(RuntimeService rt, String pi) {
+        List<Execution> executions = rt.createExecutionQuery()
+            .processInstanceId(pi)
+            .orderByProcessInstanceId().asc().list();
+        StringBuilder bld = new StringBuilder();
+        boolean first = true;
+        for (Execution exec : executions) {
+            if (!first) {
+                bld.append(",");
+            } else {
+                first = false;
+            }
+            bld.append(exec.getId());
+        }
+        return bld.toString();
+    }
+
+    private void printActiveProcessInstances(PrintWriter out, RuntimeService rt) {
+
+        List<ProcessInstance> piList = rt.createProcessInstanceQuery().orderByProcessInstanceId().asc().list();
+
+        out.println();
+        out.println("Active Process Instances");
+        out.println("------------------------");
+        if (piList.isEmpty()) {
+            out.println("No Active Process Instances Found.");
+            return;
+        }
+
+        TextTable txtTable = new TextTable(3);
+
+        txtTable.addHeaders("Definition ID", "Instance ID", "Executions");
+        for (ProcessInstance pi : piList) {
+            txtTable.addRow(pi.getProcessDefinitionId(),
+                pi.getProcessInstanceId(), getExecutions(rt, pi.getProcessInstanceId()));
+        }
+        txtTable.print(out);
+    }
+
+    private void printHistoricProcessInstances(PrintWriter out, HistoryService his, boolean printActive) {
+
+        List<HistoricProcessInstance> hpiList = his.createHistoricProcessInstanceQuery()
+            .orderByProcessDefinitionId().asc().list();
+
+        out.println();
+        out.println("History of Activiti Process Instances");
+        out.println("-------------------------------------");
+        if (hpiList.isEmpty()) {
+            out.println("No History on Activiti Processes.");
+            return;
+        }
+
+        TextTable txtTable = new TextTable(4);
+
+        txtTable.addHeaders("Definition ID", "Instance ID", "Start Time", "End Time");
+        for (HistoricProcessInstance hpi : hpiList) {
+            Date endTime = hpi.getEndTime();
+            if (endTime == null && !printActive) {
+                continue;  // don't print active instance history if printActive is false - default.
+            }
+            txtTable.addRow(hpi.getProcessDefinitionId(), hpi.getId(),
+                formatDate(hpi.getStartTime()), formatDate(hpi.getEndTime()));
+        }
+        txtTable.print(out);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListGroupsCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListGroupsCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListGroupsCommand.java
new file mode 100644
index 0000000..20c3c07
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListGroupsCommand.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.util.List;
+import org.activiti.engine.identity.Group;
+import org.apache.felix.gogo.commands.Command;
+
+@Command(scope = "activiti", name = "list-groups", description = "List groups")
+public class ListGroupsCommand extends ActivitiCommand {
+
+    @Override
+    protected Object doExecute() throws Exception {
+        List<Group> groups = getProcessEngine().getIdentityService()
+            .createGroupQuery().orderByGroupId().asc().list();
+
+        if (groups.isEmpty()) {
+            err().println("No groups found.");
+        }
+        for (Group group : groups) {
+            out().printf("%s\t%s\t%s\n", group.getId(), group.getName(), group.getType());
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListUsersCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListUsersCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListUsersCommand.java
new file mode 100644
index 0000000..656d139
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/ListUsersCommand.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.util.List;
+import org.activiti.engine.identity.User;
+import org.apache.felix.gogo.commands.Command;
+
+@Command(scope = "activiti", name = "list-users", description = "List users")
+public class ListUsersCommand extends ActivitiCommand {
+
+    @Override
+    protected Object doExecute() throws Exception {
+        List<User> users = getProcessEngine().getIdentityService()
+            .createUserQuery().orderByUserId().asc().list();
+
+        if (users.isEmpty()) {
+            err().println("No users found.");
+        }
+        for (User user : users) {
+            out().printf("%s\t%s\t%s\n", user.getId(), user.getEmail(), user.getPassword());
+        }
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/SignalActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/SignalActivitiCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/SignalActivitiCommand.java
new file mode 100644
index 0000000..4993c74
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/SignalActivitiCommand.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.util.List;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.Execution;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+@Command(scope = "activiti", name = "signal",
+    description = "Signals any active executions in Activiti process instances")
+public class SignalActivitiCommand extends ActivitiCommand {
+
+    @Argument(index = 0, name = "instanceIDs", description = "Instance IDs to signal set of active process " +
+        "instances", required = false, multiValued = true)
+    private String[] instanceIDs;
+
+    @Option(name = "-a", aliases = "--all", description = "Signal all active process instances")
+    private boolean signalAll;
+
+    @Option(name = "-activities", aliases = "--activities", required = false,
+        multiValued = true, description = "Signal all activities in a process instances")
+    private String[] activities;
+
+    @Override
+    protected Object doExecute() throws Exception {
+        ProcessEngine engine = this.getProcessEngine();
+        if (engine == null) {
+            out().println("Process Engine NOT Found!");
+            return null;
+        }
+        RuntimeService runtimeService = engine.getRuntimeService();
+
+        if (this.instanceIDs != null && this.instanceIDs.length > 0) {
+            for (String instanceID : this.instanceIDs) {
+                signal(runtimeService, instanceID, this.activities);
+            }
+            return null;
+        }
+
+        if (!signalAll) {
+            out().println("Process instance IDs required or use the command with -a or --all option");
+            return null;
+        } else {
+            out().println("Signalling all executions in all active process instances...");
+            List<ProcessInstance> piList = runtimeService.createProcessInstanceQuery().orderByProcessInstanceId().asc().list();
+            for (ProcessInstance pi : piList) {
+                signal(runtimeService, pi.getProcessInstanceId(), this.activities);
+            }
+        }
+
+        return null;
+    }
+
+    private void signal(RuntimeService rt, Execution exec) {
+        try {
+            if (!exec.isEnded()) {
+                rt.signal(exec.getId());
+            } else {
+                out().printf("Execution %s already ended \n" + exec.getId());
+            }
+        } catch (Exception ex) {
+            out().printf("Exception:%s in signaling the execution %s \n", ex.getMessage(), exec.getId());
+        }
+    }
+
+    private void signal(RuntimeService rt, String pi, String... activities) {
+        if (activities == null || activities.length == 0) {
+            // signal all executions in the instance 
+            out().println("Signaling all active executions in the process instance " + pi);
+            List<Execution> executions = rt.createExecutionQuery()
+                .processInstanceId(pi)
+                .orderByProcessInstanceId().asc().list();
+            for (Execution exec : executions) {
+                signal(rt, exec);
+            }
+        } else {
+            for (String activity : activities) {
+                out().printf("Signaling activity %s in process instance %s \n", activity, pi);
+                List<Execution> executions = rt.createExecutionQuery()
+                    .processInstanceId(pi)
+                    .activityId(activity)
+                    .orderByProcessInstanceId().asc().list();
+                for (Execution exec : executions) {
+                    signal(rt, exec);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/StartActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/StartActivitiCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/StartActivitiCommand.java
new file mode 100644
index 0000000..90d4114
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/StartActivitiCommand.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+package org.apache.provisionr.activiti.karaf.commands;
+
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+@Command(scope = "activiti", name = "start",
+    description = "Starts the Activiti process instance from a deployed process definition")
+public class StartActivitiCommand extends ActivitiCommand {
+
+    @Argument(index = 0, name = "definitionID", required = true, multiValued = false,
+        description = "Activiti Process definition ID to start an instance of it.")
+    private String definitionID;
+
+    @Override
+    protected Object doExecute() throws Exception {
+        ProcessEngine pe = this.getProcessEngine();
+        if (pe == null) {
+            out().println("Process Engine NOT Found!");
+            return null;
+        }
+
+        RuntimeService rt = pe.getRuntimeService();
+        if (definitionID != null) {
+            ProcessInstance pi = rt.startProcessInstanceById(definitionID);
+            out().printf("Process instance %s Started\n", pi.getProcessInstanceId());
+        }
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/UndeployActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/UndeployActivitiCommand.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/UndeployActivitiCommand.java
new file mode 100644
index 0000000..56faa3c
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/UndeployActivitiCommand.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.util.List;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.repository.Deployment;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+@Command(scope = "activiti", name = "undeploy", description = "Undeploys the Activiti Deployments " +
+    "(Process definition, images, bar files etc")
+public class UndeployActivitiCommand extends ActivitiCommand {
+
+    @Argument(index = 0, name = "deploymentIDs", description = "Deployment IDs of the Activiti deployments " +
+        "for undeploying", required = false, multiValued = true)
+    private String[] deploymentIDs;
+
+    @Option(name = "-a", aliases = "--all", description = "Undeploys all Activiti deployments ")
+    private boolean undeployAll;
+
+    @Option(name = "-c", aliases = "--cascade", description = "Deletes the given deployment and cascade deletion to " +
+        "process instances, history process instances and jobs.")
+    private boolean cascade;
+
+
+    @Override
+    protected Object doExecute() throws Exception {
+        ProcessEngine engine = this.getProcessEngine();
+        if (engine == null) {
+            out().println("Process Engine NOT Found!");
+            return null;
+        }
+
+        RepositoryService repo = engine.getRepositoryService();
+
+        if (this.deploymentIDs != null && this.deploymentIDs.length > 0) {
+            for (String deploymentID : this.deploymentIDs) {
+                repo.deleteDeployment(deploymentID, this.cascade);
+                out().printf("Undeployed %s \n", deploymentID);
+            }
+            return null;
+        }
+
+        if (!undeployAll) {
+            out().println("Activiti Deployment IDs required or use the command with -a or --all " +
+                "option for all undeployments");
+            return null;
+        } else {
+            out().println("Undeploying all Activiti deployments...");
+            List<Deployment> depList = repo.createDeploymentQuery().orderByDeploymenTime().asc().list();
+            for (Deployment dep : depList) {
+                String deploymentID = dep.getId();
+                repo.deleteDeployment(deploymentID, this.cascade);
+                out().printf("Undeployed %s \n", deploymentID);
+            }
+        }
+
+        return null;
+    }
+
+}


[09/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/ProcessVariables.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/ProcessVariables.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/ProcessVariables.java
deleted file mode 100644
index 1fc6459..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/ProcessVariables.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon;
-
-public class ProcessVariables {
-
-    private ProcessVariables() {
-        /* singleton */
-    }
-
-    /**
-     * ID of a base image from which to create the others in the pool
-     */
-    public static final String IMAGE_ID = "imageId";
-
-    /**
-     * The reservation ID for a pool as String
-     *
-     * @see com.axemblr.provisionr.amazon.activities.RunOnDemandInstances
-     */
-    public static final String RESERVATION_ID = "reservationId";
-
-    /**
-     * The amount the user is willing to pay for spot instances in the
-     * Amazon pool he's trying to start. If set, the request is for spot
-     * instances, if null the request is for on demand instances.
-     * 
-     * @see com.axemblr.provisionr.amazon.activities.RunSpotInstances
-     */
-    public static final String SPOT_BID = "spotBid";
-
-    /**
-     * Flag that gets set when the process attempts to send spot requests
-     * for the first time. Because the describe call is not consistent
-     * until a reasonable delay passes, this will be used to timeout the
-     * Activiti retries so that the requests are not resent if they were
-     * successful. 
-     * 
-     * @see com.axemblr.provisionr.amazon.activities.RunSpotInstances
-     */
-    public static final String SPOT_REQUESTS_SENT = "spotRequestsSent";
-
-    /**
-     * List of request IDs as returned by Amazon for spot instances. These need to 
-     * be followed up to get the actual instance IDs.
-     * 
-     * @see com.axemblr.provisionr.amazon.activities.RunSpotInstances
-     */
-    public static final String SPOT_INSTANCE_REQUEST_IDS = "spotInstanceRequestIds";
-
-    /**
-     * Have all spot instance requests been handled by Amazon? (none are pending)
-     * 
-     *  @see com.axemblr.provisionr.amazon.activities.CheckNoRequestsAreOpen
-     */
-    public static final String NO_SPOT_INSTANCE_REQUESTS_OPEN = "noSpotInstanceRequestsOpen";
-
-    /**
-     * Are all spot instance requests in an active state? (none cancelled, none terminated)
-     * 
-     * @see com.axemblr.provisionr.amazon.activities.CheckAllRequestsAreActive
-     */
-    public static final String ALL_SPOT_INSTANCE_REQUESTS_ACTIVE = "allSpotInstanceRequestsActive";
-
-    /**
-     * List of instance IDs as returned by Amazon
-     *
-     * @see com.axemblr.provisionr.amazon.activities.RunOnDemandInstances
-     */
-    public static final String INSTANCE_IDS = "instanceIds";
-
-    /**
-     * List of requested EBS volume IDs
-     * 
-     * @see com.axemblr.provisionr.amazon.activities.CreateEBSVolumes
-     */
-    public static final String VOLUME_IDS = "volumeIds"; 
-
-    /**
-     * Are all started instances running?
-     *
-     * @see com.axemblr.provisionr.amazon.activities.CheckAllInstancesAreRunning
-     */
-    public static final String ALL_INSTANCES_RUNNING = "allInstancesRunning";
-
-    /**
-     * Are all instances marked as terminated?
-     *
-     * @see com.axemblr.provisionr.amazon.activities.CheckAllInstancesAreTerminated
-     */
-    public static final String ALL_INSTANCES_TERMINATED = "allInstancesTerminated";
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AllInstancesMatchPredicate.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AllInstancesMatchPredicate.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AllInstancesMatchPredicate.java
deleted file mode 100644
index d7c4b04..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AllInstancesMatchPredicate.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
-import com.amazonaws.services.ec2.model.DescribeInstancesResult;
-import com.amazonaws.services.ec2.model.Instance;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Iterables;
-
-import java.util.List;
-
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AllInstancesMatchPredicate extends AmazonActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AllInstancesMatchPredicate.class);
-
-    private final String resultVariable;
-    private final Predicate<Instance> predicate;
-
-    protected AllInstancesMatchPredicate(ProviderClientCache cache,
-                                         String resultVariable, Predicate<Instance> predicate) {
-        super(cache);
-        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
-        this.predicate = checkNotNull(predicate, "predicate is null");
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
-        @SuppressWarnings("unchecked")
-        Optional<List<String>> instanceIds = 
-            Optional.fromNullable((List<String>) execution.getVariable(ProcessVariables.INSTANCE_IDS));
-
-        if (!instanceIds.isPresent()) {
-            LOG.warn("<< Process variable '{}' not found", ProcessVariables.INSTANCE_IDS);
-            return;
-        } else if (instanceIds.get().size() == 0) {
-            LOG.info(">> No instances are currently registered in the process.");
-            return;
-        }
-
-        try {
-            DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
-                .withInstanceIds(instanceIds.get()));
-
-            List<Instance> instances = collectInstancesFromReservations(result.getReservations());
-
-            if (Iterables.all(instances, predicate)) {
-                LOG.info(">> All {} instances match predicate {} ", instanceIds, predicate);
-                execution.setVariable(resultVariable, true);
-
-            } else {
-                LOG.info("<< Not all instances {} match predicate {}", instanceIds, predicate);
-                execution.setVariable(resultVariable, false);
-            }
-        } catch (AmazonServiceException exception) {
-            if (exception.getErrorCode().equalsIgnoreCase("InvalidInstanceID.NotFound")) {
-                LOG.warn("<< Got error InvalidInstanceID.NotFound. Assuming predicate {} is false", predicate);
-                execution.setVariable(resultVariable, false);
-            } else {
-                throw Throwables.propagate(exception);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AllSpotRequestsMatchPredicate.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AllSpotRequestsMatchPredicate.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AllSpotRequestsMatchPredicate.java
deleted file mode 100644
index 1de5c7a..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AllSpotRequestsMatchPredicate.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsRequest;
-import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsResult;
-import com.amazonaws.services.ec2.model.SpotInstanceRequest;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.google.common.base.Predicate;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Iterables;
-
-public class AllSpotRequestsMatchPredicate extends AmazonActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AllSpotRequestsMatchPredicate.class);
-
-    protected final String resultVariable;
-    private final Predicate<SpotInstanceRequest> predicate;
-
-    protected AllSpotRequestsMatchPredicate(ProviderClientCache cache, String resultVariable, 
-            Predicate<SpotInstanceRequest> predicate) {
-        super(cache);
-        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
-        this.predicate = checkNotNull(predicate, "predicate is null");
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
-
-        LOG.info(">> Checking if all spot requests match predicate {}", predicate);
-
-        @SuppressWarnings("unchecked")
-        List<String> requestIds = (List<String>) execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
-        checkNotNull(requestIds, "process variable '{}' not found", ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
-
-        DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest();
-        describeRequest.setSpotInstanceRequestIds(requestIds);
-
-        // Retrieve all of the requests we want to monitor.
-        DescribeSpotInstanceRequestsResult describeResult = client.describeSpotInstanceRequests(describeRequest);
-        List<SpotInstanceRequest> requests = describeResult.getSpotInstanceRequests();
-
-        if (Iterables.all(requests, predicate)) {
-            LOG.info(">> All {} requests match predicate {} ", requests, predicate);
-            execution.setVariable(resultVariable, true);
-        } else {
-            LOG.info("<< Not all requests {} match predicate {}", requests, predicate);
-            execution.setVariable(resultVariable, false);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AmazonActivity.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AmazonActivity.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AmazonActivity.java
deleted file mode 100644
index 6d8d27a..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/AmazonActivity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import java.util.List;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.Instance;
-import com.amazonaws.services.ec2.model.Reservation;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-
-public abstract class AmazonActivity implements JavaDelegate {
-
-    private final ProviderClientCache providerClientCache;
-
-    protected AmazonActivity(ProviderClientCache providerClientCache) {
-        this.providerClientCache = checkNotNull(providerClientCache, "providerClientCache is null");
-    }
-
-    /**
-     * Amazon specific activity implementation
-     *
-     * @param client    Amazon client created using the pool provider
-     * @param pool      Virtual machines pool description
-     * @param execution Activiti execution context
-     */
-    public abstract void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception;
-
-    /**
-     * Wrap the abstract {@code execute} method with the logic that knows how to create the Amazon client
-     */
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-        Pool pool = (Pool) execution.getVariable(CoreProcessVariables.POOL);
-        checkNotNull(pool, "Please add the pool description as a process " +
-            "variable with the name '%s'.", CoreProcessVariables.POOL);
-
-        execute(providerClientCache.getUnchecked(pool.getProvider()), pool, execution);
-    }
-
-    protected List<Instance> collectInstancesFromReservations(List<Reservation> reservation) {
-        /* Make a copy as an ArrayList to force lazy collection evaluation */
-        List<List<Instance>> allInstances = Lists.transform(reservation, new Function<Reservation, List<Instance>>() {
-            @Override
-            public List<Instance> apply(Reservation reservation) {
-                return reservation.getInstances();
-            }
-        });
-
-        return Lists.newArrayList(Iterables.concat(allInstances));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CancelSpotRequests.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CancelSpotRequests.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CancelSpotRequests.java
deleted file mode 100644
index e24ace5..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CancelSpotRequests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.axemblr.provisionr.amazon.activities;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.CancelSpotInstanceRequestsRequest;
-import com.axemblr.provisionr.amazon.AmazonProvisionr;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-
-public class CancelSpotRequests extends AmazonActivity {
-
-    public static final Logger LOG = LoggerFactory.getLogger(AmazonProvisionr.class);
-
-    public CancelSpotRequests(ProviderClientCache providerClientCache) {
-        super(providerClientCache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
-        @SuppressWarnings("unchecked")
-        List<String> requests = (List<String>) execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
-        checkNotNull(requests, "process variable '{}' not found", ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
-        if (requests.size() > 0) {
-            client.cancelSpotInstanceRequests(new CancelSpotInstanceRequestsRequest()
-                    .withSpotInstanceRequestIds(requests));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllInstancesAreRunning.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllInstancesAreRunning.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllInstancesAreRunning.java
deleted file mode 100644
index b15272f..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllInstancesAreRunning.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.services.ec2.model.Instance;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.google.common.base.Predicate;
-
-public class CheckAllInstancesAreRunning extends AllInstancesMatchPredicate {
-
-    public static class InstanceIsRunning implements Predicate<Instance> {
-        @Override
-        public boolean apply(Instance instance) {
-            return instance.getState().getName().equalsIgnoreCase("running");
-        }
-
-        @Override
-        public String toString() {
-            return "InstanceIsRunning{}";
-        }
-    }
-
-    public CheckAllInstancesAreRunning(ProviderClientCache cache) {
-        super(cache, ProcessVariables.ALL_INSTANCES_RUNNING, new InstanceIsRunning());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllInstancesAreTerminated.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllInstancesAreTerminated.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllInstancesAreTerminated.java
deleted file mode 100644
index 7105083..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllInstancesAreTerminated.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.services.ec2.model.Instance;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.google.common.base.Predicate;
-
-public class CheckAllInstancesAreTerminated extends AllInstancesMatchPredicate {
-
-    public static class InstanceIsTerminated implements Predicate<Instance> {
-        @Override
-        public boolean apply(Instance instance) {
-            return instance.getState().getName().equalsIgnoreCase("terminated");
-        }
-
-        @Override
-        public String toString() {
-            return "InstanceIsTerminated{}";
-        }
-    }
-
-    public CheckAllInstancesAreTerminated(ProviderClientCache cache) {
-        super(cache, ProcessVariables.ALL_INSTANCES_TERMINATED, new InstanceIsTerminated());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllRequestsAreActive.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllRequestsAreActive.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllRequestsAreActive.java
deleted file mode 100644
index 22fe199..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckAllRequestsAreActive.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.axemblr.provisionr.amazon.activities;
-
-import org.activiti.engine.delegate.DelegateExecution;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.SpotInstanceRequest;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.google.common.base.Predicate;
-
-public class CheckAllRequestsAreActive extends AllSpotRequestsMatchPredicate {
-
-    public static class RequestIsActive implements Predicate<SpotInstanceRequest> {
-
-        @Override
-        public boolean apply(SpotInstanceRequest request) {
-            return "active".equalsIgnoreCase(request.getState());
-        }
-
-        @Override
-        public String toString() {
-            return "RequestIsActive{}";
-        }
-    }
-
-    public CheckAllRequestsAreActive(ProviderClientCache cache) {
-        super(cache, ProcessVariables.ALL_SPOT_INSTANCE_REQUESTS_ACTIVE, new RequestIsActive());
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
-        super.execute(client, pool, execution);        
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckNoRequestsAreOpen.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckNoRequestsAreOpen.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckNoRequestsAreOpen.java
deleted file mode 100644
index 4641e1f..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/CheckNoRequestsAreOpen.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.services.ec2.model.SpotInstanceRequest;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.google.common.base.Predicate;
-
-public class CheckNoRequestsAreOpen extends AllSpotRequestsMatchPredicate {
-
-    public static class RequestIsNotOpen implements Predicate<SpotInstanceRequest> {
-
-        @Override
-        public boolean apply(SpotInstanceRequest request) {
-            return !"open".equalsIgnoreCase(request.getState());
-        }
-
-        @Override
-        public String toString() {
-            return "RequestIsNotOpen{}";
-        }
-    }
-
-    public CheckNoRequestsAreOpen(ProviderClientCache cache) {
-        super(cache, ProcessVariables.NO_SPOT_INSTANCE_REQUESTS_OPEN, new RequestIsNotOpen());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DeleteKeyPair.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DeleteKeyPair.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DeleteKeyPair.java
deleted file mode 100644
index 1415866..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DeleteKeyPair.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
-import com.axemblr.provisionr.amazon.core.KeyPairs;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeleteKeyPair extends AmazonActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DeleteKeyPair.class);
-
-    public DeleteKeyPair(ProviderClientCache cache) {
-        super(cache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
-        String keyName = KeyPairs.formatNameFromBusinessKey(execution.getProcessBusinessKey());
-
-        LOG.info(">> Deleting key pair {}", keyName);
-        client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(keyName));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DeleteSecurityGroup.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DeleteSecurityGroup.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DeleteSecurityGroup.java
deleted file mode 100644
index 20e56b9..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DeleteSecurityGroup.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DeleteSecurityGroupRequest;
-import com.axemblr.provisionr.amazon.core.ErrorCodes;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.amazon.core.SecurityGroups;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.base.Throwables;
-import com.google.common.cache.LoadingCache;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeleteSecurityGroup extends AmazonActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DeleteSecurityGroup.class);
-
-    public DeleteSecurityGroup(ProviderClientCache cache) {
-        super(cache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
-        final String groupName = SecurityGroups.formatNameFromBusinessKey(execution.getProcessBusinessKey());
-        try {
-            LOG.info(">> Deleting Security Group {}", groupName);
-
-            client.deleteSecurityGroup(new DeleteSecurityGroupRequest().withGroupName(groupName));
-
-        } catch (AmazonServiceException e) {
-            if (e.getErrorCode().equals(ErrorCodes.SECURITY_GROUP_NOT_FOUND)) {
-                LOG.info("<< Security Group {} not found. Ignoring this error.", groupName);
-            } else {
-                throw Throwables.propagate(e);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DumpConsoleOutput.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DumpConsoleOutput.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DumpConsoleOutput.java
deleted file mode 100644
index 9a792d8..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/DumpConsoleOutput.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.GetConsoleOutputRequest;
-import com.amazonaws.services.ec2.model.GetConsoleOutputResult;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.google.common.base.Charsets;
-import static com.google.common.base.Preconditions.checkNotNull;
-import net.schmizz.sshj.common.Base64;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DumpConsoleOutput extends AmazonActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DumpConsoleOutput.class);
-
-    public DumpConsoleOutput(ProviderClientCache providerClientCache) {
-        super(providerClientCache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
-        Machine machine = (Machine) execution.getVariable("machine");
-        checkNotNull(machine, "expecting 'machine' as a process variable");
-
-        LOG.info(">> Requesting console output for instance {}", machine.getExternalId());
-        GetConsoleOutputResult result = client.getConsoleOutput(
-            new GetConsoleOutputRequest().withInstanceId(machine.getExternalId()));
-        if (result.getOutput() != null) {
-            String content = new String(Base64.decode(result.getOutput()), Charsets.UTF_8);
-            LOG.info("<< Console output for instance {}: {}", machine.getExternalId(), content);
-        } else {
-            LOG.warn("<< Console output was null for instance {}", machine.getExternalId());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/EnsureKeyPairExists.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/EnsureKeyPairExists.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/EnsureKeyPairExists.java
deleted file mode 100644
index 545c439..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/EnsureKeyPairExists.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
-import com.amazonaws.services.ec2.model.ImportKeyPairRequest;
-import com.amazonaws.services.ec2.model.ImportKeyPairResult;
-import com.axemblr.provisionr.amazon.core.ErrorCodes;
-import com.axemblr.provisionr.amazon.core.KeyPairs;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.cache.LoadingCache;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EnsureKeyPairExists extends AmazonActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EnsureKeyPairExists.class);
-
-    public EnsureKeyPairExists(ProviderClientCache cache) {
-        super(cache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
-        String keyName = KeyPairs.formatNameFromBusinessKey(execution.getProcessBusinessKey());
-        LOG.info(">> Importing admin access key pair as {}", keyName);
-
-        final String publicKey = pool.getAdminAccess().getPublicKey();
-        try {
-            importPoolPublicKeyPair(client, keyName, publicKey);
-
-        } catch (AmazonServiceException e) {
-            if (e.getErrorCode().equals(ErrorCodes.DUPLICATE_KEYPAIR)) {
-                LOG.info("<< Duplicate key pair found. Re-importing from pool description");
-
-                client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(keyName));
-                importPoolPublicKeyPair(client, keyName, publicKey);
-            }
-        }
-    }
-
-    private void importPoolPublicKeyPair(AmazonEC2 client, String keyName, String publicKey) {
-        ImportKeyPairResult result = client.importKeyPair(new ImportKeyPairRequest()
-            .withKeyName(keyName).withPublicKeyMaterial(publicKey));
-        LOG.info("<< Created remote key with fingerprint {}", result.getKeyFingerprint());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/EnsureSecurityGroupExists.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/EnsureSecurityGroupExists.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/EnsureSecurityGroupExists.java
deleted file mode 100644
index 34cfeb4..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/EnsureSecurityGroupExists.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
-import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
-import com.amazonaws.services.ec2.model.CreateSecurityGroupResult;
-import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
-import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
-import com.amazonaws.services.ec2.model.IpPermission;
-import com.amazonaws.services.ec2.model.RevokeSecurityGroupIngressRequest;
-import com.axemblr.provisionr.amazon.core.ErrorCodes;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.amazon.core.SecurityGroups;
-import com.axemblr.provisionr.amazon.functions.ConvertRuleToIpPermission;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.base.Throwables;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static com.google.common.collect.Sets.difference;
-import java.util.Set;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EnsureSecurityGroupExists extends AmazonActivity {
-
-    public static final Logger LOG = LoggerFactory.getLogger(EnsureSecurityGroupExists.class);
-
-    public EnsureSecurityGroupExists(ProviderClientCache cache) {
-        super(cache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
-        final String businessKey = execution.getProcessBusinessKey();
-        final String groupName = SecurityGroups.formatNameFromBusinessKey(businessKey);
-
-        try {
-            LOG.info(">> Creating Security Group with name {}", groupName);
-            CreateSecurityGroupRequest request = new CreateSecurityGroupRequest()
-                .withGroupName(groupName).withDescription("Security Group for " + businessKey);
-
-            CreateSecurityGroupResult result = client.createSecurityGroup(request);
-            LOG.info("<< Created Security Group with ID {}", result.getGroupId());
-
-        } catch (AmazonServiceException e) {
-            if (e.getErrorCode().equals(ErrorCodes.DUPLICATE_SECURITY_GROUP)) {
-                LOG.warn(String.format("<< Security Group %s already exists. " +
-                    "Synchronizing ingress rules.", groupName), e);
-            } else {
-                throw Throwables.propagate(e);
-            }
-        }
-
-        synchronizeIngressRules(client, groupName, pool.getNetwork());
-    }
-
-    private void synchronizeIngressRules(AmazonEC2 client, String groupName, Network network) {
-        DescribeSecurityGroupsResult result = client.describeSecurityGroups(
-            new DescribeSecurityGroupsRequest().withGroupNames(groupName));
-
-        Set<IpPermission> existingPermissions = ImmutableSet.copyOf(getOnlyElement(
-            result.getSecurityGroups()).getIpPermissions());
-
-        Set<IpPermission> expectedPermissions = ImmutableSet.copyOf(
-            Iterables.transform(network.getIngress(), ConvertRuleToIpPermission.FUNCTION));
-
-        authorizeIngressRules(client, groupName, difference(expectedPermissions, existingPermissions));
-        revokeIngressRules(client, groupName, difference(existingPermissions, expectedPermissions));
-    }
-
-    private void authorizeIngressRules(AmazonEC2 client, String groupName, Set<IpPermission> ipPermissions) {
-        if (!ipPermissions.isEmpty()) {
-            LOG.info(">> Authorizing Security Group Ingress Rules {} for {}", ipPermissions, groupName);
-
-            AuthorizeSecurityGroupIngressRequest request = new AuthorizeSecurityGroupIngressRequest()
-                .withGroupName(groupName).withIpPermissions(ipPermissions);
-            client.authorizeSecurityGroupIngress(request);
-        }
-    }
-
-    private void revokeIngressRules(AmazonEC2 client, String groupName, Set<IpPermission> ipPermissions) {
-        if (!ipPermissions.isEmpty()) {
-            LOG.info(">> Revoking Security Group Ingress Rules: {} for {}", ipPermissions, groupName);
-
-            RevokeSecurityGroupIngressRequest request = new RevokeSecurityGroupIngressRequest()
-                .withGroupName(groupName).withIpPermissions(ipPermissions);
-            client.revokeSecurityGroupIngress(request);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/GetInstanceIdsFromSpotRequests.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/GetInstanceIdsFromSpotRequests.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/GetInstanceIdsFromSpotRequests.java
deleted file mode 100644
index 64b613b..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/GetInstanceIdsFromSpotRequests.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.axemblr.provisionr.amazon.activities;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsRequest;
-import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsResult;
-import com.amazonaws.services.ec2.model.SpotInstanceRequest;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-
-public class GetInstanceIdsFromSpotRequests extends AmazonActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(GetInstanceIdsFromSpotRequests.class);
-    
-    public GetInstanceIdsFromSpotRequests(ProviderClientCache providerClientCache) {
-        super(providerClientCache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
-        LOG.info(">> retrieving instance Ids from spot request Ids");
-
-        @SuppressWarnings("unchecked")
-        List<String> requestIds = 
-                (List<String>) execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS);
-        DescribeSpotInstanceRequestsResult result = client.describeSpotInstanceRequests(
-                new DescribeSpotInstanceRequestsRequest().withSpotInstanceRequestIds(requestIds));
-        List<String> instanceIds = new ArrayList<String>();
-        for (SpotInstanceRequest spotRequest : result.getSpotInstanceRequests()) {
-            if (spotRequest.getInstanceId() != null) {
-                instanceIds.add(spotRequest.getInstanceId());
-            }
-        }
-        execution.setVariable(ProcessVariables.INSTANCE_IDS, instanceIds);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/PublishListOfMachines.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/PublishListOfMachines.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/PublishListOfMachines.java
deleted file mode 100644
index 30adafd..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/PublishListOfMachines.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
-import com.amazonaws.services.ec2.model.DescribeInstancesResult;
-import com.amazonaws.services.ec2.model.Instance;
-import com.amazonaws.services.ec2.model.Reservation;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.base.Function;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Lists;
-import java.util.Arrays;
-import java.util.List;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Use the IDs to retrieve details about the running machines and
- * store them as a process variable (machines)
- *
- * @see Machine
- */
-public class PublishListOfMachines extends AmazonActivity {
-
-    public static final Logger LOG = LoggerFactory.getLogger(PublishListOfMachines.class);
-
-    public PublishListOfMachines(ProviderClientCache providerClientCache) {
-        super(providerClientCache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
-        @SuppressWarnings("unchecked")
-        List<String> instanceIds = (List<String>) execution.getVariable(ProcessVariables.INSTANCE_IDS);
-        checkNotNull(instanceIds, "%s not found as a process variable", ProcessVariables.INSTANCE_IDS);
-
-        LOG.info(">> Describing instances {}", instanceIds);
-        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
-            .withInstanceIds(instanceIds));
-
-        LOG.info("<< Got the following reservations: {}", result.getReservations());
-
-        List<Instance> instances = collectInstancesFromReservations(result.getReservations());
-        List<Machine> machines = Lists.transform(instances,
-            new Function<Instance, Machine>() {
-                @Override
-                public Machine apply(Instance instance) {
-                    return Machine.builder()
-                        .externalId(instance.getInstanceId())
-                        .publicDnsName(instance.getPublicDnsName())
-                        .publicIp(instance.getPublicIpAddress())
-                        .privateDnsName(instance.getPrivateDnsName())
-                        .privateIp(instance.getPrivateIpAddress())
-                        .createMachine();
-                }
-            });
-
-        /* Create a new ArrayList to force evaluation for lazy collections */
-        execution.setVariable(CoreProcessVariables.MACHINES, Lists.newArrayList(machines));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunInstances.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunInstances.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunInstances.java
deleted file mode 100644
index bd3d191..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunInstances.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package com.axemblr.provisionr.amazon.activities;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.services.ec2.model.BlockDeviceMapping;
-import com.amazonaws.services.ec2.model.EbsBlockDevice;
-import com.amazonaws.services.ec2.model.LaunchSpecification;
-import com.amazonaws.services.ec2.model.RequestSpotInstancesRequest;
-import com.amazonaws.services.ec2.model.RunInstancesRequest;
-import com.amazonaws.services.ec2.model.SpotInstanceType;
-import com.axemblr.provisionr.amazon.core.ImageTable;
-import com.axemblr.provisionr.amazon.core.ImageTableQuery;
-import com.axemblr.provisionr.amazon.core.KeyPairs;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.amazon.core.SecurityGroups;
-import com.axemblr.provisionr.amazon.options.ProviderOptions;
-import com.axemblr.provisionr.amazon.options.SoftwareOptions;
-import com.axemblr.provisionr.api.hardware.BlockDevice;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.base.Charsets;
-import com.google.common.base.Strings;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
-import com.google.common.io.Resources;
-
-import java.io.IOException;
-import java.util.Calendar;
-import java.util.List;
-
-import net.schmizz.sshj.common.Base64;
-
-import org.activiti.engine.delegate.DelegateExecution;
-
-public abstract class RunInstances extends AmazonActivity {
-
-    public static final String DEFAULT_ARCH = "amd64";
-    public static final String DEFAULT_TYPE = "instance-store";
-    public static final String DEFAULT_AMI_ID = "ami-0cdf4965"; // Ubuntu 12.10 x64
-
-    protected RunInstances(ProviderClientCache providerClientCache) {
-        super(providerClientCache);
-    }
-
-    protected RunInstancesRequest createOnDemandInstancesRequest(Pool pool, DelegateExecution execution) 
-            throws IOException {
-        return (RunInstancesRequest) createRequest(pool, execution, false);
-    }
-
-    protected RequestSpotInstancesRequest createSpotInstancesRequest(Pool pool, DelegateExecution execution) 
-            throws IOException {
-        return (RequestSpotInstancesRequest) createRequest(pool, execution, true);
-    }
-
-    private AmazonWebServiceRequest createRequest(Pool pool, DelegateExecution execution, boolean spot) 
-            throws IOException {
-        final String businessKey = execution.getProcessBusinessKey();
-
-        final String securityGroupName = SecurityGroups.formatNameFromBusinessKey(businessKey);
-        final String keyPairName = KeyPairs.formatNameFromBusinessKey(businessKey);
-
-        final String instanceType = pool.getHardware().getType();
-        final String imageId = getImageIdFromPoolConfigurationOrQueryImageTable(
-            pool, pool.getProvider(), instanceType);
-
-        final String userData = Resources.toString(Resources.getResource(RunInstances.class,
-            "/com/axemblr/provisionr/amazon/userdata.sh"), Charsets.UTF_8);
-
-        List<BlockDevice> blockDevices = pool.getHardware().getBlockDevices();
-        List<BlockDeviceMapping> blockDeviceMappings = Lists.newArrayList();
-        if (blockDevices != null && blockDevices.size() > 0) {
-            for (BlockDevice device : blockDevices) {
-                blockDeviceMappings.add(new BlockDeviceMapping()
-                        .withDeviceName(device.getName())
-                        .withEbs(new EbsBlockDevice()
-                            .withVolumeSize(device.getSize())
-                            .withDeleteOnTermination(true)
-                         ));
-            }
-        }
-
-        if (spot) {
-            Calendar validUntil = Calendar.getInstance();
-            validUntil.add(Calendar.MINUTE, 10);
-            final String spotPrice = checkNotNull(pool.getProvider().getOption(ProviderOptions.SPOT_BID),
-                    "The bid for spot instances was not specified");
-            LaunchSpecification ls = new LaunchSpecification()
-                .withInstanceType(instanceType)
-                .withKeyName(keyPairName)
-                .withImageId(imageId)
-                .withBlockDeviceMappings(blockDeviceMappings)
-                .withSecurityGroups(Lists.newArrayList(securityGroupName))
-                .withUserData(Base64.encodeBytes(userData.getBytes(Charsets.UTF_8)));
-            return new RequestSpotInstancesRequest()
-                .withSpotPrice(spotPrice)
-                .withLaunchSpecification(ls)
-                .withLaunchGroup(businessKey)
-                .withInstanceCount(pool.getExpectedSize())
-                .withType(SpotInstanceType.OneTime)
-                .withValidUntil(validUntil.getTime());
-        } else {
-            return new RunInstancesRequest()
-                .withClientToken(businessKey)
-                .withSecurityGroups(securityGroupName)
-                .withKeyName(keyPairName)
-                .withInstanceType(instanceType)
-                .withImageId(imageId)
-                .withBlockDeviceMappings(blockDeviceMappings)
-                .withMinCount(pool.getMinSize())
-                .withMaxCount(pool.getExpectedSize())
-                .withUserData(Base64.encodeBytes(userData.getBytes(Charsets.UTF_8)));
-        }
-    }
-
-    private String getImageIdFromPoolConfigurationOrQueryImageTable(
-            Pool pool, Provider provider, String instanceType
-        ) {
-            final String imageId = pool.getSoftware().getImageId();
-            if (!Strings.isNullOrEmpty(imageId)) {
-                return "default".equals(imageId) ? DEFAULT_AMI_ID : imageId;
-            }
-
-            ImageTable imageTable;
-            try {
-                imageTable = ImageTable.fromCsvResource("/com/axemblr/provisionr/amazon/ubuntu.csv");
-            } catch (IOException e) {
-                throw Throwables.propagate(e);
-            }
-
-            final String region = provider.getOptionOr(ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION);
-            final String version = provider.getOptionOr(SoftwareOptions.BASE_OPERATING_SYSTEM_VERSION,
-                SoftwareOptions.DEFAULT_BASE_OPERATING_SYSTEM_VERSION);
-
-            ImageTableQuery query = imageTable.query()
-                .filterBy("region", region)
-                .filterBy("version", version)
-                .filterBy("arch", DEFAULT_ARCH);
-
-            if (instanceType.equals("t1.micro")) {
-                query.filterBy("type", "ebs");
-            } else {
-                query.filterBy("type", DEFAULT_TYPE);
-            }
-
-            return query.singleResult();
-        }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunOnDemandInstances.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunOnDemandInstances.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunOnDemandInstances.java
deleted file mode 100644
index 6407b81..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunOnDemandInstances.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-* Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
-*
-* 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.
-*/
-
-package com.axemblr.provisionr.amazon.activities;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.Instance;
-import com.amazonaws.services.ec2.model.RunInstancesRequest;
-import com.amazonaws.services.ec2.model.RunInstancesResult;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
-
-public class RunOnDemandInstances extends RunInstances {
-
-    private static final Logger LOG = LoggerFactory.getLogger(RunOnDemandInstances.class);
-
-    public static final String DEFAULT_ARCH = "amd64";
-    public static final String DEFAULT_TYPE = "instance-store";
-
-    public RunOnDemandInstances(ProviderClientCache cache) {
-        super(cache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws IOException {
-
-        final RunInstancesRequest request = createOnDemandInstancesRequest(pool, execution);
-        // TODO allow for more options (e.g. monitoring & termination protection etc.)
-
-        LOG.info(">> Sending RunInstances request: {}", request);
-        RunInstancesResult result = client.runInstances(request);
-        LOG.info("<< Got RunInstances result: {}", result);
-
-        // TODO tag instances: managed-by: Axemblr Provisionr, business-key: ID etc.
-
-        execution.setVariable(ProcessVariables.RESERVATION_ID,
-            result.getReservation().getReservationId());
-        execution.setVariable(ProcessVariables.INSTANCE_IDS,
-            collectInstanceIdsAsList(result.getReservation().getInstances()));
-    }
-
-
-    private List<String> collectInstanceIdsAsList(List<Instance> instances) {
-        /* Make a copy as an ArrayList to force lazy collection evaluation */
-        return Lists.newArrayList(Lists.transform(instances,
-            new Function<Instance, String>() {
-                @Override
-                public String apply(Instance instance) {
-                    return instance.getInstanceId();
-                }
-            }));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunSpotInstances.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunSpotInstances.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunSpotInstances.java
deleted file mode 100644
index 16766f4..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/RunSpotInstances.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-* Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
-*
-* 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.
-*/
-package com.axemblr.provisionr.amazon.activities;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsRequest;
-import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsResult;
-import com.amazonaws.services.ec2.model.Filter;
-import com.amazonaws.services.ec2.model.RequestSpotInstancesRequest;
-import com.amazonaws.services.ec2.model.RequestSpotInstancesResult;
-import com.amazonaws.services.ec2.model.SpotInstanceRequest;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Uninterruptibles;
-
-
-public class RunSpotInstances extends RunInstances {
-
-    private static final Logger LOG = LoggerFactory.getLogger(RunSpotInstances.class);
-    
-    public RunSpotInstances(ProviderClientCache cache) {
-        super(cache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws Exception {
-        /* before sending a new request, we check to see if we already registered
-           a launch group with the process ID, if yes, we don't re-send the request */
-        final String businessKey = execution.getProcessBusinessKey();
-
-        /* we timeout if requests have already been sent - the activity is being retried. */
-        Optional<Object> alreadySent = Optional.fromNullable(
-                execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS));
-
-        if (alreadySent.isPresent()) {
-            DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest()
-                    .withFilters(new Filter()
-                        .withName("launch-group").withValues(businessKey)
-                        .withName("state").withValues("open", "active"));
-            Stopwatch stopwatch = new Stopwatch().start();
-            while (stopwatch.elapsedTime(TimeUnit.MINUTES) < 2) {
-                DescribeSpotInstanceRequestsResult result = client.describeSpotInstanceRequests(describeRequest);
-                List<SpotInstanceRequest> pending = result.getSpotInstanceRequests();
-                if (pending.size() > 0) {
-                    LOG.info("Not resending spot instance requests {} for businessKey: {}.", pending, businessKey);
-                    execution.setVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS, 
-                            collectSpotInstanceRequestIds(pending));
-                    return;
-                }
-                LOG.info("The describe call has not returned anything yet, waiting 20s and retrying.");
-                Uninterruptibles.sleepUninterruptibly(20, TimeUnit.SECONDS);
-            }
-        }
-
-        final RequestSpotInstancesRequest request = createSpotInstancesRequest(pool, execution);
-        execution.setVariable(ProcessVariables.SPOT_REQUESTS_SENT, true);
-        RequestSpotInstancesResult requestResult = client.requestSpotInstances(request);
-        List<String> spotInstanceRequestIds = collectSpotInstanceRequestIds(requestResult.getSpotInstanceRequests());
-
-        execution.setVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS, spotInstanceRequestIds);
-    }
-    
-    private List<String> collectSpotInstanceRequestIds(List<SpotInstanceRequest> requestResponses) {
-        /* Make a copy as an ArrayList to force lazy collection evaluation */
-        return Lists.newArrayList(Lists.transform(requestResponses,
-            new Function<SpotInstanceRequest, String>() {
-                @Override
-                public String apply(SpotInstanceRequest instanceRequest) {
-                    return instanceRequest.getSpotInstanceRequestId();
-                }
-            }));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/SetupAdminAccess.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/SetupAdminAccess.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/SetupAdminAccess.java
deleted file mode 100644
index 68ed926..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/SetupAdminAccess.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.Mustache;
-import com.axemblr.provisionr.core.activities.PuppetActivity;
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.io.Resources;
-import java.io.IOException;
-import java.util.Map;
-
-public class SetupAdminAccess extends PuppetActivity {
-
-    public static final String DEFAULT_UBUNTU_AMI_USER = "ubuntu";
-
-    public static final String ADMIN_ACCESS_TEMPLATE = "/com/axemblr/provisionr/amazon/puppet/adminaccess.pp.mustache";
-    public static final String SSHD_CONFIG_TEMPLATE = "/com/axemblr/provisionr/amazon/puppet/sshd_config.mustache";
-    public static final String SUDOERS_TEMPLATE = "/com/axemblr/provisionr/amazon/puppet/sudoers";
-
-    public SetupAdminAccess() {
-        super("adminaccess");
-    }
-
-    @Override
-    public AdminAccess overrideAdminAccess(Pool pool) {
-        return pool.getAdminAccess().toBuilder().username(DEFAULT_UBUNTU_AMI_USER).createAdminAccess();
-    }
-
-    @Override
-    public String createPuppetScript(Pool pool, Machine machine) throws Exception {
-        return Mustache.toString(getClass(), ADMIN_ACCESS_TEMPLATE,
-            ImmutableMap.of(
-                "user", pool.getAdminAccess().getUsername(),
-                "publicKey", getRawSshKey(pool))
-        );
-    }
-
-    private String getRawSshKey(Pool pool) {
-        return pool.getAdminAccess().getPublicKey().split(" ")[1];
-    }
-
-    @Override
-    public Map<String, String> createAdditionalFiles(Pool pool, Machine machine) throws IOException {
-        return ImmutableMap.of(
-            "/tmp/sshd_config",
-            Mustache.toString(getClass(), SSHD_CONFIG_TEMPLATE,
-                ImmutableMap.of("user", pool.getAdminAccess().getUsername())),
-            "/tmp/sudoers",
-            Resources.toString(Resources.getResource(getClass(), SUDOERS_TEMPLATE), Charsets.UTF_8)
-        );
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/TerminateInstances.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/TerminateInstances.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/TerminateInstances.java
deleted file mode 100644
index 25bc47b..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/activities/TerminateInstances.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.activities;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
-import com.axemblr.provisionr.amazon.ProcessVariables;
-import com.axemblr.provisionr.amazon.core.ProviderClientCache;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.google.common.base.Optional;
-
-import java.util.List;
-
-import org.activiti.engine.delegate.DelegateExecution;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Terminate instances previously started by {@see RunOnDemandInstances}
- */
-public class TerminateInstances extends AmazonActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(TerminateInstances.class);
-
-    public TerminateInstances(ProviderClientCache cache) {
-        super(cache);
-    }
-
-    @Override
-    public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) {
-        @SuppressWarnings("unchecked")
-        Optional<List<String>> instanceIds = 
-                Optional.fromNullable((List<String>) execution.getVariable(ProcessVariables.INSTANCE_IDS));
-
-        LOG.info(">> Terminating instances: {}", instanceIds);
-        if (instanceIds.isPresent() && instanceIds.get().size() > 0) {
-            client.terminateInstances(new TerminateInstancesRequest().withInstanceIds(instanceIds.get()));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/config/DefaultProviderConfig.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/config/DefaultProviderConfig.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/config/DefaultProviderConfig.java
deleted file mode 100644
index 09e5b2f..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/config/DefaultProviderConfig.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.config;
-
-import com.axemblr.provisionr.amazon.AmazonProvisionr;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.provider.ProviderBuilder;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class DefaultProviderConfig {
-
-    private final String accessKey;
-    private final String secretKey;
-    private final String region;
-    private final String endpoint;
-
-    public DefaultProviderConfig(String accessKey, String secretKey, String region, String endpoint) {
-        this.accessKey = checkNotNull(accessKey, "accessKey is null");
-        this.secretKey = checkNotNull(secretKey, "secretKey is null");
-        this.region = checkNotNull(region, "region is null");
-        this.endpoint = checkNotNull(endpoint, "endpoint is null");
-    }
-
-    public Optional<Provider> createProvider() {
-        if (accessKey.isEmpty() || secretKey.isEmpty()) {
-            return Optional.absent();
-        }
-        final ProviderBuilder builder = Provider.builder()
-            .id(AmazonProvisionr.ID)
-            .accessKey(accessKey)
-            .secretKey(secretKey);
-
-        if (!region.isEmpty()) {
-            builder.option("region", region);
-        }
-
-        if (endpoint.isEmpty()) {
-            builder.endpoint(Optional.<String>absent());
-        } else {
-            builder.endpoint(endpoint);
-        }
-
-        return Optional.of(builder.createProvider());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ErrorCodes.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ErrorCodes.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ErrorCodes.java
deleted file mode 100644
index 78a159f..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ErrorCodes.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.core;
-
-public class ErrorCodes {
-
-    private ErrorCodes() {
-        /* singleton */
-    }
-
-    public static final String SECURITY_GROUP_NOT_FOUND = "InvalidGroup.NotFound";
-
-    public static final String DUPLICATE_SECURITY_GROUP = "InvalidGroup.Duplicate";
-
-    public static final String DUPLICATE_KEYPAIR = "InvalidKeyPair.Duplicate";
-
-    public static final String KEYPAIR_NOT_FOUND = "InvalidKeyPair.NotFound";
-
-}                         

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ImageTable.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ImageTable.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ImageTable.java
deleted file mode 100644
index 3a9587d..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ImageTable.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.core;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableTable;
-import com.google.common.collect.Iterables;
-import static com.google.common.collect.Iterables.transform;
-import static com.google.common.collect.Lists.newArrayList;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Table;
-import com.google.common.collect.Tables;
-import com.google.common.io.Resources;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-public class ImageTable {
-
-    private static final Splitter COMMA = Splitter.on(",").trimResults();
-
-    /**
-     * Load the list of AMIs from a resource file (csv format)
-     * <p/>
-     * Note: the parser is doing only split by comma. There is no
-     * support for escaping line components
-     *
-     * @param resource path to resource
-     * @return an instance of {@see ImageTable}
-     * @throws IOException
-     */
-    public static ImageTable fromCsvResource(String resource) throws IOException {
-        checkNotNull(resource, "resource is null");
-
-        List<String> lines = Resources.readLines(Resources.getResource(ImageTable.class, resource), Charsets.UTF_8);
-        checkArgument(!lines.isEmpty(), "the resource is an empty file");
-
-        final ImmutableTable.Builder<String, String, String> table = ImmutableTable.builder();
-        final Iterable<String> headers = extractHeaders(lines);
-
-        int index = 0;
-        for (String line : Iterables.skip(lines, 1)) {
-            final Iterable<Table.Cell<String, String, String>> cells =
-                combineHeadersWithLinePartsAsTableCells(index, headers, COMMA.split(line));
-            for (Table.Cell<String, String, String> cell : cells) {
-                table.put(cell);
-            }
-            index++;
-        }
-
-        return new ImageTable(table.build());
-    }
-
-    static Iterable<Table.Cell<String, String, String>> combineHeadersWithLinePartsAsTableCells(
-        int index, Iterable<String> headers, Iterable<String> lineParts
-    ) {
-        final String rowKey = "" + index;
-        return transform(zip(headers, lineParts),
-            new Function<Map.Entry<String, String>, Table.Cell<String, String, String>>() {
-                @Override
-                public Table.Cell<String, String, String> apply(Map.Entry<String, String> entry) {
-                    return Tables.immutableCell(rowKey, entry.getKey(), entry.getValue());
-                }
-            });
-    }
-
-    static <K, V> Iterable<Map.Entry<K, V>> zip(Iterable<K> first, Iterable<V> second) {
-        checkArgument(Iterables.size(first) == Iterables.size(second), "iterables don't have the same size");
-
-        final Iterator<K> iterator = first.iterator();
-        return newArrayList(transform(second, new Function<V, Map.Entry<K, V>>() {
-            @Override
-            public Map.Entry<K, V> apply(V input) {
-                return Maps.immutableEntry(iterator.next(), input);
-            }
-        }));
-    }
-
-    static Iterable<String> extractHeaders(List<String> lines) {
-        String headerLine = Iterables.getFirst(lines, "");
-        checkArgument(!headerLine.isEmpty(), "Found an empty header line");
-
-        return COMMA.split(headerLine);
-    }
-
-    private final Table<String, String, String> table;
-
-    public ImageTable(Table<String, String, String> table) {
-        this.table = checkNotNull(table, "table is null");
-    }
-
-    Table<String, String, String> getTable() {
-        return table;
-    }
-
-    public ImageTableQuery query() {
-        return new ImageTableQuery(this);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(table);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final ImageTable other = (ImageTable) obj;
-        return Objects.equal(this.table, other.table);
-    }
-
-    @Override
-    public String toString() {
-        return "ImageTable{" +
-            "table=" + table +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ImageTableQuery.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ImageTableQuery.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ImageTableQuery.java
deleted file mode 100644
index 78c18c9..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/ImageTableQuery.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.core;
-
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import java.util.Map;
-
-public class ImageTableQuery {
-
-    private final ImageTable table;
-    private final ImmutableMap.Builder<String, String> filtersBuilder = ImmutableMap.builder();
-
-    public ImageTableQuery(ImageTable table) {
-        this.table = checkNotNull(table, "table is null");
-    }
-
-    public ImageTableQuery filterBy(String column, String value) {
-        filtersBuilder.put(column, value);
-        return this;
-    }
-
-    public String singleResult() {
-        final Map<String, String> filters = filtersBuilder.build();
-        final ImmutableSet.Builder<String> builder = ImmutableSet.builder();
-
-        for (String row : table.getTable().rowKeySet()) {
-            if (matchesFilters(table.getTable().row(row), filters)) {
-                builder.add(table.getTable().get(row, "ami-id"));
-            }
-        }
-        return Iterables.getOnlyElement(builder.build());
-    }
-
-    boolean matchesFilters(final Map<String, String> row, Map<String, String> filters) {
-        return Iterables.all(filters.entrySet(),
-            new Predicate<Map.Entry<String, String>>() {
-                @Override
-                public boolean apply(Map.Entry<String, String> entry) {
-                    return Objects.equal(row.get(entry.getKey()), entry.getValue());
-                }
-            });
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(table, filtersBuilder);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final ImageTableQuery other = (ImageTableQuery) obj;
-        return Objects.equal(this.table, other.table) && Objects.equal(this.filtersBuilder, other.filtersBuilder);
-    }
-
-    @Override
-    public String toString() {
-        return "ImageTableQuery{" +
-            "table=" + table +
-            ", filters=" + filtersBuilder +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/KeyPairs.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/KeyPairs.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/KeyPairs.java
deleted file mode 100644
index fb7acf7..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/core/KeyPairs.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon.core;
-
-public class KeyPairs {
-
-    private KeyPairs() {
-        /* singleton */
-    }
-
-    public static String formatNameFromBusinessKey(String businessKey) {
-        return String.format("key-%s", businessKey);
-    }
-}


[11/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreatePoolCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreatePoolCommand.java b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreatePoolCommand.java
deleted file mode 100644
index ae7514f..0000000
--- a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/CreatePoolCommand.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.BlockDevice;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.commands.predicates.ProvisionrPredicates;
-import com.axemblr.provisionr.core.templates.PoolTemplate;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.io.Files;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
-
-/**
- * A typical call looks like this:
- * <p/>
- * $ provisionr:create --id amazon --key web-1 --size 5 --hardware-type m1.small \
- * --port 80 --port 443 --package nginx --package gunicorn --package python-pip
- */
-@Command(scope = "provisionr", name = "create", description = "Create pool of virtual machines")
-public class CreatePoolCommand extends CreateCommand {
-
-    @Option(name = "-k", aliases = "--key", description = "Unique business identifier for this pool", required = true)
-    private String key;
-
-    @Option(name = "-s", aliases = "--size", description = "Expected pool size")
-    private int size = 1;
-
-    @Option(name = "-h", aliases = "--hardware-type", description = "Virtual machine hardware type")
-    private String hardwareType = "t1.micro";
-
-    @Option(name = "--port", description = "Firewall ports that need to be open for any TCP traffic " +
-            "(multi-valued). SSH (22) is always open by default.", multiValued = true)
-    private List<Integer> ports = Lists.newArrayList();
-
-    @Option(name = "--volume", description = "Block devices that will be attached to each instance. " +
-        "(multi-valued) Expects the following format: [mapping]:[size in GB]. ", multiValued = true)
-    private List<String> blockDeviceOptions = Lists.newArrayList();
-
-    @Option(name = "-o", aliases = "--provider-options", description = "Provider-specific options (multi-valued). " +
-        "Expects either the key=value format or just plain key. If value is not specified, defaults to 'true'. " +
-        "Supported values: spotBid=x.xxx (Amazon).", multiValued = true)
-    private List<String> providerOptions = Lists.newArrayList();
-
-    @Option(name = "--image-id", description = "The id of the OS image with which the machines will be created.")
-    private String imageId = "";
-
-    @Option(name = "--cached-image", description = "If the machines will have their packages and files downloaded " +
-        "or not. If creating the machines from an existent image, software might already be installed.")
-    private boolean cachedImage = false;
-
-    public CreatePoolCommand(List<Provisionr> services, List<PoolTemplate> templates) {
-        super(services, templates);
-    }
-
-    @Override
-    protected Object doExecute() throws Exception {
-        checkArgument(size > 0, "size should be a positive integer");
-
-        Provisionr service = getService();
-        final Pool pool = createPoolFromArgumentsAndServiceDefaults(service);
-        final String processInstanceId = service.startPoolManagementProcess(key, pool);
-        return String.format("Pool management process started (id: %s)", processInstanceId);
-    }
-
-    Pool createPoolFromArgumentsAndServiceDefaults(Provisionr service) {
-        final Optional<Provider> defaultProvider = getDefaultProvider(service);
-
-        /* append the provider options that were passed in and rebuild the default provider */
-        // TODO: this currently does not support overriding default options, it will throw an exception
-        Map<String,String> options = ImmutableMap.<String, String>builder()
-                .putAll(defaultProvider.get().getOptions())     // default options
-                .putAll(parseProviderOptions(providerOptions))  // options added by the user
-                .build();
-        Provider provider = defaultProvider.get().toBuilder().options(options).createProvider();
-
-        final Software software = Software.builder()
-                .packages(packages)
-                .imageId(imageId)
-                .cachedImage(cachedImage)
-                .createSoftware();
-        final Hardware hardware = Hardware.builder()
-                .type(hardwareType)
-                .blockDevices(parseBlockDeviceOptions(blockDeviceOptions))
-                .createHardware();
-
-        final Pool pool = Pool.builder()
-                .provider(provider)
-                .hardware(hardware)
-                .software(software)
-                .network(buildNetwork(ports))
-                .adminAccess(collectCurrentUserCredentialsForAdminAccess())
-                .minSize(size)
-                .expectedSize(size)
-                .bootstrapTimeInSeconds(bootstrapTimeout)
-                .createPool();
-
-        return template != null ? applyTemplate(pool) : pool;
-    }
-
-    private List<BlockDevice> parseBlockDeviceOptions(List<String> options) {
-        List<BlockDevice> result = Lists.newArrayList();
-        for (String option : options) {
-            String[] parts = option.split(":");
-            checkArgument(parts.length == 2, "The arguments for the --volume option must be mapping:size");
-            result.add(BlockDevice.builder().name(parts[0]).size(Integer.parseInt(parts[1])).createBlockDevice());
-        }
-        return result;
-    }
-
-    private Map<String, String> parseProviderOptions(List<String> providerOptions) {
-        Map<String, String> result = Maps.newHashMap();
-        for (String option : providerOptions) {
-            String[] parts = option.split("=");
-            String value = parts.length > 1 ? parts[1] : "true";
-            result.put(parts[0], value);
-        }
-        return result;
-    }
-
-    @VisibleForTesting
-    void setKey(String key) {
-        this.key = checkNotNull(key, "key is null");
-    }
-
-    @VisibleForTesting
-    void setSize(int size) {
-        checkArgument(size > 0, "size should be a positive number");
-        this.size = size;
-    }
-
-    @VisibleForTesting
-    void setHardwareType(String hardwareType) {
-        this.hardwareType = checkNotNull(hardwareType, "hardwareType is null");
-    }
-
-    @VisibleForTesting
-    void setPorts(List<Integer> ports) {
-        this.ports = ImmutableList.copyOf(ports);
-    }
-
-    @VisibleForTesting
-    void setProviderOptions(List<String> providerOptions) {
-        this.providerOptions = ImmutableList.copyOf(providerOptions);
-    }
-
-    @VisibleForTesting
-    void setBlockDeviceOptions(List<String> blockDeviceOptions) {
-        this.blockDeviceOptions = ImmutableList.copyOf(blockDeviceOptions);
-    }
-
-    @VisibleForTesting
-    void setCachedImage(boolean cachedImage) {
-        this.cachedImage = cachedImage;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/DestroyPoolCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/DestroyPoolCommand.java b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/DestroyPoolCommand.java
deleted file mode 100644
index bdaff11..0000000
--- a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/DestroyPoolCommand.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.commands.predicates.ProvisionrPredicates;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Iterables;
-import java.util.List;
-import java.util.NoSuchElementException;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
-
-@Command(scope = "provisionr", name = "destroy", description = "Destroy pool")
-public class DestroyPoolCommand extends OsgiCommandSupport {
-
-    @Option(name = "-k", aliases = "--key", description = "Pool key", required = true)
-    private String businessKey;
-
-    private final List<Provisionr> services;
-    private final ProcessEngine processEngine;
-
-    public DestroyPoolCommand(List<Provisionr> services, ProcessEngine processEngine) {
-        this.services = checkNotNull(services, "services is null");
-        this.processEngine = checkNotNull(processEngine, "processEngine is null");
-    }
-
-    @Override
-    protected Object doExecute() throws Exception {
-        checkNotNull(businessKey, "pool business key is mandatory");
-
-        ProcessInstance instance = processEngine.getRuntimeService().createProcessInstanceQuery()
-            .processInstanceBusinessKey(businessKey).singleResult();
-        checkNotNull(instance, "no pool found with key " + businessKey);
-
-        String providerId = (String) processEngine.getRuntimeService()
-            .getVariable(instance.getId(), CoreProcessVariables.PROVIDER);
-        checkNotNull(providerId, "the process instance has no provider ID");
-
-        Optional<Provisionr> service = Iterables.tryFind(services, ProvisionrPredicates.withId(providerId));
-
-        if (service.isPresent()) {
-            service.get().destroyPool(businessKey);
-        } else {
-            throw new NoSuchElementException("No provisioning service found with id: " + providerId);
-        }
-
-        return null;
-    }
-
-    @VisibleForTesting
-    void setBusinessKey(String businessKey) {
-        this.businessKey = businessKey;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListPoolsCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListPoolsCommand.java b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListPoolsCommand.java
deleted file mode 100644
index 7d4be15..0000000
--- a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListPoolsCommand.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.reflect.TypeToken;
-import java.io.PrintStream;
-import java.util.List;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
-
-@Command(scope = "provisionr", name = "pools", description = "List active pools")
-public class ListPoolsCommand extends OsgiCommandSupport {
-
-    private PrintStream out = System.out;
-
-    @Option(name = "-k", aliases = "--key", description = "Key for filtering a specific pool",
-        required = false)
-    private String key = "";
-
-    private final ProcessEngine processEngine;
-
-    public ListPoolsCommand(ProcessEngine processEngine) {
-        this.processEngine = checkNotNull(processEngine, "processEngine is null");
-    }
-
-    @Override
-    protected Object doExecute() throws Exception {
-        List<ProcessInstance> processes;
-        if (key.isEmpty()) {
-            processes = processEngine.getRuntimeService().createProcessInstanceQuery().list();
-        } else {
-            processes = processEngine.getRuntimeService().createProcessInstanceQuery()
-                .processInstanceBusinessKey(key).list();
-        }
-
-        if (processes.isEmpty()) {
-            out.println("No active pools found. You can create one using provisionr:create");
-            return null;
-        }
-
-        final Gson gson = new GsonBuilder().setPrettyPrinting().create();
-        for (ProcessInstance instance : processes) {
-            Pool pool = (Pool) processEngine.getRuntimeService()
-                .getVariable(instance.getId(), CoreProcessVariables.POOL);
-            if (pool == null) {
-                continue; /* skip - this process is not a provisionr process */
-            }
-
-            String businessKey = (String) processEngine.getRuntimeService()
-                .getVariable(instance.getId(), CoreProcessVariables.POOL_BUSINESS_KEY);
-            if (!Objects.equal(instance.getBusinessKey(), businessKey)) {
-                continue; /* ignore - this is a process started by the main pool management process */
-            }
-
-            @SuppressWarnings("unchecked")
-            List<Machine> machines = (List<Machine>) processEngine.getRuntimeService()
-                .getVariable(instance.getId(), CoreProcessVariables.MACHINES);
-
-            out.println("****** Pool Description ******");
-            out.println(gson.toJson(pool));
-
-            out.println("****** List of Machines ******");
-            if (machines != null) {
-                out.println(gson.toJson(machines, new TypeToken<List<Machine>>() {
-                }.getType()));
-            }
-
-            out.println("Pool Key: " + instance.getBusinessKey());
-            out.println();
-        }
-
-        return null;
-    }
-
-    @VisibleForTesting
-    void setOut(PrintStream out) {
-        this.out = checkNotNull(out, "out is null");
-    }
-
-    @VisibleForTesting
-    void setKey(String key) {
-        this.key = checkNotNull(key, "key is null");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListServicesCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListServicesCommand.java b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListServicesCommand.java
deleted file mode 100644
index 4026ecf..0000000
--- a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListServicesCommand.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Lists;
-import java.io.PrintStream;
-import java.util.List;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
-
-@Command(scope = "provisionr", name = "services", description = "List provisioning services")
-public class ListServicesCommand extends OsgiCommandSupport {
-
-    private PrintStream out = System.out;
-
-    private final List<Provisionr> services;
-
-    public ListServicesCommand(List<Provisionr> services) {
-        this.services = checkNotNull(services, "services is null");
-    }
-
-    @Override
-    protected Object doExecute() throws Exception {
-        List<String> ids = Lists.newArrayList();
-        for (Provisionr service : services) {
-            ids.add(service.getId());
-        }
-        out.printf("Services: %s%n", Joiner.on(", ").join(ids));
-        return null;
-    }
-
-    @VisibleForTesting
-    void setOut(PrintStream out) {
-        this.out = checkNotNull(out, "out is null");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListTemplatesCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListTemplatesCommand.java b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListTemplatesCommand.java
deleted file mode 100644
index 80c8df3..0000000
--- a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ListTemplatesCommand.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import com.axemblr.provisionr.core.templates.PoolTemplate;
-import com.google.common.annotations.VisibleForTesting;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.io.PrintStream;
-import java.util.List;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
-
-/**
- * List pre-configured templates that can be used to create clusters on different providers
- */
-@Command(scope = "provisionr", name = "templates", description = "List of pre-configured templates")
-public class ListTemplatesCommand extends OsgiCommandSupport {
-
-    private PrintStream out = System.out;
-
-    private final List<PoolTemplate> templates;
-
-    public ListTemplatesCommand(List<PoolTemplate> templates) {
-        this.templates = checkNotNull(templates, "templates is null");
-    }
-
-    @Override
-    protected Object doExecute() throws Exception {
-        for (PoolTemplate template : templates) {
-            out.printf("- %s\n\t%s\n", template.getId(), template.getDescription());
-        }
-
-        return null;
-    }
-
-    @VisibleForTesting
-    void setOut(PrintStream out) {
-        this.out = checkNotNull(out, "out is null");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ResetRetriesCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ResetRetriesCommand.java b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ResetRetriesCommand.java
deleted file mode 100644
index 26d00bd..0000000
--- a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/ResetRetriesCommand.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.annotations.VisibleForTesting;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.io.PrintStream;
-import java.util.List;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.impl.persistence.entity.JobEntity;
-import org.activiti.engine.runtime.Job;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
-
-@Command(scope = "provisionr", name = "reset-retries",
-    description = "Reset to default (3) the number of retries of all jobs without retries left.")
-public class ResetRetriesCommand extends OsgiCommandSupport {
-
-    private final ProcessEngine processEngine;
-    private PrintStream out = System.out;
-
-    @Option(name = "-k", aliases = "--key", description = "Reset number of retries for jobs associated with pool", required = true)
-    private String businessKey;
-
-    public ResetRetriesCommand(ProcessEngine processEngine) {
-        this.processEngine = checkNotNull(processEngine, "processEngine is null");
-    }
-
-    @Override
-    protected Object doExecute() throws Exception {
-        if (businessKey == null || businessKey.isEmpty()) {
-            out.println("Please supply a business key");
-        } else {
-            // reverse the list to start the sub-processes first (they have bigger id's)
-            List<ProcessInstance> processInstanceList = processEngine.getRuntimeService()
-                .createProcessInstanceQuery().variableValueEquals(CoreProcessVariables.POOL_BUSINESS_KEY, businessKey)
-                .orderByProcessInstanceId().desc().list();
-
-            out.printf("Found %d processes with pool business key %s\n", processInstanceList.size(), businessKey);
-            int count = 0;
-            for (ProcessInstance instance : processInstanceList) {
-                List<Job> jobs = processEngine.getManagementService().createJobQuery()
-                    .processInstanceId(instance.getProcessInstanceId()).withException().list();
-                for (Job job : jobs) {
-                    count++;
-                    processEngine.getManagementService().setJobRetries(job.getId(), JobEntity.DEFAULT_RETRIES);
-                }
-            }
-            out.printf("Number of retries reset for %s jobs\n", count);
-        }
-        return null;
-    }
-
-    @VisibleForTesting
-    void setBusinessKey(String businessKey) {
-        this.businessKey = businessKey;
-    }
-
-    @VisibleForTesting
-    void setOut(PrintStream out) {
-        this.out = out;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/predicates/ProvisionrPredicates.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/predicates/ProvisionrPredicates.java b/karaf/commands/src/main/java/com/axemblr/provisionr/commands/predicates/ProvisionrPredicates.java
deleted file mode 100644
index b8a10f9..0000000
--- a/karaf/commands/src/main/java/com/axemblr/provisionr/commands/predicates/ProvisionrPredicates.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands.predicates;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.google.common.base.Predicate;
-
-public class ProvisionrPredicates {
-
-    private ProvisionrPredicates() {
-    }
-
-    public static Predicate<Provisionr> withId(final String id) {
-        return new Predicate<Provisionr>() {
-
-            @Override
-            public boolean apply(Provisionr candidate) {
-                return candidate.getId().equals(id);
-            }
-
-            @Override
-            public String toString() {
-                return "WithId{id=" + id + "}";
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/org/apache/provisionr/commands/CreateCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/org/apache/provisionr/commands/CreateCommand.java b/karaf/commands/src/main/java/org/apache/provisionr/commands/CreateCommand.java
new file mode 100644
index 0000000..d18239d
--- /dev/null
+++ b/karaf/commands/src/main/java/org/apache/provisionr/commands/CreateCommand.java
@@ -0,0 +1,126 @@
+package org.apache.provisionr.commands;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.io.Files;
+import java.io.File;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import org.apache.felix.gogo.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.commands.predicates.ProvisionrPredicates;
+import org.apache.provisionr.core.templates.PoolTemplate;
+
+public abstract class CreateCommand extends OsgiCommandSupport {
+
+    @Option(name = "--id", description = "Service ID (use provisionr:services)", required = true)
+    protected String id;
+
+    @Option(name = "--package", description = "Package to install by default (multi-valued)",
+        multiValued = true)
+    protected List<String> packages = Lists.newArrayList();
+
+    @Option(name = "-t", aliases = "--template", description = "Pre-configured template (packages, files)")
+    protected String template;
+
+    @Option(name = "--timeout", description = "Timeout in seconds for the command's initialization steps. " +
+        "If not specified, defaults to 600 seconds.")
+    protected int bootstrapTimeout = 600;
+
+    protected final List<Provisionr> services;
+
+    protected final List<PoolTemplate> templates;
+
+    public CreateCommand(List<Provisionr> services, List<PoolTemplate> templates) {
+        this.services = checkNotNull(services, "services is null");
+        this.templates = checkNotNull(templates, "templates is null");
+    }
+
+    @VisibleForTesting
+    void setId(String id) {
+        this.id = checkNotNull(id, "id is null");
+    }
+
+    @VisibleForTesting
+    void setPackages(List<String> packages) {
+        this.packages = ImmutableList.copyOf(packages);
+    }
+
+    @VisibleForTesting
+    void setTemplate(String template) {
+        this.template = checkNotNull(template, "template is null");
+    }
+
+    @VisibleForTesting
+    AdminAccess collectCurrentUserCredentialsForAdminAccess() {
+        String userHome = System.getProperty("user.home");
+
+        try {
+            String publicKey = Files.toString(new File(userHome, ".ssh/id_rsa.pub"), Charsets.UTF_8);
+            String privateKey = Files.toString(new File(userHome, ".ssh/id_rsa"), Charsets.UTF_8);
+
+            return AdminAccess.builder().username(System.getProperty("user.name"))
+                .publicKey(publicKey).privateKey(privateKey).createAdminAccess();
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    @VisibleForTesting
+    Pool applyTemplate(Pool pool) {
+        for (PoolTemplate candidate : templates) {
+            if (candidate.getId().equalsIgnoreCase(template)) {
+                return candidate.apply(pool);
+            }
+        }
+        throw new NoSuchElementException("No pool template found with name: " + template);
+    }
+
+    @VisibleForTesting
+    Network buildNetwork(List<Integer> ports) {
+        /* Always allow ICMP and ssh traffic by default */
+        return Network.builder().addRules(
+            Rule.builder().anySource().icmp().createRule(),
+            Rule.builder().anySource().tcp().port(22).createRule()
+        ).addRules(
+            formatPortsAsIngressRules(ports)
+        ).createNetwork();
+    }
+
+    Optional<Provider> getDefaultProvider(Provisionr service) {
+        checkArgument(service.getDefaultProvider().isPresent(), String.format("please configure a default provider " +
+            "by editing etc/org.apache.provisionr.%s.cfg", id));
+        return service.getDefaultProvider();
+    }
+
+    Provisionr getService() {
+        Optional<Provisionr> service = Iterables.tryFind(services, ProvisionrPredicates.withId(id));
+        if (!service.isPresent()) {
+            throw new NoSuchElementException("No provisioning service found with id: " + id);
+        }
+        return service.get();
+    }
+
+    private Set<Rule> formatPortsAsIngressRules(List<Integer> ports) {
+        ImmutableSet.Builder<Rule> rules = ImmutableSet.builder();
+        for (int port : ports) {
+            rules.add(Rule.builder().anySource().tcp().port(port).createRule());
+        }
+        return rules.build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/org/apache/provisionr/commands/CreateImageCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/org/apache/provisionr/commands/CreateImageCommand.java b/karaf/commands/src/main/java/org/apache/provisionr/commands/CreateImageCommand.java
new file mode 100644
index 0000000..2702a70
--- /dev/null
+++ b/karaf/commands/src/main/java/org/apache/provisionr/commands/CreateImageCommand.java
@@ -0,0 +1,52 @@
+package org.apache.provisionr.commands;
+
+import com.google.common.annotations.VisibleForTesting;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.templates.PoolTemplate;
+
+@Command(scope = "provisionr", name = "cache", description = "Create a cached golden image.")
+public class CreateImageCommand extends CreateCommand {
+
+    // TODO: remove this and use a provided parameter
+    private static final String HARDWARE_TYPE = "t1.micro";
+
+    public CreateImageCommand(List<Provisionr> services, List<PoolTemplate> templates) {
+        super(services, templates);
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        Provisionr service = getService();
+        final Pool pool = createPoolOfOne(service);
+        // TODO: create service.startCachingProcess(uuid, pool) in the Provisionr class
+        return null;
+    }
+
+    @VisibleForTesting
+    Pool createPoolOfOne(Provisionr service) {
+
+        final Software software = Software.builder().packages(packages).createSoftware();
+        final Hardware hardware = Hardware.builder().type(HARDWARE_TYPE).createHardware();
+
+        final Pool pool = Pool.builder()
+            .provider(getDefaultProvider(service).get())
+            .hardware(hardware)
+            .software(software)
+            .network(buildNetwork(new ArrayList<Integer>()))
+            .adminAccess(collectCurrentUserCredentialsForAdminAccess())
+            .minSize(1)
+            .expectedSize(1)
+            .bootstrapTimeInSeconds(bootstrapTimeout)
+            .createPool();
+
+        return template != null ? applyTemplate(pool) : pool;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/org/apache/provisionr/commands/CreatePoolCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/org/apache/provisionr/commands/CreatePoolCommand.java b/karaf/commands/src/main/java/org/apache/provisionr/commands/CreatePoolCommand.java
new file mode 100644
index 0000000..2d9439e
--- /dev/null
+++ b/karaf/commands/src/main/java/org/apache/provisionr/commands/CreatePoolCommand.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.util.List;
+import java.util.Map;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.api.hardware.BlockDevice;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.templates.PoolTemplate;
+
+/**
+ * A typical call looks like this:
+ * <p/>
+ * $ provisionr:create --id amazon --key web-1 --size 5 --hardware-type m1.small \
+ * --port 80 --port 443 --package nginx --package gunicorn --package python-pip
+ */
+@Command(scope = "provisionr", name = "create", description = "Create pool of virtual machines")
+public class CreatePoolCommand extends CreateCommand {
+
+    @Option(name = "-k", aliases = "--key", description = "Unique business identifier for this pool", required = true)
+    private String key;
+
+    @Option(name = "-s", aliases = "--size", description = "Expected pool size")
+    private int size = 1;
+
+    @Option(name = "-h", aliases = "--hardware-type", description = "Virtual machine hardware type")
+    private String hardwareType = "t1.micro";
+
+    @Option(name = "--port", description = "Firewall ports that need to be open for any TCP traffic " +
+        "(multi-valued). SSH (22) is always open by default.", multiValued = true)
+    private List<Integer> ports = Lists.newArrayList();
+
+    @Option(name = "--volume", description = "Block devices that will be attached to each instance. " +
+        "(multi-valued) Expects the following format: [mapping]:[size in GB]. ", multiValued = true)
+    private List<String> blockDeviceOptions = Lists.newArrayList();
+
+    @Option(name = "-o", aliases = "--provider-options", description = "Provider-specific options (multi-valued). " +
+        "Expects either the key=value format or just plain key. If value is not specified, defaults to 'true'. " +
+        "Supported values: spotBid=x.xxx (Amazon).", multiValued = true)
+    private List<String> providerOptions = Lists.newArrayList();
+
+    @Option(name = "--image-id", description = "The id of the OS image with which the machines will be created.")
+    private String imageId = "";
+
+    @Option(name = "--cached-image", description = "If the machines will have their packages and files downloaded " +
+        "or not. If creating the machines from an existent image, software might already be installed.")
+    private boolean cachedImage = false;
+
+    public CreatePoolCommand(List<Provisionr> services, List<PoolTemplate> templates) {
+        super(services, templates);
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        checkArgument(size > 0, "size should be a positive integer");
+
+        Provisionr service = getService();
+        final Pool pool = createPoolFromArgumentsAndServiceDefaults(service);
+        final String processInstanceId = service.startPoolManagementProcess(key, pool);
+        return String.format("Pool management process started (id: %s)", processInstanceId);
+    }
+
+    Pool createPoolFromArgumentsAndServiceDefaults(Provisionr service) {
+        final Optional<Provider> defaultProvider = getDefaultProvider(service);
+
+        /* append the provider options that were passed in and rebuild the default provider */
+        // TODO: this currently does not support overriding default options, it will throw an exception
+        Map<String, String> options = ImmutableMap.<String, String>builder()
+            .putAll(defaultProvider.get().getOptions())     // default options
+            .putAll(parseProviderOptions(providerOptions))  // options added by the user
+            .build();
+        Provider provider = defaultProvider.get().toBuilder().options(options).createProvider();
+
+        final Software software = Software.builder()
+            .packages(packages)
+            .imageId(imageId)
+            .cachedImage(cachedImage)
+            .createSoftware();
+        final Hardware hardware = Hardware.builder()
+            .type(hardwareType)
+            .blockDevices(parseBlockDeviceOptions(blockDeviceOptions))
+            .createHardware();
+
+        final Pool pool = Pool.builder()
+            .provider(provider)
+            .hardware(hardware)
+            .software(software)
+            .network(buildNetwork(ports))
+            .adminAccess(collectCurrentUserCredentialsForAdminAccess())
+            .minSize(size)
+            .expectedSize(size)
+            .bootstrapTimeInSeconds(bootstrapTimeout)
+            .createPool();
+
+        return template != null ? applyTemplate(pool) : pool;
+    }
+
+    private List<BlockDevice> parseBlockDeviceOptions(List<String> options) {
+        List<BlockDevice> result = Lists.newArrayList();
+        for (String option : options) {
+            String[] parts = option.split(":");
+            checkArgument(parts.length == 2, "The arguments for the --volume option must be mapping:size");
+            result.add(BlockDevice.builder().name(parts[0]).size(Integer.parseInt(parts[1])).createBlockDevice());
+        }
+        return result;
+    }
+
+    private Map<String, String> parseProviderOptions(List<String> providerOptions) {
+        Map<String, String> result = Maps.newHashMap();
+        for (String option : providerOptions) {
+            String[] parts = option.split("=");
+            String value = parts.length > 1 ? parts[1] : "true";
+            result.put(parts[0], value);
+        }
+        return result;
+    }
+
+    @VisibleForTesting
+    void setKey(String key) {
+        this.key = checkNotNull(key, "key is null");
+    }
+
+    @VisibleForTesting
+    void setSize(int size) {
+        checkArgument(size > 0, "size should be a positive number");
+        this.size = size;
+    }
+
+    @VisibleForTesting
+    void setHardwareType(String hardwareType) {
+        this.hardwareType = checkNotNull(hardwareType, "hardwareType is null");
+    }
+
+    @VisibleForTesting
+    void setPorts(List<Integer> ports) {
+        this.ports = ImmutableList.copyOf(ports);
+    }
+
+    @VisibleForTesting
+    void setProviderOptions(List<String> providerOptions) {
+        this.providerOptions = ImmutableList.copyOf(providerOptions);
+    }
+
+    @VisibleForTesting
+    void setBlockDeviceOptions(List<String> blockDeviceOptions) {
+        this.blockDeviceOptions = ImmutableList.copyOf(blockDeviceOptions);
+    }
+
+    @VisibleForTesting
+    void setCachedImage(boolean cachedImage) {
+        this.cachedImage = cachedImage;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/org/apache/provisionr/commands/DestroyPoolCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/org/apache/provisionr/commands/DestroyPoolCommand.java b/karaf/commands/src/main/java/org/apache/provisionr/commands/DestroyPoolCommand.java
new file mode 100644
index 0000000..6d03969
--- /dev/null
+++ b/karaf/commands/src/main/java/org/apache/provisionr/commands/DestroyPoolCommand.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Iterables;
+import java.util.List;
+import java.util.NoSuchElementException;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.commands.predicates.ProvisionrPredicates;
+import org.apache.provisionr.core.CoreProcessVariables;
+
+@Command(scope = "provisionr", name = "destroy", description = "Destroy pool")
+public class DestroyPoolCommand extends OsgiCommandSupport {
+
+    @Option(name = "-k", aliases = "--key", description = "Pool key", required = true)
+    private String businessKey;
+
+    private final List<Provisionr> services;
+    private final ProcessEngine processEngine;
+
+    public DestroyPoolCommand(List<Provisionr> services, ProcessEngine processEngine) {
+        this.services = checkNotNull(services, "services is null");
+        this.processEngine = checkNotNull(processEngine, "processEngine is null");
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        checkNotNull(businessKey, "pool business key is mandatory");
+
+        ProcessInstance instance = processEngine.getRuntimeService().createProcessInstanceQuery()
+            .processInstanceBusinessKey(businessKey).singleResult();
+        checkNotNull(instance, "no pool found with key " + businessKey);
+
+        String providerId = (String) processEngine.getRuntimeService()
+            .getVariable(instance.getId(), CoreProcessVariables.PROVIDER);
+        checkNotNull(providerId, "the process instance has no provider ID");
+
+        Optional<Provisionr> service = Iterables.tryFind(services, ProvisionrPredicates.withId(providerId));
+
+        if (service.isPresent()) {
+            service.get().destroyPool(businessKey);
+        } else {
+            throw new NoSuchElementException("No provisioning service found with id: " + providerId);
+        }
+
+        return null;
+    }
+
+    @VisibleForTesting
+    void setBusinessKey(String businessKey) {
+        this.businessKey = businessKey;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/org/apache/provisionr/commands/ListPoolsCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/org/apache/provisionr/commands/ListPoolsCommand.java b/karaf/commands/src/main/java/org/apache/provisionr/commands/ListPoolsCommand.java
new file mode 100644
index 0000000..c00f787
--- /dev/null
+++ b/karaf/commands/src/main/java/org/apache/provisionr/commands/ListPoolsCommand.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import java.io.PrintStream;
+import java.util.List;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+
+@Command(scope = "provisionr", name = "pools", description = "List active pools")
+public class ListPoolsCommand extends OsgiCommandSupport {
+
+    private PrintStream out = System.out;
+
+    @Option(name = "-k", aliases = "--key", description = "Key for filtering a specific pool",
+        required = false)
+    private String key = "";
+
+    private final ProcessEngine processEngine;
+
+    public ListPoolsCommand(ProcessEngine processEngine) {
+        this.processEngine = checkNotNull(processEngine, "processEngine is null");
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        List<ProcessInstance> processes;
+        if (key.isEmpty()) {
+            processes = processEngine.getRuntimeService().createProcessInstanceQuery().list();
+        } else {
+            processes = processEngine.getRuntimeService().createProcessInstanceQuery()
+                .processInstanceBusinessKey(key).list();
+        }
+
+        if (processes.isEmpty()) {
+            out.println("No active pools found. You can create one using provisionr:create");
+            return null;
+        }
+
+        final Gson gson = new GsonBuilder().setPrettyPrinting().create();
+        for (ProcessInstance instance : processes) {
+            Pool pool = (Pool) processEngine.getRuntimeService()
+                .getVariable(instance.getId(), CoreProcessVariables.POOL);
+            if (pool == null) {
+                continue; /* skip - this process is not a provisionr process */
+            }
+
+            String businessKey = (String) processEngine.getRuntimeService()
+                .getVariable(instance.getId(), CoreProcessVariables.POOL_BUSINESS_KEY);
+            if (!Objects.equal(instance.getBusinessKey(), businessKey)) {
+                continue; /* ignore - this is a process started by the main pool management process */
+            }
+
+            @SuppressWarnings("unchecked")
+            List<Machine> machines = (List<Machine>) processEngine.getRuntimeService()
+                .getVariable(instance.getId(), CoreProcessVariables.MACHINES);
+
+            out.println("****** Pool Description ******");
+            out.println(gson.toJson(pool));
+
+            out.println("****** List of Machines ******");
+            if (machines != null) {
+                out.println(gson.toJson(machines, new TypeToken<List<Machine>>() {
+                }.getType()));
+            }
+
+            out.println("Pool Key: " + instance.getBusinessKey());
+            out.println();
+        }
+
+        return null;
+    }
+
+    @VisibleForTesting
+    void setOut(PrintStream out) {
+        this.out = checkNotNull(out, "out is null");
+    }
+
+    @VisibleForTesting
+    void setKey(String key) {
+        this.key = checkNotNull(key, "key is null");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/org/apache/provisionr/commands/ListServicesCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/org/apache/provisionr/commands/ListServicesCommand.java b/karaf/commands/src/main/java/org/apache/provisionr/commands/ListServicesCommand.java
new file mode 100644
index 0000000..ef108a9
--- /dev/null
+++ b/karaf/commands/src/main/java/org/apache/provisionr/commands/ListServicesCommand.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import org.apache.provisionr.api.Provisionr;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Lists;
+import java.io.PrintStream;
+import java.util.List;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+
+@Command(scope = "provisionr", name = "services", description = "List provisioning services")
+public class ListServicesCommand extends OsgiCommandSupport {
+
+    private PrintStream out = System.out;
+
+    private final List<Provisionr> services;
+
+    public ListServicesCommand(List<Provisionr> services) {
+        this.services = checkNotNull(services, "services is null");
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        List<String> ids = Lists.newArrayList();
+        for (Provisionr service : services) {
+            ids.add(service.getId());
+        }
+        out.printf("Services: %s%n", Joiner.on(", ").join(ids));
+        return null;
+    }
+
+    @VisibleForTesting
+    void setOut(PrintStream out) {
+        this.out = checkNotNull(out, "out is null");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/org/apache/provisionr/commands/ListTemplatesCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/org/apache/provisionr/commands/ListTemplatesCommand.java b/karaf/commands/src/main/java/org/apache/provisionr/commands/ListTemplatesCommand.java
new file mode 100644
index 0000000..9072367
--- /dev/null
+++ b/karaf/commands/src/main/java/org/apache/provisionr/commands/ListTemplatesCommand.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import org.apache.provisionr.core.templates.PoolTemplate;
+import com.google.common.annotations.VisibleForTesting;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.io.PrintStream;
+import java.util.List;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+
+/**
+ * List pre-configured templates that can be used to create clusters on different providers
+ */
+@Command(scope = "provisionr", name = "templates", description = "List of pre-configured templates")
+public class ListTemplatesCommand extends OsgiCommandSupport {
+
+    private PrintStream out = System.out;
+
+    private final List<PoolTemplate> templates;
+
+    public ListTemplatesCommand(List<PoolTemplate> templates) {
+        this.templates = checkNotNull(templates, "templates is null");
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        for (PoolTemplate template : templates) {
+            out.printf("- %s\n\t%s\n", template.getId(), template.getDescription());
+        }
+
+        return null;
+    }
+
+    @VisibleForTesting
+    void setOut(PrintStream out) {
+        this.out = checkNotNull(out, "out is null");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/org/apache/provisionr/commands/ResetRetriesCommand.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/org/apache/provisionr/commands/ResetRetriesCommand.java b/karaf/commands/src/main/java/org/apache/provisionr/commands/ResetRetriesCommand.java
new file mode 100644
index 0000000..75cdeea
--- /dev/null
+++ b/karaf/commands/src/main/java/org/apache/provisionr/commands/ResetRetriesCommand.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+
+import com.google.common.annotations.VisibleForTesting;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.io.PrintStream;
+import java.util.List;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.impl.persistence.entity.JobEntity;
+import org.activiti.engine.runtime.Job;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.provisionr.core.CoreProcessVariables;
+
+@Command(scope = "provisionr", name = "reset-retries",
+    description = "Reset to default (3) the number of retries of all jobs without retries left.")
+public class ResetRetriesCommand extends OsgiCommandSupport {
+
+    private final ProcessEngine processEngine;
+    private PrintStream out = System.out;
+
+    @Option(name = "-k", aliases = "--key", description = "Reset number of retries for jobs associated with pool", required = true)
+    private String businessKey;
+
+    public ResetRetriesCommand(ProcessEngine processEngine) {
+        this.processEngine = checkNotNull(processEngine, "processEngine is null");
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        if (businessKey == null || businessKey.isEmpty()) {
+            out.println("Please supply a business key");
+        } else {
+            // reverse the list to start the sub-processes first (they have bigger id's)
+            List<ProcessInstance> processInstanceList = processEngine.getRuntimeService()
+                .createProcessInstanceQuery().variableValueEquals(CoreProcessVariables.POOL_BUSINESS_KEY, businessKey)
+                .orderByProcessInstanceId().desc().list();
+
+            out.printf("Found %d processes with pool business key %s\n", processInstanceList.size(), businessKey);
+            int count = 0;
+            for (ProcessInstance instance : processInstanceList) {
+                List<Job> jobs = processEngine.getManagementService().createJobQuery()
+                    .processInstanceId(instance.getProcessInstanceId()).withException().list();
+                for (Job job : jobs) {
+                    count++;
+                    processEngine.getManagementService().setJobRetries(job.getId(), JobEntity.DEFAULT_RETRIES);
+                }
+            }
+            out.printf("Number of retries reset for %s jobs\n", count);
+        }
+        return null;
+    }
+
+    @VisibleForTesting
+    void setBusinessKey(String businessKey) {
+        this.businessKey = businessKey;
+    }
+
+    @VisibleForTesting
+    void setOut(PrintStream out) {
+        this.out = out;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/java/org/apache/provisionr/commands/predicates/ProvisionrPredicates.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/java/org/apache/provisionr/commands/predicates/ProvisionrPredicates.java b/karaf/commands/src/main/java/org/apache/provisionr/commands/predicates/ProvisionrPredicates.java
new file mode 100644
index 0000000..8008fd8
--- /dev/null
+++ b/karaf/commands/src/main/java/org/apache/provisionr/commands/predicates/ProvisionrPredicates.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands.predicates;
+
+import org.apache.provisionr.api.Provisionr;
+import com.google.common.base.Predicate;
+
+public class ProvisionrPredicates {
+
+    private ProvisionrPredicates() {
+    }
+
+    public static Predicate<Provisionr> withId(final String id) {
+        return new Predicate<Provisionr>() {
+
+            @Override
+            public boolean apply(Provisionr candidate) {
+                return candidate.getId().equals(id);
+            }
+
+            @Override
+            public String toString() {
+                return "WithId{id=" + id + "}";
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/main/resources/OSGI-INF/blueprint/context.xml
----------------------------------------------------------------------
diff --git a/karaf/commands/src/main/resources/OSGI-INF/blueprint/context.xml b/karaf/commands/src/main/resources/OSGI-INF/blueprint/context.xml
index b7fd209..b26cbbe 100644
--- a/karaf/commands/src/main/resources/OSGI-INF/blueprint/context.xml
+++ b/karaf/commands/src/main/resources/OSGI-INF/blueprint/context.xml
@@ -19,44 +19,44 @@
            xmlns:shell="http://karaf.apache.org/xmlns/shell/v1.0.0"
         >
 
-    <reference-list id="provisionrServices" interface="com.axemblr.provisionr.api.Provisionr"
+    <reference-list id="provisionrServices" interface="org.apache.provisionr.api.Provisionr"
                     availability="optional" activation="eager"/>
 
-    <reference-list id="templates" interface="com.axemblr.provisionr.core.templates.PoolTemplate"
+    <reference-list id="templates" interface="org.apache.provisionr.core.templates.PoolTemplate"
                     availability="optional" activation="eager"/>
 
     <reference id="processEngine" interface="org.activiti.engine.ProcessEngine"/>
 
     <shell:command-bundle>
         <shell:command name="provisionr/services">
-            <shell:action class="com.axemblr.provisionr.commands.ListServicesCommand">
+            <shell:action class="org.apache.provisionr.commands.ListServicesCommand">
                 <shell:argument ref="provisionrServices"/>
             </shell:action>
         </shell:command>
         <shell:command name="provisionr/pools">
-            <shell:action class="com.axemblr.provisionr.commands.ListPoolsCommand">
+            <shell:action class="org.apache.provisionr.commands.ListPoolsCommand">
                 <shell:argument ref="processEngine"/>
             </shell:action>
         </shell:command>
         <shell:command name="provisionr/templates">
-            <shell:action class="com.axemblr.provisionr.commands.ListTemplatesCommand">
+            <shell:action class="org.apache.provisionr.commands.ListTemplatesCommand">
                 <shell:argument ref="templates"/>
             </shell:action>
         </shell:command>
         <shell:command name="provisionr/create">
-            <shell:action class="com.axemblr.provisionr.commands.CreatePoolCommand">
+            <shell:action class="org.apache.provisionr.commands.CreatePoolCommand">
                 <shell:argument ref="provisionrServices"/>
                 <shell:argument ref="templates"/>
             </shell:action>
         </shell:command>
         <shell:command name="provisionr/destroy">
-            <shell:action class="com.axemblr.provisionr.commands.DestroyPoolCommand">
+            <shell:action class="org.apache.provisionr.commands.DestroyPoolCommand">
                 <shell:argument ref="provisionrServices"/>
                 <shell:argument ref="processEngine"/>
             </shell:action>
         </shell:command>
         <shell:command name="provisionr/reset-retries">
-            <shell:action class="com.axemblr.provisionr.commands.ResetRetriesCommand">
+            <shell:action class="org.apache.provisionr.commands.ResetRetriesCommand">
                 <shell:argument ref="processEngine"/>
             </shell:action>
         </shell:command>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/CreatePoolCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/CreatePoolCommandTest.java b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/CreatePoolCommandTest.java
deleted file mode 100644
index 7573ab7..0000000
--- a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/CreatePoolCommandTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import static org.fest.assertions.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyMapOf;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.provider.ProviderBuilder;
-import com.axemblr.provisionr.core.templates.PoolTemplate;
-import com.axemblr.provisionr.core.templates.xml.XmlTemplate;
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.io.Resources;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import org.apache.felix.service.command.CommandSession;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.ArgumentCaptor;
-
-public class CreatePoolCommandTest {
-
-    public static final String TEST_PROVISIONR_ID = "amazon";
-    public static final String TEST_BUSINESS_KEY = "j-123";
-
-    @Rule
-    public ExpectedException exception = ExpectedException.none();
-
-    @Test
-    public void testCreatePoolStartsTheManagementProcess() throws Exception {
-        final Provisionr service = newProvisionrMockWithId(TEST_PROVISIONR_ID);
-        final Pool pool = mock(Pool.class);
-
-        final List<Provisionr> services = ImmutableList.of(service);
-        final List<PoolTemplate> templates = ImmutableList.of();
-        CreatePoolCommand command = new CreatePoolCommand(services, templates) {
-            @Override
-            protected Pool createPoolFromArgumentsAndServiceDefaults(Provisionr service) {
-                return pool;
-            }
-        };
-        command.setId(TEST_PROVISIONR_ID);
-        command.setKey(TEST_BUSINESS_KEY);
-
-        CommandSession session = mock(CommandSession.class);
-        String output = (String) command.execute(session);
-
-        verify(service).startPoolManagementProcess(TEST_BUSINESS_KEY, pool);
-        assertThat(output).isEqualTo("Pool management process started (id: null)");
-    }
-
-    @Test(expected = NoSuchElementException.class)
-    public void testProvisioningServiceNotFound() throws Exception {
-        CreatePoolCommand command = new CreatePoolCommand(Collections.<Provisionr>emptyList(),
-            Collections.<PoolTemplate>emptyList());
-        command.setId("dummy");
-
-        CommandSession session = mock(CommandSession.class);
-        command.execute(session);
-    }
-
-    @Test
-    public void testCreatePoolWithTemplate() {
-        final PoolTemplate template = XmlTemplate.newXmlTemplate(readDefaultTemplate("jenkins"));
-
-        CreatePoolCommand command = newPoolCommandWithMockedAdminAccess(template);
-
-        command.setId("service");
-        command.setKey("key");
-        command.setTemplate(template.getId());
-
-        Provisionr service = mock(Provisionr.class);
-        Provider provider = newProviderMockWithBuilder();
-        when(service.getDefaultProvider()).thenReturn(Optional.of(provider));
-
-        Pool pool = command.createPoolFromArgumentsAndServiceDefaults(service);
-
-        assertThat(pool.getSoftware().getRepositories()).hasSize(1);
-        assertThat(pool.getSoftware().getPackages()).contains("jenkins").contains("git-core");
-    }
-
-    @Test
-    public void testProviderSpecificOptions() {
-        CreatePoolCommand command = newPoolCommandWithMockedAdminAccess();
-        command.setId("service");
-        command.setKey("key");
-        command.setProviderOptions(Lists.newArrayList("spotBid=0.07"));
-
-        Provisionr service = mock(Provisionr.class);
-        Provider provider = newProviderMockWithBuilder();
-        when(service.getDefaultProvider()).thenReturn(Optional.of(provider));
-
-        command.createPoolFromArgumentsAndServiceDefaults(service);
-
-        @SuppressWarnings("unchecked")
-        ArgumentCaptor<Map<String, String>> argument = (ArgumentCaptor<Map<String, String>>) (Object) 
-                ArgumentCaptor.forClass(Map.class);
-        verify(provider.toBuilder()).options(argument.capture());
-
-        assertThat(argument.getValue().containsKey("spotBid")).isTrue();
-        assertThat(argument.getValue().get("spotBid")).isEqualTo("0.07");
-    }
-
-    @Test
-    public void testBlockDeviceOptions() {
-        CreatePoolCommand command = newPoolCommandWithMockedAdminAccess();
-        command.setId("service");
-        command.setKey("key");
-
-        Provisionr service = mock(Provisionr.class);
-        Provider provider = newProviderMockWithBuilder();
-        when(service.getDefaultProvider()).thenReturn(Optional.of(provider));
-
-        Pool pool = command.createPoolFromArgumentsAndServiceDefaults(service);
-        assertThat(pool.getHardware().getBlockDevices()).isEmpty();
-
-        command.setBlockDeviceOptions(Lists.newArrayList("/dev/sda2:8", "/dev/sda9:2"));
-        pool = command.createPoolFromArgumentsAndServiceDefaults(service);
-        assertThat(pool.getHardware().getBlockDevices()).hasSize(2);
-        assertThat(pool.getHardware().getBlockDevices().get(0).getSize()).isEqualTo(8);
-        assertThat(pool.getHardware().getBlockDevices().get(0).getName()).isEqualTo("/dev/sda2");
-        assertThat(pool.getHardware().getBlockDevices().get(1).getSize()).isEqualTo(2);
-        assertThat(pool.getHardware().getBlockDevices().get(1).getName()).isEqualTo("/dev/sda9");
-
-        command.setBlockDeviceOptions(Lists.newArrayList("/dev/sda1:7"));
-        pool = command.createPoolFromArgumentsAndServiceDefaults(service);
-        assertThat(pool.getHardware().getBlockDevices()).hasSize(1);
-        assertThat(pool.getHardware().getBlockDevices().get(0).getSize()).isEqualTo(7);
-
-        command.setBlockDeviceOptions(Lists.newArrayList("this=breaks"));
-        exception.expect(IllegalArgumentException.class);
-        pool = command.createPoolFromArgumentsAndServiceDefaults(service);
-
-        command.setBlockDeviceOptions(Lists.newArrayList("/dev/sda1"));
-        exception.expect(IllegalArgumentException.class);
-        pool = command.createPoolFromArgumentsAndServiceDefaults(service);
-
-    }
-
-    private Provisionr newProvisionrMockWithId(String id) {
-        Provisionr service = mock(Provisionr.class);
-        when(service.getId()).thenReturn(id);
-        return service;
-    }
-
-    private Provider newProviderMockWithBuilder() {
-        Provider provider = mock(Provider.class);
-        ProviderBuilder providerBuilder = mock(ProviderBuilder.class);
-        when(providerBuilder.options(anyMapOf(String.class, String.class))).thenReturn(providerBuilder);
-        when(providerBuilder.createProvider()).thenReturn(provider);
-        when(provider.toBuilder()).thenReturn(providerBuilder);
-        return provider;
-    }
-
-
-    private String readDefaultTemplate(String name) {
-        try {
-            return Resources.toString(Resources.getResource(PoolTemplate.class,
-                String.format("/com/axemblr/provisionr/core/templates/%s.xml", name)), Charsets.UTF_8);
-
-        } catch (IOException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    private CreatePoolCommand newPoolCommandWithMockedAdminAccess(PoolTemplate template) {
-        List<PoolTemplate> templates = template != null ? ImmutableList.<PoolTemplate>of(template) :
-            ImmutableList.<PoolTemplate>of();
-        return new CreatePoolCommand(Collections.<Provisionr>emptyList(), templates) {
-            @Override
-            protected AdminAccess collectCurrentUserCredentialsForAdminAccess() {
-                return mock(AdminAccess.class);
-            }
-        };
-    }
-
-    private CreatePoolCommand newPoolCommandWithMockedAdminAccess() {
-        return this.newPoolCommandWithMockedAdminAccess(null);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/DestroyPoolCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/DestroyPoolCommandTest.java b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/DestroyPoolCommandTest.java
deleted file mode 100644
index 3514601..0000000
--- a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/DestroyPoolCommandTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.collect.ImmutableList;
-import java.util.NoSuchElementException;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.engine.runtime.ProcessInstanceQuery;
-import org.apache.felix.service.command.CommandSession;
-import org.junit.Test;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class DestroyPoolCommandTest {
-
-    public static final String TEST_PROVISIONR_ID = "amazon";
-
-    public static final String TEST_BUSINESS_KEY = "dummy";
-    public static final String PROCESS_INSTANCE_ID = "123";
-
-    @Test
-    public void testDestroyPool() throws Exception {
-        Provisionr service = mock(Provisionr.class);
-        when(service.getId()).thenReturn(TEST_PROVISIONR_ID);
-
-        ProcessEngine processEngine = mockProcessEngine(PROCESS_INSTANCE_ID, TEST_BUSINESS_KEY, TEST_PROVISIONR_ID);
-
-        DestroyPoolCommand command = new DestroyPoolCommand(ImmutableList.of(service), processEngine);
-        command.setBusinessKey(TEST_BUSINESS_KEY);
-
-        CommandSession session = mock(CommandSession.class);
-        command.execute(session);
-
-        verify(service).destroyPool(TEST_BUSINESS_KEY);
-    }
-
-    @Test(expected = NoSuchElementException.class)
-    public void testFailsWithAnEmptyServiceList() throws Exception {
-        ProcessEngine processEngine = mockProcessEngine(PROCESS_INSTANCE_ID, TEST_BUSINESS_KEY, TEST_PROVISIONR_ID);
-
-        DestroyPoolCommand command = new DestroyPoolCommand(ImmutableList.<Provisionr>of(), processEngine);
-
-        CommandSession session = mock(CommandSession.class);
-        command.setBusinessKey(TEST_BUSINESS_KEY);
-        command.execute(session);
-    }
-
-    public ProcessEngine mockProcessEngine(String processInstanceId, String businessKey, String providerId) {
-        ProcessInstance instance = mock(ProcessInstance.class);
-        when(instance.getId()).thenReturn(processInstanceId);
-
-        ProcessInstanceQuery query = mock(ProcessInstanceQuery.class);
-        when(query.singleResult()).thenReturn(instance);
-        when(query.processInstanceBusinessKey(eq(businessKey))).thenReturn(query);
-
-        RuntimeService runtimeService = mock(RuntimeService.class);
-        when(runtimeService.createProcessInstanceQuery()).thenReturn(query);
-        when(runtimeService.getVariable(eq(processInstanceId), eq(CoreProcessVariables.PROVIDER)))
-            .thenReturn(providerId);
-
-        ProcessEngine processEngine = mock(ProcessEngine.class);
-        when(processEngine.getRuntimeService()).thenReturn(runtimeService);
-
-        return processEngine;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListPoolsCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListPoolsCommandTest.java b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListPoolsCommandTest.java
deleted file mode 100644
index 83c989e..0000000
--- a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListPoolsCommandTest.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.collect.ImmutableList;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Collections;
-import java.util.List;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.engine.runtime.ProcessInstanceQuery;
-import org.apache.felix.service.command.CommandSession;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Matchers;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ListPoolsCommandTest {
-
-    private ByteArrayOutputStream outputStream;
-    private PrintStream out;
-
-    @Before
-    public void setUp() {
-        outputStream = new ByteArrayOutputStream();
-        out = new PrintStream(outputStream);
-    }
-
-    @After
-    public void tearDown() throws IOException {
-        out.close();
-        outputStream.close();
-    }
-
-    @Test
-    public void testNoProcessesRunning() throws Exception {
-        final ProcessEngine processEngine = newProcessEngineMock(Collections.<ProcessInstance>emptyList());
-
-        ListPoolsCommand command = new ListPoolsCommand(processEngine);
-        command.setOut(out);
-
-        CommandSession session = mock(CommandSession.class);
-        command.execute(session);
-        out.flush();
-
-        assertThat(outputStream.toString()).containsIgnoringCase("no active pools found");
-        outputStream.reset();
-
-        command.setKey("dummy");
-        command.execute(session);
-        out.flush();
-
-        assertThat(outputStream.toString()).containsIgnoringCase("no active pools found");
-    }
-
-    @Test
-    public void testListProcess() throws Exception {
-        final List<ProcessInstance> processes = ImmutableList.of(
-            newProcessInstanceMock("p1", "k1"),
-            newProcessInstanceMock("p2", "k2")
-        );
-        final ProcessEngine processEngine = newProcessEngineMock(processes);
-
-        Pool pool = mock(Pool.class);
-        setVariable(processEngine, "p1", CoreProcessVariables.POOL, pool);
-        setVariable(processEngine, "p1", CoreProcessVariables.POOL_BUSINESS_KEY, "k1");
-
-        ListPoolsCommand command = new ListPoolsCommand(processEngine);
-        command.setOut(out);
-
-        /* list all active pools */
-        CommandSession session = mock(CommandSession.class);
-        command.execute(session);
-        out.flush();
-
-        assertThat(outputStream.toString())
-            .contains("Pool Description")
-            .contains("List of Machines")
-            .contains("Pool Key: k1");
-
-        /* run the same command with a filter on business key */
-        outputStream.reset();
-        command.setKey("k2");
-        command.execute(session);
-        out.flush();
-
-        assertThat(outputStream.toString()).isEmpty();
-    }
-
-    private ProcessInstance newProcessInstanceMock(String id, String businessKey) {
-        ProcessInstance instance = mock(ProcessInstance.class);
-
-        when(instance.getId()).thenReturn(id);
-        when(instance.getBusinessKey()).thenReturn(businessKey);
-
-        return instance;
-    }
-
-    private void setVariable(ProcessEngine engine, String instanceId, String key, Object value) {
-        RuntimeService runtimeService = engine.getRuntimeService();
-
-        when(runtimeService.getVariable(instanceId, key)).thenReturn(value);
-    }
-
-    private ProcessEngine newProcessEngineMock(List<ProcessInstance> instances) {
-        ProcessEngine processEngine = mock(ProcessEngine.class);
-
-        RuntimeService runtimeService = mock(RuntimeService.class);
-        when(processEngine.getRuntimeService()).thenReturn(runtimeService);
-
-        ProcessInstanceQuery allInstancesQuery = mock(ProcessInstanceQuery.class);
-        when(allInstancesQuery.list()).thenReturn(instances);
-        when(runtimeService.createProcessInstanceQuery()).thenReturn(allInstancesQuery);
-
-        for (ProcessInstance instance : instances) {
-            ProcessInstanceQuery singleResultQuery = mock(ProcessInstanceQuery.class);
-
-            when(singleResultQuery.list()).thenReturn(ImmutableList.of(instance));
-            when(allInstancesQuery.processInstanceBusinessKey(instance.getBusinessKey()))
-                .thenReturn(singleResultQuery);
-        }
-
-        if (instances.isEmpty()) {
-            ProcessInstanceQuery emptyQuery = mock(ProcessInstanceQuery.class);
-
-            when(emptyQuery.list()).thenReturn(Collections.<ProcessInstance>emptyList());
-            when(allInstancesQuery.processInstanceBusinessKey(Matchers.<String>any()))
-                .thenReturn(emptyQuery);
-        }
-
-        return processEngine;
-    }
-
-}


[03/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/CommandSupport.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/CommandSupport.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/CommandSupport.java
new file mode 100644
index 0000000..5663372
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/CommandSupport.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.commands;
+
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.cloudstack.DefaultProviderConfig;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.Closeables;
+import java.io.PrintStream;
+import java.util.Properties;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.jclouds.Constants;
+import org.jclouds.ContextBuilder;
+import org.jclouds.cloudstack.CloudStackApiMetadata;
+import org.jclouds.cloudstack.CloudStackAsyncClient;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.rest.RestContext;
+
+
+/**
+ * Base class for CloudStack  Karaf Shell commands. It takes care of creating and cleaning a
+ * {@link org.jclouds.cloudstack.CloudStackContext} for each command.
+ */
+public abstract class CommandSupport extends OsgiCommandSupport {
+
+    private RestContext<CloudStackClient, CloudStackAsyncClient> context = null;
+    public static final String CLOUDSTACK_SCOPE = "cloudstack";
+
+    private final Provider provider;
+
+    protected CommandSupport(DefaultProviderConfig providerConfig) {
+        this.provider = providerConfig.createProvider().get();
+    }
+
+    public abstract Object doExecuteWithContext(CloudStackClient client, PrintStream out) throws Exception;
+
+    @Override
+    protected Object doExecute() throws Exception {
+        try {
+            context = newCloudStackContext(provider);
+            return doExecuteWithContext(context.getApi(), System.out);
+        } finally {
+            Closeables.closeQuietly(context);
+        }
+    }
+
+    protected RestContext<CloudStackClient, CloudStackAsyncClient> newCloudStackContext(Provider provider) {
+        Properties overrides = new Properties();
+        overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
+        return ContextBuilder.newBuilder(new CloudStackApiMetadata())
+            .endpoint(provider.getEndpoint().get())
+            .modules(ImmutableSet.of(new SLF4JLoggingModule()))
+            .credentials(provider.getAccessKey(), provider.getSecretKey())
+            .overrides(overrides)
+            .build(CloudStackApiMetadata.CONTEXT_TOKEN);
+    }
+
+    public Provider getProvider() {
+        return provider;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/OfferingsCommand.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/OfferingsCommand.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/OfferingsCommand.java
new file mode 100644
index 0000000..de2063e
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/OfferingsCommand.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.commands;
+
+import org.apache.provisionr.cloudstack.DefaultProviderConfig;
+import java.io.PrintStream;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.DiskOffering;
+import org.jclouds.cloudstack.domain.NetworkOffering;
+import org.jclouds.cloudstack.domain.ServiceOffering;
+
+@Command(scope = CommandSupport.CLOUDSTACK_SCOPE, name = OfferingsCommand.NAME,
+    description = "Commands to list CloudStack Service Offerings")
+public class OfferingsCommand extends CommandSupport {
+
+    public static final String NAME = "offerings";
+
+    @Option(name = "-s", aliases = "--service", description = "List service offerings")
+    private boolean serviceOffering;
+
+    @Option(name = "-n", aliases = "--network", description = "List network offerings")
+    private boolean networkOffering;
+
+    @Option(name = "-d", aliases = "--disk", description = "List disk offerings")
+    private boolean diskOffering;
+
+    public OfferingsCommand(DefaultProviderConfig providerConfig) {
+        super(providerConfig);
+    }
+
+    @Override
+    public Object doExecuteWithContext(CloudStackClient client, PrintStream out) throws Exception {
+        if (isDiskOfferingListed() || isServiceOfferingListed() || isNetworkOfferingListed()) {
+            out.printf("CloudStack Offerings for provider %s\n", getProvider().getId());
+            listServiceOfferingsIfSpecified(client, out);
+            listNetworkOfferingsIfSpecified(client, out);
+            listDiskOfferingsIfSpecified(client, out);
+        } else {
+            out.printf("No option specified. See --help for details.");
+        }
+        return null;
+    }
+
+    private void listDiskOfferingsIfSpecified(CloudStackClient client, PrintStream out) {
+        if (isDiskOfferingListed()) {
+            for (DiskOffering offering : client.getOfferingClient().listDiskOfferings()) {
+                out.printf("---\n%s\n", offering.toString());
+            }
+        }
+    }
+
+    private void listNetworkOfferingsIfSpecified(CloudStackClient client, PrintStream out) {
+        if (isNetworkOfferingListed()) {
+            for (NetworkOffering offering : client.getOfferingClient().listNetworkOfferings()) {
+                out.printf("---\n%s\n", offering.toString());
+            }
+        }
+    }
+
+    private void listServiceOfferingsIfSpecified(CloudStackClient client, PrintStream out) {
+        if (isServiceOfferingListed()) {
+            for (ServiceOffering offering : client.getOfferingClient().listServiceOfferings()) {
+                out.printf("---\n%s\n", offering.toString());
+            }
+        }
+    }
+
+    public boolean isDiskOfferingListed() {
+        return diskOffering;
+    }
+
+    public void setDiskOffering(boolean diskOffering) {
+        this.diskOffering = diskOffering;
+    }
+
+    public boolean isNetworkOfferingListed() {
+        return networkOffering;
+    }
+
+    public void setNetworkOffering(boolean networkOffering) {
+        this.networkOffering = networkOffering;
+    }
+
+    public boolean isServiceOfferingListed() {
+        return serviceOffering;
+    }
+
+    public void setServiceOffering(boolean serviceOffering) {
+        this.serviceOffering = serviceOffering;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/TemplatesCommand.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/TemplatesCommand.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/TemplatesCommand.java
new file mode 100644
index 0000000..54f3d7b
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/TemplatesCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.commands;
+
+import org.apache.provisionr.cloudstack.DefaultProviderConfig;
+import java.io.PrintStream;
+import org.apache.felix.gogo.commands.Command;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.Template;
+
+@Command(scope = CommandSupport.CLOUDSTACK_SCOPE, name = TemplatesCommand.NAME,
+    description = "Commands to list CloudStack templates")
+public class TemplatesCommand extends CommandSupport {
+
+    public static final String NAME = "templates";
+
+    public TemplatesCommand(DefaultProviderConfig providerConfig) {
+        super(providerConfig);
+    }
+
+    @Override
+    public Object doExecuteWithContext(CloudStackClient client, PrintStream out) throws Exception {
+        out.printf("CloudStack templates for provider %s\n", getProvider().getId());
+
+        for (Template template : client.getTemplateClient().listTemplates()) {
+            out.printf("---\n%s\n", template.toString());
+        }
+        out.println();
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/ZonesCommand.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/ZonesCommand.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/ZonesCommand.java
new file mode 100644
index 0000000..4ca5429
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/commands/ZonesCommand.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.commands;
+
+import org.apache.provisionr.cloudstack.DefaultProviderConfig;
+import java.io.PrintStream;
+import org.apache.felix.gogo.commands.Command;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.Zone;
+
+@Command(scope = CommandSupport.CLOUDSTACK_SCOPE, name = ZonesCommand.NAME,
+    description = "Commands to list CloudStack Zones")
+public class ZonesCommand extends CommandSupport {
+
+    public static final String NAME = "zones";
+
+    public ZonesCommand(DefaultProviderConfig defaultProviderConfig) {
+        super(defaultProviderConfig);
+    }
+
+    @Override
+    public Object doExecuteWithContext(CloudStackClient client, PrintStream out) throws Exception {
+        out.printf("CloudStack zones for provider %s\n", getProvider().getId());
+        for (Zone zone : client.getZoneClient().listZones()) {
+            out.printf("---\n%s\n", zone.toString());
+        }
+        out.println();
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/ConvertIngressRuleToRule.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/ConvertIngressRuleToRule.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/ConvertIngressRuleToRule.java
new file mode 100644
index 0000000..3fb5d6b
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/ConvertIngressRuleToRule.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.core;
+
+import org.apache.provisionr.api.network.Protocol;
+import org.apache.provisionr.api.network.Rule;
+import com.google.common.base.Function;
+import org.jclouds.cloudstack.domain.IngressRule;
+
+public enum ConvertIngressRuleToRule implements Function<IngressRule, Rule> {
+    FUNCTION;
+
+    @Override
+    public Rule apply(IngressRule input) {
+        Rule rule;
+        if (input.getProtocol().equalsIgnoreCase("icmp")) {
+            rule = Rule.builder()
+                .anySource()
+                .protocol(Protocol.valueOf(input.getProtocol().toUpperCase()))
+                .cidr(input.getCIDR())
+                .createRule();
+        } else {
+            rule = Rule.builder()
+                .anySource()
+                .protocol(Protocol.valueOf(input.getProtocol().toUpperCase()))
+                .ports(input.getStartPort(), input.getEndPort())
+                .cidr(input.getCIDR())
+                .createRule();
+        }
+        return rule;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/KeyPairs.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/KeyPairs.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/KeyPairs.java
new file mode 100644
index 0000000..d50edac
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/KeyPairs.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.core;
+
+public class KeyPairs {
+
+    private KeyPairs() {
+        // singleton
+    }
+
+    public static String formatNameFromBusinessKey(String businessKey) {
+        return String.format("key-%s", businessKey);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/Networks.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/Networks.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/Networks.java
new file mode 100644
index 0000000..1da1012
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/Networks.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.core;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.Network;
+
+public class Networks {
+
+    private Networks() {
+    }
+
+    public static String formatNameFromBusinessKey(String processBusinessKey) {
+        return String.format("networks-%s", processBusinessKey);
+    }
+
+    /**
+     * Returns the first network with the given name.
+     *
+     * @throws NoSuchElementException   if no network is found
+     * @throws IllegalArgumentException if more networks with the same name are found
+     */
+    public static Network getByName(CloudStackClient client, final String networkName) {
+        Set<Network> networks = Sets.filter(client.getNetworkClient().listNetworks(), new Predicate<Network>() {
+            @Override
+            public boolean apply(Network input) {
+                return input.getName().equals(networkName);
+            }
+        });
+        return Iterables.getOnlyElement(networks);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/SecurityGroups.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/SecurityGroups.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/SecurityGroups.java
new file mode 100644
index 0000000..4fcbec4
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/SecurityGroups.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.core;
+
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Protocol;
+import org.apache.provisionr.api.network.Rule;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.IngressRule;
+import org.jclouds.cloudstack.domain.SecurityGroup;
+import org.jclouds.cloudstack.features.SecurityGroupClient;
+import static org.jclouds.cloudstack.options.ListSecurityGroupsOptions.Builder.named;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SecurityGroups {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SecurityGroup.class);
+    public static final int DEFAULT_ICMP_CODE = 0;
+    public static final int DEFAULT_ICMP_TYPE = 8;
+
+    private SecurityGroups() {
+    }
+
+    public static String formatNameFromBusinessKey(String processBusinessKey) {
+        return String.format("network-%s", processBusinessKey);
+    }
+
+    /**
+     * Get a SecurityGroup by name.
+     *
+     * @throws NoSuchElementException if securityGroup does not exist.
+     */
+    public static SecurityGroup getByName(CloudStackClient cloudStackClient, String securityGroup) {
+        return Iterables.getOnlyElement(cloudStackClient
+            .getSecurityGroupClient()
+            .listSecurityGroups(named(securityGroup)));
+    }
+
+    public static Set<SecurityGroup> getAll(CloudStackClient cloudStackClient) {
+        return cloudStackClient.getSecurityGroupClient().listSecurityGroups();
+    }
+
+    public static void deleteByName(CloudStackClient cloudStackClient, String securityGroupName) {
+        try {
+            SecurityGroup securityGroup = getByName(cloudStackClient, securityGroupName);
+            LOG.info("Deleting SecurityGroup {}", securityGroup.getName());
+            cloudStackClient.getSecurityGroupClient().deleteSecurityGroup(securityGroup.getId());
+        } catch (NoSuchElementException e) {
+            LOG.warn("Exception retrieving SecurityGroup (most likely it does not yet exist){}: {}", securityGroupName, e);
+        }
+    }
+
+    public static SecurityGroup createSecurityGroup(CloudStackClient cloudStackClient, String securityGroupName) {
+        SecurityGroupClient securityGroupClient = cloudStackClient.getSecurityGroupClient();
+        return securityGroupClient.createSecurityGroup(securityGroupName);
+    }
+
+    public static void deleteNetworkRules(CloudStackClient cloudStackClient, SecurityGroup securityGroup) {
+        for (IngressRule rule : securityGroup.getIngressRules()) {
+            cloudStackClient.getSecurityGroupClient().revokeIngressRule(rule.getId());
+        }
+    }
+
+    public static void applyNetworkRules(CloudStackClient cloudStackClient, SecurityGroup securityGroup, Network network) {
+        SecurityGroupClient securityGroupClient = cloudStackClient.getSecurityGroupClient();
+        for (Rule rule : network.getIngress()) {
+            if (rule.getProtocol() == Protocol.ICMP) {
+                securityGroupClient.authorizeIngressICMPToCIDRs(securityGroup.getId(), DEFAULT_ICMP_CODE,
+                    DEFAULT_ICMP_TYPE, ImmutableList.of(rule.getCidr()));
+            } else {
+                securityGroupClient.authorizeIngressPortsToCIDRs(securityGroup.getId(),
+                    rule.getProtocol().name(),
+                    rule.getPorts().lowerEndpoint(),
+                    rule.getPorts().upperEndpoint(),
+                    Lists.newArrayList(rule.getCidr()));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/VirtualMachines.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/VirtualMachines.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/VirtualMachines.java
new file mode 100644
index 0000000..aab0cbd
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/VirtualMachines.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.core;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.VirtualMachine;
+import static org.jclouds.cloudstack.domain.VirtualMachine.State.STARTING;
+import org.jclouds.cloudstack.options.ListVirtualMachinesOptions;
+import static org.jclouds.util.Preconditions2.checkNotEmpty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VirtualMachines {
+
+    private static final Logger LOG = LoggerFactory.getLogger(VirtualMachines.class);
+    public static int WAIT_TIME_OUT_IN_SECONDS = 180;
+    public static final int BETWEEN_REQUESTS_SLEEP_TIME = WAIT_TIME_OUT_IN_SECONDS / 10;
+
+    private VirtualMachines() {
+    }
+
+    public static List<String> destroyAllVirtualMachineByName(final CloudStackClient client, final String vmName) {
+        checkNotEmpty(vmName);
+
+        Set<VirtualMachine> vms = Sets.filter(client.getVirtualMachineClient()
+            .listVirtualMachines(ListVirtualMachinesOptions.Builder.name(vmName)), new Predicate<VirtualMachine>() {
+            @Override
+            public boolean apply(VirtualMachine input) {
+                return vmName.equals(input.getDisplayName());
+            }
+        });
+
+        List<String> jobIds = Lists.newArrayList();
+        LOG.info("Deleting a total of {} virtual machine instances", vms.size());
+        for (VirtualMachine vm : vms) {
+            LOG.info("Deleting instance with id {}", vm.getId());
+            jobIds.add(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId()));
+        }
+        return ImmutableList.copyOf(jobIds);
+    }
+
+    public static void waitForVMtoStart(final CloudStackClient client, final String vmName) {
+        checkNotEmpty(vmName);
+        VirtualMachine machine = getVirtualMachineByName(client, vmName);
+        String id = machine.getId();
+        long startTime = System.currentTimeMillis();
+        while (machine.getState() == STARTING) {
+            try {
+                LOG.info("Waiting for VM {} - id {} to start", machine.getName(), machine.getId());
+                TimeUnit.SECONDS.sleep(BETWEEN_REQUESTS_SLEEP_TIME);
+                machine = client.getVirtualMachineClient().getVirtualMachine(id);
+            } catch (InterruptedException e) {
+                LOG.info("Interrupted while waiting for VM's to start");
+                Throwables.propagateIfPossible(e);
+            }
+            if (timeOutExceeded(startTime)) {
+                break;
+            }
+        }
+
+        switch (machine.getState()) {
+            case RUNNING:
+                LOG.info("VM {} is running, as expected", vmName);
+                break;
+            default:
+                throw new IllegalStateException("VM " + machine + "is not in RUNNING state");
+        }
+    }
+
+    private static boolean timeOutExceeded(long startTime) {
+        return System.currentTimeMillis() - startTime > (WAIT_TIME_OUT_IN_SECONDS * 1000);
+    }
+
+    private static VirtualMachine getVirtualMachineByName(CloudStackClient client, final String vmName) {
+        Set<VirtualMachine> machines = Sets.filter(client.getVirtualMachineClient()
+            .listVirtualMachines(ListVirtualMachinesOptions.Builder.name(vmName)), new Predicate<VirtualMachine>() {
+            @Override
+            public boolean apply(VirtualMachine input) {
+                return vmName.equals(input.getDisplayName());
+            }
+        });
+        return Iterables.getOnlyElement(machines);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/Zones.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/Zones.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/Zones.java
new file mode 100644
index 0000000..566b5cb
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/core/Zones.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.core;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import java.util.Set;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.Zone;
+
+public class Zones {
+
+    private Zones() {
+    }
+
+    public static boolean hasSecurityGroupEnabled(final CloudStackClient cloudStackClient, final String zoneName) {
+        Set<Zone> ourZone = Sets.filter(cloudStackClient.getZoneClient().listZones(), new Predicate<Zone>() {
+            @Override
+            public boolean apply(Zone input) {
+                return input.getName().equals(zoneName);
+            }
+        });
+        return Iterables.getOnlyElement(ourZone).isSecurityGroupsEnabled();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/resources/OSGI-INF/blueprint/context.xml
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/resources/OSGI-INF/blueprint/context.xml b/providers/cloudstack/src/main/resources/OSGI-INF/blueprint/context.xml
index 95e63ab..099d1a2 100644
--- a/providers/cloudstack/src/main/resources/OSGI-INF/blueprint/context.xml
+++ b/providers/cloudstack/src/main/resources/OSGI-INF/blueprint/context.xml
@@ -19,7 +19,7 @@
            xmlns:shell="http://karaf.apache.org/xmlns/shell/v1.0.0"
            xmlns:cfg="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
 
-    <cfg:property-placeholder persistent-id="com.axemblr.provisionr.cloudstack"
+    <cfg:property-placeholder persistent-id="org.apache.provisionr.cloudstack"
                               placeholder-prefix="$(" placeholder-suffix=")" update-strategy="reload">
         <cfg:default-properties>
             <cfg:property name="endpoint" value=""/>
@@ -34,7 +34,7 @@
     <!-- Configure a DefaultProviderConfiguration via ConfigAdmin
         WARNING: Order of arguments is important.
     -->
-    <bean id="defaultProviderConfig" class="com.axemblr.provisionr.cloudstack.DefaultProviderConfig">
+    <bean id="defaultProviderConfig" class="org.apache.provisionr.cloudstack.DefaultProviderConfig">
         <argument value="$(endpoint)"/>
         <argument value="$(accessKey)"/>
         <argument value="$(secretKey)"/>
@@ -45,46 +45,46 @@
 
     <reference id="processEngine" interface="org.activiti.engine.ProcessEngine"/>
 
-    <bean id="cloudstackService" class="com.axemblr.provisionr.cloudstack.CloudStackProvisionr">
+    <bean id="cloudstackService" class="org.apache.provisionr.cloudstack.CloudStackProvisionr">
         <argument ref="processEngine"/>
         <argument ref="defaultProviderConfig"/>
     </bean>
 
-    <service ref="cloudstackService" interface="com.axemblr.provisionr.api.Provisionr"/>
+    <service ref="cloudstackService" interface="org.apache.provisionr.api.Provisionr"/>
 
     <bean id="cloudstack_ensureSecurityGroupExists"
-          class="com.axemblr.provisionr.cloudstack.activities.EnsureSecurityGroupExists"/>
+          class="org.apache.provisionr.cloudstack.activities.EnsureSecurityGroupExists"/>
     <service ref="cloudstack_ensureSecurityGroupExists"
              auto-export="interfaces"/>
 
     <bean id="cloudstack_deleteSecurityGroup"
-          class="com.axemblr.provisionr.cloudstack.activities.DeleteSecurityGroup"/>
+          class="org.apache.provisionr.cloudstack.activities.DeleteSecurityGroup"/>
     <service ref="cloudstack_deleteSecurityGroup" auto-export="interfaces">
     </service>
     <bean id="cloudstack_ensureKeyPairExists"
-          class="com.axemblr.provisionr.cloudstack.activities.EnsureKeyPairExists"/>
+          class="org.apache.provisionr.cloudstack.activities.EnsureKeyPairExists"/>
     <service ref="cloudstack_ensureKeyPairExists" auto-export="interfaces">
     </service>
 
     <bean id="cloudstack_deleteKeyPair"
-          class="com.axemblr.provisionr.cloudstack.activities.DeleteKeyPair"/>
+          class="org.apache.provisionr.cloudstack.activities.DeleteKeyPair"/>
     <service ref="cloudstack_deleteKeyPair" auto-export="interfaces">
     </service>
 
     <!-- CloudStack Karaf shell commands for discovery -->
     <shell:command-bundle>
         <shell:command name="cloudstack/zones">
-            <shell:action class="com.axemblr.provisionr.cloudstack.commands.ZonesCommand">
+            <shell:action class="org.apache.provisionr.cloudstack.commands.ZonesCommand">
                 <shell:argument ref="defaultProviderConfig"/>
             </shell:action>
         </shell:command>
         <shell:command name="cloudstack/templates">
-            <shell:action class="com.axemblr.provisionr.cloudstack.commands.TemplatesCommand">
+            <shell:action class="org.apache.provisionr.cloudstack.commands.TemplatesCommand">
                 <shell:argument ref="defaultProviderConfig"/>
             </shell:action>
         </shell:command>
         <shell:command name="cloudstack/offerings">
-            <shell:action class="com.axemblr.provisionr.cloudstack.commands.OfferingsCommand">
+            <shell:action class="org.apache.provisionr.cloudstack.commands.OfferingsCommand">
                 <shell:argument ref="defaultProviderConfig"/>
             </shell:action>
         </shell:command>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/resources/com.axemblr.provisionr.cloudstack.cfg
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/resources/com.axemblr.provisionr.cloudstack.cfg b/providers/cloudstack/src/main/resources/com.axemblr.provisionr.cloudstack.cfg
deleted file mode 100644
index f826bb0..0000000
--- a/providers/cloudstack/src/main/resources/com.axemblr.provisionr.cloudstack.cfg
+++ /dev/null
@@ -1,10 +0,0 @@
-
-# CloudStack provisioning service configuration
-
-endpoint = http://example.com/api
-accessKey = access
-secretKey = secret
-
-zoneId = 1
-templateId = 1
-serviceOffering = 1

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/resources/features.xml b/providers/cloudstack/src/main/resources/features.xml
index 6da9285..a45e561 100644
--- a/providers/cloudstack/src/main/resources/features.xml
+++ b/providers/cloudstack/src/main/resources/features.xml
@@ -16,23 +16,23 @@
   ~ limitations under the License.
   -->
 
-<features name="axemblr-provisionr-cloudstack-features-${project.version}"
+<features name="provisionr-cloudstack-features-${project.version}"
           xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
 
     <repository>
-        mvn:com.axemblr.provisionr/provisionr-core/${project.version}/xml/features
+        mvn:org.apache.provisionr/provisionr-core/${project.version}/xml/features
     </repository>
     <repository>
         mvn:org.jclouds.karaf/jclouds-karaf/${jclouds.karaf.version}/xml/features
     </repository>
 
-    <feature name="axemblr-provisionr-cloudstack" version="${project.version}">
+    <feature name="provisionr-cloudstack" version="${project.version}">
         <feature version="${jclouds.karaf.version}">jclouds-api-cloudstack</feature>
-        <feature version="${project.version}">axemblr-provisionr-core</feature>
-        <bundle start="true">mvn:com.axemblr.provisionr/provisionr-cloudstack/${project.version}</bundle>
+        <feature version="${project.version}">provisionr-core</feature>
+        <bundle start="true">mvn:org.apache.provisionr/provisionr-cloudstack/${project.version}</bundle>
 
-        <configfile finalname="/etc/com.axemblr.provisionr.cloudstack.cfg">
-            mvn:com.axemblr.provisionr/provisionr-cloudstack/${project.version}/cfg/defaults
+        <configfile finalname="/etc/org.apache.provisionr.cloudstack.cfg">
+            mvn:org.apache.provisionr/provisionr-cloudstack/${project.version}/cfg/defaults
         </configfile>
     </feature>
 

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/resources/org.apache.provisionr.cloudstack.cfg
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/resources/org.apache.provisionr.cloudstack.cfg b/providers/cloudstack/src/main/resources/org.apache.provisionr.cloudstack.cfg
new file mode 100644
index 0000000..f826bb0
--- /dev/null
+++ b/providers/cloudstack/src/main/resources/org.apache.provisionr.cloudstack.cfg
@@ -0,0 +1,10 @@
+
+# CloudStack provisioning service configuration
+
+endpoint = http://example.com/api
+accessKey = access
+secretKey = secret
+
+zoneId = 1
+templateId = 1
+serviceOffering = 1

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/CloudStackActivityLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/CloudStackActivityLiveTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/CloudStackActivityLiveTest.java
deleted file mode 100644
index dd3062b..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/CloudStackActivityLiveTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.cloudstack.CloudStackProvisionr;
-import com.axemblr.provisionr.cloudstack.ProviderOptions;
-import com.axemblr.provisionr.cloudstack.core.SecurityGroups;
-import com.axemblr.provisionr.test.Generics;
-import com.axemblr.provisionr.test.ProvisionrLiveTestSupport;
-import com.google.common.base.Throwables;
-import java.util.Set;
-import java.util.UUID;
-import org.jclouds.cloudstack.CloudStackAsyncClient;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.Network;
-import org.jclouds.cloudstack.domain.SecurityGroup;
-import org.jclouds.cloudstack.domain.SshKeyPair;
-import org.jclouds.cloudstack.domain.VirtualMachine;
-import org.jclouds.rest.RestContext;
-import org.junit.After;
-import org.junit.Before;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Helper base class for CloudStack Live tests.
- */
-public class CloudStackActivityLiveTest<T extends CloudStackActivity> extends ProvisionrLiveTestSupport {
-
-    public CloudStackActivityLiveTest() {
-        super(CloudStackProvisionr.ID);
-    }
-
-    private static final Logger LOG = LoggerFactory.getLogger(CloudStackActivityLiveTest.class);
-
-    protected final String BUSINESS_KEY = "j-" + UUID.randomUUID().toString();
-    /**
-     * Cloud provider credentials collected from system properties.
-     */
-    protected Provider provider;
-    /**
-     * Instance of CloudStackActivity being tested. Automatically created from the
-     * generic type class argument.
-     */
-    protected CloudStackActivity activity;
-
-    protected RestContext<CloudStackClient, CloudStackAsyncClient> context;
-
-    public CloudStackActivityLiveTest(String provisionrId) {
-        super(provisionrId);
-    }
-
-    protected T createCloudStackActivitiInstance() {
-        try {
-            return getCloudStackActivityClass().newInstance();
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    protected Class<T> getCloudStackActivityClass() {
-        return Generics.getTypeParameter(getClass(), CloudStackActivity.class);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        provider = collectProviderCredentialsFromSystemProperties()
-            .option(ProviderOptions.ZONE_ID, getProviderProperty(ProviderOptions.ZONE_ID))
-            .option(ProviderOptions.NETWORK_OFFERING_ID, getProviderProperty(ProviderOptions.NETWORK_OFFERING_ID))
-            .createProvider();
-        LOG.info("Using provider {}", provider);
-
-        activity = createCloudStackActivitiInstance();
-        context = activity.newCloudStackClient(provider);
-    }
-
-
-    @After
-    public void tearDown() throws Exception {
-        context.close();
-    }
-
-    protected void logSecurityGroupDetails() {
-        Set<SecurityGroup> securityGroups = SecurityGroups.getAll(context.getApi());
-        LOG.info("Security Group count is {}", securityGroups.size());
-        for (SecurityGroup securityGroup : securityGroups) {
-            LOG.info("\tSecurity Group {}", securityGroup.getName());
-        }
-    }
-
-    protected void logKeyPairs() {
-        Set<SshKeyPair> keys = context.getApi().getSSHKeyPairClient().listSSHKeyPairs();
-        LOG.info("Access Key count is {}", keys.size());
-        for (SshKeyPair keyPair : keys) {
-            LOG.info("\tKey {}", keyPair.getName());
-        }
-    }
-
-    protected void logVirtualMachines() {
-        Set<VirtualMachine> vms = context.getApi().getVirtualMachineClient().listVirtualMachines();
-        LOG.info("Virtual machines count is {}", vms.size());
-        for (VirtualMachine vm : vms) {
-            LOG.info("\tVirtual machine {}", vm.toString());
-        }
-    }
-
-    protected void logNetworks() {
-        Set<Network> networks = context.getApi().getNetworkClient().listNetworks();
-        LOG.info("Networks count is {}", networks.size());
-        for (Network network : networks) {
-            LOG.info("{}\n", network.toString());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/DeleteKeyPairLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/DeleteKeyPairLiveTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/DeleteKeyPairLiveTest.java
deleted file mode 100644
index ee91f5c..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/DeleteKeyPairLiveTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.core.KeyPairs;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import org.activiti.engine.delegate.DelegateExecution;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class DeleteKeyPairLiveTest extends CloudStackActivityLiveTest<DeleteKeyPair> {
-
-    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        logKeyPairs();
-        context.getApi().getSSHKeyPairClient().registerSSHKeyPair(KEYPAIR_NAME, getResourceAsString("keys/test.pub"));
-    }
-
-    @Override
-    @After
-    public void tearDown() throws Exception {
-        context.getApi().getSSHKeyPairClient().deleteSSHKeyPair(KEYPAIR_NAME);
-        logKeyPairs();
-        super.tearDown();
-    }
-
-    @Test
-    public void testDeleteKeyPair() throws Exception {
-        final AdminAccess adminAccess = AdminAccess.builder()
-            .username("admin")
-            .publicKey(getResourceAsString("keys/test.pub"))
-            .privateKey(getResourceAsString("keys/test"))
-            .createAdminAccess();
-
-        DelegateExecution execution = mock(DelegateExecution.class);
-        Pool pool = mock(Pool.class);
-
-        when(pool.getAdminAccess()).thenReturn(adminAccess);
-        when(pool.getProvider()).thenReturn(provider);
-
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-
-        activity.execute(execution);
-        assertKeyNotFound(KEYPAIR_NAME);
-        /* the second call should just do nothing */
-        activity.execute(execution);
-    }
-
-    private void assertKeyNotFound(String keyName) {
-        assertThat(context.getApi().getSSHKeyPairClient().getSSHKeyPair(keyName)).isNull();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/DeleteSecurityGroupLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/DeleteSecurityGroupLiveTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/DeleteSecurityGroupLiveTest.java
deleted file mode 100644
index 9299da7..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/DeleteSecurityGroupLiveTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.ProcessVariables;
-import com.axemblr.provisionr.cloudstack.core.SecurityGroups;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import java.util.NoSuchElementException;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.junit.After;
-import static org.junit.Assert.fail;
-import org.junit.Before;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeleteSecurityGroupLiveTest extends CloudStackActivityLiveTest<DeleteSecurityGroup> {
-
-    private final Logger LOG = LoggerFactory.getLogger(DeleteSecurityGroupLiveTest.class);
-    private final String SECURITY_GROUP_NAME = SecurityGroups.formatNameFromBusinessKey(BUSINESS_KEY);
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        logSecurityGroupDetails();
-    }
-
-    @Override
-    @After
-    public void tearDown() throws Exception {
-        logSecurityGroupDetails();
-        super.tearDown();
-    }
-
-    @Test
-    public void testDeleteSecurityGroup() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-        final Network network = Network.builder().createNetwork();
-
-        Pool pool = mock(Pool.class);
-
-        when(pool.getProvider()).thenReturn(provider);
-        when(pool.getNetwork()).thenReturn(network);
-
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-
-        SecurityGroups.createSecurityGroup(context.getApi(), SECURITY_GROUP_NAME);
-
-        activity.execute(execution);
-
-        try {
-            SecurityGroups.getByName(context.getApi(), SECURITY_GROUP_NAME);
-            fail("Does not throw Exception as it should have");
-        } catch (NoSuchElementException e) {
-            LOG.info("Exception thrown. Test passed.");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureKeyPairExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureKeyPairExistsLiveTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureKeyPairExistsLiveTest.java
deleted file mode 100644
index faee9d4..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureKeyPairExistsLiveTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.core.KeyPairs;
-import com.axemblr.provisionr.cloudstack.ProcessVariables;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import java.io.IOException;
-import org.activiti.engine.delegate.DelegateExecution;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.jclouds.cloudstack.domain.SshKeyPair;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class EnsureKeyPairExistsLiveTest extends CloudStackActivityLiveTest<EnsureKeyPairExists> {
-
-    public static final String TEST_KEY_FINGERPRINT = "15:0b:a4:43:dd:58:19:9e:84:ca:db:31:a8:6b:b6:c3";
-    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        logKeyPairs();
-    }
-
-    @Override
-    @After
-    public void tearDown() throws Exception {
-        context.getApi().getSSHKeyPairClient().deleteSSHKeyPair(KEYPAIR_NAME);
-        logKeyPairs();
-        super.tearDown();
-    }
-
-    @Test
-    public void testEnsureKeyPairExists() throws Exception {
-        final AdminAccess adminAccess = AdminAccess.builder()
-            .username("admin")
-            .publicKey(getResourceAsString("keys/test.pub"))
-            .privateKey(getResourceAsString("keys/test"))
-            .createAdminAccess();
-
-        DelegateExecution execution = mock(DelegateExecution.class);
-        Pool pool = mock(Pool.class);
-
-        when(pool.getProvider()).thenReturn(provider);
-        when(pool.getAdminAccess()).thenReturn(adminAccess);
-
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-
-        activity.execute(execution);
-        assertKeyPairWasImportedAsExpected();
-
-        /* the second call should just re-import the key */
-        activity.execute(execution);
-        assertKeyPairWasImportedAsExpected();
-    }
-
-    private void assertKeyPairWasImportedAsExpected() throws IOException {
-        SshKeyPair pair = context.getApi().getSSHKeyPairClient().getSSHKeyPair(KEYPAIR_NAME);
-        assertThat(pair.getFingerprint()).isEqualTo(TEST_KEY_FINGERPRINT);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureNetworkExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureNetworkExistsLiveTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureNetworkExistsLiveTest.java
deleted file mode 100644
index b9a23bd..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureNetworkExistsLiveTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.NetworkOptions;
-import com.axemblr.provisionr.cloudstack.ProcessVariables;
-import com.axemblr.provisionr.cloudstack.core.Networks;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.axemblr.provisionr.test.ProcessVariablesCollector;
-import java.util.NoSuchElementException;
-import org.activiti.engine.delegate.DelegateExecution;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.Network;
-import org.jclouds.cloudstack.features.NetworkClient;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EnsureNetworkExistsLiveTest extends CloudStackActivityLiveTest<EnsureNetworkExists> {
-
-    private final static Logger LOG = LoggerFactory.getLogger(EnsureNetworkExistsLiveTest.class);
-    private final String networkName = Networks.formatNameFromBusinessKey(BUSINESS_KEY);
-    private DelegateExecution execution;
-    private Pool pool;
-    private ProcessVariablesCollector collector;
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        logNetworks();
-        initMocks();
-    }
-
-    private void initMocks() {
-        execution = mock(DelegateExecution.class);
-        pool = mock(Pool.class);
-
-        when(pool.getProvider()).thenReturn(provider);
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-        when(pool.getNetwork()).thenReturn(com.axemblr.provisionr.api.network.Network.builder()
-            .type("provided")
-            .createNetwork());
-        collector = new ProcessVariablesCollector();
-        collector.install(execution);
-    }
-
-    @Override
-    @After
-    public void tearDown() throws Exception {
-        deleteNetworkIfExists();
-        logNetworks();
-        super.tearDown();
-    }
-
-    private void deleteNetworkIfExists() {
-        try {
-            Network network = Networks.getByName(context.getApi(), networkName);
-            // this will not wait for the network to be deleted. operation will fail if network is used.
-            context.getApi().getNetworkClient().deleteNetwork(network.getId());
-        } catch (NoSuchElementException e) {
-            LOG.info("Network {} does not exist", networkName);
-        }
-    }
-
-    @Test
-    public void testEnsureNetworkExistsByCreatingTheNetwork() throws Exception {
-        activity.execute(execution);
-
-        assertThat(collector.getVariable(ProcessVariables.NETWORK_ID)).isNotNull();
-
-        Network network = Networks.getByName(context.getApi(), networkName);
-        assertThat(network.getName()).isEqualToIgnoringCase(networkName);
-        String networkId = network.getId();
-        // second run should not create a new network
-        activity.execute(execution);
-
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-        network = Networks.getByName(context.getApi(), networkName);
-        assertThat(network.getId()).isEqualTo(networkId);
-    }
-
-    @Test
-    public void testEnsureNetworkExistsWithProvidedExistingNetwork() throws Exception {
-        final String networkId = "network-id-0123";
-        final CloudStackClient mockClient = mock(CloudStackClient.class);
-        final NetworkClient mockNetworkClient = mock(NetworkClient.class);
-        final Network mockNetwork = mock(Network.class);
-        final com.axemblr.provisionr.api.network.Network network = com.axemblr.provisionr.api.network.Network.builder()
-            .option(NetworkOptions.EXISTING_NETWORK_ID, networkId).createNetwork();
-
-        execution.setVariable(ProcessVariables.NETWORK_ID, networkId);
-
-        when(pool.getNetwork()).thenReturn(network);
-        when(mockClient.getNetworkClient()).thenReturn(mockNetworkClient);
-        when(mockNetworkClient.getNetwork(networkId)).thenReturn(mockNetwork);
-        when(mockNetwork.getId()).thenReturn(networkId);
-
-        activity.execute(mockClient, pool, execution);
-        assertThat(collector.getVariable(ProcessVariables.NETWORK_ID)).isEqualTo(networkId);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureSecurityGroupExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureSecurityGroupExistsLiveTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureSecurityGroupExistsLiveTest.java
deleted file mode 100644
index 6abcc16..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/EnsureSecurityGroupExistsLiveTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.core.ConvertIngressRuleToRule;
-import com.axemblr.provisionr.cloudstack.core.SecurityGroups;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import java.util.NoSuchElementException;
-import org.activiti.engine.delegate.DelegateExecution;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.jclouds.cloudstack.domain.SecurityGroup;
-import static org.jclouds.cloudstack.options.ListSecurityGroupsOptions.Builder.named;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EnsureSecurityGroupExistsLiveTest extends CloudStackActivityLiveTest<EnsureSecurityGroupExists> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EnsureSecurityGroupExistsLiveTest.class);
-
-    private final String SECURITY_GROUP_NAME = "network-" + BUSINESS_KEY;
-
-    private final ImmutableSet<Rule> ingressRules = ImmutableSet.of(
-        Rule.builder().anySource().icmp().createRule(),
-        Rule.builder().anySource().tcp().port(22).createRule(),
-        Rule.builder().anySource().udp().port(53).createRule());
-
-    private final Network network = Network.builder().ingress(ingressRules).createNetwork();
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        logSecurityGroupDetails();
-        deleteSecurityGroupIfExists();
-    }
-
-    @Override
-    @After
-    public void tearDown() throws Exception {
-        deleteSecurityGroupIfExists();
-        logSecurityGroupDetails();
-        super.tearDown();
-    }
-
-    private void deleteSecurityGroupIfExists() {
-        try {
-            SecurityGroup securityGroup = Iterables.getOnlyElement(context.getApi()
-                .getSecurityGroupClient()
-                .listSecurityGroups(named(SECURITY_GROUP_NAME)));
-
-            context.getApi().getSecurityGroupClient().deleteSecurityGroup(securityGroup.getId());
-        } catch (NoSuchElementException e) {
-            LOG.info("Security group {} was not found", SECURITY_GROUP_NAME);
-        } catch (Exception e2) {
-            LOG.error("Exception deleting security group {}", e2);
-        }
-    }
-
-    @Test
-    public void testCreateSecurityGroup() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-        Pool pool = mock(Pool.class);
-
-        when(pool.getProvider()).thenReturn(provider);
-        when(pool.getNetwork()).thenReturn(network);
-
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-
-        activity.execute(execution);
-        assertSecurityGroupExistsWithRules(SecurityGroups.getByName(
-            context.getApi(), SECURITY_GROUP_NAME), ingressRules);
-    }
-
-    @Test
-    public void testCreateSecurityGroupWithExistingSecurityGroup() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-        Pool pool = mock(Pool.class);
-
-        when(pool.getProvider()).thenReturn(provider);
-
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-
-        // create the SecurityGroup with an extra Network Rule, then call the activity
-        when(pool.getNetwork()).thenReturn(network.toBuilder().addRules(
-            Rule.builder().anySource().tcp().port(80).createRule()).createNetwork());
-
-        activity.execute(execution);
-        // call the process again with the old network rules and check the rules
-        when(pool.getNetwork()).thenReturn(network);
-
-        activity.execute(execution);
-
-        assertSecurityGroupExistsWithRules(SecurityGroups.getByName(context.getApi(),
-            SECURITY_GROUP_NAME), ingressRules);
-    }
-
-    private void assertSecurityGroupExistsWithRules(SecurityGroup securityGroup, ImmutableSet<Rule> ingressRules) {
-        assertThat(ingressRules).containsAll(Iterables.transform(securityGroup.getIngressRules(),
-            ConvertIngressRuleToRule.FUNCTION));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/RunInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/RunInstancesLiveTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/RunInstancesLiveTest.java
deleted file mode 100644
index 02e7806..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/activities/RunInstancesLiveTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.cloudstack.ProviderOptions;
-import com.axemblr.provisionr.cloudstack.core.VirtualMachines;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RunInstancesLiveTest extends CloudStackActivityLiveTest<RunInstances> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(RunInstancesLiveTest.class);
-
-    private DelegateExecution execution;
-    private Pool pool;
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        logSecurityGroupDetails();
-        logKeyPairs();
-        logVirtualMachines();
-        execution = mock(DelegateExecution.class);
-        pool = mock(Pool.class);
-
-        final AdminAccess adminAccess = AdminAccess.builder()
-            .username("admin")
-            .publicKey(getResourceAsString("keys/test.pub"))
-            .privateKey(getResourceAsString("keys/test"))
-            .createAdminAccess();
-
-        final Network network = Network.builder().addRules(
-            Rule.builder().anySource().tcp().port(22).createRule()).createNetwork();
-
-        final Hardware hardware = Hardware.builder().type(getProviderProperty("serviceOffering")).createHardware();
-        final Software software = Software.builder()
-            .imageId(getProviderProperty("templateId"))
-            .createSoftware();
-
-        Map<String, String> options = ImmutableMap.of(ProviderOptions.ZONE_ID,
-            getProviderProperty("zoneId"));
-
-        when(pool.getProvider()).thenReturn(provider);
-        when(pool.getAdminAccess()).thenReturn(adminAccess);
-        when(pool.getNetwork()).thenReturn(network);
-        when(pool.getHardware()).thenReturn(hardware);
-        when(pool.getSoftware()).thenReturn(software);
-        when(pool.getOptions()).thenReturn(options);
-
-        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
-        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
-
-        new EnsureSecurityGroupExists().execute(execution);
-        new EnsureKeyPairExists().execute(execution);
-    }
-
-    @Override
-    @After
-    public void tearDown() throws Exception {
-        new DeleteKeyPair().execute(execution);
-        new DeleteSecurityGroup().execute(execution);
-
-        logSecurityGroupDetails();
-        logKeyPairs();
-        logVirtualMachines();
-        VirtualMachines.destroyAllVirtualMachineByName(context.getApi(), BUSINESS_KEY);
-        logVirtualMachines();
-        super.tearDown();
-    }
-
-    @Test
-    @Ignore
-    public void test() throws Exception {
-        activity.execute(execution);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/CommandTestSupport.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/CommandTestSupport.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/CommandTestSupport.java
deleted file mode 100644
index 696d808..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/CommandTestSupport.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.commands;
-
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.cloudstack.DefaultProviderConfig;
-import com.google.common.base.Optional;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.junit.Before;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- * Support class for CloudStack Karaf Command tests.
- */
-public class CommandTestSupport {
-
-    protected DefaultProviderConfig defaultProviderConfig;
-    protected ByteArrayOutputStream byteArrayOutputStream;
-    protected PrintStream out;
-    protected CloudStackClient client;
-
-    @Before
-    public void setUp() throws Exception {
-        defaultProviderConfig = mock(DefaultProviderConfig.class);
-        byteArrayOutputStream = new ByteArrayOutputStream();
-        out = new PrintStream(byteArrayOutputStream);
-        client = mock(CloudStackClient.class);
-        when(defaultProviderConfig.createProvider()).thenReturn(Optional.of(mock(Provider.class)));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/OfferingsCommandTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/OfferingsCommandTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/OfferingsCommandTest.java
deleted file mode 100644
index 4f00937..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/OfferingsCommandTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.commands;
-
-import com.google.common.collect.Sets;
-import java.util.Set;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.jclouds.cloudstack.domain.DiskOffering;
-import org.jclouds.cloudstack.domain.NetworkOffering;
-import org.jclouds.cloudstack.domain.ServiceOffering;
-import org.jclouds.cloudstack.features.OfferingClient;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class OfferingsCommandTest extends CommandTestSupport {
-
-    final Set<ServiceOffering> serviceOfferings = Sets.newHashSet(ServiceOffering.builder()
-        .id("service-1")
-        .name("service-one")
-        .build());
-
-    final Set<DiskOffering> diskOfferings = Sets.newHashSet(DiskOffering.builder()
-        .id("disk-1")
-        .name("disk-one")
-        .build());
-
-    final Set<NetworkOffering> networkOfferings = Sets.newHashSet(NetworkOffering.builder()
-        .id("network-1")
-        .name("network-one")
-        .build());
-
-    @Test
-    public void testOfferingCommandWithNoOptionSpecified() throws Exception {
-        final OfferingsCommand offeringsCommand = new OfferingsCommand(defaultProviderConfig);
-        offeringsCommand.doExecuteWithContext(client, out);
-        out.close();
-        assertThat(byteArrayOutputStream.toString()).contains("No option specified");
-    }
-
-    @Test
-    public void testOfferingCommandsPrintsServiceOfferings() throws Exception {
-        final OfferingClient offeringClient = mock(OfferingClient.class);
-        when(client.getOfferingClient()).thenReturn(offeringClient);
-        when(offeringClient.listServiceOfferings()).thenReturn(serviceOfferings);
-
-        final OfferingsCommand offeringsCommand = new OfferingsCommand(defaultProviderConfig);
-        offeringsCommand.setServiceOffering(true);
-        offeringsCommand.doExecuteWithContext(client, out);
-        out.close();
-
-        assertThat(byteArrayOutputStream.toString())
-            .contains("service-1")
-            .contains("service-one")
-            .doesNotContain("No option");
-    }
-
-    @Test
-    public void testOfferingsCommandWithAllOptions() throws Exception {
-        final OfferingClient offeringClient = mock(OfferingClient.class);
-
-        when(client.getOfferingClient()).thenReturn(offeringClient);
-        when(offeringClient.listServiceOfferings()).thenReturn(serviceOfferings);
-        when(offeringClient.listDiskOfferings()).thenReturn(diskOfferings);
-        when(offeringClient.listNetworkOfferings()).thenReturn(networkOfferings);
-
-        final OfferingsCommand offeringsCommand = new OfferingsCommand(defaultProviderConfig);
-
-        offeringsCommand.setServiceOffering(true);
-        offeringsCommand.setDiskOffering(true);
-        offeringsCommand.setNetworkOffering(true);
-
-        offeringsCommand.doExecuteWithContext(client, out);
-
-        out.close();
-
-        assertThat(byteArrayOutputStream.toString())
-            .contains("service-1")
-            .contains("service-one")
-            .contains("disk-1")
-            .contains("network-1")
-            .doesNotContain("No option");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/TemplatesCommandTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/TemplatesCommandTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/TemplatesCommandTest.java
deleted file mode 100644
index 4b1e8ad..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/TemplatesCommandTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.commands;
-
-import com.google.common.collect.Sets;
-import java.util.Set;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.jclouds.cloudstack.domain.Template;
-import org.jclouds.cloudstack.features.TemplateClient;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class TemplatesCommandTest extends CommandTestSupport {
-
-    final Set<Template> templates = Sets.newHashSet(Template.builder()
-        .id("template-1")
-        .name("template-one")
-        .build());
-
-    @Test
-    public void testTemplatesCommandPrintsTheTemplates() throws Exception {
-        final TemplatesCommand templatesCommand = new TemplatesCommand(defaultProviderConfig);
-        final TemplateClient templateClient = mock(TemplateClient.class);
-
-        when(client.getTemplateClient()).thenReturn(templateClient);
-        when(templateClient.listTemplates()).thenReturn(templates);
-
-        templatesCommand.doExecuteWithContext(client, out);
-        out.close();
-        assertThat(byteArrayOutputStream.toString()).contains("template-1").contains("template-one");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/ZonesCommandTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/ZonesCommandTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/ZonesCommandTest.java
deleted file mode 100644
index 472d156..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/commands/ZonesCommandTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.commands;
-
-import com.google.common.collect.Sets;
-import java.util.Set;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.jclouds.cloudstack.domain.Zone;
-import org.jclouds.cloudstack.features.ZoneClient;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ZonesCommandTest extends CommandTestSupport {
-
-    private final Set<Zone> zones = Sets.newHashSet(Zone.builder()
-        .id("zone-1")
-        .name("zone-one")
-        .securityGroupsEnabled(false)
-        .build());
-
-    @Test
-    public void testZonesCommandPrintsZones() throws Exception {
-        final ZonesCommand zonesCommand = new ZonesCommand(defaultProviderConfig);
-        final ZoneClient zoneClient = mock(ZoneClient.class);
-        when(client.getZoneClient()).thenReturn(zoneClient);
-        when(zoneClient.listZones()).thenReturn(zones);
-
-        zonesCommand.doExecuteWithContext(client, out);
-        out.close();
-
-        final String result = byteArrayOutputStream.toString();
-
-        assertThat(result)
-            .contains("zone-1")
-            .contains("zone-one")
-            .contains("false");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/core/ConversionsTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/core/ConversionsTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/core/ConversionsTest.java
deleted file mode 100644
index d0b87e8..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/core/ConversionsTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.core;
-
-import com.axemblr.provisionr.api.network.Protocol;
-import com.axemblr.provisionr.api.network.Rule;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.jclouds.cloudstack.domain.IngressRule;
-import org.junit.Test;
-
-public class ConversionsTest {
-
-    @Test
-    public void testConvertIngressRuleToRuleICMP() throws Exception {
-        final IngressRule ingressRule = IngressRule.builder()
-            .id("rule1")
-            .protocol("icmp")
-            .ICMPCode(SecurityGroups.DEFAULT_ICMP_CODE)
-            .ICMPType(SecurityGroups.DEFAULT_ICMP_TYPE)
-            .CIDR("10.0.0.0/24")
-            .build();
-
-        Rule rule = ConvertIngressRuleToRule.FUNCTION.apply(ingressRule);
-        assertThat(rule.getProtocol()).isEqualTo(Protocol.ICMP);
-        assertThat(rule.getCidr()).isEqualTo(ingressRule.getCIDR());
-    }
-
-    @Test
-    public void testConvertSinglePortRangeIngressRuleToRule() throws Exception {
-        final IngressRule ingressRule = IngressRule.builder()
-            .id("rule1")
-            .protocol("tcp")
-            .startPort(22)
-            .endPort(22)
-            .CIDR("0.0.0.1/24")
-            .build();
-
-        Rule rule = ConvertIngressRuleToRule.FUNCTION.apply(ingressRule);
-        assertThat(rule.getProtocol()).isEqualTo(Protocol.TCP);
-        assertThat(rule.getCidr()).isEqualTo(ingressRule.getCIDR());
-        assertThat(rule.getPorts().lowerEndpoint()).isEqualTo(ingressRule.getStartPort());
-        assertThat(rule.getPorts().upperEndpoint()).isEqualTo(ingressRule.getEndPort());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/core/SecurityGroupsTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/core/SecurityGroupsTest.java b/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/core/SecurityGroupsTest.java
deleted file mode 100644
index 5c5b889..0000000
--- a/providers/cloudstack/src/test/java/com/axemblr/provisionr/cloudstack/core/SecurityGroupsTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.core;
-
-import com.axemblr.provisionr.cloudstack.core.SecurityGroups;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class SecurityGroupsTest {
-
-    @Test
-    public void testSecurityNameFromBusinessProcessKey() throws Exception {
-        assertThat(SecurityGroups.formatNameFromBusinessKey("test")).isEqualTo("network-test");
-    }
-}


[18/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/network/Rule.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/network/Rule.java b/api/src/main/java/com/axemblr/provisionr/api/network/Rule.java
deleted file mode 100644
index 2f02616..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/network/Rule.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.network;
-
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Range;
-import com.google.common.collect.Ranges;
-import java.io.Serializable;
-
-public class Rule implements Serializable {
-
-    public static final String CIDR_ALL = "0.0.0.0/0";
-    public static final Range<Integer> EMPTY_RANGE = Ranges.openClosed(-1, -1);
-
-    public static RuleBuilder builder() {
-        return new RuleBuilder();
-    }
-
-    private final String cidr;
-    private final Range<Integer> ports;
-    private final Protocol protocol;
-
-    Rule(String cidr, Range<Integer> ports, Protocol protocol) {
-        this.ports = checkNotNull(ports, "ports is null");
-        this.cidr = checkNotNull(cidr, "cidr is null");
-        this.protocol = checkNotNull(protocol, "protocol is null");
-    }
-
-    public String getCidr() {
-        return cidr;
-    }
-
-    public Range<Integer> getPorts() {
-        return ports;
-    }
-
-    public Protocol getProtocol() {
-        return protocol;
-    }
-
-    public RuleBuilder toBuilder() {
-        return builder().cidr(cidr).ports(ports).protocol(protocol);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(cidr, ports, protocol);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final Rule other = (Rule) obj;
-        return Objects.equal(this.cidr, other.cidr)
-            && Objects.equal(this.ports, other.ports)
-            && Objects.equal(this.protocol, other.protocol);
-    }
-
-    @Override
-    public String toString() {
-        return Objects.toStringHelper(this).omitNullValues()
-            .add("cidr", cidr).add("ports", ports).add("protocol", protocol).toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/network/RuleBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/network/RuleBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/network/RuleBuilder.java
deleted file mode 100644
index bc6af7e..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/network/RuleBuilder.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.network;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.BoundType;
-import com.google.common.collect.Range;
-import com.google.common.collect.Ranges;
-
-public class RuleBuilder {
-
-    private String cidr = Rule.CIDR_ALL;
-    private Range<Integer> ports = Rule.EMPTY_RANGE;
-    private Protocol protocol;
-
-    public RuleBuilder cidr(String cidr) {
-        this.cidr = checkNotNull(cidr, "cidr is null");
-        return this;
-    }
-
-    public RuleBuilder anySource() {
-        this.cidr = Rule.CIDR_ALL;
-        return this;
-    }
-
-    public RuleBuilder ports(Range<Integer> ports) {
-        checkArgument(ports.hasUpperBound(), "ports should have a closed upper bound");
-        checkArgument(ports.hasLowerBound(), "ports should have a closed lower bound ");
-
-        checkArgument(ports.lowerEndpoint() > 0, "ports should be a positive range");
-        checkArgument(ports.upperEndpoint() < 65535, "ports upper bound should less than 65535");
-
-        this.ports = checkNotNull(ports, "ports is null");
-        return this;
-    }
-
-    public RuleBuilder ports(int lowerPort, int upperPort) {
-        return ports(Ranges.closed(lowerPort, upperPort));
-    }
-
-    public RuleBuilder port(int port) {
-        return ports(Ranges.singleton(port));
-    }
-
-    public RuleBuilder protocol(Protocol protocol) {
-        this.protocol = checkNotNull(protocol, "protocol is null");
-        return this;
-    }
-
-    public RuleBuilder tcp() {
-        return protocol(Protocol.TCP);
-    }
-
-    public RuleBuilder udp() {
-        return protocol(Protocol.UDP);
-    }
-
-    public RuleBuilder icmp() {
-        return protocol(Protocol.ICMP);
-    }
-
-    public Rule createRule() {
-        return new Rule(cidr, ports, protocol);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/pool/Machine.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/pool/Machine.java b/api/src/main/java/com/axemblr/provisionr/api/pool/Machine.java
deleted file mode 100644
index 9eaee8b..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/pool/Machine.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.pool;
-
-import com.axemblr.provisionr.api.util.WithOptions;
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.Map;
-
-/**
- * Details about a running machine from a pool
- * <p/>
- * Used to connect to that machine for configuration.
- */
-public class Machine extends WithOptions {
-
-    public static MachineBuilder builder() {
-        return new MachineBuilder();
-    }
-
-    /**
-     * External, provider specific, unique ID
-     */
-    private final String externalId;
-
-    /**
-     * Public DNS reachable over the internet
-     */
-    private final String publicDnsName;
-
-    /**
-     * Public IP address reachable over the internet
-     */
-    private final String publicIp;
-
-
-    /**
-     * Private DNS name (inside the cloud provider network)
-     */
-    private final String privateDnsName;
-
-    /**
-     * Private IP address (inside the cloud provider network)
-     */
-    private final String privateIp;
-
-    /**
-     * Port number for SSH
-     */
-    private final int sshPort;
-
-    Machine(String externalId, String publicDnsName, String publicIp,
-            String privateDnsName, String privateIp, int sshPort, Map<String, String> options) {
-        super(options);
-
-        this.externalId = checkNotNull(externalId, "externalId is null");
-        this.publicDnsName = checkNotNull(publicDnsName, "publicDnsName is null");
-        this.publicIp = checkNotNull(publicIp, "publicIp is null");
-        this.privateDnsName = checkNotNull(privateDnsName, "privateDnsName is null");
-        this.privateIp = checkNotNull(privateIp, "privateIp is null");
-
-        checkArgument(sshPort > 0 && sshPort < 65535, "invalid port number for ssh");
-        this.sshPort = sshPort;
-    }
-
-    /**
-     * External provider specific unique ID
-     */
-    public String getExternalId() {
-        return externalId;
-    }
-
-    /**
-     * Public DNS reachable over the internet
-     */
-    public String getPublicDnsName() {
-        return publicDnsName;
-    }
-
-    /**
-     * Public IP address reachable over the internet
-     */
-    public String getPublicIp() {
-        return publicIp;
-    }
-
-    /**
-     * Private DNS name (inside the cloud provider network)
-     */
-    public String getPrivateDnsName() {
-        return privateDnsName;
-    }
-
-    /**
-     * Private IP address (inside the cloud provider network)
-     */
-    public String getPrivateIp() {
-        return privateIp;
-    }
-
-    /**
-     * Port number for SSH
-     */
-    public int getSshPort() {
-        return sshPort;
-    }
-
-    public MachineBuilder toBuilder() {
-        return builder().externalId(externalId).publicDnsName(publicDnsName).publicIp(publicIp)
-            .privateDnsName(privateDnsName).privateIp(privateIp).options(getOptions());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(externalId, publicDnsName, publicIp,
-            privateDnsName, privateIp, sshPort, getOptions());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        final Machine other = (Machine) obj;
-        return Objects.equal(this.externalId, other.externalId)
-            && Objects.equal(this.publicDnsName, other.publicDnsName)
-            && Objects.equal(this.publicIp, other.publicIp)
-            && Objects.equal(this.privateDnsName, other.privateDnsName)
-            && Objects.equal(this.privateIp, other.privateIp)
-            && this.sshPort == other.sshPort
-            && Objects.equal(this.getOptions(), other.getOptions());
-    }
-
-    @Override
-    public String toString() {
-        return "Machine{" +
-            "externalId='" + externalId + '\'' +
-            ", publicDnsName='" + publicDnsName + '\'' +
-            ", publicIp='" + publicIp + '\'' +
-            ", privateDnsName='" + privateDnsName + '\'' +
-            ", privateIp='" + privateIp + '\'' +
-            ", sshPort=" + sshPort +
-            ", options=" + getOptions() +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/pool/MachineBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/pool/MachineBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/pool/MachineBuilder.java
deleted file mode 100644
index 38d8191..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/pool/MachineBuilder.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.pool;
-
-import com.axemblr.provisionr.api.util.BuilderWithOptions;
-import static com.google.common.base.Preconditions.checkArgument;
-
-public class MachineBuilder extends BuilderWithOptions<MachineBuilder> {
-
-    private String externalId;
-    private String publicDnsName;
-    private String publicIp;
-    private String privateDnsName;
-    private String privateIp;
-    private int sshPort = 22;
-
-    @Override
-    protected MachineBuilder getThis() {
-        return this;
-    }
-
-    public MachineBuilder localhost() {
-        return externalId("local-1").publicDnsName("localhost").publicIp("127.0.0.1")
-            .privateDnsName("localhost").privateIp("127.0.0.1").sshPort(22);
-    }
-
-    public MachineBuilder externalId(String externalId) {
-        this.externalId = externalId;
-        return this;
-    }
-
-    public MachineBuilder publicDnsName(String publicDnsName) {
-        this.publicDnsName = publicDnsName;
-        return this;
-    }
-
-    public MachineBuilder publicIp(String publicIp) {
-        this.publicIp = publicIp;
-        return this;
-    }
-
-    public MachineBuilder privateDnsName(String privateDnsName) {
-        this.privateDnsName = privateDnsName;
-        return this;
-    }
-
-    public MachineBuilder privateIp(String privateIp) {
-        this.privateIp = privateIp;
-        return this;
-    }
-
-    public MachineBuilder sshPort(int sshPort) {
-        checkArgument(sshPort > 0 && sshPort < 65535, "invalid port number for ssh");
-        this.sshPort = sshPort;
-        return this;
-    }
-
-    public Machine createMachine() {
-        return new Machine(externalId, publicDnsName, publicIp,
-            privateDnsName, privateIp, sshPort, buildOptions());
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/pool/Pool.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/pool/Pool.java b/api/src/main/java/com/axemblr/provisionr/api/pool/Pool.java
deleted file mode 100644
index 43a0831..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/pool/Pool.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.pool;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.api.util.WithOptions;
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.Map;
-
-public class Pool extends WithOptions {
-
-    public static PoolBuilder builder() {
-        return new PoolBuilder();
-    }
-
-    private final Provider provider;
-    private final Network network;
-
-    private final AdminAccess adminAccess;
-    private final Software software;
-    private final Hardware hardware;
-
-    private final int minSize;
-    private final int expectedSize;
-
-    private final int bootstrapTimeInSeconds;
-
-    Pool(Provider provider, Network network, AdminAccess adminAccess, Software software, Hardware hardware,
-         int minSize, int expectedSize, int bootstrapTimeInSeconds,
-         Map<String, String> options
-    ) {
-        super(options);
-
-        checkArgument(minSize > 0, "minSize should be positive");
-        checkArgument(minSize <= expectedSize, "minSize should be smaller or equal to expectedSize");
-        checkArgument(bootstrapTimeInSeconds > 0, "bootstrapTimeInSeconds should be positive");
-
-        this.provider = checkNotNull(provider, "provider is null");
-        this.network = checkNotNull(network, "network is null");
-        this.adminAccess = checkNotNull(adminAccess, "adminAccess is null");
-        this.software = checkNotNull(software, "software is null");
-        this.hardware = checkNotNull(hardware, "hardware is null");
-        this.minSize = minSize;
-        this.expectedSize = expectedSize;
-        this.bootstrapTimeInSeconds = bootstrapTimeInSeconds;
-    }
-
-    public Provider getProvider() {
-        return provider;
-    }
-
-    public Network getNetwork() {
-        return network;
-    }
-
-    public AdminAccess getAdminAccess() {
-        return adminAccess;
-    }
-
-    public Software getSoftware() {
-        return software;
-    }
-
-    public Hardware getHardware() {
-        return hardware;
-    }
-
-    public int getMinSize() {
-        return minSize;
-    }
-
-    public int getExpectedSize() {
-        return expectedSize;
-    }
-
-    /**
-     * The maximum amount of time to go from 0 to minSize
-     */
-    public int getBootstrapTimeInSeconds() {
-        return bootstrapTimeInSeconds;
-    }
-
-    public PoolBuilder toBuilder() {
-        return builder().provider(provider).network(network).adminAccess(adminAccess).software(software)
-            .hardware(hardware).minSize(minSize).expectedSize(expectedSize)
-            .bootstrapTimeInSeconds(bootstrapTimeInSeconds).options(getOptions());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(provider, network, adminAccess, software, hardware,
-            minSize, expectedSize, bootstrapTimeInSeconds, getOptions());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final Pool other = (Pool) obj;
-        return Objects.equal(this.provider, other.provider) && Objects.equal(this.network, other.network)
-            && Objects.equal(this.adminAccess, other.adminAccess) && Objects.equal(this.software, other.software)
-            && Objects.equal(this.hardware, other.hardware) && Objects.equal(this.minSize, other.minSize)
-            && Objects.equal(this.expectedSize, other.expectedSize)
-            && Objects.equal(this.bootstrapTimeInSeconds, other.bootstrapTimeInSeconds)
-            && Objects.equal(this.getOptions(), other.getOptions());
-    }
-
-    @Override
-    public String toString() {
-        return "Pool{" +
-            "provider=" + provider +
-            ", network=" + network +
-            ", adminAccess=" + adminAccess +
-            ", software=" + software +
-            ", hardware=" + hardware +
-            ", minSize=" + minSize +
-            ", expectedSize=" + expectedSize +
-            ", bootstrapTimeInSeconds=" + bootstrapTimeInSeconds +
-            ", options=" + getOptions() +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/pool/PoolBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/pool/PoolBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/pool/PoolBuilder.java
deleted file mode 100644
index 3a943bf..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/pool/PoolBuilder.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.pool;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.util.BuilderWithOptions;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class PoolBuilder extends BuilderWithOptions<PoolBuilder> {
-
-    private Provider provider;
-    private Network network;
-
-    private AdminAccess adminAccess;
-    private Software software;
-    private Hardware hardware;
-
-    private int minSize = -1;
-    private int expectedSize = -1;
-
-    private int bootstrapTimeInSeconds = 15 * 60;
-
-    @Override
-    protected PoolBuilder getThis() {
-        return this;
-    }
-
-    public PoolBuilder provider(Provider provider) {
-        this.provider = checkNotNull(provider, "provider is null");
-        return this;
-    }
-
-    public PoolBuilder network(Network network) {
-        this.network = checkNotNull(network, "network is null");
-        return this;
-    }
-
-    public PoolBuilder adminAccess(AdminAccess adminAccess) {
-        this.adminAccess = checkNotNull(adminAccess, "adminAccess is null");
-        return this;
-    }
-
-    public PoolBuilder software(Software software) {
-        this.software = checkNotNull(software, "software is null");
-        return this;
-    }
-
-    public PoolBuilder hardware(Hardware hardware) {
-        this.hardware = checkNotNull(hardware, "hardware is null");
-        return this;
-    }
-
-    public PoolBuilder minSize(int minSize) {
-        checkArgument(minSize > 0, "minSize should be positive");
-        this.minSize = minSize;
-        return this;
-    }
-
-    public PoolBuilder expectedSize(int expectedSize) {
-        checkArgument(expectedSize > 0, "expectedSize should be positive");
-        this.expectedSize = expectedSize;
-        return this;
-    }
-
-    public PoolBuilder bootstrapTimeInSeconds(int bootstrapTimeInSeconds) {
-        checkArgument(bootstrapTimeInSeconds > 0, "bootstrapTimeInSeconds should be positive");
-        this.bootstrapTimeInSeconds = bootstrapTimeInSeconds;
-        return this;
-    }
-
-    public Pool createPool() {
-        return new Pool(provider, network, adminAccess, software, hardware, minSize,
-            expectedSize, bootstrapTimeInSeconds, buildOptions());
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/provider/Provider.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/provider/Provider.java b/api/src/main/java/com/axemblr/provisionr/api/provider/Provider.java
deleted file mode 100644
index df93690..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/provider/Provider.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.provider;
-
-import com.axemblr.provisionr.api.util.WithOptions;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableMap;
-import java.io.Serializable;
-import java.util.Map;
-
-public class Provider extends WithOptions {
-
-    public static ProviderBuilder builder() {
-        return new ProviderBuilder();
-    }
-
-    private final String id;
-    private final Optional<String> endpoint;
-
-    private final String accessKey;
-    private final String secretKey;
-
-    Provider(String id, Optional<String> endpoint, String accessKey,
-             String secretKey, Map<String, String> options) {
-        super(options);
-        this.id = checkNotNull(id, "id is null");
-        this.endpoint = checkNotNull(endpoint, "endpoint is null");
-        this.accessKey = checkNotNull(accessKey, "accessKey is null");
-        this.secretKey = checkNotNull(secretKey, "secretKey is null");
-    }
-
-    /**
-     * Unique provider ID
-     */
-    public String getId() {
-        return id;
-    }
-
-    /**
-     * API endpoint for this provider
-     */
-    public Optional<String> getEndpoint() {
-        return endpoint;
-    }
-
-    /**
-     * API access key
-     */
-    public String getAccessKey() {
-        return accessKey;
-    }
-
-    /**
-     * API secret key
-     */
-    public String getSecretKey() {
-        return secretKey;
-    }
-
-    public ProviderBuilder toBuilder() {
-        return builder().id(id).endpoint(endpoint).accessKey(accessKey)
-            .secretKey(secretKey).options(getOptions());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(id, endpoint, accessKey, secretKey, getOptions());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final Provider other = (Provider) obj;
-        return Objects.equal(this.id, other.id)
-            && Objects.equal(this.endpoint, other.endpoint)
-            && Objects.equal(this.accessKey, other.accessKey)
-            && Objects.equal(this.secretKey, other.secretKey)
-            && Objects.equal(this.getOptions(), other.getOptions());
-    }
-
-    @Override
-    public String toString() {
-        return "Provider{" +
-            "id='" + id + '\'' +
-            ", endpoint='" + endpoint.or("") + '\'' +
-            ", accessKey='" + accessKey + '\'' +
-            ", options='" + getOptions() + '\'' +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/provider/ProviderBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/provider/ProviderBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/provider/ProviderBuilder.java
deleted file mode 100644
index b372ff4..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/provider/ProviderBuilder.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.provider;
-
-import com.axemblr.provisionr.api.util.BuilderWithOptions;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class ProviderBuilder extends BuilderWithOptions<ProviderBuilder> {
-
-    private String id;
-    private Optional<String> endpoint = Optional.absent();
-    private String accessKey;
-    private String secretKey;
-
-    @Override
-    protected ProviderBuilder getThis() {
-        return this;
-    }
-
-    public ProviderBuilder id(String id) {
-        this.id = checkNotNull(id, "id is null");
-        return this;
-    }
-
-    public ProviderBuilder endpoint(Optional<String> endpoint) {
-        this.endpoint = checkNotNull(endpoint, "endpoint is null");
-        return this;
-    }
-
-    public ProviderBuilder endpoint(String endpoint) {
-        this.endpoint = Optional.of(endpoint);
-        return this;
-    }
-
-    public ProviderBuilder accessKey(String accessKey) {
-        this.accessKey = checkNotNull(accessKey, "accessKey is null");
-        return this;
-    }
-
-    public ProviderBuilder secretKey(String secretKey) {
-        this.secretKey = checkNotNull(secretKey, "secretKey is null");
-        return this;
-    }
-
-    public Provider createProvider() {
-        return new Provider(id, endpoint, accessKey, secretKey, buildOptions());
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/software/Repository.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/software/Repository.java b/api/src/main/java/com/axemblr/provisionr/api/software/Repository.java
deleted file mode 100644
index 1ae1a01..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/software/Repository.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.software;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableList;
-import java.io.Serializable;
-import java.util.List;
-
-public class Repository implements Serializable {
-
-    public static RepositoryBuilder builder() {
-        return new RepositoryBuilder();
-    }
-
-    private final String name;
-    private final List<String> entries;
-
-    private final Optional<String> key;
-
-    Repository(String name, List<String> entries, Optional<String> key) {
-        this.name = checkNotNull(name, "name is null");
-        this.entries = ImmutableList.copyOf(entries);
-        this.key = checkNotNull(key, "key is null");
-    }
-
-    /**
-     * The name of the repository
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * List of entries (text lines) used to describe this repository
-     */
-    public List<String> getEntries() {
-        return entries;
-    }
-
-    /**
-     * PGP key used for package signing. This should be the actual key
-     * and not a link to an external resource
-     */
-    public Optional<String> getKey() {
-        return key;
-    }
-
-    public RepositoryBuilder toBuilder() {
-        return builder().name(name).entries(entries).key(key);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(name, entries, key);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        final Repository other = (Repository) obj;
-        return Objects.equal(this.name, other.name) && Objects.equal(this.entries, other.entries)
-            && Objects.equal(this.key, other.key);
-    }
-
-    @Override
-    public String toString() {
-        return "Repository{" +
-            "name='" + name + '\'' +
-            ", entries=" + entries +
-            ", key='" + key + '\'' +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/software/RepositoryBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/software/RepositoryBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/software/RepositoryBuilder.java
deleted file mode 100644
index cdd2ab8..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/software/RepositoryBuilder.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.software;
-
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableList;
-import java.util.List;
-
-public class RepositoryBuilder {
-
-    private String name;
-    private ImmutableList.Builder<String> entries = ImmutableList.builder();
-
-    private Optional<String> key = Optional.absent();
-
-    public RepositoryBuilder name(String name) {
-        this.name = checkNotNull(name, "name is null");
-        return this;
-    }
-
-    public RepositoryBuilder entries(List<String> entries) {
-        this.entries = ImmutableList.<String>builder().addAll(entries);
-        return this;
-    }
-
-    public RepositoryBuilder addEntry(String entry) {
-        this.entries.add(entry);
-        return this;
-    }
-
-    public RepositoryBuilder key(Optional<String> key) {
-        this.key = checkNotNull(key, "key is null");
-        return this;
-    }
-
-    public RepositoryBuilder key(String key) {
-        this.key = Optional.of(key);
-        return this;
-    }
-
-    public Repository createRepository() {
-        return new Repository(name, entries.build(), key);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/software/Software.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/software/Software.java b/api/src/main/java/com/axemblr/provisionr/api/software/Software.java
deleted file mode 100644
index 93a15da..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/software/Software.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.software;
-
-import com.axemblr.provisionr.api.util.WithOptions;
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Define the software environment for all the machines in the pool
- */
-public class Software extends WithOptions {
-
-    public static SoftwareBuilder builder() {
-        return new SoftwareBuilder();
-    }
-
-    private final String imageId;
-    private final boolean cachedImage;
-
-    private final Map<String, String> files;
-    private final List<String> packages;
-    private final List<Repository> repositories;
-
-    Software(String imageId, boolean cachedImage, Map<String, String> files, List<String> packages,
-             List<Repository> repositories, Map<String, String> options) {
-        super(options);
-        this.imageId = checkNotNull(imageId, "The supplied imageId was null");
-        this.cachedImage = cachedImage;
-        this.files = ImmutableMap.copyOf(files);
-        this.packages = ImmutableList.copyOf(packages);
-        this.repositories = ImmutableList.copyOf(repositories);
-    }
-
-    public String getImageId() {
-        return imageId;
-    }
-
-    public boolean isCachedImage() {
-        return cachedImage;
-    }
-
-    /**
-     * Map of remote files that need to be available on the local filesystem
-     */
-    public Map<String, String> getFiles() {
-        return files;
-    }
-
-    /**
-     * List of packages that should be installed
-     * <p/>
-     * This list can also include paths to local files
-     */
-    public List<String> getPackages() {
-        return packages;
-    }
-
-    /**
-     * List of custom repositories to add to the system before
-     * installing any packages
-     */
-    public List<Repository> getRepositories() {
-        return repositories;
-    }
-
-    public SoftwareBuilder toBuilder() {
-        return builder().imageId(imageId).files(files)
-            .packages(packages).repositories(repositories).options(getOptions());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(imageId, cachedImage, files, packages, repositories, getOptions());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-
-        final Software other = (Software) obj;
-        return Objects.equal(this.imageId, other.imageId)
-            && Objects.equal(this.cachedImage, other.cachedImage)
-            && Objects.equal(this.files, other.files)
-            && Objects.equal(this.packages, other.packages)
-            && Objects.equal(this.repositories, other.repositories)
-            && Objects.equal(this.getOptions(), other.getOptions());
-    }
-
-    @Override
-    public String toString() {
-        return "Software{" +
-            "imageId='" + imageId + '\'' +
-            ", cachedImage=" + cachedImage +
-            ", files=" + files +
-            ", packages=" + packages +
-            ", repositories=" + repositories +
-            ", options=" + getOptions() +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/software/SoftwareBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/software/SoftwareBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/software/SoftwareBuilder.java
deleted file mode 100644
index 358f273..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/software/SoftwareBuilder.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.software;
-
-import com.axemblr.provisionr.api.util.BuilderWithOptions;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import java.util.Map;
-
-public class SoftwareBuilder extends BuilderWithOptions<SoftwareBuilder> {
-
-    private String imageId = "default";
-    private boolean cachedImage = false;
-
-    private ImmutableMap.Builder<String, String> files = ImmutableMap.builder();
-    private ImmutableList.Builder<String> packages = ImmutableList.builder();
-    private ImmutableList.Builder<Repository> repositories = ImmutableList.builder();
-
-    @Override
-    protected SoftwareBuilder getThis() {
-        return this;
-    }
-
-    public SoftwareBuilder imageId(String imageId) {
-        this.imageId = checkNotNull(imageId, "The imageId was null");
-        return this;
-    }
-
-    public SoftwareBuilder cachedImage(boolean cachedImage) {
-        this.cachedImage = cachedImage;
-        return this;
-    }
-
-    public SoftwareBuilder files(Map<String, String> files) {
-        this.files = ImmutableMap.<String, String>builder().putAll(files);
-        return this;
-    }
-
-    public SoftwareBuilder file(String sourceUrl, String destinationPath) {
-        this.files.put(sourceUrl, destinationPath);
-        return this;
-    }
-
-    public SoftwareBuilder packages(Iterable<String> packages) {
-        this.packages = ImmutableList.<String>builder().addAll(packages);
-        return this;
-    }
-
-    public SoftwareBuilder packages(String... packages) {
-        this.packages = ImmutableList.<String>builder().addAll(Lists.newArrayList(packages));
-        return this;
-    }
-
-    public SoftwareBuilder addPackage(String pkg) {
-        this.packages.add(pkg);
-        return this;
-    }
-
-    public SoftwareBuilder repositories(Iterable<Repository> repositories) {
-        this.repositories = ImmutableList.<Repository>builder().addAll(repositories);
-        return this;
-    }
-
-    public SoftwareBuilder repository(Repository repository) {
-        this.repositories.add(repository);
-        return this;
-    }
-
-    public Software createSoftware() {
-        return new Software(imageId, cachedImage, files.build(), packages.build(),
-            repositories.build(), buildOptions());
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/util/BuilderWithOptions.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/util/BuilderWithOptions.java b/api/src/main/java/com/axemblr/provisionr/api/util/BuilderWithOptions.java
deleted file mode 100644
index ff7e965..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/util/BuilderWithOptions.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.util;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.io.Closeables;
-import com.google.common.io.Resources;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Base class useful for creating builders for objects that accept
- * an arbitrary map of options (key, value string pairs)
- */
-public abstract class BuilderWithOptions<P extends BuilderWithOptions<P>> {
-
-    private ImmutableMap.Builder<String, String> options = ImmutableMap.builder();
-
-    /**
-     * Override this method to return 'this' to allow builder method chaining
-     */
-    protected abstract P getThis();
-
-    /**
-     * Replace options with the ones supplied as argument
-     */
-    public P options(Map<String, String> options) {
-        this.options = ImmutableMap.<String, String>builder().putAll(options);
-        return getThis();
-    }
-
-    /**
-     * Replace options with the ones extracted from the Properties object
-     */
-    public P options(Properties properties) {
-        this.options = ImmutableMap.builder();
-        for (String key : properties.stringPropertyNames()) {
-            options.put(key, properties.getProperty(key));
-        }
-        return getThis();
-    }
-
-    /**
-     * Load options from a properties file available as a resource on the classpath
-     */
-    public P optionsFromResource(String resource) {
-        Properties properties = new Properties();
-        ByteArrayInputStream in = null;
-        try {
-            in = new ByteArrayInputStream(Resources.toByteArray(Resources.getResource(resource)));
-            properties.load(in);
-            return options(properties);
-
-        } catch (IOException e) {
-            throw Throwables.propagate(e);
-        } finally {
-            Closeables.closeQuietly(in);
-        }
-    }
-
-    /**
-     * Add a new option
-     */
-    public P option(String key, String value) {
-        this.options.put(key, value);
-        return getThis();
-    }
-
-    protected Map<String, String> buildOptions() {
-        return options.build();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/util/WithOptions.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/util/WithOptions.java b/api/src/main/java/com/axemblr/provisionr/api/util/WithOptions.java
deleted file mode 100644
index 0ae9321..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/util/WithOptions.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.util;
-
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableMap;
-import java.io.Serializable;
-import java.util.Map;
-
-public abstract class WithOptions implements Serializable {
-
-    private final Map<String, String> options;
-
-    public WithOptions(Map<String, String> options) {
-        this.options = ImmutableMap.copyOf(options);
-    }
-
-    public Map<String, String> getOptions() {
-        return options;
-    }
-
-    public String getOption(String key) {
-        return options.get(checkNotNull(key, "key is null"));
-    }
-
-    public String getOptionOr(String key, String value) {
-        return Optional.fromNullable(getOption(key)).or(value);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/Provisionr.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/Provisionr.java b/api/src/main/java/org/apache/provisionr/api/Provisionr.java
new file mode 100644
index 0000000..0eabb57
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/Provisionr.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api;
+
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import com.google.common.base.Optional;
+import java.util.List;
+
+public interface Provisionr {
+
+    /**
+     * Get unique ID for this provisionr
+     */
+    public String getId();
+
+
+    /**
+     * Return the default provider configured for this bundle using the
+     * Blueprint configuration mechanism or something else
+     *
+     * @see Provider
+     */
+    public Optional<Provider> getDefaultProvider();
+
+    /**
+     * Start a provisioning process based on the pool description
+     * <p/>
+     * This process will run until the pool is destroyed
+     *
+     * @param businessKey external process ID (e.g. job ID, business key)
+     * @param pool        pool description
+     * @return internal process ID
+     */
+    String startPoolManagementProcess(String businessKey, Pool pool);
+
+
+    /**
+     * Retrieve the list of machines for a pool or an empty list
+     *
+     * @param businessKey external pool ID (e.g. job ID)
+     * @return list of running machines or empty
+     */
+    List<Machine> getMachines(String businessKey);
+
+    /**
+     * Get current pool status
+     *
+     * @param businessKey external process ID (e.g. job ID)
+     * @return internal status information
+     */
+    String getStatus(String businessKey);
+
+    /**
+     * Destroy all the machines from the pool with that id
+     *
+     * @param businessKey external pool ID (e.g. job ID, business key)
+     */
+    void destroyPool(String businessKey);
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/access/AdminAccess.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/access/AdminAccess.java b/api/src/main/java/org/apache/provisionr/api/access/AdminAccess.java
new file mode 100644
index 0000000..4f1dc54
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/access/AdminAccess.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.access;
+
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.io.Serializable;
+
+/**
+ * Describe the only user allowed to access machine from the pool over SSH
+ * <p/>
+ * This user will support only key-based SSH authentication have
+ * password-less sudo access
+ */
+public class AdminAccess implements Serializable {
+
+    public static AdminAccessBuilder builder() {
+        return new AdminAccessBuilder();
+    }
+
+    private final String username;
+    private final String publicKey;
+    private final String privateKey;
+
+    AdminAccess(String username, String publicKey, String privateKey) {
+        this.username = checkNotNull(username, "username is null");
+        this.publicKey = checkNotNull(publicKey, "publicKey is null");
+        this.privateKey = checkNotNull(privateKey, "privateKey is null");
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPublicKey() {
+        return publicKey;
+    }
+
+    public String getPrivateKey() {
+        return privateKey;
+    }
+
+    public AdminAccessBuilder toBuilder() {
+        return builder().username(username)
+            .publicKey(publicKey).privateKey(privateKey);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(username, publicKey, privateKey);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final AdminAccess other = (AdminAccess) obj;
+        return Objects.equal(this.username, other.username)
+            && Objects.equal(this.publicKey, other.publicKey)
+            && Objects.equal(this.privateKey, other.privateKey);
+    }
+
+    @Override
+    public String toString() {
+        return "AdminAccess{" +
+            "username='" + username + '\'' +
+            ", publicKey='" + publicKey + '\'' +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/access/AdminAccessBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/access/AdminAccessBuilder.java b/api/src/main/java/org/apache/provisionr/api/access/AdminAccessBuilder.java
new file mode 100644
index 0000000..9d8fa75
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/access/AdminAccessBuilder.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.access;
+
+import com.google.common.base.Charsets;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Throwables;
+import com.google.common.io.Files;
+import java.io.File;
+
+public class AdminAccessBuilder {
+
+    private String username;
+    private String publicKey;
+    private String privateKey;
+
+    public AdminAccessBuilder username(String username) {
+        this.username = checkNotNull(username, "username is null");
+        return this;
+    }
+
+    public AdminAccessBuilder publicKey(String publicKey) {
+        checkArgument(publicKey.startsWith("ssh-rsa "), "The key does not start with ssh-rsa as expected");
+        this.publicKey = checkNotNull(publicKey, "publicKey is null");
+        return this;
+    }
+
+    public AdminAccessBuilder privateKey(String privateKey) {
+        checkArgument(privateKey.startsWith("-----BEGIN RSA PRIVATE KEY-----"),
+            "The key does not start with -----BEGIN RSA PRIVATE KEY----- as expected");
+        this.privateKey = checkNotNull(privateKey, "privateKey is null");
+        return this;
+    }
+
+    public AdminAccessBuilder asCurrentUser() {
+        String userHome = System.getProperty("user.home");
+
+        try {
+            String publicKey = Files.toString(new File(userHome, ".ssh/id_rsa.pub"), Charsets.UTF_8);
+            String privateKey = Files.toString(new File(userHome, ".ssh/id_rsa"), Charsets.UTF_8);
+
+            return username(System.getProperty("user.name")).publicKey(publicKey).privateKey(privateKey);
+
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    public AdminAccess createAdminAccess() {
+        return new AdminAccess(username, publicKey, privateKey);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/hardware/BlockDevice.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/hardware/BlockDevice.java b/api/src/main/java/org/apache/provisionr/api/hardware/BlockDevice.java
new file mode 100644
index 0000000..c006f22
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/hardware/BlockDevice.java
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+*
+* 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.
+*/
+
+package org.apache.provisionr.api.hardware;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import org.apache.provisionr.api.util.WithOptions;
+import com.google.common.base.Objects;
+
+import java.util.Map;
+
+public class BlockDevice extends WithOptions {
+
+    private int size;
+    private String name;
+
+    public static BlockDeviceBuilder builder() {
+        return new BlockDeviceBuilder();
+    }
+
+    BlockDevice(int size, String name, Map<String, String> options) {
+        super(options);
+        checkArgument(size > 0, "the block device size should be a positive integer");
+        this.size = size;
+        this.name = name;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(size, name, getOptions());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final BlockDevice other = (BlockDevice) obj;
+        return Objects.equal(this.size, other.size)
+            && Objects.equal(this.name, this.name)
+            && Objects.equal(this.getOptions(), other.getOptions());
+    }
+
+    @Override
+    public String toString() {
+        return "BlockDevice {" +
+            "size=" + size +
+            "name=" + name +
+            ", options=" + getOptions() + "}";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/hardware/BlockDeviceBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/hardware/BlockDeviceBuilder.java b/api/src/main/java/org/apache/provisionr/api/hardware/BlockDeviceBuilder.java
new file mode 100644
index 0000000..17fb5c3
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/hardware/BlockDeviceBuilder.java
@@ -0,0 +1,33 @@
+package org.apache.provisionr.api.hardware;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.provisionr.api.util.BuilderWithOptions;
+
+public class BlockDeviceBuilder extends BuilderWithOptions<BlockDeviceBuilder> {
+
+    private Integer size;
+    private String name;
+
+    @Override
+    protected BlockDeviceBuilder getThis() {
+        return this;
+    }
+
+    public BlockDeviceBuilder size(int size) {
+        checkArgument(size > 0, "The block device size must be a positive integer");
+        this.size = size;
+        return this;
+    }
+
+    public BlockDeviceBuilder name(String mapping) {
+        this.name = checkNotNull(mapping, "The block device must have a name - the OS path on which it is mapped");
+        return this;
+    }
+
+    public BlockDevice createBlockDevice() {
+        checkNotNull(size, "The size was not specified");
+        return new BlockDevice(size, name, buildOptions());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/hardware/Hardware.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/hardware/Hardware.java b/api/src/main/java/org/apache/provisionr/api/hardware/Hardware.java
new file mode 100644
index 0000000..b6f67f3
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/hardware/Hardware.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.hardware;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.provisionr.api.util.WithOptions;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Map;
+
+public class Hardware extends WithOptions {
+
+    public static HardwareBuilder builder() {
+        return new HardwareBuilder();
+    }
+
+    private final String type;
+    private List<BlockDevice> blockDevices;
+
+    Hardware(String type, List<BlockDevice> blockDevices, Map<String, String> options) {
+        super(options);
+        this.type = checkNotNull(type, "type is null");
+        this.blockDevices = ImmutableList.copyOf(blockDevices);
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public List<BlockDevice> getBlockDevices() {
+        return blockDevices;
+    }
+
+    public HardwareBuilder toBuilder() {
+        return builder().type(type).blockDevices(blockDevices).options(getOptions());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(type, getOptions(), getBlockDevices());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final Hardware other = (Hardware) obj;
+        return Objects.equal(this.type, other.type)
+            && Objects.equal(this.getOptions(), other.getOptions())
+            && Objects.equal(this.getBlockDevices(), other.getBlockDevices());
+    }
+
+    @Override
+    public String toString() {
+        return "Hardware{" +
+            "type='" + type + '\'' +
+            ", blockDevices=" + getBlockDevices() + 
+            ", options=" + getOptions() +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/hardware/HardwareBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/hardware/HardwareBuilder.java b/api/src/main/java/org/apache/provisionr/api/hardware/HardwareBuilder.java
new file mode 100644
index 0000000..c8c2d95
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/hardware/HardwareBuilder.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.hardware;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.provisionr.api.util.BuilderWithOptions;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+public class HardwareBuilder extends BuilderWithOptions<HardwareBuilder> {
+
+    private String type = "default";
+    private List<BlockDevice> blockDevices = Lists.newArrayList();
+
+    @Override
+    protected HardwareBuilder getThis() {
+        return this;
+    }
+
+    /**
+     * This is similar to <a href="http://aws.amazon.com/ec2/instance-types/">'instance type'</a> on Amazon
+     * or <a href="http://docs.cloudstack.org/Glossary">'service offering'</a> on CloudStack
+     *
+     * @param type
+     * @return
+     */
+    public HardwareBuilder type(String type) {
+        this.type = checkNotNull(type, "type is null");
+        return this;
+    }
+
+    public HardwareBuilder blockDevices(List<BlockDevice> blockDevices) {
+        this.blockDevices = checkNotNull(blockDevices, "the list of block devices is null");
+        return this;
+    }
+
+    public Hardware createHardware() {
+        return new Hardware(type, blockDevices, buildOptions());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/network/Network.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/network/Network.java b/api/src/main/java/org/apache/provisionr/api/network/Network.java
new file mode 100644
index 0000000..1a1a262
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/network/Network.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.network;
+
+import org.apache.provisionr.api.util.WithOptions;
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableSet;
+import java.util.Map;
+import java.util.Set;
+
+public class Network extends WithOptions {
+
+    public static NetworkBuilder builder() {
+        return new NetworkBuilder();
+    }
+
+    private final String type;
+    private final Set<Rule> ingress;
+
+    Network(String type, Set<Rule> ingress, Map<String, String> options) {
+        super(options);
+        this.type = checkNotNull(type, "type is null");
+        this.ingress = ImmutableSet.copyOf(ingress);
+    }
+
+    /**
+     * Implementation specific network type information
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Set of rules for incoming packages
+     */
+    public Set<Rule> getIngress() {
+        return ingress;
+    }
+
+    public NetworkBuilder toBuilder() {
+        return builder().type(type).ingress(ingress).options(getOptions());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(type, ingress, getOptions());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final Network other = (Network) obj;
+        return Objects.equal(this.type, other.type)
+            && Objects.equal(this.ingress, other.ingress)
+            && Objects.equal(this.getOptions(), other.getOptions());
+    }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(this).omitNullValues()
+            .add("type", type).add("ingress", ingress)
+            .add("options", getOptions()).toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/network/NetworkBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/network/NetworkBuilder.java b/api/src/main/java/org/apache/provisionr/api/network/NetworkBuilder.java
new file mode 100644
index 0000000..f49e10d
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/network/NetworkBuilder.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.network;
+
+import org.apache.provisionr.api.util.BuilderWithOptions;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import java.util.Set;
+
+public class NetworkBuilder extends BuilderWithOptions<NetworkBuilder> {
+
+    private String type = "default";
+    private ImmutableSet.Builder<Rule> ingress = ImmutableSet.builder();
+
+    @Override
+    protected NetworkBuilder getThis() {
+        return this;
+    }
+
+    public NetworkBuilder type(String type) {
+        this.type = checkNotNull(type, "type is null");
+        return this;
+    }
+
+    public NetworkBuilder ingress(Set<Rule> incoming) {
+        this.ingress = ImmutableSet.<Rule>builder().addAll(incoming);
+        return this;
+    }
+
+    public NetworkBuilder addRules(Rule... rules) {
+        return addRules(Lists.newArrayList(rules));
+    }
+
+    public NetworkBuilder addRules(Iterable<Rule> rules) {
+        this.ingress.addAll(rules);
+        return this;
+    }
+
+    public Network createNetwork() {
+        return new Network(type, ingress.build(), buildOptions());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/network/Protocol.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/network/Protocol.java b/api/src/main/java/org/apache/provisionr/api/network/Protocol.java
new file mode 100644
index 0000000..403b71f
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/network/Protocol.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.network;
+
+public enum Protocol {
+    TCP,
+    UDP,
+    ICMP
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/network/Rule.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/network/Rule.java b/api/src/main/java/org/apache/provisionr/api/network/Rule.java
new file mode 100644
index 0000000..ddb12d8
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/network/Rule.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.network;
+
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Range;
+import com.google.common.collect.Ranges;
+import java.io.Serializable;
+
+public class Rule implements Serializable {
+
+    public static final String CIDR_ALL = "0.0.0.0/0";
+    public static final Range<Integer> EMPTY_RANGE = Ranges.openClosed(-1, -1);
+
+    public static RuleBuilder builder() {
+        return new RuleBuilder();
+    }
+
+    private final String cidr;
+    private final Range<Integer> ports;
+    private final Protocol protocol;
+
+    Rule(String cidr, Range<Integer> ports, Protocol protocol) {
+        this.ports = checkNotNull(ports, "ports is null");
+        this.cidr = checkNotNull(cidr, "cidr is null");
+        this.protocol = checkNotNull(protocol, "protocol is null");
+    }
+
+    public String getCidr() {
+        return cidr;
+    }
+
+    public Range<Integer> getPorts() {
+        return ports;
+    }
+
+    public Protocol getProtocol() {
+        return protocol;
+    }
+
+    public RuleBuilder toBuilder() {
+        return builder().cidr(cidr).ports(ports).protocol(protocol);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(cidr, ports, protocol);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final Rule other = (Rule) obj;
+        return Objects.equal(this.cidr, other.cidr)
+            && Objects.equal(this.ports, other.ports)
+            && Objects.equal(this.protocol, other.protocol);
+    }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(this).omitNullValues()
+            .add("cidr", cidr).add("ports", ports).add("protocol", protocol).toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/network/RuleBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/network/RuleBuilder.java b/api/src/main/java/org/apache/provisionr/api/network/RuleBuilder.java
new file mode 100644
index 0000000..e14306b
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/network/RuleBuilder.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.network;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Range;
+import com.google.common.collect.Ranges;
+
+public class RuleBuilder {
+
+    private String cidr = Rule.CIDR_ALL;
+    private Range<Integer> ports = Rule.EMPTY_RANGE;
+    private Protocol protocol;
+
+    public RuleBuilder cidr(String cidr) {
+        this.cidr = checkNotNull(cidr, "cidr is null");
+        return this;
+    }
+
+    public RuleBuilder anySource() {
+        this.cidr = Rule.CIDR_ALL;
+        return this;
+    }
+
+    public RuleBuilder ports(Range<Integer> ports) {
+        checkArgument(ports.hasUpperBound(), "ports should have a closed upper bound");
+        checkArgument(ports.hasLowerBound(), "ports should have a closed lower bound ");
+
+        checkArgument(ports.lowerEndpoint() > 0, "ports should be a positive range");
+        checkArgument(ports.upperEndpoint() < 65535, "ports upper bound should less than 65535");
+
+        this.ports = checkNotNull(ports, "ports is null");
+        return this;
+    }
+
+    public RuleBuilder ports(int lowerPort, int upperPort) {
+        return ports(Ranges.closed(lowerPort, upperPort));
+    }
+
+    public RuleBuilder port(int port) {
+        return ports(Ranges.singleton(port));
+    }
+
+    public RuleBuilder protocol(Protocol protocol) {
+        this.protocol = checkNotNull(protocol, "protocol is null");
+        return this;
+    }
+
+    public RuleBuilder tcp() {
+        return protocol(Protocol.TCP);
+    }
+
+    public RuleBuilder udp() {
+        return protocol(Protocol.UDP);
+    }
+
+    public RuleBuilder icmp() {
+        return protocol(Protocol.ICMP);
+    }
+
+    public Rule createRule() {
+        return new Rule(cidr, ports, protocol);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/org/apache/provisionr/api/pool/Machine.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/provisionr/api/pool/Machine.java b/api/src/main/java/org/apache/provisionr/api/pool/Machine.java
new file mode 100644
index 0000000..5806a7c
--- /dev/null
+++ b/api/src/main/java/org/apache/provisionr/api/pool/Machine.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.api.pool;
+
+import org.apache.provisionr.api.util.WithOptions;
+import com.google.common.base.Objects;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Map;
+
+/**
+ * Details about a running machine from a pool
+ * <p/>
+ * Used to connect to that machine for configuration.
+ */
+public class Machine extends WithOptions {
+
+    public static MachineBuilder builder() {
+        return new MachineBuilder();
+    }
+
+    /**
+     * External, provider specific, unique ID
+     */
+    private final String externalId;
+
+    /**
+     * Public DNS reachable over the internet
+     */
+    private final String publicDnsName;
+
+    /**
+     * Public IP address reachable over the internet
+     */
+    private final String publicIp;
+
+
+    /**
+     * Private DNS name (inside the cloud provider network)
+     */
+    private final String privateDnsName;
+
+    /**
+     * Private IP address (inside the cloud provider network)
+     */
+    private final String privateIp;
+
+    /**
+     * Port number for SSH
+     */
+    private final int sshPort;
+
+    Machine(String externalId, String publicDnsName, String publicIp,
+            String privateDnsName, String privateIp, int sshPort, Map<String, String> options) {
+        super(options);
+
+        this.externalId = checkNotNull(externalId, "externalId is null");
+        this.publicDnsName = checkNotNull(publicDnsName, "publicDnsName is null");
+        this.publicIp = checkNotNull(publicIp, "publicIp is null");
+        this.privateDnsName = checkNotNull(privateDnsName, "privateDnsName is null");
+        this.privateIp = checkNotNull(privateIp, "privateIp is null");
+
+        checkArgument(sshPort > 0 && sshPort < 65535, "invalid port number for ssh");
+        this.sshPort = sshPort;
+    }
+
+    /**
+     * External provider specific unique ID
+     */
+    public String getExternalId() {
+        return externalId;
+    }
+
+    /**
+     * Public DNS reachable over the internet
+     */
+    public String getPublicDnsName() {
+        return publicDnsName;
+    }
+
+    /**
+     * Public IP address reachable over the internet
+     */
+    public String getPublicIp() {
+        return publicIp;
+    }
+
+    /**
+     * Private DNS name (inside the cloud provider network)
+     */
+    public String getPrivateDnsName() {
+        return privateDnsName;
+    }
+
+    /**
+     * Private IP address (inside the cloud provider network)
+     */
+    public String getPrivateIp() {
+        return privateIp;
+    }
+
+    /**
+     * Port number for SSH
+     */
+    public int getSshPort() {
+        return sshPort;
+    }
+
+    public MachineBuilder toBuilder() {
+        return builder().externalId(externalId).publicDnsName(publicDnsName).publicIp(publicIp)
+            .privateDnsName(privateDnsName).privateIp(privateIp).options(getOptions());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(externalId, publicDnsName, publicIp,
+            privateDnsName, privateIp, sshPort, getOptions());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        final Machine other = (Machine) obj;
+        return Objects.equal(this.externalId, other.externalId)
+            && Objects.equal(this.publicDnsName, other.publicDnsName)
+            && Objects.equal(this.publicIp, other.publicIp)
+            && Objects.equal(this.privateDnsName, other.privateDnsName)
+            && Objects.equal(this.privateIp, other.privateIp)
+            && this.sshPort == other.sshPort
+            && Objects.equal(this.getOptions(), other.getOptions());
+    }
+
+    @Override
+    public String toString() {
+        return "Machine{" +
+            "externalId='" + externalId + '\'' +
+            ", publicDnsName='" + publicDnsName + '\'' +
+            ", publicIp='" + publicIp + '\'' +
+            ", privateDnsName='" + privateDnsName + '\'' +
+            ", privateIp='" + privateIp + '\'' +
+            ", sshPort=" + sshPort +
+            ", options=" + getOptions() +
+            '}';
+    }
+}


[04/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/CloudStackActivity.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/CloudStackActivity.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/CloudStackActivity.java
deleted file mode 100644
index 3e128b9..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/CloudStackActivity.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.io.Closeables;
-import com.google.inject.Module;
-import java.util.Properties;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.jclouds.Constants;
-import org.jclouds.ContextBuilder;
-import org.jclouds.cloudstack.CloudStackApiMetadata;
-import org.jclouds.cloudstack.CloudStackAsyncClient;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
-import org.jclouds.rest.RestContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Base class for all activities that require access to a CloudStack based cloud.
- */
-public abstract class CloudStackActivity implements JavaDelegate {
-
-    private static final Logger LOG = LoggerFactory.getLogger(CloudStackActivity.class);
-
-    /**
-     * Implement activity logic in this method. It will be called with a reference to the {@link CloudStackClient}
-     */
-    public abstract void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution);
-
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-
-        RestContext<CloudStackClient, CloudStackAsyncClient> restContext = null;
-        try {
-            Pool pool = Pool.class.cast(checkNotNull(execution.getVariable(CoreProcessVariables.POOL),
-                "Please add 'pool' variable to the process"));
-            // delegate
-            restContext = newCloudStackClient(pool.getProvider());
-            execute(restContext.getApi(), pool, execution);
-
-        } finally {
-            Closeables.closeQuietly(restContext);
-        }
-    }
-
-    /**
-     * Creates a new {@link CloudStackClient} with {@link Provider} supplied credentials.
-     */
-    RestContext<CloudStackClient, CloudStackAsyncClient> newCloudStackClient(Provider provider) {
-        checkArgument(provider.getEndpoint().isPresent(), "please specify an endpoint for this provider");
-        Properties overrides = new Properties();
-        overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
-        return ContextBuilder.newBuilder(new CloudStackApiMetadata())
-            .endpoint(provider.getEndpoint().get())
-            .modules(ImmutableSet.<Module>of(new SLF4JLoggingModule()))
-            .credentials(provider.getAccessKey(), provider.getSecretKey())
-            .overrides(overrides)
-            .build(CloudStackApiMetadata.CONTEXT_TOKEN);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/DeleteKeyPair.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/DeleteKeyPair.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/DeleteKeyPair.java
deleted file mode 100644
index 2368e57..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/DeleteKeyPair.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.core.KeyPairs;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeleteKeyPair extends CloudStackActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DeleteKeyPair.class);
-
-    @Override
-    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
-        String keyName = KeyPairs.formatNameFromBusinessKey(execution.getProcessBusinessKey());
-        LOG.info("Deleting Admin Access Key pair {}", keyName);
-        cloudStackClient.getSSHKeyPairClient().deleteSSHKeyPair(keyName);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/DeleteSecurityGroup.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/DeleteSecurityGroup.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/DeleteSecurityGroup.java
deleted file mode 100644
index 8dbd03e..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/DeleteSecurityGroup.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.core.SecurityGroups;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeleteSecurityGroup extends CloudStackActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DeleteSecurityGroup.class);
-
-    @Override
-    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
-        String securityGroupName = SecurityGroups.formatNameFromBusinessKey(execution.getProcessBusinessKey());
-        SecurityGroups.deleteByName(cloudStackClient, securityGroupName);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureKeyPairExists.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureKeyPairExists.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureKeyPairExists.java
deleted file mode 100644
index f719831..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureKeyPairExists.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.core.KeyPairs;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.SshKeyPair;
-import org.jclouds.cloudstack.features.SSHKeyPairClient;
-import org.jclouds.crypto.SshKeys;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EnsureKeyPairExists extends CloudStackActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EnsureKeyPairExists.class);
-
-    @Override
-    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
-        String keyName = KeyPairs.formatNameFromBusinessKey(execution.getProcessBusinessKey());
-        LOG.info("Creating admin access key pair as {}", keyName);
-        SSHKeyPairClient sshKeyPairClient = cloudStackClient.getSSHKeyPairClient();
-        try {
-            SshKeyPair sshKeyPair = sshKeyPairClient.registerSSHKeyPair(keyName, pool.getAdminAccess().getPublicKey());
-            LOG.info("Registered remote key with fingerprint {}", sshKeyPair.getFingerprint());
-        } catch (IllegalStateException e) {
-            LOG.warn("Key with name {} already exists", keyName);
-            SshKeyPair key = sshKeyPairClient.getSSHKeyPair(keyName);
-            if (key.getFingerprint().equals(SshKeys.fingerprintPublicKey(pool.getAdminAccess().getPublicKey()))) {
-                LOG.info("Fingerprints match. Not updating admin access key pair.");
-            } else {
-                LOG.info("Fingerprint do not match. Replacing admin access key pair.");
-                sshKeyPairClient.deleteSSHKeyPair(keyName);
-                sshKeyPairClient.registerSSHKeyPair(keyName, pool.getAdminAccess().getPublicKey());
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureNetworkExists.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureNetworkExists.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureNetworkExists.java
deleted file mode 100644
index 211fef7..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureNetworkExists.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.NetworkOptions;
-import com.axemblr.provisionr.cloudstack.ProcessVariables;
-import com.axemblr.provisionr.cloudstack.ProviderOptions;
-import com.axemblr.provisionr.cloudstack.core.Networks;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.NoSuchElementException;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.Network;
-import org.jclouds.cloudstack.options.CreateNetworkOptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EnsureNetworkExists extends CloudStackActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EnsureNetworkExists.class);
-
-    @Override
-    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
-        if (execution.getVariable(ProcessVariables.NETWORK_ID) != null) {
-            LOG.warn("Network process variable ({}) will be overwritten!", ProcessVariables.NETWORK_ID);
-        }
-        Network network;
-        final String existingNetwork = pool.getNetwork().getOption(NetworkOptions.EXISTING_NETWORK_ID);
-        if (existingNetwork != null) {
-            network = checkNotNull(cloudStackClient.getNetworkClient().getNetwork(existingNetwork),
-                "Network with id " + existingNetwork + " does not exist");
-        } else {
-            final String networkName = Networks.formatNameFromBusinessKey(execution.getProcessBusinessKey());
-            final String zoneId = pool.getProvider().getOption(ProviderOptions.ZONE_ID);
-            final String networkOfferingId = pool.getProvider().getOption(ProviderOptions.NETWORK_OFFERING_ID);
-            try {
-                network = Networks.getByName(cloudStackClient, networkName);
-                LOG.info("Network with name {} exists.", networkName);
-            } catch (NoSuchElementException e) {
-                LOG.info(String.format("Creating network %s in zone %s with offering %s",
-                    networkName, zoneId, networkOfferingId));
-                network = cloudStackClient.getNetworkClient().createNetworkInZone(zoneId, networkOfferingId, networkName,
-                    networkName, CreateNetworkOptions.NONE);
-            }
-        }
-        LOG.info("Storing network id {} in process variable {}", network.getId(), ProcessVariables.NETWORK_ID);
-        execution.setVariable(ProcessVariables.NETWORK_ID, network.getId());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureSecurityGroupExists.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureSecurityGroupExists.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureSecurityGroupExists.java
deleted file mode 100644
index 8da633a..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/EnsureSecurityGroupExists.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.core.SecurityGroups;
-import static com.google.common.base.Preconditions.checkNotNull;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.SecurityGroup;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Creates a CloudStack {@link SecurityGroup} with specified rules. If a SecurityGroup with the same name exists,
- * it will be deleted first.
- */
-public class EnsureSecurityGroupExists extends CloudStackActivity {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EnsureSecurityGroupExists.class);
-
-    @Override
-    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
-        Network network = checkNotNull(pool.getNetwork(), "Please configure a network for the pool");
-        String securityGroupName = SecurityGroups.formatNameFromBusinessKey(execution.getProcessBusinessKey());
-        SecurityGroup securityGroup;
-        try {
-            LOG.info("Creating SecurityGroup {}", securityGroupName);
-            securityGroup = SecurityGroups.createSecurityGroup(cloudStackClient, securityGroupName);
-        } catch (IllegalStateException e) {
-            LOG.info("Failed creating SecurityGroup {} - checking if it exists", securityGroupName);
-            securityGroup = SecurityGroups.getByName(cloudStackClient, securityGroupName);
-            LOG.info("Delete old SecurityGroup rules for {}", securityGroupName);
-            SecurityGroups.deleteNetworkRules(cloudStackClient, securityGroup);
-        }
-        if (securityGroup != null) {
-            LOG.info("Applying network rules on SecurityGroup {}", securityGroupName);
-            SecurityGroups.applyNetworkRules(cloudStackClient, securityGroup, network);
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/RunInstances.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/RunInstances.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/RunInstances.java
deleted file mode 100644
index f419f3e..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/activities/RunInstances.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.cloudstack.ProviderOptions;
-import com.axemblr.provisionr.cloudstack.core.KeyPairs;
-import com.axemblr.provisionr.cloudstack.core.Networks;
-import com.axemblr.provisionr.cloudstack.core.VirtualMachines;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.AsyncCreateResponse;
-import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RunInstances extends CloudStackActivity {
-
-    public static final Logger LOG = LoggerFactory.getLogger(RunInstances.class);
-
-    @Override
-    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
-        final String businessKey = execution.getProcessBusinessKey();
-
-        final String keyPairName = KeyPairs.formatNameFromBusinessKey(businessKey);
-
-        final String zoneId = pool.getOptions().get(ProviderOptions.ZONE_ID);
-        final String templateId = pool.getSoftware().getImageId();
-        final String serviceOffering = pool.getHardware().getType();
-
-        LOG.info("Starting instances!");
-
-        AsyncCreateResponse asyncCreateResponse = cloudStackClient.getVirtualMachineClient()
-            .deployVirtualMachineInZone(zoneId, serviceOffering, templateId,
-                DeployVirtualMachineOptions.Builder
-                    .displayName(businessKey)
-                    .group(businessKey)
-                    .networkId(Networks.formatNameFromBusinessKey(businessKey))
-                    .keyPair(keyPairName)
-                    .name(businessKey));
-
-        VirtualMachines.waitForVMtoStart(cloudStackClient, businessKey);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/CommandSupport.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/CommandSupport.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/CommandSupport.java
deleted file mode 100644
index 9099350..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/CommandSupport.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.commands;
-
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.cloudstack.DefaultProviderConfig;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.io.Closeables;
-import java.io.PrintStream;
-import java.util.Properties;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
-import org.jclouds.Constants;
-import org.jclouds.ContextBuilder;
-import org.jclouds.cloudstack.CloudStackApiMetadata;
-import org.jclouds.cloudstack.CloudStackAsyncClient;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
-import org.jclouds.rest.RestContext;
-
-
-/**
- * Base class for CloudStack  Karaf Shell commands. It takes care of creating and cleaning a
- * {@link org.jclouds.cloudstack.CloudStackContext} for each command.
- */
-public abstract class CommandSupport extends OsgiCommandSupport {
-
-    private RestContext<CloudStackClient, CloudStackAsyncClient> context = null;
-    public static final String CLOUDSTACK_SCOPE = "cloudstack";
-
-    private final Provider provider;
-
-    protected CommandSupport(DefaultProviderConfig providerConfig) {
-        this.provider = providerConfig.createProvider().get();
-    }
-
-    public abstract Object doExecuteWithContext(CloudStackClient client, PrintStream out) throws Exception;
-
-    @Override
-    protected Object doExecute() throws Exception {
-        try {
-            context = newCloudStackContext(provider);
-            return doExecuteWithContext(context.getApi(), System.out);
-        } finally {
-            Closeables.closeQuietly(context);
-        }
-    }
-
-    protected RestContext<CloudStackClient, CloudStackAsyncClient> newCloudStackContext(Provider provider) {
-        Properties overrides = new Properties();
-        overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
-        return ContextBuilder.newBuilder(new CloudStackApiMetadata())
-            .endpoint(provider.getEndpoint().get())
-            .modules(ImmutableSet.of(new SLF4JLoggingModule()))
-            .credentials(provider.getAccessKey(), provider.getSecretKey())
-            .overrides(overrides)
-            .build(CloudStackApiMetadata.CONTEXT_TOKEN);
-    }
-
-    public Provider getProvider() {
-        return provider;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/OfferingsCommand.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/OfferingsCommand.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/OfferingsCommand.java
deleted file mode 100644
index fe479ea..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/OfferingsCommand.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.commands;
-
-import com.axemblr.provisionr.cloudstack.DefaultProviderConfig;
-import java.io.PrintStream;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.DiskOffering;
-import org.jclouds.cloudstack.domain.NetworkOffering;
-import org.jclouds.cloudstack.domain.ServiceOffering;
-
-@Command(scope = CommandSupport.CLOUDSTACK_SCOPE, name = OfferingsCommand.NAME,
-    description = "Commands to list CloudStack Service Offerings")
-public class OfferingsCommand extends CommandSupport {
-
-    public static final String NAME = "offerings";
-
-    @Option(name = "-s", aliases = "--service", description = "List service offerings")
-    private boolean serviceOffering;
-
-    @Option(name = "-n", aliases = "--network", description = "List network offerings")
-    private boolean networkOffering;
-
-    @Option(name = "-d", aliases = "--disk", description = "List disk offerings")
-    private boolean diskOffering;
-
-    public OfferingsCommand(DefaultProviderConfig providerConfig) {
-        super(providerConfig);
-    }
-
-    @Override
-    public Object doExecuteWithContext(CloudStackClient client, PrintStream out) throws Exception {
-        if (isDiskOfferingListed() || isServiceOfferingListed() || isNetworkOfferingListed()) {
-            out.printf("CloudStack Offerings for provider %s\n", getProvider().getId());
-            listServiceOfferingsIfSpecified(client, out);
-            listNetworkOfferingsIfSpecified(client, out);
-            listDiskOfferingsIfSpecified(client, out);
-        } else {
-            out.printf("No option specified. See --help for details.");
-        }
-        return null;
-    }
-
-    private void listDiskOfferingsIfSpecified(CloudStackClient client, PrintStream out) {
-        if (isDiskOfferingListed()) {
-            for (DiskOffering offering : client.getOfferingClient().listDiskOfferings()) {
-                out.printf("---\n%s\n", offering.toString());
-            }
-        }
-    }
-
-    private void listNetworkOfferingsIfSpecified(CloudStackClient client, PrintStream out) {
-        if (isNetworkOfferingListed()) {
-            for (NetworkOffering offering : client.getOfferingClient().listNetworkOfferings()) {
-                out.printf("---\n%s\n", offering.toString());
-            }
-        }
-    }
-
-    private void listServiceOfferingsIfSpecified(CloudStackClient client, PrintStream out) {
-        if (isServiceOfferingListed()) {
-            for (ServiceOffering offering : client.getOfferingClient().listServiceOfferings()) {
-                out.printf("---\n%s\n", offering.toString());
-            }
-        }
-    }
-
-    public boolean isDiskOfferingListed() {
-        return diskOffering;
-    }
-
-    public void setDiskOffering(boolean diskOffering) {
-        this.diskOffering = diskOffering;
-    }
-
-    public boolean isNetworkOfferingListed() {
-        return networkOffering;
-    }
-
-    public void setNetworkOffering(boolean networkOffering) {
-        this.networkOffering = networkOffering;
-    }
-
-    public boolean isServiceOfferingListed() {
-        return serviceOffering;
-    }
-
-    public void setServiceOffering(boolean serviceOffering) {
-        this.serviceOffering = serviceOffering;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/TemplatesCommand.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/TemplatesCommand.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/TemplatesCommand.java
deleted file mode 100644
index caa53db..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/TemplatesCommand.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.commands;
-
-import com.axemblr.provisionr.cloudstack.DefaultProviderConfig;
-import java.io.PrintStream;
-import org.apache.felix.gogo.commands.Command;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.Template;
-
-@Command(scope = CommandSupport.CLOUDSTACK_SCOPE, name = TemplatesCommand.NAME,
-    description = "Commands to list CloudStack templates")
-public class TemplatesCommand extends CommandSupport {
-
-    public static final String NAME = "templates";
-
-    public TemplatesCommand(DefaultProviderConfig providerConfig) {
-        super(providerConfig);
-    }
-
-    @Override
-    public Object doExecuteWithContext(CloudStackClient client, PrintStream out) throws Exception {
-        out.printf("CloudStack templates for provider %s\n", getProvider().getId());
-
-        for (Template template : client.getTemplateClient().listTemplates()) {
-            out.printf("---\n%s\n", template.toString());
-        }
-        out.println();
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/ZonesCommand.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/ZonesCommand.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/ZonesCommand.java
deleted file mode 100644
index 039d635..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/commands/ZonesCommand.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.commands;
-
-import com.axemblr.provisionr.cloudstack.DefaultProviderConfig;
-import java.io.PrintStream;
-import org.apache.felix.gogo.commands.Command;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.Zone;
-
-@Command(scope = CommandSupport.CLOUDSTACK_SCOPE, name = ZonesCommand.NAME,
-    description = "Commands to list CloudStack Zones")
-public class ZonesCommand extends CommandSupport {
-
-    public static final String NAME = "zones";
-
-    public ZonesCommand(DefaultProviderConfig defaultProviderConfig) {
-        super(defaultProviderConfig);
-    }
-
-    @Override
-    public Object doExecuteWithContext(CloudStackClient client, PrintStream out) throws Exception {
-        out.printf("CloudStack zones for provider %s\n", getProvider().getId());
-        for (Zone zone : client.getZoneClient().listZones()) {
-            out.printf("---\n%s\n", zone.toString());
-        }
-        out.println();
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/ConvertIngressRuleToRule.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/ConvertIngressRuleToRule.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/ConvertIngressRuleToRule.java
deleted file mode 100644
index 4a53133..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/ConvertIngressRuleToRule.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.core;
-
-import com.axemblr.provisionr.api.network.Protocol;
-import com.axemblr.provisionr.api.network.Rule;
-import com.google.common.base.Function;
-import org.jclouds.cloudstack.domain.IngressRule;
-
-public enum ConvertIngressRuleToRule implements Function<IngressRule, Rule> {
-    FUNCTION;
-
-    @Override
-    public Rule apply(IngressRule input) {
-        Rule rule;
-        if (input.getProtocol().equalsIgnoreCase("icmp")) {
-            rule = Rule.builder()
-                .anySource()
-                .protocol(Protocol.valueOf(input.getProtocol().toUpperCase()))
-                .cidr(input.getCIDR())
-                .createRule();
-        } else {
-            rule = Rule.builder()
-                .anySource()
-                .protocol(Protocol.valueOf(input.getProtocol().toUpperCase()))
-                .ports(input.getStartPort(), input.getEndPort())
-                .cidr(input.getCIDR())
-                .createRule();
-        }
-        return rule;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/KeyPairs.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/KeyPairs.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/KeyPairs.java
deleted file mode 100644
index 88f8b66..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/KeyPairs.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.core;
-
-public class KeyPairs {
-
-    private KeyPairs() {
-        // singleton
-    }
-
-    public static String formatNameFromBusinessKey(String businessKey) {
-        return String.format("key-%s", businessKey);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/Networks.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/Networks.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/Networks.java
deleted file mode 100644
index db85bd3..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/Networks.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.core;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.Network;
-
-public class Networks {
-
-    private Networks() {
-    }
-
-    public static String formatNameFromBusinessKey(String processBusinessKey) {
-        return String.format("networks-%s", processBusinessKey);
-    }
-
-    /**
-     * Returns the first network with the given name.
-     *
-     * @throws NoSuchElementException   if no network is found
-     * @throws IllegalArgumentException if more networks with the same name are found
-     */
-    public static Network getByName(CloudStackClient client, final String networkName) {
-        Set<Network> networks = Sets.filter(client.getNetworkClient().listNetworks(), new Predicate<Network>() {
-            @Override
-            public boolean apply(Network input) {
-                return input.getName().equals(networkName);
-            }
-        });
-        return Iterables.getOnlyElement(networks);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/SecurityGroups.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/SecurityGroups.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/SecurityGroups.java
deleted file mode 100644
index 735b6e5..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/SecurityGroups.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.core;
-
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Protocol;
-import com.axemblr.provisionr.api.network.Rule;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.IngressRule;
-import org.jclouds.cloudstack.domain.SecurityGroup;
-import org.jclouds.cloudstack.features.SecurityGroupClient;
-import static org.jclouds.cloudstack.options.ListSecurityGroupsOptions.Builder.named;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SecurityGroups {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SecurityGroup.class);
-    public static final int DEFAULT_ICMP_CODE = 0;
-    public static final int DEFAULT_ICMP_TYPE = 8;
-
-    private SecurityGroups() {
-    }
-
-    public static String formatNameFromBusinessKey(String processBusinessKey) {
-        return String.format("network-%s", processBusinessKey);
-    }
-
-    /**
-     * Get a SecurityGroup by name.
-     *
-     * @throws NoSuchElementException if securityGroup does not exist.
-     */
-    public static SecurityGroup getByName(CloudStackClient cloudStackClient, String securityGroup) {
-        return Iterables.getOnlyElement(cloudStackClient
-            .getSecurityGroupClient()
-            .listSecurityGroups(named(securityGroup)));
-    }
-
-    public static Set<SecurityGroup> getAll(CloudStackClient cloudStackClient) {
-        return cloudStackClient.getSecurityGroupClient().listSecurityGroups();
-    }
-
-    public static void deleteByName(CloudStackClient cloudStackClient, String securityGroupName) {
-        try {
-            SecurityGroup securityGroup = getByName(cloudStackClient, securityGroupName);
-            LOG.info("Deleting SecurityGroup {}", securityGroup.getName());
-            cloudStackClient.getSecurityGroupClient().deleteSecurityGroup(securityGroup.getId());
-        } catch (NoSuchElementException e) {
-            LOG.warn("Exception retrieving SecurityGroup (most likely it does not yet exist){}: {}", securityGroupName, e);
-        }
-    }
-
-    public static SecurityGroup createSecurityGroup(CloudStackClient cloudStackClient, String securityGroupName) {
-        SecurityGroupClient securityGroupClient = cloudStackClient.getSecurityGroupClient();
-        return securityGroupClient.createSecurityGroup(securityGroupName);
-    }
-
-    public static void deleteNetworkRules(CloudStackClient cloudStackClient, SecurityGroup securityGroup) {
-        for (IngressRule rule : securityGroup.getIngressRules()) {
-            cloudStackClient.getSecurityGroupClient().revokeIngressRule(rule.getId());
-        }
-    }
-
-    public static void applyNetworkRules(CloudStackClient cloudStackClient, SecurityGroup securityGroup, Network network) {
-        SecurityGroupClient securityGroupClient = cloudStackClient.getSecurityGroupClient();
-        for (Rule rule : network.getIngress()) {
-            if (rule.getProtocol() == Protocol.ICMP) {
-                securityGroupClient.authorizeIngressICMPToCIDRs(securityGroup.getId(), DEFAULT_ICMP_CODE,
-                    DEFAULT_ICMP_TYPE, ImmutableList.of(rule.getCidr()));
-            } else {
-                securityGroupClient.authorizeIngressPortsToCIDRs(securityGroup.getId(),
-                    rule.getProtocol().name(),
-                    rule.getPorts().lowerEndpoint(),
-                    rule.getPorts().upperEndpoint(),
-                    Lists.newArrayList(rule.getCidr()));
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/VirtualMachines.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/VirtualMachines.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/VirtualMachines.java
deleted file mode 100644
index 00efc0d..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/VirtualMachines.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.core;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.VirtualMachine;
-import static org.jclouds.cloudstack.domain.VirtualMachine.State.STARTING;
-import org.jclouds.cloudstack.options.ListVirtualMachinesOptions;
-import static org.jclouds.util.Preconditions2.checkNotEmpty;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class VirtualMachines {
-
-    private static final Logger LOG = LoggerFactory.getLogger(VirtualMachines.class);
-    public static int WAIT_TIME_OUT_IN_SECONDS = 180;
-    public static final int BETWEEN_REQUESTS_SLEEP_TIME = WAIT_TIME_OUT_IN_SECONDS / 10;
-
-    private VirtualMachines() {
-    }
-
-    public static List<String> destroyAllVirtualMachineByName(final CloudStackClient client, final String vmName) {
-        checkNotEmpty(vmName);
-
-        Set<VirtualMachine> vms = Sets.filter(client.getVirtualMachineClient()
-            .listVirtualMachines(ListVirtualMachinesOptions.Builder.name(vmName)), new Predicate<VirtualMachine>() {
-            @Override
-            public boolean apply(VirtualMachine input) {
-                return vmName.equals(input.getDisplayName());
-            }
-        });
-
-        List<String> jobIds = Lists.newArrayList();
-        LOG.info("Deleting a total of {} virtual machine instances", vms.size());
-        for (VirtualMachine vm : vms) {
-            LOG.info("Deleting instance with id {}", vm.getId());
-            jobIds.add(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId()));
-        }
-        return ImmutableList.copyOf(jobIds);
-    }
-
-    public static void waitForVMtoStart(final CloudStackClient client, final String vmName) {
-        checkNotEmpty(vmName);
-        VirtualMachine machine = getVirtualMachineByName(client, vmName);
-        String id = machine.getId();
-        long startTime = System.currentTimeMillis();
-        while (machine.getState() == STARTING) {
-            try {
-                LOG.info("Waiting for VM {} - id {} to start", machine.getName(), machine.getId());
-                TimeUnit.SECONDS.sleep(BETWEEN_REQUESTS_SLEEP_TIME);
-                machine = client.getVirtualMachineClient().getVirtualMachine(id);
-            } catch (InterruptedException e) {
-                LOG.info("Interrupted while waiting for VM's to start");
-                Throwables.propagateIfPossible(e);
-            }
-            if (timeOutExceeded(startTime)) {
-                break;
-            }
-        }
-
-        switch (machine.getState()) {
-            case RUNNING:
-                LOG.info("VM {} is running, as expected", vmName);
-                break;
-            default:
-                throw new IllegalStateException("VM " + machine + "is not in RUNNING state");
-        }
-    }
-
-    private static boolean timeOutExceeded(long startTime) {
-        return System.currentTimeMillis() - startTime > (WAIT_TIME_OUT_IN_SECONDS * 1000);
-    }
-
-    private static VirtualMachine getVirtualMachineByName(CloudStackClient client, final String vmName) {
-        Set<VirtualMachine> machines = Sets.filter(client.getVirtualMachineClient()
-            .listVirtualMachines(ListVirtualMachinesOptions.Builder.name(vmName)), new Predicate<VirtualMachine>() {
-            @Override
-            public boolean apply(VirtualMachine input) {
-                return vmName.equals(input.getDisplayName());
-            }
-        });
-        return Iterables.getOnlyElement(machines);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/Zones.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/Zones.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/Zones.java
deleted file mode 100644
index eebc4ce..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/core/Zones.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.cloudstack.core;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import java.util.Set;
-import org.jclouds.cloudstack.CloudStackClient;
-import org.jclouds.cloudstack.domain.Zone;
-
-public class Zones {
-
-    private Zones() {
-    }
-
-    public static boolean hasSecurityGroupEnabled(final CloudStackClient cloudStackClient, final String zoneName) {
-        Set<Zone> ourZone = Sets.filter(cloudStackClient.getZoneClient().listZones(), new Predicate<Zone>() {
-            @Override
-            public boolean apply(Zone input) {
-                return input.getName().equals(zoneName);
-            }
-        });
-        return Iterables.getOnlyElement(ourZone).isSecurityGroupsEnabled();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/CloudStackProvisionr.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/CloudStackProvisionr.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/CloudStackProvisionr.java
new file mode 100644
index 0000000..2ce5a99
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/CloudStackProvisionr.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack;
+
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.Maps;
+import java.util.Map;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.core.CoreConstants;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.apache.provisionr.core.ProvisionrSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CloudStackProvisionr extends ProvisionrSupport {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CloudStackProvisionr.class);
+    public static final String ID = "cloudstack";
+    /**
+     * Process key must match the one in
+     *  providers/cloudstack/src/main/resources/OSGI-INF/activiti/cloudstack.bpmn20.xml
+     */
+    public static final String PROCESS_KEY = "cloudstack";
+
+    private final ProcessEngine processEngine;
+    private final Optional<Provider> defaultProvider;
+
+    public CloudStackProvisionr(ProcessEngine processEngine, DefaultProviderConfig providerConfig) {
+        this.processEngine = checkNotNull(processEngine, "processEngine is null");
+        this.defaultProvider = providerConfig.createProvider();
+
+        if (defaultProvider.isPresent()) {
+            LOG.info("Default provider for CloudStackProvisionr is {}", defaultProvider.get());
+        } else {
+            LOG.info("No default provider configured for CloudStackProvisionr");
+        }
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    @Override
+    public Optional<Provider> getDefaultProvider() {
+        return defaultProvider;
+    }
+
+    @Override
+    public String startPoolManagementProcess(String businessKey, Pool pool) {
+        Map<String, Object> arguments = Maps.newHashMap();
+
+        arguments.put(CoreProcessVariables.POOL, pool);
+        arguments.put(CoreProcessVariables.PROVIDER, getId());
+        arguments.put(CoreProcessVariables.POOL_BUSINESS_KEY, businessKey);
+        arguments.put(CoreProcessVariables.BOOTSTRAP_TIMEOUT,
+            convertTimeoutToISO8601TimeDuration(pool.getBootstrapTimeInSeconds()));
+
+        /* Authenticate as kermit to make the process visible in the Explorer UI */
+        processEngine.getIdentityService().setAuthenticatedUserId(CoreConstants.ACTIVITI_EXPLORER_DEFAULT_USER);
+
+        RuntimeService runtimeService = processEngine.getRuntimeService();
+        ProcessInstance instance = runtimeService.startProcessInstanceByKey(PROCESS_KEY, businessKey, arguments);
+
+        return instance.getProcessInstanceId();
+    }
+
+    @Override
+    public void destroyPool(String businessKey) {
+        LOG.info("**** CloudStack (destroyPool) id: " + businessKey);
+        // TODO use triggerSignalEvent as needed
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/DefaultProviderConfig.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/DefaultProviderConfig.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/DefaultProviderConfig.java
new file mode 100644
index 0000000..05ac50c
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/DefaultProviderConfig.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack;
+
+import org.apache.provisionr.api.provider.Provider;
+import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class DefaultProviderConfig {
+
+    private final String endpoint;
+    private final String accessKey;
+    private final String secretKey;
+    private final String zoneId;
+    private final String templateId;
+    private final String serviceOffering;
+
+    public DefaultProviderConfig(
+        String endpoint, String accessKey, String secretKey, String zoneId, String templateId, String serviceOffering
+    ) {
+        this.endpoint = checkNotNull(endpoint, "endpoint is null");
+        this.accessKey = checkNotNull(accessKey, "access key is null");
+        this.secretKey = checkNotNull(secretKey, "secret key is null");
+        this.zoneId = checkNotNull(zoneId, "zone id is null");
+        this.templateId = checkNotNull(templateId, "template id is null");
+        this.serviceOffering = checkNotNull(serviceOffering, "service offering is null");
+    }
+
+    public Optional<Provider> createProvider() {
+        if (accessKey.isEmpty() || secretKey.isEmpty() || endpoint.isEmpty()) {
+            return Optional.absent();
+        }
+        return Optional.of(Provider.builder()
+            .id(CloudStackProvisionr.ID)
+            .endpoint(endpoint)
+            .accessKey(accessKey)
+            .secretKey(secretKey)
+            .option(ProviderOptions.ZONE_ID, zoneId)
+            .option(ProviderOptions.TEMPLATE_ID, templateId)
+            .option(ProviderOptions.SERVICE_OFFERING_ID, serviceOffering)
+            .createProvider());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/NetworkOptions.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/NetworkOptions.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/NetworkOptions.java
new file mode 100644
index 0000000..9fb3fdd
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/NetworkOptions.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack;
+
+/**
+ * {@link org.apache.provisionr.api.network.Network Network} configuration is passed via the
+ * {@link org.apache.provisionr.api.pool.Pool Pool} object. This class stores names for those options.
+ */
+public class NetworkOptions {
+
+    private NetworkOptions() {
+        throw new RuntimeException("Do not instantiate");
+    }
+
+    /**
+     * Pass this option if you wish to use an existing CloudStack network.
+     */
+    public static final String EXISTING_NETWORK_ID = "existingNetworkId";
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/ProcessVariables.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/ProcessVariables.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/ProcessVariables.java
new file mode 100644
index 0000000..83c72fe
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/ProcessVariables.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack;
+
+public class ProcessVariables {
+
+    private ProcessVariables() {
+        // prevent instantiation
+    }
+
+    public static final String NETWORK_ID = "networkId";
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/ProviderOptions.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/ProviderOptions.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/ProviderOptions.java
new file mode 100644
index 0000000..9874696
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/ProviderOptions.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack;
+
+
+/**
+ * Building a pool of VM's on CloudStack requires more knowledge of the cloud's architecture,
+ * You need to know things like in what zone to build the pool, the ID's of service offerings, network offerings,
+ * and more.
+ * <p/>
+ * All the information is passed via Provider Options. This class stores some of the option names.
+ */
+public class ProviderOptions {
+
+    private ProviderOptions() {
+        throw new RuntimeException(ProviderOptions.class.getName() + " should not be instantiated");
+    }
+
+    public static final String ZONE_ID = "zoneId";
+    public static final String TEMPLATE_ID = "templateId";
+    public static final String SERVICE_OFFERING_ID = "serviceOfferingId";
+    public static final String NETWORK_OFFERING_ID = "networkOfferingId";
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/CloudStackActivity.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/CloudStackActivity.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/CloudStackActivity.java
new file mode 100644
index 0000000..5bbe3d2
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/CloudStackActivity.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.Closeables;
+import com.google.inject.Module;
+import java.util.Properties;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.JavaDelegate;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.jclouds.Constants;
+import org.jclouds.ContextBuilder;
+import org.jclouds.cloudstack.CloudStackApiMetadata;
+import org.jclouds.cloudstack.CloudStackAsyncClient;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.rest.RestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Base class for all activities that require access to a CloudStack based cloud.
+ */
+public abstract class CloudStackActivity implements JavaDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CloudStackActivity.class);
+
+    /**
+     * Implement activity logic in this method. It will be called with a reference to the {@link CloudStackClient}
+     */
+    public abstract void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution);
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+
+        RestContext<CloudStackClient, CloudStackAsyncClient> restContext = null;
+        try {
+            Pool pool = Pool.class.cast(checkNotNull(execution.getVariable(CoreProcessVariables.POOL),
+                "Please add 'pool' variable to the process"));
+            // delegate
+            restContext = newCloudStackClient(pool.getProvider());
+            execute(restContext.getApi(), pool, execution);
+
+        } finally {
+            Closeables.closeQuietly(restContext);
+        }
+    }
+
+    /**
+     * Creates a new {@link CloudStackClient} with {@link Provider} supplied credentials.
+     */
+    RestContext<CloudStackClient, CloudStackAsyncClient> newCloudStackClient(Provider provider) {
+        checkArgument(provider.getEndpoint().isPresent(), "please specify an endpoint for this provider");
+        Properties overrides = new Properties();
+        overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
+        return ContextBuilder.newBuilder(new CloudStackApiMetadata())
+            .endpoint(provider.getEndpoint().get())
+            .modules(ImmutableSet.<Module>of(new SLF4JLoggingModule()))
+            .credentials(provider.getAccessKey(), provider.getSecretKey())
+            .overrides(overrides)
+            .build(CloudStackApiMetadata.CONTEXT_TOKEN);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/DeleteKeyPair.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/DeleteKeyPair.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/DeleteKeyPair.java
new file mode 100644
index 0000000..b0f49af
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/DeleteKeyPair.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.core.KeyPairs;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeleteKeyPair extends CloudStackActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeleteKeyPair.class);
+
+    @Override
+    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
+        String keyName = KeyPairs.formatNameFromBusinessKey(execution.getProcessBusinessKey());
+        LOG.info("Deleting Admin Access Key pair {}", keyName);
+        cloudStackClient.getSSHKeyPairClient().deleteSSHKeyPair(keyName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/DeleteSecurityGroup.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/DeleteSecurityGroup.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/DeleteSecurityGroup.java
new file mode 100644
index 0000000..d4f28d1
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/DeleteSecurityGroup.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.core.SecurityGroups;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeleteSecurityGroup extends CloudStackActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeleteSecurityGroup.class);
+
+    @Override
+    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
+        String securityGroupName = SecurityGroups.formatNameFromBusinessKey(execution.getProcessBusinessKey());
+        SecurityGroups.deleteByName(cloudStackClient, securityGroupName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureKeyPairExists.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureKeyPairExists.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureKeyPairExists.java
new file mode 100644
index 0000000..80e7b86
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureKeyPairExists.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.core.KeyPairs;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.SshKeyPair;
+import org.jclouds.cloudstack.features.SSHKeyPairClient;
+import org.jclouds.crypto.SshKeys;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnsureKeyPairExists extends CloudStackActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EnsureKeyPairExists.class);
+
+    @Override
+    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
+        String keyName = KeyPairs.formatNameFromBusinessKey(execution.getProcessBusinessKey());
+        LOG.info("Creating admin access key pair as {}", keyName);
+        SSHKeyPairClient sshKeyPairClient = cloudStackClient.getSSHKeyPairClient();
+        try {
+            SshKeyPair sshKeyPair = sshKeyPairClient.registerSSHKeyPair(keyName, pool.getAdminAccess().getPublicKey());
+            LOG.info("Registered remote key with fingerprint {}", sshKeyPair.getFingerprint());
+        } catch (IllegalStateException e) {
+            LOG.warn("Key with name {} already exists", keyName);
+            SshKeyPair key = sshKeyPairClient.getSSHKeyPair(keyName);
+            if (key.getFingerprint().equals(SshKeys.fingerprintPublicKey(pool.getAdminAccess().getPublicKey()))) {
+                LOG.info("Fingerprints match. Not updating admin access key pair.");
+            } else {
+                LOG.info("Fingerprint do not match. Replacing admin access key pair.");
+                sshKeyPairClient.deleteSSHKeyPair(keyName);
+                sshKeyPairClient.registerSSHKeyPair(keyName, pool.getAdminAccess().getPublicKey());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureNetworkExists.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureNetworkExists.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureNetworkExists.java
new file mode 100644
index 0000000..ec4c22b
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureNetworkExists.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.NetworkOptions;
+import org.apache.provisionr.cloudstack.ProcessVariables;
+import org.apache.provisionr.cloudstack.ProviderOptions;
+import org.apache.provisionr.cloudstack.core.Networks;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.NoSuchElementException;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.Network;
+import org.jclouds.cloudstack.options.CreateNetworkOptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnsureNetworkExists extends CloudStackActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EnsureNetworkExists.class);
+
+    @Override
+    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
+        if (execution.getVariable(ProcessVariables.NETWORK_ID) != null) {
+            LOG.warn("Network process variable ({}) will be overwritten!", ProcessVariables.NETWORK_ID);
+        }
+        Network network;
+        final String existingNetwork = pool.getNetwork().getOption(NetworkOptions.EXISTING_NETWORK_ID);
+        if (existingNetwork != null) {
+            network = checkNotNull(cloudStackClient.getNetworkClient().getNetwork(existingNetwork),
+                "Network with id " + existingNetwork + " does not exist");
+        } else {
+            final String networkName = Networks.formatNameFromBusinessKey(execution.getProcessBusinessKey());
+            final String zoneId = pool.getProvider().getOption(ProviderOptions.ZONE_ID);
+            final String networkOfferingId = pool.getProvider().getOption(ProviderOptions.NETWORK_OFFERING_ID);
+            try {
+                network = Networks.getByName(cloudStackClient, networkName);
+                LOG.info("Network with name {} exists.", networkName);
+            } catch (NoSuchElementException e) {
+                LOG.info(String.format("Creating network %s in zone %s with offering %s",
+                    networkName, zoneId, networkOfferingId));
+                network = cloudStackClient.getNetworkClient().createNetworkInZone(zoneId, networkOfferingId, networkName,
+                    networkName, CreateNetworkOptions.NONE);
+            }
+        }
+        LOG.info("Storing network id {} in process variable {}", network.getId(), ProcessVariables.NETWORK_ID);
+        execution.setVariable(ProcessVariables.NETWORK_ID, network.getId());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureSecurityGroupExists.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureSecurityGroupExists.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureSecurityGroupExists.java
new file mode 100644
index 0000000..858aea8
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/EnsureSecurityGroupExists.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.core.SecurityGroups;
+import static com.google.common.base.Preconditions.checkNotNull;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.SecurityGroup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Creates a CloudStack {@link SecurityGroup} with specified rules. If a SecurityGroup with the same name exists,
+ * it will be deleted first.
+ */
+public class EnsureSecurityGroupExists extends CloudStackActivity {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EnsureSecurityGroupExists.class);
+
+    @Override
+    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
+        Network network = checkNotNull(pool.getNetwork(), "Please configure a network for the pool");
+        String securityGroupName = SecurityGroups.formatNameFromBusinessKey(execution.getProcessBusinessKey());
+        SecurityGroup securityGroup;
+        try {
+            LOG.info("Creating SecurityGroup {}", securityGroupName);
+            securityGroup = SecurityGroups.createSecurityGroup(cloudStackClient, securityGroupName);
+        } catch (IllegalStateException e) {
+            LOG.info("Failed creating SecurityGroup {} - checking if it exists", securityGroupName);
+            securityGroup = SecurityGroups.getByName(cloudStackClient, securityGroupName);
+            LOG.info("Delete old SecurityGroup rules for {}", securityGroupName);
+            SecurityGroups.deleteNetworkRules(cloudStackClient, securityGroup);
+        }
+        if (securityGroup != null) {
+            LOG.info("Applying network rules on SecurityGroup {}", securityGroupName);
+            SecurityGroups.applyNetworkRules(cloudStackClient, securityGroup, network);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/RunInstances.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/RunInstances.java b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/RunInstances.java
new file mode 100644
index 0000000..d9c3b8e
--- /dev/null
+++ b/providers/cloudstack/src/main/java/org/apache/provisionr/cloudstack/activities/RunInstances.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.cloudstack.activities;
+
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.cloudstack.ProviderOptions;
+import org.apache.provisionr.cloudstack.core.KeyPairs;
+import org.apache.provisionr.cloudstack.core.Networks;
+import org.apache.provisionr.cloudstack.core.VirtualMachines;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.AsyncCreateResponse;
+import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RunInstances extends CloudStackActivity {
+
+    public static final Logger LOG = LoggerFactory.getLogger(RunInstances.class);
+
+    @Override
+    public void execute(CloudStackClient cloudStackClient, Pool pool, DelegateExecution execution) {
+        final String businessKey = execution.getProcessBusinessKey();
+
+        final String keyPairName = KeyPairs.formatNameFromBusinessKey(businessKey);
+
+        final String zoneId = pool.getOptions().get(ProviderOptions.ZONE_ID);
+        final String templateId = pool.getSoftware().getImageId();
+        final String serviceOffering = pool.getHardware().getType();
+
+        LOG.info("Starting instances!");
+
+        AsyncCreateResponse asyncCreateResponse = cloudStackClient.getVirtualMachineClient()
+            .deployVirtualMachineInZone(zoneId, serviceOffering, templateId,
+                DeployVirtualMachineOptions.Builder
+                    .displayName(businessKey)
+                    .group(businessKey)
+                    .networkId(Networks.formatNameFromBusinessKey(businessKey))
+                    .keyPair(keyPairName)
+                    .name(businessKey));
+
+        VirtualMachines.waitForVMtoStart(cloudStackClient, businessKey);
+    }
+}


[21/21] git commit: PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

* Changed com.axemblr to org.apache for all packages
* Also removed all mentions of Axemblr
* Updated README.md to use the new groupId
* All components under activiti/ now have org.apache.provisionr as groupId
* Added org.apache:apache as parent to the project parent pom
* Updated Apache Karaf branding bundle


Project: http://git-wip-us.apache.org/repos/asf/incubator-provisionr/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-provisionr/commit/6ba40c4b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-provisionr/tree/6ba40c4b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-provisionr/diff/6ba40c4b

Branch: refs/heads/master
Commit: 6ba40c4b2fcd597b35a08e44ae38ab69ad3b9660
Parents: 6559ede
Author: Andrei Savu <as...@apache.org>
Authored: Mon Apr 1 00:23:47 2013 +0300
Committer: Andrei Savu <as...@apache.org>
Committed: Mon Apr 1 11:47:22 2013 +0300

----------------------------------------------------------------------
 README.md                                          |   43 +--
 activiti/commands/pom.xml                          |   10 +-
 .../activiti/karaf/commands/ActivitiCommand.java   |   64 ----
 .../activiti/karaf/commands/AddGroupCommand.java   |   64 ----
 .../activiti/karaf/commands/AddUserCommand.java    |   54 ---
 .../commands/CleanHistoryActivitiCommand.java      |  125 -------
 .../karaf/commands/DeleteGroupCommand.java         |   33 --
 .../activiti/karaf/commands/DeleteUserCommand.java |   38 ---
 .../karaf/commands/InfoActivitiCommand.java        |  249 --------------
 .../karaf/commands/KillActivitiCommand.java        |   72 ----
 .../karaf/commands/ListActivitiCommand.java        |  220 ------------
 .../activiti/karaf/commands/ListGroupsCommand.java |   39 ---
 .../activiti/karaf/commands/ListUsersCommand.java  |   40 ---
 .../karaf/commands/SignalActivitiCommand.java      |  110 ------
 .../karaf/commands/StartActivitiCommand.java       |   51 ---
 .../karaf/commands/UndeployActivitiCommand.java    |   80 -----
 .../handlers/AbstractActivitiPrintHandler.java     |  178 ----------
 .../commands/handlers/ActivitiPrintHandler.java    |   47 ---
 .../handlers/DefaultActivitiPrintHandler.java      |   57 ----
 .../org/activiti/karaf/commands/util/Commands.java |   97 ------
 .../activiti/karaf/commands/util/TextTable.java    |   94 ------
 .../activiti/karaf/commands/ActivitiCommand.java   |   64 ++++
 .../activiti/karaf/commands/AddGroupCommand.java   |   64 ++++
 .../activiti/karaf/commands/AddUserCommand.java    |   54 +++
 .../commands/CleanHistoryActivitiCommand.java      |  125 +++++++
 .../karaf/commands/DeleteGroupCommand.java         |   33 ++
 .../activiti/karaf/commands/DeleteUserCommand.java |   38 +++
 .../karaf/commands/InfoActivitiCommand.java        |  249 ++++++++++++++
 .../karaf/commands/KillActivitiCommand.java        |   72 ++++
 .../karaf/commands/ListActivitiCommand.java        |  220 ++++++++++++
 .../activiti/karaf/commands/ListGroupsCommand.java |   39 +++
 .../activiti/karaf/commands/ListUsersCommand.java  |   40 +++
 .../karaf/commands/SignalActivitiCommand.java      |  110 ++++++
 .../karaf/commands/StartActivitiCommand.java       |   51 +++
 .../karaf/commands/UndeployActivitiCommand.java    |   80 +++++
 .../handlers/AbstractActivitiPrintHandler.java     |  178 ++++++++++
 .../commands/handlers/ActivitiPrintHandler.java    |   47 +++
 .../handlers/DefaultActivitiPrintHandler.java      |   57 ++++
 .../activiti/karaf/commands/util/Commands.java     |   97 ++++++
 .../activiti/karaf/commands/util/TextTable.java    |   94 ++++++
 .../resources/OSGI-INF/blueprint/bpm-commands.xml  |   26 +-
 .../karaf/commands/ActivitiCommandTest.java        |  117 -------
 .../activiti/karaf/commands/ActivitiTestCase.java  |  136 --------
 .../karaf/commands/InfoActivitiCommandTest.java    |  141 --------
 .../karaf/commands/ListActivitiCommandTest.java    |   46 ---
 .../karaf/commands/ActivitiCommandTest.java        |  117 +++++++
 .../activiti/karaf/commands/ActivitiTestCase.java  |  136 ++++++++
 .../karaf/commands/InfoActivitiCommandTest.java    |  141 ++++++++
 .../karaf/commands/ListActivitiCommandTest.java    |   46 +++
 activiti/explorer/pom.xml                          |   11 +-
 api/pom.xml                                        |    6 +-
 .../com/axemblr/provisionr/api/Provisionr.java     |   75 -----
 .../axemblr/provisionr/api/access/AdminAccess.java |   88 -----
 .../provisionr/api/access/AdminAccessBuilder.java  |   67 ----
 .../provisionr/api/hardware/BlockDevice.java       |   77 -----
 .../api/hardware/BlockDeviceBuilder.java           |   33 --
 .../axemblr/provisionr/api/hardware/Hardware.java  |   83 -----
 .../provisionr/api/hardware/HardwareBuilder.java   |   56 ----
 .../axemblr/provisionr/api/network/Network.java    |   87 -----
 .../provisionr/api/network/NetworkBuilder.java     |   57 ----
 .../axemblr/provisionr/api/network/Protocol.java   |   23 --
 .../com/axemblr/provisionr/api/network/Rule.java   |   84 -----
 .../provisionr/api/network/RuleBuilder.java        |   80 -----
 .../com/axemblr/provisionr/api/pool/Machine.java   |  164 ---------
 .../provisionr/api/pool/MachineBuilder.java        |   76 -----
 .../java/com/axemblr/provisionr/api/pool/Pool.java |  146 --------
 .../axemblr/provisionr/api/pool/PoolBuilder.java   |   94 ------
 .../axemblr/provisionr/api/provider/Provider.java  |  111 -------
 .../provisionr/api/provider/ProviderBuilder.java   |   63 ----
 .../provisionr/api/software/Repository.java        |   95 ------
 .../provisionr/api/software/RepositoryBuilder.java |   59 ----
 .../axemblr/provisionr/api/software/Software.java  |  124 -------
 .../provisionr/api/software/SoftwareBuilder.java   |   89 -----
 .../provisionr/api/util/BuilderWithOptions.java    |   89 -----
 .../axemblr/provisionr/api/util/WithOptions.java   |   44 ---
 .../java/org/apache/provisionr/api/Provisionr.java |   75 +++++
 .../apache/provisionr/api/access/AdminAccess.java  |   88 +++++
 .../provisionr/api/access/AdminAccessBuilder.java  |   67 ++++
 .../provisionr/api/hardware/BlockDevice.java       |   77 +++++
 .../api/hardware/BlockDeviceBuilder.java           |   33 ++
 .../apache/provisionr/api/hardware/Hardware.java   |   82 +++++
 .../provisionr/api/hardware/HardwareBuilder.java   |   56 ++++
 .../org/apache/provisionr/api/network/Network.java |   84 +++++
 .../provisionr/api/network/NetworkBuilder.java     |   57 ++++
 .../apache/provisionr/api/network/Protocol.java    |   23 ++
 .../org/apache/provisionr/api/network/Rule.java    |   84 +++++
 .../apache/provisionr/api/network/RuleBuilder.java |   79 +++++
 .../org/apache/provisionr/api/pool/Machine.java    |  164 +++++++++
 .../apache/provisionr/api/pool/MachineBuilder.java |   76 +++++
 .../java/org/apache/provisionr/api/pool/Pool.java  |  146 ++++++++
 .../apache/provisionr/api/pool/PoolBuilder.java    |   94 ++++++
 .../apache/provisionr/api/provider/Provider.java   |  109 ++++++
 .../provisionr/api/provider/ProviderBuilder.java   |   63 ++++
 .../apache/provisionr/api/software/Repository.java |   95 ++++++
 .../provisionr/api/software/RepositoryBuilder.java |   59 ++++
 .../apache/provisionr/api/software/Software.java   |  124 +++++++
 .../provisionr/api/software/SoftwareBuilder.java   |   89 +++++
 .../provisionr/api/util/BuilderWithOptions.java    |   89 +++++
 .../apache/provisionr/api/util/WithOptions.java    |   44 +++
 .../axemblr/provisionr/api/AssertSerializable.java |   54 ---
 .../provisionr/api/access/AdminAccessTest.java     |   35 --
 .../provisionr/api/network/NetworkTest.java        |   42 ---
 .../axemblr/provisionr/api/network/RuleTest.java   |   31 --
 .../axemblr/provisionr/api/pool/MachineTest.java   |   42 ---
 .../com/axemblr/provisionr/api/pool/PoolTest.java  |   67 ----
 .../provisionr/api/provider/ProviderTest.java      |   38 ---
 .../provisionr/api/software/RepositoryTest.java    |   39 ---
 .../provisionr/api/software/SoftwareTest.java      |   49 ---
 .../api/util/BuilderWithOptionsTest.java           |   59 ----
 .../apache/provisionr/api/AssertSerializable.java  |   54 +++
 .../provisionr/api/access/AdminAccessTest.java     |   35 ++
 .../apache/provisionr/api/network/NetworkTest.java |   42 +++
 .../apache/provisionr/api/network/RuleTest.java    |   31 ++
 .../apache/provisionr/api/pool/MachineTest.java    |   42 +++
 .../org/apache/provisionr/api/pool/PoolTest.java   |   67 ++++
 .../provisionr/api/provider/ProviderTest.java      |   38 +++
 .../provisionr/api/software/RepositoryTest.java    |   39 +++
 .../provisionr/api/software/SoftwareTest.java      |   49 +++
 .../api/util/BuilderWithOptionsTest.java           |   59 ++++
 console/pom.xml                                    |   15 +-
 .../provisionr/client/ProvisionrClient.java        |   34 --
 .../apache/provisionr/client/ProvisionrClient.java |   34 ++
 .../main/resources/OSGI-INF/blueprint/context.xml  |    6 +-
 .../resources/com.axemblr.provisionr.console.cfg   |    5 -
 console/src/main/resources/features.xml            |   14 +-
 .../resources/org.apache.provisionr.console.cfg    |    5 +
 core/pom.xml                                       |   20 +-
 .../com/axemblr/provisionr/core/CoreConstants.java |   10 -
 .../provisionr/core/CoreProcessVariables.java      |   70 ----
 .../com/axemblr/provisionr/core/CoreSignals.java   |   29 --
 .../java/com/axemblr/provisionr/core/Mustache.java |   58 ----
 .../com/axemblr/provisionr/core/PoolStatus.java    |   34 --
 .../axemblr/provisionr/core/ProvisionrSupport.java |   95 ------
 .../main/java/com/axemblr/provisionr/core/Ssh.java |  145 --------
 .../ConfigurableFailedJobCommandFactory.java       |  153 ---------
 .../core/activiti/ConfigurationFactory.java        |   68 ----
 .../core/activities/CheckProcessesEnded.java       |   76 -----
 .../provisionr/core/activities/DownloadFiles.java  |   53 ---
 .../core/activities/InstallPackages.java           |   50 ---
 .../core/activities/InstallRepositories.java       |   62 ----
 .../core/activities/IsMachinePortOpen.java         |   90 -----
 .../core/activities/KillMachineSetUpProcesses.java |   65 ----
 .../provisionr/core/activities/PuppetActivity.java |  131 --------
 .../activities/SpawnProcessForEachMachine.java     |   96 ------
 .../provisionr/core/logging/ErrorStreamLogger.java |   33 --
 .../provisionr/core/logging/InfoStreamLogger.java  |   33 --
 .../provisionr/core/logging/StreamLogger.java      |   67 ----
 .../provisionr/core/templates/PoolTemplate.java    |   38 ---
 .../core/templates/PoolTemplateInstaller.java      |  109 ------
 .../provisionr/core/templates/xml/FileEntry.java   |   91 -----
 .../core/templates/xml/RepositoryEntry.java        |  114 -------
 .../provisionr/core/templates/xml/XmlTemplate.java |  257 ---------------
 .../org/apache/provisionr/core/CoreConstants.java  |   10 +
 .../provisionr/core/CoreProcessVariables.java      |   70 ++++
 .../org/apache/provisionr/core/CoreSignals.java    |   29 ++
 .../java/org/apache/provisionr/core/Mustache.java  |   58 ++++
 .../org/apache/provisionr/core/PoolStatus.java     |   34 ++
 .../apache/provisionr/core/ProvisionrSupport.java  |   95 ++++++
 .../main/java/org/apache/provisionr/core/Ssh.java  |  145 ++++++++
 .../ConfigurableFailedJobCommandFactory.java       |  153 +++++++++
 .../core/activiti/ConfigurationFactory.java        |   68 ++++
 .../core/activities/CheckProcessesEnded.java       |   76 +++++
 .../provisionr/core/activities/DownloadFiles.java  |   53 +++
 .../core/activities/InstallPackages.java           |   50 +++
 .../core/activities/InstallRepositories.java       |   62 ++++
 .../core/activities/IsMachinePortOpen.java         |   90 +++++
 .../core/activities/KillMachineSetUpProcesses.java |   65 ++++
 .../provisionr/core/activities/PuppetActivity.java |  131 ++++++++
 .../activities/SpawnProcessForEachMachine.java     |   96 ++++++
 .../provisionr/core/logging/ErrorStreamLogger.java |   33 ++
 .../provisionr/core/logging/InfoStreamLogger.java  |   33 ++
 .../provisionr/core/logging/StreamLogger.java      |   67 ++++
 .../provisionr/core/templates/PoolTemplate.java    |   38 +++
 .../core/templates/PoolTemplateInstaller.java      |  109 ++++++
 .../provisionr/core/templates/xml/FileEntry.java   |   91 +++++
 .../core/templates/xml/RepositoryEntry.java        |  114 +++++++
 .../provisionr/core/templates/xml/XmlTemplate.java |  257 +++++++++++++++
 .../main/resources/OSGI-INF/blueprint/context.xml  |   18 +-
 core/src/main/resources/com.axemblr.provisionr.cfg |   37 --
 .../provisionr/core/puppet/files.pp.mustache       |   25 --
 .../provisionr/core/puppet/packages.pp.mustache    |    7 -
 .../core/puppet/repositories.pp.mustache           |   38 ---
 .../com/axemblr/provisionr/core/templates/cdh3.xml |  108 ------
 .../com/axemblr/provisionr/core/templates/cdh4.xml |   59 ----
 .../axemblr/provisionr/core/templates/jenkins.xml  |  132 --------
 core/src/main/resources/features.xml               |   24 +-
 core/src/main/resources/org.apache.provisionr.cfg  |   37 ++
 .../provisionr/core/puppet/files.pp.mustache       |   25 ++
 .../provisionr/core/puppet/packages.pp.mustache    |    7 +
 .../core/puppet/repositories.pp.mustache           |   38 +++
 .../org/apache/provisionr/core/templates/cdh3.xml  |  108 ++++++
 .../org/apache/provisionr/core/templates/cdh4.xml  |   59 ++++
 .../apache/provisionr/core/templates/jenkins.xml   |  132 ++++++++
 .../com/axemblr/provisionr/core/BaseJaxbTest.java  |   57 ----
 .../provisionr/core/ProvisionrSupportTest.java     |   32 --
 .../com/axemblr/provisionr/core/SshLiveTest.java   |  131 --------
 .../provisionr/core/activiti/AlwaysFailTask.java   |   37 --
 .../ConfigurableFailedJobCommandFactoryTest.java   |   60 ----
 .../core/activities/CheckProcessesEndedTest.java   |   98 ------
 .../core/activities/CheckProcessesTest.java        |   56 ----
 .../core/activities/DownloadFilesTest.java         |   51 ---
 .../core/activities/InstallPackagesTest.java       |   44 ---
 .../core/activities/InstallRepositoriesTest.java   |   52 ---
 .../core/activities/IsMachinePortOpenTest.java     |   88 -----
 .../activities/KillMachineSetUpProcessesTest.java  |   93 ------
 .../activities/SpawnProcessForEachMachineTest.java |   86 -----
 .../provisionr/core/logging/StreamLoggerTest.java  |   55 ---
 .../core/templates/PoolTemplateInstallerTest.java  |   61 ----
 .../core/templates/xml/XmlTemplateTest.java        |  106 ------
 .../org/apache/provisionr/core/BaseJaxbTest.java   |   57 ++++
 .../provisionr/core/ProvisionrSupportTest.java     |   32 ++
 .../org/apache/provisionr/core/SshLiveTest.java    |  131 ++++++++
 .../provisionr/core/activiti/AlwaysFailTask.java   |   37 ++
 .../ConfigurableFailedJobCommandFactoryTest.java   |   60 ++++
 .../core/activities/CheckProcessesEndedTest.java   |   95 ++++++
 .../core/activities/CheckProcessesTest.java        |   56 ++++
 .../core/activities/DownloadFilesTest.java         |   51 +++
 .../core/activities/InstallPackagesTest.java       |   46 +++
 .../core/activities/InstallRepositoriesTest.java   |   54 +++
 .../core/activities/IsMachinePortOpenTest.java     |   88 +++++
 .../activities/KillMachineSetUpProcessesTest.java  |   93 ++++++
 .../activities/SpawnProcessForEachMachineTest.java |   86 +++++
 .../provisionr/core/logging/StreamLoggerTest.java  |   56 ++++
 .../core/templates/PoolTemplateInstallerTest.java  |   63 ++++
 .../core/templates/xml/XmlTemplateTest.java        |  106 ++++++
 .../test/resources/diagrams/alwaysFail.bpmn20.xml  |    2 +-
 ...ols of Virtual Machines - ApacheCon NA 2013.pdf |  Bin 456683 -> 0 bytes
 docs/icla.pdf                                      |  Bin 48313 -> 0 bytes
 integration/rundeck/pom.xml                        |    8 +-
 .../com/axemblr/provisionr/rundeck/Attribute.java  |   86 -----
 .../java/com/axemblr/provisionr/rundeck/Node.java  |  169 ----------
 .../com/axemblr/provisionr/rundeck/Project.java    |   78 -----
 .../axemblr/provisionr/rundeck/RundeckServlet.java |  128 -------
 .../org/apache/provisionr/rundeck/Attribute.java   |   86 +++++
 .../java/org/apache/provisionr/rundeck/Node.java   |  169 ++++++++++
 .../org/apache/provisionr/rundeck/Project.java     |   78 +++++
 .../apache/provisionr/rundeck/RundeckServlet.java  |  128 +++++++
 .../main/resources/OSGI-INF/blueprint/context.xml  |    2 +-
 .../rundeck/src/main/resources/features.xml        |   10 +-
 .../axemblr/provisionr/rundeck/BaseJaxbTest.java   |   57 ----
 .../axemblr/provisionr/rundeck/ProjectTest.java    |   60 ----
 .../provisionr/rundeck/RundeckServletTest.java     |   62 ----
 .../apache/provisionr/rundeck/BaseJaxbTest.java    |   57 ++++
 .../org/apache/provisionr/rundeck/ProjectTest.java |   60 ++++
 .../provisionr/rundeck/RundeckServletTest.java     |   62 ++++
 karaf/assembly-tests/pom.xml                       |   10 +-
 .../karaf/CustomKarafDistributionTest.java         |  248 --------------
 .../karaf/CustomKarafDistributionTest.java         |  248 ++++++++++++++
 karaf/assembly/pom.xml                             |   16 +-
 karaf/assembly/src/main/assembly/unix.xml          |    2 +-
 .../etc/org.apache.karaf.features.cfg              |    4 +-
 karaf/branding/pom.xml                             |    7 +-
 .../org/apache/karaf/branding/branding.properties  |   22 +-
 karaf/commands/pom.xml                             |   13 +-
 .../axemblr/provisionr/commands/CreateCommand.java |  130 --------
 .../provisionr/commands/CreateImageCommand.java    |   61 ----
 .../provisionr/commands/CreatePoolCommand.java     |  197 -----------
 .../provisionr/commands/DestroyPoolCommand.java    |   75 -----
 .../provisionr/commands/ListPoolsCommand.java      |  109 ------
 .../provisionr/commands/ListServicesCommand.java   |   54 ---
 .../provisionr/commands/ListTemplatesCommand.java  |   54 ---
 .../provisionr/commands/ResetRetriesCommand.java   |   81 -----
 .../commands/predicates/ProvisionrPredicates.java  |   41 ---
 .../apache/provisionr/commands/CreateCommand.java  |  126 +++++++
 .../provisionr/commands/CreateImageCommand.java    |   52 +++
 .../provisionr/commands/CreatePoolCommand.java     |  181 ++++++++++
 .../provisionr/commands/DestroyPoolCommand.java    |   75 +++++
 .../provisionr/commands/ListPoolsCommand.java      |  109 ++++++
 .../provisionr/commands/ListServicesCommand.java   |   54 +++
 .../provisionr/commands/ListTemplatesCommand.java  |   54 +++
 .../provisionr/commands/ResetRetriesCommand.java   |   81 +++++
 .../commands/predicates/ProvisionrPredicates.java  |   41 +++
 .../main/resources/OSGI-INF/blueprint/context.xml  |   16 +-
 .../provisionr/commands/CreatePoolCommandTest.java |  210 ------------
 .../commands/DestroyPoolCommandTest.java           |   87 -----
 .../provisionr/commands/ListPoolsCommandTest.java  |  156 ---------
 .../commands/ListServicesCommandTest.java          |   62 ----
 .../commands/ListTemplatesCommandTest.java         |   77 -----
 .../commands/ResetRetriesCommandTest.java          |   96 ------
 .../provisionr/commands/CreatePoolCommandTest.java |  207 ++++++++++++
 .../commands/DestroyPoolCommandTest.java           |   87 +++++
 .../provisionr/commands/ListPoolsCommandTest.java  |  156 +++++++++
 .../commands/ListServicesCommandTest.java          |   62 ++++
 .../commands/ListTemplatesCommandTest.java         |   77 +++++
 .../commands/ResetRetriesCommandTest.java          |   96 ++++++
 karaf/features/pom.xml                             |   23 +-
 karaf/features/src/main/resources/features.xml     |   50 ++--
 parent/pom.xml                                     |  116 +++++--
 pom.xml                                            |    7 +-
 providers/amazon-tests/pom.xml                     |   15 +-
 .../amazon/AmazonProvisionrLiveTest.java           |  207 ------------
 .../amazon/AmazonProvisionrLiveTest.java           |  207 ++++++++++++
 providers/amazon/pom.xml                           |   17 +-
 .../provisionr/amazon/AmazonProvisionr.java        |  127 -------
 .../provisionr/amazon/ProcessVariables.java        |  107 ------
 .../activities/AllInstancesMatchPredicate.java     |   91 -----
 .../activities/AllSpotRequestsMatchPredicate.java  |   77 -----
 .../amazon/activities/AmazonActivity.java          |   75 -----
 .../amazon/activities/CancelSpotRequests.java      |   37 --
 .../activities/CheckAllInstancesAreRunning.java    |   41 ---
 .../activities/CheckAllInstancesAreTerminated.java |   41 ---
 .../activities/CheckAllRequestsAreActive.java      |   35 --
 .../amazon/activities/CheckNoRequestsAreOpen.java  |   26 --
 .../amazon/activities/DeleteKeyPair.java           |   43 ---
 .../amazon/activities/DeleteSecurityGroup.java     |   57 ----
 .../amazon/activities/DumpConsoleOutput.java       |   55 ---
 .../amazon/activities/EnsureKeyPairExists.java     |   66 ----
 .../activities/EnsureSecurityGroupExists.java      |  112 -------
 .../activities/GetInstanceIdsFromSpotRequests.java |   44 ---
 .../amazon/activities/PublishListOfMachines.java   |   83 -----
 .../provisionr/amazon/activities/RunInstances.java |  148 ---------
 .../amazon/activities/RunOnDemandInstances.java    |   76 -----
 .../amazon/activities/RunSpotInstances.java        |  100 ------
 .../amazon/activities/SetupAdminAccess.java        |   71 ----
 .../amazon/activities/TerminateInstances.java      |   56 ----
 .../amazon/config/DefaultProviderConfig.java       |   60 ----
 .../axemblr/provisionr/amazon/core/ErrorCodes.java |   33 --
 .../axemblr/provisionr/amazon/core/ImageTable.java |  143 --------
 .../provisionr/amazon/core/ImageTableQuery.java    |   87 -----
 .../axemblr/provisionr/amazon/core/KeyPairs.java   |   28 --
 .../amazon/core/ProviderClientCache.java           |   28 --
 .../amazon/core/ProviderClientCacheSupplier.java   |  114 -------
 .../provisionr/amazon/core/SecurityGroups.java     |   29 --
 .../functions/ConvertIpPermissionToRule.java       |   40 ---
 .../functions/ConvertRuleToIpPermission.java       |   40 ---
 .../provisionr/amazon/options/ProviderOptions.java |   31 --
 .../provisionr/amazon/options/SoftwareOptions.java |   30 --
 .../apache/provisionr/amazon/AmazonProvisionr.java |  127 +++++++
 .../apache/provisionr/amazon/ProcessVariables.java |  107 ++++++
 .../activities/AllInstancesMatchPredicate.java     |   91 +++++
 .../activities/AllSpotRequestsMatchPredicate.java  |   75 +++++
 .../amazon/activities/AmazonActivity.java          |   73 ++++
 .../amazon/activities/CancelSpotRequests.java      |   36 ++
 .../activities/CheckAllInstancesAreRunning.java    |   41 +++
 .../activities/CheckAllInstancesAreTerminated.java |   41 +++
 .../activities/CheckAllRequestsAreActive.java      |   35 ++
 .../amazon/activities/CheckNoRequestsAreOpen.java  |   26 ++
 .../amazon/activities/DeleteKeyPair.java           |   43 +++
 .../amazon/activities/DeleteSecurityGroup.java     |   55 +++
 .../amazon/activities/DumpConsoleOutput.java       |   55 +++
 .../amazon/activities/EnsureKeyPairExists.java     |   64 ++++
 .../activities/EnsureSecurityGroupExists.java      |  110 ++++++
 .../activities/GetInstanceIdsFromSpotRequests.java |   44 +++
 .../amazon/activities/PublishListOfMachines.java   |   80 +++++
 .../provisionr/amazon/activities/RunInstances.java |  144 ++++++++
 .../amazon/activities/RunOnDemandInstances.java    |   76 +++++
 .../amazon/activities/RunSpotInstances.java        |  100 ++++++
 .../amazon/activities/SetupAdminAccess.java        |   71 ++++
 .../amazon/activities/TerminateInstances.java      |   56 ++++
 .../amazon/config/DefaultProviderConfig.java       |   60 ++++
 .../apache/provisionr/amazon/core/ErrorCodes.java  |   33 ++
 .../apache/provisionr/amazon/core/ImageTable.java  |  143 ++++++++
 .../provisionr/amazon/core/ImageTableQuery.java    |   87 +++++
 .../apache/provisionr/amazon/core/KeyPairs.java    |   28 ++
 .../amazon/core/ProviderClientCache.java           |   28 ++
 .../amazon/core/ProviderClientCacheSupplier.java   |  114 +++++++
 .../provisionr/amazon/core/SecurityGroups.java     |   29 ++
 .../functions/ConvertIpPermissionToRule.java       |   40 +++
 .../functions/ConvertRuleToIpPermission.java       |   40 +++
 .../provisionr/amazon/options/ProviderOptions.java |   29 ++
 .../provisionr/amazon/options/SoftwareOptions.java |   30 ++
 .../main/resources/OSGI-INF/blueprint/context.xml  |   48 ++--
 .../resources/com.axemblr.provisionr.amazon.cfg    |    7 -
 .../resources/com/axemblr/provisionr/amazon/README |    3 -
 .../amazon/puppet/adminaccess.pp.mustache          |   62 ----
 .../provisionr/amazon/puppet/sshd_config.mustache  |   83 -----
 .../com/axemblr/provisionr/amazon/puppet/sudoers   |   28 --
 .../com/axemblr/provisionr/amazon/ubuntu.csv       |  221 -------------
 .../com/axemblr/provisionr/amazon/userdata.sh      |   16 -
 providers/amazon/src/main/resources/features.xml   |   14 +-
 .../resources/org.apache.provisionr.amazon.cfg     |    7 +
 .../resources/org/apache/provisionr/amazon/README  |    3 +
 .../amazon/puppet/adminaccess.pp.mustache          |   62 ++++
 .../provisionr/amazon/puppet/sshd_config.mustache  |   83 +++++
 .../org/apache/provisionr/amazon/puppet/sudoers    |   28 ++
 .../org/apache/provisionr/amazon/ubuntu.csv        |  221 +++++++++++++
 .../org/apache/provisionr/amazon/userdata.sh       |   16 +
 .../amazon/ProcessDefinitionSyntaxCheckTest.java   |   54 ---
 .../amazon/activities/AmazonActivityLiveTest.java  |  132 --------
 .../amazon/activities/CreatePoolLiveTest.java      |   75 -----
 .../amazon/activities/DeleteKeyPairLiveTest.java   |   89 -----
 .../activities/DeleteSecurityGroupLiveTest.java    |   73 ----
 .../activities/EnsureKeyPairExistsLiveTest.java    |   80 -----
 .../EnsureSecurityGroupExistsLiveTest.java         |  130 --------
 .../activities/PublishListOfMachinesTest.java      |   73 ----
 .../activities/RunOnDemandInstancesLiveTest.java   |  144 --------
 .../activities/RunSpotInstancesLiveTest.java       |  112 -------
 .../amazon/activities/SetupAdminAccessTest.java    |   52 ---
 .../activities/TerminateInstancesLiveTest.java     |   77 -----
 .../amazon/config/DefaultProviderConfigTest.java   |   42 ---
 .../amazon/core/ImageTableQueryTest.java           |   34 --
 .../provisionr/amazon/core/ImageTableTest.java     |   66 ----
 .../ConvertIpPermissionToRuleAndBackTest.java      |   60 ----
 .../amazon/ProcessDefinitionSyntaxCheckTest.java   |   54 +++
 .../amazon/activities/AmazonActivityLiveTest.java  |  132 ++++++++
 .../amazon/activities/CreatePoolLiveTest.java      |   72 ++++
 .../amazon/activities/DeleteKeyPairLiveTest.java   |   88 +++++
 .../activities/DeleteSecurityGroupLiveTest.java    |   66 ++++
 .../activities/EnsureKeyPairExistsLiveTest.java    |   79 +++++
 .../EnsureSecurityGroupExistsLiveTest.java         |  129 ++++++++
 .../activities/PublishListOfMachinesTest.java      |   73 ++++
 .../activities/RunOnDemandInstancesLiveTest.java   |  144 ++++++++
 .../activities/RunSpotInstancesLiveTest.java       |  107 ++++++
 .../amazon/activities/SetupAdminAccessTest.java    |   52 +++
 .../activities/TerminateInstancesLiveTest.java     |   68 ++++
 .../amazon/config/DefaultProviderConfigTest.java   |   42 +++
 .../amazon/core/ImageTableQueryTest.java           |   34 ++
 .../provisionr/amazon/core/ImageTableTest.java     |   66 ++++
 .../ConvertIpPermissionToRuleAndBackTest.java      |   60 ++++
 providers/cloudstack-tests/pom.xml                 |   17 +-
 .../cloudstack/CloudStackProvisionrLiveTest.java   |  105 ------
 .../cloudstack/CloudStackProvisionrLiveTest.java   |  105 ++++++
 providers/cloudstack/pom.xml                       |   17 +-
 .../cloudstack/CloudStackProvisionr.java           |   92 -----
 .../cloudstack/DefaultProviderConfig.java          |   57 ----
 .../provisionr/cloudstack/NetworkOptions.java      |   33 --
 .../provisionr/cloudstack/ProcessVariables.java    |   26 --
 .../provisionr/cloudstack/ProviderOptions.java     |   37 --
 .../cloudstack/activities/CloudStackActivity.java  |   82 -----
 .../cloudstack/activities/DeleteKeyPair.java       |   36 --
 .../cloudstack/activities/DeleteSecurityGroup.java |   35 --
 .../cloudstack/activities/EnsureKeyPairExists.java |   53 ---
 .../cloudstack/activities/EnsureNetworkExists.java |   64 ----
 .../activities/EnsureSecurityGroupExists.java      |   56 ----
 .../cloudstack/activities/RunInstances.java        |   58 ----
 .../cloudstack/commands/CommandSupport.java        |   76 -----
 .../cloudstack/commands/OfferingsCommand.java      |  107 ------
 .../cloudstack/commands/TemplatesCommand.java      |   45 ---
 .../cloudstack/commands/ZonesCommand.java          |   44 ---
 .../cloudstack/core/ConvertIngressRuleToRule.java  |   46 ---
 .../provisionr/cloudstack/core/KeyPairs.java       |   28 --
 .../provisionr/cloudstack/core/Networks.java       |   51 ---
 .../provisionr/cloudstack/core/SecurityGroups.java |   99 ------
 .../cloudstack/core/VirtualMachines.java           |  107 ------
 .../axemblr/provisionr/cloudstack/core/Zones.java  |   40 ---
 .../cloudstack/CloudStackProvisionr.java           |   92 +++++
 .../cloudstack/DefaultProviderConfig.java          |   57 ++++
 .../provisionr/cloudstack/NetworkOptions.java      |   33 ++
 .../provisionr/cloudstack/ProcessVariables.java    |   26 ++
 .../provisionr/cloudstack/ProviderOptions.java     |   37 ++
 .../cloudstack/activities/CloudStackActivity.java  |   82 +++++
 .../cloudstack/activities/DeleteKeyPair.java       |   36 ++
 .../cloudstack/activities/DeleteSecurityGroup.java |   35 ++
 .../cloudstack/activities/EnsureKeyPairExists.java |   53 +++
 .../cloudstack/activities/EnsureNetworkExists.java |   64 ++++
 .../activities/EnsureSecurityGroupExists.java      |   56 ++++
 .../cloudstack/activities/RunInstances.java        |   58 ++++
 .../cloudstack/commands/CommandSupport.java        |   76 +++++
 .../cloudstack/commands/OfferingsCommand.java      |  107 ++++++
 .../cloudstack/commands/TemplatesCommand.java      |   45 +++
 .../cloudstack/commands/ZonesCommand.java          |   44 +++
 .../cloudstack/core/ConvertIngressRuleToRule.java  |   46 +++
 .../provisionr/cloudstack/core/KeyPairs.java       |   28 ++
 .../provisionr/cloudstack/core/Networks.java       |   51 +++
 .../provisionr/cloudstack/core/SecurityGroups.java |   99 ++++++
 .../cloudstack/core/VirtualMachines.java           |  107 ++++++
 .../apache/provisionr/cloudstack/core/Zones.java   |   40 +++
 .../main/resources/OSGI-INF/blueprint/context.xml  |   22 +-
 .../com.axemblr.provisionr.cloudstack.cfg          |   10 -
 .../cloudstack/src/main/resources/features.xml     |   14 +-
 .../resources/org.apache.provisionr.cloudstack.cfg |   10 +
 .../activities/CloudStackActivityLiveTest.java     |  129 --------
 .../activities/DeleteKeyPairLiveTest.java          |   77 -----
 .../activities/DeleteSecurityGroupLiveTest.java    |   78 -----
 .../activities/EnsureKeyPairExistsLiveTest.java    |   83 -----
 .../activities/EnsureNetworkExistsLiveTest.java    |  123 -------
 .../EnsureSecurityGroupExistsLiveTest.java         |  127 -------
 .../activities/RunInstancesLiveTest.java           |  107 ------
 .../cloudstack/commands/CommandTestSupport.java    |   47 ---
 .../cloudstack/commands/OfferingsCommandTest.java  |   98 ------
 .../cloudstack/commands/TemplatesCommandTest.java  |   47 ---
 .../cloudstack/commands/ZonesCommandTest.java      |   53 ---
 .../cloudstack/core/ConversionsTest.java           |   58 ----
 .../cloudstack/core/SecurityGroupsTest.java        |   29 --
 .../activities/CloudStackActivityLiveTest.java     |  129 ++++++++
 .../activities/DeleteKeyPairLiveTest.java          |   77 +++++
 .../activities/DeleteSecurityGroupLiveTest.java    |   77 +++++
 .../activities/EnsureKeyPairExistsLiveTest.java    |   82 +++++
 .../activities/EnsureNetworkExistsLiveTest.java    |  123 +++++++
 .../EnsureSecurityGroupExistsLiveTest.java         |  127 +++++++
 .../activities/RunInstancesLiveTest.java           |  107 ++++++
 .../cloudstack/commands/CommandTestSupport.java    |   47 +++
 .../cloudstack/commands/OfferingsCommandTest.java  |   98 ++++++
 .../cloudstack/commands/TemplatesCommandTest.java  |   47 +++
 .../cloudstack/commands/ZonesCommandTest.java      |   53 +++
 .../cloudstack/core/ConversionsTest.java           |   58 ++++
 .../cloudstack/core/SecurityGroupsTest.java        |   28 ++
 .../cloudstack/src/test/resources/logback.xml      |    2 +-
 scripts/deploy.sh                                  |    4 +-
 test-support/pom.xml                               |   10 +-
 .../java/com/axemblr/provisionr/test/Generics.java |   75 -----
 .../com/axemblr/provisionr/test/KarafTests.java    |  117 -------
 .../provisionr/test/ProcessVariablesCollector.java |   64 ----
 .../provisionr/test/ProvisionrLiveTestSupport.java |  153 ---------
 .../com/axemblr/provisionr/test/TestConstants.java |   39 ---
 .../java/org/apache/provisionr/test/Generics.java  |   75 +++++
 .../org/apache/provisionr/test/KarafTests.java     |  117 +++++++
 .../provisionr/test/ProcessVariablesCollector.java |   64 ++++
 .../provisionr/test/ProvisionrLiveTestSupport.java |  153 +++++++++
 .../org/apache/provisionr/test/TestConstants.java  |   39 +++
 .../com/axemblr/provisionr/test/id_rsa_test        |   27 --
 .../com/axemblr/provisionr/test/id_rsa_test.pub    |    1 -
 test-support/src/main/resources/features.xml       |    2 +-
 .../org/apache/provisionr/test/id_rsa_test         |   27 ++
 .../org/apache/provisionr/test/id_rsa_test.pub     |    1 +
 505 files changed, 17877 insertions(+), 17919 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 76b06ef..67e88a6 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-Axemblr Provisionr [![Build Status](https://buildhive.cloudbees.com/job/axemblr/job/axemblr-provisionr/badge/icon)](https://buildhive.cloudbees.com/job/axemblr/job/axemblr-provisionr/)
-==================
+Apache Provisionr
+=================
 
 *Simple Service for Managing Pools of 10s or 100s of Virtual Machines*
 
@@ -29,33 +29,12 @@ You can use Activiti Explorer to inspect the process while running:
 
 ![Shell](http://people.apache.org/~asavu/shell.png)
 
-Who is behind this?
--------------------
-
-Core developers:
-
-* Andrei Savu - [LinkedIn](http://www.linkedin.com/in/sandrei), [Github](https://github.com/andreisavu)
-* Ioan Eugen Stan - [LinkedIn](http://www.linkedin.com/in/ieugen), [Github](https://github.com/ieugen)
-* Alex Ciminian - [LinkedIn](http://www.linkedin.com/in/alexciminian), [GitHub](https://github.com/cimi)
-
 License
 -------
 
 Apache License Version 2.0
 http://apache.org/licenses/LICENSE-2.0.txt
 
-Get involved in the community 
------------------------------
-
-For those of you who really dig our software, we have created two mailing lists that yo can join depending on your involvement: 
-
-* If you are a user join: [provisionr-users@googlegroups.com](https://groups.google.com/forum/?fromgroups#!forum/provisionr-users)
-* If you wish to develop Provisionr go to [provisionr-dev@googlegroups.com](https://groups.google.com/forum/?fromgroups#!forum/provisionr-dev)
-
-Join us on IRC channel *#axemblr* on *irc.freenode.net*.
-
-We appreciate any kind of help so don't hesitate.
-
 
 Supported cloud providers
 -------------------------
@@ -71,7 +50,7 @@ You can build a binary release by running:
 
 And you will find the .tar.gz file in:
 
-    karaf/assembly/target/com.axemblr.provisionr-*.tar.gz
+    karaf/assembly/target/org.apache.provisionr-*.tar.gz
 
 How to run?
 -----------
@@ -79,23 +58,23 @@ How to run?
 Extract the custom Karaf distribution:
 
     $ cd karaf/assembly/target/
-    $ tar xvfz com.axemblr.provisionr-0.0.1-SNAPSHOT.tar.gz
-    $ cd com.axemblr.provisionr-0.0.1-SNAPSHOT
+    $ tar xvfz org.apache.provisionr-0.0.1-SNAPSHOT.tar.gz
+    $ cd org.apache.provisionr-0.0.1-SNAPSHOT
 
 Start and configure the Amazon provisionr:
 
     $ ./bin/provisionr
-    provisionr [0.0.1-SNAPSHOT] $ config:edit com.axemblr.provisionr.amazon
+    provisionr [0.0.1-SNAPSHOT] $ config:edit org.apache.provisionr.amazon
     provisionr [0.0.1-SNAPSHOT] $ config:proplist
-        service.pid = com.axemblr.provisionr.amazon
+        service.pid = org.apache.provisionr.amazon
         secretKey = secret
-        felix.fileinstall.filename = file:[...]/etc/com.axemblr.provisionr.amazon.cfg
+        felix.fileinstall.filename = file:[...]/etc/org.apache.provisionr.amazon.cfg
         region = us-east-1
         accessKey = access
     provisionr [0.0.1-SNAPSHOT] $ config:propset accessKey "XXXXXXX"
     provisionr [0.0.1-SNAPSHOT] $ config:propset secretKey "XXXXXXX"
     provisionr [0.0.1-SNAPSHOT] $ config:update
-    provisionr [0.0.1-SNAPSHOT] $ config:list "(service.pid=com.axemblr.provisionr.amazon)"
+    provisionr [0.0.1-SNAPSHOT] $ config:list "(service.pid=org.apache.provisionr.amazon)"
 
 Create a pool:
 
@@ -116,8 +95,8 @@ You should see an Activiti process in execution:
     BPMN Deployments
     ----------------
      ID   Name                               Deployment Time         
-    [1  ][com.axemblr.provisionr.amazon    ][Dec 13, 2012 1:52:05 PM]
-    [5  ][com.axemblr.provisionr.cloudstack][Dec 13, 2012 1:52:07 PM]
+    [1  ][org.apache.provisionr.amazon    ][Dec 13, 2012 1:52:05 PM]
+    [5  ][org.apache.provisionr.cloudstack][Dec 13, 2012 1:52:07 PM]
 
     BPMN Process Definitions
     -------------------------

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/pom.xml
----------------------------------------------------------------------
diff --git a/activiti/commands/pom.xml b/activiti/commands/pom.xml
index 490d4ab..a24cb49 100644
--- a/activiti/commands/pom.xml
+++ b/activiti/commands/pom.xml
@@ -21,17 +21,17 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <artifactId>provisionr-parent</artifactId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
 
-    <groupId>org.activiti.karaf</groupId>
     <artifactId>activiti-karaf-commands</artifactId>
     <packaging>bundle</packaging>
 
-    <name>Activiti Karaf :: Commands</name>
+    <name>Apache Provisionr :: Activiti Karaf :: Commands</name>
+    <description>Apache Karaf commands for the Activiti process engine</description>
     <url>http://activiti.org</url>
 
     <properties>
@@ -161,8 +161,8 @@
                     <outputDirectory>${basedir}/target/classes</outputDirectory>
                     <instructions>
                         <Export-Package>
-                            org.activiti.karaf.commands,
-                            org.activiti.karaf.commands.handlers,
+                            org.apache.provisionr.activiti.karaf.commands,
+                            org.apache.provisionr.activiti.karaf.commandsiti.karaf.commands.haorg.apache.provisionr.activiti.karaf.commands
                             org.activiti.karaf.commands.util
                         </Export-Package>
                         <Import-Package>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/ActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/ActivitiCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/ActivitiCommand.java
deleted file mode 100644
index ef800a7..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/ActivitiCommand.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-package org.activiti.karaf.commands;
-
-import java.io.PrintWriter;
-import org.activiti.engine.ProcessEngine;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
-
-/**
- * Base class for implementing Activiti Karaf commands
- *
- * @author Srinivasan Chikkala
- */
-public abstract class ActivitiCommand extends OsgiCommandSupport {
-
-    /**
-     * By default write normal messages to stdout
-     */
-    private PrintWriter out = new PrintWriter(System.out, true);
-
-    /**
-     * By default write error messages to stderr
-     */
-    private PrintWriter err = new PrintWriter(System.err, true);
-
-    private ProcessEngine processEngine;
-
-    public ProcessEngine getProcessEngine() {
-        return processEngine;
-    }
-
-    public void setProcessEngine(ProcessEngine processEngine) {
-        this.processEngine = processEngine;
-    }
-
-    public PrintWriter out() {
-        return out;
-    }
-
-    public void setOut(PrintWriter out) {
-        this.out = out;
-    }
-
-    public PrintWriter err() {
-        return err;
-    }
-
-    public void setErr(PrintWriter err) {
-        this.err = err;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/AddGroupCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/AddGroupCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/AddGroupCommand.java
deleted file mode 100644
index 97f0237..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/AddGroupCommand.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import com.google.common.annotations.VisibleForTesting;
-import static com.google.common.base.Preconditions.checkNotNull;
-import org.activiti.engine.IdentityService;
-import org.activiti.engine.identity.Group;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-@Command(scope = "activiti", name = "add-group", description = "Create new user group")
-public class AddGroupCommand extends ActivitiCommand {
-
-    @Option(name = "-i", aliases = "--id", description = "Group ID", required = true)
-    private String id;
-
-    @Option(name = "-n", aliases = "--name", description = "Group Name", required = true)
-    private String name;
-
-    @Option(name = "-t", aliases = "--type", description = "Group Type")
-    private String type = "security-role";
-
-    @Override
-    protected Object doExecute() throws Exception {
-        IdentityService identityService = getProcessEngine().getIdentityService();
-
-        Group group = identityService.newGroup(id);
-        group.setName(name);
-        group.setType(type);
-        identityService.saveGroup(group);
-
-        return null;
-    }
-
-    @VisibleForTesting
-    void setId(String id) {
-        this.id = checkNotNull(id, "id is null");
-    }
-
-    @VisibleForTesting
-    void setName(String name) {
-        this.name = checkNotNull(name, "name is null");
-    }
-
-    @VisibleForTesting
-    void setType(String type) {
-        this.type = checkNotNull(type, "type is null");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/AddUserCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/AddUserCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/AddUserCommand.java
deleted file mode 100644
index 3f7ba78..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/AddUserCommand.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import org.activiti.engine.IdentityService;
-import org.activiti.engine.identity.User;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-@Command(scope = "activiti", name = "add-user", description = "Create a new Activiti user")
-public class AddUserCommand extends ActivitiCommand {
-
-    @Option(name = "-i", aliases = "--id", description = "User ID", required = true)
-    private String id;
-
-    @Option(name = "-p", aliases = "--password", description = "User password", required = true)
-    private String password;
-
-    @Option(name = "-g", aliases = "--group", description = "Group ID", required = true)
-    private String groupId;
-
-    @Option(name = "-e", aliases = "--email", description = "User email")
-    private String email = "";
-
-    @Override
-    protected Object doExecute() throws Exception {
-        if (getProcessEngine() == null) {
-            throw new NullPointerException("Please configure a processEngine instance for this command");
-        }
-        IdentityService identityService = getProcessEngine().getIdentityService();
-
-        User user = identityService.newUser(id);
-        user.setEmail(password);
-        identityService.saveUser(user);
-
-        identityService.createMembership(id, groupId);
-
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/CleanHistoryActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/CleanHistoryActivitiCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/CleanHistoryActivitiCommand.java
deleted file mode 100644
index 2b9bf38..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/CleanHistoryActivitiCommand.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-package org.activiti.karaf.commands;
-
-import java.util.List;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.history.HistoricProcessInstance;
-import org.apache.felix.gogo.commands.Argument;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-/**
- * @author Srinivasan Chikkala
- */
-@Command(scope = "activiti", name = "clean-history", description = "Removes history of the Activiti process instances")
-public class CleanHistoryActivitiCommand extends ActivitiCommand {
-
-    @Argument(index = 0, name = "instanceIDs", description = "Instance IDs to remove from history",
-        required = false, multiValued = true)
-    private String[] instanceIDs;
-
-    @Option(name = "-a", aliases = "--all", description = "Remove all Activiti Processes from history")
-    private boolean cleanAll;
-
-    @Option(name = "-pd", aliases = "--definitions", required = false, multiValued = true,
-        description = "Removes history of process instances started from the definitions")
-    private String[] definitionIDs;
-
-    @Override
-    protected Object doExecute() throws Exception {
-        ProcessEngine engine = this.getProcessEngine();
-        if (engine == null) {
-            out().println("Process Engine NOT Found!");
-            return null;
-        }
-        HistoryService historyService = engine.getHistoryService();
-
-        // order of priority if instnaceIDs or definitionIDs and all on the list
-        // process instnaceID and exist or process definitionIDs and exit or process all 
-        // TODO figure out how to add mutually exclusive options - instanceIDs | definitions | all
-
-        if (this.instanceIDs != null && this.instanceIDs.length > 0) {
-            this.cleanProcessInstanceHistory(historyService, this.instanceIDs);
-            return null;
-        }
-
-        if (this.definitionIDs != null && this.definitionIDs.length > 0) {
-            this.cleanProcessDefinitionHistory(historyService, this.definitionIDs);
-            return null;
-        }
-
-        // clean all history
-        if (!cleanAll) {
-            out().println("Process instance IDs required or use the command with -a " +
-                "or --all option to clean all history");
-            return null;
-        } else {
-            cleanAllHistory(historyService);
-        }
-
-        return null;
-    }
-
-    private void cleanAllHistory(HistoryService hs) {
-        out().println("Cleaning History of All Process Instances...");
-        List<HistoricProcessInstance> hpiList = hs.createHistoricProcessInstanceQuery()
-            .orderByProcessDefinitionId().asc().list();
-        if (hpiList == null || hpiList.size() == 0) {
-            out().println("No Process History found! ");
-            return;
-        }
-        for (HistoricProcessInstance hpi : hpiList) {
-            String processId = hpi.getId();
-            hs.deleteHistoricProcessInstance(hpi.getId());
-            out().printf("History removed for process instance %s \n", processId);
-        }
-    }
-
-    private void cleanProcessInstanceHistory(HistoryService hs, String... instances) {
-        for (String instanceId : instances) {
-            // query and if exists delete.
-            HistoricProcessInstance hpi = hs.createHistoricProcessInstanceQuery()
-                .processInstanceId(instanceId).singleResult();
-            if (hpi != null) {
-                hs.deleteHistoricProcessInstance(hpi.getId());
-                out().printf("History removed for process instance %s \n", hpi.getId());
-            } else {
-                out().printf("No History found for process instance %s \n", instanceId);
-            }
-        }
-    }
-
-    private void cleanProcessDefinitionHistory(HistoryService hs, String... definitions) {
-
-        for (String definitionId : definitions) {
-            List<HistoricProcessInstance> hpiList = hs.createHistoricProcessInstanceQuery()
-                .processDefinitionId(definitionId)
-                .orderByProcessDefinitionId().asc().list();
-            if (hpiList == null || hpiList.size() == 0) {
-                out().printf("No History found for process definition %s \n", definitionId);
-                break;
-            }
-            for (HistoricProcessInstance hpi : hpiList) {
-                String processId = hpi.getId();
-                hs.deleteHistoricProcessInstance(hpi.getId());
-                out().printf("History removed for process instance %s with definition %s\n", processId,
-                    definitionId);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/DeleteGroupCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/DeleteGroupCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/DeleteGroupCommand.java
deleted file mode 100644
index 3c6ca5c..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/DeleteGroupCommand.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-@Command(scope = "activiti", name = "delete-group", description = "Delete Group")
-public class DeleteGroupCommand extends ActivitiCommand {
-
-    @Option(name = "-i", aliases = "--id", description = "Group ID", required = true)
-    private String id;
-
-    @Override
-    protected Object doExecute() throws Exception {
-        getProcessEngine().getIdentityService().deleteGroup(id);
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/DeleteUserCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/DeleteUserCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/DeleteUserCommand.java
deleted file mode 100644
index f68a311..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/DeleteUserCommand.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import org.activiti.engine.IdentityService;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-@Command(scope = "activiti", name = "delete-user", description = "Delete existing Activiti user")
-public class DeleteUserCommand extends ActivitiCommand {
-
-    @Option(name = "--id", description = "User ID")
-    private String id;
-
-    @Override
-    protected Object doExecute() throws Exception {
-        if (getProcessEngine() == null) {
-            throw new NullPointerException("Please configure a processEngine instance for this command");
-        }
-        IdentityService identityService = getProcessEngine().getIdentityService();
-        identityService.deleteUser(id);
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/InfoActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/InfoActivitiCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/InfoActivitiCommand.java
deleted file mode 100644
index 11dd63a..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/InfoActivitiCommand.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-package org.activiti.karaf.commands;
-
-import java.io.PrintWriter;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.history.HistoricActivityInstance;
-import org.activiti.engine.history.HistoricProcessInstance;
-import org.activiti.engine.repository.Deployment;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.karaf.commands.handlers.ActivitiPrintHandler;
-import org.activiti.karaf.commands.handlers.DefaultActivitiPrintHandler;
-import org.activiti.karaf.commands.util.Commands;
-import org.apache.felix.gogo.commands.Argument;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-/**
- * karaf command class that prints the details about the bpmn process inlcuding deployment, definition,
- * instance and process varaible details.
- *
- * @author Srinivasan Chikkala
- */
-@Command(scope = "activiti", name = "info", description = "Provides details about the Activiti process instance")
-public class InfoActivitiCommand extends ActivitiCommand {
-
-    private static final Logger LOG = Logger.getLogger(InfoActivitiCommand.class.getName());
-
-    @Argument(index = 0, name = "instanceID", description = "Instance ID for which the details should " +
-        "be displayed", required = true, multiValued = false)
-    private String instanceID;
-
-    @Option(name = "-v", aliases = "--verbose", description = "Full details of the process instance")
-    private boolean verbose;
-
-    @Option(name = "-q", aliases = "--quiet", description = "Show minimum required details of the process instance")
-    private boolean quiet;
-
-    private ActivitiPrintHandler printHandler;
-
-    public boolean isVerbose() {
-        return verbose;
-    }
-
-    public void setVerbose(boolean verbose) {
-        this.verbose = verbose;
-    }
-
-    public boolean isQuiet() {
-        return quiet;
-    }
-
-    public void setQuiet(boolean quiet) {
-        this.quiet = quiet;
-    }
-
-    public String getInstanceID() {
-        return instanceID;
-    }
-
-    public void setInstanceID(String instanceID) {
-        this.instanceID = instanceID;
-    }
-
-    public ActivitiPrintHandler getPrintHandler() {
-        return printHandler;
-    }
-
-    public void setPrintHandler(ActivitiPrintHandler printHandler) {
-        this.printHandler = printHandler;
-    }
-
-    @Override
-    protected Object doExecute() throws Exception {
-        Object obj = null;
-        try {
-            obj = executeCommand();
-        } catch (Exception ex) {
-            out().println(ex.getMessage());
-            LOG.log(Level.INFO, ex.getMessage(), ex);
-        }
-        return obj;
-    }
-
-    protected Object executeCommand() throws Exception {
-        ProcessEngine pe = this.getProcessEngine();
-        if (pe == null) {
-            out().println("Process Engine NOT Found!");
-            return null;
-        }
-        if (this.instanceID == null || this.instanceID.trim().length() == 0) {
-            out().println("Instance ID required to show the information about the instance");
-            return null;
-        }
-
-        this.printHandler = this.findBPMPrintHandler();
-
-        printDetails(this.instanceID.trim());
-        return null;
-    }
-
-    protected ActivitiPrintHandler findBPMPrintHandler() {
-        ActivitiPrintHandler handler;
-        List<ActivitiPrintHandler> hList = null;
-        try {
-            String filter = null; // add the filter here per process.
-            hList = this.getAllServices(ActivitiPrintHandler.class, filter);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        if (hList == null || hList.size() == 0) {
-            DefaultActivitiPrintHandler defHandler = new DefaultActivitiPrintHandler();
-            defHandler.setProcessEngine(this.getProcessEngine());
-            handler = defHandler;
-        } else {
-            handler = hList.get(0); // first one that matches.
-        }
-        return handler;
-    }
-
-    protected void printDeploymentInfo(Deployment depInfo) {
-        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
-        nvMap.put("Deployment ID", depInfo.getId());
-        nvMap.put("Deployment Name", depInfo.getName());
-        nvMap.put("Deployment Time", Commands.UTIL.formatDate(depInfo.getDeploymentTime()));
-        Commands.UTIL.printNameValues(new PrintWriter(out(), true), nvMap);
-    }
-
-    protected void printProcessDefinitionInfo(ProcessDefinition pd) {
-        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
-        nvMap.put("Definition ID", pd.getId());
-        nvMap.put("Definition Name", pd.getName());
-        nvMap.put("Version", Integer.toString(pd.getVersion()));
-        nvMap.put("Resource Name", pd.getResourceName());
-        Commands.UTIL.printNameValues(new PrintWriter(out(), true), nvMap);
-
-    }
-
-    protected void printProcessInstanceInfo(HistoricProcessInstance hpi) {
-        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
-        nvMap.put("Instance ID", hpi.getId());
-        nvMap.put("Start Activity", hpi.getStartActivityId());
-        nvMap.put("End Activity", hpi.getEndActivityId());
-        nvMap.put("Start Time", Commands.UTIL.formatDate(hpi.getStartTime()));
-        nvMap.put("End Time", Commands.UTIL.formatDate(hpi.getEndTime()));
-        if (!this.isQuiet()) {
-            nvMap.put("Duration", Commands.UTIL.formatDuration(hpi.getDurationInMillis()));
-        }
-
-        PrintWriter out = new PrintWriter(out(), true);
-        Commands.UTIL.printNameValues(out, nvMap);
-        // print instance data
-        this.getPrintHandler().printInstanceData(out, this.isVerbose(), this.isQuiet(), hpi);
-    }
-
-    protected void printActivityInstanceInfo(HistoricActivityInstance actInst) {
-
-        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
-        nvMap.put("Activity ID", actInst.getActivityId());
-        if (!this.isQuiet()) {
-            nvMap.put("Activity Type", actInst.getActivityType());
-        }
-        nvMap.put("Activity Name", actInst.getActivityName());
-        if (!this.isQuiet()) {
-            nvMap.put("Execution ID", actInst.getExecutionId());
-        }
-        nvMap.put("Start Time", Commands.UTIL.formatDate(actInst.getStartTime()));
-        nvMap.put("End Time", Commands.UTIL.formatDate(actInst.getEndTime()));
-        if (!this.isQuiet()) {
-            nvMap.put("Duration", Commands.UTIL.formatDuration(actInst.getDurationInMillis()));
-        }
-
-        PrintWriter out = new PrintWriter(out(), true);
-        Commands.UTIL.printNameValues(out, nvMap);
-        // print activity vars
-        this.getPrintHandler().printActivityData(out, this.isVerbose(), this.isQuiet(), actInst);
-        out().println("-------------");
-    }
-
-    protected void printDetails(String pid) {
-        ProcessEngine pe = this.getProcessEngine();
-        RepositoryService repo = pe.getRepositoryService();
-        RuntimeService rt = pe.getRuntimeService();
-        HistoryService hs = pe.getHistoryService();
-
-        ProcessInstance pi = rt.createProcessInstanceQuery().processInstanceId(pid).singleResult();
-        HistoricProcessInstance hpi = hs.createHistoricProcessInstanceQuery().processInstanceId(pid)
-            .singleResult();
-        if (pi == null && hpi == null) {
-            // both null means. no process with that id.
-            out().printf("No process details found with process id %s \n", pid);
-            return;
-        }
-
-        String pdId = null;
-        if (pi != null) {
-            pdId = pi.getProcessDefinitionId();
-        } else if (hpi != null) {
-            pdId = hpi.getProcessDefinitionId();
-        }
-
-        ProcessDefinition pd = repo.createProcessDefinitionQuery().processDefinitionId(pdId).singleResult();
-        Deployment depInfo = repo.createDeploymentQuery().deploymentId(pd.getDeploymentId()).singleResult();
-        // print
-        if (isVerbose()) {
-            out().println("======== Deployment Details");
-            printDeploymentInfo(depInfo);
-
-            out().println("======== Process Definition Details");
-            printProcessDefinitionInfo(pd);
-        }
-
-        out().println("======== Process Instance Details");
-        printProcessInstanceInfo(hpi);
-
-        List<HistoricActivityInstance> actInstList = hs.createHistoricActivityInstanceQuery()
-            .processInstanceId(hpi.getId()).orderByHistoricActivityInstanceStartTime().asc().list();
-        if (actInstList != null && actInstList.size() > 0) {
-            out().println("======== Activity Execution Details");
-            for (HistoricActivityInstance actInst : actInstList) {
-                printActivityInstanceInfo(actInst);
-            }
-        } else {
-            LOG.info("No Activity execution details");
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/KillActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/KillActivitiCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/KillActivitiCommand.java
deleted file mode 100644
index 00717a1..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/KillActivitiCommand.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-package org.activiti.karaf.commands;
-
-import java.util.List;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.apache.felix.gogo.commands.Argument;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-/**
- * @author Srinivasan Chikkala
- */
-@Command(scope = "activiti", name = "kill", description = "Kills any active Activiti process instances")
-public class KillActivitiCommand extends ActivitiCommand {
-
-    @Argument(index = 0, name = "instanceIDs", description = "Instance IDs to kill set of active process instances",
-        required = false, multiValued = true)
-    private String[] instanceIDs;
-
-    @Option(name = "-a", aliases = "--all", description = "Kill all active process instances")
-    private boolean killAll;
-
-    @Override
-    protected Object doExecute() throws Exception {
-        ProcessEngine processEngine = this.getProcessEngine();
-        if (processEngine == null) {
-            out().println("Process Engine NOT Found!");
-            return null;
-        }
-
-        RuntimeService runtimeService = processEngine.getRuntimeService();
-
-        if (this.instanceIDs != null && this.instanceIDs.length > 0) {
-            for (String instanceID : instanceIDs) {
-                runtimeService.deleteProcessInstance(instanceID, "Forcefully terminating the instance");
-                out().printf("Process instance %s terminated\n", instanceID);
-            }
-            return null;
-        }
-
-        if (!killAll) {
-            out().println("Process instance IDs required or use the command with -a or --all option");
-            return null;
-        } else {
-            out().println("Signalling all executions in all active process instances...");
-            List<ProcessInstance> piList = runtimeService.createProcessInstanceQuery().orderByProcessInstanceId().asc().list();
-            for (ProcessInstance pi : piList) {
-                String instanceID = pi.getProcessInstanceId();
-                runtimeService.deleteProcessInstance(instanceID, "Forcefully terminating the instance");
-                out().printf("Process instance %s terminated\n", instanceID);
-            }
-        }
-
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/ListActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/ListActivitiCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/ListActivitiCommand.java
deleted file mode 100644
index 5483620..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/ListActivitiCommand.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import java.io.PrintWriter;
-import java.text.DateFormat;
-import java.util.Date;
-import java.util.List;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.history.HistoricProcessInstance;
-import org.activiti.engine.repository.Deployment;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.activiti.engine.runtime.Execution;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.karaf.commands.util.TextTable;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-/**
- * @author Srinivasan Chikkala
- */
-@Command(scope = "activiti", name = "list", description = "Displays information about Activiti active " +
-    "process instances, process definitions, history of process instances")
-public class ListActivitiCommand extends ActivitiCommand {
-
-    @Option(name = "-pi", aliases = "--active", description = "Display information about all active process instances")
-    private boolean active;
-
-    @Option(name = "-pd", aliases = "--definitions", description = "Display information about all process definitions")
-    private boolean definitions;
-
-    @Option(name = "-h", aliases = "--history", description = "Display information about history of all process instances")
-    private boolean history;
-
-    @Option(name = "-d", aliases = "--deployments", description = "Display information about all Activiti deployments")
-    private boolean deployments;
-
-
-    @Override
-    protected Object doExecute() throws Exception {
-        ProcessEngine pe = this.getProcessEngine();
-
-        if (pe == null) {
-            out().println("Process Engine NOT Found!");
-            return null;
-        }
-
-        if (!(this.active || this.definitions || this.history || this.deployments)) {
-            // none of them set, display everything 
-            // set all to true;
-            this.active = this.definitions = this.history = this.deployments = true;
-        }
-
-        if (this.deployments) {
-            RepositoryService repo = pe.getRepositoryService();
-            printDeployments(out(), repo);
-        }
-
-        if (this.definitions) {
-            RepositoryService repo = pe.getRepositoryService();
-            printProcessDefinitions(out(), repo);
-        }
-
-        if (this.history) {
-            HistoryService his = pe.getHistoryService();
-            boolean printActive = !this.active; // if we show active process, dont print then in history 
-            printHistoricProcessInstances(out(), his, printActive);
-        }
-
-        if (this.active) {
-            RuntimeService rt = pe.getRuntimeService();
-            printActiveProcessInstances(out(), rt);
-        }
-
-
-        return null;
-    }
-
-    private String formatDate(Date date) {
-        String dateTxt = "";
-        if (date != null) {
-            dateTxt = DateFormat.getDateTimeInstance().format(date);
-        }
-        return dateTxt;
-    }
-
-    private String formatBpmResource(String bpmResource) {
-        if (bpmResource.startsWith("bundleresource:")) {
-            return bpmResource.substring("bundleresource:".length());
-        } else {
-            return bpmResource;
-        }
-    }
-
-    private void printDeployments(PrintWriter out, RepositoryService repo) {
-
-        List<Deployment> depList = repo.createDeploymentQuery().orderByDeploymenTime().asc().list();
-
-        out.println();
-        out.println("Activiti Deployments");
-        out.println("--------------------");
-        if (depList.isEmpty()) {
-            out.println("No Activiti Deployments Found.");
-            return;
-        }
-
-        TextTable txtTable = new TextTable(3);
-
-        txtTable.addHeaders("ID", "Name", "Deployment Time");
-        for (Deployment dep : depList) {
-            txtTable.addRow(dep.getId(), dep.getName(), formatDate(dep.getDeploymentTime()));
-        }
-        txtTable.print(out);
-    }
-
-    private void printProcessDefinitions(PrintWriter out, RepositoryService repo) {
-        List<ProcessDefinition> pdList = repo.createProcessDefinitionQuery()
-            .orderByDeploymentId().asc().list();
-
-        out.println();
-        out.println("Activiti Process Definitions");
-        out.println("----------------------------");
-        if (pdList.isEmpty()) {
-            out.println("No Activiti Process Definitions Found.");
-            return;
-        }
-
-        TextTable txtTable = new TextTable(4);
-
-        txtTable.addHeaders("Definition ID", "Name", "Version", "Resource");
-        for (ProcessDefinition pd : pdList) {
-            Integer ver = pd.getVersion();
-            txtTable.addRow(pd.getId(), pd.getName(), ver.toString(), formatBpmResource(pd.getResourceName()));
-        }
-        txtTable.print(out);
-    }
-
-    private String getExecutions(RuntimeService rt, String pi) {
-        List<Execution> executions = rt.createExecutionQuery()
-            .processInstanceId(pi)
-            .orderByProcessInstanceId().asc().list();
-        StringBuilder bld = new StringBuilder();
-        boolean first = true;
-        for (Execution exec : executions) {
-            if (!first) {
-                bld.append(",");
-            } else {
-                first = false;
-            }
-            bld.append(exec.getId());
-        }
-        return bld.toString();
-    }
-
-    private void printActiveProcessInstances(PrintWriter out, RuntimeService rt) {
-
-        List<ProcessInstance> piList = rt.createProcessInstanceQuery().orderByProcessInstanceId().asc().list();
-
-        out.println();
-        out.println("Active Process Instances");
-        out.println("------------------------");
-        if (piList.isEmpty()) {
-            out.println("No Active Process Instances Found.");
-            return;
-        }
-
-        TextTable txtTable = new TextTable(3);
-
-        txtTable.addHeaders("Definition ID", "Instance ID", "Executions");
-        for (ProcessInstance pi : piList) {
-            txtTable.addRow(pi.getProcessDefinitionId(),
-                pi.getProcessInstanceId(), getExecutions(rt, pi.getProcessInstanceId()));
-        }
-        txtTable.print(out);
-    }
-
-    private void printHistoricProcessInstances(PrintWriter out, HistoryService his, boolean printActive) {
-
-        List<HistoricProcessInstance> hpiList = his.createHistoricProcessInstanceQuery()
-            .orderByProcessDefinitionId().asc().list();
-
-        out.println();
-        out.println("History of Activiti Process Instances");
-        out.println("-------------------------------------");
-        if (hpiList.isEmpty()) {
-            out.println("No History on Activiti Processes.");
-            return;
-        }
-
-        TextTable txtTable = new TextTable(4);
-
-        txtTable.addHeaders("Definition ID", "Instance ID", "Start Time", "End Time");
-        for (HistoricProcessInstance hpi : hpiList) {
-            Date endTime = hpi.getEndTime();
-            if (endTime == null && !printActive) {
-                continue;  // don't print active instance history if printActive is false - default.
-            }
-            txtTable.addRow(hpi.getProcessDefinitionId(), hpi.getId(),
-                formatDate(hpi.getStartTime()), formatDate(hpi.getEndTime()));
-        }
-        txtTable.print(out);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/ListGroupsCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/ListGroupsCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/ListGroupsCommand.java
deleted file mode 100644
index eb6c312..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/ListGroupsCommand.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import java.util.List;
-import org.activiti.engine.identity.Group;
-import org.apache.felix.gogo.commands.Command;
-
-@Command(scope = "activiti", name = "list-groups", description = "List groups")
-public class ListGroupsCommand extends ActivitiCommand {
-
-    @Override
-    protected Object doExecute() throws Exception {
-        List<Group> groups = getProcessEngine().getIdentityService()
-            .createGroupQuery().orderByGroupId().asc().list();
-
-        if (groups.isEmpty()) {
-            err().println("No groups found.");
-        }
-        for (Group group : groups) {
-            out().printf("%s\t%s\t%s\n", group.getId(), group.getName(), group.getType());
-        }
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/ListUsersCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/ListUsersCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/ListUsersCommand.java
deleted file mode 100644
index 95c97e0..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/ListUsersCommand.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import java.util.List;
-import org.activiti.engine.identity.User;
-import org.apache.felix.gogo.commands.Command;
-
-@Command(scope = "activiti", name = "list-users", description = "List users")
-public class ListUsersCommand extends ActivitiCommand {
-
-    @Override
-    protected Object doExecute() throws Exception {
-        List<User> users = getProcessEngine().getIdentityService()
-            .createUserQuery().orderByUserId().asc().list();
-
-        if (users.isEmpty()) {
-            err().println("No users found.");
-        }
-        for (User user : users) {
-            out().printf("%s\t%s\t%s\n", user.getId(), user.getEmail(), user.getPassword());
-        }
-
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/activiti/karaf/commands/SignalActivitiCommand.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/activiti/karaf/commands/SignalActivitiCommand.java b/activiti/commands/src/main/java/org/activiti/karaf/commands/SignalActivitiCommand.java
deleted file mode 100644
index 66331e3..0000000
--- a/activiti/commands/src/main/java/org/activiti/karaf/commands/SignalActivitiCommand.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-package org.activiti.karaf.commands;
-
-import java.util.List;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.Execution;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.apache.felix.gogo.commands.Argument;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-/**
- * @author Srinivasan Chikkala
- */
-@Command(scope = "activiti", name = "signal",
-    description = "Signals any active executions in Activiti process instances")
-public class SignalActivitiCommand extends ActivitiCommand {
-
-    @Argument(index = 0, name = "instanceIDs", description = "Instance IDs to signal set of active process " +
-        "instances", required = false, multiValued = true)
-    private String[] instanceIDs;
-
-    @Option(name = "-a", aliases = "--all", description = "Signal all active process instances")
-    private boolean signalAll;
-
-    @Option(name = "-activities", aliases = "--activities", required = false,
-        multiValued = true, description = "Signal all activities in a process instances")
-    private String[] activities;
-
-    @Override
-    protected Object doExecute() throws Exception {
-        ProcessEngine engine = this.getProcessEngine();
-        if (engine == null) {
-            out().println("Process Engine NOT Found!");
-            return null;
-        }
-        RuntimeService runtimeService = engine.getRuntimeService();
-
-        if (this.instanceIDs != null && this.instanceIDs.length > 0) {
-            for (String instanceID : this.instanceIDs) {
-                signal(runtimeService, instanceID, this.activities);
-            }
-            return null;
-        }
-
-        if (!signalAll) {
-            out().println("Process instance IDs required or use the command with -a or --all option");
-            return null;
-        } else {
-            out().println("Signalling all executions in all active process instances...");
-            List<ProcessInstance> piList = runtimeService.createProcessInstanceQuery().orderByProcessInstanceId().asc().list();
-            for (ProcessInstance pi : piList) {
-                signal(runtimeService, pi.getProcessInstanceId(), this.activities);
-            }
-        }
-
-        return null;
-    }
-
-    private void signal(RuntimeService rt, Execution exec) {
-        try {
-            if (!exec.isEnded()) {
-                rt.signal(exec.getId());
-            } else {
-                out().printf("Execution %s already ended \n" + exec.getId());
-            }
-        } catch (Exception ex) {
-            out().printf("Exception:%s in signaling the execution %s \n", ex.getMessage(), exec.getId());
-        }
-    }
-
-    private void signal(RuntimeService rt, String pi, String... activities) {
-        if (activities == null || activities.length == 0) {
-            // signal all executions in the instance 
-            out().println("Signaling all active executions in the process instance " + pi);
-            List<Execution> executions = rt.createExecutionQuery()
-                .processInstanceId(pi)
-                .orderByProcessInstanceId().asc().list();
-            for (Execution exec : executions) {
-                signal(rt, exec);
-            }
-        } else {
-            for (String activity : activities) {
-                out().printf("Signaling activity %s in process instance %s \n", activity, pi);
-                List<Execution> executions = rt.createExecutionQuery()
-                    .processInstanceId(pi)
-                    .activityId(activity)
-                    .orderByProcessInstanceId().asc().list();
-                for (Execution exec : executions) {
-                    signal(rt, exec);
-                }
-            }
-        }
-    }
-}


[14/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/org/apache/provisionr/core/templates/xml/XmlTemplate.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/provisionr/core/templates/xml/XmlTemplate.java b/core/src/main/java/org/apache/provisionr/core/templates/xml/XmlTemplate.java
new file mode 100644
index 0000000..1255082
--- /dev/null
+++ b/core/src/main/java/org/apache/provisionr/core/templates/xml/XmlTemplate.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.core.templates.xml;
+
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.NetworkBuilder;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.pool.PoolBuilder;
+import org.apache.provisionr.api.software.Repository;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.api.software.SoftwareBuilder;
+import org.apache.provisionr.core.templates.PoolTemplate;
+import com.google.common.annotations.VisibleForTesting;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Throwables;
+import static com.google.common.collect.Lists.newArrayList;
+import com.google.common.io.CharStreams;
+import com.google.common.io.Closeables;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Basic representation of a pool template
+ * <p/>
+ * Designed to be consumed *only* by JAXB
+ * <p/>
+ * If you need to implement a pool template see {@code PoolTemplate}
+ */
+@XmlRootElement(name = "template")
+public class XmlTemplate implements PoolTemplate {
+
+    /**
+     * @return an XmlTemplate instance resulted from parsing the content
+     */
+    public static XmlTemplate newXmlTemplate(String content) {
+        try {
+            JAXBContext context = JAXBContext.newInstance(XmlTemplate.class);
+            return (XmlTemplate) context.createUnmarshaller()
+                .unmarshal(new ByteArrayInputStream(content.getBytes()));
+
+        } catch (JAXBException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    /**
+     * @return an XmlTemplate instance resulted from parsing a file
+     */
+    public static XmlTemplate newXmlTemplate(File file) {
+        FileReader reader = null;
+        try {
+            reader = new FileReader(file);
+            return newXmlTemplate(CharStreams.toString(reader));
+
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        } finally {
+            Closeables.closeQuietly(reader);
+        }
+    }
+
+    private String id;
+    private String description;
+    private String osVersion;
+
+    private List<String> packages = newArrayList();
+    private List<Integer> ports = newArrayList();
+
+    private List<FileEntry> files = newArrayList();
+
+    private List<RepositoryEntry> repositories = newArrayList();
+
+    public XmlTemplate() {
+    }
+
+    @Override
+    public Pool apply(Pool pool) {
+        PoolBuilder result = pool.toBuilder();
+
+        result.software(apply(pool.getSoftware()));
+        result.network(apply(pool.getNetwork()));
+
+        if (osVersion != null) {
+            result.provider(pool.getProvider().toBuilder()
+                .option("version", osVersion).createProvider());
+        }
+
+        return result.createPool();
+    }
+
+    @VisibleForTesting
+    Software apply(Software software) {
+        SoftwareBuilder result = software.toBuilder();
+
+        // Add all the new packages
+        for (String pkg : packages) {
+            result.addPackage(pkg);
+        }
+
+        // Add all the new files
+        for (FileEntry entry : files) {
+            result.file(entry.getSource(), entry.getDestination());
+        }
+
+        // Add all the new custom repositories
+        for (RepositoryEntry entry : repositories) {
+            result.repository(Repository.builder().name(entry.getId()).key(entry.getKey())
+                .entries(entry.getEntries()).createRepository());
+        }
+
+        return result.createSoftware();
+    }
+
+    @VisibleForTesting
+    Network apply(Network network) {
+        NetworkBuilder result = network.toBuilder();
+        for (int port : ports) {
+            result.addRules(Rule.builder().anySource().tcp().port(port).createRule());
+        }
+        return result.createNetwork();
+    }
+
+    @XmlAttribute(name = "id")
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = checkNotNull(id, "id is null");
+    }
+
+    @Override
+    public String getDescription() {
+        return description.trim();
+    }
+
+    public void setDescription(String description) {
+        this.description = checkNotNull(description, "description is null");
+    }
+
+    @XmlAttribute(name = "os-version")
+    public String getOsVersion() {
+        return osVersion;
+    }
+
+    public void setOsVersion(String osVersion) {
+        this.osVersion = checkNotNull(osVersion, "osVersion is null");
+    }
+
+    @XmlElementWrapper(name = "packages")
+    @XmlElement(name = "package")
+    public List<String> getPackages() {
+        return packages;
+    }
+
+    public void setPackages(List<String> packages) {
+        this.packages = checkNotNull(packages, "packages is null");
+    }
+
+    @XmlElementWrapper(name = "ports")
+    @XmlElement(name = "port")
+    public List<Integer> getPorts() {
+        return ports;
+    }
+
+    public void setPorts(List<Integer> ports) {
+        this.ports = checkNotNull(ports, "ports is null");
+    }
+
+    @XmlElementWrapper(name = "files")
+    @XmlElement(name = "file")
+    public List<FileEntry> getFiles() {
+        return files;
+    }
+
+    public void setFiles(List<FileEntry> files) {
+        this.files = checkNotNull(files, "files is null");
+    }
+
+    @XmlElementWrapper(name = "repositories")
+    @XmlElement(name = "repository")
+    public List<RepositoryEntry> getRepositories() {
+        return repositories;
+    }
+
+    public void setRepositories(List<RepositoryEntry> repositories) {
+        this.repositories = checkNotNull(repositories, "repositories is null");
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        XmlTemplate that = (XmlTemplate) o;
+
+        if (description != null ? !description.equals(that.description) : that.description != null) return false;
+        if (files != null ? !files.equals(that.files) : that.files != null) return false;
+        if (id != null ? !id.equals(that.id) : that.id != null) return false;
+        if (osVersion != null ? !osVersion.equals(that.osVersion) : that.osVersion != null) return false;
+        if (packages != null ? !packages.equals(that.packages) : that.packages != null) return false;
+        if (ports != null ? !ports.equals(that.ports) : that.ports != null) return false;
+        if (repositories != null ? !repositories.equals(that.repositories) : that.repositories != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id != null ? id.hashCode() : 0;
+        result = 31 * result + (description != null ? description.hashCode() : 0);
+        result = 31 * result + (osVersion != null ? osVersion.hashCode() : 0);
+        result = 31 * result + (packages != null ? packages.hashCode() : 0);
+        result = 31 * result + (ports != null ? ports.hashCode() : 0);
+        result = 31 * result + (files != null ? files.hashCode() : 0);
+        result = 31 * result + (repositories != null ? repositories.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "XmlTemplate{" +
+            "id='" + id + '\'' +
+            ", description='" + description + '\'' +
+            ", osVersion='" + osVersion + '\'' +
+            ", packages=" + packages +
+            ", ports=" + ports +
+            ", files=" + files +
+            ", repositories=" + repositories +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/OSGI-INF/blueprint/context.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/OSGI-INF/blueprint/context.xml b/core/src/main/resources/OSGI-INF/blueprint/context.xml
index 7d07c57..c66ba80 100644
--- a/core/src/main/resources/OSGI-INF/blueprint/context.xml
+++ b/core/src/main/resources/OSGI-INF/blueprint/context.xml
@@ -17,10 +17,10 @@
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            xmlns:cfg="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
 
-    <cfg:property-placeholder persistent-id="com.axemblr.provisionr"
+    <cfg:property-placeholder persistent-id="org.apache.provisionr"
                               placeholder-prefix="$(" placeholder-suffix=")" update-strategy="reload">
         <cfg:default-properties>
-            <cfg:property name="activiti.db.url" value="jdbc:h2:mem:axemblr;MVCC=TRUE;DB_CLOSE_DELAY=-1"/>
+            <cfg:property name="activiti.db.url" value="jdbc:h2:mem:provisionr;MVCC=TRUE;DB_CLOSE_DELAY=-1"/>
             <cfg:property name="activiti.db.user" value="sa"/>
             <cfg:property name="activiti.db.password" value=""/>
             <cfg:property name="activiti.db.schemaUpdate" value="true"/>
@@ -53,12 +53,12 @@
     </bean>
 
     <bean id="configurableFailedJobCommandFactory"
-          class="com.axemblr.provisionr.core.activiti.ConfigurableFailedJobCommandFactory">
+          class="org.apache.provisionr.core.activiti.ConfigurableFailedJobCommandFactory">
         <argument value="$(activiti.job.maxNumberOfRetries)"/>
         <argument value="$(activiti.job.timeBetweenRetriesInSeconds)"/>
     </bean>
 
-    <bean id="configurationFactory" class="com.axemblr.provisionr.core.activiti.ConfigurationFactory">
+    <bean id="configurationFactory" class="org.apache.provisionr.core.activiti.ConfigurationFactory">
         <property name="dataSource" ref="dataSource"/>
         <property name="databaseSchemaUpdate" value="$(activiti.db.schemaUpdate)"/>
         <property name="jobExecutorActivate" value="true"/>
@@ -100,26 +100,26 @@
     <bean id="bouncyCastleAsJceProviderRegistration" class="net.schmizz.sshj.common.SecurityUtils"
           factory-method="getSecurityProvider"/>
 
-    <bean id="poolTemplateInstaller" class="com.axemblr.provisionr.core.templates.PoolTemplateInstaller">
+    <bean id="poolTemplateInstaller" class="org.apache.provisionr.core.templates.PoolTemplateInstaller">
         <argument ref="blueprintBundleContext"/>
     </bean>
     <service ref="poolTemplateInstaller" auto-export="interfaces"/>
 
     <!-- Reusable Activiti activities -->
 
-    <bean id="checkSshPortIsOpen" class="com.axemblr.provisionr.core.activities.IsMachinePortOpen">
+    <bean id="checkSshPortIsOpen" class="org.apache.provisionr.core.activities.IsMachinePortOpen">
         <argument value="sshPortIsOpen"/>
         <argument value="22"/>
     </bean>
     <service ref="checkSshPortIsOpen" auto-export="interfaces"/>
 
-    <bean id="installRepositories" class="com.axemblr.provisionr.core.activities.InstallRepositories"/>
+    <bean id="installRepositories" class="org.apache.provisionr.core.activities.InstallRepositories"/>
     <service ref="installRepositories" auto-export="interfaces"/>
 
-    <bean id="installPackages" class="com.axemblr.provisionr.core.activities.InstallPackages"/>
+    <bean id="installPackages" class="org.apache.provisionr.core.activities.InstallPackages"/>
     <service ref="installPackages" auto-export="interfaces"/>
 
-    <bean id="downloadFiles" class="com.axemblr.provisionr.core.activities.DownloadFiles"/>
+    <bean id="downloadFiles" class="org.apache.provisionr.core.activities.DownloadFiles"/>
     <service ref="downloadFiles" auto-export="interfaces"/>
 
 </blueprint>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/com.axemblr.provisionr.cfg
----------------------------------------------------------------------
diff --git a/core/src/main/resources/com.axemblr.provisionr.cfg b/core/src/main/resources/com.axemblr.provisionr.cfg
deleted file mode 100644
index cc2e4a4..0000000
--- a/core/src/main/resources/com.axemblr.provisionr.cfg
+++ /dev/null
@@ -1,37 +0,0 @@
-
-#
-# Database configuration
-#
-
-# We use MVCC to enable row-level locking on h2. This avoids transaction dead locks.
-activiti.db.url=jdbc:h2:data/state;MVCC=TRUE;DB_CLOSE_DELAY=-1
-
-activiti.db.user=sa
-# activiti.db.password=
-
-activiti.db.schemaUpdate=true
-
-#
-# Job Executor configuration
-#
-
-activiti.executor.queueSize=30
-
-activiti.executor.corePoolSize=15
-activiti.executor.maxPoolSize=100
-
-activiti.executor.maxJobsPerAcquisition=30
-
-# between two job acquisitions
-activiti.executor.waitTimeInMillis=1000
-activiti.executor.lockTimeInMillis=600000
-
-
-#
-# Job Retries
-#
-
-# Use -1 for infinity
-activiti.job.maxNumberOfRetries=13
-activiti.job.timeBetweenRetriesInSeconds=10
-

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/com/axemblr/provisionr/core/puppet/files.pp.mustache
----------------------------------------------------------------------
diff --git a/core/src/main/resources/com/axemblr/provisionr/core/puppet/files.pp.mustache b/core/src/main/resources/com/axemblr/provisionr/core/puppet/files.pp.mustache
deleted file mode 100644
index b804ab5..0000000
--- a/core/src/main/resources/com/axemblr/provisionr/core/puppet/files.pp.mustache
+++ /dev/null
@@ -1,25 +0,0 @@
-
-package { "wget":
-  ensure => "installed"
-}
-
-define download_file(
-  $uri,
-  $timeout = 300,
-  $user_agent = "Axemblr Provisionr (https://github.com/axemblr/axemblr-provisionr)"
-) {
-  exec { $name:
-    command => "/usr/bin/wget --no-check-certificate -nv -U '${user_agent}' ${uri} -O ${name}",
-    timeout => $timeout, # seconds
-    logoutput => true,
-    tries => 3,
-    try_sleep => 5, # seconds
-    require => Package["wget"]
-  }
-}
-
-{{#files}}
-download_file {"{{destination}}":
-  uri => "{{source}}"
-}
-{{/files}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/com/axemblr/provisionr/core/puppet/packages.pp.mustache
----------------------------------------------------------------------
diff --git a/core/src/main/resources/com/axemblr/provisionr/core/puppet/packages.pp.mustache b/core/src/main/resources/com/axemblr/provisionr/core/puppet/packages.pp.mustache
deleted file mode 100644
index 0826e53..0000000
--- a/core/src/main/resources/com/axemblr/provisionr/core/puppet/packages.pp.mustache
+++ /dev/null
@@ -1,7 +0,0 @@
-
-# Ensure all packages listed bellow are installed
-Package { ensure => "installed" }
-
-{{#packages}}
-package { "{{package}}": }
-{{/packages}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/com/axemblr/provisionr/core/puppet/repositories.pp.mustache
----------------------------------------------------------------------
diff --git a/core/src/main/resources/com/axemblr/provisionr/core/puppet/repositories.pp.mustache b/core/src/main/resources/com/axemblr/provisionr/core/puppet/repositories.pp.mustache
deleted file mode 100644
index 67c4385..0000000
--- a/core/src/main/resources/com/axemblr/provisionr/core/puppet/repositories.pp.mustache
+++ /dev/null
@@ -1,38 +0,0 @@
-# Register repositories and refresh index
-
-define apt::repository (
-  $content,
-  $key,
-  $apt_sources_dir = "/etc/apt/sources.list.d"
-) {
-  file { "apt::repository ${name}":
-    path    => "${apt_sources_dir}/${name}.list",
-    content => "${content}\n",
-    owner   => root,
-    group   => root,
-    mode    => 0644,
-    ensure  => present
-  }
-  file { "/tmp/${name}.key":
-    content => "${key}"
-  }
-  exec { "apt-key add ${name}":
-    command => "/usr/bin/apt-key add /tmp/${name}.key",
-    unless  => "/usr/bin/apt-key list | /bin/grep -c ${name}",
-    require => File["/tmp/${name}.key"],
-  }
-  exec { "apt-get update ${name}":
-    command => "/usr/bin/apt-get update",
-    require => [Exec["apt-key add ${name}"], File["apt::repository ${name}"]]
-  }
-}
-
-{{#repositories}}
-apt::repository { "{{name}}":
-  content => "{{content}}\n",
-  key => "{{key}}"
-}
-{{/repositories}}
-
-
-

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/com/axemblr/provisionr/core/templates/cdh3.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/com/axemblr/provisionr/core/templates/cdh3.xml b/core/src/main/resources/com/axemblr/provisionr/core/templates/cdh3.xml
deleted file mode 100644
index a289182..0000000
--- a/core/src/main/resources/com/axemblr/provisionr/core/templates/cdh3.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<template id="cdh3" os-version="10.04 LTS">
-    <description>
-        Cloudera CDH3 template for Ubuntu 10.04 LTS (lucid) including the Cloudera Manager installer
-    </description>
-    <packages>
-        <package>cloudera-manager-agent</package>
-        <package>cloudera-manager-daemons</package>
-        <package>oracle-j2sdk1.6</package>
-        <package>hadoop-0.20</package>
-        <package>hadoop-0.20-native</package>
-        <package>hadoop-hive</package>
-        <package>hadoop-pig</package>
-        <package>oozie-client</package>
-        <package>oozie</package>
-        <package>hue-plugins</package>
-        <package>hue-common</package>
-        <package>hue-proxy</package>
-        <package>hue-about</package>
-        <package>hue-help</package>
-        <package>hue-filebrowser</package>
-        <package>hue-jobsub</package>
-        <package>hue-beeswax</package>
-        <package>hue-useradmin</package>
-        <package>hue-shell</package>
-        <package>hue</package>
-    </packages>
-    <ports>
-        <port>7180</port>
-        <port>8888</port>
-        <port>8080</port>
-    </ports>
-    <files>
-        <file source="http://archive.cloudera.com/cm4/installer/latest/cloudera-manager-installer.bin"
-              destination="/opt/cloudera-manager-installer.bin"/>
-    </files>
-    <repositories>
-        <repository id="cloudera-cdh3">
-            <entries>
-                <entry>deb http://archive.cloudera.com/debian lucid-cdh3 contrib</entry>
-            </entries>
-            <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.4.9 (GNU/Linux)
-
-mQGiBEnvgi0RBADLx1qQlXlrvHOo13dUvoWL97Ny/0s0S/GcMEgAqYvZzUPVcq8H
-GUsOb4PLTfcL1H7Ptq9fqr02uIb5Bc/ltdwE9GFaT2nvdfBx9T8jr8LrW9JE2xJq
-dCyFO5yP9YbZeFAxNO3yBxeP85lQ9CdWWLvyYdtQ+T84EYerqkcVbSvYRwCg6zyx
-EE3jWYvyVv/3HTrVTYpgHgMD/2kMR1Z2vEYOSM7h4cnRnxiadhefqJ2WCm4L30Rx
-/F9JBLAEuIuUndiOShoB043iDY+rrqCHqHQ/uI2D4piW9cDYMo7EJlsFtQ5g2SFg
-PcS4+DLhU464dTQsTGAhvcv+F0VQV4iu1HdD2/kKJkCS/MZL4rr4emqsh6VIBDdG
-ytPaA/9cyRJZe2BrBM2pECGncE5RUaM3g37Ka+VnmMVOXgZdzgCxwFZyVhyxzssD
-kB4jcm75UEZx8BiaoPQDQEsBongdx5M4Vwv5XnvUq7sK7eZLmUzW9hmkPjgLea0/
-znchvPsLeTNqSfIcH14TbFt6B2y1G3Vbi5/6UiAaIqLrqjZlCrQXQ2xvdWRlcmEg
-QXB0IFJlcG9zaXRvcnmIYAQTEQIAIAUCSe+CLQIbAwYLCQgHAwIEFQIIAwQWAgMB
-Ah4BAheAAAoJEDJ1dO4CqBjdGQUAnitydC/NGEh0aZXDN1v22pWFpRzTAJ46N4gT
-Zx25oWfyppX3R7fSH+7TPrkCDQRJ74ItEAgAq8s4iMsGhk9nnMF6wlarqHjws4Dw
-NFZBzA1Ah8KnMtrdr8t99OfzY1b7PNzHXujcaTTqL6L881ezdsls9aHp2kr24Btr
-8nqEZJHSjCnQscAGu+NrhoH2KvK+tMRCHGRcy5UNQbLTJi4Hf8Lo+zv0WUy9BCDu
-7HoDlwrrh1Rw5oOwLFc2UXSTEB6BwYna0mZcNjVpfKNHa//wJcKR0AtsCwRT9znP
-GS0Hpqi1l0/iU7sJhNWyyF427ANg+Jv2n4IP+dd734ZiFeJ9tWCtBjfc3MZJKETk
-tiCtX7FVIIqBAmYLwPqcvZMGJMrNzLBtRuuiBv5bFcPpMEhoD40oQEG8uwADBQf/
-f3NpQbuAcZLMzbrHYu3FB/+4ETvDJXJIEUiQUdobWancSBUhuNPOqIgLzIWM1jRu
-jWGIpkeP6iqNW9kDrq26CuMFP2CoVvnaMiLXUvyf62HWAiYXXlZle5O97bvhYMtM
-Y4o5sMo2ktI9IcgYIFicFwcmuGyGL7nJ3Bo9FAUV2LvMe++O/f13jsPpygoTZgGT
-6w0erglWgrgf5pXt8ajlI4TUrlMVg9Iy/tB9ZzVHnpk21o4vLHwZkgXe1WlK/Rze
-ZCruXyXHaFyEJN2zlP2xNj2F2WisL+/HEnl/qzU4IpNI2LQV2aiY9Nt8MBXgSHAh
-gWKWkjiB+tswgzuNsBOTM4hJBBgRAgAJBQJJ74ItAhsMAAoJEDJ1dO4CqBjd988A
-oJ1WlEx2BcFA7W1RMyErejcvB6thAKCf3t0thSQvkoGi3AOJ4Haj/C3yUQ==
-=H6IR
------END PGP PUBLIC KEY BLOCK-----]]></key>
-        </repository>
-        <repository id="cloudera-cm4">
-            <entries>
-                <entry>deb http://archive.cloudera.com/cm4/ubuntu/lucid/amd64/cm lucid-cm4 contrib</entry>
-                <entry>deb-src http://archive.cloudera.com/cm4/ubuntu/lucid/amd64/cm lucid-cm4 contrib</entry>
-            </entries>
-            <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.4.9 (GNU/Linux)
-
-mQGiBEnvgi0RBADLx1qQlXlrvHOo13dUvoWL97Ny/0s0S/GcMEgAqYvZzUPVcq8H
-GUsOb4PLTfcL1H7Ptq9fqr02uIb5Bc/ltdwE9GFaT2nvdfBx9T8jr8LrW9JE2xJq
-dCyFO5yP9YbZeFAxNO3yBxeP85lQ9CdWWLvyYdtQ+T84EYerqkcVbSvYRwCg6zyx
-EE3jWYvyVv/3HTrVTYpgHgMD/2kMR1Z2vEYOSM7h4cnRnxiadhefqJ2WCm4L30Rx
-/F9JBLAEuIuUndiOShoB043iDY+rrqCHqHQ/uI2D4piW9cDYMo7EJlsFtQ5g2SFg
-PcS4+DLhU464dTQsTGAhvcv+F0VQV4iu1HdD2/kKJkCS/MZL4rr4emqsh6VIBDdG
-ytPaA/9cyRJZe2BrBM2pECGncE5RUaM3g37Ka+VnmMVOXgZdzgCxwFZyVhyxzssD
-kB4jcm75UEZx8BiaoPQDQEsBongdx5M4Vwv5XnvUq7sK7eZLmUzW9hmkPjgLea0/
-znchvPsLeTNqSfIcH14TbFt6B2y1G3Vbi5/6UiAaIqLrqjZlCrQXQ2xvdWRlcmEg
-QXB0IFJlcG9zaXRvcnmIYAQTEQIAIAUCSe+CLQIbAwYLCQgHAwIEFQIIAwQWAgMB
-Ah4BAheAAAoJEDJ1dO4CqBjdGQUAnitydC/NGEh0aZXDN1v22pWFpRzTAJ46N4gT
-Zx25oWfyppX3R7fSH+7TPrkCDQRJ74ItEAgAq8s4iMsGhk9nnMF6wlarqHjws4Dw
-NFZBzA1Ah8KnMtrdr8t99OfzY1b7PNzHXujcaTTqL6L881ezdsls9aHp2kr24Btr
-8nqEZJHSjCnQscAGu+NrhoH2KvK+tMRCHGRcy5UNQbLTJi4Hf8Lo+zv0WUy9BCDu
-7HoDlwrrh1Rw5oOwLFc2UXSTEB6BwYna0mZcNjVpfKNHa//wJcKR0AtsCwRT9znP
-GS0Hpqi1l0/iU7sJhNWyyF427ANg+Jv2n4IP+dd734ZiFeJ9tWCtBjfc3MZJKETk
-tiCtX7FVIIqBAmYLwPqcvZMGJMrNzLBtRuuiBv5bFcPpMEhoD40oQEG8uwADBQf/
-f3NpQbuAcZLMzbrHYu3FB/+4ETvDJXJIEUiQUdobWancSBUhuNPOqIgLzIWM1jRu
-jWGIpkeP6iqNW9kDrq26CuMFP2CoVvnaMiLXUvyf62HWAiYXXlZle5O97bvhYMtM
-Y4o5sMo2ktI9IcgYIFicFwcmuGyGL7nJ3Bo9FAUV2LvMe++O/f13jsPpygoTZgGT
-6w0erglWgrgf5pXt8ajlI4TUrlMVg9Iy/tB9ZzVHnpk21o4vLHwZkgXe1WlK/Rze
-ZCruXyXHaFyEJN2zlP2xNj2F2WisL+/HEnl/qzU4IpNI2LQV2aiY9Nt8MBXgSHAh
-gWKWkjiB+tswgzuNsBOTM4hJBBgRAgAJBQJJ74ItAhsMAAoJEDJ1dO4CqBjd988A
-oJ1WlEx2BcFA7W1RMyErejcvB6thAKCf3t0thSQvkoGi3AOJ4Haj/C3yUQ==
-=H6IR
------END PGP PUBLIC KEY BLOCK-----]]></key>
-        </repository>
-    </repositories>
-</template>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/com/axemblr/provisionr/core/templates/cdh4.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/com/axemblr/provisionr/core/templates/cdh4.xml b/core/src/main/resources/com/axemblr/provisionr/core/templates/cdh4.xml
deleted file mode 100644
index bd9181b..0000000
--- a/core/src/main/resources/com/axemblr/provisionr/core/templates/cdh4.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<template id="cdh4" os-version="10.04 LTS">
-    <description>
-        Cloudera CDH4 template for Ubuntu 10.04 LTS (lucid)
-    </description>
-    <packages>
-        <package>openjdk-6-jdk</package>
-        <package>hadoop-0.20-mapreduce-jobtracker</package>
-        <package>hadoop-hdfs-namenode</package>
-        <package>hadoop-0.20-mapreduce-tasktracker</package>
-        <package>hadoop-hdfs-datanode</package>
-        <package>hadoop-client</package>
-        <package>xmlstarlet</package>
-    </packages>
-    <ports>
-        <port>7180</port>
-        <port>8888</port>
-        <port>8080</port>
-        <port>8020</port>
-        <port>50010</port>
-        <port>50020</port>
-    </ports>
-    <repositories>
-        <repository id="cloudera-cdh4">
-            <entries>
-                <entry>deb [arch=amd64] http://archive.cloudera.com/cdh4/ubuntu/lucid/amd64/cdh lucid-cdh4 contrib</entry>
-            </entries>
-            <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.4.9 (GNU/Linux)
-
-mQGiBEnvgi0RBADLx1qQlXlrvHOo13dUvoWL97Ny/0s0S/GcMEgAqYvZzUPVcq8H
-GUsOb4PLTfcL1H7Ptq9fqr02uIb5Bc/ltdwE9GFaT2nvdfBx9T8jr8LrW9JE2xJq
-dCyFO5yP9YbZeFAxNO3yBxeP85lQ9CdWWLvyYdtQ+T84EYerqkcVbSvYRwCg6zyx
-EE3jWYvyVv/3HTrVTYpgHgMD/2kMR1Z2vEYOSM7h4cnRnxiadhefqJ2WCm4L30Rx
-/F9JBLAEuIuUndiOShoB043iDY+rrqCHqHQ/uI2D4piW9cDYMo7EJlsFtQ5g2SFg
-PcS4+DLhU464dTQsTGAhvcv+F0VQV4iu1HdD2/kKJkCS/MZL4rr4emqsh6VIBDdG
-ytPaA/9cyRJZe2BrBM2pECGncE5RUaM3g37Ka+VnmMVOXgZdzgCxwFZyVhyxzssD
-kB4jcm75UEZx8BiaoPQDQEsBongdx5M4Vwv5XnvUq7sK7eZLmUzW9hmkPjgLea0/
-znchvPsLeTNqSfIcH14TbFt6B2y1G3Vbi5/6UiAaIqLrqjZlCrQXQ2xvdWRlcmEg
-QXB0IFJlcG9zaXRvcnmIYAQTEQIAIAUCSe+CLQIbAwYLCQgHAwIEFQIIAwQWAgMB
-Ah4BAheAAAoJEDJ1dO4CqBjdGQUAnitydC/NGEh0aZXDN1v22pWFpRzTAJ46N4gT
-Zx25oWfyppX3R7fSH+7TPrkCDQRJ74ItEAgAq8s4iMsGhk9nnMF6wlarqHjws4Dw
-NFZBzA1Ah8KnMtrdr8t99OfzY1b7PNzHXujcaTTqL6L881ezdsls9aHp2kr24Btr
-8nqEZJHSjCnQscAGu+NrhoH2KvK+tMRCHGRcy5UNQbLTJi4Hf8Lo+zv0WUy9BCDu
-7HoDlwrrh1Rw5oOwLFc2UXSTEB6BwYna0mZcNjVpfKNHa//wJcKR0AtsCwRT9znP
-GS0Hpqi1l0/iU7sJhNWyyF427ANg+Jv2n4IP+dd734ZiFeJ9tWCtBjfc3MZJKETk
-tiCtX7FVIIqBAmYLwPqcvZMGJMrNzLBtRuuiBv5bFcPpMEhoD40oQEG8uwADBQf/
-f3NpQbuAcZLMzbrHYu3FB/+4ETvDJXJIEUiQUdobWancSBUhuNPOqIgLzIWM1jRu
-jWGIpkeP6iqNW9kDrq26CuMFP2CoVvnaMiLXUvyf62HWAiYXXlZle5O97bvhYMtM
-Y4o5sMo2ktI9IcgYIFicFwcmuGyGL7nJ3Bo9FAUV2LvMe++O/f13jsPpygoTZgGT
-6w0erglWgrgf5pXt8ajlI4TUrlMVg9Iy/tB9ZzVHnpk21o4vLHwZkgXe1WlK/Rze
-ZCruXyXHaFyEJN2zlP2xNj2F2WisL+/HEnl/qzU4IpNI2LQV2aiY9Nt8MBXgSHAh
-gWKWkjiB+tswgzuNsBOTM4hJBBgRAgAJBQJJ74ItAhsMAAoJEDJ1dO4CqBjd988A
-oJ1WlEx2BcFA7W1RMyErejcvB6thAKCf3t0thSQvkoGi3AOJ4Haj/C3yUQ==
-=H6IR
------END PGP PUBLIC KEY BLOCK-----]]></key>
-        </repository>
-    </repositories>
-</template>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/com/axemblr/provisionr/core/templates/jenkins.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/com/axemblr/provisionr/core/templates/jenkins.xml b/core/src/main/resources/com/axemblr/provisionr/core/templates/jenkins.xml
deleted file mode 100644
index c7297f3..0000000
--- a/core/src/main/resources/com/axemblr/provisionr/core/templates/jenkins.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<template id="jenkins">
-    <description>A short template that installs the latest jenkins with git &amp; svn</description>
-    <packages>
-        <package>jenkins</package>
-        <package>git-core</package>
-        <package>subversion</package>
-    </packages>
-    <ports>
-        <port>8080</port>
-    </ports>
-    <repositories>
-        <repository id="jenkins">
-            <entries>
-                <entry>deb http://pkg.jenkins-ci.org/debian binary/</entry>
-            </entries>
-            <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK-----
-        Version: GnuPG v1.4.9 (GNU/Linux)
-
-        mQGiBEmFQG0RBACXScOxb6BTV6rQE/tcJopAEWsdvmE0jNIRWjDDzB7HovX6Anrq
-        n7+Vq4spAReSFbBVaYiiOx2cGDymj2dyx2i9NAI/9/cQXJOU+RPdDzHVlO1Edksp
-        5rKn0cGPWY5sLxRf8s/tO5oyKgwCVgTaB5a8gBHaoGms3nNC4YYf+lqlpwCgjbti
-        3u1iMIx6Rs+dG0+xw1oi5FUD/2tLJMx7vCUQHhPRupeYFPoD8vWpcbGb5nHfHi4U
-        8/x4qZspAIwvXtGw0UBHildGpqe9onp22Syadn/7JgMWhHoFw5Ke/rTMlxREL7pa
-        TiXuagD2G84tjJ66oJP1FigslJzrnG61y85V7THL61OFqDg6IOP4onbsdqHby4VD
-        zZj9A/9uQxIn5250AGLNpARStAcNPJNJbHOQuv0iF3vnG8uO7/oscB0TYb8/juxr
-        hs9GdSN0U0BxENR+8KWy5lttpqLMKlKRknQYy34UstQiyFgAQ9Epncu9uIbVDgWt
-        y7utnqXN033EyYkcWx5EhLAgHkC7wSzeSWABV3JSXN7CeeOif7QiS29oc3VrZSBL
-        YXdhZ3VjaGkgPGtrQGtvaHN1a2Uub3JnPohjBBMRAgAjAhsDBgsJCAcDAgQVAggD
-        BBYCAwECHgECF4AFAko/7vYCGQEACgkQm30y8tUFguabhgCgi54IQR4rpJZ/uUHe
-        ZB879zUWTQwAniQDBO+Zly7Fsvm0Mcvqvl02UzxCtC1Lb2hzdWtlIEthd2FndWNo
-        aSA8a29oc3VrZS5rYXdhZ3VjaGlAc3VuLmNvbT6IYAQTEQIAIAUCSj/qbQIbAwYL
-        CQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEJt9MvLVBYLm38gAoIGR2+TQeJaCeEa8
-        CQhZYzDoiJkQAJ0cpmD+0VA+leOAr5LEccNVd70Z/dHNy83JARAAAQEAAAAAAAAA
-        AAAAAAD/2P/gABBKRklGAAEBAQBgAGAAAP/hAGBFeGlmAABJSSoACAAAAAQAMQEC
-        ABkAAAA+AAAAEFEBAAEAAAABQ5AAEVEEAAEAAAASCwAAElEEAAEAAAASCwAAAAAA
-        AE1hY3JvbWVkaWEgRmlyZXdvcmtzIDQuMAAA/9sAQwAIBgYHBgUIBwcHCQkICgwU
-        DQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy
-        /9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
-        MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgArgCWAwEiAAIRAQMRAf/EAB8AAAEF
-        AQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQEC
-        AwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
-        NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqS
-        k5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk
-        5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkK
-        C//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGx
-        wQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFla
-        Y2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2
-        t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQAC
-        EQMRAD8A9wEj/wB9vzpfMf8Avt+dRinCpGSeY398/nS72/vH86YKBQBJvb+8fzpd
-        7f3j+dMFLQA/e394/nS7j6n86ZSimA7cfU07cfU1HnFOFADtx9aXJ9TTKUUxD8n1
-        pc+9Mp1AC5ozSUtAC0maKKADNFJ2ooAoCnCmilzWZQ6lFJSimAopaQUtAC54rOvN
-        dsLCTZPPGrdwXAry/wCKHxXfRppND0Mq16Bie5PIi9lHdv5V8/X+rXt/O8tzcyyy
-        MclnYkk0avYdl1PqPxT8VtH8NwqwzdXEuSkaHoB61wjftCXhlzHosBjHZpSCa8PW
-        O7uhuAkcDueaaYbhOqMMe1L5lcvWx9U+FPjJ4f8AEU0dpdhtLvXOFWdgY3PoH6fg
-        cV6MrZGa+EklIOJOPqK9i+G3xem0TytI8QSSXGnHCQXJO57f2Pqn6indrclq+x9G
-        5pwNVoLiO4hSaGRZIpFDKynIYHuKmBqyB+aWmg0uaAFopKKAFoozRQBQFLSUorMo
-        UUtJSigB1ZHijWovD/hu+1KZlUQxErnu3YfnWsK8k+Pt60PhaxtAxAnuOQO4UE0P
-        YaWp8/Xd1LeTz3Mzl5pnLuxPJJNa+i+HDclZZ1yp5C1Q0axa+1BEx8i8mvS7S3WG
-        NQo6elcWLxDprljuelgsOp+/IgtdCiVFVYx07CnXHhyNgflA/Ct+1BwOKmkVq8xS
-        m9bnr2S0sec6n4UVo2KKNw6Vx9xby2U3lSAj617NcR5J4zmua1/Q4r+1JVQJU5Ui
-        uzD4qUXyz2OHFYWM1zR3Ol+CHj0xXX/CKajMTHKd1g7H7r94/oeo9wR3r3tWr4ht
-        pZtNv4bmElZ7eVZUIOPmU5/pX2dpOpR6tpFnqMQxHdQpMoz03DOK9ePY8OaszUDU
-        +oFNSg0yUOopKWgAoo6mikBRpwptLWZY4UoptLTELXin7QbD7PoiFv45Gx+Ar2uv
-        FP2g7dfsejXOfm8x48evGf6UmNbnm3hCBls57sJuYnYg9TXSyW2uIgNpJbs5GWDj
-        gewrP8EJu0XIHKyNV2+j1txM0MzIQV8oIQN3POSenHTg15VSV6z2+Z7dGNqKt26G
-        hpeo6rC3lajZxKOgdG6/hW5NcoIC4HOOhrmbJb1IokuZWkfbmUsQQGz2xW5OAbAE
-        Y3d/es5TtJo6oRbjcx7uXVryXbblIIv723JqN9PuUdLhJ2aQf6xW6OP6VBqS6jcQ
-        sLS4aOQHCqH2qVx64znP8verWn2d/DKrPOzxbFBWQ5O7HJyOxParv7t7oxcfeasz
-        z3xBaC01uZV4RxvAr6X+F0rv8NdCMj7iICAfQBjgV87+NYzHr6jHHlA/rX0H8LFa
-        P4baLu3DMTHDDtvOPwr1sM7xR4mK0m/U7lTUyniqyGp1NbtHOmSUuaaDS1JQuaKS
-        ikBTpaQUVmUOpabS0xC15f8AF7wxc+IEsJI3VI4Nyrkfxtjn6YH616hWL4ptDd6B
-        cBTh0+cH0xUVL8j5dzSk0prm2PD/AAnYvp+ltazDbNHM6yD3BrpEiWToOKzPLktr
-        mRiSwlO7J9atQ3bFsCvGnJSlzM+gpLlXKJcpDAegGT+ZqYgPYAgVnz3DpKW8pJW6
-        AM2MUranci38vy4gBz/9alGF3dG0ppKzZYs0ilB4BwauOixggVlW9w8sivsWJuhC
-        nOanmun83bimtNCZPS5g6/osOta3Zq8giRImMjeoyMAe5Oa940SxTStFsbCM/JbQ
-        JGv0AryTTLRLzXIwwDOWVAvfGecCvZx19q9fAttPyPBzCyatuyyhqZTxVdDU612M
-        4ESg04GowacDUFjqKQc0UDKlLSUtZFC0UUCmAtMmiSeF4pBlHBVh7U6imI878Y+G
-        rbTbGC7tFf5WKyFmz1rimZoy2wZJGQBXter2C6lpc9qw++vy/XtXiMoe3upLeTiS
-        Nipry8XSUJJpaHq4Os5JpvUoC4uJr1rYIkJC7vMuGCgj2rZ/4Ry/aHzvtdltO4Ei
-        TPTH+NUrhFlUB1yQODVB8RjyRboR6hiAfqM4rCLTPR6aSt8rktzJc2l7HZgRXLOu
-        4SQPkKPU1fUtu3SHJUc/WqlvGIULKo3kdhgCr+lwfb9ZtLItxLIAx9upp25pKKMq
-        klFN3PTfDenR2mjWbtEvnsm8sVG4buevXpit1aiUAcAYHapVr6GMVGKij5iUnKTk
-        ydKnU1ClSikwRIKcD60wU4GpLQ7PpRSUUhlaikpc1kWLRSUUxC5ozSZozTA5Txn8
-        QtF8DxRDUDLPeTDdFaQAFyucbiTwo+vXsK8huNZHiVJddtbY2/mysfJL7iAD0JwM
-        1h/F+X7V8RtUKybzEUj5PTCjj8KseD2S304WbzxPJ9/CsDjcM4/DvXLjF+6TXc7M
-        F/EafY1YNThkVcttccMpqY3trtx8ufeoJbK3acrLECPcUsmj2EUYfyw27kcmvOjY
-        9NuS6kc+pxp8seWc8Koq7pWox+HLiHWdQSR0gO90jALYxjAzjnmsxbnTbCXMssMK
-        r6nk/h1rH17xLY3lpJa25dw4wWxgfrW9KnOU04owqziotSZ7r4S8daT4xFwunpcR
-        S24DPHOoBweMjBOa6pDXzn8JNej0nxdFbSKqwX6/ZtzHG1s5U59yMfjX0SpwcGvc
-        Wp4MlZltDUoNV42qYGpYIlFOzUYNOBqSx4opBzRSArUtNqrqWqWOj2D32pXcVrap
-        96WVsDPoO5PsOayNC5TXkWKJpZHVI0GWd2AVR7k9K8Z8R/HTazweHNPBHQXd4Ovu
-        sY/9mP4V5Trvi7XPETltW1S4uVzkRM2I1+iDCj8qtRYWPfvEXxh8L6GJIrWZ9Vu1
-        48u1/wBWD7yHj8s15Jr/AMYfFGtyOlvdDS7c5xFZnace7n5j+n0rz1n3Hmmk4zzV
-        KKFcdNPI7s0jM7sxZmY5LE9ST61CsrI25SQR3BwacWzwRUZX0qiblgaheq25bucH
-        18w086tqDrta9uCvp5hqng56UDmp5I9iueXcmDsxyzEn1JqROvNQKD7VKCqDJOas
-        kuRuMgjp711+n/FHxVpyIsWqNPHEAojukWQEe5PP61wvnEj0B4ApykZJJ7UDPfvD
-        Hxp0+/dLfXbYWMp4E8RLxH6jqv616laXtve26XFrPFPC/KyRsGU/iK+MBICcDitn
-        QPFWseHbvztMv5YM/eTOUb6qeDRcXKj7CV8ing1434V+NtpezR2niC3W0Y8fa4cm
-        PP8AtL1H1Ga9atrqG6gSe3mjmhcZSSNgysPYikTZouCiow4xRRYLmRr+tW/h7Qrv
-        Vbkbo7dCwQHBdugUfU4r5Y8TeKtV8Tak15qlwztk+XEDiOFf7qL2H6nvXr3x01n7
-        Po2n6SjfNcymaQf7K8D9T+leBzPuT3H8qiC0NHoNeYnvURc4phPNITmrJuLu5pSa
-        Z3pRyKYhM80oOaaetAoAkzwKTd6Cm5pBQA8EnqTijOSeOKaT2oHSgY7cTTg1Rilp
-        AS7/AGpc4UA96iHJApXbk0wJ0kOeDXTeGPGer+GbtZNOunWMnLwscxv9V/ya5T7q
-        D1NOEhQYHU9/Siw0z7A8KeJ7XxToceo2ymNs7JoicmNx1HuOcg0V5j8A9RQnWNKl
-        lVARHcruOOfut/7LRTViJaPQ5b42agbrx29uGytrAiAehPJ/nXmrNu2H14NdD481
-        A6j401S6zkPMQPoOP6VzQOcj0OaiGxctxpNA5obqfrQKokSlWkzQDzQAMOaSnN1F
-        JQAtFFFAAKKKO9AC0UlGaBj0HemjlvrTkOEY03vQIe7YJP4CkTBfn6mkbkA/Wkzg
-        YHU9aYGtpl7Pau8kEzxMwwShwcUVUtWIU4oqbXLTFv3M0jSkksWJP481SU/Pk1Ym
-        b7/1FViMY96diWKwy5+tITTm+7mo6BC0DrR2oHWgB7dBTac3SmUALS0lKOtACUua
-        KKACm0vSk70ASLxF9TSYzznrQf8AVqKTPH40wHHHQfjTM55pTwp9+KQdKALEL7Is
-        +poph4Cr6Cigdz//2YhgBBMRAgAgBQJKP/cgAhsDBgsJCAcDAgQVAggDBBYCAwEC
-        HgECF4AACgkQm30y8tUFgua3awCdFQlChLgn/n4tb4jLe1RgxOxHxosAn2Cn2oNh
-        sZ91wUb4d5JuH88TCupsuQINBEmFQG0QCADqAXWgiis4yi96os3QZmK5809ojjTT
-        nlICgbztrT55cMVTDBc9SneyRQlC0cS+M1z4Do6lj81sNJdJiBPqTYYA1+exTFvs
-        5zCxPInDP3hvqXxHTP142XN1hdzt53R7smn8O0wyO+RCBUb44e9NkusvBd5UP3Je
-        449hnpXJ4WO3cVMFm4ghxs7ERlpAi5NTEsVVdM8dqHbZJtk8gbzdAHH0ybiAXmWy
-        LFGZDuuKiFAkqm/Wled7id6N+cPx107dwBclwPxzfEYKEqJ1YDDHoDlyfx4012y1
-        53e5sGyah/IPBYrrLMfG+Wmiwr5nCX0tmwOcyukuE94hbzJCX2wBdbWLAAMGCACz
-        l3cuM4lGt/wr5liM4gotXpZAopY+EnbLIBuOHFXXR7HnyAgST1jH/AUbafvPjyDh
-        EkFDyUP14XtHNIAqsN1UpuyYbM90bMPAWXJxrazMsSF+Tv5yIxHiy4cc1pjoqHA2
-        kwqIGHmTxYzOPOS19ZWQAtevoTE6pCARphY0dzpscCWaXGs/ZqNAhjL96WLYV1Oo
-        Ut+9mTnOcs6Vuxaxp2wN2S5DK1S9gdIxWEc8wMUPiQe8CYk0OySdORIblMs3bGqD
-        FoM5HcBAZP1YlXitPH2nIRv0DtOQGMQOCkqUWmQuQAUgKV+YO86lO4S7EhTET/GP
-        sQb6P7efm/Cs8wbq/wyIiEkEGBECAAkFAkmFQG0CGwwACgkQm30y8tUFgua2mACe
-        JNBW4snDC4OzjKU6QT386/GA9ssAn3vLzSwn8N1xv5MihWGr5kVzvaE2
-        =cjdq
-        -----END PGP PUBLIC KEY BLOCK-----
-    ]]></key>
-        </repository>
-    </repositories>
-</template>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/features.xml b/core/src/main/resources/features.xml
index 62ec269..cc9b586 100644
--- a/core/src/main/resources/features.xml
+++ b/core/src/main/resources/features.xml
@@ -16,7 +16,7 @@
   ~ limitations under the License.
   -->
 
-<features name="axemblr-provisionr-core-features-${project.version}"
+<features name="provisionr-core-features-${project.version}"
           xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
 
     <feature name="activiti-karaf" version="${activiti.version}">
@@ -36,7 +36,7 @@
         <bundle start="true">mvn:org.activiti/activiti-osgi/${activiti.version}</bundle>
     </feature>
 
-    <feature name="axemblr-provisionr-core" version="${project.version}">
+    <feature name="provisionr-core" version="${project.version}">
         <feature version="${activiti.version}">activiti-karaf</feature>
 
         <bundle dependency="true">mvn:com.google.code.gson/gson/${gson.version}</bundle>
@@ -46,29 +46,31 @@
         <bundle dependency="true">
             mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jzlib/${jzlib.bundle.version}
         </bundle>
-        <bundle dependency="true">wrap:mvn:com.github.spullara.mustache.java/compiler/${mustache.version}</bundle>
+        <bundle dependency="true">
+            wrap:mvn:com.github.spullara.mustache.java/compiler/${mustache.version}
+        </bundle>
 
-        <bundle start="true">mvn:com.axemblr.provisionr/provisionr-api/${project.version}</bundle>
-        <bundle start="true">mvn:com.axemblr.provisionr/provisionr-core/${project.version}</bundle>
+        <bundle start="true">mvn:org.apache.provisionr/provisionr-api/${project.version}</bundle>
+        <bundle start="true">mvn:org.apache.provisionr/provisionr-core/${project.version}</bundle>
 
-        <configfile finalname="/etc/com.axemblr.provisionr.cfg">
-            mvn:com.axemblr.provisionr/provisionr-core/${project.version}/cfg/defaults
+        <configfile finalname="/etc/org.apache.provisionr.cfg">
+            mvn:org.apache.provisionr/provisionr-core/${project.version}/cfg/defaults
         </configfile>
 
         <configfile finalname="/etc/org.apache.felix.fileinstall-templates.cfg">
-            mvn:com.axemblr.provisionr/provisionr-core/${project.version}/cfg/fileinstall
+            mvn:org.apache.provisionr/provisionr-core/${project.version}/cfg/fileinstall
         </configfile>
 
         <configfile finalname="/templates/cdh3.xml">
-            mvn:com.axemblr.provisionr/provisionr-core/${project.version}/template/cdh3
+            mvn:org.apache.provisionr/provisionr-core/${project.version}/template/cdh3
         </configfile>
 
         <configfile finalname="/templates/cdh4.xml">
-            mvn:com.axemblr.provisionr/provisionr-core/${project.version}/template/cdh4
+            mvn:org.apache.provisionr/provisionr-core/${project.version}/template/cdh4
         </configfile>
 
         <configfile finalname="/templates/jenkins.xml">
-            mvn:com.axemblr.provisionr/provisionr-core/${project.version}/template/jenkins
+            mvn:org.apache.provisionr/provisionr-core/${project.version}/template/jenkins
         </configfile>
     </feature>
 </features>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/org.apache.provisionr.cfg
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org.apache.provisionr.cfg b/core/src/main/resources/org.apache.provisionr.cfg
new file mode 100644
index 0000000..cc2e4a4
--- /dev/null
+++ b/core/src/main/resources/org.apache.provisionr.cfg
@@ -0,0 +1,37 @@
+
+#
+# Database configuration
+#
+
+# We use MVCC to enable row-level locking on h2. This avoids transaction dead locks.
+activiti.db.url=jdbc:h2:data/state;MVCC=TRUE;DB_CLOSE_DELAY=-1
+
+activiti.db.user=sa
+# activiti.db.password=
+
+activiti.db.schemaUpdate=true
+
+#
+# Job Executor configuration
+#
+
+activiti.executor.queueSize=30
+
+activiti.executor.corePoolSize=15
+activiti.executor.maxPoolSize=100
+
+activiti.executor.maxJobsPerAcquisition=30
+
+# between two job acquisitions
+activiti.executor.waitTimeInMillis=1000
+activiti.executor.lockTimeInMillis=600000
+
+
+#
+# Job Retries
+#
+
+# Use -1 for infinity
+activiti.job.maxNumberOfRetries=13
+activiti.job.timeBetweenRetriesInSeconds=10
+

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/org/apache/provisionr/core/puppet/files.pp.mustache
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/provisionr/core/puppet/files.pp.mustache b/core/src/main/resources/org/apache/provisionr/core/puppet/files.pp.mustache
new file mode 100644
index 0000000..e13abb2
--- /dev/null
+++ b/core/src/main/resources/org/apache/provisionr/core/puppet/files.pp.mustache
@@ -0,0 +1,25 @@
+
+package { "wget":
+  ensure => "installed"
+}
+
+define download_file(
+  $uri,
+  $timeout = 300,
+  $user_agent = "Apache Provisionr (http://provisionr.incubator.apache.org/)"
+) {
+  exec { $name:
+    command => "/usr/bin/wget --no-check-certificate -nv -U '${user_agent}' ${uri} -O ${name}",
+    timeout => $timeout, # seconds
+    logoutput => true,
+    tries => 3,
+    try_sleep => 5, # seconds
+    require => Package["wget"]
+  }
+}
+
+{{#files}}
+download_file {"{{destination}}":
+  uri => "{{source}}"
+}
+{{/files}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/org/apache/provisionr/core/puppet/packages.pp.mustache
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/provisionr/core/puppet/packages.pp.mustache b/core/src/main/resources/org/apache/provisionr/core/puppet/packages.pp.mustache
new file mode 100644
index 0000000..0826e53
--- /dev/null
+++ b/core/src/main/resources/org/apache/provisionr/core/puppet/packages.pp.mustache
@@ -0,0 +1,7 @@
+
+# Ensure all packages listed bellow are installed
+Package { ensure => "installed" }
+
+{{#packages}}
+package { "{{package}}": }
+{{/packages}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/org/apache/provisionr/core/puppet/repositories.pp.mustache
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/provisionr/core/puppet/repositories.pp.mustache b/core/src/main/resources/org/apache/provisionr/core/puppet/repositories.pp.mustache
new file mode 100644
index 0000000..67c4385
--- /dev/null
+++ b/core/src/main/resources/org/apache/provisionr/core/puppet/repositories.pp.mustache
@@ -0,0 +1,38 @@
+# Register repositories and refresh index
+
+define apt::repository (
+  $content,
+  $key,
+  $apt_sources_dir = "/etc/apt/sources.list.d"
+) {
+  file { "apt::repository ${name}":
+    path    => "${apt_sources_dir}/${name}.list",
+    content => "${content}\n",
+    owner   => root,
+    group   => root,
+    mode    => 0644,
+    ensure  => present
+  }
+  file { "/tmp/${name}.key":
+    content => "${key}"
+  }
+  exec { "apt-key add ${name}":
+    command => "/usr/bin/apt-key add /tmp/${name}.key",
+    unless  => "/usr/bin/apt-key list | /bin/grep -c ${name}",
+    require => File["/tmp/${name}.key"],
+  }
+  exec { "apt-get update ${name}":
+    command => "/usr/bin/apt-get update",
+    require => [Exec["apt-key add ${name}"], File["apt::repository ${name}"]]
+  }
+}
+
+{{#repositories}}
+apt::repository { "{{name}}":
+  content => "{{content}}\n",
+  key => "{{key}}"
+}
+{{/repositories}}
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/org/apache/provisionr/core/templates/cdh3.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/provisionr/core/templates/cdh3.xml b/core/src/main/resources/org/apache/provisionr/core/templates/cdh3.xml
new file mode 100644
index 0000000..a289182
--- /dev/null
+++ b/core/src/main/resources/org/apache/provisionr/core/templates/cdh3.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template id="cdh3" os-version="10.04 LTS">
+    <description>
+        Cloudera CDH3 template for Ubuntu 10.04 LTS (lucid) including the Cloudera Manager installer
+    </description>
+    <packages>
+        <package>cloudera-manager-agent</package>
+        <package>cloudera-manager-daemons</package>
+        <package>oracle-j2sdk1.6</package>
+        <package>hadoop-0.20</package>
+        <package>hadoop-0.20-native</package>
+        <package>hadoop-hive</package>
+        <package>hadoop-pig</package>
+        <package>oozie-client</package>
+        <package>oozie</package>
+        <package>hue-plugins</package>
+        <package>hue-common</package>
+        <package>hue-proxy</package>
+        <package>hue-about</package>
+        <package>hue-help</package>
+        <package>hue-filebrowser</package>
+        <package>hue-jobsub</package>
+        <package>hue-beeswax</package>
+        <package>hue-useradmin</package>
+        <package>hue-shell</package>
+        <package>hue</package>
+    </packages>
+    <ports>
+        <port>7180</port>
+        <port>8888</port>
+        <port>8080</port>
+    </ports>
+    <files>
+        <file source="http://archive.cloudera.com/cm4/installer/latest/cloudera-manager-installer.bin"
+              destination="/opt/cloudera-manager-installer.bin"/>
+    </files>
+    <repositories>
+        <repository id="cloudera-cdh3">
+            <entries>
+                <entry>deb http://archive.cloudera.com/debian lucid-cdh3 contrib</entry>
+            </entries>
+            <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.9 (GNU/Linux)
+
+mQGiBEnvgi0RBADLx1qQlXlrvHOo13dUvoWL97Ny/0s0S/GcMEgAqYvZzUPVcq8H
+GUsOb4PLTfcL1H7Ptq9fqr02uIb5Bc/ltdwE9GFaT2nvdfBx9T8jr8LrW9JE2xJq
+dCyFO5yP9YbZeFAxNO3yBxeP85lQ9CdWWLvyYdtQ+T84EYerqkcVbSvYRwCg6zyx
+EE3jWYvyVv/3HTrVTYpgHgMD/2kMR1Z2vEYOSM7h4cnRnxiadhefqJ2WCm4L30Rx
+/F9JBLAEuIuUndiOShoB043iDY+rrqCHqHQ/uI2D4piW9cDYMo7EJlsFtQ5g2SFg
+PcS4+DLhU464dTQsTGAhvcv+F0VQV4iu1HdD2/kKJkCS/MZL4rr4emqsh6VIBDdG
+ytPaA/9cyRJZe2BrBM2pECGncE5RUaM3g37Ka+VnmMVOXgZdzgCxwFZyVhyxzssD
+kB4jcm75UEZx8BiaoPQDQEsBongdx5M4Vwv5XnvUq7sK7eZLmUzW9hmkPjgLea0/
+znchvPsLeTNqSfIcH14TbFt6B2y1G3Vbi5/6UiAaIqLrqjZlCrQXQ2xvdWRlcmEg
+QXB0IFJlcG9zaXRvcnmIYAQTEQIAIAUCSe+CLQIbAwYLCQgHAwIEFQIIAwQWAgMB
+Ah4BAheAAAoJEDJ1dO4CqBjdGQUAnitydC/NGEh0aZXDN1v22pWFpRzTAJ46N4gT
+Zx25oWfyppX3R7fSH+7TPrkCDQRJ74ItEAgAq8s4iMsGhk9nnMF6wlarqHjws4Dw
+NFZBzA1Ah8KnMtrdr8t99OfzY1b7PNzHXujcaTTqL6L881ezdsls9aHp2kr24Btr
+8nqEZJHSjCnQscAGu+NrhoH2KvK+tMRCHGRcy5UNQbLTJi4Hf8Lo+zv0WUy9BCDu
+7HoDlwrrh1Rw5oOwLFc2UXSTEB6BwYna0mZcNjVpfKNHa//wJcKR0AtsCwRT9znP
+GS0Hpqi1l0/iU7sJhNWyyF427ANg+Jv2n4IP+dd734ZiFeJ9tWCtBjfc3MZJKETk
+tiCtX7FVIIqBAmYLwPqcvZMGJMrNzLBtRuuiBv5bFcPpMEhoD40oQEG8uwADBQf/
+f3NpQbuAcZLMzbrHYu3FB/+4ETvDJXJIEUiQUdobWancSBUhuNPOqIgLzIWM1jRu
+jWGIpkeP6iqNW9kDrq26CuMFP2CoVvnaMiLXUvyf62HWAiYXXlZle5O97bvhYMtM
+Y4o5sMo2ktI9IcgYIFicFwcmuGyGL7nJ3Bo9FAUV2LvMe++O/f13jsPpygoTZgGT
+6w0erglWgrgf5pXt8ajlI4TUrlMVg9Iy/tB9ZzVHnpk21o4vLHwZkgXe1WlK/Rze
+ZCruXyXHaFyEJN2zlP2xNj2F2WisL+/HEnl/qzU4IpNI2LQV2aiY9Nt8MBXgSHAh
+gWKWkjiB+tswgzuNsBOTM4hJBBgRAgAJBQJJ74ItAhsMAAoJEDJ1dO4CqBjd988A
+oJ1WlEx2BcFA7W1RMyErejcvB6thAKCf3t0thSQvkoGi3AOJ4Haj/C3yUQ==
+=H6IR
+-----END PGP PUBLIC KEY BLOCK-----]]></key>
+        </repository>
+        <repository id="cloudera-cm4">
+            <entries>
+                <entry>deb http://archive.cloudera.com/cm4/ubuntu/lucid/amd64/cm lucid-cm4 contrib</entry>
+                <entry>deb-src http://archive.cloudera.com/cm4/ubuntu/lucid/amd64/cm lucid-cm4 contrib</entry>
+            </entries>
+            <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.9 (GNU/Linux)
+
+mQGiBEnvgi0RBADLx1qQlXlrvHOo13dUvoWL97Ny/0s0S/GcMEgAqYvZzUPVcq8H
+GUsOb4PLTfcL1H7Ptq9fqr02uIb5Bc/ltdwE9GFaT2nvdfBx9T8jr8LrW9JE2xJq
+dCyFO5yP9YbZeFAxNO3yBxeP85lQ9CdWWLvyYdtQ+T84EYerqkcVbSvYRwCg6zyx
+EE3jWYvyVv/3HTrVTYpgHgMD/2kMR1Z2vEYOSM7h4cnRnxiadhefqJ2WCm4L30Rx
+/F9JBLAEuIuUndiOShoB043iDY+rrqCHqHQ/uI2D4piW9cDYMo7EJlsFtQ5g2SFg
+PcS4+DLhU464dTQsTGAhvcv+F0VQV4iu1HdD2/kKJkCS/MZL4rr4emqsh6VIBDdG
+ytPaA/9cyRJZe2BrBM2pECGncE5RUaM3g37Ka+VnmMVOXgZdzgCxwFZyVhyxzssD
+kB4jcm75UEZx8BiaoPQDQEsBongdx5M4Vwv5XnvUq7sK7eZLmUzW9hmkPjgLea0/
+znchvPsLeTNqSfIcH14TbFt6B2y1G3Vbi5/6UiAaIqLrqjZlCrQXQ2xvdWRlcmEg
+QXB0IFJlcG9zaXRvcnmIYAQTEQIAIAUCSe+CLQIbAwYLCQgHAwIEFQIIAwQWAgMB
+Ah4BAheAAAoJEDJ1dO4CqBjdGQUAnitydC/NGEh0aZXDN1v22pWFpRzTAJ46N4gT
+Zx25oWfyppX3R7fSH+7TPrkCDQRJ74ItEAgAq8s4iMsGhk9nnMF6wlarqHjws4Dw
+NFZBzA1Ah8KnMtrdr8t99OfzY1b7PNzHXujcaTTqL6L881ezdsls9aHp2kr24Btr
+8nqEZJHSjCnQscAGu+NrhoH2KvK+tMRCHGRcy5UNQbLTJi4Hf8Lo+zv0WUy9BCDu
+7HoDlwrrh1Rw5oOwLFc2UXSTEB6BwYna0mZcNjVpfKNHa//wJcKR0AtsCwRT9znP
+GS0Hpqi1l0/iU7sJhNWyyF427ANg+Jv2n4IP+dd734ZiFeJ9tWCtBjfc3MZJKETk
+tiCtX7FVIIqBAmYLwPqcvZMGJMrNzLBtRuuiBv5bFcPpMEhoD40oQEG8uwADBQf/
+f3NpQbuAcZLMzbrHYu3FB/+4ETvDJXJIEUiQUdobWancSBUhuNPOqIgLzIWM1jRu
+jWGIpkeP6iqNW9kDrq26CuMFP2CoVvnaMiLXUvyf62HWAiYXXlZle5O97bvhYMtM
+Y4o5sMo2ktI9IcgYIFicFwcmuGyGL7nJ3Bo9FAUV2LvMe++O/f13jsPpygoTZgGT
+6w0erglWgrgf5pXt8ajlI4TUrlMVg9Iy/tB9ZzVHnpk21o4vLHwZkgXe1WlK/Rze
+ZCruXyXHaFyEJN2zlP2xNj2F2WisL+/HEnl/qzU4IpNI2LQV2aiY9Nt8MBXgSHAh
+gWKWkjiB+tswgzuNsBOTM4hJBBgRAgAJBQJJ74ItAhsMAAoJEDJ1dO4CqBjd988A
+oJ1WlEx2BcFA7W1RMyErejcvB6thAKCf3t0thSQvkoGi3AOJ4Haj/C3yUQ==
+=H6IR
+-----END PGP PUBLIC KEY BLOCK-----]]></key>
+        </repository>
+    </repositories>
+</template>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/org/apache/provisionr/core/templates/cdh4.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/provisionr/core/templates/cdh4.xml b/core/src/main/resources/org/apache/provisionr/core/templates/cdh4.xml
new file mode 100644
index 0000000..bd9181b
--- /dev/null
+++ b/core/src/main/resources/org/apache/provisionr/core/templates/cdh4.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template id="cdh4" os-version="10.04 LTS">
+    <description>
+        Cloudera CDH4 template for Ubuntu 10.04 LTS (lucid)
+    </description>
+    <packages>
+        <package>openjdk-6-jdk</package>
+        <package>hadoop-0.20-mapreduce-jobtracker</package>
+        <package>hadoop-hdfs-namenode</package>
+        <package>hadoop-0.20-mapreduce-tasktracker</package>
+        <package>hadoop-hdfs-datanode</package>
+        <package>hadoop-client</package>
+        <package>xmlstarlet</package>
+    </packages>
+    <ports>
+        <port>7180</port>
+        <port>8888</port>
+        <port>8080</port>
+        <port>8020</port>
+        <port>50010</port>
+        <port>50020</port>
+    </ports>
+    <repositories>
+        <repository id="cloudera-cdh4">
+            <entries>
+                <entry>deb [arch=amd64] http://archive.cloudera.com/cdh4/ubuntu/lucid/amd64/cdh lucid-cdh4 contrib</entry>
+            </entries>
+            <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.9 (GNU/Linux)
+
+mQGiBEnvgi0RBADLx1qQlXlrvHOo13dUvoWL97Ny/0s0S/GcMEgAqYvZzUPVcq8H
+GUsOb4PLTfcL1H7Ptq9fqr02uIb5Bc/ltdwE9GFaT2nvdfBx9T8jr8LrW9JE2xJq
+dCyFO5yP9YbZeFAxNO3yBxeP85lQ9CdWWLvyYdtQ+T84EYerqkcVbSvYRwCg6zyx
+EE3jWYvyVv/3HTrVTYpgHgMD/2kMR1Z2vEYOSM7h4cnRnxiadhefqJ2WCm4L30Rx
+/F9JBLAEuIuUndiOShoB043iDY+rrqCHqHQ/uI2D4piW9cDYMo7EJlsFtQ5g2SFg
+PcS4+DLhU464dTQsTGAhvcv+F0VQV4iu1HdD2/kKJkCS/MZL4rr4emqsh6VIBDdG
+ytPaA/9cyRJZe2BrBM2pECGncE5RUaM3g37Ka+VnmMVOXgZdzgCxwFZyVhyxzssD
+kB4jcm75UEZx8BiaoPQDQEsBongdx5M4Vwv5XnvUq7sK7eZLmUzW9hmkPjgLea0/
+znchvPsLeTNqSfIcH14TbFt6B2y1G3Vbi5/6UiAaIqLrqjZlCrQXQ2xvdWRlcmEg
+QXB0IFJlcG9zaXRvcnmIYAQTEQIAIAUCSe+CLQIbAwYLCQgHAwIEFQIIAwQWAgMB
+Ah4BAheAAAoJEDJ1dO4CqBjdGQUAnitydC/NGEh0aZXDN1v22pWFpRzTAJ46N4gT
+Zx25oWfyppX3R7fSH+7TPrkCDQRJ74ItEAgAq8s4iMsGhk9nnMF6wlarqHjws4Dw
+NFZBzA1Ah8KnMtrdr8t99OfzY1b7PNzHXujcaTTqL6L881ezdsls9aHp2kr24Btr
+8nqEZJHSjCnQscAGu+NrhoH2KvK+tMRCHGRcy5UNQbLTJi4Hf8Lo+zv0WUy9BCDu
+7HoDlwrrh1Rw5oOwLFc2UXSTEB6BwYna0mZcNjVpfKNHa//wJcKR0AtsCwRT9znP
+GS0Hpqi1l0/iU7sJhNWyyF427ANg+Jv2n4IP+dd734ZiFeJ9tWCtBjfc3MZJKETk
+tiCtX7FVIIqBAmYLwPqcvZMGJMrNzLBtRuuiBv5bFcPpMEhoD40oQEG8uwADBQf/
+f3NpQbuAcZLMzbrHYu3FB/+4ETvDJXJIEUiQUdobWancSBUhuNPOqIgLzIWM1jRu
+jWGIpkeP6iqNW9kDrq26CuMFP2CoVvnaMiLXUvyf62HWAiYXXlZle5O97bvhYMtM
+Y4o5sMo2ktI9IcgYIFicFwcmuGyGL7nJ3Bo9FAUV2LvMe++O/f13jsPpygoTZgGT
+6w0erglWgrgf5pXt8ajlI4TUrlMVg9Iy/tB9ZzVHnpk21o4vLHwZkgXe1WlK/Rze
+ZCruXyXHaFyEJN2zlP2xNj2F2WisL+/HEnl/qzU4IpNI2LQV2aiY9Nt8MBXgSHAh
+gWKWkjiB+tswgzuNsBOTM4hJBBgRAgAJBQJJ74ItAhsMAAoJEDJ1dO4CqBjd988A
+oJ1WlEx2BcFA7W1RMyErejcvB6thAKCf3t0thSQvkoGi3AOJ4Haj/C3yUQ==
+=H6IR
+-----END PGP PUBLIC KEY BLOCK-----]]></key>
+        </repository>
+    </repositories>
+</template>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/resources/org/apache/provisionr/core/templates/jenkins.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/provisionr/core/templates/jenkins.xml b/core/src/main/resources/org/apache/provisionr/core/templates/jenkins.xml
new file mode 100644
index 0000000..c7297f3
--- /dev/null
+++ b/core/src/main/resources/org/apache/provisionr/core/templates/jenkins.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template id="jenkins">
+    <description>A short template that installs the latest jenkins with git &amp; svn</description>
+    <packages>
+        <package>jenkins</package>
+        <package>git-core</package>
+        <package>subversion</package>
+    </packages>
+    <ports>
+        <port>8080</port>
+    </ports>
+    <repositories>
+        <repository id="jenkins">
+            <entries>
+                <entry>deb http://pkg.jenkins-ci.org/debian binary/</entry>
+            </entries>
+            <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK-----
+        Version: GnuPG v1.4.9 (GNU/Linux)
+
+        mQGiBEmFQG0RBACXScOxb6BTV6rQE/tcJopAEWsdvmE0jNIRWjDDzB7HovX6Anrq
+        n7+Vq4spAReSFbBVaYiiOx2cGDymj2dyx2i9NAI/9/cQXJOU+RPdDzHVlO1Edksp
+        5rKn0cGPWY5sLxRf8s/tO5oyKgwCVgTaB5a8gBHaoGms3nNC4YYf+lqlpwCgjbti
+        3u1iMIx6Rs+dG0+xw1oi5FUD/2tLJMx7vCUQHhPRupeYFPoD8vWpcbGb5nHfHi4U
+        8/x4qZspAIwvXtGw0UBHildGpqe9onp22Syadn/7JgMWhHoFw5Ke/rTMlxREL7pa
+        TiXuagD2G84tjJ66oJP1FigslJzrnG61y85V7THL61OFqDg6IOP4onbsdqHby4VD
+        zZj9A/9uQxIn5250AGLNpARStAcNPJNJbHOQuv0iF3vnG8uO7/oscB0TYb8/juxr
+        hs9GdSN0U0BxENR+8KWy5lttpqLMKlKRknQYy34UstQiyFgAQ9Epncu9uIbVDgWt
+        y7utnqXN033EyYkcWx5EhLAgHkC7wSzeSWABV3JSXN7CeeOif7QiS29oc3VrZSBL
+        YXdhZ3VjaGkgPGtrQGtvaHN1a2Uub3JnPohjBBMRAgAjAhsDBgsJCAcDAgQVAggD
+        BBYCAwECHgECF4AFAko/7vYCGQEACgkQm30y8tUFguabhgCgi54IQR4rpJZ/uUHe
+        ZB879zUWTQwAniQDBO+Zly7Fsvm0Mcvqvl02UzxCtC1Lb2hzdWtlIEthd2FndWNo
+        aSA8a29oc3VrZS5rYXdhZ3VjaGlAc3VuLmNvbT6IYAQTEQIAIAUCSj/qbQIbAwYL
+        CQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEJt9MvLVBYLm38gAoIGR2+TQeJaCeEa8
+        CQhZYzDoiJkQAJ0cpmD+0VA+leOAr5LEccNVd70Z/dHNy83JARAAAQEAAAAAAAAA
+        AAAAAAD/2P/gABBKRklGAAEBAQBgAGAAAP/hAGBFeGlmAABJSSoACAAAAAQAMQEC
+        ABkAAAA+AAAAEFEBAAEAAAABQ5AAEVEEAAEAAAASCwAAElEEAAEAAAASCwAAAAAA
+        AE1hY3JvbWVkaWEgRmlyZXdvcmtzIDQuMAAA/9sAQwAIBgYHBgUIBwcHCQkICgwU
+        DQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy
+        /9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
+        MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgArgCWAwEiAAIRAQMRAf/EAB8AAAEF
+        AQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQEC
+        AwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
+        NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqS
+        k5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk
+        5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkK
+        C//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGx
+        wQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFla
+        Y2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2
+        t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQAC
+        EQMRAD8A9wEj/wB9vzpfMf8Avt+dRinCpGSeY398/nS72/vH86YKBQBJvb+8fzpd
+        7f3j+dMFLQA/e394/nS7j6n86ZSimA7cfU07cfU1HnFOFADtx9aXJ9TTKUUxD8n1
+        pc+9Mp1AC5ozSUtAC0maKKADNFJ2ooAoCnCmilzWZQ6lFJSimAopaQUtAC54rOvN
+        dsLCTZPPGrdwXAry/wCKHxXfRppND0Mq16Bie5PIi9lHdv5V8/X+rXt/O8tzcyyy
+        MclnYkk0avYdl1PqPxT8VtH8NwqwzdXEuSkaHoB61wjftCXhlzHosBjHZpSCa8PW
+        O7uhuAkcDueaaYbhOqMMe1L5lcvWx9U+FPjJ4f8AEU0dpdhtLvXOFWdgY3PoH6fg
+        cV6MrZGa+EklIOJOPqK9i+G3xem0TytI8QSSXGnHCQXJO57f2Pqn6indrclq+x9G
+        5pwNVoLiO4hSaGRZIpFDKynIYHuKmBqyB+aWmg0uaAFopKKAFoozRQBQFLSUorMo
+        UUtJSigB1ZHijWovD/hu+1KZlUQxErnu3YfnWsK8k+Pt60PhaxtAxAnuOQO4UE0P
+        YaWp8/Xd1LeTz3Mzl5pnLuxPJJNa+i+HDclZZ1yp5C1Q0axa+1BEx8i8mvS7S3WG
+        NQo6elcWLxDprljuelgsOp+/IgtdCiVFVYx07CnXHhyNgflA/Ct+1BwOKmkVq8xS
+        m9bnr2S0sec6n4UVo2KKNw6Vx9xby2U3lSAj617NcR5J4zmua1/Q4r+1JVQJU5Ui
+        uzD4qUXyz2OHFYWM1zR3Ol+CHj0xXX/CKajMTHKd1g7H7r94/oeo9wR3r3tWr4ht
+        pZtNv4bmElZ7eVZUIOPmU5/pX2dpOpR6tpFnqMQxHdQpMoz03DOK9ePY8OaszUDU
+        +oFNSg0yUOopKWgAoo6mikBRpwptLWZY4UoptLTELXin7QbD7PoiFv45Gx+Ar2uv
+        FP2g7dfsejXOfm8x48evGf6UmNbnm3hCBls57sJuYnYg9TXSyW2uIgNpJbs5GWDj
+        gewrP8EJu0XIHKyNV2+j1txM0MzIQV8oIQN3POSenHTg15VSV6z2+Z7dGNqKt26G
+        hpeo6rC3lajZxKOgdG6/hW5NcoIC4HOOhrmbJb1IokuZWkfbmUsQQGz2xW5OAbAE
+        Y3d/es5TtJo6oRbjcx7uXVryXbblIIv723JqN9PuUdLhJ2aQf6xW6OP6VBqS6jcQ
+        sLS4aOQHCqH2qVx64znP8verWn2d/DKrPOzxbFBWQ5O7HJyOxParv7t7oxcfeasz
+        z3xBaC01uZV4RxvAr6X+F0rv8NdCMj7iICAfQBjgV87+NYzHr6jHHlA/rX0H8LFa
+        P4baLu3DMTHDDtvOPwr1sM7xR4mK0m/U7lTUyniqyGp1NbtHOmSUuaaDS1JQuaKS
+        ikBTpaQUVmUOpabS0xC15f8AF7wxc+IEsJI3VI4Nyrkfxtjn6YH616hWL4ptDd6B
+        cBTh0+cH0xUVL8j5dzSk0prm2PD/AAnYvp+ltazDbNHM6yD3BrpEiWToOKzPLktr
+        mRiSwlO7J9atQ3bFsCvGnJSlzM+gpLlXKJcpDAegGT+ZqYgPYAgVnz3DpKW8pJW6
+        AM2MUranci38vy4gBz/9alGF3dG0ppKzZYs0ilB4BwauOixggVlW9w8sivsWJuhC
+        nOanmun83bimtNCZPS5g6/osOta3Zq8giRImMjeoyMAe5Oa940SxTStFsbCM/JbQ
+        JGv0AryTTLRLzXIwwDOWVAvfGecCvZx19q9fAttPyPBzCyatuyyhqZTxVdDU612M
+        4ESg04GowacDUFjqKQc0UDKlLSUtZFC0UUCmAtMmiSeF4pBlHBVh7U6imI878Y+G
+        rbTbGC7tFf5WKyFmz1rimZoy2wZJGQBXter2C6lpc9qw++vy/XtXiMoe3upLeTiS
+        Nipry8XSUJJpaHq4Os5JpvUoC4uJr1rYIkJC7vMuGCgj2rZ/4Ry/aHzvtdltO4Ei
+        TPTH+NUrhFlUB1yQODVB8RjyRboR6hiAfqM4rCLTPR6aSt8rktzJc2l7HZgRXLOu
+        4SQPkKPU1fUtu3SHJUc/WqlvGIULKo3kdhgCr+lwfb9ZtLItxLIAx9upp25pKKMq
+        klFN3PTfDenR2mjWbtEvnsm8sVG4buevXpit1aiUAcAYHapVr6GMVGKij5iUnKTk
+        ydKnU1ClSikwRIKcD60wU4GpLQ7PpRSUUhlaikpc1kWLRSUUxC5ozSZozTA5Txn8
+        QtF8DxRDUDLPeTDdFaQAFyucbiTwo+vXsK8huNZHiVJddtbY2/mysfJL7iAD0JwM
+        1h/F+X7V8RtUKybzEUj5PTCjj8KseD2S304WbzxPJ9/CsDjcM4/DvXLjF+6TXc7M
+        F/EafY1YNThkVcttccMpqY3trtx8ufeoJbK3acrLECPcUsmj2EUYfyw27kcmvOjY
+        9NuS6kc+pxp8seWc8Koq7pWox+HLiHWdQSR0gO90jALYxjAzjnmsxbnTbCXMssMK
+        r6nk/h1rH17xLY3lpJa25dw4wWxgfrW9KnOU04owqziotSZ7r4S8daT4xFwunpcR
+        S24DPHOoBweMjBOa6pDXzn8JNej0nxdFbSKqwX6/ZtzHG1s5U59yMfjX0SpwcGvc
+        Wp4MlZltDUoNV42qYGpYIlFOzUYNOBqSx4opBzRSArUtNqrqWqWOj2D32pXcVrap
+        96WVsDPoO5PsOayNC5TXkWKJpZHVI0GWd2AVR7k9K8Z8R/HTazweHNPBHQXd4Ovu
+        sY/9mP4V5Trvi7XPETltW1S4uVzkRM2I1+iDCj8qtRYWPfvEXxh8L6GJIrWZ9Vu1
+        48u1/wBWD7yHj8s15Jr/AMYfFGtyOlvdDS7c5xFZnace7n5j+n0rz1n3Hmmk4zzV
+        KKFcdNPI7s0jM7sxZmY5LE9ST61CsrI25SQR3BwacWzwRUZX0qiblgaheq25bucH
+        18w086tqDrta9uCvp5hqng56UDmp5I9iueXcmDsxyzEn1JqROvNQKD7VKCqDJOas
+        kuRuMgjp711+n/FHxVpyIsWqNPHEAojukWQEe5PP61wvnEj0B4ApykZJJ7UDPfvD
+        Hxp0+/dLfXbYWMp4E8RLxH6jqv616laXtve26XFrPFPC/KyRsGU/iK+MBICcDitn
+        QPFWseHbvztMv5YM/eTOUb6qeDRcXKj7CV8ing1434V+NtpezR2niC3W0Y8fa4cm
+        PP8AtL1H1Ga9atrqG6gSe3mjmhcZSSNgysPYikTZouCiow4xRRYLmRr+tW/h7Qrv
+        Vbkbo7dCwQHBdugUfU4r5Y8TeKtV8Tak15qlwztk+XEDiOFf7qL2H6nvXr3x01n7
+        Po2n6SjfNcymaQf7K8D9T+leBzPuT3H8qiC0NHoNeYnvURc4phPNITmrJuLu5pSa
+        Z3pRyKYhM80oOaaetAoAkzwKTd6Cm5pBQA8EnqTijOSeOKaT2oHSgY7cTTg1Rilp
+        AS7/AGpc4UA96iHJApXbk0wJ0kOeDXTeGPGer+GbtZNOunWMnLwscxv9V/ya5T7q
+        D1NOEhQYHU9/Siw0z7A8KeJ7XxToceo2ymNs7JoicmNx1HuOcg0V5j8A9RQnWNKl
+        lVARHcruOOfut/7LRTViJaPQ5b42agbrx29uGytrAiAehPJ/nXmrNu2H14NdD481
+        A6j401S6zkPMQPoOP6VzQOcj0OaiGxctxpNA5obqfrQKokSlWkzQDzQAMOaSnN1F
+        JQAtFFFAAKKKO9AC0UlGaBj0HemjlvrTkOEY03vQIe7YJP4CkTBfn6mkbkA/Wkzg
+        YHU9aYGtpl7Pau8kEzxMwwShwcUVUtWIU4oqbXLTFv3M0jSkksWJP481SU/Pk1Ym
+        b7/1FViMY96diWKwy5+tITTm+7mo6BC0DrR2oHWgB7dBTac3SmUALS0lKOtACUua
+        KKACm0vSk70ASLxF9TSYzznrQf8AVqKTPH40wHHHQfjTM55pTwp9+KQdKALEL7Is
+        +poph4Cr6Cigdz//2YhgBBMRAgAgBQJKP/cgAhsDBgsJCAcDAgQVAggDBBYCAwEC
+        HgECF4AACgkQm30y8tUFgua3awCdFQlChLgn/n4tb4jLe1RgxOxHxosAn2Cn2oNh
+        sZ91wUb4d5JuH88TCupsuQINBEmFQG0QCADqAXWgiis4yi96os3QZmK5809ojjTT
+        nlICgbztrT55cMVTDBc9SneyRQlC0cS+M1z4Do6lj81sNJdJiBPqTYYA1+exTFvs
+        5zCxPInDP3hvqXxHTP142XN1hdzt53R7smn8O0wyO+RCBUb44e9NkusvBd5UP3Je
+        449hnpXJ4WO3cVMFm4ghxs7ERlpAi5NTEsVVdM8dqHbZJtk8gbzdAHH0ybiAXmWy
+        LFGZDuuKiFAkqm/Wled7id6N+cPx107dwBclwPxzfEYKEqJ1YDDHoDlyfx4012y1
+        53e5sGyah/IPBYrrLMfG+Wmiwr5nCX0tmwOcyukuE94hbzJCX2wBdbWLAAMGCACz
+        l3cuM4lGt/wr5liM4gotXpZAopY+EnbLIBuOHFXXR7HnyAgST1jH/AUbafvPjyDh
+        EkFDyUP14XtHNIAqsN1UpuyYbM90bMPAWXJxrazMsSF+Tv5yIxHiy4cc1pjoqHA2
+        kwqIGHmTxYzOPOS19ZWQAtevoTE6pCARphY0dzpscCWaXGs/ZqNAhjL96WLYV1Oo
+        Ut+9mTnOcs6Vuxaxp2wN2S5DK1S9gdIxWEc8wMUPiQe8CYk0OySdORIblMs3bGqD
+        FoM5HcBAZP1YlXitPH2nIRv0DtOQGMQOCkqUWmQuQAUgKV+YO86lO4S7EhTET/GP
+        sQb6P7efm/Cs8wbq/wyIiEkEGBECAAkFAkmFQG0CGwwACgkQm30y8tUFgua2mACe
+        JNBW4snDC4OzjKU6QT386/GA9ssAn3vLzSwn8N1xv5MihWGr5kVzvaE2
+        =cjdq
+        -----END PGP PUBLIC KEY BLOCK-----
+    ]]></key>
+        </repository>
+    </repositories>
+</template>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/BaseJaxbTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/BaseJaxbTest.java b/core/src/test/java/com/axemblr/provisionr/core/BaseJaxbTest.java
deleted file mode 100644
index c37ccb3..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/BaseJaxbTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.junit.Before;
-
-public abstract class BaseJaxbTest {
-
-    protected JAXBContext jaxb;
-
-    static {
-        XMLUnit.setIgnoreWhitespace(true);
-        XMLUnit.setIgnoreComments(true);
-        XMLUnit.setIgnoreAttributeOrder(true);
-    }
-
-    @Before
-    public void setUp() throws JAXBException {
-        jaxb = JAXBContext.newInstance(getContextClasses());
-    }
-
-    public abstract Class[] getContextClasses();
-
-    /**
-     * Marshal an object as XML using a standard JAXB Context
-     */
-    protected String asXml(Object obj) throws Exception {
-        ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
-        PrintStream out = new PrintStream(outBytes);
-
-        Marshaller marshaller = jaxb.createMarshaller();
-        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
-
-        marshaller.marshal(obj, out);
-        return outBytes.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/ProvisionrSupportTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/ProvisionrSupportTest.java b/core/src/test/java/com/axemblr/provisionr/core/ProvisionrSupportTest.java
deleted file mode 100644
index e8b0d96..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/ProvisionrSupportTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.axemblr.provisionr.core;
-
-import static org.fest.assertions.api.Assertions.assertThat;
-
-import com.axemblr.provisionr.api.pool.Pool;
-
-import org.junit.Test;
-
-public class ProvisionrSupportTest {
-
-    @Test
-    public void testConvertTimeout() {
-        ProvisionrSupport provisionr = new ProvisionrSupportTestable();
-        assertThat(provisionr.convertTimeoutToISO8601TimeDuration(600)).isEqualTo("PT10M");
-        assertThat(provisionr.convertTimeoutToISO8601TimeDuration(601)).isEqualTo("PT601S");
-        assertThat(provisionr.convertTimeoutToISO8601TimeDuration(300)).isEqualTo("PT5M");
-        assertThat(provisionr.convertTimeoutToISO8601TimeDuration(42)).isEqualTo("PT42S");
-    }
-}
-
-class ProvisionrSupportTestable extends ProvisionrSupport {
-    @Override
-    public String getId() {
-        return null;
-    }
-    @Override
-    public String startPoolManagementProcess(String businessKey, Pool pool) {
-        return null;
-    }
-    @Override
-    public void destroyPool(String businessKey) {}
-};

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/SshLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/SshLiveTest.java b/core/src/test/java/com/axemblr/provisionr/core/SshLiveTest.java
deleted file mode 100644
index 9798e8a..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/SshLiveTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.core.logging.StreamLogger;
-import com.google.common.collect.Lists;
-import com.google.common.io.CharStreams;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.List;
-import java.util.UUID;
-import net.schmizz.sshj.SSHClient;
-import net.schmizz.sshj.connection.channel.direct.Session;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-
-public class SshLiveTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SshLiveTest.class);
-
-    private final Machine localhost = Machine.builder().localhost().createMachine();
-
-    private final AdminAccess adminAccess = AdminAccess.builder()
-        .asCurrentUser().createAdminAccess();
-
-    @Test
-    public void testConnectToLocalhostAndCollectOutput() throws IOException {
-        SSHClient client = Ssh.newClient(localhost, adminAccess, 1000);
-        try {
-            Session session = client.startSession();
-            try {
-                final Session.Command command = session.exec("echo 'stdout' && echo 'stderr' 1>&2");
-
-                String stdout = CharStreams.toString(new InputStreamReader(command.getInputStream()));
-                String stderr = CharStreams.toString(new InputStreamReader(command.getErrorStream()));
-
-                command.join();
-                assertThat(command.getExitStatus()).isEqualTo(0);
-                assertThat(command.getExitErrorMessage()).isNull();
-
-                assertThat(stdout).contains("stdout");
-                assertThat(stderr).contains("stderr");
-
-            } finally {
-                session.close();
-            }
-        } finally {
-            client.close();
-        }
-    }
-
-    @Test
-    public void testConnectStreamLoggerToCommand() throws IOException, InterruptedException {
-        SSHClient client = Ssh.newClient(localhost, adminAccess, 1000);
-        try {
-            Session session = client.startSession();
-            try {
-                final Session.Command command = session.exec("echo 'line1' && echo && echo 'line2'");
-                final List<String> lines = Lists.newCopyOnWriteArrayList();
-
-                StreamLogger logger = new StreamLogger(command.getInputStream(), LOG, MarkerFactory.getMarker("live")) {
-                    @Override
-                    protected void log(Logger logger, Marker marker, String line) {
-                        logger.info(marker, line);  /* just for visual inspection */
-                        lines.add(line);
-                    }
-                };
-                logger.start();
-
-                command.join();
-                logger.join();
-
-                assertThat(lines).hasSize(2).contains("line1", "line2");
-
-            } finally {
-                session.close();
-            }
-        } finally {
-            client.close();
-        }
-    }
-
-    @Test
-    public void testCreateFileOverSsh() throws IOException {
-        SSHClient client = Ssh.newClient(localhost, adminAccess, 1000);
-        try {
-            String destination = "/tmp/" + UUID.randomUUID().toString();
-            String content = UUID.randomUUID().toString();
-
-            Ssh.createFile(client, content, 0600, destination);
-
-            /* Check the file exists and has the expected content */
-            Session session = client.startSession();
-            try {
-                final Session.Command command = session.exec("set +x +e && cat " + destination);
-
-                String output = CharStreams.toString(new InputStreamReader(command.getInputStream()));
-                command.join();
-
-                assertThat(command.getExitStatus()).isEqualTo(0);
-                assertThat(output).contains(content);
-
-            } finally {
-                session.close();
-            }
-        } finally {
-            client.close();
-        }
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activiti/AlwaysFailTask.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activiti/AlwaysFailTask.java b/core/src/test/java/com/axemblr/provisionr/core/activiti/AlwaysFailTask.java
deleted file mode 100644
index 049b644..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activiti/AlwaysFailTask.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activiti;
-
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AlwaysFailTask implements JavaDelegate {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AlwaysFailTask.class);
-
-    public static final AtomicInteger COUNTER = new AtomicInteger(0);
-
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-        COUNTER.incrementAndGet();
-        throw new RuntimeException("Failing. Time is " + new Date());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activiti/ConfigurableFailedJobCommandFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activiti/ConfigurableFailedJobCommandFactoryTest.java b/core/src/test/java/com/axemblr/provisionr/core/activiti/ConfigurableFailedJobCommandFactoryTest.java
deleted file mode 100644
index eadc848..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activiti/ConfigurableFailedJobCommandFactoryTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activiti;
-
-import com.google.common.base.Stopwatch;
-import java.util.concurrent.TimeUnit;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration;
-import org.activiti.engine.impl.jobexecutor.DefaultJobExecutor;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-public class ConfigurableFailedJobCommandFactoryTest {
-
-    @Test
-    public void testConfigurableNumberOfRetries() throws InterruptedException {
-        DefaultJobExecutor jobExecutor = new DefaultJobExecutor();
-
-        jobExecutor.setCorePoolSize(2);
-        jobExecutor.setQueueSize(2);
-        jobExecutor.setMaxJobsPerAcquisition(5);
-        jobExecutor.setWaitTimeInMillis(50);
-        jobExecutor.setLockTimeInMillis(180000);
-
-        ProcessEngine processEngine = new StandaloneInMemProcessEngineConfiguration()
-            .setJobExecutorActivate(true)
-            .setJobExecutor(jobExecutor)
-            .setFailedJobCommandFactory(new ConfigurableFailedJobCommandFactory(2, 1))
-            .buildProcessEngine();
-
-        processEngine.getRepositoryService().createDeployment()
-            .addClasspathResource("diagrams/alwaysFail.bpmn20.xml").deploy();
-
-        Stopwatch stopwatch = new Stopwatch().start();
-        processEngine.getRuntimeService().startProcessInstanceByKey("alwaysFail");
-
-        while (AlwaysFailTask.COUNTER.get() != 3 /* = 1 normal execution + 2 retries */) {
-            TimeUnit.MILLISECONDS.sleep(100);
-        }
-
-        stopwatch.stop();
-        assertThat(stopwatch.elapsedTime(TimeUnit.SECONDS)).isGreaterThanOrEqualTo(2);
-
-        processEngine.close();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activities/CheckProcessesEndedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activities/CheckProcessesEndedTest.java b/core/src/test/java/com/axemblr/provisionr/core/activities/CheckProcessesEndedTest.java
deleted file mode 100644
index f466d0f..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activities/CheckProcessesEndedTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.test.ProcessVariablesCollector;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import java.util.Map;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.engine.runtime.ProcessInstanceQuery;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class CheckProcessesEndedTest extends CheckProcessesTest {
-
-    private static final String PROCESS_IDS = "process_ids";
-
-    private static final String RESULT = "result";
-
-    @Test
-    public void testWithAListOfEndedProcesses() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-        when(execution.getVariable(eq(PROCESS_IDS))).thenReturn(Lists.newArrayList("1", "2"));
-
-        ProcessVariablesCollector collector = new ProcessVariablesCollector();
-        collector.install(execution);
-
-        RuntimeService runtimeService = mockRuntimeService(ImmutableMap.of(
-            "1", mockProcessInstance(/* ended= */ true),
-            "2", mockProcessInstance(/* ended= */ true)
-        ));
-
-        JavaDelegate delegate = new CheckProcessesEnded(runtimeService, PROCESS_IDS, RESULT);
-        delegate.execute(execution);
-
-        assertThat((Boolean) collector.getVariable(RESULT)).isTrue();
-    }
-
-    @Test
-    public void testWithOneEndedAndOneStillRunning() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-        when(execution.getVariable(eq(PROCESS_IDS))).thenReturn(Lists.newArrayList("1", "2"));
-
-        ProcessVariablesCollector collector = new ProcessVariablesCollector();
-        collector.install(execution);
-
-        RuntimeService runtimeService = mockRuntimeService(ImmutableMap.of(
-            "1", mockProcessInstance(/* ended= */ true),
-            "2", mockProcessInstance(/* ended= */ false)
-        ));
-
-        JavaDelegate delegate = new CheckProcessesEnded(runtimeService, PROCESS_IDS, RESULT);
-        delegate.execute(execution);
-
-        assertThat((Boolean) collector.getVariable(RESULT)).isFalse();
-    }
-
-    /**
-     * We consider an invalid process instance ID as ended by default
-     */
-    @Test
-    public void testWithOneInvalidProcessId() throws Exception {
-        DelegateExecution execution = mock(DelegateExecution.class);
-        when(execution.getVariable(eq(PROCESS_IDS))).thenReturn(Lists.newArrayList("1", "invalid"));
-
-        ProcessVariablesCollector collector = new ProcessVariablesCollector();
-        collector.install(execution);
-
-        RuntimeService runtimeService = mockRuntimeService(ImmutableMap.of(
-            "1", mockProcessInstance(/* ended= */ true)), "invalid");
-
-        JavaDelegate delegate = new CheckProcessesEnded(runtimeService, PROCESS_IDS, RESULT);
-        delegate.execute(execution);
-
-        assertThat((Boolean) collector.getVariable(RESULT)).isTrue();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activities/CheckProcessesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activities/CheckProcessesTest.java b/core/src/test/java/com/axemblr/provisionr/core/activities/CheckProcessesTest.java
deleted file mode 100644
index d5448be..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activities/CheckProcessesTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Map;
-
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.engine.runtime.ProcessInstanceQuery;
-
-public abstract class CheckProcessesTest {
-
-    protected RuntimeService mockRuntimeService(Map<String, ProcessInstance> instances, 
-                                              String... notFoundProcessInstanceIds) {
-        RuntimeService runtimeService = mock(RuntimeService.class);
-
-        ProcessInstanceQuery generalQuery = mock(ProcessInstanceQuery.class);
-        for (Map.Entry<String, ProcessInstance> entry : instances.entrySet()) {
-            ProcessInstanceQuery specificQuery = mock(ProcessInstanceQuery.class);
-            when(specificQuery.singleResult()).thenReturn(entry.getValue());
-
-            when(generalQuery.processInstanceId(eq(entry.getKey()))).thenReturn(specificQuery);
-        }
-        for (String notFound : notFoundProcessInstanceIds) {
-            /* create a mock that returns null for all method calls (default) */
-            when(generalQuery.processInstanceId(eq(notFound))).thenReturn(mock(ProcessInstanceQuery.class));
-        }
-        when(runtimeService.createProcessInstanceQuery()).thenReturn(generalQuery);
-
-        return runtimeService;
-    }
-
-    protected ProcessInstance mockProcessInstance(boolean ended) {
-        ProcessInstance processInstance = mock(ProcessInstance.class);
-        when(processInstance.isEnded()).thenReturn(ended);
-        return processInstance;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activities/DownloadFilesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activities/DownloadFilesTest.java b/core/src/test/java/com/axemblr/provisionr/core/activities/DownloadFilesTest.java
deleted file mode 100644
index e3bd125..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activities/DownloadFilesTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Software;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class DownloadFilesTest {
-
-    @Test
-    public void testCreatePuppetScript() throws Exception {
-        Software software = Software.builder()
-            .file("http://bin.axemblr.com/test.tar.gz", "/opt/test.tar.gz")
-            .file("http://google.com", "/opt/google.html")
-            .createSoftware();
-
-        Pool pool = mock(Pool.class);
-        when(pool.getSoftware()).thenReturn(software);
-
-        PuppetActivity activity = new DownloadFiles();
-        String content = activity.createPuppetScript(pool, null);
-
-        assertThat(content)
-            .contains("download_file {\"/opt/test.tar.gz\":\n" +
-                "  uri => \"http://bin.axemblr.com/test.tar.gz\"\n" +
-                "}")
-            .contains("download_file {\"/opt/google.html\":\n" +
-                "  uri => \"http://google.com\"\n" +
-                "}");
-
-        assertThat(activity.createAdditionalFiles(pool, null)).isEmpty();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/test/java/com/axemblr/provisionr/core/activities/InstallPackagesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/axemblr/provisionr/core/activities/InstallPackagesTest.java b/core/src/test/java/com/axemblr/provisionr/core/activities/InstallPackagesTest.java
deleted file mode 100644
index 3d840bc..0000000
--- a/core/src/test/java/com/axemblr/provisionr/core/activities/InstallPackagesTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Software;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class InstallPackagesTest {
-
-    @Test
-    public void testCreatePuppetScript() throws Exception {
-        Pool pool = mock(Pool.class);
-        when(pool.getSoftware()).thenReturn(Software.builder()
-            .packages("git-core", "vim").createSoftware());
-
-        PuppetActivity activity = new InstallPackages();
-        String content = activity.createPuppetScript(pool, null);
-
-        assertThat(content).contains(
-            "Package { ensure => \"installed\" }\n" +
-                "\n" +
-                "package { \"git-core\": }\n" +
-                "package { \"vim\": }\n"
-        );
-    }
-}


[16/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/console/src/main/resources/OSGI-INF/blueprint/context.xml
----------------------------------------------------------------------
diff --git a/console/src/main/resources/OSGI-INF/blueprint/context.xml b/console/src/main/resources/OSGI-INF/blueprint/context.xml
index 2591a8c..a23ed27 100644
--- a/console/src/main/resources/OSGI-INF/blueprint/context.xml
+++ b/console/src/main/resources/OSGI-INF/blueprint/context.xml
@@ -18,7 +18,7 @@
            xmlns:cxf="http://cxf.apache.org/blueprint/core"
            xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs">
 
-    <reference-list id="provisionrs" interface="com.axemblr.provisionr.api.Provisionr"/>
+    <reference-list id="providers" interface="org.apache.provisionr.api.Provisionr"/>
 
     <cxf:bus>
         <cxf:features>
@@ -32,8 +32,8 @@
     <!--</jaxrs:serviceBeans>-->
     <!--</jaxrs:server>-->
 
-    <bean id="poolClient" class="com.axemblr.provisionr.client.ProvisionrClient">
-        <argument ref="provisionrs"/>
+    <bean id="poolClient" class="org.apache.provisionr.client.ProvisionrClient">
+        <argument ref="providers"/>
     </bean>
 
 </blueprint>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/console/src/main/resources/com.axemblr.provisionr.console.cfg
----------------------------------------------------------------------
diff --git a/console/src/main/resources/com.axemblr.provisionr.console.cfg b/console/src/main/resources/com.axemblr.provisionr.console.cfg
deleted file mode 100644
index 5e012c3..0000000
--- a/console/src/main/resources/com.axemblr.provisionr.console.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-#
-# REST API Configurations
-#
-

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/console/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/console/src/main/resources/features.xml b/console/src/main/resources/features.xml
index 9daa190..29a5d97 100644
--- a/console/src/main/resources/features.xml
+++ b/console/src/main/resources/features.xml
@@ -16,24 +16,24 @@
   ~ limitations under the License.
   -->
 
-<features name="axemblr-provisionr-console-features-${project.version}"
+<features name="provisionr-console-features-${project.version}"
           xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
 
     <repository>
-        mvn:com.axemblr.provisionr/provisionr-core/${project.version}/xml/features
+        mvn:org.apache.provisionr/provisionr-core/${project.version}/xml/features
     </repository>
     <repository>
         mvn:org.apache.cxf.karaf/apache-cxf/${cxf.version}/xml/features
     </repository>
 
-    <feature name="axemblr-provisionr-console" version="${project.version}">
+    <feature name="provisionr-console" version="${project.version}">
         <feature version="${cxf.version}">cxf</feature>
-        <feature version="${project.version}">axemblr-provisionr-core</feature>
+        <feature version="${project.version}">provisionr-core</feature>
 
-        <bundle start="true">mvn:com.axemblr.provisionr/provisionr-console/${project.version}</bundle>
+        <bundle start="true">mvn:org.apache.provisionr/provisionr-console/${project.version}</bundle>
 
-        <configfile finalname="/etc/com.axemblr.provisionr.console.cfg">
-            mvn:com.axemblr.provisionr/provisionr-console/${project.version}/cfg/defaults
+        <configfile finalname="/etc/org.apache.provisionr.console.cfg">
+            mvn:org.apache.provisionr/provisionr-console/${project.version}/cfg/defaults
         </configfile>
     </feature>
 

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/console/src/main/resources/org.apache.provisionr.console.cfg
----------------------------------------------------------------------
diff --git a/console/src/main/resources/org.apache.provisionr.console.cfg b/console/src/main/resources/org.apache.provisionr.console.cfg
new file mode 100644
index 0000000..5e012c3
--- /dev/null
+++ b/console/src/main/resources/org.apache.provisionr.console.cfg
@@ -0,0 +1,5 @@
+
+#
+# REST API Configurations
+#
+

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 9a77fdd..c53d4fc 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -17,21 +17,21 @@
 
 <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/xsd/maven-4.0.0.xsd">
     <parent>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <artifactId>provisionr-parent</artifactId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Core</name>
+    <name>Apache Provisionr :: Core</name>
     <description>Includes Activiti Engine configuration and common building blocks</description>
     <artifactId>provisionr-core</artifactId>
     <packaging>bundle</packaging>
 
     <properties>
         <osgi.import>*</osgi.import>
-        <osgi.export>com.axemblr.provisionr.core*</osgi.export>
+        <osgi.export>org.apache.provisionr.core*</osgi.export>
     </properties>
 
     <dependencies>
@@ -44,7 +44,7 @@
             <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
@@ -68,7 +68,7 @@
             <artifactId>org.apache.felix.fileinstall</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-test-support</artifactId>
             <scope>test</scope>
             <exclusions>
@@ -165,7 +165,7 @@
                                     <classifier>features</classifier>
                                 </artifact>
                                 <artifact>
-                                    <file>${project.build.directory}/classes/com.axemblr.provisionr.cfg</file>
+                                    <file>${project.build.directory}/classes/org.apache.provisionr.cfg</file>
                                     <type>cfg</type>
                                     <classifier>defaults</classifier>
                                 </artifact>
@@ -178,21 +178,21 @@
                                 </artifact>
                                 <artifact>
                                     <file>
-                                        ${project.build.directory}/classes/com/axemblr/provisionr/core/templates/cdh3.xml
+                                        ${project.build.directory}/classes/org/apache/provisionr/core/templates/cdh3.xml
                                     </file>
                                     <type>template</type>
                                     <classifier>cdh3</classifier>
                                 </artifact>
                                 <artifact>
                                     <file>
-                                        ${project.build.directory}/classes/com/axemblr/provisionr/core/templates/cdh4.xml
+                                        ${project.build.directory}/classes/org/apache/provisionr/core/templates/cdh4.xml
                                     </file>
                                     <type>template</type>
                                     <classifier>cdh4</classifier>
                                 </artifact>
                                 <artifact>
                                     <file>
-                                        ${project.build.directory}/classes/com/axemblr/provisionr/core/templates/jenkins.xml
+                                        ${project.build.directory}/classes/org/apache/provisionr/core/templates/jenkins.xml
                                     </file>
                                     <type>template</type>
                                     <classifier>jenkins</classifier>
@@ -219,7 +219,7 @@
                                 <descriptor>file:${project.build.directory}/classes/features.xml</descriptor>
                             </descriptors>
                             <features>
-                                <feature>axemblr-provisionr-core</feature>
+                                <feature>provisionr-core</feature>
                             </features>
                             <repository>target/features-repo</repository>
                         </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/CoreConstants.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/CoreConstants.java b/core/src/main/java/com/axemblr/provisionr/core/CoreConstants.java
deleted file mode 100644
index 655aea9..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/CoreConstants.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.axemblr.provisionr.core;
-
-public class CoreConstants {
-
-    private CoreConstants() {
-    }
-
-    public static final String ACTIVITI_EXPLORER_DEFAULT_USER = "kermit";
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/CoreProcessVariables.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/CoreProcessVariables.java b/core/src/main/java/com/axemblr/provisionr/core/CoreProcessVariables.java
deleted file mode 100644
index 5dfa1d6..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/CoreProcessVariables.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core;
-
-public class CoreProcessVariables {
-
-    private CoreProcessVariables() {
-        throw new RuntimeException("Should not instantiate");
-    }
-
-    /**
-     * Provider ID as returned by the Provisionr object
-     *
-     * @see com.axemblr.provisionr.api.Provisionr
-     */
-    public static final String PROVIDER = "provider";
-
-    /**
-     * Pool configuration description
-     *
-     * @see com.axemblr.provisionr.api.pool.Pool
-     */
-    public static final String POOL = "pool";
-
-    /**
-     * Contains a list of machines that are running
-     *
-     * @see com.axemblr.provisionr.api.pool.Machine
-     */
-    public static final String MACHINES = "machines";
-
-    /**
-     * Pool status stored as process variable
-     * <p/>
-     * This can be an arbitrary string. We will restrict the domain later on.
-     */
-    public static final String STATUS = "status";
-
-    /**
-     * Variable to store the pool business key. The key is passed as a process variable to all processes that take
-     * part in setting up the pool.
-     */
-    public static final String POOL_BUSINESS_KEY = "poolBusinessKey";
-
-    /**
-     * Configurable value for the interval of time in which to wait for the pool
-     * to become available.
-     */
-    public static final String BOOTSTRAP_TIMEOUT = "bootstrapTimeout";
-
-    /**
-     * Flag that indicates if the image the machines are being built from already has all its software
-     * installed and there's no need to download and install the packages and files.
-     */
-    public static final String IS_CACHED_IMAGE = "isCachedImage";
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/CoreSignals.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/CoreSignals.java b/core/src/main/java/com/axemblr/provisionr/core/CoreSignals.java
deleted file mode 100644
index cb6d6b3..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/CoreSignals.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core;
-
-public class CoreSignals {
-
-    private CoreSignals() {
-    }
-
-    /**
-     * Standard event that triggers pool termination
-     */
-    public static final String TERMINATE_POOL = "terminatePoolEvent";
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/Mustache.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/Mustache.java b/core/src/main/java/com/axemblr/provisionr/core/Mustache.java
deleted file mode 100644
index d71e6ae..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/Mustache.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core;
-
-import com.github.mustachejava.DefaultMustacheFactory;
-import com.github.mustachejava.MustacheFactory;
-import com.google.common.base.Charsets;
-import com.google.common.io.Resources;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.StringReader;
-import java.io.Writer;
-import java.net.URL;
-import java.util.Map;
-
-/**
- * Utility functions for rendering mustache templates as strings
- */
-public class Mustache {
-
-    private Mustache() {
-    }
-
-    public static String toString(Class<?> contextClass, String resource, Map<String, ?> scopes)
-        throws IOException {
-        return toString(Resources.getResource(contextClass, resource), scopes);
-    }
-
-    public static String toString(URL resource, Map<String, ?> scopes) throws IOException {
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        Writer writer = new OutputStreamWriter(outputStream);
-
-        String content = Resources.toString(resource, Charsets.UTF_8);
-
-        MustacheFactory factory = new DefaultMustacheFactory();
-        factory.compile(new StringReader(content), resource.toString())
-            .execute(writer, scopes);
-
-        writer.close();
-        return outputStream.toString();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/PoolStatus.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/PoolStatus.java b/core/src/main/java/com/axemblr/provisionr/core/PoolStatus.java
deleted file mode 100644
index 849f9c9..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/PoolStatus.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core;
-
-/**
- * A standard set of pool statuses
- */
-public class PoolStatus {
-
-    private PoolStatus() {
-    }
-
-    public static String UNDEFINED = "undefined";
-
-    public static String SETUP = "setup";
-
-    public static String READY = "ready";
-
-    public static String TERMINATED = "terminated";
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/ProvisionrSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/ProvisionrSupport.java b/core/src/main/java/com/axemblr/provisionr/core/ProvisionrSupport.java
deleted file mode 100644
index e1ab420..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/ProvisionrSupport.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import java.util.List;
-import java.util.NoSuchElementException;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.Execution;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class ProvisionrSupport implements Provisionr {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ProvisionrSupport.class);
-
-    @Override
-    public Optional<Provider> getDefaultProvider() {
-        return Optional.absent();
-    }
-
-    @Override
-    public String getStatus(String businessKey) {
-        return PoolStatus.UNDEFINED;
-    }
-
-    @Override
-    public List<Machine> getMachines(String businessKey) {
-        return ImmutableList.of();
-    }
-
-    /**
-     * Trigger a signal event on all executions for a specific business key.
-     *
-     * @see <a href="http://www.activiti.org/userguide/index.html#bpmnSignalEventDefinition" />
-     * @see CoreSignals
-     */
-    protected void triggerSignalEvent(ProcessEngine processEngine, String businessKey, String signalName) {
-        RuntimeService runtimeService = processEngine.getRuntimeService();
-
-        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
-            .processInstanceBusinessKey(businessKey).singleResult();
-
-        List<Execution> executions = runtimeService.createExecutionQuery()
-            .processInstanceId(processInstance.getProcessInstanceId())
-            .signalEventSubscriptionName(signalName).list();
-
-        if (executions.isEmpty()) {
-            throw new NoSuchElementException(String.format("No executions found waiting " +
-                "for signal '%s' on process %s", signalName, businessKey));
-        }
-        for (Execution execution : executions) {
-            LOG.info("Sending '{}' signal to execution {} for process {}",
-                new Object[]{signalName, execution.getId(), businessKey});
-            runtimeService.signalEventReceived(signalName, execution.getId());
-
-        }
-    }
-
-    /**
-     * Convert a timeout specified in seconds to a string representation that can be used
-     * inside the Activiti definitions of timeouts. 
-     * 
-     * @see http://en.wikipedia.org/wiki/ISO_8601#Durations
-     */
-    protected String convertTimeoutToISO8601TimeDuration(int bootstrapTimeoutInSeconds) {
-        StringBuilder result = new StringBuilder("PT");
-        if (bootstrapTimeoutInSeconds % 60 == 0) {
-            result.append(bootstrapTimeoutInSeconds / 60).append("M");
-        } else {
-            result.append(bootstrapTimeoutInSeconds).append("S");
-        }
-        return result.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/Ssh.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/Ssh.java b/core/src/main/java/com/axemblr/provisionr/core/Ssh.java
deleted file mode 100644
index 889c4fc..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/Ssh.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.core.logging.ErrorStreamLogger;
-import com.axemblr.provisionr.core.logging.InfoStreamLogger;
-import com.google.common.base.Charsets;
-import static com.google.common.base.Preconditions.checkArgument;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.PublicKey;
-import net.schmizz.sshj.SSHClient;
-import net.schmizz.sshj.common.SecurityUtils;
-import net.schmizz.sshj.connection.channel.direct.Session;
-import net.schmizz.sshj.transport.verification.HostKeyVerifier;
-import net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile;
-import net.schmizz.sshj.xfer.InMemorySourceFile;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-
-public class Ssh {
-
-    private static final Logger LOG = LoggerFactory.getLogger(Ssh.class);
-
-    /**
-     * Fail if a connection can't be established in this amount of time
-     */
-    public static final int DEFAULT_CONNECT_TIMEOUT = 30 * 1000; /* milliseconds */
-
-    public static final int DEFAULT_READ_TIMEOUT = 10 * 60 * 1000; /* milliseconds */
-
-    private Ssh() {
-    }
-
-    /**
-     * Accept any host key from the remote machines
-     */
-    private enum AcceptAnyHostKeyVerifier implements HostKeyVerifier {
-        INSTANCE;
-
-        @Override
-        public boolean verify(String hostname, int port, PublicKey key) {
-            String fingerprint = SecurityUtils.getFingerprint(key);
-            LOG.info("Automatically accepting host key for {}:{} with fingerprint {}",
-                new Object[]{hostname, port, fingerprint});
-            return true;
-        }
-    }
-
-    public static SSHClient newClient(Machine machine, AdminAccess adminAccess) throws IOException {
-        return newClient(machine, adminAccess, DEFAULT_READ_TIMEOUT);
-    }
-
-    /**
-     * Create a new {@code SSHClient} connected to the remote machine using the
-     * AdminAccess credentials as provided
-     */
-    public static SSHClient newClient(
-        Machine machine, AdminAccess adminAccess, int timeoutInMillis
-    ) throws IOException {
-        checkArgument(timeoutInMillis >= 0, "timeoutInMillis should be positive or 0");
-
-        final SSHClient client = new SSHClient();
-        client.addHostKeyVerifier(AcceptAnyHostKeyVerifier.INSTANCE);
-
-        if (timeoutInMillis != 0) {
-            client.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
-            client.setTimeout(timeoutInMillis);
-        }
-        client.connect(machine.getPublicDnsName(), machine.getSshPort());
-
-        OpenSSHKeyFile key = new OpenSSHKeyFile();
-        key.init(adminAccess.getPrivateKey(), adminAccess.getPublicKey());
-        client.authPublickey(adminAccess.getUsername(), key);
-
-        return client;
-    }
-
-    /**
-     * Stream command output as log message for easy debugging
-     */
-    public static void logCommandOutput(Logger logger, String instanceId, Session.Command command) {
-        final Marker marker = MarkerFactory.getMarker("ssh-" + instanceId);
-
-        new InfoStreamLogger(command.getInputStream(), logger, marker)
-            .start();
-        new ErrorStreamLogger(command.getErrorStream(), logger, marker)
-            .start();
-    }
-
-    /**
-     * Create a remote file on SSH from a string
-     *
-     * @param client      ssh client instance
-     * @param content     content for the new file
-     * @param permissions unix permissions
-     * @param destination destination path
-     * @throws IOException
-     */
-    public static void createFile(
-        SSHClient client, String content, final int permissions, String destination
-    ) throws IOException {
-        final byte[] bytes = content.getBytes(Charsets.UTF_8);
-        client.newSCPFileTransfer().upload(new InMemorySourceFile() {
-            @Override
-            public String getName() {
-                return "in-memory";
-            }
-
-            @Override
-            public long getLength() {
-                return bytes.length;
-            }
-
-            @Override
-            public int getPermissions() throws IOException {
-                return permissions;
-            }
-
-            @Override
-            public InputStream getInputStream() throws IOException {
-                return new ByteArrayInputStream(bytes);
-            }
-        }, destination);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activiti/ConfigurableFailedJobCommandFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activiti/ConfigurableFailedJobCommandFactory.java b/core/src/main/java/com/axemblr/provisionr/core/activiti/ConfigurableFailedJobCommandFactory.java
deleted file mode 100644
index 4de708e..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activiti/ConfigurableFailedJobCommandFactory.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activiti;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Date;
-import java.util.UUID;
-import org.activiti.engine.impl.calendar.BusinessCalendar;
-import org.activiti.engine.impl.calendar.CycleBusinessCalendar;
-import org.activiti.engine.impl.context.Context;
-import org.activiti.engine.impl.interceptor.Command;
-import org.activiti.engine.impl.interceptor.CommandContext;
-import org.activiti.engine.impl.jobexecutor.FailedJobCommandFactory;
-import org.activiti.engine.impl.persistence.entity.JobEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * We need a custom @{link FailedJobCommandFactory} implementation that allows
- * us to customize the global number of retries per job
- */
-public class ConfigurableFailedJobCommandFactory implements FailedJobCommandFactory {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ConfigurableFailedJobCommandFactory.class);
-
-    /**
-     * This class is a bit of a hack because there is no easy way to
-     * change @{link JobEntity.DEFAULT_RETRIES}
-     * <p/>
-     * We get the desired behaviour by incrementing the number of retries until we
-     * exceed maxNumberOfRetries + DEFAULT_RETRIES (considered to be 0)
-     * <p/>
-     * If maxNumberOfRetries is -1 (infinity) the job will be always retried.
-     */
-    public static class IncrementJobRetriesCmd implements Command<Object> {
-
-        private final String LOCK_OWNER = "job-retries-" + UUID.randomUUID().toString();
-
-        private final String jobId;
-        private final Throwable exception;
-
-        private final int maxNumberOfRetries;
-        private final int waitBetweenRetriesInSeconds;
-
-        public IncrementJobRetriesCmd(String jobId, Throwable exception, int maxNumberOfRetries,
-                                      int waitBetweenRetriesInSeconds) {
-            this.jobId = checkNotNull(jobId, "jobId is null");
-            this.exception = exception;
-
-            this.maxNumberOfRetries = maxNumberOfRetries;
-            this.waitBetweenRetriesInSeconds = waitBetweenRetriesInSeconds;
-        }
-
-        @Override
-        public Object execute(CommandContext commandContext) {
-            JobEntity job = Context.getCommandContext()
-                .getJobManager()
-                .findJobById(jobId);
-
-            updateNumberOfRetries(job);
-
-            if (exception != null) {
-                job.setExceptionMessage(exception.getMessage());
-                job.setExceptionStacktrace(getExceptionStacktrace());
-            }
-
-            return null;
-        }
-
-        private void updateNumberOfRetries(JobEntity job) {
-            if (maxNumberOfRetries == -1) {
-                job.setLockOwner(LOCK_OWNER);
-                job.setLockExpirationTime(calculateDueDate());
-                return; /* always retry without counting */
-            }
-
-            int realUpperBound = maxNumberOfRetries + JobEntity.DEFAULT_RETRIES;
-            if (job.getRetries() >= realUpperBound) {
-                LOG.warn("Job {} from process {} has no more retries left. The process will block and may " +
-                    "require human intervention.", job.getId(), job.getProcessInstanceId());
-
-                job.setRetries(0);  /* stop retrying this job */
-                job.setLockOwner(null);
-
-            } else {
-                final Date newDate = calculateDueDate();
-                LOG.info("Scheduling job {} from process {} to be retried at {}. Try {}/{}",
-                    new Object[]{job.getId(), job.getProcessInstanceId(), newDate,
-                        job.getRetries() - JobEntity.DEFAULT_RETRIES, maxNumberOfRetries});
-
-                /* I've tried to use job.setDuedate() but it doesn't work as expected */
-
-                job.setLockOwner(LOCK_OWNER);
-                job.setLockExpirationTime(newDate);
-
-                job.setRetries(job.getRetries() + 1);
-            }
-        }
-
-        /**
-         * Based on code from @{link TimerEntity.calculateDueDate}
-         */
-        private Date calculateDueDate() {
-            BusinessCalendar businessCalendar = Context
-                .getProcessEngineConfiguration()
-                .getBusinessCalendarManager()
-                .getBusinessCalendar(CycleBusinessCalendar.NAME);
-
-            return businessCalendar.resolveDuedate(
-                String.format("R/PT%dS", waitBetweenRetriesInSeconds));
-        }
-
-        private String getExceptionStacktrace() {
-            StringWriter stringWriter = new StringWriter();
-            exception.printStackTrace(new PrintWriter(stringWriter));
-            return stringWriter.toString();
-        }
-    }
-
-    private final int maxNumberOfRetries;
-    private final int waitBetweenRetriesInSeconds;
-
-    public ConfigurableFailedJobCommandFactory(int maxNumberOfRetries, int waitBetweenRetriesInSeconds) {
-        checkArgument(maxNumberOfRetries > 0 || maxNumberOfRetries == -1,
-            "Max number of retries should be a positive number or -1 (infinite)");
-        checkArgument(waitBetweenRetriesInSeconds > 0, "waitBetweenRetriesInSeconds should be positive");
-
-        this.maxNumberOfRetries = maxNumberOfRetries;
-        this.waitBetweenRetriesInSeconds = waitBetweenRetriesInSeconds;
-    }
-
-    @Override
-    public Command<Object> getCommand(String jobId, Throwable exception) {
-        return new IncrementJobRetriesCmd(jobId, exception, maxNumberOfRetries, waitBetweenRetriesInSeconds);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activiti/ConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activiti/ConfigurationFactory.java b/core/src/main/java/com/axemblr/provisionr/core/activiti/ConfigurationFactory.java
deleted file mode 100644
index 39af2e3..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activiti/ConfigurationFactory.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activiti;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import javax.sql.DataSource;
-import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;
-import org.activiti.engine.impl.jobexecutor.FailedJobCommandFactory;
-import org.activiti.engine.impl.jobexecutor.JobExecutor;
-
-public class ConfigurationFactory {
-
-    private DataSource dataSource;
-    private String databaseSchemaUpdate;
-
-    private boolean jobExecutorActivate = true;
-    private JobExecutor jobExecutor;
-
-    private FailedJobCommandFactory failedJobCommandFactory;
-
-    public StandaloneProcessEngineConfiguration getConfiguration() {
-        StandaloneProcessEngineConfiguration conf = new StandaloneProcessEngineConfiguration();
-
-        conf.setDataSource(dataSource);
-        conf.setDatabaseSchemaUpdate(databaseSchemaUpdate);
-
-        conf.setJobExecutorActivate(jobExecutorActivate);
-        conf.setJobExecutor(jobExecutor);
-
-        conf.setFailedJobCommandFactory(failedJobCommandFactory);
-
-        return conf;
-    }
-
-    public void setDataSource(DataSource dataSource) {
-        this.dataSource = checkNotNull(dataSource, "dataSource is null");
-    }
-
-    public void setDatabaseSchemaUpdate(String databaseSchemaUpdate) {
-        this.databaseSchemaUpdate = checkNotNull(databaseSchemaUpdate, "databaseSchemaUpdate is null");
-    }
-
-    public void setJobExecutorActivate(boolean jobExecutorActivate) {
-        this.jobExecutorActivate = jobExecutorActivate;
-    }
-
-    public void setJobExecutor(JobExecutor jobExecutor) {
-        this.jobExecutor = checkNotNull(jobExecutor, "jobExecutor is null");
-    }
-
-    public void setFailedJobCommandFactory(FailedJobCommandFactory failedJobCommandFactory) {
-        this.failedJobCommandFactory = checkNotNull(failedJobCommandFactory, "failedJobCommandFactory is null");
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activities/CheckProcessesEnded.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activities/CheckProcessesEnded.java b/core/src/main/java/com/axemblr/provisionr/core/activities/CheckProcessesEnded.java
deleted file mode 100644
index 38417fb..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activities/CheckProcessesEnded.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import java.util.List;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class CheckProcessesEnded implements JavaDelegate {
-
-    private static final Logger LOG = LoggerFactory.getLogger(CheckProcessesEnded.class);
-
-    private final RuntimeService runtimeService;
-
-    private final String variableWithProcessIds;
-    private final String resultVariable;
-
-    public CheckProcessesEnded(RuntimeService runtimeService, String variableWithProcessIds,
-                               String resultVariable) {
-        this.runtimeService = checkNotNull(runtimeService, "runtimeService is null");
-        this.variableWithProcessIds = checkNotNull(variableWithProcessIds, "variableWithProcessIds is null");
-        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
-    }
-
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-        @SuppressWarnings("unchecked")
-        List<String> processIds = (List<String>) execution.getVariable(variableWithProcessIds);
-
-        List<String> ended = Lists.newArrayList(Iterables.filter(processIds, new Predicate<String>() {
-            @Override
-            public boolean apply(String processInstanceId) {
-                ProcessInstance instance = runtimeService.createProcessInstanceQuery()
-                    .processInstanceId(processInstanceId).singleResult();
-
-                return instance == null || instance.isEnded();
-            }
-        }));
-
-        boolean done = (processIds.size() == ended.size());
-        execution.setVariable(resultVariable, done);
-
-        if (done) {
-            LOG.info("All background processes ENDED: {}", processIds);
-        } else {
-            if (LOG.isInfoEnabled()) {
-                LOG.info("Still waiting for: {}", Sets.difference(ImmutableSet.copyOf(processIds),
-                    ImmutableSet.copyOf(ended)));
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activities/DownloadFiles.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activities/DownloadFiles.java b/core/src/main/java/com/axemblr/provisionr/core/activities/DownloadFiles.java
deleted file mode 100644
index 216a028..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activities/DownloadFiles.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.core.Mustache;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import java.util.List;
-import java.util.Map;
-
-public class DownloadFiles extends PuppetActivity {
-
-    public static final String FILES_TEMPLATE = "/com/axemblr/provisionr/core/puppet/files.pp.mustache";
-
-    public DownloadFiles() {
-        super("files");
-    }
-
-    @Override
-    public String createPuppetScript(Pool pool, Machine machine) throws Exception {
-        return Mustache.toString(InstallPackages.class, FILES_TEMPLATE,
-            ImmutableMap.of("files", filesAsListOfMaps(pool.getSoftware())));
-    }
-
-    private List<Map<String, String>> filesAsListOfMaps(Software software) {
-        return Lists.newArrayList(Iterables.transform(software.getFiles().entrySet(),
-            new Function<Map.Entry<String, String>, Map<String, String>>() {
-                @Override
-                public Map<String, String> apply(Map.Entry<String, String> entry) {
-                    return ImmutableMap.of("source", entry.getKey(), "destination", entry.getValue());
-                }
-            }));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activities/InstallPackages.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activities/InstallPackages.java b/core/src/main/java/com/axemblr/provisionr/core/activities/InstallPackages.java
deleted file mode 100644
index 3581d1c..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activities/InstallPackages.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.core.Mustache;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-public class InstallPackages extends PuppetActivity {
-
-    public static final String PACKAGES_TEMPLATE = "/com/axemblr/provisionr/core/puppet/packages.pp.mustache";
-
-    public InstallPackages() {
-        super("packages");
-    }
-
-    @Override
-    public String createPuppetScript(Pool pool, Machine machine) throws IOException {
-        return Mustache.toString(InstallPackages.class, PACKAGES_TEMPLATE,
-            ImmutableMap.of("packages", packagesAsListOfMaps(pool.getSoftware())));
-    }
-
-    private List<Map<String, String>> packagesAsListOfMaps(Software software) {
-        ImmutableList.Builder<Map<String, String>> result = ImmutableList.builder();
-        for (String pkg : software.getPackages()) {
-            result.add(ImmutableMap.of("package", pkg));
-        }
-        return result.build();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activities/InstallRepositories.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activities/InstallRepositories.java b/core/src/main/java/com/axemblr/provisionr/core/activities/InstallRepositories.java
deleted file mode 100644
index 880f7d4..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activities/InstallRepositories.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.software.Repository;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.core.Mustache;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import java.util.List;
-import java.util.Map;
-
-public class InstallRepositories extends PuppetActivity {
-
-    public static final String REPOSITORIES_TEMPLATE =
-        "/com/axemblr/provisionr/core/puppet/repositories.pp.mustache";
-
-    public InstallRepositories() {
-        super("repositories");
-    }
-
-    @Override
-    public String createPuppetScript(Pool pool, Machine machine) throws Exception {
-        return Mustache.toString(getClass(), REPOSITORIES_TEMPLATE,
-            ImmutableMap.<String, List<Map<String, String>>>of(
-                "repositories", repositoriesAsListOfMaps(pool.getSoftware())));
-    }
-
-    private List<Map<String, String>> repositoriesAsListOfMaps(Software software) {
-        return Lists.transform(software.getRepositories(), new Function<Repository, Map<String, String>>() {
-            @Override
-            public Map<String, String> apply(Repository repository) {
-                ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String>builder()
-                    .put("name", repository.getName())
-                    .put("content", Joiner.on("\\n").join(repository.getEntries()));
-
-                if (repository.getKey().isPresent()) {
-                    builder.put("key", repository.getKey().get().replace("\n", "\\n"));
-                }
-                return builder.build();
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activities/IsMachinePortOpen.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activities/IsMachinePortOpen.java b/core/src/main/java/com/axemblr/provisionr/core/activities/IsMachinePortOpen.java
deleted file mode 100644
index b94a850..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activities/IsMachinePortOpen.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Check that we can connect to a specific port on a remote machine
- * <p/>
- * This activity expects to find an environment variable named 'machine'
- */
-public class IsMachinePortOpen implements JavaDelegate {
-
-    private static final Logger LOG = LoggerFactory.getLogger(IsMachinePortOpen.class);
-
-    public static final String MACHINE = "machine";
-    public static final int TIMEOUT_IN_MILLISECONDS = 1000;
-
-    private final String resultVariable;
-    private final int port;
-
-    public IsMachinePortOpen(String resultVariable, int port) {
-        checkArgument(port > 0, "invalid port number");
-        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
-        this.port = port;
-    }
-
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-        Machine machine = (Machine) execution.getVariable(MACHINE);
-        checkNotNull(machine, "expecting a process variable named machine (multi-instance?)");
-
-        if (isPortOpen(machine, port)) {
-            LOG.info("<< Port {} is OPEN on {}", port, machine.getPublicDnsName());
-            execution.setVariable(resultVariable, true);
-
-        } else {
-            LOG.info("<< Port {} is CLOSED on {}", port, machine.getPublicDnsName());
-            execution.setVariable(resultVariable, false);
-        }
-    }
-
-    private boolean isPortOpen(Machine machine, int port) {
-        InetSocketAddress socketAddress = new InetSocketAddress(machine.getPublicDnsName(), port);
-
-        Socket socket = null;
-        try {
-            socket = new Socket();
-            socket.setReuseAddress(false);
-            socket.setSoLinger(false, 1);
-            socket.setSoTimeout(TIMEOUT_IN_MILLISECONDS);
-            socket.connect(socketAddress, TIMEOUT_IN_MILLISECONDS);
-
-        } catch (IOException e) {
-            return false;
-        } finally {
-            if (socket != null) {
-                try {
-                    socket.close();
-                } catch (IOException ioe) {
-                    // no work to do
-                }
-            }
-        }
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activities/KillMachineSetUpProcesses.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activities/KillMachineSetUpProcesses.java b/core/src/main/java/com/axemblr/provisionr/core/activities/KillMachineSetUpProcesses.java
deleted file mode 100644
index b0134af..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activities/KillMachineSetUpProcesses.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class KillMachineSetUpProcesses implements JavaDelegate {
-
-    private static final Logger LOG = LoggerFactory.getLogger(KillMachineSetUpProcesses.class);
-
-    private RuntimeService runtimeService;
-    private String variableWithProcessIds;
-
-    public KillMachineSetUpProcesses(RuntimeService runtimeService, String variableWithProcessIds) {
-        this.runtimeService = checkNotNull(runtimeService, "runtimeService is null");
-        this.variableWithProcessIds = checkNotNull(variableWithProcessIds, "variableWithProcessIds is null");
-    }
-
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-        @SuppressWarnings("unchecked")
-        List<String> processIds = (List<String>) execution.getVariable(variableWithProcessIds);
-
-        List<String> forceEnded = Lists.newArrayList(Iterables.filter(processIds, new Predicate<String>() {
-            @Override
-            public boolean apply(String processInstanceId) {
-                ProcessInstance instance = runtimeService.createProcessInstanceQuery()
-                    .processInstanceId(processInstanceId).singleResult();
-                if (instance != null && !instance.isEnded()) {
-                    runtimeService.deleteProcessInstance(processInstanceId, "Pending process needs to be killed");
-                    return true;
-                }
-                return false;
-            }
-        }));
-        LOG.info("Killed pending machine setup processes: {}", forceEnded);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activities/PuppetActivity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activities/PuppetActivity.java b/core/src/main/java/com/axemblr/provisionr/core/activities/PuppetActivity.java
deleted file mode 100644
index 9d28e47..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activities/PuppetActivity.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.axemblr.provisionr.core.Ssh;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-import net.schmizz.sshj.SSHClient;
-import net.schmizz.sshj.connection.channel.direct.Session;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Abstract activity useful for implementing activities that execute
- * puppet scripts on pool machines
- */
-public abstract class PuppetActivity implements JavaDelegate {
-
-    private static final Logger LOG = LoggerFactory.getLogger(PuppetActivity.class);
-
-    /**
-     * Puppet apply had no failures during the current transaction
-     * <p/>
-     * --detailed-exitcodes Provide transaction information via exit codes. If this is
-     * enabled, an exit code of '2' means there were changes, an exit code of '4' means
-     * there were failures during the transaction, and an exit code of '6' means there
-     * were both changes and failures.
-     *
-     * @see <a href="http://docs.puppetlabs.com/man/apply.html" />
-     */
-    public static final int PUPPET_FINISHED_WITH_NO_FAILURES = 2;
-
-    private final String remoteFileName;
-
-    public PuppetActivity(String remoteFileName) {
-        this.remoteFileName = checkNotNull(remoteFileName);
-    }
-
-    /**
-     * This method creates a Puppet script for remote execution
-     */
-    public abstract String createPuppetScript(Pool pool, Machine machine) throws Exception;
-
-    /**
-     * Override this method to change the credentials used for SSH access
-     */
-    public AdminAccess overrideAdminAccess(Pool pool) {
-        return pool.getAdminAccess();
-    }
-
-    /**
-     * Map of additional files to create on the remote machine. Contains pairs of (remotePath, content)
-     */
-    public Map<String, String> createAdditionalFiles(Pool pool, Machine machine) throws Exception {
-        return ImmutableMap.of();
-    }
-
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-        Pool pool = (Pool) execution.getVariable(CoreProcessVariables.POOL);
-        checkNotNull(pool, "Please add the pool description as a process " +
-            "variable with the name '%s'.", CoreProcessVariables.POOL);
-
-        Machine machine = (Machine) execution.getVariable("machine");
-        checkNotNull(machine, "expecting a process variable named 'machine'");
-
-        LOG.info(">> Connecting to machine {} to run puppet script", machine);
-
-        SSHClient client = Ssh.newClient(machine, overrideAdminAccess(pool));
-        try {
-            for (Map.Entry<String, String> entry : createAdditionalFiles(pool, machine).entrySet()) {
-                Ssh.createFile(client, /* content = */ entry.getValue(), 0600, /* destination= */ entry.getKey());
-            }
-
-            final String destination = "/tmp/" + remoteFileName + ".pp";
-            Ssh.createFile(client, createPuppetScript(pool, machine), 0600, destination);
-
-            Session session = client.startSession();
-            try {
-                session.allocateDefaultPTY();
-
-                // TODO: extract this loop outside of this activity (probably using a business process error)
-                final String runScriptWithWaitCommand = "while ! which puppet &> /dev/null ; " +
-                    "do echo 'Puppet command not found. Waiting for userdata.sh script to finish (10s)' " +
-                    "&& sleep 10; " +
-                    "done " +
-                    "&& sudo puppet apply --detailed-exitcodes --debug --verbose " + destination;
-                Session.Command command = session.exec(runScriptWithWaitCommand);
-
-                Ssh.logCommandOutput(LOG, machine.getExternalId(), command);
-                command.join();
-
-                final Integer exitStatus = command.getExitStatus();
-                if (exitStatus != PUPPET_FINISHED_WITH_NO_FAILURES && exitStatus != 0) {
-                    throw new RuntimeException(String.format("Failed to execute puppet. " +
-                        "Exit code: %d. Exit message: %s", exitStatus, command.getExitErrorMessage()));
-
-                } else {
-                    LOG.info("<< Command completed successfully with exit code 0");
-                }
-
-
-            } finally {
-                session.close();
-            }
-        } finally {
-            client.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/activities/SpawnProcessForEachMachine.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/activities/SpawnProcessForEachMachine.java b/core/src/main/java/com/axemblr/provisionr/core/activities/SpawnProcessForEachMachine.java
deleted file mode 100644
index 4c2e36b..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/activities/SpawnProcessForEachMachine.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.activities;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.core.CoreConstants;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.JavaDelegate;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Create an Activiti process for each machine and store the process IDs
- */
-public class SpawnProcessForEachMachine implements JavaDelegate {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SpawnProcessForEachMachine.class);
-
-    /**
-     * Name of the process variable that stores a {@link com.axemblr.provisionr.api.pool.Machine Machine} object.
-     * Used inside the process to connect to that machine.
-     */
-    private static final String MACHINE = "machine";
-
-    private final ProcessEngine processEngine;
-    private final String processKey;
-    private final String type;
-    private final String resultVariable;
-
-    public SpawnProcessForEachMachine(
-        ProcessEngine processEngine, String processKey, String type, String resultVariable
-    ) {
-        this.processEngine = checkNotNull(processEngine, "processEngine is null");
-        this.processKey = checkNotNull(processKey, "processKey is null");
-        this.type = checkNotNull(type, "type is null");
-        this.resultVariable = checkNotNull(resultVariable, "resultVariable is null");
-    }
-
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-        final Pool pool = (Pool) execution.getVariable(CoreProcessVariables.POOL);
-        checkNotNull(pool, "Expecting to find a pool description as process variable");
-
-        @SuppressWarnings("unchecked")
-        List<Machine> machines = (List<Machine>) execution.getVariable(CoreProcessVariables.MACHINES);
-        checkNotNull(machines, "Expecting to find the list of machines as process variable");
-
-        final String poolBusinessKey = String.class.cast(execution.getVariable(CoreProcessVariables.POOL_BUSINESS_KEY));
-        checkNotNull(poolBusinessKey, "No way to link sub-processes to master process, poolBusinessKey is null");
-
-        /* Authenticate as kermit to make the process visible in the Explorer UI */
-        processEngine.getIdentityService().setAuthenticatedUserId(CoreConstants.ACTIVITI_EXPLORER_DEFAULT_USER);
-
-        List<String> processIds = Lists.newArrayList();
-        for (Machine machine : machines) {
-            final String perMachineProcessBusinessKey = String.format("%s-%s-%s",
-                execution.getProcessBusinessKey(), type, machine.getExternalId());
-
-            ProcessInstance perMachineProcess = processEngine.getRuntimeService().startProcessInstanceByKey(
-                processKey, perMachineProcessBusinessKey,
-                ImmutableMap.<String, Object>of(CoreProcessVariables.POOL, pool,
-                    CoreProcessVariables.POOL_BUSINESS_KEY, poolBusinessKey,
-                    CoreProcessVariables.IS_CACHED_IMAGE, pool.getSoftware().isCachedImage(),
-                    MACHINE, machine));
-
-            LOG.info("Started background '" + type + "' process {} ({}) for machine {}",
-                new Object[]{perMachineProcessBusinessKey, perMachineProcess.getId(), machine.getExternalId()});
-            processIds.add(perMachineProcess.getId());
-        }
-
-        LOG.info("Saving process IDs {} as {}", processIds, resultVariable);
-        execution.setVariable(resultVariable, processIds);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/logging/ErrorStreamLogger.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/logging/ErrorStreamLogger.java b/core/src/main/java/com/axemblr/provisionr/core/logging/ErrorStreamLogger.java
deleted file mode 100644
index b578069..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/logging/ErrorStreamLogger.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.logging;
-
-import java.io.InputStream;
-import org.slf4j.Logger;
-import org.slf4j.Marker;
-
-public class ErrorStreamLogger extends StreamLogger {
-
-    public ErrorStreamLogger(InputStream inputStream, Logger logger, Marker marker) {
-        super(inputStream, logger, marker);
-    }
-
-    @Override
-    protected void log(Logger logger, Marker marker, String line) {
-        logger.error(marker, line);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/logging/InfoStreamLogger.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/logging/InfoStreamLogger.java b/core/src/main/java/com/axemblr/provisionr/core/logging/InfoStreamLogger.java
deleted file mode 100644
index 5fb67d1..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/logging/InfoStreamLogger.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.logging;
-
-import java.io.InputStream;
-import org.slf4j.Logger;
-import org.slf4j.Marker;
-
-public class InfoStreamLogger extends StreamLogger {
-
-    public InfoStreamLogger(InputStream inputStream, Logger logger, Marker marker) {
-        super(inputStream, logger, marker);
-    }
-
-    @Override
-    protected void log(Logger logger, Marker marker, String line) {
-        logger.info(marker, line);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/logging/StreamLogger.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/logging/StreamLogger.java b/core/src/main/java/com/axemblr/provisionr/core/logging/StreamLogger.java
deleted file mode 100644
index 044845e..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/logging/StreamLogger.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.logging;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Throwables;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import org.slf4j.Logger;
-import org.slf4j.Marker;
-
-public abstract class StreamLogger extends Thread {
-
-    private final InputStream inputStream;
-    private final Logger logger;
-    private final Marker marker;
-
-    public StreamLogger(InputStream inputStream, Logger logger, Marker marker) {
-        this.inputStream = checkNotNull(inputStream, "inputStream is null");
-        this.logger = checkNotNull(logger, "logger is null");
-        this.marker = checkNotNull(marker, "marker is null");
-
-        setName(marker.getName());
-        setDaemon(true);
-    }
-
-    /**
-     * Write the log message at a specific level including the marker
-     *
-     * @param logger reference to external logger
-     * @param marker log message marker
-     * @param line   line collected from the input stream
-     */
-    protected abstract void log(Logger logger, Marker marker, String line);
-
-
-    @Override
-    public void run() {
-        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
-        try {
-            String line;
-            while ((line = reader.readLine()) != null) {
-                if (!line.isEmpty()) {
-                    log(logger, marker, line);
-                }
-            }
-        } catch (IOException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/templates/PoolTemplate.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/templates/PoolTemplate.java b/core/src/main/java/com/axemblr/provisionr/core/templates/PoolTemplate.java
deleted file mode 100644
index 9097f22..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/templates/PoolTemplate.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.templates;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.google.common.base.Function;
-
-/**
- * Marker interface for pre-configured pools. You can use it by
- * applying the function on an existing pool definition
- */
-public interface PoolTemplate extends Function<Pool, Pool> {
-
-    /**
-     * Get the pre-configured pool template identifier
-     */
-    String getId();
-
-    /**
-     * A short description of this template
-     */
-    String getDescription();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/templates/PoolTemplateInstaller.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/templates/PoolTemplateInstaller.java b/core/src/main/java/com/axemblr/provisionr/core/templates/PoolTemplateInstaller.java
deleted file mode 100644
index 3147e9e..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/templates/PoolTemplateInstaller.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.templates;
-
-import com.axemblr.provisionr.core.templates.xml.XmlTemplate;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Maps;
-import java.io.File;
-import java.util.concurrent.ConcurrentMap;
-import org.apache.felix.fileinstall.ArtifactInstaller;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Listener for pool template files
- * <p/>
- * When a new xml file is places under templates this class is
- * notified and a new pool template is registered as a service
- */
-public class PoolTemplateInstaller implements ArtifactInstaller {
-
-    private static final Logger LOG = LoggerFactory.getLogger(PoolTemplateInstaller.class);
-
-    public static final String TEMPLATES_FOLDER = "templates";
-    public static final String TEMPLATES_EXTENSION = ".xml";
-
-    /**
-     * A bundle context provided by the OSGi framework
-     */
-    private final BundleContext bundleContext;
-
-    /**
-     * A map with all the pool templates registered by this listener
-     */
-    private final ConcurrentMap<String, ServiceRegistration> templates;
-
-    public PoolTemplateInstaller(BundleContext bundleContext) {
-        this.bundleContext = checkNotNull(bundleContext, "bundleContext is null");
-        this.templates = Maps.newConcurrentMap();
-    }
-
-    @Override
-    public boolean canHandle(File file) {
-        return TEMPLATES_FOLDER.equals(file.getParentFile().getName())
-            && file.getName().endsWith(TEMPLATES_EXTENSION);
-    }
-
-    /**
-     * Install a new pool template as a service using the file content
-     * <p/>
-     * The absolute file path is the unique identifier
-     */
-    @Override
-    public void install(File file) throws Exception {
-        final String absolutePath = file.getAbsolutePath();
-        LOG.info("Installing Pool template from  " + absolutePath);
-
-        if (!templates.containsKey(absolutePath)) {
-            PoolTemplate template = XmlTemplate.newXmlTemplate(file);
-            ServiceRegistration registration = bundleContext
-                .registerService(PoolTemplate.class.getName(), template, null);
-
-            templates.put(absolutePath, registration);
-            LOG.info("Registered new template with ID: " + template.getId());
-        }
-    }
-
-    /**
-     * Uninstall a pool description identified by the absolute file path
-     */
-    @Override
-    public void uninstall(File file) throws Exception {
-        final String absolutePath = file.getAbsolutePath();
-        LOG.info("Uninstalling Pool template for path " + absolutePath);
-
-        if (templates.containsKey(absolutePath)) {
-            templates.remove(absolutePath).unregister();
-        }
-    }
-
-    /**
-     * Update a pool template
-     * <p/>
-     * This method performs no actions if there is no pool registered for this file
-     */
-    @Override
-    public void update(File file) throws Exception {
-        if (templates.containsKey(file.getAbsolutePath())) {
-            uninstall(file);
-            install(file);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/templates/xml/FileEntry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/templates/xml/FileEntry.java b/core/src/main/java/com/axemblr/provisionr/core/templates/xml/FileEntry.java
deleted file mode 100644
index edaba76..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/templates/xml/FileEntry.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.templates.xml;
-
-import com.google.common.annotations.VisibleForTesting;
-import static com.google.common.base.Preconditions.checkNotNull;
-import javax.xml.bind.annotation.XmlAttribute;
-
-/**
- * Represents a file entry from a pool template
- * <p/>
- * Designed to be consumed only by JAXB. It looks like this in xml:
- * <p/>
- * <file source="http://archive.cloudera.com/cm4/installer/latest/cloudera-manager-installer.bin"
- * destination="/opt/cloudera-manager-installer.bin"/>
- */
-public class FileEntry {
-
-    private String source;
-    private String destination;
-
-    public FileEntry() {
-    }
-
-    @VisibleForTesting
-    FileEntry(String source, String destination) {
-        this.source = checkNotNull(source, "source is null");
-        this.destination = checkNotNull(destination, "destination is null");
-    }
-
-    @XmlAttribute(name = "source")
-    public String getSource() {
-        return source;
-    }
-
-    public void setSource(String source) {
-        this.source = checkNotNull(source, "source is null");
-    }
-
-    @XmlAttribute(name = "destination")
-    public String getDestination() {
-        return destination;
-    }
-
-    public void setDestination(String destination) {
-        this.destination = checkNotNull(destination, "destination is null");
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        FileEntry fileEntry = (FileEntry) o;
-
-        if (destination != null ? !destination.equals(fileEntry.destination) : fileEntry.destination != null)
-            return false;
-        if (source != null ? !source.equals(fileEntry.source) : fileEntry.source != null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = source != null ? source.hashCode() : 0;
-        result = 31 * result + (destination != null ? destination.hashCode() : 0);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "FileEntry{" +
-            "source='" + source + '\'' +
-            ", destination='" + destination + '\'' +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/core/src/main/java/com/axemblr/provisionr/core/templates/xml/RepositoryEntry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/axemblr/provisionr/core/templates/xml/RepositoryEntry.java b/core/src/main/java/com/axemblr/provisionr/core/templates/xml/RepositoryEntry.java
deleted file mode 100644
index b991c4c..0000000
--- a/core/src/main/java/com/axemblr/provisionr/core/templates/xml/RepositoryEntry.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.core.templates.xml;
-
-import com.google.common.annotations.VisibleForTesting;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Lists.newArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-
-/**
- * Represents a custom repository entry from a pool template
- * <p/>
- * Designed to be consumed only by JAXB. It looks like this in xml:
- * <p/>
- * <repository id="cloudera-cdh3">
- * <entries>
- * <entry>deb http://archive.cloudera.com/debian lucid-cdh3 contrib</entry>
- * </entries>
- * <key><![CDATA[-----BEGIN PGP PUBLIC KEY BLOCK----- ]]</key>
- * </repository>
- */
-public class RepositoryEntry {
-
-    private String id;
-
-    private List<String> entries = newArrayList();
-
-    private String key;
-
-    public RepositoryEntry() {
-    }
-
-    @VisibleForTesting
-    RepositoryEntry(String id, List<String> entries, String key) {
-        this.id = checkNotNull(id, "id is null");
-        this.entries = checkNotNull(entries, "entries is null");
-        this.key = checkNotNull(key, "key is null");
-    }
-
-    @XmlAttribute(name = "id")
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = checkNotNull(id, "id is null");
-    }
-
-    @XmlElementWrapper(name = "entries")
-    @XmlElement(name = "entry")
-    public List<String> getEntries() {
-        return entries;
-    }
-
-    public void setEntries(List<String> entries) {
-        this.entries = checkNotNull(entries, "entries is null");
-    }
-
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(String key) {
-        this.key = checkNotNull(key, "key is null");
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        RepositoryEntry that = (RepositoryEntry) o;
-
-        if (entries != null ? !entries.equals(that.entries) : that.entries != null) return false;
-        if (id != null ? !id.equals(that.id) : that.id != null) return false;
-        if (key != null ? !key.equals(that.key) : that.key != null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = id != null ? id.hashCode() : 0;
-        result = 31 * result + (entries != null ? entries.hashCode() : 0);
-        result = 31 * result + (key != null ? key.hashCode() : 0);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "RepositoryEntry{" +
-            "id='" + id + '\'' +
-            ", entries=" + entries +
-            ", key='" + key + '\'' +
-            '}';
-    }
-}


[10/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListServicesCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListServicesCommandTest.java b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListServicesCommandTest.java
deleted file mode 100644
index c265613..0000000
--- a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListServicesCommandTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.google.common.collect.ImmutableList;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.util.List;
-import org.apache.felix.service.command.CommandSession;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class ListServicesCommandTest {
-
-    @Test
-    public void testListServices() throws Exception {
-        List<Provisionr> services = ImmutableList.of(
-            newProvisionrMockWithId("p1"),
-            newProvisionrMockWithId("p2")
-        );
-
-        ListServicesCommand command = new ListServicesCommand(services);
-
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        PrintStream out = new PrintStream(outputStream);
-        command.setOut(out);
-
-        CommandSession session = mock(CommandSession.class);
-        command.execute(session);
-        out.close();
-
-        for (Provisionr service : services) {
-            verify(service).getId();
-        }
-
-        assertThat(outputStream.toString()).isEqualTo("Services: p1, p2\n");
-    }
-
-    private Provisionr newProvisionrMockWithId(String id) {
-        Provisionr service = mock(Provisionr.class);
-        when(service.getId()).thenReturn(id);
-        return service;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListTemplatesCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListTemplatesCommandTest.java b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListTemplatesCommandTest.java
deleted file mode 100644
index 36678af..0000000
--- a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ListTemplatesCommandTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import com.axemblr.provisionr.core.templates.PoolTemplate;
-import com.axemblr.provisionr.core.templates.xml.XmlTemplate;
-import com.google.common.base.Charsets;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.io.Resources;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import org.apache.felix.service.command.CommandSession;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-
-public class ListTemplatesCommandTest {
-
-    private ByteArrayOutputStream outputStream;
-    private PrintStream out;
-
-    @Before
-    public void setUp() {
-        outputStream = new ByteArrayOutputStream();
-        out = new PrintStream(outputStream);
-    }
-
-    @After
-    public void tearDown() throws IOException {
-        out.close();
-        outputStream.close();
-    }
-
-    @Test
-    public void testListTemplates() throws Exception {
-        final ImmutableList<PoolTemplate> templates = ImmutableList.<PoolTemplate>of(
-            XmlTemplate.newXmlTemplate(readDefaultTemplate("jenkins")),
-            XmlTemplate.newXmlTemplate(readDefaultTemplate("cdh3")));
-
-        ListTemplatesCommand command = new ListTemplatesCommand(templates);
-
-        command.setOut(out);
-        command.execute(mock(CommandSession.class));
-
-        out.flush();
-
-        assertThat(outputStream.toString()).contains("jenkins").contains("cdh3");
-    }
-
-    private String readDefaultTemplate(String name) {
-        try {
-            return Resources.toString(Resources.getResource(PoolTemplate.class,
-                String.format("/com/axemblr/provisionr/core/templates/%s.xml", name)), Charsets.UTF_8);
-
-        } catch (IOException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ResetRetriesCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ResetRetriesCommandTest.java b/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ResetRetriesCommandTest.java
deleted file mode 100644
index d7b1437..0000000
--- a/karaf/commands/src/test/java/com/axemblr/provisionr/commands/ResetRetriesCommandTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.commands;
-
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.google.common.collect.ImmutableList;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.util.List;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.engine.runtime.ProcessInstanceQuery;
-import org.apache.felix.service.command.CommandSession;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ResetRetriesCommandTest {
-
-    private static final String BUSINESS_KEY = "k1";
-    private ByteArrayOutputStream outputStream;
-    private PrintStream out;
-
-    @Before
-    public void setUp() throws Exception {
-        outputStream = new ByteArrayOutputStream();
-        out = new PrintStream(outputStream);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        out.close();
-        outputStream.close();
-    }
-
-    @Test
-    public void testResumeCommandNeedsBusinessKey() throws Exception {
-        final ResetRetriesCommand command = new ResetRetriesCommand(newMockProcessEngine());
-        command.setOut(out);
-
-        CommandSession commandSession = mock(CommandSession.class);
-        command.execute(commandSession);
-        out.flush();
-        assertThat(outputStream.toString()).containsIgnoringCase("please supply a business key");
-    }
-
-    private ProcessEngine newMockProcessEngine() {
-        final ProcessEngine engine = mock(ProcessEngine.class);
-        final List<ProcessInstance> processes = ImmutableList.of(
-            newProcessInstanceMock("p1", BUSINESS_KEY, true),
-            newProcessInstanceMock("p2", BUSINESS_KEY, false),
-            newProcessInstanceMock("p3", BUSINESS_KEY, true)
-        );
-
-        final RuntimeService runtimeService = mock(RuntimeService.class);
-        final ProcessInstanceQuery processInstanceQuery = mock(ProcessInstanceQuery.class);
-
-        when(engine.getRuntimeService()).thenReturn(runtimeService);
-        when(runtimeService.createProcessInstanceQuery()).thenReturn(processInstanceQuery);
-        when(processInstanceQuery.variableValueEquals(CoreProcessVariables.POOL_BUSINESS_KEY, BUSINESS_KEY))
-            .thenReturn(processInstanceQuery);
-        when(processInstanceQuery.orderByProcessInstanceId()).thenReturn(processInstanceQuery);
-        when(processInstanceQuery.desc()).thenReturn(processInstanceQuery);
-        when(processInstanceQuery.list()).thenReturn(processes);
-
-        return engine;
-    }
-
-    private ProcessInstance newProcessInstanceMock(String id, String businessKey, boolean isSuspended) {
-        ProcessInstance instance = mock(ProcessInstance.class);
-
-        when(instance.getId()).thenReturn(id);
-        when(instance.getBusinessKey()).thenReturn(businessKey);
-        when(instance.isSuspended()).thenReturn(isSuspended);
-
-        return instance;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/org/apache/provisionr/commands/CreatePoolCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/org/apache/provisionr/commands/CreatePoolCommandTest.java b/karaf/commands/src/test/java/org/apache/provisionr/commands/CreatePoolCommandTest.java
new file mode 100644
index 0000000..d48487e
--- /dev/null
+++ b/karaf/commands/src/test/java/org/apache/provisionr/commands/CreatePoolCommandTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.io.Resources;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.provider.ProviderBuilder;
+import org.apache.provisionr.core.templates.PoolTemplate;
+import org.apache.provisionr.core.templates.xml.XmlTemplate;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentCaptor;
+import static org.mockito.Matchers.anyMapOf;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class CreatePoolCommandTest {
+
+    public static final String TEST_PROVISIONR_ID = "amazon";
+    public static final String TEST_BUSINESS_KEY = "j-123";
+
+    @Rule
+    public ExpectedException exception = ExpectedException.none();
+
+    @Test
+    public void testCreatePoolStartsTheManagementProcess() throws Exception {
+        final Provisionr service = newProvisionrMockWithId(TEST_PROVISIONR_ID);
+        final Pool pool = mock(Pool.class);
+
+        final List<Provisionr> services = ImmutableList.of(service);
+        final List<PoolTemplate> templates = ImmutableList.of();
+        CreatePoolCommand command = new CreatePoolCommand(services, templates) {
+            @Override
+            protected Pool createPoolFromArgumentsAndServiceDefaults(Provisionr service) {
+                return pool;
+            }
+        };
+        command.setId(TEST_PROVISIONR_ID);
+        command.setKey(TEST_BUSINESS_KEY);
+
+        CommandSession session = mock(CommandSession.class);
+        String output = (String) command.execute(session);
+
+        verify(service).startPoolManagementProcess(TEST_BUSINESS_KEY, pool);
+        assertThat(output).isEqualTo("Pool management process started (id: null)");
+    }
+
+    @Test(expected = NoSuchElementException.class)
+    public void testProvisioningServiceNotFound() throws Exception {
+        CreatePoolCommand command = new CreatePoolCommand(Collections.<Provisionr>emptyList(),
+            Collections.<PoolTemplate>emptyList());
+        command.setId("dummy");
+
+        CommandSession session = mock(CommandSession.class);
+        command.execute(session);
+    }
+
+    @Test
+    public void testCreatePoolWithTemplate() {
+        final PoolTemplate template = XmlTemplate.newXmlTemplate(readDefaultTemplate("jenkins"));
+
+        CreatePoolCommand command = newPoolCommandWithMockedAdminAccess(template);
+
+        command.setId("service");
+        command.setKey("key");
+        command.setTemplate(template.getId());
+
+        Provisionr service = mock(Provisionr.class);
+        Provider provider = newProviderMockWithBuilder();
+        when(service.getDefaultProvider()).thenReturn(Optional.of(provider));
+
+        Pool pool = command.createPoolFromArgumentsAndServiceDefaults(service);
+
+        assertThat(pool.getSoftware().getRepositories()).hasSize(1);
+        assertThat(pool.getSoftware().getPackages()).contains("jenkins").contains("git-core");
+    }
+
+    @Test
+    public void testProviderSpecificOptions() {
+        CreatePoolCommand command = newPoolCommandWithMockedAdminAccess();
+        command.setId("service");
+        command.setKey("key");
+        command.setProviderOptions(Lists.newArrayList("spotBid=0.07"));
+
+        Provisionr service = mock(Provisionr.class);
+        Provider provider = newProviderMockWithBuilder();
+        when(service.getDefaultProvider()).thenReturn(Optional.of(provider));
+
+        command.createPoolFromArgumentsAndServiceDefaults(service);
+
+        @SuppressWarnings("unchecked")
+        ArgumentCaptor<Map<String, String>> argument = (ArgumentCaptor<Map<String, String>>) (Object)
+            ArgumentCaptor.forClass(Map.class);
+        verify(provider.toBuilder()).options(argument.capture());
+
+        assertThat(argument.getValue().containsKey("spotBid")).isTrue();
+        assertThat(argument.getValue().get("spotBid")).isEqualTo("0.07");
+    }
+
+    @Test
+    public void testBlockDeviceOptions() {
+        CreatePoolCommand command = newPoolCommandWithMockedAdminAccess();
+        command.setId("service");
+        command.setKey("key");
+
+        Provisionr service = mock(Provisionr.class);
+        Provider provider = newProviderMockWithBuilder();
+        when(service.getDefaultProvider()).thenReturn(Optional.of(provider));
+
+        Pool pool = command.createPoolFromArgumentsAndServiceDefaults(service);
+        assertThat(pool.getHardware().getBlockDevices()).isEmpty();
+
+        command.setBlockDeviceOptions(Lists.newArrayList("/dev/sda2:8", "/dev/sda9:2"));
+        pool = command.createPoolFromArgumentsAndServiceDefaults(service);
+        assertThat(pool.getHardware().getBlockDevices()).hasSize(2);
+        assertThat(pool.getHardware().getBlockDevices().get(0).getSize()).isEqualTo(8);
+        assertThat(pool.getHardware().getBlockDevices().get(0).getName()).isEqualTo("/dev/sda2");
+        assertThat(pool.getHardware().getBlockDevices().get(1).getSize()).isEqualTo(2);
+        assertThat(pool.getHardware().getBlockDevices().get(1).getName()).isEqualTo("/dev/sda9");
+
+        command.setBlockDeviceOptions(Lists.newArrayList("/dev/sda1:7"));
+        pool = command.createPoolFromArgumentsAndServiceDefaults(service);
+        assertThat(pool.getHardware().getBlockDevices()).hasSize(1);
+        assertThat(pool.getHardware().getBlockDevices().get(0).getSize()).isEqualTo(7);
+
+        command.setBlockDeviceOptions(Lists.newArrayList("this=breaks"));
+        exception.expect(IllegalArgumentException.class);
+        pool = command.createPoolFromArgumentsAndServiceDefaults(service);
+
+        command.setBlockDeviceOptions(Lists.newArrayList("/dev/sda1"));
+        exception.expect(IllegalArgumentException.class);
+        pool = command.createPoolFromArgumentsAndServiceDefaults(service);
+
+    }
+
+    private Provisionr newProvisionrMockWithId(String id) {
+        Provisionr service = mock(Provisionr.class);
+        when(service.getId()).thenReturn(id);
+        return service;
+    }
+
+    private Provider newProviderMockWithBuilder() {
+        Provider provider = mock(Provider.class);
+        ProviderBuilder providerBuilder = mock(ProviderBuilder.class);
+        when(providerBuilder.options(anyMapOf(String.class, String.class))).thenReturn(providerBuilder);
+        when(providerBuilder.createProvider()).thenReturn(provider);
+        when(provider.toBuilder()).thenReturn(providerBuilder);
+        return provider;
+    }
+
+
+    private String readDefaultTemplate(String name) {
+        try {
+            return Resources.toString(Resources.getResource(PoolTemplate.class,
+                String.format("/org/apache/provisionr/core/templates/%s.xml", name)), Charsets.UTF_8);
+
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    private CreatePoolCommand newPoolCommandWithMockedAdminAccess(PoolTemplate template) {
+        List<PoolTemplate> templates = template != null ? ImmutableList.<PoolTemplate>of(template) :
+            ImmutableList.<PoolTemplate>of();
+        return new CreatePoolCommand(Collections.<Provisionr>emptyList(), templates) {
+            @Override
+            protected AdminAccess collectCurrentUserCredentialsForAdminAccess() {
+                return mock(AdminAccess.class);
+            }
+        };
+    }
+
+    private CreatePoolCommand newPoolCommandWithMockedAdminAccess() {
+        return this.newPoolCommandWithMockedAdminAccess(null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/org/apache/provisionr/commands/DestroyPoolCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/org/apache/provisionr/commands/DestroyPoolCommandTest.java b/karaf/commands/src/test/java/org/apache/provisionr/commands/DestroyPoolCommandTest.java
new file mode 100644
index 0000000..9973f36
--- /dev/null
+++ b/karaf/commands/src/test/java/org/apache/provisionr/commands/DestroyPoolCommandTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.core.CoreProcessVariables;
+import com.google.common.collect.ImmutableList;
+import java.util.NoSuchElementException;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.runtime.ProcessInstanceQuery;
+import org.apache.felix.service.command.CommandSession;
+import org.junit.Test;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class DestroyPoolCommandTest {
+
+    public static final String TEST_PROVISIONR_ID = "amazon";
+
+    public static final String TEST_BUSINESS_KEY = "dummy";
+    public static final String PROCESS_INSTANCE_ID = "123";
+
+    @Test
+    public void testDestroyPool() throws Exception {
+        Provisionr service = mock(Provisionr.class);
+        when(service.getId()).thenReturn(TEST_PROVISIONR_ID);
+
+        ProcessEngine processEngine = mockProcessEngine(PROCESS_INSTANCE_ID, TEST_BUSINESS_KEY, TEST_PROVISIONR_ID);
+
+        DestroyPoolCommand command = new DestroyPoolCommand(ImmutableList.of(service), processEngine);
+        command.setBusinessKey(TEST_BUSINESS_KEY);
+
+        CommandSession session = mock(CommandSession.class);
+        command.execute(session);
+
+        verify(service).destroyPool(TEST_BUSINESS_KEY);
+    }
+
+    @Test(expected = NoSuchElementException.class)
+    public void testFailsWithAnEmptyServiceList() throws Exception {
+        ProcessEngine processEngine = mockProcessEngine(PROCESS_INSTANCE_ID, TEST_BUSINESS_KEY, TEST_PROVISIONR_ID);
+
+        DestroyPoolCommand command = new DestroyPoolCommand(ImmutableList.<Provisionr>of(), processEngine);
+
+        CommandSession session = mock(CommandSession.class);
+        command.setBusinessKey(TEST_BUSINESS_KEY);
+        command.execute(session);
+    }
+
+    public ProcessEngine mockProcessEngine(String processInstanceId, String businessKey, String providerId) {
+        ProcessInstance instance = mock(ProcessInstance.class);
+        when(instance.getId()).thenReturn(processInstanceId);
+
+        ProcessInstanceQuery query = mock(ProcessInstanceQuery.class);
+        when(query.singleResult()).thenReturn(instance);
+        when(query.processInstanceBusinessKey(eq(businessKey))).thenReturn(query);
+
+        RuntimeService runtimeService = mock(RuntimeService.class);
+        when(runtimeService.createProcessInstanceQuery()).thenReturn(query);
+        when(runtimeService.getVariable(eq(processInstanceId), eq(CoreProcessVariables.PROVIDER)))
+            .thenReturn(providerId);
+
+        ProcessEngine processEngine = mock(ProcessEngine.class);
+        when(processEngine.getRuntimeService()).thenReturn(runtimeService);
+
+        return processEngine;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/org/apache/provisionr/commands/ListPoolsCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/org/apache/provisionr/commands/ListPoolsCommandTest.java b/karaf/commands/src/test/java/org/apache/provisionr/commands/ListPoolsCommandTest.java
new file mode 100644
index 0000000..4f36d55
--- /dev/null
+++ b/karaf/commands/src/test/java/org/apache/provisionr/commands/ListPoolsCommandTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import com.google.common.collect.ImmutableList;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.List;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.runtime.ProcessInstanceQuery;
+import org.apache.felix.service.command.CommandSession;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Matchers;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ListPoolsCommandTest {
+
+    private ByteArrayOutputStream outputStream;
+    private PrintStream out;
+
+    @Before
+    public void setUp() {
+        outputStream = new ByteArrayOutputStream();
+        out = new PrintStream(outputStream);
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        out.close();
+        outputStream.close();
+    }
+
+    @Test
+    public void testNoProcessesRunning() throws Exception {
+        final ProcessEngine processEngine = newProcessEngineMock(Collections.<ProcessInstance>emptyList());
+
+        ListPoolsCommand command = new ListPoolsCommand(processEngine);
+        command.setOut(out);
+
+        CommandSession session = mock(CommandSession.class);
+        command.execute(session);
+        out.flush();
+
+        assertThat(outputStream.toString()).containsIgnoringCase("no active pools found");
+        outputStream.reset();
+
+        command.setKey("dummy");
+        command.execute(session);
+        out.flush();
+
+        assertThat(outputStream.toString()).containsIgnoringCase("no active pools found");
+    }
+
+    @Test
+    public void testListProcess() throws Exception {
+        final List<ProcessInstance> processes = ImmutableList.of(
+            newProcessInstanceMock("p1", "k1"),
+            newProcessInstanceMock("p2", "k2")
+        );
+        final ProcessEngine processEngine = newProcessEngineMock(processes);
+
+        Pool pool = mock(Pool.class);
+        setVariable(processEngine, "p1", CoreProcessVariables.POOL, pool);
+        setVariable(processEngine, "p1", CoreProcessVariables.POOL_BUSINESS_KEY, "k1");
+
+        ListPoolsCommand command = new ListPoolsCommand(processEngine);
+        command.setOut(out);
+
+        /* list all active pools */
+        CommandSession session = mock(CommandSession.class);
+        command.execute(session);
+        out.flush();
+
+        assertThat(outputStream.toString())
+            .contains("Pool Description")
+            .contains("List of Machines")
+            .contains("Pool Key: k1");
+
+        /* run the same command with a filter on business key */
+        outputStream.reset();
+        command.setKey("k2");
+        command.execute(session);
+        out.flush();
+
+        assertThat(outputStream.toString()).isEmpty();
+    }
+
+    private ProcessInstance newProcessInstanceMock(String id, String businessKey) {
+        ProcessInstance instance = mock(ProcessInstance.class);
+
+        when(instance.getId()).thenReturn(id);
+        when(instance.getBusinessKey()).thenReturn(businessKey);
+
+        return instance;
+    }
+
+    private void setVariable(ProcessEngine engine, String instanceId, String key, Object value) {
+        RuntimeService runtimeService = engine.getRuntimeService();
+
+        when(runtimeService.getVariable(instanceId, key)).thenReturn(value);
+    }
+
+    private ProcessEngine newProcessEngineMock(List<ProcessInstance> instances) {
+        ProcessEngine processEngine = mock(ProcessEngine.class);
+
+        RuntimeService runtimeService = mock(RuntimeService.class);
+        when(processEngine.getRuntimeService()).thenReturn(runtimeService);
+
+        ProcessInstanceQuery allInstancesQuery = mock(ProcessInstanceQuery.class);
+        when(allInstancesQuery.list()).thenReturn(instances);
+        when(runtimeService.createProcessInstanceQuery()).thenReturn(allInstancesQuery);
+
+        for (ProcessInstance instance : instances) {
+            ProcessInstanceQuery singleResultQuery = mock(ProcessInstanceQuery.class);
+
+            when(singleResultQuery.list()).thenReturn(ImmutableList.of(instance));
+            when(allInstancesQuery.processInstanceBusinessKey(instance.getBusinessKey()))
+                .thenReturn(singleResultQuery);
+        }
+
+        if (instances.isEmpty()) {
+            ProcessInstanceQuery emptyQuery = mock(ProcessInstanceQuery.class);
+
+            when(emptyQuery.list()).thenReturn(Collections.<ProcessInstance>emptyList());
+            when(allInstancesQuery.processInstanceBusinessKey(Matchers.<String>any()))
+                .thenReturn(emptyQuery);
+        }
+
+        return processEngine;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/org/apache/provisionr/commands/ListServicesCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/org/apache/provisionr/commands/ListServicesCommandTest.java b/karaf/commands/src/test/java/org/apache/provisionr/commands/ListServicesCommandTest.java
new file mode 100644
index 0000000..f3d642e
--- /dev/null
+++ b/karaf/commands/src/test/java/org/apache/provisionr/commands/ListServicesCommandTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import org.apache.provisionr.api.Provisionr;
+import com.google.common.collect.ImmutableList;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+import org.apache.felix.service.command.CommandSession;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ListServicesCommandTest {
+
+    @Test
+    public void testListServices() throws Exception {
+        List<Provisionr> services = ImmutableList.of(
+            newProvisionrMockWithId("p1"),
+            newProvisionrMockWithId("p2")
+        );
+
+        ListServicesCommand command = new ListServicesCommand(services);
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        PrintStream out = new PrintStream(outputStream);
+        command.setOut(out);
+
+        CommandSession session = mock(CommandSession.class);
+        command.execute(session);
+        out.close();
+
+        for (Provisionr service : services) {
+            verify(service).getId();
+        }
+
+        assertThat(outputStream.toString()).isEqualTo("Services: p1, p2\n");
+    }
+
+    private Provisionr newProvisionrMockWithId(String id) {
+        Provisionr service = mock(Provisionr.class);
+        when(service.getId()).thenReturn(id);
+        return service;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/org/apache/provisionr/commands/ListTemplatesCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/org/apache/provisionr/commands/ListTemplatesCommandTest.java b/karaf/commands/src/test/java/org/apache/provisionr/commands/ListTemplatesCommandTest.java
new file mode 100644
index 0000000..56b778f
--- /dev/null
+++ b/karaf/commands/src/test/java/org/apache/provisionr/commands/ListTemplatesCommandTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import org.apache.provisionr.core.templates.PoolTemplate;
+import org.apache.provisionr.core.templates.xml.XmlTemplate;
+import com.google.common.base.Charsets;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.io.Resources;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import org.apache.felix.service.command.CommandSession;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+
+public class ListTemplatesCommandTest {
+
+    private ByteArrayOutputStream outputStream;
+    private PrintStream out;
+
+    @Before
+    public void setUp() {
+        outputStream = new ByteArrayOutputStream();
+        out = new PrintStream(outputStream);
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        out.close();
+        outputStream.close();
+    }
+
+    @Test
+    public void testListTemplates() throws Exception {
+        final ImmutableList<PoolTemplate> templates = ImmutableList.<PoolTemplate>of(
+            XmlTemplate.newXmlTemplate(readDefaultTemplate("jenkins")),
+            XmlTemplate.newXmlTemplate(readDefaultTemplate("cdh3")));
+
+        ListTemplatesCommand command = new ListTemplatesCommand(templates);
+
+        command.setOut(out);
+        command.execute(mock(CommandSession.class));
+
+        out.flush();
+
+        assertThat(outputStream.toString()).contains("jenkins").contains("cdh3");
+    }
+
+    private String readDefaultTemplate(String name) {
+        try {
+            return Resources.toString(Resources.getResource(PoolTemplate.class,
+                String.format("/org/apache/provisionr/core/templates/%s.xml", name)), Charsets.UTF_8);
+
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/commands/src/test/java/org/apache/provisionr/commands/ResetRetriesCommandTest.java
----------------------------------------------------------------------
diff --git a/karaf/commands/src/test/java/org/apache/provisionr/commands/ResetRetriesCommandTest.java b/karaf/commands/src/test/java/org/apache/provisionr/commands/ResetRetriesCommandTest.java
new file mode 100644
index 0000000..b6044a3
--- /dev/null
+++ b/karaf/commands/src/test/java/org/apache/provisionr/commands/ResetRetriesCommandTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.commands;
+
+import com.google.common.collect.ImmutableList;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.runtime.ProcessInstanceQuery;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ResetRetriesCommandTest {
+
+    private static final String BUSINESS_KEY = "k1";
+    private ByteArrayOutputStream outputStream;
+    private PrintStream out;
+
+    @Before
+    public void setUp() throws Exception {
+        outputStream = new ByteArrayOutputStream();
+        out = new PrintStream(outputStream);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        out.close();
+        outputStream.close();
+    }
+
+    @Test
+    public void testResumeCommandNeedsBusinessKey() throws Exception {
+        final ResetRetriesCommand command = new ResetRetriesCommand(newMockProcessEngine());
+        command.setOut(out);
+
+        CommandSession commandSession = mock(CommandSession.class);
+        command.execute(commandSession);
+        out.flush();
+        assertThat(outputStream.toString()).containsIgnoringCase("please supply a business key");
+    }
+
+    private ProcessEngine newMockProcessEngine() {
+        final ProcessEngine engine = mock(ProcessEngine.class);
+        final List<ProcessInstance> processes = ImmutableList.of(
+            newProcessInstanceMock("p1", BUSINESS_KEY, true),
+            newProcessInstanceMock("p2", BUSINESS_KEY, false),
+            newProcessInstanceMock("p3", BUSINESS_KEY, true)
+        );
+
+        final RuntimeService runtimeService = mock(RuntimeService.class);
+        final ProcessInstanceQuery processInstanceQuery = mock(ProcessInstanceQuery.class);
+
+        when(engine.getRuntimeService()).thenReturn(runtimeService);
+        when(runtimeService.createProcessInstanceQuery()).thenReturn(processInstanceQuery);
+        when(processInstanceQuery.variableValueEquals(CoreProcessVariables.POOL_BUSINESS_KEY, BUSINESS_KEY))
+            .thenReturn(processInstanceQuery);
+        when(processInstanceQuery.orderByProcessInstanceId()).thenReturn(processInstanceQuery);
+        when(processInstanceQuery.desc()).thenReturn(processInstanceQuery);
+        when(processInstanceQuery.list()).thenReturn(processes);
+
+        return engine;
+    }
+
+    private ProcessInstance newProcessInstanceMock(String id, String businessKey, boolean isSuspended) {
+        ProcessInstance instance = mock(ProcessInstance.class);
+
+        when(instance.getId()).thenReturn(id);
+        when(instance.getBusinessKey()).thenReturn(businessKey);
+        when(instance.isSuspended()).thenReturn(isSuspended);
+
+        return instance;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/features/pom.xml
----------------------------------------------------------------------
diff --git a/karaf/features/pom.xml b/karaf/features/pom.xml
index ca14e80..9979d6e 100644
--- a/karaf/features/pom.xml
+++ b/karaf/features/pom.xml
@@ -15,16 +15,17 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Karaf Features</name>
+    <name>Apache Provisionr :: Karaf Features</name>
     <artifactId>provisionr-features</artifactId>
     <packaging>jar</packaging>
 
@@ -35,40 +36,40 @@
     <!-- Dependencies are used only for ordering the reactor -->
     <dependencies>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-amazon</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-cloudstack</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-console</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-rundeck</artifactId>
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-commands</artifactId>
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.activiti.karaf</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>activiti-karaf-commands</artifactId>
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.activiti.karaf</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>activiti-karaf-web-explorer</artifactId>
             <version>${project.version}</version>
             <type>war</type>
@@ -161,7 +162,7 @@
                                 <descriptor>file:${project.build.directory}/features.xml</descriptor>
                             </descriptors>
                             <features>
-                                <feature>axemblr-provisionr-all</feature>
+                                <feature>provisionr-all</feature>
                             </features>
                             <repository>target/features-repo</repository>
                         </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/karaf/features/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/karaf/features/src/main/resources/features.xml b/karaf/features/src/main/resources/features.xml
index c115966..ffe5670 100644
--- a/karaf/features/src/main/resources/features.xml
+++ b/karaf/features/src/main/resources/features.xml
@@ -16,63 +16,65 @@
   ~ limitations under the License.
   -->
 
-<features name="axemblr-provisionr-features-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
+<features name="provisionr-features-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
 
     <feature name="activiti-karaf-commands" version="${project.version}">
         <bundle dependency="true">mvn:com.google.code.gson/gson/${gson.version}</bundle>
-        <bundle start="true">mvn:org.activiti.karaf/activiti-karaf-commands/${project.version}</bundle>
+        <bundle start="true">
+            mvn:org.apache.provisionr/activiti-karaf-commands/${project.version}
+        </bundle>
     </feature>
 
     <feature name="activiti-karaf-web-explorer" version="${project.version}">
         <feature>war</feature>
         <feature>jpa</feature>
 
+        <feature>spring</feature>
+        <feature>spring-jdbc</feature>
+        <feature>spring-orm</feature>
+
+        <feature>spring-dm</feature>
+        <feature>spring-dm-web</feature>
+
         <bundle>mvn:commons-io/commons-io/2.0.1</bundle>
         <bundle>mvn:commons-fileupload/commons-fileupload/1.2.2</bundle>
         <bundle>mvn:org.codehaus.jackson/jackson-core-asl/1.4.3</bundle>
         <bundle>mvn:org.codehaus.jackson/jackson-mapper-asl/1.4.3</bundle>
 
-        <feature version="${spring.version}">spring</feature>
-        <feature version="${spring.version}">spring-jdbc</feature>
-        <feature version="${spring.version}">spring-orm</feature>
-
-        <feature version="${spring.osgi.version}">spring-dm</feature>
-        <feature version="${spring.osgi.version}">spring-dm-web</feature>
-
         <bundle start="true">mvn:com.vaadin/vaadin/${vaadin.version}</bundle>
         <bundle start="true">wrap:mvn:com.thebuzzmedia/imgscalr-lib/3.1</bundle>
-        <bundle start="true">mvn:org.activiti.karaf/activiti-karaf-web-explorer/${version}/war</bundle>
+        <bundle start="true">mvn:org.apache.provisionr/activiti-karaf-web-explorer/${version}/war</bundle>
     </feature>
 
     <repository>
-        mvn:com.axemblr.provisionr/provisionr-core/${project.version}/xml/features
+        mvn:org.apache.provisionr/provisionr-core/${project.version}/xml/features
     </repository>
     <repository>
-        mvn:com.axemblr.provisionr/provisionr-console/${project.version}/xml/features
+        mvn:org.apache.provisionr/provisionr-console/${project.version}/xml/features
     </repository>
     <repository>
-        mvn:com.axemblr.provisionr/provisionr-amazon/${project.version}/xml/features
+        mvn:org.apache.provisionr/provisionr-amazon/${project.version}/xml/features
     </repository>
     <repository>
-        mvn:com.axemblr.provisionr/provisionr-cloudstack/${project.version}/xml/features
+        mvn:org.apache.provisionr/provisionr-cloudstack/${project.version}/xml/features
     </repository>
     <repository>
-        mvn:com.axemblr.provisionr/provisionr-rundeck/${project.version}/xml/features
+        mvn:org.apache.provisionr/provisionr-rundeck/${project.version}/xml/features
     </repository>
 
-    <feature name="axemblr-provisionr-commands" version="${project.version}">
-        <bundle start="true">mvn:com.axemblr.provisionr/provisionr-commands/${project.version}</bundle>
+    <feature name="provisionr-commands" version="${project.version}">
+        <bundle start="true">mvn:org.apache.provisionr/provisionr-commands/${project.version}</bundle>
     </feature>
 
-    <feature name="axemblr-provisionr-all" version="${project.version}">
-        <feature version="${project.version}">axemblr-provisionr-core</feature>
-        <feature version="${project.version}">axemblr-provisionr-rundeck</feature>
+    <feature name="provisionr-all" version="${project.version}">
+        <feature version="${project.version}">provisionr-core</feature>
+        <feature version="${project.version}">provisionr-rundeck</feature>
 
-        <feature version="${project.version}">axemblr-provisionr-commands</feature>
-        <feature version="${project.version}">axemblr-provisionr-amazon</feature>
+        <feature version="${project.version}">provisionr-commands</feature>
+        <feature version="${project.version}">provisionr-amazon</feature>
 
-        <!--<feature version="${project.version}">axemblr-provisionr-console</feature>-->
-        <!--<feature version="${project.version}">axemblr-provisionr-cloudstack</feature>-->
+        <!--<feature version="${project.version}">provisionr-console</feature>-->
+        <!--<feature version="${project.version}">provisionr-cloudstack</feature>-->
 
         <feature version="${project.version}">activiti-karaf-commands</feature>
         <feature version="${project.version}">activiti-karaf-web-explorer</feature>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 933f7ba..497e928 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -15,19 +15,25 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>13</version>
+    </parent>
 
-    <groupId>com.axemblr.provisionr</groupId>
+    <groupId>org.apache.provisionr</groupId>
     <artifactId>provisionr-parent</artifactId>
     <version>0.4.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
-    <modelVersion>4.0.0</modelVersion>
-
-    <name>Axemblr Provisionr :: Parent</name>
+    <name>Apache Provisionr :: Parent</name>
     <description>Pool management service for 10s or 100s of virtual machines</description>
 
-    <url>https://github.com/axemblr/axemblr-provisionr</url>
+    <url>http://provisionr.incubator.apache.org/</url>
     <inceptionYear>2012</inceptionYear>
 
     <prerequisites>
@@ -36,30 +42,81 @@
 
     <developers>
         <developer>
+            <name>Tom White</name>
+            <email>tomwhite@apache.org</email>
+            <roles>
+                <role>mentor</role>
+            </roles>
+        </developer>
+        <developer>
+            <name>Mohammad Nour</name>
+            <email>mnour@apache.org</email>
+            <roles>
+                <role>mentor</role>
+            </roles>
+        </developer>
+        <developer>
+            <name>Roman Shaposhnik</name>
+            <email>rvs@apache.org</email>
+            <roles>
+                <role>mentor</role>
+                <role>committer</role>
+            </roles>
+        </developer>
+        <developer>
             <name>Andrei Savu</name>
-            <email>asavu@axemblr.com</email>
+            <email>asavu@apache.org</email>
+            <roles>
+                <role>committer</role>
+            </roles>
         </developer>
         <developer>
             <name>Ioan Eugen Stan</name>
-            <email>ieugen@axemblr.com</email>
+            <email>ieugen@apache.org</email>
+            <roles>
+                <role>committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <name>Alex Ciminian</name>
+            <email>cimi@apache.org</email>
+            <roles>
+                <role>committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <name>Amandeep Khurana</name>
+            <email>ak@apache.org</email>
+            <roles>
+                <role>committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <name>Eric Sammer</name>
+            <email>esammer@apache.org</email>
+            <roles>
+                <role>committer</role>
+            </roles>
         </developer>
     </developers>
 
     <organization>
-        <name>Axemblr Software Solutions</name>
-        <url>http://axemblr.com/</url>
+        <name>Apache Software Foundation</name>
+        <url>http://www.apache.org/</url>
     </organization>
 
     <scm>
-        <connection>scm:git:git@github.com:axemblr/axemblr-provisionr.git</connection>
-        <developerConnection>scm:git:git@github.com:axemblr/axemblr-provisionr.git</developerConnection>
-        <url>https://github.com/axemblr/axemblr-provisionr</url>
+        <connection>scm:git:https://git-wip-us.apache.org/repos/asf/incubator-provisionr.git</connection>
+        <developerConnection>
+            scm:git:https://git-wip-us.apache.org/repos/asf/incubator-provisionr.git
+        </developerConnection>
+        <url>https://git-wip-us.apache.org/repos/asf?p=incubator-provisionr.git</url>
         <tag>HEAD</tag>
     </scm>
 
     <issueManagement>
-        <system>github</system>
-        <url>https://github.com/axemblr/axemblr-provisionr/issues</url>
+        <system>jira</system>
+        <url>https://issues.apache.org/jira/browse/PROVISIONR</url>
     </issueManagement>
 
     <properties>
@@ -117,37 +174,37 @@
                 <version>${osgi.framework.version}</version>
             </dependency>
             <dependency>
-                <groupId>com.axemblr.provisionr</groupId>
+                <groupId>org.apache.provisionr</groupId>
                 <artifactId>provisionr-api</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-                <groupId>com.axemblr.provisionr</groupId>
+                <groupId>org.apache.provisionr</groupId>
                 <artifactId>provisionr-core</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-                <groupId>com.axemblr.provisionr</groupId>
+                <groupId>org.apache.provisionr</groupId>
                 <artifactId>provisionr-console</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-                <groupId>com.axemblr.provisionr</groupId>
+                <groupId>org.apache.provisionr</groupId>
                 <artifactId>provisionr-features</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-                <groupId>com.axemblr.provisionr</groupId>
+                <groupId>org.apache.provisionr</groupId>
                 <artifactId>provisionr-amazon</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-                <groupId>com.axemblr.provisionr</groupId>
+                <groupId>org.apache.provisionr</groupId>
                 <artifactId>provisionr-cloudstack</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-                <groupId>com.axemblr.provisionr</groupId>
+                <groupId>org.apache.provisionr</groupId>
                 <artifactId>provisionr-branding</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -202,7 +259,7 @@
                 <version>${h2.version}</version>
             </dependency>
             <dependency>
-                <groupId>com.axemblr.provisionr</groupId>
+                <groupId>org.apache.provisionr</groupId>
                 <artifactId>provisionr-test-support</artifactId>
                 <version>${project.version}</version>
                 <scope>test</scope>
@@ -262,19 +319,6 @@
         </repository>
     </repositories>
 
-    <distributionManagement>
-        <snapshotRepository>
-            <id>axemblr-snapshots</id>
-            <name>Axemblr Internal Snapshots</name>
-            <url>http://decebal.axemblr.com/nexus/content/repositories/snapshots</url>
-        </snapshotRepository>
-        <repository>
-            <id>axemblr-releases</id>
-            <name>Axemblr Internal Releases</name>
-            <url>http://decebal.axemblr.com/nexus/content/repositories/releases</url>
-        </repository>
-    </distributionManagement>
-
     <build>
         <plugins>
             <plugin>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 0367f8d..fdf2104 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,16 +15,17 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <parent>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <artifactId>provisionr-parent</artifactId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>./parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Aggregator</name>
+    <name>Apache Provisionr :: Aggregator</name>
     <artifactId>provisionr-aggregator</artifactId>
     <packaging>pom</packaging>
 

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon-tests/pom.xml
----------------------------------------------------------------------
diff --git a/providers/amazon-tests/pom.xml b/providers/amazon-tests/pom.xml
index e105d9e..f5940ec 100644
--- a/providers/amazon-tests/pom.xml
+++ b/providers/amazon-tests/pom.xml
@@ -15,25 +15,26 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: Amazon Integration Tests</name>
+    <name>Apache Provisionr :: Amazon Integration Tests</name>
     <artifactId>provisionr-amazon-tests</artifactId>
 
     <dependencies>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-amazon</artifactId>
         </dependency>
         <dependency>
@@ -41,11 +42,11 @@
             <artifactId>activiti-engine</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-features</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-test-support</artifactId>
         </dependency>
     </dependencies>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon-tests/src/test/java/com/axemblr/provisionr/amazon/AmazonProvisionrLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon-tests/src/test/java/com/axemblr/provisionr/amazon/AmazonProvisionrLiveTest.java b/providers/amazon-tests/src/test/java/com/axemblr/provisionr/amazon/AmazonProvisionrLiveTest.java
deleted file mode 100644
index 873c355..0000000
--- a/providers/amazon-tests/src/test/java/com/axemblr/provisionr/amazon/AmazonProvisionrLiveTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon;
-
-import com.axemblr.provisionr.amazon.options.ProviderOptions;
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Protocol;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.software.Software;
-import com.axemblr.provisionr.core.PoolStatus;
-import com.axemblr.provisionr.core.Ssh;
-import com.axemblr.provisionr.core.templates.PoolTemplate;
-import com.axemblr.provisionr.core.templates.xml.XmlTemplate;
-import static com.axemblr.provisionr.test.KarafTests.installProvisionrFeatures;
-import static com.axemblr.provisionr.test.KarafTests.installProvisionrTestSupportBundle;
-import static com.axemblr.provisionr.test.KarafTests.passThroughAllSystemPropertiesWithPrefix;
-import static com.axemblr.provisionr.test.KarafTests.useDefaultKarafAsInProjectWithJunitBundles;
-import com.axemblr.provisionr.test.ProvisionrLiveTestSupport;
-import com.google.common.base.Charsets;
-import com.google.common.io.Resources;
-import java.io.IOException;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import net.schmizz.sshj.SSHClient;
-import net.schmizz.sshj.connection.channel.direct.Session;
-import static org.junit.Assert.assertTrue;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.Configuration;
-import org.ops4j.pax.exam.junit.ExamReactorStrategy;
-import org.ops4j.pax.exam.junit.JUnit4TestRunner;
-import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@RunWith(JUnit4TestRunner.class)
-@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
-public class AmazonProvisionrLiveTest extends ProvisionrLiveTestSupport {
-
-    public static final Logger LOG = LoggerFactory.getLogger(AmazonProvisionrLiveTest.class);
-
-    public static final int TEST_POOL_SIZE = 2;
-
-    public static final String DEFAULT_JENKINS_TEMPLATE_PATH = "/com/axemblr/provisionr/core/templates/jenkins.xml";
-
-    public AmazonProvisionrLiveTest() {
-        super(AmazonProvisionr.ID);
-    }
-
-    @Configuration
-    public Option[] configuration() throws Exception {
-        return new Option[]{
-            useDefaultKarafAsInProjectWithJunitBundles(),
-            passThroughAllSystemPropertiesWithPrefix("test.amazon."),
-            installProvisionrFeatures("axemblr-provisionr-amazon"),
-            installProvisionrTestSupportBundle()
-        };
-    }
-
-    @Test
-    public void startProvisioningProcessForOnDemandInstances() throws Exception {
-        startProvisioningProcess(null);
-    }
-
-    @Test
-    public void startProvisioningProcessForSpotInstances() throws Exception {
-        startProvisioningProcess("0.04");
-    }
-
-    private void startProvisioningProcess(String spotBid) throws Exception {
-        waitForProcessDeployment(AmazonProvisionr.MANAGEMENT_PROCESS_KEY);
-
-        final Provisionr provisionr = getOsgiService(Provisionr.class, 5000);
-
-        Provider provider = collectProviderCredentialsFromSystemProperties()
-            .option(ProviderOptions.REGION, getProviderProperty(
-                ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION))
-            .createProvider();
-
-        if (spotBid != null) {
-            provider = provider.toBuilder()
-                    .option(ProviderOptions.SPOT_BID, spotBid)
-                    .createProvider();
-        }
-
-        final Network network = Network.builder().addRules(
-            Rule.builder().anySource().icmp().createRule(),
-            Rule.builder().anySource().port(22).protocol(Protocol.TCP).createRule()
-        ).createNetwork();
-
-        final Hardware hardware = Hardware.builder().type("t1.micro").createHardware();
-
-        final AdminAccess adminAccess = AdminAccess.builder().asCurrentUser().createAdminAccess();
-
-        final String destinationPath = "/home/" + adminAccess.getUsername() + "/axemblr.html";
-        final Software software = Software.builder()
-            .imageId("default")
-            .file("http://axemblr.com", destinationPath)
-            .createSoftware();
-
-        PoolTemplate jenkins = XmlTemplate.newXmlTemplate(Resources.toString(Resources
-            .getResource(PoolTemplate.class, DEFAULT_JENKINS_TEMPLATE_PATH), Charsets.UTF_8));
-
-        final Pool pool = jenkins.apply(Pool.builder()
-            .provider(provider)
-            .network(network)
-            .adminAccess(adminAccess)
-            .software(software)
-            .hardware(hardware)
-            .minSize(TEST_POOL_SIZE)
-            .expectedSize(TEST_POOL_SIZE)
-            .createPool());
-
-        final String businessKey = "j-" + UUID.randomUUID().toString();
-        String processInstanceId = provisionr.startPoolManagementProcess(businessKey, pool);
-
-        try {
-            waitForPoolStatus(provisionr, businessKey, PoolStatus.READY);
-
-            List<Machine> machines = provisionr.getMachines(businessKey);
-            assertTrue(machines.size() >= TEST_POOL_SIZE && machines.size() <= TEST_POOL_SIZE);
-
-            for (Machine machine : machines) {
-                assertSshCommand(machine, adminAccess, "test -f " + destinationPath);
-
-                /* These are added through the Jenkins Debian template */
-                assertSshCommand(machine, adminAccess, "hash git >/dev/null 2>&1");
-                assertSshCommand(machine, adminAccess, "hash java >/dev/null 2>&1");
-                assertSshCommand(machine, adminAccess, "test -f /etc/apt/sources.list.d/jenkins.list");
-            }
-        } finally {
-            provisionr.destroyPool(businessKey);
-
-            waitForPoolStatus(provisionr, businessKey, PoolStatus.TERMINATED);
-            waitForProcessEnd(processInstanceId);
-        }
-    }
-
-    private void assertSshCommand(Machine machine, AdminAccess adminAccess, String bashCommand) throws IOException {
-        LOG.info("Checking return code for command '{}' on machine {}", bashCommand, machine.getExternalId());
-        SSHClient client = Ssh.newClient(machine, adminAccess);
-        try {
-            Session session = client.startSession();
-            try {
-                session.allocateDefaultPTY();
-                Session.Command command = session.exec(bashCommand);
-
-                command.join();
-                assertTrue("Exit code was " + command.getExitStatus() + " for command " + bashCommand,
-                    command.getExitStatus() == 0);
-            } finally {
-                session.close();
-            }
-        } finally {
-            client.close();
-        }
-    }
-
-    private void waitForPoolStatus(Provisionr provisionr, String businessKey,
-                                   String expectedStatus) throws InterruptedException, TimeoutException {
-        for (int i = 0; i < 120; i++) {
-            String status;
-            try {
-                status = provisionr.getStatus(businessKey);
-
-            } catch (NoSuchElementException e) {
-                LOG.info(String.format("Pool management process not found with key %s. " +
-                    "Assuming process terminated as expected.", businessKey));
-                return;  /* The process ended as expected */
-            }
-
-            if (status.equals(expectedStatus)) {
-                LOG.info("Pool status is '{}'. Advancing.", status);
-                return;
-            } else {
-                LOG.info("Pool status is '{}'. Waiting 10s for '{}'. Try {}/120",
-                    new Object[]{status, expectedStatus, i});
-                TimeUnit.SECONDS.sleep(10);
-            }
-        }
-        throw new TimeoutException("Status check timed out after 20 minutes");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon-tests/src/test/java/org/apache/provisionr/amazon/AmazonProvisionrLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon-tests/src/test/java/org/apache/provisionr/amazon/AmazonProvisionrLiveTest.java b/providers/amazon-tests/src/test/java/org/apache/provisionr/amazon/AmazonProvisionrLiveTest.java
new file mode 100644
index 0000000..3ed0950
--- /dev/null
+++ b/providers/amazon-tests/src/test/java/org/apache/provisionr/amazon/AmazonProvisionrLiveTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.amazon;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Resources;
+import java.io.IOException;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.connection.channel.direct.Session;
+import org.apache.provisionr.amazon.options.ProviderOptions;
+import org.apache.provisionr.api.Provisionr;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Protocol;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.PoolStatus;
+import org.apache.provisionr.core.Ssh;
+import org.apache.provisionr.core.templates.PoolTemplate;
+import org.apache.provisionr.core.templates.xml.XmlTemplate;
+import static org.apache.provisionr.test.KarafTests.installProvisionrFeatures;
+import static org.apache.provisionr.test.KarafTests.installProvisionrTestSupportBundle;
+import static org.apache.provisionr.test.KarafTests.passThroughAllSystemPropertiesWithPrefix;
+import static org.apache.provisionr.test.KarafTests.useDefaultKarafAsInProjectWithJunitBundles;
+import org.apache.provisionr.test.ProvisionrLiveTestSupport;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.ExamReactorStrategy;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RunWith(JUnit4TestRunner.class)
+@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
+public class AmazonProvisionrLiveTest extends ProvisionrLiveTestSupport {
+
+    public static final Logger LOG = LoggerFactory.getLogger(AmazonProvisionrLiveTest.class);
+
+    public static final int TEST_POOL_SIZE = 2;
+
+    public static final String DEFAULT_JENKINS_TEMPLATE_PATH = "/org/apache/provisionr/core/templates/jenkins.xml";
+
+    public AmazonProvisionrLiveTest() {
+        super(AmazonProvisionr.ID);
+    }
+
+    @Configuration
+    public Option[] configuration() throws Exception {
+        return new Option[]{
+            useDefaultKarafAsInProjectWithJunitBundles(),
+            passThroughAllSystemPropertiesWithPrefix("test.amazon."),
+            installProvisionrFeatures("provisionr-amazon"),
+            installProvisionrTestSupportBundle()
+        };
+    }
+
+    @Test
+    public void startProvisioningProcessForOnDemandInstances() throws Exception {
+        startProvisioningProcess(null);
+    }
+
+    @Test
+    public void startProvisioningProcessForSpotInstances() throws Exception {
+        startProvisioningProcess("0.04");
+    }
+
+    private void startProvisioningProcess(String spotBid) throws Exception {
+        waitForProcessDeployment(AmazonProvisionr.MANAGEMENT_PROCESS_KEY);
+
+        final Provisionr provisionr = getOsgiService(Provisionr.class, 5000);
+
+        Provider provider = collectProviderCredentialsFromSystemProperties()
+            .option(ProviderOptions.REGION, getProviderProperty(
+                ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION))
+            .createProvider();
+
+        if (spotBid != null) {
+            provider = provider.toBuilder()
+                .option(ProviderOptions.SPOT_BID, spotBid)
+                .createProvider();
+        }
+
+        final Network network = Network.builder().addRules(
+            Rule.builder().anySource().icmp().createRule(),
+            Rule.builder().anySource().port(22).protocol(Protocol.TCP).createRule()
+        ).createNetwork();
+
+        final Hardware hardware = Hardware.builder().type("t1.micro").createHardware();
+
+        final AdminAccess adminAccess = AdminAccess.builder().asCurrentUser().createAdminAccess();
+
+        final String destinationPath = "/home/" + adminAccess.getUsername() + "/provisionr.html";
+        final Software software = Software.builder()
+            .imageId("default")
+            .file("http://provisionr.incubator.apache.org", destinationPath)
+            .createSoftware();
+
+        PoolTemplate jenkins = XmlTemplate.newXmlTemplate(Resources.toString(Resources
+            .getResource(PoolTemplate.class, DEFAULT_JENKINS_TEMPLATE_PATH), Charsets.UTF_8));
+
+        final Pool pool = jenkins.apply(Pool.builder()
+            .provider(provider)
+            .network(network)
+            .adminAccess(adminAccess)
+            .software(software)
+            .hardware(hardware)
+            .minSize(TEST_POOL_SIZE)
+            .expectedSize(TEST_POOL_SIZE)
+            .createPool());
+
+        final String businessKey = "j-" + UUID.randomUUID().toString();
+        String processInstanceId = provisionr.startPoolManagementProcess(businessKey, pool);
+
+        try {
+            waitForPoolStatus(provisionr, businessKey, PoolStatus.READY);
+
+            List<Machine> machines = provisionr.getMachines(businessKey);
+            assertTrue(machines.size() >= TEST_POOL_SIZE && machines.size() <= TEST_POOL_SIZE);
+
+            for (Machine machine : machines) {
+                assertSshCommand(machine, adminAccess, "test -f " + destinationPath);
+
+                /* These are added through the Jenkins Debian template */
+                assertSshCommand(machine, adminAccess, "hash git >/dev/null 2>&1");
+                assertSshCommand(machine, adminAccess, "hash java >/dev/null 2>&1");
+                assertSshCommand(machine, adminAccess, "test -f /etc/apt/sources.list.d/jenkins.list");
+            }
+        } finally {
+            provisionr.destroyPool(businessKey);
+
+            waitForPoolStatus(provisionr, businessKey, PoolStatus.TERMINATED);
+            waitForProcessEnd(processInstanceId);
+        }
+    }
+
+    private void assertSshCommand(Machine machine, AdminAccess adminAccess, String bashCommand) throws IOException {
+        LOG.info("Checking return code for command '{}' on machine {}", bashCommand, machine.getExternalId());
+        SSHClient client = Ssh.newClient(machine, adminAccess);
+        try {
+            Session session = client.startSession();
+            try {
+                session.allocateDefaultPTY();
+                Session.Command command = session.exec(bashCommand);
+
+                command.join();
+                assertTrue("Exit code was " + command.getExitStatus() + " for command " + bashCommand,
+                    command.getExitStatus() == 0);
+            } finally {
+                session.close();
+            }
+        } finally {
+            client.close();
+        }
+    }
+
+    private void waitForPoolStatus(Provisionr provisionr, String businessKey,
+                                   String expectedStatus) throws InterruptedException, TimeoutException {
+        for (int i = 0; i < 120; i++) {
+            String status;
+            try {
+                status = provisionr.getStatus(businessKey);
+
+            } catch (NoSuchElementException e) {
+                LOG.info(String.format("Pool management process not found with key %s. " +
+                    "Assuming process terminated as expected.", businessKey));
+                return;  /* The process ended as expected */
+            }
+
+            if (status.equals(expectedStatus)) {
+                LOG.info("Pool status is '{}'. Advancing.", status);
+                return;
+            } else {
+                LOG.info("Pool status is '{}'. Waiting 10s for '{}'. Try {}/120",
+                    new Object[]{status, expectedStatus, i});
+                TimeUnit.SECONDS.sleep(10);
+            }
+        }
+        throw new TimeoutException("Status check timed out after 20 minutes");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/pom.xml
----------------------------------------------------------------------
diff --git a/providers/amazon/pom.xml b/providers/amazon/pom.xml
index b15fe96..b1a9285 100644
--- a/providers/amazon/pom.xml
+++ b/providers/amazon/pom.xml
@@ -14,16 +14,17 @@
   ~ 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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <artifactId>provisionr-parent</artifactId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
 
-    <name>Axemblr Provisionr :: Amazon</name>
+    <name>Apache Provisionr :: Amazon</name>
     <artifactId>provisionr-amazon</artifactId>
     <packaging>bundle</packaging>
 
@@ -33,11 +34,11 @@
             <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-core</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
@@ -54,7 +55,7 @@
             <version>${aws.sdk.version}</version>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-test-support</artifactId>
             <scope>test</scope>
             <exclusions>
@@ -161,7 +162,7 @@
                                     <classifier>features</classifier>
                                 </artifact>
                                 <artifact>
-                                    <file>${project.build.directory}/classes/com.axemblr.provisionr.amazon.cfg</file>
+                                    <file>${project.build.directory}/classes/org.apache.provisionr.amazon.cfg</file>
                                     <type>cfg</type>
                                     <classifier>defaults</classifier>
                                 </artifact>
@@ -187,7 +188,7 @@
                                 <descriptor>file:${project.build.directory}/classes/features.xml</descriptor>
                             </descriptors>
                             <features>
-                                <feature>axemblr-provisionr-amazon</feature>
+                                <feature>provisionr-amazon</feature>
                             </features>
                             <repository>target/features-repo</repository>
                         </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/AmazonProvisionr.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/AmazonProvisionr.java b/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/AmazonProvisionr.java
deleted file mode 100644
index 4255df5..0000000
--- a/providers/amazon/src/main/java/com/axemblr/provisionr/amazon/AmazonProvisionr.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.amazon;
-
-import com.axemblr.provisionr.amazon.config.DefaultProviderConfig;
-import com.axemblr.provisionr.amazon.options.ProviderOptions;
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.core.CoreConstants;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.axemblr.provisionr.core.CoreSignals;
-import com.axemblr.provisionr.core.PoolStatus;
-import com.axemblr.provisionr.core.ProvisionrSupport;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Maps;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AmazonProvisionr extends ProvisionrSupport {
-
-    public static final Logger LOG = LoggerFactory.getLogger(AmazonProvisionr.class);
-
-    public static final String ID = "amazon";
-    public static final String MANAGEMENT_PROCESS_KEY = "amazonPoolManagement";
-
-    private final ProcessEngine processEngine;
-    private final Optional<Provider> defaultProvider;
-
-    public AmazonProvisionr(ProcessEngine processEngine, DefaultProviderConfig defaultProviderConfig) {
-        this.processEngine = checkNotNull(processEngine, "processEngine is null");
-        this.defaultProvider = defaultProviderConfig.createProvider();
-
-        if (defaultProvider.isPresent()) {
-            LOG.info("Default provider for AmazonProvisionr is {}", defaultProvider.get());
-        } else {
-            LOG.info("No default provider configured for AmazonProvisionr");
-        }
-    }
-
-    @Override
-    public String getId() {
-        return ID;
-    }
-
-    @Override
-    public Optional<Provider> getDefaultProvider() {
-        return defaultProvider;
-    }
-
-    @Override
-    public String startPoolManagementProcess(String businessKey, Pool pool) {
-        Map<String, Object> arguments = Maps.newHashMap();
-
-        arguments.put(CoreProcessVariables.POOL, pool);
-        arguments.put(CoreProcessVariables.PROVIDER, getId());
-        arguments.put(CoreProcessVariables.POOL_BUSINESS_KEY, businessKey);
-        arguments.put(CoreProcessVariables.BOOTSTRAP_TIMEOUT, 
-                convertTimeoutToISO8601TimeDuration(pool.getBootstrapTimeInSeconds()));
-        arguments.put(CoreProcessVariables.IS_CACHED_IMAGE, pool.getSoftware().isCachedImage());
-
-        /* needed because the Activiti EL doesn't work as expected and properties can't be read from the pool. */
-        arguments.put(ProcessVariables.SPOT_BID, pool.getProvider().getOption(ProviderOptions.SPOT_BID));
-
-        /* Authenticate as kermit to make the process visible in the Explorer UI */
-        processEngine.getIdentityService().setAuthenticatedUserId(CoreConstants.ACTIVITI_EXPLORER_DEFAULT_USER);
-
-        ProcessInstance instance = processEngine.getRuntimeService()
-            .startProcessInstanceByKey(MANAGEMENT_PROCESS_KEY, businessKey, arguments);
-
-        return instance.getProcessInstanceId();
-    }
-
-    @Override
-    public List<Machine> getMachines(String businessKey) {
-        ProcessInstance instance = processEngine.getRuntimeService().createProcessInstanceQuery()
-            .processInstanceBusinessKey(businessKey).singleResult();
-        if (instance == null) {
-            throw new NoSuchElementException("No active pool found with key: " + businessKey);
-        }
-
-        @SuppressWarnings("unchecked") List<Machine> machines = (List<Machine>) processEngine.getRuntimeService()
-            .getVariable(instance.getId(), CoreProcessVariables.MACHINES);
-
-        return Optional.fromNullable(machines).or(Collections.<Machine>emptyList());
-    }
-
-    @Override
-    public String getStatus(String businessKey) {
-        ProcessInstance instance = processEngine.getRuntimeService().createProcessInstanceQuery()
-            .processInstanceBusinessKey(businessKey).singleResult();
-        if (instance == null) {
-            throw new NoSuchElementException("No active pool found with key: " + businessKey);
-        }
-
-        String status = (String) processEngine.getRuntimeService().getVariable(instance.getId(),
-            CoreProcessVariables.STATUS);
-
-        return Optional.fromNullable(status).or(PoolStatus.UNDEFINED);
-    }
-
-    @Override
-    public void destroyPool(String businessKey) {
-        triggerSignalEvent(processEngine, businessKey, CoreSignals.TERMINATE_POOL);
-    }
-}


[19/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr

Posted by as...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/AbstractActivitiPrintHandler.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/AbstractActivitiPrintHandler.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/AbstractActivitiPrintHandler.java
new file mode 100644
index 0000000..be0cb85
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/AbstractActivitiPrintHandler.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands.handlers;
+
+import java.io.PrintWriter;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.activiti.engine.ActivitiException;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.history.HistoricDetail;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.history.HistoricVariableUpdate;
+import org.apache.provisionr.activiti.karaf.commands.util.Commands;
+
+/**
+ * Abstract class that provides most of the implementation required to print process variable using
+ * print handler.
+ *
+ * @author Srinivasan Chikkala
+ * @see DefaultActivitiPrintHandler
+ */
+public abstract class AbstractActivitiPrintHandler implements ActivitiPrintHandler {
+
+    public static final String PROCESS_DEFINITION_PROP = "bpm.process.definition";
+    public static final String PROCESS_VARS_PROP = "bpm.process.variables";
+
+    private static final Logger LOG = Logger.getLogger(AbstractActivitiPrintHandler.class.getName());
+
+    private boolean verbose;
+    private boolean quiet;
+    private ProcessEngine processEngine;
+
+    public boolean isQuiet() {
+        return quiet;
+    }
+
+    public void setQuiet(boolean quiet) {
+        this.quiet = quiet;
+    }
+
+    public boolean isVerbose() {
+        return verbose;
+    }
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+
+    public ProcessEngine getProcessEngine() {
+        return processEngine;
+    }
+
+    public void setProcessEngine(ProcessEngine processEngine) {
+        this.processEngine = processEngine;
+    }
+
+    /**
+     * Extended class can implement this method to print the variable specific information.
+     */
+    protected abstract void printVariable(PrintWriter out, String varName, Object varValue);
+
+    protected void printVariable(PrintWriter out, HistoricVariableUpdate var) {
+
+        LinkedHashMap<String, String> nvMap = new LinkedHashMap<String, String>();
+        // nvMap.put("Variable Type", var.getVariableTypeName());
+        if (this.isVerbose()) {
+            nvMap.put("Variable ID", var.getId());
+            nvMap.put("Revision", "" + var.getRevision());
+            nvMap.put("Updated Time", Commands.UTIL.formatDate(var.getTime()));
+        }
+        nvMap.put("Variable Name", var.getVariableName());
+        Object value = var.getValue();
+        String simpleValue = Commands.UTIL.valueOf(value);
+        if (simpleValue != null) {
+            nvMap.put("Value", simpleValue);
+        } else {
+            nvMap.put("Value", "");
+        }
+        Commands.UTIL.printNameValues(out, nvMap);
+
+        if (simpleValue == null) {
+            // print the value in a json serialization format.
+            printVariable(out, var.getVariableName(), value);
+        }
+        out.println();
+    }
+
+    protected void printVariables(PrintWriter out, Map<String, HistoricVariableUpdate> vars) {
+        for (HistoricVariableUpdate var : vars.values()) {
+            printVariable(out, var);
+        }
+    }
+
+    protected void printVariables(PrintWriter out, List<HistoricDetail> varList) {
+        Map<String, HistoricVariableUpdate> varMap = new TreeMap<String, HistoricVariableUpdate>();
+        // filter revisions
+        for (HistoricDetail detail : varList) {
+            HistoricVariableUpdate varDetail = (HistoricVariableUpdate) detail;
+            String varName = varDetail.getVariableName();
+            // expects the varList is sorted in a descending order of time.
+            if (!varMap.containsKey(varName)) {
+                varMap.put(varName, varDetail);
+            } else {
+                LOG.info("#### " + varName + " has multiple updates!!! "
+                    + Commands.UTIL.formatDate(varDetail.getTime()) + " Revision= "
+                    + varDetail.getRevision());
+            }
+        }
+        printVariables(out, varMap);
+    }
+
+    @Override
+    public void printInstanceData(PrintWriter out, boolean verbose, boolean quite, HistoricProcessInstance hpi) {
+        this.setVerbose(verbose);
+        this.setQuiet(quite);
+
+        List<HistoricDetail> varList = null;
+        try {
+            varList = this.processEngine.getHistoryService().createHistoricDetailQuery()
+                .variableUpdates().processInstanceId(hpi.getId()).orderByTime().desc().list();
+        } catch (ActivitiException ex) {
+            // silent about the error. and log it.
+            LOG.log(Level.INFO, "Error in getting process variables. " + ex.getMessage(), ex);
+        }
+        if (varList != null && varList.size() > 0) {
+            out.println("-------- Instance Variables ");
+            printVariables(out, varList);
+        } else {
+            LOG.info("------ No Instance Variables! for " + hpi.getId());
+        }
+    }
+
+    @Override
+    public void printActivityData(PrintWriter out, boolean verbose, boolean quite,
+                                  HistoricActivityInstance actInst) {
+        this.setVerbose(verbose);
+        this.setQuiet(quite);
+        if (quite) {
+            // don't print activity variable update per activity
+            return;
+        }
+        List<HistoricDetail> varList = null;
+        try {
+            varList = this.processEngine.getHistoryService().createHistoricDetailQuery()
+                .variableUpdates().activityInstanceId(actInst.getId()).orderByTime().desc().list();
+        } catch (ActivitiException ex) {
+            //silent about the error. and log it.
+            LOG.log(Level.INFO, "Error in getting process variables. " + ex.getMessage(), ex);
+        }
+
+        if (varList != null && varList.size() > 0) {
+            out.println("-------- Task Variables");
+            printVariables(out, varList);
+        } else {
+            LOG.info("------ No Task Variables! for " + actInst.getActivityId());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/ActivitiPrintHandler.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/ActivitiPrintHandler.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/ActivitiPrintHandler.java
new file mode 100644
index 0000000..c395693
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/ActivitiPrintHandler.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands.handlers;
+
+import java.io.PrintWriter;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.history.HistoricProcessInstance;
+
+/**
+ * Service interface whose implementations can handle process variables printing as part of bpm:info cmd.
+ * service providers can register implementation of this interface as a OSGi service which the bpm:info cmd
+ * can lookup and use to print a bpmn process specific variable information.
+ * <p/>
+ * Each OSGi service registered can have the following set of properties
+ * process-definition=<process-definition-id> - which handles all process instances variable printing for this
+ * process definition.
+ * process-var-name=<name-of-the-var> - which handles all process instances that contains this variable name
+ * useful when you want to handles any process definitions that contains this variable.
+ *
+ * @author Srinivasan Chikkala
+ */
+public interface ActivitiPrintHandler {
+
+    /**
+     * Print instance level Activiti process variable data
+     */
+    void printInstanceData(PrintWriter out, boolean verbose, boolean quiet, HistoricProcessInstance hpi);
+
+    /**
+     * Print activity level Activiti process variable data
+     */
+    void printActivityData(PrintWriter out, boolean verbose, boolean quiet, HistoricActivityInstance actInst);
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/DefaultActivitiPrintHandler.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/DefaultActivitiPrintHandler.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/DefaultActivitiPrintHandler.java
new file mode 100644
index 0000000..67a1f5d
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/handlers/DefaultActivitiPrintHandler.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands.handlers;
+
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.lang.reflect.Modifier;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.provisionr.activiti.karaf.commands.util.Commands;
+
+/**
+ * Default implementation of the process variable print handler.
+ *
+ * @author Srinivasan Chikkala
+ */
+public class DefaultActivitiPrintHandler extends AbstractActivitiPrintHandler {
+
+    private static final Logger LOG = Logger.getLogger(DefaultActivitiPrintHandler.class.getName());
+
+    protected void printVariable(PrintWriter out, String varName, Object varValue) {
+        Gson gson = new GsonBuilder()
+            .setPrettyPrinting()
+            .serializeNulls()
+            .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
+            .create();
+
+        LOG.info("Printing var " + varName);
+        String jsonText = null;
+        try {
+            jsonText = gson.toJson(varValue);
+        } catch (Exception ex) {
+            jsonText = "{\n  " + varValue + "\n}"; // use default toString object            
+            LOG.log(Level.SEVERE, "Serializing Activiti Variable. " + ex.getMessage(), ex);
+        }
+
+        Commands.UTIL.printText(out, new StringReader(jsonText), " ");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/util/Commands.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/util/Commands.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/util/Commands.java
new file mode 100644
index 0000000..f3edd30
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/util/Commands.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.TimeZone;
+
+/**
+ * This class provides common utils for commands processing
+ *
+ * @author Srinivasan Chikkala
+ */
+public class Commands {
+
+    public static final Commands UTIL = new Commands();
+
+    public void printNameValues(PrintWriter out, Map<String, String> nvMap) {
+        String fmt = "  %-16.16s %-20.60s\n";
+        for (String key : nvMap.keySet()) {
+            String value = nvMap.get(key);
+            out.printf(fmt, key + ":", value);
+        }
+    }
+
+    public String formatDate(Date date) {
+        String dateTxt = "--";
+        if (date != null) {
+            dateTxt = DateFormat.getDateTimeInstance().format(date);
+        }
+        return dateTxt;
+    }
+
+    public String formatDuration(Long duration) {
+        String dTxt = "--";
+        if (duration != null) {
+            SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss:SSS");
+            format.setTimeZone(TimeZone.getTimeZone("GMT"));
+            dTxt = format.format(new Date(duration));
+        }
+        return dTxt;
+    }
+
+    public void printText(PrintWriter out, Reader txtReader, String tabSpace) {
+        BufferedReader in = new BufferedReader(txtReader);
+        String line = null;
+        try {
+            while ((line = in.readLine()) != null) {
+                out.printf("  %-16.16s %s\n", tabSpace, line);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Convert a simple object to string.
+     *
+     * @param obj object .
+     * @return string if the object is simple. else return null.
+     */
+    public String valueOf(Object obj) {
+        String value = null;
+        if (obj == null) {
+            value = "NULL";
+        } else if (obj.getClass().isPrimitive()
+            || obj.getClass().isEnum()
+            || obj instanceof java.lang.String) {
+            value = obj.toString();
+        } else if (obj instanceof Date) {
+            value = formatDate((Date) obj);
+        } else {
+            value = null;
+        }
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/util/TextTable.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/util/TextTable.java b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/util/TextTable.java
new file mode 100644
index 0000000..24c3831
--- /dev/null
+++ b/activiti/commands/src/main/java/org/apache/provisionr/activiti/karaf/commands/util/TextTable.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+package org.apache.provisionr.activiti.karaf.commands.util;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+public class TextTable {
+
+    private static final int DEFAULT_WIDTH = 3;
+    private int col;
+
+    private List<String> columnHeaders;
+    private List<Integer> columnWidths;
+    private List<List<String>> rows;
+
+    public TextTable(int col) {
+        this.col = col;
+        this.columnHeaders = new ArrayList<String>();
+        this.columnWidths = new ArrayList<Integer>();
+        this.rows = new ArrayList<List<String>>();
+    }
+
+    public void addHeaders(String... headers) {
+        for (String header : headers) {
+            this.columnHeaders.add(header);
+            this.columnWidths.add(DEFAULT_WIDTH);
+        }
+    }
+
+    public void addRow(String... colValues) {
+        List<String> row = new ArrayList<String>();
+        rows.add(row);
+        if (colValues != null && colValues.length > this.col) {
+            throw new IllegalArgumentException("Number of Column values passed are more than the tables " +
+                "column cound " + this.col);
+        }
+        for (int i = 0; i < this.col; ++i) {
+            String colValue = "";
+            if ((i < colValues.length) && (colValues[i] != null)) {
+                colValue = colValues[i];
+                Integer colWidth = this.columnWidths.get(i);
+                if (colWidth < colValue.length()) {
+                    this.columnWidths.set(i, colValue.length());
+                }
+            }
+            row.add(colValue);
+        }
+    }
+
+    public void print(PrintStream stremaOut) {
+        PrintWriter out = new PrintWriter(stremaOut, true);
+        print(out);
+    }
+
+    public void print(PrintWriter out) {
+        StringBuilder hdrFmtBuff = new StringBuilder();
+        StringBuilder rowFmtBuff = new StringBuilder();
+        // " %-20.20s   %-20.20s [%-20.20s]\n";
+        // "[%-20.20s] [%-20.20s] [%-20.20s]\n";
+        for (Integer width : this.columnWidths) {
+            hdrFmtBuff.append(" %-").append(width).append(".").append(width).append("s ");
+            rowFmtBuff.append("[%-").append(width).append(".").append(width).append("s]");
+        }
+        hdrFmtBuff.append("\n");
+        rowFmtBuff.append("\n");
+        String hdrFmt = hdrFmtBuff.toString();
+        String rowFmt = rowFmtBuff.toString();
+
+        out.printf(hdrFmt, this.columnHeaders.toArray());
+        for (List<String> row : this.rows) {
+            out.printf(rowFmt, row.toArray());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/main/resources/OSGI-INF/blueprint/bpm-commands.xml
----------------------------------------------------------------------
diff --git a/activiti/commands/src/main/resources/OSGI-INF/blueprint/bpm-commands.xml b/activiti/commands/src/main/resources/OSGI-INF/blueprint/bpm-commands.xml
index 67aa83a..0661bb3 100644
--- a/activiti/commands/src/main/resources/OSGI-INF/blueprint/bpm-commands.xml
+++ b/activiti/commands/src/main/resources/OSGI-INF/blueprint/bpm-commands.xml
@@ -22,67 +22,67 @@
            xmlns:cfg="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0">
     <shell:command-bundle>
         <shell:command name="activiti/list">
-            <shell:action class="org.activiti.karaf.commands.ListActivitiCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.ListActivitiCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/start">
-            <shell:action class="org.activiti.karaf.commands.StartActivitiCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.StartActivitiCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/kill">
-            <shell:action class="org.activiti.karaf.commands.KillActivitiCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.KillActivitiCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/signal">
-            <shell:action class="org.activiti.karaf.commands.SignalActivitiCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.SignalActivitiCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/undeploy">
-            <shell:action class="org.activiti.karaf.commands.UndeployActivitiCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.UndeployActivitiCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/clean-history">
-            <shell:action class="org.activiti.karaf.commands.CleanHistoryActivitiCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.CleanHistoryActivitiCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/info">
-            <shell:action class="org.activiti.karaf.commands.InfoActivitiCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.InfoActivitiCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/add-user">
-            <shell:action class="org.activiti.karaf.commands.AddUserCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.AddUserCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/delete-user">
-            <shell:action class="org.activiti.karaf.commands.DeleteUserCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.DeleteUserCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/add-group">
-            <shell:action class="org.activiti.karaf.commands.AddGroupCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.AddGroupCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/delete-group">
-            <shell:action class="org.activiti.karaf.commands.DeleteGroupCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.DeleteGroupCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/list-groups">
-            <shell:action class="org.activiti.karaf.commands.ListGroupsCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.ListGroupsCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>
         <shell:command name="activiti/list-users">
-            <shell:action class="org.activiti.karaf.commands.ListUsersCommand">
+            <shell:action class="org.apache.provisionr.activiti.karaf.commands.ListUsersCommand">
                 <shell:property name="processEngine" ref="processEngineRef"/>
             </shell:action>
         </shell:command>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/test/java/org/activiti/karaf/commands/ActivitiCommandTest.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/test/java/org/activiti/karaf/commands/ActivitiCommandTest.java b/activiti/commands/src/test/java/org/activiti/karaf/commands/ActivitiCommandTest.java
deleted file mode 100644
index 02f323a..0000000
--- a/activiti/commands/src/test/java/org/activiti/karaf/commands/ActivitiCommandTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-import org.activiti.karaf.commands.util.TextTable;
-import org.junit.After;
-import static org.junit.Assert.assertEquals;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * @author Srinivasan Chikkala
- */
-public class ActivitiCommandTest {
-
-    private ByteArrayOutputStream backingStream;
-    private PrintWriter out;
-
-    @Before
-    public void setUp() {
-        backingStream = new ByteArrayOutputStream();
-        out = new PrintWriter(backingStream);
-    }
-
-    @After
-    public void tearDown() {
-        out.close();
-        backingStream.reset();
-    }
-
-    public String collectOutput() {
-        out.flush();
-        return backingStream.toString();
-    }
-
-    @Test
-    public void testTextTable1() {
-        String[] headers = {"col1", "column2", "c3"};
-        String[] row1 = {"myvalue111111111111111x", "myvalue2", "myvalue3"};
-        String[] row2 = {"myvalue1", "myvalue2", "myvalue3"};
-        String[] row3 = {"myvalue1", "myvalue2", "myvalue3"};
-
-        final String expectedOutput = " col1                     column2   c3       \n" +
-            "[myvalue111111111111111x][myvalue2][myvalue3]\n" +
-            "[myvalue1               ][myvalue2][myvalue3]\n" +
-            "[myvalue1               ][myvalue2][myvalue3]\n";
-
-        TextTable table = new TextTable(3);
-        table.addHeaders(headers);
-        table.addRow(row1);
-        table.addRow(row2);
-        table.addRow(row3);
-
-        table.print(out);
-        assertEquals(collectOutput(), expectedOutput);
-    }
-
-    @Test
-    public void testTextTable2() {
-        String[] headers = {"col1", "column2", "c3"};
-        String[] row1 = {"myvalue1", "myvalue2", "myvalue3"};
-        String[] row2 = {"myvalue111111111111111111111111111111x", "myvalue2", "myvalue3"};
-        String[] row3 = {"myvalue1", "myvalue2", "myvalue33333333333333333333x"};
-
-        final String expectedOutput = " col1                                    column2   c3                           \n" +
-            "[myvalue1                              ][myvalue2][myvalue3                    ]\n" +
-            "[myvalue111111111111111111111111111111x][myvalue2][myvalue3                    ]\n" +
-            "[myvalue1                              ][myvalue2][myvalue33333333333333333333x]\n";
-
-        TextTable table = new TextTable(3);
-        table.addHeaders(headers);
-        table.addRow(row1);
-        table.addRow(row2);
-        table.addRow(row3);
-
-        table.print(out);
-        assertEquals(collectOutput(), expectedOutput);
-    }
-
-    @Test
-    public void testTextTable3() {
-        String[] headers = {"col1", "column2", "c3"};
-        String[] row1 = {"myvalue1", "myvalue2", "myvalue3ddddddddddddddddddx"};
-        String[] row2 = {"myvalue1", "myvalue2", "myvalue3"};
-        String[] row3 = {"myvalue11111111111111111111111x", "myvalue2", "myvalue3"};
-
-        final String expectedOutput = " col1                             column2   c3                          \n" +
-            "[myvalue1                       ][myvalue2][myvalue3ddddddddddddddddddx]\n" +
-            "[myvalue1                       ][myvalue2][myvalue3                   ]\n" +
-            "[myvalue11111111111111111111111x][myvalue2][myvalue3                   ]\n";
-
-        TextTable table = new TextTable(3);
-        table.addHeaders(headers);
-        table.addRow(row1);
-        table.addRow(row2);
-        table.addRow(row3);
-
-        table.print(out);
-        assertEquals(collectOutput(), expectedOutput);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/test/java/org/activiti/karaf/commands/ActivitiTestCase.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/test/java/org/activiti/karaf/commands/ActivitiTestCase.java b/activiti/commands/src/test/java/org/activiti/karaf/commands/ActivitiTestCase.java
deleted file mode 100644
index 2a2f80e..0000000
--- a/activiti/commands/src/test/java/org/activiti/karaf/commands/ActivitiTestCase.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.TaskService;
-import org.activiti.engine.history.HistoricProcessInstance;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.engine.test.ActivitiRule;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-/**
- * @author Srinivasan Chikkala
- */
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration("classpath:activiti.cfg.xml")
-public abstract class ActivitiTestCase {
-
-    private static final Logger LOG = Logger.getLogger(ActivitiTestCase.class.getName());
-
-    @Autowired
-    private ProcessEngine processEngine;
-
-    @Autowired
-    private RuntimeService runtimeService;
-
-    @Autowired
-    private TaskService taskService;
-
-    @Autowired
-    @Rule
-    public ActivitiRule activitiSpringRule;
-
-    private ByteArrayOutputStream outputStream;
-    private PrintWriter out;
-
-    private ByteArrayOutputStream errStream;
-    private PrintWriter err;
-
-    @Before
-    public void setUp() {
-        outputStream = new ByteArrayOutputStream();
-        out = new PrintWriter(outputStream);
-
-        errStream = new ByteArrayOutputStream();
-        err = new PrintWriter(errStream);
-    }
-
-    @After
-    public void tearDown() throws IOException {
-        processEngine.close();
-
-        out.close();
-        outputStream.close();
-
-        err.close();
-        errStream.close();
-    }
-
-    public PrintWriter getOut() {
-        return out;
-    }
-
-    public PrintWriter getErr() {
-        return err;
-    }
-
-    public String collectStdOutput() throws IOException {
-        out.flush();
-        outputStream.flush();
-
-        return outputStream.toString();
-    }
-
-    public String collectErrOutput() throws IOException {
-        err.flush();
-        errStream.flush();
-
-        return errStream.toString();
-    }
-
-    protected ProcessEngine getProcessEngine() {
-        return this.processEngine;
-    }
-
-    protected ProcessInstance startProcess(String processKey) throws Exception {
-        return startProcess(processKey, new HashMap<String, Object>());
-    }
-
-    protected ProcessInstance startProcess(String processKey, Map<String, Object> variables) throws Exception {
-        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey, variables);
-        String processInstanceId = processInstance.getId();
-
-        LOG.info("Started process instance id " + processInstanceId);
-        runtimeService.createProcessInstanceQuery().count();
-
-        HistoricProcessInstance historicProcessInstance = processEngine
-            .getHistoryService().createHistoricProcessInstanceQuery()
-            .processInstanceId(processInstanceId).singleResult();
-
-        if (historicProcessInstance != null) {
-            LOG.info("Finished " + processKey + "Instance. took "
-                + historicProcessInstance.getDurationInMillis() + " millis");
-        }
-        return processInstance;
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/test/java/org/activiti/karaf/commands/InfoActivitiCommandTest.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/test/java/org/activiti/karaf/commands/InfoActivitiCommandTest.java b/activiti/commands/src/test/java/org/activiti/karaf/commands/InfoActivitiCommandTest.java
deleted file mode 100644
index abf57bb..0000000
--- a/activiti/commands/src/test/java/org/activiti/karaf/commands/InfoActivitiCommandTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.TreeMap;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.engine.test.Deployment;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-/**
- * @author Srinivasan Chikkala
- */
-public class InfoActivitiCommandTest extends ActivitiTestCase {
-
-    @Test
-    @Deployment(resources = {"diagrams/test-bpm-1.bpmn20.xml", "diagrams/test-bpm-2.bpmn20.xml",
-        "diagrams/test-bpm-3.bpmn20.xml"})
-    public void testListBPMCommand1() throws Exception {
-        String processKey = "Test-bpm-1";
-
-        Map<String, Object> variables = new TreeMap<String, Object>();
-        variables.put("myfoo", new Foo());
-        variables.put("mybar", new Bar());
-        variables.put("my.array", new Object[]{new Foo(), new Bar()});
-
-        ProcessInstance processInstance = this.startProcess(processKey, variables);
-
-        InfoActivitiCommand command = new InfoActivitiCommand();
-        command.setProcessEngine(this.getProcessEngine());
-        command.setInstanceID(processInstance.getId());
-        command.setOut(getOut());
-        command.setErr(getErr());
-
-        command.doExecute();
-
-        assertThat(collectStdOutput())
-            .contains("Instance ID:")
-            .contains("Start Activity:  startevent1")
-            .contains("End Activity:    endevent1")
-            .contains("Variable Name:   my.array")
-            .contains("\"mybar\": \"bar3\"")
-            .contains("Variable Name:   mybar")
-            .contains(" Variable Name:   myfoo");
-    }
-
-    public static class Foo implements Serializable {
-
-        private static final long serialVersionUID = 1L;
-        private String myfoo = "foo2";
-        private boolean yes;
-        private String[] users = {"foo1", "foo2", "foo3"};
-        private Bar fooBar = new Bar();
-
-        public Bar getFooBar() {
-            return fooBar;
-        }
-
-        public void setFooBar(Bar fooBar) {
-            this.fooBar = fooBar;
-        }
-
-        public String getMyfoo() {
-            return myfoo;
-        }
-
-        public void setMyfoo(String myfoo) {
-            this.myfoo = myfoo;
-        }
-
-        public boolean isYes() {
-            return yes;
-        }
-
-        public void setYes(boolean yes) {
-            this.yes = yes;
-        }
-
-        public String[] getUsers() {
-            return users;
-        }
-
-        public void setUsers(String[] users) {
-            this.users = users;
-        }
-
-        public static Foo getFoo() {
-            return new Foo();
-        }
-    }
-
-    public static class Bar implements Serializable {
-
-        private static final long serialVersionUID = 1L;
-        private String mybar = "bar3";
-        private boolean yes;
-        private String[] users = {"bar1", "bar2", "bar3"};
-
-        public String getMybar() {
-            return mybar;
-        }
-
-        public void setMybar(String mybar) {
-            this.mybar = mybar;
-        }
-
-        public boolean isYes() {
-            return yes;
-        }
-
-        public void setYes(boolean yes) {
-            this.yes = yes;
-        }
-
-        public String[] getUsers() {
-            return users;
-        }
-
-        public void setUsers(String[] users) {
-            this.users = users;
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/test/java/org/activiti/karaf/commands/ListActivitiCommandTest.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/test/java/org/activiti/karaf/commands/ListActivitiCommandTest.java b/activiti/commands/src/test/java/org/activiti/karaf/commands/ListActivitiCommandTest.java
deleted file mode 100644
index 10dcef1..0000000
--- a/activiti/commands/src/test/java/org/activiti/karaf/commands/ListActivitiCommandTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2012 Cisco Systems
- *
- * 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.
- */
-
-package org.activiti.karaf.commands;
-
-import org.activiti.engine.test.Deployment;
-import static org.fest.assertions.api.Assertions.assertThat;
-import org.junit.Test;
-
-/**
- * @author Srinivasan Chikkala
- */
-public class ListActivitiCommandTest extends ActivitiTestCase {
-
-    @Test
-    @Deployment(resources = {"diagrams/test-bpm-1.bpmn20.xml", "diagrams/test-bpm-2.bpmn20.xml",
-        "diagrams/test-bpm-3.bpmn20.xml"})
-    public void testListCommand() throws Exception {
-        ListActivitiCommand command = new ListActivitiCommand();
-
-        command.setProcessEngine(getProcessEngine());
-        command.setOut(getOut());
-        command.setErr(getErr());
-
-        command.doExecute();
-
-        assertThat(collectStdOutput())
-            .contains("[diagrams/test-bpm-2.bpmn20.xml]")
-            .contains("[diagrams/test-bpm-3.bpmn20.xml]")
-            .contains("[diagrams/test-bpm-1.bpmn20.xml]")
-            .contains("[ListActivitiCommandTest.testListCommand]");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ActivitiCommandTest.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ActivitiCommandTest.java b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ActivitiCommandTest.java
new file mode 100644
index 0000000..7afc0f2
--- /dev/null
+++ b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ActivitiCommandTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import org.apache.provisionr.activiti.karaf.commands.util.TextTable;
+import org.junit.After;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+public class ActivitiCommandTest {
+
+    private ByteArrayOutputStream backingStream;
+    private PrintWriter out;
+
+    @Before
+    public void setUp() {
+        backingStream = new ByteArrayOutputStream();
+        out = new PrintWriter(backingStream);
+    }
+
+    @After
+    public void tearDown() {
+        out.close();
+        backingStream.reset();
+    }
+
+    public String collectOutput() {
+        out.flush();
+        return backingStream.toString();
+    }
+
+    @Test
+    public void testTextTable1() {
+        String[] headers = {"col1", "column2", "c3"};
+        String[] row1 = {"myvalue111111111111111x", "myvalue2", "myvalue3"};
+        String[] row2 = {"myvalue1", "myvalue2", "myvalue3"};
+        String[] row3 = {"myvalue1", "myvalue2", "myvalue3"};
+
+        final String expectedOutput = " col1                     column2   c3       \n" +
+            "[myvalue111111111111111x][myvalue2][myvalue3]\n" +
+            "[myvalue1               ][myvalue2][myvalue3]\n" +
+            "[myvalue1               ][myvalue2][myvalue3]\n";
+
+        TextTable table = new TextTable(3);
+        table.addHeaders(headers);
+        table.addRow(row1);
+        table.addRow(row2);
+        table.addRow(row3);
+
+        table.print(out);
+        assertEquals(collectOutput(), expectedOutput);
+    }
+
+    @Test
+    public void testTextTable2() {
+        String[] headers = {"col1", "column2", "c3"};
+        String[] row1 = {"myvalue1", "myvalue2", "myvalue3"};
+        String[] row2 = {"myvalue111111111111111111111111111111x", "myvalue2", "myvalue3"};
+        String[] row3 = {"myvalue1", "myvalue2", "myvalue33333333333333333333x"};
+
+        final String expectedOutput = " col1                                    column2   c3                           \n" +
+            "[myvalue1                              ][myvalue2][myvalue3                    ]\n" +
+            "[myvalue111111111111111111111111111111x][myvalue2][myvalue3                    ]\n" +
+            "[myvalue1                              ][myvalue2][myvalue33333333333333333333x]\n";
+
+        TextTable table = new TextTable(3);
+        table.addHeaders(headers);
+        table.addRow(row1);
+        table.addRow(row2);
+        table.addRow(row3);
+
+        table.print(out);
+        assertEquals(collectOutput(), expectedOutput);
+    }
+
+    @Test
+    public void testTextTable3() {
+        String[] headers = {"col1", "column2", "c3"};
+        String[] row1 = {"myvalue1", "myvalue2", "myvalue3ddddddddddddddddddx"};
+        String[] row2 = {"myvalue1", "myvalue2", "myvalue3"};
+        String[] row3 = {"myvalue11111111111111111111111x", "myvalue2", "myvalue3"};
+
+        final String expectedOutput = " col1                             column2   c3                          \n" +
+            "[myvalue1                       ][myvalue2][myvalue3ddddddddddddddddddx]\n" +
+            "[myvalue1                       ][myvalue2][myvalue3                   ]\n" +
+            "[myvalue11111111111111111111111x][myvalue2][myvalue3                   ]\n";
+
+        TextTable table = new TextTable(3);
+        table.addHeaders(headers);
+        table.addRow(row1);
+        table.addRow(row2);
+        table.addRow(row3);
+
+        table.print(out);
+        assertEquals(collectOutput(), expectedOutput);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ActivitiTestCase.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ActivitiTestCase.java b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ActivitiTestCase.java
new file mode 100644
index 0000000..7879636
--- /dev/null
+++ b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ActivitiTestCase.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.test.ActivitiRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("classpath:activiti.cfg.xml")
+public abstract class ActivitiTestCase {
+
+    private static final Logger LOG = Logger.getLogger(ActivitiTestCase.class.getName());
+
+    @Autowired
+    private ProcessEngine processEngine;
+
+    @Autowired
+    private RuntimeService runtimeService;
+
+    @Autowired
+    private TaskService taskService;
+
+    @Autowired
+    @Rule
+    public ActivitiRule activitiSpringRule;
+
+    private ByteArrayOutputStream outputStream;
+    private PrintWriter out;
+
+    private ByteArrayOutputStream errStream;
+    private PrintWriter err;
+
+    @Before
+    public void setUp() {
+        outputStream = new ByteArrayOutputStream();
+        out = new PrintWriter(outputStream);
+
+        errStream = new ByteArrayOutputStream();
+        err = new PrintWriter(errStream);
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        processEngine.close();
+
+        out.close();
+        outputStream.close();
+
+        err.close();
+        errStream.close();
+    }
+
+    public PrintWriter getOut() {
+        return out;
+    }
+
+    public PrintWriter getErr() {
+        return err;
+    }
+
+    public String collectStdOutput() throws IOException {
+        out.flush();
+        outputStream.flush();
+
+        return outputStream.toString();
+    }
+
+    public String collectErrOutput() throws IOException {
+        err.flush();
+        errStream.flush();
+
+        return errStream.toString();
+    }
+
+    protected ProcessEngine getProcessEngine() {
+        return this.processEngine;
+    }
+
+    protected ProcessInstance startProcess(String processKey) throws Exception {
+        return startProcess(processKey, new HashMap<String, Object>());
+    }
+
+    protected ProcessInstance startProcess(String processKey, Map<String, Object> variables) throws Exception {
+        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey, variables);
+        String processInstanceId = processInstance.getId();
+
+        LOG.info("Started process instance id " + processInstanceId);
+        runtimeService.createProcessInstanceQuery().count();
+
+        HistoricProcessInstance historicProcessInstance = processEngine
+            .getHistoryService().createHistoricProcessInstanceQuery()
+            .processInstanceId(processInstanceId).singleResult();
+
+        if (historicProcessInstance != null) {
+            LOG.info("Finished " + processKey + "Instance. took "
+                + historicProcessInstance.getDurationInMillis() + " millis");
+        }
+        return processInstance;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/InfoActivitiCommandTest.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/InfoActivitiCommandTest.java b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/InfoActivitiCommandTest.java
new file mode 100644
index 0000000..6e32b1c
--- /dev/null
+++ b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/InfoActivitiCommandTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.TreeMap;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.test.Deployment;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+public class InfoActivitiCommandTest extends ActivitiTestCase {
+
+    @Test
+    @Deployment(resources = {"diagrams/test-bpm-1.bpmn20.xml", "diagrams/test-bpm-2.bpmn20.xml",
+        "diagrams/test-bpm-3.bpmn20.xml"})
+    public void testListBPMCommand1() throws Exception {
+        String processKey = "Test-bpm-1";
+
+        Map<String, Object> variables = new TreeMap<String, Object>();
+        variables.put("myfoo", new Foo());
+        variables.put("mybar", new Bar());
+        variables.put("my.array", new Object[]{new Foo(), new Bar()});
+
+        ProcessInstance processInstance = this.startProcess(processKey, variables);
+
+        InfoActivitiCommand command = new InfoActivitiCommand();
+        command.setProcessEngine(this.getProcessEngine());
+        command.setInstanceID(processInstance.getId());
+        command.setOut(getOut());
+        command.setErr(getErr());
+
+        command.doExecute();
+
+        assertThat(collectStdOutput())
+            .contains("Instance ID:")
+            .contains("Start Activity:  startevent1")
+            .contains("End Activity:    endevent1")
+            .contains("Variable Name:   my.array")
+            .contains("\"mybar\": \"bar3\"")
+            .contains("Variable Name:   mybar")
+            .contains(" Variable Name:   myfoo");
+    }
+
+    public static class Foo implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+        private String myfoo = "foo2";
+        private boolean yes;
+        private String[] users = {"foo1", "foo2", "foo3"};
+        private Bar fooBar = new Bar();
+
+        public Bar getFooBar() {
+            return fooBar;
+        }
+
+        public void setFooBar(Bar fooBar) {
+            this.fooBar = fooBar;
+        }
+
+        public String getMyfoo() {
+            return myfoo;
+        }
+
+        public void setMyfoo(String myfoo) {
+            this.myfoo = myfoo;
+        }
+
+        public boolean isYes() {
+            return yes;
+        }
+
+        public void setYes(boolean yes) {
+            this.yes = yes;
+        }
+
+        public String[] getUsers() {
+            return users;
+        }
+
+        public void setUsers(String[] users) {
+            this.users = users;
+        }
+
+        public static Foo getFoo() {
+            return new Foo();
+        }
+    }
+
+    public static class Bar implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+        private String mybar = "bar3";
+        private boolean yes;
+        private String[] users = {"bar1", "bar2", "bar3"};
+
+        public String getMybar() {
+            return mybar;
+        }
+
+        public void setMybar(String mybar) {
+            this.mybar = mybar;
+        }
+
+        public boolean isYes() {
+            return yes;
+        }
+
+        public void setYes(boolean yes) {
+            this.yes = yes;
+        }
+
+        public String[] getUsers() {
+            return users;
+        }
+
+        public void setUsers(String[] users) {
+            this.users = users;
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ListActivitiCommandTest.java
----------------------------------------------------------------------
diff --git a/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ListActivitiCommandTest.java b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ListActivitiCommandTest.java
new file mode 100644
index 0000000..c675735
--- /dev/null
+++ b/activiti/commands/src/test/java/org/apache/provisionr/activiti/karaf/commands/ListActivitiCommandTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012 Cisco Systems
+ *
+ * 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.
+ */
+
+package org.apache.provisionr.activiti.karaf.commands;
+
+import org.activiti.engine.test.Deployment;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+/**
+ * @author Srinivasan Chikkala
+ */
+public class ListActivitiCommandTest extends ActivitiTestCase {
+
+    @Test
+    @Deployment(resources = {"diagrams/test-bpm-1.bpmn20.xml", "diagrams/test-bpm-2.bpmn20.xml",
+        "diagrams/test-bpm-3.bpmn20.xml"})
+    public void testListCommand() throws Exception {
+        ListActivitiCommand command = new ListActivitiCommand();
+
+        command.setProcessEngine(getProcessEngine());
+        command.setOut(getOut());
+        command.setErr(getErr());
+
+        command.doExecute();
+
+        assertThat(collectStdOutput())
+            .contains("[diagrams/test-bpm-2.bpmn20.xml]")
+            .contains("[diagrams/test-bpm-3.bpmn20.xml]")
+            .contains("[diagrams/test-bpm-1.bpmn20.xml]")
+            .contains("[ListActivitiCommandTest.testListCommand]");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/activiti/explorer/pom.xml
----------------------------------------------------------------------
diff --git a/activiti/explorer/pom.xml b/activiti/explorer/pom.xml
index c010873..f0ad6fa 100644
--- a/activiti/explorer/pom.xml
+++ b/activiti/explorer/pom.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<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">
+<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">
     <!--
         Copyright 2012 Cisco Systems
         
@@ -21,17 +22,16 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <artifactId>provisionr-parent</artifactId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
 
-    <groupId>org.activiti.karaf</groupId>
     <artifactId>activiti-karaf-web-explorer</artifactId>
     <packaging>war</packaging>
 
-    <name>Activiti Karaf :: Web Explorer</name>
+    <name>Apache Provisionr :: Activiti Karaf :: Explorer</name>
     <description>Activiti Explorer Web Application As OGSi War</description>
     <url>http://activiti.org</url>
 
@@ -270,7 +270,8 @@
                         <Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath>
                         <Webapp-Context>activiti-explorer</Webapp-Context>
                         <Bundle-Name>${project.name}</Bundle-Name>
-                        <Import-Package>org.activiti.osgi*;resolution:=optional, ${activiti.osgi.import}</Import-Package>
+                        <Import-Package>org.activiti.osgi*;resolution:=optional, ${activiti.osgi.import}
+                        </Import-Package>
                         <DynamicImport-Package>${activiti.osgi.dynamic}</DynamicImport-Package>
                         <Include-Resource>${activiti.osgi.include.resource}</Include-Resource>
                     </instructions>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/pom.xml
----------------------------------------------------------------------
diff --git a/api/pom.xml b/api/pom.xml
index f8e62d8..2bd7763 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -17,13 +17,13 @@
 <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/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <artifactId>provisionr-parent</artifactId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../parent</relativePath>
     </parent>
 
-    <name>Axemblr Provisionr :: API</name>
+    <name>Apache Provisionr :: API</name>
     <artifactId>provisionr-api</artifactId>
     <packaging>bundle</packaging>
 
@@ -53,7 +53,7 @@
                     <outputDirectory>${basedir}/target/classes</outputDirectory>
                     <instructions>
                         <Fragment-Host>org.activiti.engine</Fragment-Host>
-                        <Export-Package>com.axemblr.provisionr.api*</Export-Package>
+                        <Export-Package>org.apache.provisionr.api*</Export-Package>
                         <Private-Package>!*</Private-Package>
                     </instructions>
                 </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/Provisionr.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/Provisionr.java b/api/src/main/java/com/axemblr/provisionr/api/Provisionr.java
deleted file mode 100644
index 2b4c483..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/Provisionr.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api;
-
-import com.axemblr.provisionr.api.pool.Machine;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.base.Optional;
-import java.util.List;
-
-public interface Provisionr {
-
-    /**
-     * Get unique ID for this provisionr
-     */
-    public String getId();
-
-
-    /**
-     * Return the default provider configured for this bundle using the
-     * Blueprint configuration mechanism or something else
-     *
-     * @see Provider
-     */
-    public Optional<Provider> getDefaultProvider();
-
-    /**
-     * Start a provisioning process based on the pool description
-     * <p/>
-     * This process will run until the pool is destroyed
-     *
-     * @param businessKey external process ID (e.g. job ID, business key)
-     * @param pool        pool description
-     * @return internal process ID
-     */
-    String startPoolManagementProcess(String businessKey, Pool pool);
-
-
-    /**
-     * Retrieve the list of machines for a pool or an empty list
-     *
-     * @param businessKey external pool ID (e.g. job ID)
-     * @return list of running machines or empty
-     */
-    List<Machine> getMachines(String businessKey);
-
-    /**
-     * Get current pool status
-     *
-     * @param businessKey external process ID (e.g. job ID)
-     * @return internal status information
-     */
-    String getStatus(String businessKey);
-
-    /**
-     * Destroy all the machines from the pool with that id
-     *
-     * @param businessKey external pool ID (e.g. job ID, business key)
-     */
-    void destroyPool(String businessKey);
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/access/AdminAccess.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/access/AdminAccess.java b/api/src/main/java/com/axemblr/provisionr/api/access/AdminAccess.java
deleted file mode 100644
index f17f473..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/access/AdminAccess.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.access;
-
-import com.google.common.base.Objects;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.io.Serializable;
-
-/**
- * Describe the only user allowed to access machine from the pool over SSH
- * <p/>
- * This user will support only key-based SSH authentication have
- * password-less sudo access
- */
-public class AdminAccess implements Serializable {
-
-    public static AdminAccessBuilder builder() {
-        return new AdminAccessBuilder();
-    }
-
-    private final String username;
-    private final String publicKey;
-    private final String privateKey;
-
-    AdminAccess(String username, String publicKey, String privateKey) {
-        this.username = checkNotNull(username, "username is null");
-        this.publicKey = checkNotNull(publicKey, "publicKey is null");
-        this.privateKey = checkNotNull(privateKey, "privateKey is null");
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public String getPublicKey() {
-        return publicKey;
-    }
-
-    public String getPrivateKey() {
-        return privateKey;
-    }
-
-    public AdminAccessBuilder toBuilder() {
-        return builder().username(username)
-            .publicKey(publicKey).privateKey(privateKey);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(username, publicKey, privateKey);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final AdminAccess other = (AdminAccess) obj;
-        return Objects.equal(this.username, other.username)
-            && Objects.equal(this.publicKey, other.publicKey)
-            && Objects.equal(this.privateKey, other.privateKey);
-    }
-
-    @Override
-    public String toString() {
-        return "AdminAccess{" +
-            "username='" + username + '\'' +
-            ", publicKey='" + publicKey + '\'' +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/access/AdminAccessBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/access/AdminAccessBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/access/AdminAccessBuilder.java
deleted file mode 100644
index 69f03bc..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/access/AdminAccessBuilder.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.access;
-
-import com.google.common.base.Charsets;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Throwables;
-import com.google.common.io.Files;
-import java.io.File;
-
-public class AdminAccessBuilder {
-
-    private String username;
-    private String publicKey;
-    private String privateKey;
-
-    public AdminAccessBuilder username(String username) {
-        this.username = checkNotNull(username, "username is null");
-        return this;
-    }
-
-    public AdminAccessBuilder publicKey(String publicKey) {
-        checkArgument(publicKey.startsWith("ssh-rsa "), "The key does not start with ssh-rsa as expected");
-        this.publicKey = checkNotNull(publicKey, "publicKey is null");
-        return this;
-    }
-
-    public AdminAccessBuilder privateKey(String privateKey) {
-        checkArgument(privateKey.startsWith("-----BEGIN RSA PRIVATE KEY-----"),
-            "The key does not start with -----BEGIN RSA PRIVATE KEY----- as expected");
-        this.privateKey = checkNotNull(privateKey, "privateKey is null");
-        return this;
-    }
-
-    public AdminAccessBuilder asCurrentUser() {
-        String userHome = System.getProperty("user.home");
-
-        try {
-            String publicKey = Files.toString(new File(userHome, ".ssh/id_rsa.pub"), Charsets.UTF_8);
-            String privateKey = Files.toString(new File(userHome, ".ssh/id_rsa"), Charsets.UTF_8);
-
-            return username(System.getProperty("user.name")).publicKey(publicKey).privateKey(privateKey);
-
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    public AdminAccess createAdminAccess() {
-        return new AdminAccess(username, publicKey, privateKey);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/hardware/BlockDevice.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/hardware/BlockDevice.java b/api/src/main/java/com/axemblr/provisionr/api/hardware/BlockDevice.java
deleted file mode 100644
index ed72ebd..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/hardware/BlockDevice.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-* Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
-*
-* 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.
-*/
-
-package com.axemblr.provisionr.api.hardware;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.axemblr.provisionr.api.util.WithOptions;
-import com.google.common.base.Objects;
-
-import java.util.Map;
-
-public class BlockDevice extends WithOptions {
-
-    private int size;
-    private String name;
-
-    public static BlockDeviceBuilder builder() {
-        return new BlockDeviceBuilder();
-    }
-
-    BlockDevice(int size, String name, Map<String, String> options) {
-        super(options);
-        checkArgument(size > 0, "the block device size should be a positive integer");
-        this.size = size;
-        this.name = name;
-    }
-
-    public int getSize() {
-        return size;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(size, name, getOptions());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final BlockDevice other = (BlockDevice) obj;
-        return Objects.equal(this.size, other.size)
-            && Objects.equal(this.name, this.name)
-            && Objects.equal(this.getOptions(), other.getOptions());
-    }
-
-    @Override
-    public String toString() {
-        return "BlockDevice {" +
-            "size=" + size +
-            "name=" + name +
-            ", options=" + getOptions() + "}";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/hardware/BlockDeviceBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/hardware/BlockDeviceBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/hardware/BlockDeviceBuilder.java
deleted file mode 100644
index 7353a84..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/hardware/BlockDeviceBuilder.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.axemblr.provisionr.api.hardware;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.axemblr.provisionr.api.util.BuilderWithOptions;
-
-public class BlockDeviceBuilder extends BuilderWithOptions<BlockDeviceBuilder> {
-
-    private Integer size;
-    private String name;
-
-    @Override
-    protected BlockDeviceBuilder getThis() {
-        return this;
-    }
-
-    public BlockDeviceBuilder size(int size) {
-        checkArgument(size > 0, "The block device size must be a positive integer");
-        this.size = size;
-        return this;
-    }
-
-    public BlockDeviceBuilder name(String mapping) {
-        this.name = checkNotNull(mapping, "The block device must have a name - the OS path on which it is mapped");
-        return this;
-    }
-
-    public BlockDevice createBlockDevice() {
-        checkNotNull(size, "The size was not specified");
-        return new BlockDevice(size, name, buildOptions());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/hardware/Hardware.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/hardware/Hardware.java b/api/src/main/java/com/axemblr/provisionr/api/hardware/Hardware.java
deleted file mode 100644
index 55ae6cf..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/hardware/Hardware.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.hardware;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.axemblr.provisionr.api.util.WithOptions;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-import java.util.Map;
-
-public class Hardware extends WithOptions {
-
-    public static HardwareBuilder builder() {
-        return new HardwareBuilder();
-    }
-
-    private final String type;
-    private List<BlockDevice> blockDevices;
-
-    Hardware(String type, List<BlockDevice> blockDevices, Map<String, String> options) {
-        super(options);
-        this.type = checkNotNull(type, "type is null");
-        this.blockDevices = ImmutableList.copyOf(blockDevices);
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public List<BlockDevice> getBlockDevices() {
-        return blockDevices;
-    }
-
-    public HardwareBuilder toBuilder() {
-        return builder().type(type).blockDevices(blockDevices).options(getOptions());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(type, getOptions(), getBlockDevices());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final Hardware other = (Hardware) obj;
-        return Objects.equal(this.type, other.type)
-            && Objects.equal(this.getOptions(), other.getOptions())
-            && Objects.equal(this.getBlockDevices(), other.getBlockDevices());
-    }
-
-    @Override
-    public String toString() {
-        return "Hardware{" +
-            "type='" + type + '\'' +
-            ", blockDevices=" + getBlockDevices() + 
-            ", options=" + getOptions() +
-            '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/hardware/HardwareBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/hardware/HardwareBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/hardware/HardwareBuilder.java
deleted file mode 100644
index 0904546..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/hardware/HardwareBuilder.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.hardware;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.axemblr.provisionr.api.util.BuilderWithOptions;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-
-public class HardwareBuilder extends BuilderWithOptions<HardwareBuilder> {
-
-    private String type = "default";
-    private List<BlockDevice> blockDevices = Lists.newArrayList();
-
-    @Override
-    protected HardwareBuilder getThis() {
-        return this;
-    }
-
-    /**
-     * This is similar to <a href="http://aws.amazon.com/ec2/instance-types/">'instance type'</a> on Amazon
-     * or <a href="http://docs.cloudstack.org/Glossary">'service offering'</a> on CloudStack
-     *
-     * @param type
-     * @return
-     */
-    public HardwareBuilder type(String type) {
-        this.type = checkNotNull(type, "type is null");
-        return this;
-    }
-
-    public HardwareBuilder blockDevices(List<BlockDevice> blockDevices) {
-        this.blockDevices = checkNotNull(blockDevices, "the list of block devices is null");
-        return this;
-    }
-
-    public Hardware createHardware() {
-        return new Hardware(type, blockDevices, buildOptions());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/network/Network.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/network/Network.java b/api/src/main/java/com/axemblr/provisionr/api/network/Network.java
deleted file mode 100644
index b47721a..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/network/Network.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.network;
-
-import com.axemblr.provisionr.api.util.WithOptions;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import java.io.Serializable;
-import java.util.Map;
-import java.util.Set;
-
-public class Network extends WithOptions {
-
-    public static NetworkBuilder builder() {
-        return new NetworkBuilder();
-    }
-
-    private final String type;
-    private final Set<Rule> ingress;
-
-    Network(String type, Set<Rule> ingress, Map<String, String> options) {
-        super(options);
-        this.type = checkNotNull(type, "type is null");
-        this.ingress = ImmutableSet.copyOf(ingress);
-    }
-
-    /**
-     * Implementation specific network type information
-     */
-    public String getType() {
-        return type;
-    }
-
-    /**
-     * Set of rules for incoming packages
-     */
-    public Set<Rule> getIngress() {
-        return ingress;
-    }
-
-    public NetworkBuilder toBuilder() {
-        return builder().type(type).ingress(ingress).options(getOptions());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(type, ingress, getOptions());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final Network other = (Network) obj;
-        return Objects.equal(this.type, other.type)
-            && Objects.equal(this.ingress, other.ingress)
-            && Objects.equal(this.getOptions(), other.getOptions());
-    }
-
-    @Override
-    public String toString() {
-        return Objects.toStringHelper(this).omitNullValues()
-            .add("type", type).add("ingress", ingress)
-            .add("options", getOptions()).toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/network/NetworkBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/network/NetworkBuilder.java b/api/src/main/java/com/axemblr/provisionr/api/network/NetworkBuilder.java
deleted file mode 100644
index 06c25d5..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/network/NetworkBuilder.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.network;
-
-import com.axemblr.provisionr.api.util.BuilderWithOptions;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import java.util.Set;
-
-public class NetworkBuilder extends BuilderWithOptions<NetworkBuilder> {
-
-    private String type = "default";
-    private ImmutableSet.Builder<Rule> ingress = ImmutableSet.builder();
-
-    @Override
-    protected NetworkBuilder getThis() {
-        return this;
-    }
-
-    public NetworkBuilder type(String type) {
-        this.type = checkNotNull(type, "type is null");
-        return this;
-    }
-
-    public NetworkBuilder ingress(Set<Rule> incoming) {
-        this.ingress = ImmutableSet.<Rule>builder().addAll(incoming);
-        return this;
-    }
-
-    public NetworkBuilder addRules(Rule... rules) {
-        return addRules(Lists.newArrayList(rules));
-    }
-
-    public NetworkBuilder addRules(Iterable<Rule> rules) {
-        this.ingress.addAll(rules);
-        return this;
-    }
-
-    public Network createNetwork() {
-        return new Network(type, ingress.build(), buildOptions());
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/api/src/main/java/com/axemblr/provisionr/api/network/Protocol.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/com/axemblr/provisionr/api/network/Protocol.java b/api/src/main/java/com/axemblr/provisionr/api/network/Protocol.java
deleted file mode 100644
index ec9ba05..0000000
--- a/api/src/main/java/com/axemblr/provisionr/api/network/Protocol.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * 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.
- */
-
-package com.axemblr.provisionr.api.network;
-
-public enum Protocol {
-    TCP,
-    UDP,
-    ICMP
-}