Fix #1562: support dependency scopes
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 @@
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 @@
- 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 @@
// 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 @@
package v1
import (
+ "fmt"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -75,3 +76,56 @@
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 @@
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 @@
// 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 @@
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 @@
}
}
+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"