You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2018/11/20 10:06:58 UTC

[camel-k] branch master updated: refactor: make traits more flexible

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


The following commit(s) were added to refs/heads/master by this push:
     new 8f7c085  refactor: make traits more flexible
8f7c085 is described below

commit 8f7c0858315f7fdc8576d79c246edf16e65396ad
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Tue Nov 20 10:33:40 2018 +0100

    refactor: make traits more flexible
---
 pkg/builder/builder_types.go              | 11 +++++++++
 pkg/builder/kaniko/kaniko.go              | 10 ++++-----
 pkg/builder/s2i/s2i.go                    |  8 +++----
 pkg/stub/action/context/initialize.go     |  5 +++++
 pkg/stub/action/integration/deploy.go     |  2 +-
 pkg/stub/action/integration/initialize.go |  2 +-
 pkg/trait/catalog.go                      | 32 +++++---------------------
 pkg/trait/dependencies.go                 | 23 +++++++++++--------
 pkg/trait/deployment.go                   | 13 ++++++-----
 pkg/trait/ingress.go                      | 33 +++++++++++++++------------
 pkg/trait/knative.go                      | 22 +++++++++++-------
 pkg/trait/owner.go                        | 10 ++++++---
 pkg/trait/route.go                        | 30 +++++++++++++++----------
 pkg/trait/service.go                      | 28 +++++++++++++----------
 pkg/trait/trait.go                        | 37 ++++++++++++-------------------
 pkg/trait/trait_test.go                   |  9 +++++---
 pkg/trait/types.go                        | 17 +++++---------
 17 files changed, 155 insertions(+), 137 deletions(-)

diff --git a/pkg/builder/builder_types.go b/pkg/builder/builder_types.go
index 6b97c1e..33eac31 100644
--- a/pkg/builder/builder_types.go
+++ b/pkg/builder/builder_types.go
@@ -26,6 +26,17 @@ import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 )
 
