diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5231862
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.idea
+*.iml
+target
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..61ab4bc
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,39 @@
+
+
+ 4.0.0
+ io.obsidian.booster.common
+ booster-common
+ 1-SNAPSHOT
+
+ 3.6.1
+ 1.7.0
+ 2.9.0
+ 1.4.34
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+
+
+ com.jayway.restassured
+ rest-assured
+ ${rest-assured.version}
+
+
+ io.fabric8
+ openshift-client
+ ${openshift-client.version}
+
+
+ com.jayway.awaitility
+ awaitility
+ ${awaitifily.version}
+
+
+
diff --git a/src/main/java/io/obsidian/booster/common/OpenShiftTestAssistant.java b/src/main/java/io/obsidian/booster/common/OpenShiftTestAssistant.java
new file mode 100644
index 0000000..c55ee30
--- /dev/null
+++ b/src/main/java/io/obsidian/booster/common/OpenShiftTestAssistant.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2016-2017 Red Hat, Inc, and individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.obsidian.booster.common;
+
+import com.jayway.restassured.RestAssured;
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.client.DefaultKubernetesClient;
+import io.fabric8.kubernetes.client.dsl.NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable;
+import io.fabric8.openshift.api.model.DeploymentConfig;
+import io.fabric8.openshift.api.model.Route;
+import io.fabric8.openshift.client.OpenShiftClient;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Clement Escoffier
+ */
+public class OpenShiftTestAssistant {
+
+ private final OpenShiftClient client;
+ private final String project;
+ private String applicationName;
+ private Map> created
+ = new LinkedHashMap<>();
+
+ public OpenShiftTestAssistant() {
+ client = new DefaultKubernetesClient().adapt(OpenShiftClient.class);
+ project = client.getNamespace();
+ }
+
+ public List extends HasMetadata> deploy(String name, File template) throws IOException {
+ try (FileInputStream fis = new FileInputStream(template)) {
+ NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable declarations = client.load(fis);
+ List entities = declarations.createOrReplace();
+ created.put(name, declarations);
+ System.out.println(name + " deployed, " + entities.size() + " object(s) created.");
+
+ return entities;
+ }
+ }
+
+ public String deployApplication() throws IOException {
+ applicationName = System.getProperty("app.name");
+
+ List extends HasMetadata> entities
+ = deploy("application", new File("target/classes/META-INF/fabric8/openshift.yml"));
+
+ Optional first = entities.stream()
+ .filter(hm -> hm instanceof DeploymentConfig)
+ .map(hm -> (DeploymentConfig) hm)
+ .map(dc -> dc.getMetadata()
+ .getName())
+ .findFirst();
+ if (applicationName == null && first.isPresent()) {
+ applicationName = first.get();
+ }
+
+ Route route = client.adapt(OpenShiftClient.class)
+ .routes()
+ .inNamespace(project)
+ .withName(applicationName)
+ .get();
+ assertThat(route).isNotNull();
+ RestAssured.baseURI = "http://" + Objects.requireNonNull(route)
+ .getSpec()
+ .getHost();
+ System.out.println("Route url: " + RestAssured.baseURI);
+
+ return applicationName;
+ }
+
+ public void cleanup() {
+ List keys = new ArrayList<>(created.keySet());
+ Collections.reverse(keys);
+ for (String key : keys) {
+ System.out.println("Deleting " + key);
+ created.remove(key)
+ .delete();
+ }
+ }
+
+ public void awaitApplicationReadinessOrFail() {
+ await().atMost(5, TimeUnit.MINUTES)
+ .until(() -> {
+ List list = client.pods()
+ .inNamespace(project)
+ .list()
+ .getItems();
+ return list.stream()
+ .filter(pod ->
+ pod.getMetadata()
+ .getName()
+ .startsWith(applicationName))
+ .filter(this::isRunning)
+ .collect(Collectors.toList())
+ .size() >= 1;
+ }
+ );
+
+ }
+
+ private boolean isRunning(Pod pod) {
+ return "running".equalsIgnoreCase(pod.getStatus()
+ .getPhase());
+ }
+
+
+ public OpenShiftClient client() {
+ return client;
+ }
+
+ public String project() {
+ return project;
+ }
+
+ public String applicationName() {
+ return applicationName;
+ }
+
+ public void awaitPodReadinessOrFail(Predicate filter) {
+ await().atMost(5, TimeUnit.MINUTES)
+ .until(() -> {
+ List list = client.pods()
+ .inNamespace(project)
+ .list()
+ .getItems();
+ return list.stream()
+ .filter(filter)
+ .filter(this::isRunning)
+ .collect(Collectors.toList())
+ .size() >= 1;
+ }
+ );
+ }
+}
\ No newline at end of file