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 f3a76b4f2 feat(trait): add InfluencesBuild() func
f3a76b4f2 is described below
commit f3a76b4f2e8564a47bc661f8becc28d860f66b18
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Mon Jun 26 12:48:01 2023 +0200
feat(trait): add InfluencesBuild() func
With this func we have a lower level of granularity, giving the possibility
to each trait to define when influences a build.
Closes #4511
---
docs/modules/ROOT/pages/architecture/traits.adoc | 3 ++
e2e/common/traits/camel_test.go | 61 ++++++++++++++++++++++++
pkg/controller/integration/kits.go | 25 +++++-----
pkg/resources/resources.go | 17 +++++++
pkg/trait/builder.go | 5 ++
pkg/trait/camel.go | 5 ++
pkg/trait/quarkus.go | 5 ++
pkg/trait/registry.go | 5 ++
pkg/trait/trait_types.go | 11 +++++
9 files changed, 124 insertions(+), 13 deletions(-)
diff --git a/docs/modules/ROOT/pages/architecture/traits.adoc
b/docs/modules/ROOT/pages/architecture/traits.adoc
index d773c6a6c..3457b3b4e 100644
--- a/docs/modules/ROOT/pages/architecture/traits.adoc
+++ b/docs/modules/ROOT/pages/architecture/traits.adoc
@@ -43,6 +43,7 @@ type Trait interface {
Configure(environment *Environment) (bool, error)
Apply(environment *Environment) error
InfluencesKit() bool
+ InfluencesBuild(this, prev map[string]interface{}) bool
IsPlatformTrait() bool
RequiresIntegrationPlatform() bool
IsAllowedInProfile(v1.TraitProfile) bool
@@ -58,4 +59,6 @@ The `Order()` method helps in resolving the order of
execution of different trai
The `InfluencesKit()`, `IsPlatformTrait()` and `RequiresIntegrationPlatform()`
methods are easy to understand. They are used to determine if a trait has to
influence an `IntegrationKit` build/initialization, if it's a platform trait
(ie, needed by the platform itself) or are requiring the presence of an
`IntegrationPlatform`.
+The presence of `InfluencesBuild()` will let specify the level of granularity
of a trait down to its properties for a rebuild. So, if you need, you can
compare the traits properties coming from the `prev` (previous) Integration to
decide if it is worth to rebuild an Integration or the trait can reuse the one
already provided in `this` version.
+
Finally, through the `IsAllowedInProfile()` method we can override the default
behavior (allow the trait for any profile). We must specify the profile we
expect for this trait to be executed properly.
diff --git a/e2e/common/traits/camel_test.go b/e2e/common/traits/camel_test.go
new file mode 100644
index 000000000..aa41d69f9
--- /dev/null
+++ b/e2e/common/traits/camel_test.go
@@ -0,0 +1,61 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go ->
Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package traits
+
+import (
+ "testing"
+
+ . "github.com/onsi/gomega"
+
+ corev1 "k8s.io/api/core/v1"
+
+ . "github.com/apache/camel-k/v2/e2e/support"
+ v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+)
+
+func TestCamelTrait(t *testing.T) {
+ RegisterTestingT(t)
+
+ t.Run("properties changes should not rebuild", func(t *testing.T) {
+ name := "java"
+ Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+ "--name", name,
+ ).Execute()).To(Succeed())
+ Eventually(IntegrationPodPhase(ns, name),
TestTimeoutLong).Should(Equal(corev1.PodRunning))
+ Eventually(IntegrationConditionStatus(ns, name,
v1.IntegrationConditionReady),
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+ Eventually(IntegrationLogs(ns, name),
TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+ integrationKit := IntegrationKit(ns, name)()
+
+ Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+ "--name", name,
+ "-p", "a=1",
+ ).Execute()).To(Succeed())
+ Eventually(IntegrationPodPhase(ns, name),
TestTimeoutShort).Should(Equal(corev1.PodRunning))
+ Eventually(IntegrationConditionStatus(ns, name,
v1.IntegrationConditionReady),
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+ Eventually(IntegrationLogs(ns, name),
TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+ Eventually(IntegrationKit(ns,
name)).Should(Equal(integrationKit))
+ })
+
+ // Clean-up
+ Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/pkg/controller/integration/kits.go
b/pkg/controller/integration/kits.go
index 8dbc7337f..e26c9f544 100644
--- a/pkg/controller/integration/kits.go
+++ b/pkg/controller/integration/kits.go
@@ -199,8 +199,7 @@ func hasMatchingTraits(traitMap trait.Options, kitTraitMap
trait.Options) (bool,
catalog := trait.NewCatalog(nil)
for _, t := range catalog.AllTraits() {
- if t == nil || !t.InfluencesKit() {
- // We don't store the trait configuration if the trait
cannot influence the kit behavior
+ if t == nil {
continue
}
@@ -211,17 +210,17 @@ func hasMatchingTraits(traitMap trait.Options,
kitTraitMap trait.Options) (bool,
if !ok1 && !ok2 {
continue
}
- if !ok1 || !ok2 {
- return false, nil
- }
- if ct, ok := t.(trait.ComparableTrait); ok {
- // if it's match trait use its matches method to
determine the match
- if match, err := matchesComparableTrait(ct, it, kt);
!match || err != nil {
- return false, err
- }
- } else {
- if !matchesTrait(it, kt) {
- return false, nil
+
+ if t.InfluencesKit() && t.InfluencesBuild(it, kt) {
+ if ct, ok := t.(trait.ComparableTrait); ok {
+ // if it's match trait use its matches method
to determine the match
+ if match, err := matchesComparableTrait(ct, it,
kt); !match || err != nil {
+ return false, err
+ }
+ } else {
+ if !matchesTrait(it, kt) {
+ return false, nil
+ }
}
}
}
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index d6daa4592..b0d7a821a 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -174,6 +174,18 @@ var assets = func() http.FileSystem {
name: "manager",
modTime: time.Time{},
},
+ "/manager/bundle": &vfsgen۰DirInfo{
+ name: "bundle",
+ modTime: time.Time{},
+ },
+ "/manager/bundle/manifests": &vfsgen۰DirInfo{
+ name: "manifests",
+ modTime: time.Time{},
+ },
+ "/manager/bundle/metadata": &vfsgen۰DirInfo{
+ name: "metadata",
+ modTime: time.Time{},
+ },
"/manager/operator-deployment.yaml": &vfsgen۰CompressedFileInfo{
name: "operator-deployment.yaml",
modTime: time.Time{},
@@ -686,6 +698,7 @@ var assets = func() http.FileSystem {
fs["/crd/bases/camel.apache.org_pipes.yaml"].(os.FileInfo),
}
fs["/manager"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
+ fs["/manager/bundle"].(os.FileInfo),
fs["/manager/operator-deployment.yaml"].(os.FileInfo),
fs["/manager/operator-pvc.yaml"].(os.FileInfo),
fs["/manager/operator-service-account.yaml"].(os.FileInfo),
@@ -699,6 +712,10 @@ var assets = func() http.FileSystem {
fs["/manager/patch-toleration.yaml"].(os.FileInfo),
fs["/manager/patch-watch-namespace-global.yaml"].(os.FileInfo),
}
+ fs["/manager/bundle"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
+ fs["/manager/bundle/manifests"].(os.FileInfo),
+ fs["/manager/bundle/metadata"].(os.FileInfo),
+ }
fs["/prometheus"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
fs["/prometheus/operator-pod-monitor.yaml"].(os.FileInfo),
fs["/prometheus/operator-prometheus-rule.yaml"].(os.FileInfo),
diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go
index 5c18f42c6..6e583d88c 100644
--- a/pkg/trait/builder.go
+++ b/pkg/trait/builder.go
@@ -53,6 +53,11 @@ func (t *builderTrait) InfluencesKit() bool {
return true
}
+// InfluencesBuild overrides base class method.
+func (t *builderTrait) InfluencesBuild(this, prev map[string]interface{}) bool
{
+ return true
+}
+
func (t *builderTrait) Configure(e *Environment) (bool, error) {
if e.IntegrationKit == nil || !pointer.BoolDeref(t.Enabled, true) {
return false, nil
diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go
index 8974b7879..ecb5137f8 100644
--- a/pkg/trait/camel.go
+++ b/pkg/trait/camel.go
@@ -58,6 +58,11 @@ func (t *camelTrait) InfluencesKit() bool {
return true
}
+// InfluencesBuild only when the runtime has changed.
+func (t *camelTrait) InfluencesBuild(this, prev map[string]interface{}) bool {
+ return this["runtimeVersion"] != prev["runtimeVersion"]
+}
+
func (t *camelTrait) Configure(e *Environment) (bool, error) {
if !pointer.BoolDeref(t.Enabled, true) {
return false, errors.New("trait camel cannot be disabled")
diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go
index 23f011ae0..ae182e740 100644
--- a/pkg/trait/quarkus.go
+++ b/pkg/trait/quarkus.go
@@ -106,6 +106,11 @@ func (t *quarkusTrait) InfluencesKit() bool {
return true
}
+// InfluencesBuild overrides base class method.
+func (t *quarkusTrait) InfluencesBuild(this, prev map[string]interface{}) bool
{
+ return true
+}
+
var _ ComparableTrait = &quarkusTrait{}
func (t *quarkusTrait) Matches(trait Trait) bool {
diff --git a/pkg/trait/registry.go b/pkg/trait/registry.go
index 508fa1905..27aed1355 100644
--- a/pkg/trait/registry.go
+++ b/pkg/trait/registry.go
@@ -53,6 +53,11 @@ func (t *registryTrait) InfluencesKit() bool {
return true
}
+// InfluencesBuild overrides base class method.
+func (t *registryTrait) InfluencesBuild(this, prev map[string]interface{})
bool {
+ return true
+}
+
func (t *registryTrait) Configure(e *Environment) (bool, error) {
// disabled by default
if e.IntegrationKit == nil || !pointer.BoolDeref(t.Enabled, false) {
diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go
index 6fb7e7b2d..7114f5667 100644
--- a/pkg/trait/trait_types.go
+++ b/pkg/trait/trait_types.go
@@ -69,6 +69,11 @@ type Trait interface {
// InfluencesKit determines if the trait has any influence on
Integration Kits
InfluencesKit() bool
+ // InfluencesBuild defines a low level of granularity for those traits
which influences the build.
+ // The trait can specify if any particular trait configuration
influences a build or not.
+ // Note: You must override this method if you override `InfluencesKit()`
+ InfluencesBuild(this, prev map[string]interface{}) bool
+
// IsPlatformTrait marks all fundamental traits that allow the platform
to work
IsPlatformTrait() bool
@@ -135,6 +140,12 @@ func (trait *BaseTrait) InfluencesKit() bool {
return false
}
+// InfluencesBuild defines a low level of granularity for those traits which
influences the build.
+// The trait can specify if any particular trait configuration influences a
build or not.
+func (trait *BaseTrait) InfluencesBuild(this, prev map[string]interface{})
bool {
+ return false
+}
+
// IsPlatformTrait marks all fundamental traits that allow the platform to
work.
func (trait *BaseTrait) IsPlatformTrait() bool {
return false