provisionr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From as...@apache.org
Subject [10/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr
Date Mon, 01 Apr 2013 08:52:33 GMT
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);
-    }
-}


Mime
View raw message