diff --git a/README.adoc b/README.adoc
index 7cd8835..89516f1 100644
--- a/README.adoc
+++ b/README.adoc
@@ -70,7 +70,7 @@ will now display the generated WSDL.
== Integration Testing
-The example includes a https://github.com/fabric8io/fabric8/tree/master/components/fabric8-arquillian[fabric8 arquillian] Kubernetes Integration Test.
+The example includes a Kubernetes Integration Test.
Once the container image has been built and deployed in Kubernetes, the integration test can be run with:
[source,bash,options="nowrap",subs="attributes+"]
@@ -78,7 +78,7 @@ Once the container image has been built and deployed in Kubernetes, the integrat
mvn test -Dtest=*KT
----
-The test is disabled by default and has to be enabled using `-Dtest`. https://fabric8.io/guide/testing.html[Integration Testing] and https://fabric8.io/guide/arquillian.html[Fabric8 Arquillian Extension] provide more information on writing full fledged black box integration tests for Kubernetes.
+The test is disabled by default and has to be enabled using `-Dtest`.
== Running the quickstart standalone on your machine
diff --git a/pom.xml b/pom.xml
index 343d672..17a4df2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,24 +62,23 @@
junit
test
+
- org.jboss.arquillian.junit
- arquillian-junit-container
- test
-
-
- org.arquillian.cube
- arquillian-cube-openshift
+ io.fabric8
+ kubernetes-model
test
+
io.fabric8
- kubernetes-model
+ kubernetes-client
test
+
io.fabric8
- kubernetes-client
+ openshift-client
+ 4.6.2
test
diff --git a/src/test/java/io/fabric8/quickstarts/cxf/jaxws/KubernetesIntegrationKT.java b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/KubernetesIntegrationKT.java
index 7b52629..dc92299 100644
--- a/src/test/java/io/fabric8/quickstarts/cxf/jaxws/KubernetesIntegrationKT.java
+++ b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/KubernetesIntegrationKT.java
@@ -16,42 +16,53 @@
package io.fabric8.quickstarts.cxf.jaxws;
-
-import static org.junit.Assert.assertTrue;
-
-import org.arquillian.cube.kubernetes.api.Session;
-import org.jboss.arquillian.container.test.api.RunAsClient;
-import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.arquillian.test.api.ArquillianResource;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodList;
import io.fabric8.kubernetes.client.KubernetesClient;
-import io.fabric8.kubernetes.client.internal.readiness.Readiness;
+import io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestConfig;
+import io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestSetup;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.TimeUnit;
+
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestConfig.createConfig;
-@RunWith(Arquillian.class)
-@RunAsClient
public class KubernetesIntegrationKT {
- @ArquillianResource
- KubernetesClient client;
+ private static Logger LOG = LoggerFactory.getLogger(KubernetesIntegrationKT.class);
- @ArquillianResource
- public Session session;
@Test
- public void testAppProvisionsRunningPods() throws Exception {
- boolean foundReadyPod = false;
-
- PodList podList = client.pods().inNamespace(session.getNamespace()).list();
- for (Pod p : podList.getItems()) {
- if (!p.getMetadata().getName().endsWith("build") && !p.getMetadata().getName().endsWith("deploy")) {
- assertTrue(p.getMetadata().getName() + " is not ready", Readiness.isReady(p));
- foundReadyPod = true;
+ public void testAppProvisionsRunningPods() {
+ KubernetesTestConfig config = createConfig();
+ KubernetesTestSetup testSetup = new KubernetesTestSetup(config);
+
+ try {
+ testSetup.setUp();
+ KubernetesClient client = config.getClient();
+ PodList podList = client.pods().inNamespace(config.getNamespace()).list();
+
+ if (podList.getItems().isEmpty()) {
+ Assert.fail("No pods found in namespace "+ config.getNamespace());
+ }
+
+ for (Pod pod : podList.getItems()) {
+ try {
+ if (!pod.getMetadata().getName().endsWith("build") && !pod.getMetadata().getName().endsWith("deploy")) {
+ client.resource(pod)
+ .inNamespace(config.getNamespace())
+ .waitUntilReady(config.getKubernetesTimeout(), TimeUnit.SECONDS);
+ LOG.info("Pod {} is in state: {}",pod.getMetadata().getName(),pod.getStatus().getPhase());
+ }
+ } catch (InterruptedException e) {
+ Assert.fail("Timeout reached waiting for pod " + pod.getMetadata().getName());
+ }
}
+ } finally {
+ testSetup.tearDown();
}
- assertTrue("Found no ready pods in namespace", foundReadyPod);
}
}
diff --git a/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestConfig.java b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestConfig.java
new file mode 100644
index 0000000..6925812
--- /dev/null
+++ b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestConfig.java
@@ -0,0 +1,233 @@
+package io.fabric8.quickstarts.cxf.jaxws.support;
+
+import io.fabric8.kubernetes.client.Config;
+import io.fabric8.kubernetes.client.ConfigBuilder;
+import io.fabric8.kubernetes.client.DefaultKubernetesClient;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPathExpressionException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.failNotDeployed;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getArrayListStringProperty;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getArtifactId;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getBooleanProperty;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getIntProperty;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getResourceFileAsStream;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getStringProperty;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.isNullOrEmpty;
+import static java.util.Collections.singletonMap;
+import static java.util.Objects.nonNull;
+
+
+public class KubernetesTestConfig {
+
+
+ public static final String NAMESPACE_USE_CURRENT = "kt.namespace.use.current";
+ public static final String NAMESPACE_TO_USE = "kt.namespace.use.existing";
+ public static final String NAMESPACE_DESTROY_ENABLED = "kt.namespace.destroy.enabled";
+ public static final String NAMESPACE_PREFIX = "kt.namespace.prefix";
+ public static final String RESOUCE_FILE_PATH = "kt.resource.file.path";
+ public static final String KUBERNETES_MASTER = "kubernetes.master";
+ public static final String KUBERNETES_USERNAME = "kubernetes.username";
+ public static final String KUBERNETES_PASSWORD = "kubernetes.password";
+ public static final String KUBERNETES_TIMEOUT = "kubernetes.timeout";
+
+ public static final int DEFAULT_KUBERNETES_TIMEOUT = 300;
+ public static final String ENV_DEPENDENCIES = "kt.env.dependencies";
+ public static final String DEFAULT_NAMESPACE_PREFIX = "ktest";
+
+ public static final String TARGET_DIR_PATH = System.getProperty("basedir", ".") + "/target";
+ public static final String DEFAULT_RESOUCE_FILE_PATH = TARGET_DIR_PATH + "/classes/META-INF/jkube/openshift.yml";
+
+ public static final String TEST_PROPERTIES_FILE = "kubernetesTest.properties";
+
+
+ private final Properties systemPropertiesVars = System.getProperties();
+
+ private boolean shouldDestroyNamespace = false;
+
+ private boolean useExistingNamespace = true;
+
+ private String namespace;
+
+ private String resourceFilePath;
+
+ private String imageStreamFilePath;
+
+ private List dependencies;
+
+ private String kubernetesMaster;
+
+ private String kubernetesUsername;
+
+ private String kubernetesPassword;
+
+ private KubernetesClient kubeClient;
+
+ private int kubernetesTimeout;
+
+ private String mainNamespace;
+
+ private Map ktestLabels = singletonMap("scope","ktest");
+
+ private KubernetesTestConfig() {
+ }
+
+ public static KubernetesTestConfig createConfig() {
+ KubernetesTestConfig config = new KubernetesTestConfig();
+ config.loadConfiguration();
+ return config;
+ }
+
+ public KubernetesClient getClient() {
+ if (kubeClient == null) {
+ if (isNullOrEmpty(kubernetesMaster)) {
+ kubeClient = new DefaultKubernetesClient();
+ }else {
+ Config config = new ConfigBuilder()
+ .withMasterUrl(kubernetesMaster)
+ .withUsername(kubernetesUsername)
+ .withPassword(kubernetesPassword)
+ .build();
+ kubeClient = new DefaultKubernetesClient(config);
+ }
+ }
+ return kubeClient;
+ }
+
+ private void loadConfiguration() {
+
+ Properties prop = new Properties();
+
+ try (InputStream input = getResourceFileAsStream(TEST_PROPERTIES_FILE)) {
+ // load a properties file
+ if(nonNull(input)) {
+ prop.load(input);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ prop.putAll(systemPropertiesVars);
+
+ Map testConfig = prop.entrySet().stream().collect(
+ Collectors.toMap(
+ e -> String.valueOf(e.getKey()),
+ e -> String.valueOf(e.getValue()),
+ (prev, next) -> next,
+ HashMap::new)
+ );
+ String artifactId = null;
+ try{
+ artifactId = getArtifactId();
+ } catch (XPathExpressionException | ParserConfigurationException |IOException| SAXException e) {
+ failNotDeployed();
+ }
+
+ namespace = generateNamespaceName(testConfig);
+
+ resourceFilePath = getStringProperty(RESOUCE_FILE_PATH, testConfig, DEFAULT_RESOUCE_FILE_PATH);
+
+ imageStreamFilePath = TARGET_DIR_PATH + "/" + artifactId + "-is.yml" ;
+
+ dependencies = getArrayListStringProperty(ENV_DEPENDENCIES, testConfig);
+
+ kubernetesMaster = getStringProperty(KUBERNETES_MASTER, testConfig, null);
+
+ kubernetesUsername = getStringProperty(KUBERNETES_USERNAME, testConfig, null);
+
+ kubernetesPassword = getStringProperty(KUBERNETES_PASSWORD, testConfig, null);
+
+ kubernetesTimeout = getIntProperty(KUBERNETES_TIMEOUT,testConfig,DEFAULT_KUBERNETES_TIMEOUT);
+
+ shouldDestroyNamespace = getBooleanProperty(NAMESPACE_DESTROY_ENABLED, testConfig, true);
+
+ mainNamespace = extractMainNamespaceName(imageStreamFilePath);
+ }
+
+
+ private String generateNamespaceName(Map config) {
+ String sessionId = UUID.randomUUID().toString().split("-")[0];
+ String namespace = getBooleanProperty(NAMESPACE_USE_CURRENT, config, false)
+ ? new ConfigBuilder().build().getNamespace()
+ : getStringProperty(NAMESPACE_TO_USE, config, null);
+ if (isNullOrEmpty(namespace)) {
+ namespace = getStringProperty(NAMESPACE_PREFIX, config, DEFAULT_NAMESPACE_PREFIX) + "-" + sessionId;
+ shouldDestroyNamespace = true;
+ useExistingNamespace = false;
+ }
+ return namespace;
+ }
+
+ private String extractMainNamespaceName(String imageStreamFilePath){
+ Pattern pattern = Pattern.compile("\\s*\"namespace\"\\s*:\\s*\"[a-z0-9]([-a-z0-9]*[a-z0-9])?\".*");
+ Predicate namespacePredicate = pattern.asPredicate();
+
+ Optional mainNamespace = Optional.empty();
+
+ try (Stream stream = Files.lines(Paths.get(imageStreamFilePath))) {
+ mainNamespace = stream
+ .filter(namespacePredicate)
+ .map(x->pattern.matcher(x).group(1)).findFirst();
+ }catch (IOException e) {
+ failNotDeployed();
+ }
+ return mainNamespace.orElseGet(() -> new DefaultKubernetesClient().getNamespace());
+ }
+
+
+ // Getter
+
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String getResourceFilePath() {
+ return resourceFilePath;
+ }
+
+ public List getDependencies() {
+ return dependencies;
+ }
+
+ public boolean isUseExistingNamespace() {
+ return useExistingNamespace;
+ }
+
+ public boolean isShouldDestroyNamespace() {
+ return shouldDestroyNamespace;
+ }
+
+ public int getKubernetesTimeout() {
+ return kubernetesTimeout;
+ }
+
+ public Map getKtestLabels() {
+ return ktestLabels;
+ }
+
+ public String getImageStreamFilePath() {
+ return imageStreamFilePath;
+ }
+
+ public String getMainNamespace() {
+ return mainNamespace;
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestDeployer.java b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestDeployer.java
new file mode 100644
index 0000000..85406a5
--- /dev/null
+++ b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestDeployer.java
@@ -0,0 +1,187 @@
+package io.fabric8.quickstarts.cxf.jaxws.support;
+
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.fabric8.kubernetes.api.model.Namespace;
+import io.fabric8.kubernetes.api.model.NamespaceBuilder;
+import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
+import io.fabric8.kubernetes.api.model.rbac.RoleBindingBuilder;
+import io.fabric8.kubernetes.api.model.rbac.Subject;
+import io.fabric8.kubernetes.api.model.rbac.SubjectBuilder;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.KubernetesClientException;
+import io.fabric8.kubernetes.client.Watch;
+import io.fabric8.kubernetes.client.Watcher;
+import io.fabric8.openshift.api.model.ImageLookupPolicy;
+import io.fabric8.openshift.api.model.ImageStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.failNotDeployed;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.isNotNullOrEmpty;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.isNullOrEmpty;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+public class KubernetesTestDeployer {
+
+ private final static Logger LOG = LoggerFactory.getLogger(KubernetesTestDeployer.class);
+
+ private final static Predicate supportReadiness =
+ resource -> Arrays.asList("Node", "Deployment", "ReplicaSet", "StatefulSet", "Pod", "DeploymentConfig", "ReplicationController")
+ .contains(resource.getKind());
+
+ public static void deploy(KubernetesClient client, KubernetesTestConfig config) {
+ createNamespace(client, config);
+
+ // deploy dependencies
+ if (isNotNullOrEmpty(config.getDependencies())) {
+ LOG.info("Deploy dependencies from file {}", config.getImageStreamFilePath());
+ for (String dependency : config.getDependencies()) {
+ deployFromFile(client, config, dependency);
+ }
+ }
+
+ String sourceNamespace = config.getMainNamespace();
+ LOG.info("Deploy RoleBinding ");
+ createRoleBinding(client, sourceNamespace, config);
+ LOG.info("Deploy ImageStreams from file {}", config.getImageStreamFilePath());
+ createImageStream(client, config);
+ // deploy resources
+ LOG.info("Deploy resources from file {}", config.getResourceFilePath());
+ deployFromFile(client, config, config.getResourceFilePath());
+ }
+
+
+ private static void deployFromFile(KubernetesClient client, KubernetesTestConfig config, String resourcesFilePath) {
+ if (isNullOrEmpty(resourcesFilePath)) {
+ failNotDeployed();
+ }
+ LOG.info("Loading resources file: " + resourcesFilePath);
+ List resourceList = null;
+
+ try (InputStream resources = new FileInputStream(resourcesFilePath)) {
+ resourceList = client.load(resources).get();
+ } catch (IOException e) {
+ LOG.error("Problem loading resources file {}", resourcesFilePath);
+ failNotDeployed();
+ }
+
+ List deployedResourceList = client.resourceList(resourceList)
+ .inNamespace(config.getNamespace())
+ .createOrReplace();
+
+ LOG.info("Waiting for reources to be ready");
+ deployedResourceList.stream()
+ .filter(supportReadiness)
+ .forEach(resource -> {
+ try {
+ client.resource(resource)
+ .inNamespace(config.getNamespace())
+ .waitUntilReady(config.getKubernetesTimeout(), SECONDS);
+ } catch (InterruptedException e) {
+ LOG.error("Timeout reached waiting for "+resource.getKind()+" with name "+resource.getMetadata().getName()+" to be ready");
+ failNotDeployed();
+ }
+ });
+ LOG.info("Reources are ready Now");
+ }
+
+ private static void createRoleBinding(KubernetesClient client, String sourceNamespace, KubernetesTestConfig config) {
+
+ String targetNamespace = config.getNamespace();
+
+ Subject subject = new SubjectBuilder()
+ .withName("default")
+ .withKind("ServiceAccount")
+ .withNamespace(targetNamespace)
+ .build();
+
+ RoleBindingBuilder roleBindingBuilder = new RoleBindingBuilder();
+ RoleBinding roleBinding = roleBindingBuilder
+ .withKind("RoleBinding")
+ .withApiVersion("rbac.authorization.k8s.io/v1")
+ .withNewMetadata()
+ .withName("ktest-system:image-puller")
+ .withNamespace(sourceNamespace)
+ .withLabels(config.getKtestLabels())
+ .endMetadata()
+ .withSubjects(subject)
+ .withNewRoleRef()
+ .withApiGroup("rbac.authorization.k8s.io")
+ .withKind("ClusterRole")
+ .withName("system:image-puller")
+ .endRoleRef()
+ .build();
+
+ client.rbac().roleBindings().inNamespace(sourceNamespace).createOrReplace(roleBinding);
+ }
+
+ private static void createNamespace(KubernetesClient client, KubernetesTestConfig config) {
+ if (config.isUseExistingNamespace()) {
+ return;
+ }
+ Namespace ns = new NamespaceBuilder().withNewMetadata().withName(config.getNamespace()).endMetadata().build();
+ client.namespaces().create(ns);
+ LOG.info("Namespace " + config.getNamespace() + " created.");
+ }
+
+
+ public static void deleteNamespace(KubernetesClient
+ client, KubernetesTestConfig config) {
+ final CountDownLatch isWatchClosed = new CountDownLatch(1);
+ Watch watch = client.namespaces().withName(config.getNamespace()).watch(new Watcher() {
+ @Override
+ public void eventReceived(Action action, Namespace resource) {
+ if (action.equals(Action.DELETED)) {
+ LOG.debug("Deleted event for namespace {} received", config.getNamespace());
+ isWatchClosed.countDown();
+ }
+ }
+ @Override
+ public void onClose(KubernetesClientException cause) {
+ isWatchClosed.countDown();
+ }
+ });
+ try {
+ if (config.isShouldDestroyNamespace()) {
+ client.namespaces().withName(config.getNamespace()).delete();
+ LOG.info("Waiting for namespace deletion " + config.getNamespace() + " ...");
+ isWatchClosed.await(config.getKubernetesTimeout(), TimeUnit.SECONDS);
+ LOG.info("Namespace - " + config.getNamespace() + " deleted.");
+ }
+ } catch (InterruptedException e) {
+ isWatchClosed.countDown();
+ watch.close();
+ throw new RuntimeException("Timeout reached while waiting for namespace deletion.");
+ }
+ }
+
+ private static void createImageStream(KubernetesClient client, KubernetesTestConfig config) {
+ try (InputStream imageStreamFile = new FileInputStream(config.getImageStreamFilePath())) {
+ List result = client.load(imageStreamFile).get();
+ result = result.stream().peek(
+ x -> {
+ if (x instanceof ImageStream) {
+ ((ImageStream) x).getSpec()
+ .setLookupPolicy(new ImageLookupPolicy(true));
+ }
+ }
+ ).collect(Collectors.toList());
+
+ client.resourceList(result)
+ .inNamespace(config.getNamespace())
+ .createOrReplace();
+ } catch (IOException e) {
+ failNotDeployed();
+ }
+ }
+}
diff --git a/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestSetup.java b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestSetup.java
new file mode 100644
index 0000000..9a62ace
--- /dev/null
+++ b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestSetup.java
@@ -0,0 +1,44 @@
+package io.fabric8.quickstarts.cxf.jaxws.support;
+
+import io.fabric8.kubernetes.client.KubernetesClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestDeployer.deleteNamespace;
+import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestDeployer.deploy;
+
+
+public class KubernetesTestSetup {
+
+ protected static Logger LOG = LoggerFactory.getLogger(KubernetesTestSetup.class);
+
+ private KubernetesTestConfig config;
+
+ private KubernetesClient client;
+
+ public KubernetesTestSetup(KubernetesTestConfig config) {
+ this.config = config;
+ this.client = config.getClient();
+ }
+
+ public void setUp() {
+ LOG.info("Doing setup...");
+ deploy(client, config);
+ LOG.info("setup done.");
+ }
+
+ public void tearDown() {
+ LOG.info("Doing teardown...");
+ if(config.isShouldDestroyNamespace()) {
+ deleteNamespace(client, config);
+ client.rbac()
+ .roleBindings()
+ .inNamespace(config.getMainNamespace())
+ .withLabels(config.getKtestLabels())
+ .delete();
+ }else{
+ LOG.info("Nothing to do!");
+ }
+ LOG.info("Teardown done.");
+ }
+}
diff --git a/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestUtil.java b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestUtil.java
new file mode 100644
index 0000000..a5923bd
--- /dev/null
+++ b/src/test/java/io/fabric8/quickstarts/cxf/jaxws/support/KubernetesTestUtil.java
@@ -0,0 +1,108 @@
+package io.fabric8.quickstarts.cxf.jaxws.support;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTestUtil {
+
+ protected static Logger LOG = LoggerFactory.getLogger(KubernetesTestUtil.class);
+
+
+ public static boolean isNullOrEmpty(String s) {
+ return s == null || s.isEmpty();
+ }
+
+ public static boolean isNullOrEmpty(Collection s) {
+ return s == null || s.isEmpty();
+ }
+
+
+ public static boolean isNullOrEmpty(Object [] s) {
+ return s == null || s.length == 0;
+ }
+
+ public static boolean isNotNullOrEmpty(String s) {
+ return !isNullOrEmpty(s);
+ }
+
+ public static boolean isNotNullOrEmpty(Collection s) {
+ return !isNullOrEmpty(s);
+ }
+
+ public static InputStream getResourceFileAsStream(String fileName) {
+ return KubernetesTestUtil.class.getClassLoader().getResourceAsStream(fileName);
+ }
+
+ public static void failNotDeployed(){
+ String errorMessage = "Error loading resource file. Be sure to run `mvn oc:deploy` before running this integration test.";
+ LOG.error(errorMessage);
+ throw new RuntimeException(errorMessage);
+ }
+
+ public static String getStringProperty(String name, Map map) {
+ return getStringProperty(name, map, null);
+ }
+ public static String getStringProperty(String name, Map map, String defaultValue) {
+ if (map.containsKey(name) && isNotNullOrEmpty(map.get(name))) {
+ defaultValue = map.get(name);
+ }
+ return defaultValue;
+ }
+
+ public static List getArrayListStringProperty(String name, Map map) {
+ if (map.containsKey(name) && isNotNullOrEmpty(map.get(name))) {
+ return Arrays.asList(map.get(name).split(","));
+ }
+ return null;
+ }
+
+ public static int getIntProperty(String name, Map map, int defaultValue) {
+ if (map.containsKey(name) && isNotNullOrEmpty(map.get(name))) {
+ return Integer.parseInt(map.get(name));
+ }
+ return defaultValue;
+ }
+
+ public static Boolean getBooleanProperty(String name, Map map, Boolean defaultValue) {
+ if (map.containsKey(name) && isNotNullOrEmpty(map.get(name))) {
+ defaultValue = Boolean.parseBoolean(map.get(name));
+ }
+ return defaultValue;
+ }
+
+ public static String getArtifactId() throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
+
+ DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+ domFactory.setNamespaceAware(true);
+
+ DocumentBuilder builder = domFactory.newDocumentBuilder();
+ Document doc = builder.parse(new File("./pom.xml"));
+ XPath xpath = XPathFactory.newInstance().newXPath();
+
+ XPathExpression expr = xpath.compile("/*[local-name() = 'project']/*[local-name() = 'artifactId']/text()");
+ Node result = (Node) expr.evaluate(doc, XPathConstants.NODE);
+ String artifactId = result.getTextContent();
+ LOG.info("Detected artifactId: {}", artifactId);
+ return artifactId;
+ }
+
+}
diff --git a/src/test/resources/kubernetesTest.properties b/src/test/resources/kubernetesTest.properties
new file mode 100644
index 0000000..caf44fc
--- /dev/null
+++ b/src/test/resources/kubernetesTest.properties
@@ -0,0 +1,33 @@
+####
+
+### Use current namespace instead creating a new one. Default false
+#kt.namespace.use.current
+
+### Use the namespace specified in this property instead creating a new one.
+#kt.namespace.use.existing
+
+### Delete the namespace at the end of the test. Default true
+#kt.namespace.destroy.enabled
+
+### Use the namespace prefix specified in this property in this property
+### instead the default one "ktest"
+#kt.namespace.prefix
+
+### Install the resources loaded from the specified file path.
+### Default: target/classes/META-INF/jkube/openshift.yml
+#kt.resource.file.path
+
+### The master URI used to login to Kubernetes/Openshift cluster. Autodetected if empty.
+#kubernetes.master
+
+### The username used to login to Kubernetes/Openshift cluster. Autodetected if empty
+#kubernetes.username
+
+### The password used to login to Kubernetes/Openshift cluster. Autodetected if empty
+#kubernetes.password
+
+### How much second the client wait until the newly created resource is ready. Default 60
+#kubernetes.timeout
+
+### Comma separated list of resources file paths to load and deploy before testing.
+#kt.env.dependencies