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"