This is an automated email from the ASF dual-hosted git repository. nferraro pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit a8f8db916698a2f6578aea5143bbe2e4749857f6 Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Mon Mar 16 18:01:38 2020 +0100 Set default for rest based services #1347 #1347 --- pkg/metadata/metadata_dependencies_test.go | 13 ++++- pkg/trait/container.go | 42 ++++++++++++++- pkg/trait/cron.go | 12 +---- pkg/trait/cron_test.go | 18 +------ pkg/trait/dependencies.go | 12 +++++ pkg/trait/dependencies_test.go | 87 +++++++++++++++++++++++++++++- pkg/trait/openapi.go | 50 +++-------------- pkg/trait/openapi_test.go | 50 ----------------- pkg/util/source/inspector_groovy.go | 3 ++ pkg/util/source/inspector_java_script.go | 7 ++- pkg/util/source/inspector_java_source.go | 7 ++- pkg/util/source/inspector_kotlin.go | 3 ++ pkg/util/source/inspector_xml.go | 2 +- pkg/util/source/inspector_yaml.go | 2 +- pkg/util/source/types.go | 10 ++-- 15 files changed, 187 insertions(+), 131 deletions(-) diff --git a/pkg/metadata/metadata_dependencies_test.go b/pkg/metadata/metadata_dependencies_test.go index fe5c0e9..b0973e1 100644 --- a/pkg/metadata/metadata_dependencies_test.go +++ b/pkg/metadata/metadata_dependencies_test.go @@ -561,10 +561,11 @@ func TestXMLRestDependency(t *testing.T) { t, []string{ "camel:direct", - "camel:rest", "camel:mock", }, meta.Dependencies.List()) + + assert.True(t, meta.RequiredCapabilities.Has("rest")) } func TestXMLLanguageDependencies(t *testing.T) { @@ -683,7 +684,15 @@ func TestYAMLRestDependency(t *testing.T) { meta := Extract(catalog, code) - assert.ElementsMatch(t, []string{"camel:direct", "camel:rest", "camel:log"}, meta.Dependencies.List()) + assert.ElementsMatch( + t, + []string{ + "camel:direct", + "camel:log", + }, + meta.Dependencies.List()) + + assert.True(t, meta.RequiredCapabilities.Has("rest")) } func TestYAMLHystrixDependency(t *testing.T) { diff --git a/pkg/trait/container.go b/pkg/trait/container.go index 6028936..a172543 100644 --- a/pkg/trait/container.go +++ b/pkg/trait/container.go @@ -43,6 +43,18 @@ const ( defaultServicePort = 80 defaultProbePath = "/health" containerTraitID = "container" + + // CamelRestPortProperty --- + CamelRestPortProperty = "camel.context.rest-configuration.port" + // CamelRestDefaultPort --- + CamelRestDefaultPort = "8080" + + // CamelRestComponentProperty --- + CamelRestComponentProperty = "camel.context.rest-configuration.component" + // CamelRestDefaultComponentMain --- + CamelRestDefaultComponentMain = "undertow" + // CamelRestDefaultComponentQuarkus --- + CamelRestDefaultComponentQuarkus = "platform-http" ) // The Container trait can be used to configure properties of the container where the integration will run. @@ -169,7 +181,7 @@ func (t *containerTrait) configureDependencies(e *Environment) { } if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) { - if capability, ok := e.CamelCatalog.Runtime.Capabilities["health"]; ok { + if capability, ok := e.CamelCatalog.Runtime.Capabilities[v1.CapabilityHealth]; ok { for _, dependency := range capability.Dependencies { util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, fmt.Sprintf("mvn:%s/%s", dependency.GroupID, dependency.ArtifactID)) } @@ -204,6 +216,10 @@ func (t *containerTrait) configureContainer(e *Environment) error { t.configureService(e, &container) } + if err := t.configureCapabilities(e); err != nil { + return err + } + // // Deployment // @@ -414,6 +430,30 @@ func (t *containerTrait) configureResources(_ *Environment, container *corev1.Co } } } + +func (t *containerTrait) configureCapabilities(e *Environment) error { + if !util.StringSliceExists(e.Integration.Status.Capabilities, v1.CapabilityRest) { + return nil + } + + if e.ApplicationProperties == nil { + e.ApplicationProperties = make(map[string]string) + } + + switch e.CamelCatalog.Runtime.Provider { + case v1.RuntimeProviderMain: + e.ApplicationProperties[CamelRestPortProperty] = CamelRestDefaultPort + e.ApplicationProperties[CamelRestComponentProperty] = CamelRestDefaultComponentMain + case v1.RuntimeProviderQuarkus: + // On quarkus, the rest endpoint is bound to the platform http service + e.ApplicationProperties[CamelRestComponentProperty] = CamelRestDefaultComponentQuarkus + default: + return fmt.Errorf("unsupported runtime: %s", e.CamelCatalog.Runtime.Provider) + } + + return nil +} + func (t *containerTrait) configureProbes(e *Environment, container *corev1.Container, port int, path string) error { if e.ApplicationProperties == nil { e.ApplicationProperties = make(map[string]string) diff --git a/pkg/trait/cron.go b/pkg/trait/cron.go index 6b6ac85..6d4d332 100644 --- a/pkg/trait/cron.go +++ b/pkg/trait/cron.go @@ -20,7 +20,6 @@ package trait import ( "fmt" "regexp" - "sort" "strconv" "strings" @@ -129,7 +128,7 @@ func (t *cronTrait) Configure(e *Environment) (bool, error) { return false, nil } - if _, ok := e.CamelCatalog.Runtime.Capabilities["cron"]; !ok { + if _, ok := e.CamelCatalog.Runtime.Capabilities[v1.CapabilityCron]; !ok { e.Integration.Status.SetCondition( v1.IntegrationConditionCronJobAvailable, corev1.ConditionFalse, @@ -234,14 +233,7 @@ func (t *cronTrait) Configure(e *Environment) (bool, error) { func (t *cronTrait) Apply(e *Environment) error { if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) { - if capability, ok := e.CamelCatalog.Runtime.Capabilities["cron"]; ok { - for _, dependency := range capability.Dependencies { - util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, fmt.Sprintf("mvn:%s/%s", dependency.GroupID, dependency.ArtifactID)) - } - - // sort the dependencies to get always the same list if they don't change - sort.Strings(e.Integration.Status.Dependencies) - } + util.StringSliceUniqueAdd(&e.Integration.Status.Capabilities, v1.CapabilityCron) if t.Fallback != nil && *t.Fallback { util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, genericCronComponentFallback) diff --git a/pkg/trait/cron_test.go b/pkg/trait/cron_test.go index c077fe2..a12aaab 100644 --- a/pkg/trait/cron_test.go +++ b/pkg/trait/cron_test.go @@ -19,7 +19,6 @@ package trait import ( "context" - "fmt" "strings" "testing" @@ -286,13 +285,7 @@ func TestCronDeps(t *testing.T) { ct := environment.GetTrait("cron").(*cronTrait) assert.NotNil(t, ct) assert.Nil(t, ct.Fallback) - - capability, ok := environment.CamelCatalog.Runtime.Capabilities["cron"] - assert.True(t, ok) - - for _, dependency := range capability.Dependencies { - assert.True(t, util.StringSliceExists(environment.Integration.Status.Dependencies, fmt.Sprintf("mvn:%s/%s", dependency.GroupID, dependency.ArtifactID))) - } + assert.True(t, util.StringSliceExists(environment.Integration.Status.Capabilities, v1.CapabilityCron)) } func TestCronDepsFallback(t *testing.T) { @@ -367,14 +360,7 @@ func TestCronDepsFallback(t *testing.T) { ct := environment.GetTrait("cron").(*cronTrait) assert.NotNil(t, ct) assert.NotNil(t, ct.Fallback) - - capability, ok := environment.CamelCatalog.Runtime.Capabilities["cron"] - assert.True(t, ok) - - for _, dependency := range capability.Dependencies { - assert.True(t, util.StringSliceExists(environment.Integration.Status.Dependencies, fmt.Sprintf("mvn:%s/%s", dependency.GroupID, dependency.ArtifactID))) - } - + assert.True(t, util.StringSliceExists(environment.Integration.Status.Capabilities, v1.CapabilityCron)) assert.True(t, util.StringSliceExists(environment.Integration.Status.Dependencies, genericCronComponentFallback)) } diff --git a/pkg/trait/dependencies.go b/pkg/trait/dependencies.go index 79d5ecc..7d7e010 100644 --- a/pkg/trait/dependencies.go +++ b/pkg/trait/dependencies.go @@ -89,12 +89,24 @@ func (t *dependenciesTrait) Apply(e *Environment) error { } } } + + meta.RequiredCapabilities.Each(func(item string) bool { + util.StringSliceUniqueAdd(&e.Integration.Status.Capabilities, item) + return true + }) } for _, dependency := range e.Integration.Spec.Dependencies { util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, dependency) } + // add runtime specific dependencies + for _, capability := range e.Integration.Status.Capabilities { + for _, dependency := range e.CamelCatalog.Runtime.CapabilityDependencies(capability) { + util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, fmt.Sprintf("mvn:%s/%s", dependency.GroupID, dependency.ArtifactID)) + } + } + // add dependencies back to integration dependencies.Each(func(item string) bool { util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, item) diff --git a/pkg/trait/dependencies_test.go b/pkg/trait/dependencies_test.go index 8a376e2..d227d2f 100644 --- a/pkg/trait/dependencies_test.go +++ b/pkg/trait/dependencies_test.go @@ -185,7 +185,8 @@ func TestIntegrationAutoGeneratedDeps(t *testing.T) { []string{ "camel:direct", "camel:log", - "camel:rest", + "mvn:org.apache.camel/camel-rest", + "mvn:org.apache.camel/camel-undertow", "mvn:org.apache.camel.k/camel-k-loader-java", "mvn:org.apache.camel.k/camel-k-loader-xml", "mvn:org.apache.camel.k/camel-k-runtime-main"}, @@ -238,3 +239,87 @@ func TestIntegrationCustomLoader(t *testing.T) { e.Integration.Status.Dependencies, ) } + +func TestRestDeps(t *testing.T) { + catalog, err := camel.DefaultCatalog() + assert.Nil(t, err) + + e := &Environment{ + Catalog: NewEnvironmentTestCatalog(), + CamelCatalog: catalog, + Integration: &v1.Integration{ + Spec: v1.IntegrationSpec{ + Sources: []v1.SourceSpec{ + { + DataSpec: v1.DataSpec{ + Name: "flow.java", + Content: `rest().to("log:bar");`, + }, + Language: v1.LanguageJavaSource, + }, + }, + }, + Status: v1.IntegrationStatus{ + Phase: v1.IntegrationPhaseInitialization, + }, + }, + } + + trait := newDependenciesTrait() + enabled, err := trait.Configure(e) + assert.Nil(t, err) + assert.True(t, enabled) + + err = trait.Apply(e) + assert.Nil(t, err) + assert.Subset( + t, + e.Integration.Status.Dependencies, + []string{ + "mvn:org.apache.camel/camel-rest", + "mvn:org.apache.camel/camel-undertow", + }, + ) +} + +func TestRestDepsQuarkus(t *testing.T) { + catalog, err := camel.QuarkusCatalog() + assert.Nil(t, err) + + e := &Environment{ + Catalog: NewEnvironmentTestCatalog(), + CamelCatalog: catalog, + Integration: &v1.Integration{ + Spec: v1.IntegrationSpec{ + Sources: []v1.SourceSpec{ + { + DataSpec: v1.DataSpec{ + Name: "flow.java", + Content: `rest().route().to("log:bar");`, + }, + Language: v1.LanguageJavaSource, + }, + }, + }, + Status: v1.IntegrationStatus{ + Phase: v1.IntegrationPhaseInitialization, + }, + }, + } + + trait := newDependenciesTrait() + enabled, err := trait.Configure(e) + assert.Nil(t, err) + assert.True(t, enabled) + + err = trait.Apply(e) + assert.Nil(t, err) + assert.Subset( + t, + e.Integration.Status.Dependencies, + []string{ + "mvn:org.apache.camel.quarkus/camel-quarkus-rest", + "mvn:org.apache.camel.quarkus/camel-quarkus-platform-http", + }, + ) +} diff --git a/pkg/trait/openapi.go b/pkg/trait/openapi.go index af40121..10d7828 100644 --- a/pkg/trait/openapi.go +++ b/pkg/trait/openapi.go @@ -24,16 +24,16 @@ import ( "os" "path" "path/filepath" - "sort" "strconv" "strings" + "github.com/apache/camel-k/pkg/util" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "github.com/apache/camel-k/pkg/apis/camel/v1" - "github.com/apache/camel-k/pkg/util" "github.com/apache/camel-k/pkg/util/defaults" "github.com/apache/camel-k/pkg/util/gzip" "github.com/apache/camel-k/pkg/util/kubernetes" @@ -43,12 +43,6 @@ import ( // OpenAPITraitName --- const OpenAPITraitName = "openapi" -// CamelRestPortProperty --- -const CamelRestPortProperty = "camel.context.rest-configuration.port" - -// CamelRestDefaultPort --- -const CamelRestDefaultPort = "8080" - // The OpenAPI DSL trait is internally used to allow creating integrations from a OpenAPI specs. // // +camel-k:trait=openapi @@ -77,17 +71,13 @@ func (t *openAPITrait) Configure(e *Environment) (bool, error) { } // check if the runtime provides 'rest' capabilities - if _, ok := e.CamelCatalog.Runtime.Capabilities["rest"]; !ok { - t.L.Infof("the runtime provider %s does not declare 'rest' capability", e.CamelCatalog.Runtime.Provider) + if _, ok := e.CamelCatalog.Runtime.Capabilities[v1.CapabilityRest]; !ok { + return false, fmt.Errorf("the runtime provider %s does not declare 'rest' capability", e.CamelCatalog.Runtime.Provider) } for _, resource := range e.Integration.Spec.Resources { if resource.Type == v1.ResourceTypeOpenAPI { - return e.IntegrationInPhase( - v1.IntegrationPhaseInitialization, - v1.IntegrationPhaseDeploying, - v1.IntegrationPhaseRunning, - ), nil + return e.IntegrationInPhase(v1.IntegrationPhaseInitialization), nil } } @@ -95,24 +85,8 @@ func (t *openAPITrait) Configure(e *Environment) (bool, error) { } func (t *openAPITrait) Apply(e *Environment) error { - if len(e.Integration.Spec.Resources) == 0 { - return nil - } - - if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) { - t.computeDependencies(e) - return t.generateRestDSL(e) - } - - if e.IntegrationInPhase(v1.IntegrationPhaseDeploying, v1.IntegrationPhaseRunning) { - e.ApplicationProperties[CamelRestPortProperty] = CamelRestDefaultPort - return nil - } + util.StringSliceUniqueAdd(&e.Integration.Status.Capabilities, v1.CapabilityRest) - return nil -} - -func (t *openAPITrait) generateRestDSL(e *Environment) error { root := os.TempDir() tmpDir, err := ioutil.TempDir(root, "openapi") if err != nil { @@ -278,15 +252,3 @@ func (t *openAPITrait) generateMavenProject(e *Environment) (maven.Project, erro return p, nil } - -func (t *openAPITrait) computeDependencies(e *Environment) { - // check if the runtime provides 'rest' capabilities - if capability, ok := e.CamelCatalog.Runtime.Capabilities["rest"]; ok { - for _, dependency := range capability.Dependencies { - util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, fmt.Sprintf("mvn:%s/%s", dependency.GroupID, dependency.ArtifactID)) - } - - // sort the dependencies to get always the same list if they don't change - sort.Strings(e.Integration.Status.Dependencies) - } -} diff --git a/pkg/trait/openapi_test.go b/pkg/trait/openapi_test.go index 791fbc5..dc09c01 100644 --- a/pkg/trait/openapi_test.go +++ b/pkg/trait/openapi_test.go @@ -62,53 +62,3 @@ func TestRestDslTraitApplicability(t *testing.T) { assert.Nil(t, err) assert.True(t, enabled) } - -func TestRestDslTraitDeps(t *testing.T) { - catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) - - e := &Environment{ - CamelCatalog: catalog, - Integration: &v1.Integration{ - Spec: v1.IntegrationSpec{ - Resources: []v1.ResourceSpec{ - {Type: v1.ResourceTypeOpenAPI}, - }, - }, - Status: v1.IntegrationStatus{ - Phase: v1.IntegrationPhaseInitialization, - }, - }, - } - - trait := newOpenAPITrait().(*openAPITrait) - trait.computeDependencies(e) - - assert.Contains(t, e.Integration.Status.Dependencies, "mvn:org.apache.camel/camel-rest") - assert.Contains(t, e.Integration.Status.Dependencies, "mvn:org.apache.camel/camel-undertow") -} - -func TestRestDslTraitDepsQuarkus(t *testing.T) { - catalog, err := camel.QuarkusCatalog() - assert.Nil(t, err) - - e := &Environment{ - CamelCatalog: catalog, - Integration: &v1.Integration{ - Spec: v1.IntegrationSpec{ - Resources: []v1.ResourceSpec{ - {Type: v1.ResourceTypeOpenAPI}, - }, - }, - Status: v1.IntegrationStatus{ - Phase: v1.IntegrationPhaseInitialization, - }, - }, - } - - trait := newOpenAPITrait().(*openAPITrait) - trait.computeDependencies(e) - - assert.Contains(t, e.Integration.Status.Dependencies, "mvn:org.apache.camel.quarkus/camel-quarkus-rest") - assert.Contains(t, e.Integration.Status.Dependencies, "mvn:org.apache.camel.quarkus/camel-quarkus-platform-http") -} diff --git a/pkg/util/source/inspector_groovy.go b/pkg/util/source/inspector_groovy.go index a37bfc0..9f705c3 100644 --- a/pkg/util/source/inspector_groovy.go +++ b/pkg/util/source/inspector_groovy.go @@ -50,6 +50,9 @@ func (i GroovyInspector) Extract(source v1.SourceSpec, meta *Metadata) error { i.discoverDependencies(source, meta) hasRest := restRegexp.MatchString(source.Content) || restClosureRegexp.MatchString(source.Content) + if hasRest { + meta.RequiredCapabilities.Add(v1.CapabilityRest) + } meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs) meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs) diff --git a/pkg/util/source/inspector_java_script.go b/pkg/util/source/inspector_java_script.go index f79dd3a..dc5be41 100644 --- a/pkg/util/source/inspector_java_script.go +++ b/pkg/util/source/inspector_java_script.go @@ -49,7 +49,12 @@ func (i JavaScriptInspector) Extract(source v1.SourceSpec, meta *Metadata) error i.discoverDependencies(source, meta) - meta.ExposesHTTPServices = restRegexp.MatchString(source.Content) || i.containsHTTPURIs(meta.FromURIs) + hasRest := restRegexp.MatchString(source.Content) + if hasRest { + meta.RequiredCapabilities.Add(v1.CapabilityRest) + } + + meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs) meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs) return nil diff --git a/pkg/util/source/inspector_java_source.go b/pkg/util/source/inspector_java_source.go index 32bd0b0..e548267 100644 --- a/pkg/util/source/inspector_java_source.go +++ b/pkg/util/source/inspector_java_source.go @@ -45,7 +45,12 @@ func (i JavaSourceInspector) Extract(source v1.SourceSpec, meta *Metadata) error i.discoverDependencies(source, meta) - meta.ExposesHTTPServices = restRegexp.MatchString(source.Content) || i.containsHTTPURIs(meta.FromURIs) + hasRest := restRegexp.MatchString(source.Content) + if hasRest { + meta.RequiredCapabilities.Add(v1.CapabilityRest) + } + + meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs) meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs) return nil diff --git a/pkg/util/source/inspector_kotlin.go b/pkg/util/source/inspector_kotlin.go index b949318..4a405ce 100644 --- a/pkg/util/source/inspector_kotlin.go +++ b/pkg/util/source/inspector_kotlin.go @@ -46,6 +46,9 @@ func (i KotlinInspector) Extract(source v1.SourceSpec, meta *Metadata) error { i.discoverDependencies(source, meta) hasRest := restRegexp.MatchString(source.Content) || restClosureRegexp.MatchString(source.Content) + if hasRest { + meta.RequiredCapabilities.Add(v1.CapabilityRest) + } meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs) meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs) diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go index 48777de..f9f2ab6 100644 --- a/pkg/util/source/inspector_xml.go +++ b/pkg/util/source/inspector_xml.go @@ -44,8 +44,8 @@ func (i XMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error { if se, ok := t.(xml.StartElement); ok { switch se.Name.Local { case "rest", "restConfiguration": - i.addDependency("camel:rest", meta) meta.ExposesHTTPServices = true + meta.RequiredCapabilities.Add(v1.CapabilityRest) case "circuitBreaker": i.addDependency("camel:hystrix", meta) case "language": diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go index e42eb38..8ddf8c3 100644 --- a/pkg/util/source/inspector_yaml.go +++ b/pkg/util/source/inspector_yaml.go @@ -58,8 +58,8 @@ func (inspector YAMLInspector) Extract(source v1.SourceSpec, meta *Metadata) err func (inspector YAMLInspector) parseStep(key string, content interface{}, meta *Metadata) error { switch key { case "rest": - inspector.addDependency("camel:rest", meta) meta.ExposesHTTPServices = true + meta.RequiredCapabilities.Add(v1.CapabilityRest) case "circuitBreaker": inspector.addDependency("camel:hystrix", meta) } diff --git a/pkg/util/source/types.go b/pkg/util/source/types.go index 1802917..f6f15e0 100644 --- a/pkg/util/source/types.go +++ b/pkg/util/source/types.go @@ -34,13 +34,17 @@ type Metadata struct { // are activated from external calls, including HTTP (useful to determine if the // integration can scale to 0) PassiveEndpoints bool + // RequiredCapabilities lists the capabilities required by the integration + // to run + RequiredCapabilities *strset.Set } // NewMetadata -- func NewMetadata() Metadata { return Metadata{ - FromURIs: make([]string, 0), - ToURIs: make([]string, 0), - Dependencies: strset.New(), + FromURIs: make([]string, 0), + ToURIs: make([]string, 0), + Dependencies: strset.New(), + RequiredCapabilities: strset.New(), } }