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 220796920ae3fcb752938e8e8da108a92184cd4d
Author: nicolaferraro <ni.ferr...@gmail.com>
AuthorDate: Mon Nov 16 10:58:09 2020 +0100

    Fix #1562: support dependency scopes
---
 addons/master/master.go                         |  1 +
 deploy/camel-catalog-1.6.0-SNAPSHOT.yaml        |  8 +++
 pkg/apis/camel/v1/camelcatalog_types.go         | 13 ++++-
 pkg/apis/camel/v1/camelcatalog_types_support.go | 54 ++++++++++++++++++
 pkg/trait/cron.go                               |  1 +
 pkg/util/source/inspector.go                    | 37 +++++++++----
 pkg/util/source/inspector_yaml_test.go          | 74 +++++++++++++++++++++++++
 7 files changed, 175 insertions(+), 13 deletions(-)

diff --git a/addons/master/master.go b/addons/master/master.go
index bd69f22..7f00b35 100644
--- a/addons/master/master.go
+++ b/addons/master/master.go
@@ -194,6 +194,7 @@ func findAdditionalDependencies(e *trait.Environment, meta 
metadata.IntegrationM
                                childComponent := strings.ReplaceAll(parts[2], 
"/", "")
                                if artifact := 
e.CamelCatalog.GetArtifactByScheme(childComponent); artifact != nil {
                                        dependencies = append(dependencies, 
artifact.GetDependencyID())
+                                       dependencies = append(dependencies, 
artifact.GetConsumerDependencyIDs(childComponent)...)
                                }
                        }
                }
diff --git a/deploy/camel-catalog-1.6.0-SNAPSHOT.yaml 
b/deploy/camel-catalog-1.6.0-SNAPSHOT.yaml
index 6740a0d..56f15aa 100644
--- a/deploy/camel-catalog-1.6.0-SNAPSHOT.yaml
+++ b/deploy/camel-catalog-1.6.0-SNAPSHOT.yaml
@@ -2842,6 +2842,14 @@ spec:
       - id: knative
         http: true
         passive: false
+        producer:
+          dependencies:
+          - groupId: org.apache.camel.k
+            artifactId: camel-k-knative-producer
+        consumer:
+          dependencies:
+          - groupId: org.apache.camel.k
+            artifactId: camel-k-knative-consumer
     camel-k-master:
       groupId: org.apache.camel.k
       artifactId: camel-k-master
