This is an automated email from the ASF dual-hosted git repository.

astefanutti 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 45d5666  Misleading "service.enabled=false" when used in combination 
with the prometheus trait #768
45d5666 is described below

commit 45d5666e699460da51051874fd918dfe82399300
Author: lburgazzoli <lburgazz...@gmail.com>
AuthorDate: Wed Jul 17 11:37:47 2019 +0200

    Misleading "service.enabled=false" when used in combination with the 
prometheus trait #768
---
 docs/modules/ROOT/pages/traits.adoc          |  57 +++++++++-----
 pkg/apis/camel/v1alpha1/integration_types.go |  10 +++
 pkg/trait/classpath.go                       |   3 -
 pkg/trait/container.go                       |  85 +++++++++++++++++++--
 pkg/trait/jolokia.go                         |  46 +++++++-----
 pkg/trait/prometheus.go                      |  94 ++++++++++++++---------
 pkg/trait/service.go                         | 108 ++++++---------------------
 pkg/trait/service_test.go                    |  24 ++++--
 pkg/trait/trait_catalog.go                   |  12 +--
 pkg/trait/trait_test.go                      |  10 +--
 pkg/util/kubernetes/collection.go            |  21 ++++++
 11 files changed, 285 insertions(+), 185 deletions(-)

diff --git a/docs/modules/ROOT/pages/traits.adoc 
b/docs/modules/ROOT/pages/traits.adoc
index 0c7ecc8..8bb33ba 100644
--- a/docs/modules/ROOT/pages/traits.adoc
+++ b/docs/modules/ROOT/pages/traits.adoc
@@ -34,13 +34,13 @@ A trait may have additional properties that can be 
configured by the end user.
 E.g. the following command configures the container `port` that should be 
exposed by the service:
 
 ```
-kamel run --trait service.enabled=true --trait service.port=8081 file.groovy
+kamel run --trait service.enabled=true --trait container.service-port=8081 
file.groovy
 ```
 
 Or the equivalent command (assuming that the service trait is enabled by 
auto-detection):
 
 ```
-kamel run -t service.port=8081 file.groovy
+kamel run -t container.service-port=8081 file.groovy
 ```
 
 NOTE: Enabling a trait does not force the trait to be activated, especially if 
the trait specific preconditions do not hold.
@@ -73,9 +73,6 @@ The following is a list of common traits that can be 
configured by the end users
 [cols="m,"]
 !===
 
-! deployer.container-image
-! Generates a container image for the Integration that includes the sources 
and resources in the generated images instead of mounting them to the pod.
-
 ! deployer.kind
 ! Allows to explicitly select the desired deployment kind between `deployment` 
or `knative-service` when creating the resources for running the integration.
 
@@ -190,18 +187,6 @@ More information can be found in the official Kubernetes 
documentation about htt
 [cols="m,"]
 !===
 
-! service.port
-! To configure a different port exposed by the service (default `80`).
-
-! service.port-name
-! To configure a different port name for the port exposed by the service 
(default `http`).
-
-! service.container-port
-! To configure a different port exposed by the container (default `8080`).
-
-! service.container-port-name
-! To configure a different port name for the port exposed by the container 
(default `http`).
-
 !===
 
 | route
@@ -326,7 +311,7 @@ It's disabled by default.
 
 | probes
 | Kubernetes, OpenShift
-| Configure LIveness and Readiness probes.
+| Configure Liveness and Readiness probes.
   +
   +
   It's disabled by default.
@@ -367,6 +352,42 @@ It's disabled by default.
 
 !===
 
