From 657fedb717056a4ee7cf3e7b00aa2eb4814e878e Mon Sep 17 00:00:00 2001
From: Ioannis Canellos <iocanel@gmail.com>
Date: Tue, 30 Jun 2020 16:10:07 +0300
Subject: [PATCH] fix (#10332): Knative manifest now uses valid port names.

---
 bom/runtime/pom.xml                           |  2 +-
 .../deployment/KubernetesProcessor.java       | 86 ++++++++++++++++---
 .../io/quarkus/it/kubernetes/KnativeTest.java | 25 +++++-
 3 files changed, 97 insertions(+), 16 deletions(-)

diff --git a/bom/runtime/pom.xml b/bom/runtime/pom.xml
index 0cf853e7ebd7c4..38ac38020cdd18 100644
--- a/bom/runtime/pom.xml
+++ b/bom/runtime/pom.xml
@@ -144,7 +144,7 @@
         <aws-alexa-sdk.version>2.30.0</aws-alexa-sdk.version>
         <azure-functions-java-library.version>1.3.0</azure-functions-java-library.version>
         <kotlin.version>1.3.72</kotlin.version>
-        <dekorate.version>0.12.1</dekorate.version>
+        <dekorate.version>0.12.3</dekorate.version>
         <maven-artifact-transfer.version>0.10.0</maven-artifact-transfer.version>
         <jline.version>2.14.6</jline.version>
         <maven-invoker.version>3.0.1</maven-invoker.version>
diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java
index 9fcfc97378fb17..1152d752c15f32 100644
--- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java
+++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java
@@ -1,7 +1,27 @@
 package io.quarkus.kubernetes.deployment;
 
-import static io.quarkus.kubernetes.deployment.Constants.*;
-import static io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem.*;
+import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT;
+import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_S2I_IMAGE_NAME;
+import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT;
+import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT_CONFIG;
+import static io.quarkus.kubernetes.deployment.Constants.HTTP_PORT;
+import static io.quarkus.kubernetes.deployment.Constants.KNATIVE;
+import static io.quarkus.kubernetes.deployment.Constants.KUBERNETES;
+import static io.quarkus.kubernetes.deployment.Constants.MAX_NODE_PORT_VALUE;
+import static io.quarkus.kubernetes.deployment.Constants.MAX_PORT_NUMBER;
+import static io.quarkus.kubernetes.deployment.Constants.MINIKUBE;
+import static io.quarkus.kubernetes.deployment.Constants.MIN_NODE_PORT_VALUE;
+import static io.quarkus.kubernetes.deployment.Constants.MIN_PORT_NUMBER;
+import static io.quarkus.kubernetes.deployment.Constants.OPENSHIFT;
+import static io.quarkus.kubernetes.deployment.Constants.OPENSHIFT_APP_RUNTIME;
+import static io.quarkus.kubernetes.deployment.Constants.QUARKUS;
+import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_BUILD_TIMESTAMP;
+import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_COMMIT_ID;
+import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_VCS_URL;
+import static io.quarkus.kubernetes.deployment.Constants.SERVICE;
+import static io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem.DEFAULT_PRIORITY;
+import static io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem.VANILLA_KUBERNETES_PRIORITY;
+import static io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem.mergeList;
 
 import java.io.File;
 import java.io.IOException;
@@ -9,11 +29,21 @@
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.security.MessageDigest;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 import org.jboss.logging.Logger;
@@ -28,7 +58,28 @@
 import io.dekorate.kubernetes.config.Label;
 import io.dekorate.kubernetes.config.PortBuilder;
 import io.dekorate.kubernetes.configurator.AddPort;
-import io.dekorate.kubernetes.decorator.*;
+import io.dekorate.kubernetes.decorator.AddAnnotationDecorator;
+import io.dekorate.kubernetes.decorator.AddAwsElasticBlockStoreVolumeDecorator;
+import io.dekorate.kubernetes.decorator.AddAzureDiskVolumeDecorator;
+import io.dekorate.kubernetes.decorator.AddAzureFileVolumeDecorator;
+import io.dekorate.kubernetes.decorator.AddConfigMapVolumeDecorator;
+import io.dekorate.kubernetes.decorator.AddEnvVarDecorator;
+import io.dekorate.kubernetes.decorator.AddImagePullSecretDecorator;
+import io.dekorate.kubernetes.decorator.AddInitContainerDecorator;
+import io.dekorate.kubernetes.decorator.AddLabelDecorator;
+import io.dekorate.kubernetes.decorator.AddLivenessProbeDecorator;
+import io.dekorate.kubernetes.decorator.AddMountDecorator;
+import io.dekorate.kubernetes.decorator.AddPvcVolumeDecorator;
+import io.dekorate.kubernetes.decorator.AddReadinessProbeDecorator;
+import io.dekorate.kubernetes.decorator.AddRoleBindingResourceDecorator;
+import io.dekorate.kubernetes.decorator.AddSecretVolumeDecorator;
+import io.dekorate.kubernetes.decorator.AddServiceAccountResourceDecorator;
+import io.dekorate.kubernetes.decorator.ApplyArgsDecorator;
+import io.dekorate.kubernetes.decorator.ApplyCommandDecorator;
+import io.dekorate.kubernetes.decorator.ApplyImagePullPolicyDecorator;
+import io.dekorate.kubernetes.decorator.ApplyServiceAccountNamedDecorator;
+import io.dekorate.kubernetes.decorator.ApplyWorkingDirDecorator;
+import io.dekorate.kubernetes.decorator.RemoveAnnotationDecorator;
 import io.dekorate.processor.SimpleFileReader;
 import io.dekorate.processor.SimpleFileWriter;
 import io.dekorate.project.BuildInfo;
@@ -55,7 +106,15 @@
 import io.quarkus.deployment.pkg.PackageConfig;
 import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
 import io.quarkus.deployment.util.FileUtil;
-import io.quarkus.kubernetes.spi.*;
+import io.quarkus.kubernetes.spi.KubernetesAnnotationBuildItem;
+import io.quarkus.kubernetes.spi.KubernetesCommandBuildItem;
+import io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem;
+import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
+import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
+import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
+import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
+import io.quarkus.kubernetes.spi.KubernetesPortBuildItem;
+import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem;
 
 class KubernetesProcessor {
 
@@ -198,13 +257,13 @@ public void build(ApplicationInfoBuildItem applicationInfo,
         final Map<String, String> generatedResourcesMap;
         // by passing false to SimpleFileWriter, we ensure that no files are actually written during this phase
         Project project = createProject(applicationInfo, artifactPath);
-        final SessionWriter sessionWriter = new SimpleFileWriter(root, false);
+        final SessionWriter sessionWriter = new SimpleFileWriter(project, false);
         final SessionReader sessionReader = new SimpleFileReader(
                 project.getRoot().resolve("src").resolve("main").resolve("kubernetes"), kubernetesDeploymentTargets
                         .getEntriesSortedByPriority().stream()
                         .map(EnabledKubernetesDeploymentTargetsBuildItem.Entry::getName).collect(Collectors.toSet()));
         sessionWriter.setProject(project);
-        final Session session = Session.getSession(new io.dekorate.logger.NoopLogger());
+        final Session session = Session.getSession();
         session.setWriter(sessionWriter);
         session.setReader(sessionReader);
 
@@ -249,21 +308,20 @@ public void build(ApplicationInfoBuildItem applicationInfo,
 
         List<String> generatedFileNames = new ArrayList<>(generatedResourcesMap.size());
         for (Map.Entry<String, String> resourceEntry : generatedResourcesMap.entrySet()) {
-            String fileName = resourceEntry.getKey().replace(root.toAbsolutePath().toString(), "");
-            String relativePath = resourceEntry.getKey().replace(root.toAbsolutePath().toString(), KUBERNETES);
+            Path path = Paths.get(resourceEntry.getKey());
+            String fileName = path.toFile().getName();
+            Path targetPath = outputTarget.getOutputDirectory().resolve(KUBERNETES).resolve(fileName);
+            String relativePath = targetPath.toAbsolutePath().toString().replace(root.toAbsolutePath().toString(), "");
 
+            resourceEntry.getKey().replace(root.toAbsolutePath().toString(), KUBERNETES);
             if (fileName.endsWith(".yml") || fileName.endsWith(".json")) {
                 String target = fileName.substring(0, fileName.lastIndexOf("."));
-                if (target.startsWith(File.separator)) {
-                    target = target.substring(1);
-                }
-
                 if (!deploymentTargets.contains(target)) {
                     continue;
                 }
             }
 
-            generatedFileNames.add(fileName.replace("/", ""));
+            generatedFileNames.add(fileName);
             generatedResourceProducer.produce(
                     new GeneratedFileSystemResourceBuildItem(
                             // we need to make sure we are only passing the relative path to the build item
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeTest.java
index 52cc4d5a7a3cb9..9364ba9e205de8 100644
--- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeTest.java
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeTest.java
@@ -2,13 +2,17 @@
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.io.IOException;
 import java.nio.file.Path;
+import java.util.List;
 
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.JavaArchive;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
+import io.fabric8.knative.serving.v1.Service;
+import io.fabric8.kubernetes.api.model.HasMetadata;
 import io.quarkus.test.ProdBuildResults;
 import io.quarkus.test.ProdModeTestResults;
 import io.quarkus.test.QuarkusProdModeTest;
@@ -26,11 +30,30 @@ public class KnativeTest {
     private ProdModeTestResults prodModeTestResults;
 
     @Test
-    public void assertGeneratedResources() {
+    public void assertGeneratedResources() throws IOException {
         Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
         assertThat(kubernetesDir)
                 .isDirectoryContaining(p -> p.getFileName().endsWith("knative.json"))
                 .isDirectoryContaining(p -> p.getFileName().endsWith("knative.yml"))
                 .satisfies(p -> assertThat(p.toFile().listFiles()).hasSize(2));
+
+        List<HasMetadata> kubernetesList = DeserializationUtil
+                .deserializeAsList(kubernetesDir.resolve("knative.yml"));
+
+        assertThat(kubernetesList).filteredOn(i -> "Service".equals(i.getKind())).hasOnlyOneElementSatisfying(i -> {
+            assertThat(i).isInstanceOfSatisfying(Service.class, s -> {
+                assertThat(s.getSpec()).satisfies(spec -> {
+                    assertThat(spec.getTemplate()).satisfies(template -> {
+                        assertThat(template.getSpec()).satisfies(templateSpec -> {
+                            assertThat(templateSpec.getContainers()).hasSize(1).hasOnlyOneElementSatisfying(c -> {
+                                assertThat(c.getPorts()).hasSize(1).hasOnlyOneElementSatisfying(p -> {
+                                    assertThat(p.getName()).isEqualTo("http1");
+                                });
+                            });
+                        });
+                    });
+                });
+            });
+        });
     }
 }