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