+const (
+	// ProjectGenerationPhase --
+	ProjectGenerationPhase int = 10
+	// ProjectBuildPhase --
+	ProjectBuildPhase int = 20
+	// ApplicationPackagePhase --
+	ApplicationPackagePhase int = 30
+	// ApplicationPublishPhase --
+	ApplicationPublishPhase int = 40
+)
+
 // Builder --
 type Builder interface {
 	Submit(request Request) Result
diff --git a/pkg/builder/kaniko/kaniko.go b/pkg/builder/kaniko/kaniko.go
index 4cf6754..33d8e4f 100644
--- a/pkg/builder/kaniko/kaniko.go
+++ b/pkg/builder/kaniko/kaniko.go
@@ -23,11 +23,11 @@ import (
 
 // DefaultSteps --
 var DefaultSteps = []builder.Step{
-	builder.NewStep("generate", 10, builder.GenerateProject),
-	builder.NewStep("dependencies", 20, builder.ComputeDependencies),
-	builder.NewStep("packager", 30, builder.StandardPackager),
-	builder.NewStep("publisher", 40, Publisher),
+	builder.NewStep("generate", builder.ProjectGenerationPhase, builder.GenerateProject),
+	builder.NewStep("build/compute-dependencies", builder.ProjectBuildPhase, builder.ComputeDependencies),
+	builder.NewStep("packager", builder.ApplicationPackagePhase, builder.StandardPackager),
+	builder.NewStep("publisher/kaniko", builder.ApplicationPublishPhase, Publisher),
 }
 
 // BuildDir is the directory where to build artifacts (shared with the Kaniko pod)
-var BuildDir = "/workspace"
\ No newline at end of file
+var BuildDir = "/workspace"
diff --git a/pkg/builder/s2i/s2i.go b/pkg/builder/s2i/s2i.go
index 3dd6d5e..e8854fe 100644
--- a/pkg/builder/s2i/s2i.go
+++ b/pkg/builder/s2i/s2i.go
@@ -21,8 +21,8 @@ import "github.com/apache/camel-k/pkg/builder"
 
 // DefaultSteps --
 var DefaultSteps = []builder.Step{
-	builder.NewStep("generate", 10, builder.GenerateProject),
-	builder.NewStep("dependencies", 20, builder.ComputeDependencies),
-	builder.NewStep("packager", 30, builder.IncrementalPackager),
-	builder.NewStep("publisher", 40, Publisher),
+	builder.NewStep("generate", builder.ProjectGenerationPhase, builder.GenerateProject),
+	builder.NewStep("build/compute-dependencies", builder.ProjectBuildPhase, builder.ComputeDependencies),
+	builder.NewStep("packager/incremental", builder.ApplicationPackagePhase, builder.IncrementalPackager),
+	builder.NewStep("publisher/s2i", builder.ApplicationPublishPhase, Publisher),
 }
diff --git a/pkg/stub/action/context/initialize.go b/pkg/stub/action/context/initialize.go
index 6f7108e..3161dd9 100644
--- a/pkg/stub/action/context/initialize.go
+++ b/pkg/stub/action/context/initialize.go
@@ -50,6 +50,11 @@ func (action *initializeAction) Handle(context *v1alpha1.IntegrationContext) err
 
 	target := context.DeepCopy()
 
+	// execute custom initialization
+	//if err := trait.Apply(nil, context); err != nil {
+	//	return err
+	//}
+
 	// update the status
 	logrus.Info("Context ", target.Name, " transitioning to state ", v1alpha1.IntegrationContextPhaseBuilding)
 	target.Status.Phase = v1alpha1.IntegrationContextPhaseBuilding
diff --git a/pkg/stub/action/integration/deploy.go b/pkg/stub/action/integration/deploy.go
index d666a7b..134a74d 100644
--- a/pkg/stub/action/integration/deploy.go
+++ b/pkg/stub/action/integration/deploy.go
@@ -42,7 +42,7 @@ func (action *deployAction) CanHandle(integration *v1alpha1.Integration) bool {
 }
 
 func (action *deployAction) Handle(integration *v1alpha1.Integration) error {
-	resources, err := trait.BeforeDeployment(integration)
+	resources, err := trait.Apply(integration, nil)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/stub/action/integration/initialize.go b/pkg/stub/action/integration/initialize.go
index 949df34..fa02315 100644
--- a/pkg/stub/action/integration/initialize.go
+++ b/pkg/stub/action/integration/initialize.go
@@ -64,7 +64,7 @@ func (action *initializeAction) Handle(integration *v1alpha1.Integration) error
 	target.Spec.Source.Language = meta.Language
 
 	// execute custom initialization
-	if err := trait.BeforeInit(target); err != nil {
+	if _, err := trait.Apply(target, nil); err != nil {
 		return err
 	}
 
diff --git a/pkg/trait/catalog.go b/pkg/trait/catalog.go
index 5bea83c..7ddecea 100644
--- a/pkg/trait/catalog.go
+++ b/pkg/trait/catalog.go
@@ -18,12 +18,12 @@ limitations under the License.
 package trait
 
 import (
+	"reflect"
+	"strings"
+
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/platform"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/fatih/structs"
-	"reflect"
-	"strings"
 )
 
 // Catalog collects all information about traits in one place
@@ -95,37 +95,17 @@ func (c *Catalog) traitsFor(environment *environment) []Trait {
 	return nil
 }
 
-func (c *Catalog) executeBeforeDeployment(environment *environment, resources *kubernetes.Collection) error {
-	c.configure(environment)
-	traits := c.traitsFor(environment)
-	for _, trait := range traits {
-		if trait.IsAuto() {
-			if err := trait.autoconfigure(environment, resources); err != nil {
-				return err
-			}
-		}
-		if trait.IsEnabled() {
-			if err := trait.beforeDeploy(environment, resources); err != nil {
-				return err
-			}
-			environment.ExecutedTraits = append(environment.ExecutedTraits, trait.ID())
-		}
-	}
-	return nil
-}
-
-func (c *Catalog) executeBeforeInit(environment *environment, integration *v1alpha1.Integration) error {
+func (c *Catalog) apply(environment *environment) error {
 	c.configure(environment)
 	traits := c.traitsFor(environment)
-	resources := kubernetes.NewCollection()
 	for _, trait := range traits {
 		if trait.IsAuto() {
-			if err := trait.autoconfigure(environment, resources); err != nil {
+			if err := trait.autoconfigure(environment); err != nil {
 				return err
 			}
 		}
 		if trait.IsEnabled() {
-			if err := trait.beforeInit(environment, integration); err != nil {
+			if err := trait.apply(environment); err != nil {
 				return err
 			}
 			environment.ExecutedTraits = append(environment.ExecutedTraits, trait.ID())
diff --git a/pkg/trait/dependencies.go b/pkg/trait/dependencies.go
index 5bdb82d..d55c059 100644
--- a/pkg/trait/dependencies.go
+++ b/pkg/trait/dependencies.go
@@ -18,10 +18,11 @@ limitations under the License.
 package trait
 
 import (
+	"sort"
+
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/metadata"
 	"github.com/apache/camel-k/pkg/util"
-	"sort"
 )
 
 type dependenciesTrait struct {
@@ -34,22 +35,26 @@ func newDependenciesTrait() *dependenciesTrait {
 	}
 }
 
-func (d *dependenciesTrait) beforeInit(environment *environment, integration *v1alpha1.Integration) error {
-	meta := metadata.Extract(integration.Spec.Source)
+func (d *dependenciesTrait) apply(e *environment) error {
+	if e.Integration == nil || e.Integration.Status.Phase != "" {
+		return nil
+	}
+
+	meta := metadata.Extract(e.Integration.Spec.Source)
 
 	if meta.Language == v1alpha1.LanguageGroovy {
-		util.StringSliceUniqueAdd(&integration.Spec.Dependencies, "runtime:groovy")
+		util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "runtime:groovy")
 	} else if meta.Language == v1alpha1.LanguageKotlin {
-		util.StringSliceUniqueAdd(&integration.Spec.Dependencies, "runtime:kotlin")
+		util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "runtime:kotlin")
 	}
 
 	// jvm runtime and camel-core required by default
-	util.StringSliceUniqueAdd(&integration.Spec.Dependencies, "runtime:jvm")
-	util.StringSliceUniqueAdd(&integration.Spec.Dependencies, "camel:core")
+	util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "runtime:jvm")
+	util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "camel:core")
 
-	integration.Spec.Dependencies = d.mergeDependencies(integration.Spec.Dependencies, meta.Dependencies)
+	e.Integration.Spec.Dependencies = d.mergeDependencies(e.Integration.Spec.Dependencies, meta.Dependencies)
 	// sort the dependencies to get always the same list if they don't change
-	sort.Strings(integration.Spec.Dependencies)
+	sort.Strings(e.Integration.Spec.Dependencies)
 	return nil
 }
 
diff --git a/pkg/trait/deployment.go b/pkg/trait/deployment.go
index 41f5e93..05df9ee 100644
--- a/pkg/trait/deployment.go
+++ b/pkg/trait/deployment.go
@@ -21,8 +21,7 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/apache/camel-k/pkg/util/kubernetes"
-
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -38,9 +37,13 @@ func newDeploymentTrait() *deploymentTrait {
 	}
 }
 
-func (d *deploymentTrait) beforeDeploy(environment *environment, resources *kubernetes.Collection) error {
-	resources.Add(d.getConfigMapFor(environment))
-	resources.Add(d.getDeploymentFor(environment))
+func (d *deploymentTrait) apply(e *environment) error {
+	if e.Integration == nil || e.Integration.Status.Phase != v1alpha1.IntegrationPhaseDeploying {
+		return nil
+	}
+
+	e.Resources.Add(d.getConfigMapFor(e))
+	e.Resources.Add(d.getDeploymentFor(e))
 	return nil
 }
 
diff --git a/pkg/trait/ingress.go b/pkg/trait/ingress.go
index c166c43..660de26 100644
--- a/pkg/trait/ingress.go
+++ b/pkg/trait/ingress.go
@@ -19,7 +19,8 @@ package trait
 
 import (
 	"errors"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/api/extensions/v1beta1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -38,31 +39,35 @@ func newIngressTrait() *ingressTrait {
 	}
 }
 
-func (e *ingressTrait) autoconfigure(environment *environment, resources *kubernetes.Collection) error {
-	if e.Enabled == nil {
-		hasService := e.getTargetService(environment, resources) != nil
-		hasHost := e.Host != ""
+func (i *ingressTrait) autoconfigure(e *environment) error {
+	if i.Enabled == nil {
+		hasService := i.getTargetService(e) != nil
+		hasHost := i.Host != ""
 		enabled := hasService && hasHost
-		e.Enabled = &enabled
+		i.Enabled = &enabled
 	}
 	return nil
 }
 
-func (e *ingressTrait) beforeDeploy(environment *environment, resources *kubernetes.Collection) error {
-	if e.Host == "" {
+func (i *ingressTrait) apply(e *environment) error {
+	if e.Integration == nil || e.Integration.Status.Phase != v1alpha1.IntegrationPhaseDeploying {
+		return nil
+	}
+
+	if i.Host == "" {
 		return errors.New("cannot apply ingress trait: no host defined")
 	}
-	service := e.getTargetService(environment, resources)
+	service := i.getTargetService(e)
 	if service == nil {
 		return errors.New("cannot apply ingress trait: no target service")
 	}
 
-	resources.Add(e.getIngressFor(environment, service))
+	e.Resources.Add(i.getIngressFor(e, service))
 	return nil
 }
 
-func (*ingressTrait) getTargetService(e *environment, resources *kubernetes.Collection) (service *corev1.Service) {
-	resources.VisitService(func(s *corev1.Service) {
+func (*ingressTrait) getTargetService(e *environment) (service *corev1.Service) {
+	e.Resources.VisitService(func(s *corev1.Service) {
 		if s.ObjectMeta.Labels != nil {
 			if intName, ok := s.ObjectMeta.Labels["camel.apache.org/integration"]; ok && intName == e.Integration.Name {
 				service = s
@@ -72,7 +77,7 @@ func (*ingressTrait) getTargetService(e *environment, resources *kubernetes.Coll
 	return
 }
 
-func (e *ingressTrait) getIngressFor(env *environment, service *corev1.Service) *v1beta1.Ingress {
+func (i *ingressTrait) getIngressFor(env *environment, service *corev1.Service) *v1beta1.Ingress {
 	ingress := v1beta1.Ingress{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "Ingress",
@@ -89,7 +94,7 @@ func (e *ingressTrait) getIngressFor(env *environment, service *corev1.Service)
 			},
 			Rules: []v1beta1.IngressRule{
 				{
-					Host: e.Host,
+					Host: i.Host,
 				},
 			},
 		},
diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go
index 2175525..4b10c30 100644
--- a/pkg/trait/knative.go
+++ b/pkg/trait/knative.go
@@ -19,15 +19,17 @@ package trait
 
 import (
 	"encoding/json"
+	"strings"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+
 	"github.com/apache/camel-k/pkg/metadata"
 	knativeutil "github.com/apache/camel-k/pkg/util/knative"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
 	eventing "github.com/knative/eventing/pkg/apis/eventing/v1alpha1"
 	serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
 	"github.com/sirupsen/logrus"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"strings"
 )
 
 type knativeTrait struct {
@@ -41,19 +43,23 @@ func newKnativeTrait() *knativeTrait {
 	}
 }
 
-func (t *knativeTrait) autoconfigure(environment *environment, resources *kubernetes.Collection) error {
+func (t *knativeTrait) autoconfigure(e *environment) error {
 	if t.Sources == "" {
-		channels := t.getSourceChannels(environment)
+		channels := t.getSourceChannels(e)
 		t.Sources = strings.Join(channels, ",")
 	}
 	return nil
 }
 
-func (t *knativeTrait) beforeDeploy(environment *environment, resources *kubernetes.Collection) error {
-	for _, sub := range t.getSubscriptionsFor(environment) {
-		resources.Add(sub)
+func (t *knativeTrait) apply(e *environment) error {
+	if e.Integration == nil || e.Integration.Status.Phase != v1alpha1.IntegrationPhaseDeploying {
+		return nil
+	}
+
+	for _, sub := range t.getSubscriptionsFor(e) {
+		e.Resources.Add(sub)
 	}
-	resources.Add(t.getServiceFor(environment))
+	e.Resources.Add(t.getServiceFor(e))
 	return nil
 }
 
diff --git a/pkg/trait/owner.go b/pkg/trait/owner.go
index c0a732f..82ba46e 100644
--- a/pkg/trait/owner.go
+++ b/pkg/trait/owner.go
@@ -18,7 +18,7 @@ limitations under the License.
 package trait
 
 import (
-	"github.com/apache/camel-k/pkg/util/kubernetes"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -33,10 +33,14 @@ func newOwnerTrait() *ownerTrait {
 	}
 }
 
-func (*ownerTrait) beforeDeploy(e *environment, resources *kubernetes.Collection) error {
+func (*ownerTrait) apply(e *environment) error {
+	if e.Integration == nil || e.Integration.Status.Phase != v1alpha1.IntegrationPhaseDeploying {
+		return nil
+	}
+
 	controller := true
 	blockOwnerDeletion := true
-	resources.VisitMetaObject(func(res metav1.Object) {
+	e.Resources.VisitMetaObject(func(res metav1.Object) {
 		references := []metav1.OwnerReference{
 			{
 				APIVersion:         e.Integration.APIVersion,
diff --git a/pkg/trait/route.go b/pkg/trait/route.go
index fef1786..3477145 100644
--- a/pkg/trait/route.go
+++ b/pkg/trait/route.go
@@ -19,7 +19,9 @@ package trait
 
 import (
 	"errors"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+
 	routev1 "github.com/openshift/api/route/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -37,26 +39,30 @@ func newRouteTrait() *routeTrait {
 	}
 }
 
-func (e *routeTrait) autoconfigure(environment *environment, resources *kubernetes.Collection) error {
-	if e.Enabled == nil {
-		hasService := e.getTargetService(environment, resources) != nil
-		e.Enabled = &hasService
+func (r *routeTrait) autoconfigure(e *environment) error {
+	if r.Enabled == nil {
+		hasService := r.getTargetService(e) != nil
+		r.Enabled = &hasService
 	}
 	return nil
 }
 
-func (e *routeTrait) beforeDeploy(environment *environment, resources *kubernetes.Collection) error {
-	service := e.getTargetService(environment, resources)
+func (r *routeTrait) apply(e *environment) error {
+	if e.Integration == nil || e.Integration.Status.Phase != v1alpha1.IntegrationPhaseDeploying {
+		return nil
+	}
+
+	service := r.getTargetService(e)
 	if service == nil {
 		return errors.New("cannot apply route trait: no target service")
 	}
 
-	resources.Add(e.getRouteFor(environment, service))
+	e.Resources.Add(r.getRouteFor(e, service))
 	return nil
 }
 
-func (*routeTrait) getTargetService(e *environment, resources *kubernetes.Collection) (service *corev1.Service) {
-	resources.VisitService(func(s *corev1.Service) {
+func (*routeTrait) getTargetService(e *environment) (service *corev1.Service) {
+	e.Resources.VisitService(func(s *corev1.Service) {
 		if s.ObjectMeta.Labels != nil {
 			if intName, ok := s.ObjectMeta.Labels["camel.apache.org/integration"]; ok && intName == e.Integration.Name {
 				service = s
@@ -66,7 +72,7 @@ func (*routeTrait) getTargetService(e *environment, resources *kubernetes.Collec
 	return
 }
 
-func (e *routeTrait) getRouteFor(env *environment, service *corev1.Service) *routev1.Route {
+func (r *routeTrait) getRouteFor(env *environment, service *corev1.Service) *routev1.Route {
 	route := routev1.Route{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "Route",
@@ -84,7 +90,7 @@ func (e *routeTrait) getRouteFor(env *environment, service *corev1.Service) *rou
 				Kind: "Service",
 				Name: service.Name,
 			},
-			Host: e.Host,
+			Host: r.Host,
 		},
 	}
 	return &route
diff --git a/pkg/trait/service.go b/pkg/trait/service.go
index fdd2fa6..bc97b70 100644
--- a/pkg/trait/service.go
+++ b/pkg/trait/service.go
@@ -18,7 +18,7 @@ limitations under the License.
 package trait
 
 import (
-	"github.com/apache/camel-k/pkg/util/kubernetes"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/version"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -26,12 +26,12 @@ import (
 )
 
 var webComponents = map[string]bool{
-	"camel:servlet":                                           true,
-	"camel:undertow":                                          true,
-	"camel:jetty":                                             true,
-	"camel:jetty9":                                            true,
-	"camel:netty-http":                                        true,
-	"camel:netty4-http":                                       true,
+	"camel:servlet":     true,
+	"camel:undertow":    true,
+	"camel:jetty":       true,
+	"camel:jetty9":      true,
+	"camel:netty-http":  true,
+	"camel:netty4-http": true,
 	"mvn:org.apache.camel.k:camel-knative:" + version.Version: true,
 	// TODO find a better way to discover need for exposure
 	// maybe using the resolved classpath of the context instead of the requested dependencies
@@ -50,20 +50,24 @@ func newServiceTrait() *serviceTrait {
 	}
 }
 
-func (s *serviceTrait) autoconfigure(environment *environment, resources *kubernetes.Collection) error {
+func (s *serviceTrait) autoconfigure(e *environment) error {
 	if s.Enabled == nil {
-		required := s.requiresService(environment)
+		required := s.requiresService(e)
 		s.Enabled = &required
 	}
 	return nil
 }
 
-func (s *serviceTrait) beforeDeploy(environment *environment, resources *kubernetes.Collection) (err error) {
+func (s *serviceTrait) apply(e *environment) (err error) {
+	if e.Integration == nil || e.Integration.Status.Phase != v1alpha1.IntegrationPhaseDeploying {
+		return nil
+	}
+
 	var svc *corev1.Service
-	if svc, err = s.getServiceFor(environment); err != nil {
+	if svc, err = s.getServiceFor(e); err != nil {
 		return err
 	}
-	resources.Add(svc)
+	e.Resources.Add(svc)
 	return nil
 }
 
diff --git a/pkg/trait/trait.go b/pkg/trait/trait.go
index 9239b3a..6599085 100644
--- a/pkg/trait/trait.go
+++ b/pkg/trait/trait.go
@@ -25,44 +25,34 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
-// BeforeDeployment generates all required resources for deploying the given integration
-func BeforeDeployment(integration *v1alpha1.Integration) ([]runtime.Object, error) {
-	environment, err := newEnvironment(integration)
+// Apply --
+func Apply(integration *v1alpha1.Integration, ctx *v1alpha1.IntegrationContext) ([]runtime.Object, error) {
+	environment, err := newEnvironment(integration, ctx)
 	if err != nil {
 		return nil, err
 	}
-	resources := kubernetes.NewCollection()
+
 	catalog := NewCatalog()
 	// invoke the trait framework to determine the needed resources
-	if err := catalog.executeBeforeDeployment(environment, resources); err != nil {
+	if err := catalog.apply(environment); err != nil {
 		return nil, errors.Wrap(err, "error during trait customization before deployment")
 	}
-	return resources.Items(), nil
-}
 
-// BeforeInit executes custom initializazion of the integration
-func BeforeInit(integration *v1alpha1.Integration) error {
-	environment, err := newEnvironment(integration)
-	if err != nil {
-		return err
-	}
-	catalog := NewCatalog()
-	// invoke the trait framework to determine the needed resources
-	if err := catalog.executeBeforeInit(environment, integration); err != nil {
-		return errors.Wrap(err, "error during trait customization before init")
-	}
-	return nil
+	return environment.Resources.Items(), nil
 }
 
 // newEnvironment creates a environment from the given data
-func newEnvironment(integration *v1alpha1.Integration) (*environment, error) {
+func newEnvironment(integration *v1alpha1.Integration, ctx *v1alpha1.IntegrationContext) (*environment, error) {
 	pl, err := platform.GetCurrentPlatform(integration.Namespace)
 	if err != nil {
 		return nil, err
 	}
-	ctx, err := GetIntegrationContext(integration)
-	if err != nil {
-		return nil, err
+
+	if ctx == nil {
+		ctx, err = GetIntegrationContext(integration)
+		if err != nil {
+			return nil, err
+		}
 	}
 
 	return &environment{
@@ -70,5 +60,6 @@ func newEnvironment(integration *v1alpha1.Integration) (*environment, error) {
 		Context:        ctx,
 		Integration:    integration,
 		ExecutedTraits: make([]ID, 0),
+		Resources:      kubernetes.NewCollection(),
 	}, nil
 }
diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go
index d6f11aa..505a0db 100644
--- a/pkg/trait/trait_test.go
+++ b/pkg/trait/trait_test.go
@@ -153,11 +153,10 @@ func TestTraitDecode(t *testing.T) {
 }
 
 func processTestEnv(t *testing.T, env *environment) *kubernetes.Collection {
-	resources := kubernetes.NewCollection()
 	catalog := NewCatalog()
-	err := catalog.executeBeforeDeployment(env, resources)
+	err := catalog.apply(env)
 	assert.Nil(t, err)
-	return resources
+	return env.Resources
 }
 
 func createTestEnv(cluster v1alpha1.IntegrationPlatformCluster, dependencies ...string) *environment {
@@ -170,6 +169,9 @@ func createTestEnv(cluster v1alpha1.IntegrationPlatformCluster, dependencies ...
 			Spec: v1alpha1.IntegrationSpec{
 				Dependencies: dependencies,
 			},
+			Status: v1alpha1.IntegrationStatus{
+				Phase: v1alpha1.IntegrationPhaseDeploying,
+			},
 		},
 		Context: &v1alpha1.IntegrationContext{},
 		Platform: &v1alpha1.IntegrationPlatform{
@@ -178,5 +180,6 @@ func createTestEnv(cluster v1alpha1.IntegrationPlatformCluster, dependencies ...
 			},
 		},
 		ExecutedTraits: make([]ID, 0),
+		Resources:      kubernetes.NewCollection(),
 	}
 }
diff --git a/pkg/trait/types.go b/pkg/trait/types.go
index 3cb6cf5..476cd14 100644
--- a/pkg/trait/types.go
+++ b/pkg/trait/types.go
@@ -38,11 +38,9 @@ type Trait interface {
 	// auto determine if the trait should be configured automatically
 	IsAuto() bool
 	// autoconfigure is called before any customization to ensure the trait is fully configured
-	autoconfigure(environment *environment, resources *kubernetes.Collection) error
-	// beforeInit executes a customization of the integration before it's built
-	beforeInit(environment *environment, integration *v1alpha1.Integration) error
-	// beforeDeploy executes a customization of the gerenated resources before they are created
-	beforeDeploy(environment *environment, resources *kubernetes.Collection) error
+	autoconfigure(environment *environment) error
+	// apply executes a customization of the environment
+	apply(environment *environment) error
 }
 
 /* Base trait */
@@ -81,15 +79,11 @@ func (trait *BaseTrait) IsEnabled() bool {
 	return *trait.Enabled
 }
 
-func (trait *BaseTrait) autoconfigure(environment *environment, resources *kubernetes.Collection) error {
+func (trait *BaseTrait) autoconfigure(environment *environment) error {
 	return nil
 }
 
-func (trait *BaseTrait) beforeInit(environment *environment, integration *v1alpha1.Integration) error {
-	return nil
-}
-
-func (trait *BaseTrait) beforeDeploy(environment *environment, resources *kubernetes.Collection) error {
+func (trait *BaseTrait) apply(environment *environment) error {
 	return nil
 }
 
@@ -100,5 +94,6 @@ type environment struct {
 	Platform       *v1alpha1.IntegrationPlatform
 	Context        *v1alpha1.IntegrationContext
 	Integration    *v1alpha1.Integration
+	Resources      *kubernetes.Collection
 	ExecutedTraits []ID
 }