+| container
+| All
+| Configure integration contianer.
+  +
+  +
+  It's disabled by default.
+
+[cols="m,"]
+!===
+
+! container.request-cpu
+! The minimum amount of CPU required.
+
+! container.request-memory
+! The minimum amount of memory required.
+
+! container.limit-cpu
+! The maximum amount of CPU required.
+
+! container.limit-memory
+! The maximum amount of memory required.
+
+! container.service-port
+! To configure under which service port the container port is to be exposed 
(default `80`).
+
+! container.service-port-name
+! To configure under which service port name the container port is to be 
exposed (default `http`).
+
+! container.port
+! To configure a different port exposed by the container (default `8080`).
+
+! container.port-name
+! To configure a different port name for the port exposed by the container 
(default `http`).
+
+!===
+
 |=======================
 
 
diff --git a/pkg/apis/camel/v1alpha1/integration_types.go 
b/pkg/apis/camel/v1alpha1/integration_types.go
index b6435af..618c855 100644
--- a/pkg/apis/camel/v1alpha1/integration_types.go
+++ b/pkg/apis/camel/v1alpha1/integration_types.go
@@ -180,6 +180,10 @@ const (
        IntegrationConditionKnativeServiceAvailable IntegrationConditionType = 
"KnativeServiceAvailable"
        // IntegrationConditionExposureAvailable --
        IntegrationConditionExposureAvailable IntegrationConditionType = 
"ExposureAvailable"
+       // IntegrationConditionPrometheusAvailable --
+       IntegrationConditionPrometheusAvailable IntegrationConditionType = 
"PrometheusAvailable"
+       // IntegrationConditionJolokiaAvailable --
+       IntegrationConditionJolokiaAvailable IntegrationConditionType = 
"JolokiaAvailable"
 
        // IntegrationConditionKitAvailableReason --
        IntegrationConditionKitAvailableReason string = 
"IntegrationKitAvailable"
@@ -193,6 +197,8 @@ const (
        IntegrationConditionServiceAvailableReason string = "ServiceAvailable"
        // IntegrationConditionServiceNotAvailableReason --
        IntegrationConditionServiceNotAvailableReason string = 
"ServiceNotAvailable"
+       // IntegrationConditionContainerNotAvailableReason --
+       IntegrationConditionContainerNotAvailableReason string = 
"ContainerNotAvailable"
        // IntegrationConditionRouteAvailableReason --
        IntegrationConditionRouteAvailableReason string = "RouteAvailable"
        // IntegrationConditionRouteNotAvailableReason --
@@ -205,6 +211,10 @@ const (
        IntegrationConditionKnativeServiceAvailableReason string = 
"KnativeServiceAvailable"
        // IntegrationConditionKnativeServiceNotAvailableReason --
        IntegrationConditionKnativeServiceNotAvailableReason string = 
"KnativeServiceNotAvailable"
+       // IntegrationConditionPrometheusAvailableReason --
+       IntegrationConditionPrometheusAvailableReason string = 
"PrometheusAvailable"
+       // IntegrationConditionJolokiaAvailableReason --
+       IntegrationConditionJolokiaAvailableReason string = "JolokiaAvailable"
 )
 
 // IntegrationCondition describes the state of a resource at a certain point.
diff --git a/pkg/trait/classpath.go b/pkg/trait/classpath.go
index cb0eff9..d12585f 100644
--- a/pkg/trait/classpath.go
+++ b/pkg/trait/classpath.go
@@ -97,9 +97,6 @@ func (t *classpathTrait) Apply(e *Environment) error {
        }
 
        if e.Resources != nil {
-               //
-               // Add mounted volumes as resources
-               //
                e.Resources.VisitDeployment(func(deployment *appsv1.Deployment) 
{
                        for i := 0; i < 
len(deployment.Spec.Template.Spec.Containers); i++ {
                                cp := e.Classpath.Copy()
diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index bfd29e7..118428a 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -18,24 +18,38 @@ limitations under the License.
 package trait
 
 import (
+       "fmt"
+
        "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
        serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
        appsv1 "k8s.io/api/apps/v1"
        corev1 "k8s.io/api/core/v1"
        "k8s.io/apimachinery/pkg/api/resource"
+       "k8s.io/apimachinery/pkg/util/intstr"
 )
 
 type containerTrait struct {
-       BaseTrait     `property:",squash"`
-       RequestCPU    string `property:"request-cpu"`
-       RequestMemory string `property:"request-memory"`
-       LimitCPU      string `property:"limit-cpu"`
-       LimitMemory   string `property:"limit-memory"`
+       BaseTrait `property:",squash"`
+
+       Auto            *bool  `property:"auto"`
+       RequestCPU      string `property:"request-cpu"`
+       RequestMemory   string `property:"request-memory"`
+       LimitCPU        string `property:"limit-cpu"`
+       LimitMemory     string `property:"limit-memory"`
+       Expose          *bool  `property:"expose"`
+       Port            int    `property:"port"`
+       PortName        string `property:"port-name"`
+       ServicePort     int    `property:"service-port"`
+       ServicePortName string `property:"service-port-name"`
 }
 
 func newContainerTrait() *containerTrait {
        return &containerTrait{
-               BaseTrait: newBaseTrait("container"),
+               BaseTrait:       newBaseTrait("container"),
+               Port:            8080,
+               PortName:        httpPortName,
+               ServicePort:     80,
+               ServicePortName: httpPortName,
        }
 }
 
@@ -44,7 +58,18 @@ func (t *containerTrait) Configure(e *Environment) (bool, 
error) {
                return false, nil
        }
 
-       return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
+       if !e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying) {
+               return false, nil
+       }
+
+       if t.Auto == nil || *t.Auto {
+               if t.Expose == nil {
+                       e := 
e.Resources.GetServiceForIntegration(e.Integration) != nil
+                       t.Expose = &e
+               }
+       }
+
+       return true, nil
 }
 
 func (t *containerTrait) Apply(e *Environment) error {
@@ -63,9 +88,55 @@ func (t *containerTrait) Apply(e *Environment) error {
                })
        }
 
+       if t.Expose != nil && *t.Expose {
+               t.configureService(e)
+       }
+
        return nil
 }
 
+func (t *containerTrait) configureService(e *Environment) {
+       service := e.Resources.GetServiceForIntegration(e.Integration)
+       if service == nil {
+               return
+       }
+
+       container := e.Resources.GetContainerForIntegration(e.Integration)
+       if container == nil {
+               return
+       }
+
+       containerPort := corev1.ContainerPort{
+               Name:          t.PortName,
+               ContainerPort: int32(t.Port),
+               Protocol:      corev1.ProtocolTCP,
+       }
+
+       servicePort := corev1.ServicePort{
+               Name:       t.ServicePortName,
+               Port:       int32(t.ServicePort),
+               Protocol:   corev1.ProtocolTCP,
+               TargetPort: intstr.FromString(t.PortName),
+       }
+
+       e.Integration.Status.SetCondition(
+               v1alpha1.IntegrationConditionServiceAvailable,
+               corev1.ConditionTrue,
+               v1alpha1.IntegrationConditionServiceAvailableReason,
+
+               // service -> container
+               fmt.Sprintf("%s(%s/%d) -> %s(%s/%d)",
+                       service.Name, servicePort.Name, servicePort.Port,
+                       container.Name, containerPort.Name, 
containerPort.ContainerPort),
+       )
+
+       container.Ports = append(container.Ports, containerPort)
+       service.Spec.Ports = append(service.Spec.Ports, servicePort)
+
+       // Mark the service as a user service
+       service.Labels["camel.apache.org/service.type"] = 
v1alpha1.ServiceTypeUser
+}
+
 func (t *containerTrait) configureResources(_ *Environment, container 
*corev1.Container) {
        //
        // Requests
diff --git a/pkg/trait/jolokia.go b/pkg/trait/jolokia.go
index 3a81030..60dec4d 100644
--- a/pkg/trait/jolokia.go
+++ b/pkg/trait/jolokia.go
@@ -18,7 +18,7 @@ limitations under the License.
 package trait
 
 import (
-       "errors"
+       "fmt"
        "strconv"
        "strings"
 
@@ -115,25 +115,33 @@ func (t *jolokiaTrait) Apply(e *Environment) (err error) {
        }
        envvar.SetVal(&e.EnvVars, "AB_JOLOKIA_OPTS", strings.Join(optionValues, 
","))
 
-       // Register a post processor to add a container port to the integration 
deployment
-       e.PostProcessors = append(e.PostProcessors, func(environment 
*Environment) error {
-               var container *corev1.Container
-               environment.Resources.VisitContainer(func(c *corev1.Container) {
-                       if c.Name == environment.Integration.Name {
-                               container = c
-                       }
-               })
-               if container != nil {
-                       container.Ports = append(container.Ports, 
corev1.ContainerPort{
-                               Name:          "jolokia",
-                               ContainerPort: int32(t.Port),
-                               Protocol:      corev1.ProtocolTCP,
-                       })
-               } else {
-                       return errors.New("cannot add Jolokia container port: 
no integration container")
-               }
+       container := e.Resources.GetContainerForIntegration(e.Integration)
+       if container == nil {
+               e.Integration.Status.SetCondition(
+                       v1alpha1.IntegrationConditionJolokiaAvailable,
+                       corev1.ConditionFalse,
+                       
v1alpha1.IntegrationConditionContainerNotAvailableReason,
+                       "",
+               )
+
                return nil
-       })
+       }
+
+       containerPort := corev1.ContainerPort{
+               Name:          "jolokia",
+               ContainerPort: int32(t.Port),
+               Protocol:      corev1.ProtocolTCP,
+       }
+
+       e.Integration.Status.SetCondition(
+               v1alpha1.IntegrationConditionJolokiaAvailable,
+               corev1.ConditionTrue,
+               v1alpha1.IntegrationConditionJolokiaAvailableReason,
+               // service -> container
+               fmt.Sprintf("%s(%s/%d)", container.Name, containerPort.Name, 
containerPort.ContainerPort),
+       )
+
+       container.Ports = append(container.Ports, containerPort)
 
        return nil
 }
diff --git a/pkg/trait/prometheus.go b/pkg/trait/prometheus.go
index 5229d7b..51cdbb5 100644
--- a/pkg/trait/prometheus.go
+++ b/pkg/trait/prometheus.go
@@ -18,7 +18,7 @@ limitations under the License.
 package trait
 
 import (
-       "errors"
+       "fmt"
        "strconv"
 
        "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -66,43 +66,36 @@ func (t *prometheusTrait) Apply(e *Environment) (err error) 
{
        // Configure the Prometheus Java agent
        envvar.SetVal(&e.EnvVars, "AB_PROMETHEUS_PORT", strconv.Itoa(t.Port))
 
-       // Expose the Prometheus endpoint
-       // Either update the existing service added by previously executed 
traits
-       // (e.g. the service trait) or add a new service resource
-       svc := e.Resources.GetService(func(svc *corev1.Service) bool {
-               return svc.Name == e.Integration.Name
-       })
-       if svc == nil {
-               svc = getServiceFor(e)
-               e.Resources.Add(svc)
+       service, servicePort := t.configureServicePort(e)
+       container, containerPort := t.configureContainerPort(e)
+
+       condition := v1alpha1.IntegrationCondition{
+               Type:   v1alpha1.IntegrationConditionPrometheusAvailable,
+               Status: corev1.ConditionTrue,
+               Reason: v1alpha1.IntegrationConditionPrometheusAvailableReason,
        }
-       port := corev1.ServicePort{
-               Name:       prometheusPortName,
-               Port:       int32(t.Port),
-               Protocol:   corev1.ProtocolTCP,
-               TargetPort: intstr.FromString(prometheusPortName),
+
+       if servicePort != nil {
+               service.Spec.Ports = append(service.Spec.Ports, *servicePort)
+               condition.Message = fmt.Sprintf("%s(%s/%d) -> ", service.Name, 
servicePort.Name, servicePort.Port)
+       } else {
+               condition.Status = corev1.ConditionFalse
+               condition.Reason = 
v1alpha1.IntegrationConditionServiceNotAvailableReason
        }
-       svc.Spec.Ports = append(svc.Spec.Ports, port)
-
-       // Register a post processor to add a container port to the integration 
deployment
-       e.PostProcessors = append(e.PostProcessors, func(environment 
*Environment) error {
-               var container *corev1.Container
-               environment.Resources.VisitContainer(func(c *corev1.Container) {
-                       if c.Name == environment.Integration.Name {
-                               container = c
-                       }
-               })
-               if container != nil {
-                       container.Ports = append(container.Ports, 
corev1.ContainerPort{
-                               Name:          prometheusPortName,
-                               ContainerPort: int32(t.Port),
-                               Protocol:      corev1.ProtocolTCP,
-                       })
-               } else {
-                       return errors.New("cannot add Prometheus container 
port: no integration container")
-               }
+
+       if containerPort != nil {
+               container.Ports = append(container.Ports, *containerPort)
+               condition.Message += fmt.Sprintf("%s(%s/%d)", container.Name, 
containerPort.Name, containerPort.ContainerPort)
+       } else {
+               condition.Status = corev1.ConditionFalse
+               condition.Reason = 
v1alpha1.IntegrationConditionContainerNotAvailableReason
+       }
+
+       e.Integration.Status.SetConditions(condition)
+
+       if condition.Status == corev1.ConditionFalse {
                return nil
-       })
+       }
 
        if t.ServiceMonitor {
                // Add the ServiceMonitor resource
@@ -116,6 +109,37 @@ func (t *prometheusTrait) Apply(e *Environment) (err 
error) {
        return nil
 }
 
+func (t *prometheusTrait) configureContainerPort(e *Environment) 
(*corev1.Container, *corev1.ContainerPort) {
+       container := e.Resources.GetContainerForIntegration(e.Integration)
+       if container == nil {
+               return nil, nil
+       }
+
+       containerPort := corev1.ContainerPort{
+               Name:          prometheusPortName,
+               ContainerPort: int32(t.Port),
+               Protocol:      corev1.ProtocolTCP,
+       }
+
+       return container, &containerPort
+}
+
+func (t *prometheusTrait) configureServicePort(e *Environment) 
(*corev1.Service, *corev1.ServicePort) {
+       service := e.Resources.GetServiceForIntegration(e.Integration)
+       if service == nil {
+               return nil, nil
+       }
+
+       servicePort := corev1.ServicePort{
+               Name:       prometheusPortName,
+               Port:       int32(t.Port),
+               Protocol:   corev1.ProtocolTCP,
+               TargetPort: intstr.FromString(prometheusPortName),
+       }
+
+       return service, &servicePort
+}
+
 func (t *prometheusTrait) getServiceMonitorFor(e *Environment) 
(*monitoringv1.ServiceMonitor, error) {
        labels, err := parseCsvMap(&t.ServiceMonitorLabels)
        if err != nil {
diff --git a/pkg/trait/service.go b/pkg/trait/service.go
index 3bcbcc4..ae204c0 100644
--- a/pkg/trait/service.go
+++ b/pkg/trait/service.go
@@ -18,35 +18,23 @@ limitations under the License.
 package trait
 
 import (
-       "fmt"
-
        "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
        "github.com/apache/camel-k/pkg/metadata"
        "github.com/apache/camel-k/pkg/util/kubernetes"
        corev1 "k8s.io/api/core/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-       "k8s.io/apimachinery/pkg/util/intstr"
 )
 
 type serviceTrait struct {
        BaseTrait `property:",squash"`
-
-       Auto              *bool  `property:"auto"`
-       Port              int    `property:"port"`
-       PortName          string `property:"port-name"`
-       ContainerPort     int    `property:"container-port"`
-       ContainerPortName string `property:"container-port-name"`
+       Auto      *bool `property:"auto"`
 }
 
 const httpPortName = "http"
 
 func newServiceTrait() *serviceTrait {
        return &serviceTrait{
-               BaseTrait:         newBaseTrait("service"),
-               Port:              80,
-               PortName:          httpPortName,
-               ContainerPort:     8080,
-               ContainerPortName: httpPortName,
+               BaseTrait: newBaseTrait("service"),
        }
 }
 
@@ -96,79 +84,31 @@ func (t *serviceTrait) Configure(e *Environment) (bool, 
error) {
 }
 
 func (t *serviceTrait) Apply(e *Environment) (err error) {
-       // Either update the existing service added by previously executed 
traits
-       // (e.g. the prometheus trait) or add a new service resource
-       svc := e.Resources.GetService(func(svc *corev1.Service) bool {
-               return svc.Name == e.Integration.Name
-       })
+       svc := e.Resources.GetServiceForIntegration(e.Integration)
        if svc == nil {
-               svc = getServiceFor(e)
-               e.Resources.Add(svc)
-       }
-       port := corev1.ServicePort{
-               Name:       t.PortName,
-               Port:       int32(t.Port),
-               Protocol:   corev1.ProtocolTCP,
-               TargetPort: intstr.FromString(t.ContainerPortName),
-       }
-       svc.Spec.Ports = append(svc.Spec.Ports, port)
-
-       // Mark the service as a user service
-       svc.Labels["camel.apache.org/service.type"] = v1alpha1.ServiceTypeUser
-
-       // Register a post processor to add a container port to the integration 
deployment
-       e.PostProcessors = append(e.PostProcessors, func(environment 
*Environment) error {
-               container := environment.Resources.GetContainer(func(c 
*corev1.Container) bool {
-                       return c.Name == environment.Integration.Name
-               })
-
-               if container != nil {
-                       container.Ports = append(container.Ports, 
corev1.ContainerPort{
-                               Name:          t.ContainerPortName,
-                               ContainerPort: int32(t.ContainerPort),
-                               Protocol:      corev1.ProtocolTCP,
-                       })
-
-                       message := fmt.Sprintf("%s(%s/%d) -> %s(%s/%d)",
-                               svc.Name, port.Name, port.Port,
-                               container.Name, t.ContainerPortName, 
t.ContainerPort,
-                       )
-
-                       environment.Integration.Status.SetCondition(
-                               v1alpha1.IntegrationConditionServiceAvailable,
-                               corev1.ConditionTrue,
-                               
v1alpha1.IntegrationConditionServiceAvailableReason,
-                               message,
-                       )
-               } else {
-                       return fmt.Errorf("cannot add %s container port: no 
integration container", t.ContainerPortName)
-               }
-               return nil
-       })
-
-       return nil
-}
-
-func getServiceFor(e *Environment) *corev1.Service {
-       svc := corev1.Service{
-               TypeMeta: metav1.TypeMeta{
-                       Kind:       "Service",
-                       APIVersion: "v1",
-               },
-               ObjectMeta: metav1.ObjectMeta{
-                       Name:      e.Integration.Name,
-                       Namespace: e.Integration.Namespace,
-                       Labels: map[string]string{
-                               "camel.apache.org/integration": 
e.Integration.Name,
+               svc := corev1.Service{
+                       TypeMeta: metav1.TypeMeta{
+                               Kind:       "Service",
+                               APIVersion: "v1",
                        },
-               },
-               Spec: corev1.ServiceSpec{
-                       Ports: []corev1.ServicePort{},
-                       Selector: map[string]string{
-                               "camel.apache.org/integration": 
e.Integration.Name,
+                       ObjectMeta: metav1.ObjectMeta{
+                               Name:      e.Integration.Name,
+                               Namespace: e.Integration.Namespace,
+                               Labels: map[string]string{
+                                       "camel.apache.org/integration": 
e.Integration.Name,
+                               },
                        },
-               },
+                       Spec: corev1.ServiceSpec{
+                               Ports: []corev1.ServicePort{},
+                               Selector: map[string]string{
+                                       "camel.apache.org/integration": 
e.Integration.Name,
+                               },
+                       },
+               }
+
+               // add a new service if not already created
+               e.Resources.Add(&svc)
        }
 
-       return &svc
+       return nil
 }
diff --git a/pkg/trait/service_test.go b/pkg/trait/service_test.go
index ba88353..4e14f66 100644
--- a/pkg/trait/service_test.go
+++ b/pkg/trait/service_test.go
@@ -94,7 +94,7 @@ func TestServiceWithDefaults(t *testing.T) {
                },
                EnvVars:        make([]corev1.EnvVar, 0),
                ExecutedTraits: make([]Trait, 0),
-               Resources:      kubernetes.NewCollection(&appsv1.Deployment{}),
+               Resources:      kubernetes.NewCollection(),
                Classpath:      strset.New(),
        }
 
@@ -104,6 +104,7 @@ func TestServiceWithDefaults(t *testing.T) {
        assert.NotEmpty(t, environment.ExecutedTraits)
        assert.NotNil(t, environment.GetTrait(ID("deployment")))
        assert.NotNil(t, environment.GetTrait(ID("service")))
+       assert.NotNil(t, environment.GetTrait(ID("container")))
 
        s := environment.Resources.GetService(func(service *corev1.Service) 
bool {
                return service.Name == ServiceTestName
@@ -158,12 +159,18 @@ func TestService(t *testing.T) {
                                Traits: map[string]v1alpha1.TraitSpec{
                                        "service": {
                                                Configuration: 
map[string]string{
-                                                       "enabled":             
"true",
-                                                       "auto":                
"false",
-                                                       "port":                
"81",
-                                                       "port-name":           
"http-81",
-                                                       "container-port":      
"8081",
-                                                       "container-port-name": 
"http-8081",
+                                                       "enabled": "true",
+                                               },
+                                       },
+                                       "container": {
+                                               Configuration: 
map[string]string{
+                                                       "enabled":           
"true",
+                                                       "auto":              
"false",
+                                                       "expose":            
"true",
+                                                       "port":              
"8081",
+                                                       "port-name":         
"http-8081",
+                                                       "service-port":      
"81",
+                                                       "service-port-name": 
"http-81",
                                                },
                                        },
                                },
@@ -185,7 +192,7 @@ func TestService(t *testing.T) {
                },
                EnvVars:        make([]corev1.EnvVar, 0),
                ExecutedTraits: make([]Trait, 0),
-               Resources:      kubernetes.NewCollection(&appsv1.Deployment{}),
+               Resources:      kubernetes.NewCollection(),
                Classpath:      strset.New(),
        }
 
@@ -195,6 +202,7 @@ func TestService(t *testing.T) {
        assert.NotEmpty(t, environment.ExecutedTraits)
        assert.NotNil(t, environment.GetTrait(ID("deployment")))
        assert.NotNil(t, environment.GetTrait(ID("service")))
+       assert.NotNil(t, environment.GetTrait(ID("container")))
 
        s := environment.Resources.GetService(func(service *corev1.Service) 
bool {
                return service.Name == ServiceTestName
diff --git a/pkg/trait/trait_catalog.go b/pkg/trait/trait_catalog.go
index ffb2b79..b6a9938 100644
--- a/pkg/trait/trait_catalog.go
+++ b/pkg/trait/trait_catalog.go
@@ -134,15 +134,15 @@ func (c *Catalog) traitsFor(environment *Environment) 
[]Trait {
                        c.tDependencies,
                        c.tBuilder,
                        c.tEnvironment,
-                       c.tJolokia,
-                       c.tPrometheus,
                        c.tDeployer,
                        c.tDeployment,
                        c.tAffinity,
+                       c.tService,
                        c.tContainer,
+                       c.tJolokia,
+                       c.tPrometheus,
                        c.tClasspath,
                        c.tProbes,
-                       c.tService,
                        c.tRoute,
                        c.tOwner,
                }
@@ -155,15 +155,15 @@ func (c *Catalog) traitsFor(environment *Environment) 
[]Trait {
                        c.tDependencies,
                        c.tBuilder,
                        c.tEnvironment,
-                       c.tJolokia,
-                       c.tPrometheus,
                        c.tDeployer,
                        c.tDeployment,
                        c.tAffinity,
+                       c.tService,
                        c.tContainer,
+                       c.tJolokia,
+                       c.tPrometheus,
                        c.tClasspath,
                        c.tProbes,
-                       c.tService,
                        c.tIngress,
                        c.tOwner,
                }
diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go
index 797f2ed..44ddda6 100644
--- a/pkg/trait/trait_test.go
+++ b/pkg/trait/trait_test.go
@@ -156,13 +156,13 @@ func TestTraitDecode(t *testing.T) {
        }
        env.Integration.Spec.Traits["service"] = svcTrait
 
-       svc := newServiceTrait()
-       err := decodeTraitSpec(&svcTrait, svc)
+       ctr := newContainerTrait()
+       err := decodeTraitSpec(&svcTrait, ctr)
 
        assert.Nil(t, err)
-       assert.Equal(t, 7071, svc.Port)
-       assert.NotNil(t, svc.Enabled)
-       assert.Equal(t, false, *svc.Enabled)
+       assert.Equal(t, 7071, ctr.Port)
+       assert.NotNil(t, ctr.Enabled)
+       assert.Equal(t, false, *ctr.Enabled)
 }
 
 func TestTraitHierarchyDecode(t *testing.T) {
diff --git a/pkg/util/kubernetes/collection.go 
b/pkg/util/kubernetes/collection.go
index 418b2db..ca27e9a 100644
--- a/pkg/util/kubernetes/collection.go
+++ b/pkg/util/kubernetes/collection.go
@@ -198,6 +198,16 @@ func (c *Collection) 
GetUserServiceForIntegration(integration *v1alpha1.Integrat
        })
 }
 
+// GetServiceForIntegration returns a user Service for the given integration
+func (c *Collection) GetServiceForIntegration(integration 
*v1alpha1.Integration) *corev1.Service {
+       if integration == nil {
+               return nil
+       }
+       return c.GetService(func(s *corev1.Service) bool {
+               return s.ObjectMeta.Labels != nil && 
s.ObjectMeta.Labels["camel.apache.org/integration"] == integration.Name
+       })
+}
+
 // GetKnativeService returns a knative Service that matches the given function
 func (c *Collection) GetKnativeService(filter func(*serving.Service) bool) 
*serving.Service {
        var retValue *serving.Service
@@ -251,6 +261,17 @@ func (c *Collection) GetContainer(filter func(container 
*corev1.Container) bool)
        return retValue
 }
 
+// GetContainerForIntegration --
+func (c *Collection) GetContainerForIntegration(integration 
*v1alpha1.Integration) *corev1.Container {
+       if integration == nil {
+               return nil
+       }
+
+       return c.GetContainer(func(c *corev1.Container) bool {
+               return c.Name == integration.Name
+       })
+}
+
 // VisitContainer executes the visitor function on all Containers inside 
deployments or other resources
 func (c *Collection) VisitContainer(visitor func(container *corev1.Container)) 
{
        c.VisitDeployment(func(d *appsv1.Deployment) {

Reply via email to