This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git


The following commit(s) were added to refs/heads/main by this push:
     new e518ffb94 fix(trait): sourceless openapi
e518ffb94 is described below

commit e518ffb949ba55b3682f0f90fa1a312fc5b903da
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Fri Jul 26 16:12:52 2024 +0200

    fix(trait): sourceless openapi
    
    Ref #5680
---
 pkg/trait/openapi.go      |  53 +++++----------
 pkg/trait/openapi_test.go | 165 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 183 insertions(+), 35 deletions(-)

diff --git a/pkg/trait/openapi.go b/pkg/trait/openapi.go
index 2f2d351cc..cb201d080 100644
--- a/pkg/trait/openapi.go
+++ b/pkg/trait/openapi.go
@@ -19,7 +19,6 @@ package trait
 
 import (
        "context"
-       "errors"
        "fmt"
        "os"
        "path/filepath"
@@ -32,7 +31,6 @@ import (
        corev1 "k8s.io/api/core/v1"
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-       "k8s.io/apimachinery/pkg/runtime/schema"
 
        ctrl "sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -67,13 +65,6 @@ func (t *openAPITrait) Configure(e *Environment) (bool, 
*TraitCondition, error)
        if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
                return false, nil, nil
        }
-       if e.CamelCatalog == nil {
-               return false, 
NewIntegrationConditionPlatformDisabledCatalogMissing(), nil
-       }
-       // check if the runtime provides 'rest' capabilities
-       if _, ok := e.CamelCatalog.Runtime.Capabilities[v1.CapabilityRest]; !ok 
{
-               return false, nil, fmt.Errorf("the runtime provider %s does not 
declare 'rest' capability", e.CamelCatalog.Runtime.Provider)
-       }
 
        if t.Configmaps != nil {
                return e.IntegrationInPhase(v1.IntegrationPhaseInitialization), 
nil, nil
@@ -104,24 +95,18 @@ func (t *openAPITrait) Apply(e *Environment) error {
 func (t *openAPITrait) generateFromConfigmaps(e *Environment, tmpDir string) 
([]v1.SourceSpec, error) {
        dataSpecs := make([]v1.DataSpec, 0, len(t.Configmaps))
        for _, configmap := range t.Configmaps {
-               // verify if it was autogenerated
-               cm, err := kubernetes.GetUnstructured(e.Ctx, e.Client, 
schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ConfigMap"},
-                       configmap, e.Integration.Namespace)
-               if err == nil && cm != nil && 
cm.GetLabels()[kubernetes.ConfigMapAutogenLabel] == boolean.TrueString {
-                       refCm := 
kubernetes.NewConfigMap(e.Integration.Namespace, configmap, "", "", "", nil)
-                       e.Resources.Add(refCm)
+               cm := kubernetes.LookupConfigmap(e.Ctx, e.Client, 
e.Integration.Namespace, configmap)
+               if cm == nil {
+                       return nil, fmt.Errorf("configmap %s does not exist in 
namespace %s", configmap, e.Integration.Namespace)
                }
                // Iterate over each configmap key which may hold a different 
OpenAPI spec
-               if dataMap, ok := 
cm.UnstructuredContent()["data"].(map[string]interface{}); ok {
-                       for k, v := range dataMap {
-                               if content, ok := v.(string); ok {
-                                       dataSpecs = append(dataSpecs, 
v1.DataSpec{
-                                               Name:        k,
-                                               Content:     content,
-                                               Compression: false,
-                                       })
-                               }
-                       }
+               for k, v := range cm.Data {
+                       dataSpecs = append(dataSpecs, v1.DataSpec{
+                               Name:        k,
+                               Content:     v,
+                               Compression: false,
+                       })
+
                }
        }
 
@@ -217,11 +202,13 @@ func (t *openAPITrait) createNewOpenAPIConfigMap(e 
*Environment, resource v1.Dat
                return err
        }
 
-       project, err := t.generateMavenProject(e)
-       if err != nil {
-               return err
+       // If the catalog is missing, we use the default version used by the 
IntegrationPlatform
+       runtimeVersion := e.Platform.Status.Build.RuntimeVersion
+       if e.CamelCatalog != nil {
+               runtimeVersion = e.CamelCatalog.Runtime.Version
        }
 
+       project := t.generateMavenProject(runtimeVersion)
        mc := maven.NewContext(tmpDir)
        mc.LocalRepository = e.Platform.Status.Build.Maven.LocalRepository
        mc.AdditionalArguments = e.Platform.Status.Build.Maven.CLIOptions
@@ -320,11 +307,7 @@ func (t *openAPITrait) createNewOpenAPIConfigMap(e 
*Environment, resource v1.Dat
        return nil
 }
 
-func (t *openAPITrait) generateMavenProject(e *Environment) (maven.Project, 
error) {
-       if e.CamelCatalog == nil {
-               return maven.Project{}, errors.New("unknown camel catalog")
-       }
-
+func (t *openAPITrait) generateMavenProject(runtimeVersion string) 
maven.Project {
        p := maven.NewProjectWithGAV("org.apache.camel.k.integration", 
"camel-k-rest-dsl-generator", defaults.Version)
        p.Build = &maven.Build{
                DefaultGoal: "generate-resources",
@@ -332,7 +315,7 @@ func (t *openAPITrait) generateMavenProject(e *Environment) 
(maven.Project, erro
                        {
                                GroupID:    "org.apache.camel.k",
                                ArtifactID: "camel-k-maven-plugin",
-                               Version:    e.CamelCatalog.Runtime.Version,
+                               Version:    runtimeVersion,
                                Executions: []maven.Execution{
                                        {
                                                Phase: "generate-resources",
@@ -345,5 +328,5 @@ func (t *openAPITrait) generateMavenProject(e *Environment) 
(maven.Project, erro
                },
        }
 
-       return p, nil
+       return p
 }
diff --git a/pkg/trait/openapi_test.go b/pkg/trait/openapi_test.go
index 8619d6d83..2feff0ca1 100644
--- a/pkg/trait/openapi_test.go
+++ b/pkg/trait/openapi_test.go
@@ -18,9 +18,17 @@ limitations under the License.
 package trait
 
 import (
+       "context"
+       "os"
        "testing"
+       "time"
 
+       "github.com/apache/camel-k/v2/pkg/util/boolean"
        "github.com/apache/camel-k/v2/pkg/util/camel"
+       "github.com/apache/camel-k/v2/pkg/util/kubernetes"
+       "github.com/apache/camel-k/v2/pkg/util/test"
+       corev1 "k8s.io/api/core/v1"
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
 
@@ -65,3 +73,160 @@ func TestRestDslTraitApplicability(t *testing.T) {
        assert.True(t, enabled)
        assert.Nil(t, condition)
 }
+
+func TestRestDslTraitApplyError(t *testing.T) {
+       catalog, err := camel.DefaultCatalog()
+       require.NoError(t, err)
+       fakeClient, _ := test.NewFakeClient()
+
+       e := &Environment{
+               CamelCatalog: catalog,
+               Client:       fakeClient,
+       }
+
+       trait, _ := newOpenAPITrait().(*openAPITrait)
+       enabled, condition, err := trait.Configure(e)
+       require.NoError(t, err)
+       assert.False(t, enabled)
+       assert.Nil(t, condition)
+
+       e.Integration = &v1.Integration{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "hello",
+                       Namespace: "default",
+               },
+               Status: v1.IntegrationStatus{
+                       Phase: v1.IntegrationPhaseInitialization,
+               },
+       }
+
+       trait.Configmaps = []string{"my-configmap"}
+
+       err = trait.Apply(e)
+       require.Error(t, err)
+       assert.Equal(t, "configmap my-configmap does not exist in namespace 
default", err.Error())
+}
+
+var openapi = `
+{
+  "swagger" : "2.0",
+  "info" : {
+    "version" : "1.0",
+    "title" : "Greeting REST API"
+  },
+  "host" : "",
+  "basePath" : "/camel/",
+  "tags" : [ {
+    "name" : "greetings",
+    "description" : "Greeting to {name}"
+  } ],
+  "schemes" : [ "http" ],
+  "paths" : {
+    "/greetings/{name}" : {
+      "get" : {
+        "tags" : [ "greetings" ],
+        "operationId" : "greeting-api",
+        "parameters" : [ {
+          "name" : "name",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "Output type",
+            "schema" : {
+              "$ref" : "#/definitions/Greetings"
+            }
+          }
+        }
+      }
+    }
+  },
+  "definitions" : {
+    "Greetings" : {
+      "type" : "object",
+      "properties" : {
+        "greetings" : {
+          "type" : "string"
+        }
+      }
+    }
+  }
+}
+`
+
+func TestRestDslTraitApplyWorks(t *testing.T) {
+       catalog, err := camel.DefaultCatalog()
+       require.NoError(t, err)
+       fakeClient, _ := test.NewFakeClient(&corev1.ConfigMap{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "my-configmap",
+                       Namespace: "default",
+               },
+               Data: map[string]string{
+                       "greetings-api.json": openapi,
+               },
+       })
+
+       e := &Environment{
+               Ctx:          context.Background(),
+               CamelCatalog: catalog,
+               Client:       fakeClient,
+               Platform: &v1.IntegrationPlatform{
+                       Spec: v1.IntegrationPlatformSpec{
+                               Cluster: 
v1.IntegrationPlatformClusterKubernetes,
+                       },
+                       Status: v1.IntegrationPlatformStatus{
+                               IntegrationPlatformSpec: 
v1.IntegrationPlatformSpec{
+                                       Cluster: 
v1.IntegrationPlatformClusterKubernetes,
+                                       Build: v1.IntegrationPlatformBuildSpec{
+                                               PublishStrategy: 
v1.IntegrationPlatformBuildPublishStrategyJib,
+                                               Registry:        
v1.RegistrySpec{Address: "registry"},
+                                               RuntimeVersion:  
catalog.Runtime.Version,
+                                               Maven:           v1.MavenSpec{},
+                                               Timeout:         
&metav1.Duration{Duration: time.Minute},
+                                       },
+                               },
+                               Phase: v1.IntegrationPlatformPhaseReady,
+                       },
+               },
+               Resources: kubernetes.NewCollection(),
+       }
+
+       trait, _ := newOpenAPITrait().(*openAPITrait)
+       trait.Client = fakeClient
+       enabled, condition, err := trait.Configure(e)
+       require.NoError(t, err)
+       assert.False(t, enabled)
+       assert.Nil(t, condition)
+
+       e.Integration = &v1.Integration{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      "hello",
+                       Namespace: "default",
+               },
+               Status: v1.IntegrationStatus{
+                       Phase: v1.IntegrationPhaseInitialization,
+               },
+       }
+
+       trait.Configmaps = []string{"my-configmap"}
+
+       // use local Maven executable in tests
+       t.Setenv("MAVEN_WRAPPER", boolean.FalseString)
+       _, ok := os.LookupEnv("MAVEN_CMD")
+       if !ok {
+               t.Setenv("MAVEN_CMD", "mvn")
+       }
+
+       err = trait.Apply(e)
+       require.NoError(t, err)
+
+       assert.Equal(t, 1, e.Resources.Size())
+       sourceCm := e.Resources.GetConfigMap(func(cm *corev1.ConfigMap) bool {
+               return cm.Name == "hello-openapi-000"
+       })
+       assert.NotNil(t, sourceCm)
+       assert.Contains(t, sourceCm.Data["content"], "get id=\"greeting-api\" 
path=\"/greetings/{name}")
+}

Reply via email to