diff --git a/pkg/apis/camel/v1/camelcatalog_types.go 
b/pkg/apis/camel/v1/camelcatalog_types.go
index 89bceb9..e824943 100644
--- a/pkg/apis/camel/v1/camelcatalog_types.go
+++ b/pkg/apis/camel/v1/camelcatalog_types.go
@@ -23,9 +23,16 @@ import (
 
 // CamelScheme --
 type CamelScheme struct {
-       ID      string `json:"id" yaml:"id"`
-       Passive bool   `json:"passive" yaml:"passive"`
-       HTTP    bool   `json:"http" yaml:"http"`
+       ID       string           `json:"id" yaml:"id"`
+       Passive  bool             `json:"passive" yaml:"passive"`
+       HTTP     bool             `json:"http" yaml:"http"`
+       Consumer CamelSchemeScope `json:"consumer,omitempty" 
yaml:"consumer,omitempty"`
+       Producer CamelSchemeScope `json:"producer,omitempty" 
yaml:"producer,omitempty"`
+}
+
+// CamelSchemeScope contains scoped information about a scheme
+type CamelSchemeScope struct {
+       Dependencies []CamelArtifactDependency `json:"dependencies,omitempty" 
yaml:"dependencies,omitempty"`
 }
 
 // CamelArtifactExclusion --
diff --git a/pkg/apis/camel/v1/camelcatalog_types_support.go 
b/pkg/apis/camel/v1/camelcatalog_types_support.go
index 83fcc68..85f6c98 100644
--- a/pkg/apis/camel/v1/camelcatalog_types_support.go
+++ b/pkg/apis/camel/v1/camelcatalog_types_support.go
@@ -18,6 +18,7 @@ limitations under the License.
 package v1
 
 import (
+       "fmt"
        "strings"
 
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -75,3 +76,56 @@ func (in *CamelArtifact) GetDependencyID() string {
                return "mvn:" + in.GroupID + ":" + in.ArtifactID + ":" + 
in.Version
        }
 }
+
+func (in *CamelArtifact) GetConsumerDependencyIDs(schemeID string) (deps 
[]string) {
+       return in.getDependencyIDs(schemeID, consumerScheme)
+}
+
+func (in *CamelArtifact) GetProducerDependencyIDs(schemeID string) (deps 
[]string) {
+       return in.getDependencyIDs(schemeID, producerScheme)
+}
+
+func (in *CamelArtifact) getDependencyIDs(schemeID string, scope 
func(CamelScheme) CamelSchemeScope) (deps []string) {
+       ads := in.getDependencies(schemeID, scope)
+       if ads == nil {
+               return deps
+       }
+       deps = make([]string, 0, len(ads))
+       for _, ad := range ads {
+               deps = append(deps, fmt.Sprintf("mvn:%s/%s", ad.GroupID, 
ad.ArtifactID))
+       }
+       return deps
+}
+
+func (in *CamelArtifact) GetConsumerDependencies(schemeID string) 
[]CamelArtifactDependency {
+       return in.getDependencies(schemeID, consumerScheme)
+}
+
+func (in *CamelArtifact) GetProducerDependencies(schemeID string) 
[]CamelArtifactDependency {
+       return in.getDependencies(schemeID, producerScheme)
+}
+
+func (in *CamelArtifact) getDependencies(schemeID string, scope 
func(CamelScheme) CamelSchemeScope) []CamelArtifactDependency {
+       scheme := in.GetScheme(schemeID)
+       if scheme == nil {
+               return nil
+       }
+       return scope(*scheme).Dependencies
+}
+
+func (in *CamelArtifact) GetScheme(schemeID string) *CamelScheme {
+       for _, scheme := range in.Schemes {
+               if scheme.ID == schemeID {
+                       return &scheme
+               }
+       }
+       return nil
+}
+
+func consumerScheme(scheme CamelScheme) CamelSchemeScope {
+       return scheme.Consumer
+}
+
+func producerScheme(scheme CamelScheme) CamelSchemeScope {
+       return scheme.Producer
+}
diff --git a/pkg/trait/cron.go b/pkg/trait/cron.go
index 8e496cc..3a9aa7f 100644
--- a/pkg/trait/cron.go
+++ b/pkg/trait/cron.go
@@ -228,6 +228,7 @@ func (t *cronTrait) Apply(e *Environment) error {
                                return fmt.Errorf("no fallback artifact for 
scheme %q has been found in camel catalog", genericCronComponentFallbackScheme)
                        }
                        
util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, 
fallbackArtifact.GetDependencyID())
+                       
util.StringSliceUniqueConcat(&e.Integration.Status.Dependencies, 
fallbackArtifact.GetConsumerDependencyIDs(genericCronComponentFallbackScheme))
                }
        }
 
diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go
index 90a0051..6de2cb0 100644
--- a/pkg/util/source/inspector.go
+++ b/pkg/util/source/inspector.go
@@ -235,12 +235,27 @@ func (i *baseInspector) discoverCapabilities(source 
v1.SourceSpec, meta *Metadat
 
 // discoverDependencies returns a list of dependencies required by the given 
source code
 func (i *baseInspector) discoverDependencies(source v1.SourceSpec, meta 
*Metadata) {
-       uris := util.StringSliceJoin(meta.FromURIs, meta.ToURIs)
+       for _, uri := range meta.FromURIs {
+               candidateComp, scheme := i.decodeComponent(uri)
+               if candidateComp != nil {
+                       i.addDependency(candidateComp.GetDependencyID(), meta)
+                       if scheme != nil {
+                               for _, dep := range 
candidateComp.GetConsumerDependencyIDs(scheme.ID) {
+                                       i.addDependency(dep, meta)
+                               }
+                       }
+               }
+       }
 
-       for _, uri := range uris {
-               candidateComp := i.decodeComponent(uri)
-               if candidateComp != "" {
-                       i.addDependency(candidateComp, meta)
+       for _, uri := range meta.ToURIs {
+               candidateComp, scheme := i.decodeComponent(uri)
+               if candidateComp != nil {
+                       i.addDependency(candidateComp.GetDependencyID(), meta)
+                       if scheme != nil {
+                               for _, dep := range 
candidateComp.GetProducerDependencyIDs(scheme.ID) {
+                                       i.addDependency(dep, meta)
+                               }
+                       }
                }
        }
 
@@ -280,16 +295,18 @@ func (i *baseInspector) addDependency(dependency string, 
meta *Metadata) {
        meta.Dependencies.Add(dependency)
 }
 
-func (i *baseInspector) decodeComponent(uri string) string {
+func (i *baseInspector) decodeComponent(uri string) (*v1.CamelArtifact, 
*v1.CamelScheme) {
        uriSplit := strings.SplitN(uri, ":", 2)
        if len(uriSplit) < 2 {
-               return ""
+               return nil, nil
        }
        uriStart := uriSplit[0]
-       if component := i.catalog.GetArtifactByScheme(uriStart); component != 
nil {
-               return component.GetDependencyID()
+       scheme, ok := i.catalog.GetScheme(uriStart)
+       var schemeRef *v1.CamelScheme
+       if ok {
+               schemeRef = &scheme
        }
-       return ""
+       return i.catalog.GetArtifactByScheme(uriStart), schemeRef
 }
 
 // hasOnlyPassiveEndpoints returns true if the source has no endpoint that 
needs to remain always active
diff --git a/pkg/util/source/inspector_yaml_test.go 
b/pkg/util/source/inspector_yaml_test.go
index 518b938..18960d0 100644
--- a/pkg/util/source/inspector_yaml_test.go
+++ b/pkg/util/source/inspector_yaml_test.go
@@ -37,6 +37,80 @@ func NewtestYAMLInspector(t *testing.T) YAMLInspector {
        }
 }
 
+const YAMLRouteConsumer = `
+- from:
+    uri: knative:endpoint/default
+    steps:
+      - to:
+          uri: "log:out"
+`
+
+const YAMLRouteProducer = `
+- from:
+    uri: timer:tick
+    steps:
+      - to:
+          uri: knative:endpoint/service
+`
+
+const YAMLRouteTransformer = `
+- from:
+    uri: knative:channel/mychannel
+    steps:
+      - to:
+          uri: knative:endpoint/service
+`
+
+func TestYAMLDependencies(t *testing.T) {
+       tests := []struct {
+               name                string
+               source              string
+               dependencies        []string
+               missingDependencies []string
+       }{
+               {
+                       name:                "consumer",
+                       source:              YAMLRouteConsumer,
+                       dependencies:        
[]string{`mvn:org.apache.camel.k/camel-k-knative-consumer`},
+                       missingDependencies: 
[]string{`mvn:org.apache.camel.k/camel-k-knative-producer`},
+               },
+               {
+                       name:                "producer",
+                       source:              YAMLRouteProducer,
+                       dependencies:        
[]string{`mvn:org.apache.camel.k/camel-k-knative-producer`},
+                       missingDependencies: 
[]string{`mvn:org.apache.camel.k/camel-k-knative-consumer`},
+               },
+               {
+                       name:         "transformer",
+                       source:       YAMLRouteTransformer,
+                       dependencies: 
[]string{`mvn:org.apache.camel.k/camel-k-knative-producer`, 
`mvn:org.apache.camel.k/camel-k-knative-consumer`},
+               },
+       }
+       for _, test := range tests {
+               t.Run(test.name, func(t *testing.T) {
+                       code := v1.SourceSpec{
+                               DataSpec: v1.DataSpec{
+                                       Name:    "route.yaml",
+                                       Content: test.source,
+                               },
+                               Language: v1.LanguageYaml,
+                       }
+
+                       meta := NewMetadata()
+                       inspector := NewtestYAMLInspector(t)
+
+                       err := inspector.Extract(code, &meta)
+                       assert.Nil(t, err)
+                       for _, dependency := range test.dependencies {
+                               assert.Contains(t, meta.Dependencies.List(), 
dependency)
+                       }
+                       for _, missingDependency := range 
test.missingDependencies {
+                               assert.NotContains(t, meta.Dependencies.List(), 
missingDependency)
+                       }
+               })
+       }
+}
+
 const YAMLRestDSL = `
 - rest:
     verb: "post"

Reply via email to