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 2021/04/29 13:12:14 UTC
[camel-k] branch main updated (fc0cc52 -> cc4e016)
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git.
from fc0cc52 Updated CHANGELOG.md
new f7ad34d feat(kamelets): error handling kamelets binding support
new 1cbec51 doc(example): kameletbinding error handler
new a488a3a fix(kamelets): optional error handler
new 1849ca5 feat(kamelets): error handling kamelets binding support
new 619806d feat(crd): kameletbinding error handler
new 924378e doc(example): error handling kamelet binding
new 9287343 feat(trait): error handler trait
new 34c82df refactor(trait): integration error handler spec
new 3b8ae4a refactor(trait): error handler kamelet
new 096e5de doc(example): error handler DLC
new 5eaff76 refactor(crd): updated crd after error-handler
new 0aae942 doc(trait): error-handler generated doc
new 647b82f feat(trait): error handler advanced configuration
new 68aaeb4 fix(trait): default error handler configuration setting
new 92d1c5d refactor(trait): error handler spec definition
new d922c4a chore(controller): error handler unit test
new bb48d9a feat(trait): error handler Ref
new 7728261 feat(trait): error handler bean
new df34cad refactor(trait): error handler to bean ref
new 5eb36ef refactor(trait): error handler using bean ref
new 71e0624 refactor(controller): app properties binding
new d1a72fd refactor(trait): error handler language to yaml
new 2f621da refactor(controller): error handler useless uri
new 987fc9d refactor(controller): error handler bean properties
new 88d3706 chore(crd): error handler generated crds
new 8b1974c chore(doc): error handler generated
new 8f91086 doc(kamelets): kamelet bindings error handler
new 82df277 chore(trait): polishing PR
new 855f4a7 feat(e2e): error handler integration test
new cc4e016 doc(trait): regen
The 30 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../bases/camel.apache.org_kameletbindings.yaml | 5 +
.../1.4.0/camel.apache.org_kameletbindings.yaml | 20 ++
.../camel.apache.org_kameletbindings.yaml | 5 +
deploy/traits.yaml | 16 ++
docs/modules/ROOT/nav.adoc | 1 +
.../kamelets/kameletbindings-error-handler.adoc | 156 ++++++++++++++
.../modules/ROOT/pages/kamelets/kamelets-user.adoc | 4 +
docs/modules/ROOT/pages/kamelets/kamelets.adoc | 1 +
.../pages/{builder.adoc => error-handler.adoc} | 17 +-
.../js_test.go => traits/error_handler_test.go} | 28 ++-
.../traits/files/ErroredRoute.java} | 9 +-
.../error-handler/error-handler.kamelet.yaml | 29 ++-
.../incremental-id-source.kamelet.yaml | 31 ++-
.../kamelet-binding-error-handler.yaml | 44 ++--
.../log-sink.kamelet.yaml} | 24 +--
examples/kamelets/error-handler/readme.md | 71 +++++++
helm/camel-k/crds/crd-kamelet-binding.yaml | 5 +
pkg/apis/camel/v1/common_types.go | 5 +-
pkg/apis/camel/v1/integration_types_support.go | 13 ++
pkg/apis/camel/v1alpha1/error_handler_types.go | 229 +++++++++++++++++++++
pkg/apis/camel/v1alpha1/kamelet_binding_types.go | 9 +-
pkg/controller/kameletbinding/common.go | 17 +-
pkg/controller/kameletbinding/error_handler.go | 110 ++++++++++
.../kameletbinding/error_handler_test.go | 134 ++++++++++++
pkg/resources/resources.go | 2 +-
pkg/trait/error_handler.go | 91 ++++++++
pkg/trait/kamelets.go | 28 ++-
pkg/trait/trait_register.go | 1 +
pkg/trait/trait_test.go | 2 +-
29 files changed, 1003 insertions(+), 104 deletions(-)
create mode 100644 docs/modules/ROOT/pages/kamelets/kameletbindings-error-handler.adoc
copy docs/modules/traits/pages/{builder.adoc => error-handler.adoc} (58%)
copy e2e/common/{languages/js_test.go => traits/error_handler_test.go} (54%)
copy e2e/{builder/files/Java.java => common/traits/files/ErroredRoute.java} (83%)
copy e2e/yaks/common/kamelet-steps/prefix-action.kamelet.yaml => examples/kamelets/error-handler/error-handler.kamelet.yaml (72%)
copy e2e/yaks/common/kamelet-binding-http/timer-source.kamelet.yaml => examples/kamelets/error-handler/incremental-id-source.kamelet.yaml (69%)
copy e2e/yaks/common/kamelet-steps/steps-binding.yaml => examples/kamelets/error-handler/kamelet-binding-error-handler.yaml (63%)
copy examples/kamelets/{timer-source-log-sink/log-sink.binding.yaml => error-handler/log-sink.kamelet.yaml} (79%)
create mode 100644 examples/kamelets/error-handler/readme.md
create mode 100644 pkg/apis/camel/v1alpha1/error_handler_types.go
create mode 100644 pkg/controller/kameletbinding/error_handler.go
create mode 100644 pkg/controller/kameletbinding/error_handler_test.go
create mode 100644 pkg/trait/error_handler.go
[camel-k] 30/30: doc(trait): regen
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit cc4e01653f1ada233a0cd04d89485e33e2e2c0fa
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Apr 28 14:42:54 2021 +0200
doc(trait): regen
---
deploy/traits.yaml | 4 ++--
docs/modules/traits/pages/error-handler.adoc | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/deploy/traits.yaml b/deploy/traits.yaml
index b2c3af3..6f90900 100755
--- a/deploy/traits.yaml
+++ b/deploy/traits.yaml
@@ -284,9 +284,9 @@ traits:
type: bool
description: Can be used to enable or disable a trait. All traits share this common
property.
- - name: error-handler-ref
+ - name: ref
type: string
- description: The error handler ref name found in application properties
+ description: The error handler ref name provided or found in application properties
- name: gc
platform: false
profiles:
diff --git a/docs/modules/traits/pages/error-handler.adoc b/docs/modules/traits/pages/error-handler.adoc
index 978e76f..7ddfd17 100755
--- a/docs/modules/traits/pages/error-handler.adoc
+++ b/docs/modules/traits/pages/error-handler.adoc
@@ -27,9 +27,9 @@ The following configuration options are available:
| bool
| Can be used to enable or disable a trait. All traits share this common property.
-| error-handler.error-handler-ref
+| error-handler.ref
| string
-| The error handler ref name found in application properties
+| The error handler ref name provided or found in application properties
|===
[camel-k] 26/30: chore(doc): error handler generated
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 8b1974ca12b48b9d48f4f08d3aacfb3e3ecb4d6a
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 27 11:31:56 2021 +0200
chore(doc): error handler generated
---
deploy/traits.yaml | 9 ++++++++-
docs/modules/traits/pages/error-handler.adoc | 6 +++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/deploy/traits.yaml b/deploy/traits.yaml
index 0c567dd..22cc617 100755
--- a/deploy/traits.yaml
+++ b/deploy/traits.yaml
@@ -279,7 +279,14 @@ traits:
- OpenShift
description: The error-handler is a platform trait used to inject Error Handler
source into the integration runtime.
- properties: []
+ properties:
+ - name: enabled
+ type: bool
+ description: Can be used to enable or disable a trait. All traits share this common
+ property.
+ - name: ',omitempty'
+ type: string
+ description: The error handler ref name found in application properties
- name: gc
platform: false
profiles:
diff --git a/docs/modules/traits/pages/error-handler.adoc b/docs/modules/traits/pages/error-handler.adoc
index 0c38c7d..149eaee 100755
--- a/docs/modules/traits/pages/error-handler.adoc
+++ b/docs/modules/traits/pages/error-handler.adoc
@@ -15,7 +15,7 @@ WARNING: The error-handler trait is a *platform trait*: disabling it may comprom
Trait properties can be specified when running any integration with the CLI:
[source,console]
----
-$ kamel run --trait error-handler.[key]=[value] integration.groovy
+$ kamel run --trait error-handler.[key]=[value] --trait error-handler.[key2]=[value2] integration.groovy
----
The following configuration options are available:
@@ -27,6 +27,10 @@ The following configuration options are available:
| bool
| Can be used to enable or disable a trait. All traits share this common property.
+| error-handler.,omitempty
+| string
+| The error handler ref name found in application properties
+
|===
// End of autogenerated code - DO NOT EDIT! (configuration)
[camel-k] 08/30: refactor(trait): integration error handler spec
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 34c82df0eea0b75e4dece804604732eec13d50ef
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Apr 21 10:04:02 2021 +0200
refactor(trait): integration error handler spec
---
pkg/apis/camel/v1/common_types.go | 12 +++++++
pkg/apis/camel/v1/integration_types.go | 9 ++---
pkg/controller/kameletbinding/common.go | 14 ++++----
pkg/trait/error_handler.go | 59 +++++----------------------------
pkg/trait/kamelets.go | 19 +++++------
5 files changed, 39 insertions(+), 74 deletions(-)
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index e5b327b..e1b27e1 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -162,6 +162,18 @@ type Flow struct {
RawMessage `json:",inline"`
}
+// ErrorHandlerSpec respresents an integration error handler to be used as default at runtime
+type ErrorHandlerSpec struct {
+ Type string `json:"type,omitempty"`
+ URI string `json:"uri,omitempty"`
+ Configuration *ErrorHandlerConfiguration `json:"configuration,omitempty"`
+}
+
+// ErrorHandlerConfiguration --
+type ErrorHandlerConfiguration struct {
+ RawMessage `json:",inline"`
+}
+
// RuntimeProvider --
type RuntimeProvider string
diff --git a/pkg/apis/camel/v1/integration_types.go b/pkg/apis/camel/v1/integration_types.go
index 6ba7e10..500291c 100644
--- a/pkg/apis/camel/v1/integration_types.go
+++ b/pkg/apis/camel/v1/integration_types.go
@@ -27,10 +27,11 @@ import (
// IntegrationSpec defines the desired state of Integration
type IntegrationSpec struct {
- Replicas *int32 `json:"replicas,omitempty"`
- Sources []SourceSpec `json:"sources,omitempty"`
- Flows []Flow `json:"flows,omitempty"`
- Resources []ResourceSpec `json:"resources,omitempty"`
+ Replicas *int32 `json:"replicas,omitempty"`
+ Sources []SourceSpec `json:"sources,omitempty"`
+ ErrorHandler ErrorHandlerSpec `json:"errorHandler,omitempty"`
+ Flows []Flow `json:"flows,omitempty"`
+ Resources []ResourceSpec `json:"resources,omitempty"`
// Deprecated: use the IntegrationKit field
Kit string `json:"kit,omitempty"`
IntegrationKit *corev1.ObjectReference `json:"integrationKit,omitempty"`
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index a63780f..13e13fe 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -86,9 +86,9 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
return nil, errors.Wrap(err, "could not determine error handler URI")
}
- err = setErrorHandlerKamelet(errorHandler, kameletbinding.Spec.ErrorHandler)
+ err = setIntegrationErrorHandler(&it.Spec, errorHandler, kameletbinding.Spec.ErrorHandler)
if err != nil {
- return nil, errors.Wrap(err, "could not set error handler")
+ return nil, errors.Wrap(err, "could not set integration error handler")
}
}
@@ -159,14 +159,12 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
return &it, nil
}
-func setErrorHandlerKamelet(errorHandler *bindings.Binding, errorHandlerSpec v1alpha1.ErrorHandler) error {
- if errorHandler.ApplicationProperties == nil {
- errorHandler.ApplicationProperties = make(map[string]string)
+func setIntegrationErrorHandler(it *v1.IntegrationSpec, errorHandler *bindings.Binding, errorHandlerSpec v1alpha1.ErrorHandler) error {
+ it.ErrorHandler = v1.ErrorHandlerSpec{
+ URI: errorHandler.URI,
+ Type: string(errorHandlerSpec.Type),
}
- errorHandler.ApplicationProperties["camel.k.default-error-handler.uri"] = errorHandler.URI
- errorHandler.ApplicationProperties["camel.k.default-error-handler.type"] = string(errorHandlerSpec.Type)
-
return nil
}
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index 7101d9e..228ed12 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -19,10 +19,8 @@ package trait
import (
"fmt"
- "strings"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
- "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
)
// The error handler is a platform trait used to inject Error Handler source into the integration runtime.
@@ -30,12 +28,7 @@ import (
// +camel-k:trait=error-handler
type errorHandlerTrait struct {
BaseTrait `property:",squash"`
- // Automatically inject all referenced Kamelets and their default configuration (enabled by default)
- Auto *bool `property:"auto"`
-
- // TODO move into a struct
- ErrorHandlerURI string
- ErrorHandlerType string
+ Auto *bool `property:"auto"`
}
func newErrorHandlerTrait() Trait {
@@ -58,50 +51,14 @@ func (t *errorHandlerTrait) Configure(e *Environment) (bool, error) {
return false, nil
}
- if t.Auto == nil || *t.Auto {
- if t.ErrorHandlerType == "" {
- t.ErrorHandlerType = maybeErrorHandler(e.Integration.Configurations())
- if t.ErrorHandlerType != "" && v1alpha1.ErrorHandlerType(t.ErrorHandlerType) == v1alpha1.ErrorHandlerTypeDeadLetterChannel {
- t.ErrorHandlerURI = maybeKameletAsDefaultErrorHandler(e.Integration.Configurations())
- }
- }
- }
-
- return t.ErrorHandlerType != "", nil
-}
-
-func maybeErrorHandler(properties []v1.ConfigurationSpec) string {
- for _, property := range properties {
- if strings.HasPrefix(property.Value, "camel.k.default-error-handler.type=") {
- split := strings.Split(property.Value, "=")
- if len(split) > 0 {
- return split[1]
- }
- }
- }
-
- return ""
-}
-
-func maybeKameletAsDefaultErrorHandler(properties []v1.ConfigurationSpec) string {
- for _, property := range properties {
- if strings.HasPrefix(property.Value, "camel.k.default-error-handler.uri=") {
- split := strings.Split(property.Value, "=")
- if len(split) > 0 {
- return split[1]
- }
- }
- }
-
- return ""
+ return e.Integration.Spec.ErrorHandler.Type != "", nil
}
func (t *errorHandlerTrait) Apply(e *Environment) error {
-
if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
- if t.ErrorHandlerType != "" {
+ if e.Integration.Spec.ErrorHandler.Type != "" {
// Possible error handler
- err := addErrorHandlerAsSource(e, t.ErrorHandlerURI, t.ErrorHandlerType)
+ err := addErrorHandlerAsSource(e)
if err != nil {
return err
}
@@ -110,8 +67,8 @@ func (t *errorHandlerTrait) Apply(e *Environment) error {
return nil
}
-func addErrorHandlerAsSource(e *Environment, errorHandlerURI string, errorHandlerType string) error {
- errorHandlerStatement, err := parseErrorHandler(errorHandlerURI, errorHandlerType)
+func addErrorHandlerAsSource(e *Environment) error {
+ errorHandlerStatement, err := parseErrorHandler(e.Integration.Spec.ErrorHandler.URI, e.Integration.Spec.ErrorHandler.Type)
if err != nil {
return err
}
@@ -148,14 +105,14 @@ func addErrorHandlerAsSource(e *Environment, errorHandlerURI string, errorHandle
return nil
}
-func parseErrorHandler(errHandlUri string, errHandlType string) (string, error) {
+func parseErrorHandler(errHandlURI string, errHandlType string) (string, error) {
switch errHandlType {
case "no":
return `errorHandler(noErrorHandler());`, nil
case "default":
return `errorHandler(defaultErrorHandler());`, nil
case "dead-letter-channel":
- return fmt.Sprintf(`errorHandler(deadLetterChannel("%v"));`, errHandlUri), nil
+ return fmt.Sprintf(`errorHandler(deadLetterChannel("%v"));`, errHandlURI), nil
}
return "", fmt.Errorf("Cannot recognize any error handler of type %s", errHandlType)
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index dd4c3bb..190c17e 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -47,10 +47,6 @@ type kameletsTrait struct {
Auto *bool `property:"auto"`
// Comma separated list of Kamelet names to load into the current integration
List string `property:"list"`
-
- // TODO move into a struct
- ErrorHandlerURI string
- ErrorHandlerType string
}
type configurationKey struct {
@@ -111,13 +107,10 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
})
sort.Strings(kamelets)
}
- if t.ErrorHandlerType == "" {
- t.ErrorHandlerType = maybeErrorHandler(e.Integration.Configurations())
- if t.ErrorHandlerType != "" && v1alpha1.ErrorHandlerType(t.ErrorHandlerType) == v1alpha1.ErrorHandlerTypeDeadLetterChannel {
- t.ErrorHandlerURI = maybeKameletAsDefaultErrorHandler(e.Integration.Configurations())
- if strings.HasPrefix(t.ErrorHandlerURI, "kamelet:") {
- kamelets = append(kamelets, extractKamelet(t.ErrorHandlerURI))
- }
+ // Check if a Kamelet is configured as default error handler
+ if e.Integration.Spec.ErrorHandler.URI != "" {
+ if strings.HasPrefix(e.Integration.Spec.ErrorHandler.URI, "kamelet:") {
+ kamelets = append(kamelets, extractKamelet(e.Integration.Spec.ErrorHandler.URI))
}
}
@@ -132,8 +125,12 @@ func (t *kameletsTrait) declaredKamelets() bool {
}
func (t *kameletsTrait) Apply(e *Environment) error {
+<<<<<<< HEAD
if e.IntegrationInPhase(v1.IntegrationPhaseInitialization, v1.IntegrationPhaseRunning) {
+=======
+ if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
+>>>>>>> refactor(trait): integration error handler spec
if err := t.addKamelets(e); err != nil {
return err
}
[camel-k] 19/30: refactor(trait): error handler to bean ref
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit df34cad4b8cd4d5003fb4f512518010cd7eacd50
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Fri Apr 23 17:09:59 2021 +0200
refactor(trait): error handler to bean ref
---
pkg/apis/camel/v1/common_types.go | 12 ----
pkg/apis/camel/v1/integration_types.go | 9 ++-
pkg/apis/camel/v1/integration_types_support.go | 27 +++++++++
pkg/apis/camel/v1alpha1/error_handler_types.go | 39 ++++++++++++-
pkg/controller/kameletbinding/error_handler.go | 24 +++-----
.../kameletbinding/error_handler_test.go | 13 ++++-
pkg/trait/error_handler.go | 68 +++-------------------
pkg/trait/kamelets.go | 9 +--
8 files changed, 102 insertions(+), 99 deletions(-)
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index 71774fc..e5b327b 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -162,18 +162,6 @@ type Flow struct {
RawMessage `json:",inline"`
}
-// ErrorHandlerSpec respresents an integration error handler to be used as default at runtime
-type ErrorHandlerSpec struct {
- Type string `json:"type,omitempty"`
- URI string `json:"uri,omitempty"`
- Parameters *ErrorHandlerParameters `json:"parameters,omitempty"`
-}
-
-// ErrorHandlerParameters is an unstructured object representing the configuration parameters available for an error handler
-type ErrorHandlerParameters struct {
- RawMessage `json:",inline"`
-}
-
// RuntimeProvider --
type RuntimeProvider string
diff --git a/pkg/apis/camel/v1/integration_types.go b/pkg/apis/camel/v1/integration_types.go
index 500291c..6ba7e10 100644
--- a/pkg/apis/camel/v1/integration_types.go
+++ b/pkg/apis/camel/v1/integration_types.go
@@ -27,11 +27,10 @@ import (
// IntegrationSpec defines the desired state of Integration
type IntegrationSpec struct {
- Replicas *int32 `json:"replicas,omitempty"`
- Sources []SourceSpec `json:"sources,omitempty"`
- ErrorHandler ErrorHandlerSpec `json:"errorHandler,omitempty"`
- Flows []Flow `json:"flows,omitempty"`
- Resources []ResourceSpec `json:"resources,omitempty"`
+ Replicas *int32 `json:"replicas,omitempty"`
+ Sources []SourceSpec `json:"sources,omitempty"`
+ Flows []Flow `json:"flows,omitempty"`
+ Resources []ResourceSpec `json:"resources,omitempty"`
// Deprecated: use the IntegrationKit field
Kit string `json:"kit,omitempty"`
IntegrationKit *corev1.ObjectReference `json:"integrationKit,omitempty"`
diff --git a/pkg/apis/camel/v1/integration_types_support.go b/pkg/apis/camel/v1/integration_types_support.go
index 53705c9..295c75a 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -131,6 +131,33 @@ func (in *IntegrationSpec) AddDependency(dependency string) {
in.Dependencies = append(in.Dependencies, newDep)
}
+// HasDefaultErrorHandler checks the configuration properties to see if a default error handler is declared
+func (in *IntegrationSpec) HasDefaultErrorHandler() bool {
+ return in.GetDefaultErrorHandler() != ""
+}
+
+// GetDefaultErrorHandler returns the default error handler, if it is declared
+func (in *IntegrationSpec) GetDefaultErrorHandler() string {
+ return in.getConfigurationProperty("camel.beans.defaultErrorHandler")
+}
+
+// GetDefaultErrorHandlerURI returns the default error handler uri, if it is declared
+func (in *IntegrationSpec) GetDefaultErrorHandlerURI() string {
+ return in.getConfigurationProperty("camel.beans.defaultErrorHandler.uri")
+}
+
+func (in *IntegrationSpec) getConfigurationProperty(property string) string {
+ for _, confSpec := range in.Configuration {
+ if confSpec.Type == "property" && strings.HasPrefix(confSpec.Value, property) {
+ splitConf := strings.Split(confSpec.Value, "=")
+ if len(splitConf) > 0 {
+ return splitConf[1]
+ }
+ }
+ }
+ return ""
+}
+
// AddOrReplaceGeneratedResources --
func (in *IntegrationStatus) AddOrReplaceGeneratedResources(resources ...ResourceSpec) {
newResources := make([]ResourceSpec, 0)
diff --git a/pkg/apis/camel/v1alpha1/error_handler_types.go b/pkg/apis/camel/v1alpha1/error_handler_types.go
index 1969e2b..d40bf6f 100644
--- a/pkg/apis/camel/v1alpha1/error_handler_types.go
+++ b/pkg/apis/camel/v1alpha1/error_handler_types.go
@@ -18,9 +18,13 @@ limitations under the License.
package v1alpha1
import (
+ "encoding/json"
+
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
)
+const errorHandlerAppPropertiesPrefix = "camel.beans.defaultErrorHandler"
+
// ErrorHandlerSpec represents an unstructured object for an error handler
type ErrorHandlerSpec struct {
v1.RawMessage `json:",omitempty"`
@@ -43,6 +47,7 @@ type ErrorHandler interface {
Endpoint() *Endpoint
Ref() *string
Bean() *string
+ Configuration() (map[string]interface{}, error)
}
type abstractErrorHandler struct {
@@ -68,11 +73,16 @@ func (e abstractErrorHandler) Ref() *string {
return nil
}
-// Ref --
+// Bean --
func (e abstractErrorHandler) Bean() *string {
return nil
}
+// Configuration --
+func (e abstractErrorHandler) Configuration() (map[string]interface{}, error) {
+ return nil, nil
+}
+
// ErrorHandlerNone --
type ErrorHandlerNone struct {
*abstractErrorHandler
@@ -83,6 +93,13 @@ func (e ErrorHandlerNone) Type() ErrorHandlerType {
return ErrorHandlerTypeNone
}
+// Configuration --
+func (e ErrorHandlerNone) Configuration() (map[string]interface{}, error) {
+ return map[string]interface{}{
+ errorHandlerAppPropertiesPrefix: "#class:org.apache.camel.builder.NoErrorHandlerBuilder",
+ }, nil
+}
+
// ErrorHandlerLog represent a default (log) error handler type
type ErrorHandlerLog struct {
*abstractErrorHandler
@@ -99,6 +116,26 @@ func (e ErrorHandlerLog) Params() *ErrorHandlerParameters {
return e.Parameters
}
+// Configuration --
+func (e ErrorHandlerLog) Configuration() (map[string]interface{}, error) {
+ properties := map[string]interface{}{
+ errorHandlerAppPropertiesPrefix: "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder",
+ }
+
+ if e.Params() != nil {
+ var parameters map[string]interface{}
+ err := json.Unmarshal(e.Params().RawMessage, ¶meters)
+ if err != nil {
+ return nil, err
+ }
+ for key, value := range parameters {
+ properties[errorHandlerAppPropertiesPrefix+"."+key] = value
+ }
+ }
+
+ return properties, nil
+}
+
// ErrorHandlerDeadLetterChannel represents a dead letter channel error handler type
type ErrorHandlerDeadLetterChannel struct {
*ErrorHandlerLog
diff --git a/pkg/controller/kameletbinding/error_handler.go b/pkg/controller/kameletbinding/error_handler.go
index 15e72bb..0cf95b6 100644
--- a/pkg/controller/kameletbinding/error_handler.go
+++ b/pkg/controller/kameletbinding/error_handler.go
@@ -19,6 +19,7 @@ package kameletbinding
import (
"encoding/json"
+ "fmt"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -33,21 +34,17 @@ func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandlerSpec, bindingContext bi
if err != nil {
return nil, errors.Wrap(err, "could not parse error handler")
}
+ // We need to get the translated URI from any referenced resource (ie, kamelets)
errorHandlerURI := ""
if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeDeadLetterChannel {
errorHandler, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, *errorHandlerSpec.Endpoint())
if err != nil {
return nil, errors.Wrap(err, "could not determine error handler URI")
}
-
errorHandlerURI = errorHandler.URI
- } else if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeRef {
- errorHandlerURI = *errorHandlerSpec.Ref()
- } else if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeBean {
- errorHandlerURI = *errorHandlerSpec.Bean()
}
- err = setIntegrationErrorHandler(itSpec, errorHandlerURI, errorHandlerSpec)
+ err = setErrorHandlerConfiguration(itSpec, errorHandlerURI, errorHandlerSpec)
if err != nil {
return nil, errors.Wrap(err, "could not set integration error handler")
}
@@ -95,16 +92,13 @@ func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.ErrorHandler, error)
return nil, errors.New("You must provide any supported error handler (none, log, dead-letter-channel)")
}
-func setIntegrationErrorHandler(it *v1.IntegrationSpec, errorHandlerURI string, errorHandlerSpec v1alpha1.ErrorHandler) error {
- it.ErrorHandler = v1.ErrorHandlerSpec{
- Type: string(errorHandlerSpec.Type()),
- }
- if errorHandlerSpec.Params() != nil {
- it.ErrorHandler.Parameters = &v1.ErrorHandlerParameters{errorHandlerSpec.Params().RawMessage}
+func setErrorHandlerConfiguration(it *v1.IntegrationSpec, errorHandlerURI string, errorHandler v1alpha1.ErrorHandler) error {
+ properties, err := errorHandler.Configuration()
+ if err != nil {
+ return err
}
- if errorHandlerURI != "" {
- it.ErrorHandler.URI = errorHandlerURI
+ for key, value := range properties {
+ it.AddConfiguration("property", fmt.Sprintf("%s=%v", key, value))
}
-
return nil
}
diff --git a/pkg/controller/kameletbinding/error_handler_test.go b/pkg/controller/kameletbinding/error_handler_test.go
index 40864b9..e05caf4 100644
--- a/pkg/controller/kameletbinding/error_handler_test.go
+++ b/pkg/controller/kameletbinding/error_handler_test.go
@@ -30,6 +30,9 @@ func TestParseErrorHandlerNoneDoesSucceed(t *testing.T) {
)
assert.Nil(t, err)
assert.Equal(t, v1alpha1.ErrorHandlerTypeNone, noErrorHandler.Type())
+ parameters, err := noErrorHandler.Configuration()
+ assert.Nil(t, err)
+ assert.Equal(t, "#class:org.apache.camel.builder.NoErrorHandlerBuilder", parameters["camel.beans.defaultErrorHandler"])
}
func TestParseErrorHandlerLogDoesSucceed(t *testing.T) {
@@ -38,15 +41,23 @@ func TestParseErrorHandlerLogDoesSucceed(t *testing.T) {
)
assert.Nil(t, err)
assert.Equal(t, v1alpha1.ErrorHandlerTypeLog, logErrorHandler.Type())
+ parameters, err := logErrorHandler.Configuration()
+ assert.Nil(t, err)
+ assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters["camel.beans.defaultErrorHandler"])
}
func TestParseErrorHandlerLogWithParametersDoesSucceed(t *testing.T) {
logErrorHandler, err := parseErrorHandler(
- []byte(`{"log": {"parameters": [{"param1": "value1"}, {"param2": "value2"}]}}`),
+ []byte(`{"log": {"parameters": {"param1": "value1", "param2": "value2"}}}`),
)
assert.Nil(t, err)
assert.Equal(t, v1alpha1.ErrorHandlerTypeLog, logErrorHandler.Type())
assert.NotNil(t, logErrorHandler.Params())
+ parameters, err := logErrorHandler.Configuration()
+ assert.Nil(t, err)
+ assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters["camel.beans.defaultErrorHandler"])
+ assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"])
+ assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.param2"])
}
func TestParseErrorHandlerDLCDoesSucceed(t *testing.T) {
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index c2aee73..b7a8c0d 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -18,7 +18,6 @@ limitations under the License.
package trait
import (
- "encoding/json"
"fmt"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
@@ -51,41 +50,33 @@ func (t *errorHandlerTrait) Configure(e *Environment) (bool, error) {
return false, nil
}
- return e.Integration.Spec.ErrorHandler.Type != "", nil
+ return e.Integration.Spec.HasDefaultErrorHandler(), nil
}
func (t *errorHandlerTrait) Apply(e *Environment) error {
if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
- if e.Integration.Spec.ErrorHandler.Type != "" {
- // Possible error handler
- err := addErrorHandlerAsSource(e)
- if err != nil {
- return err
- }
+ err := addErrorHandlerAsSource(e)
+ if err != nil {
+ return err
}
}
return nil
}
func addErrorHandlerAsSource(e *Environment) error {
- errorHandlerStatement, err := parseErrorHandler(e)
- if err != nil {
- return err
- }
-
// TODO change to yaml flow when we fix https://issues.apache.org/jira/browse/CAMEL-16486
errorHandlerSource := v1.SourceSpec{
DataSpec: v1.DataSpec{
Name: "ErrorHandlerSource.java",
- Content: fmt.Sprintf(`
+ Content: `
import org.apache.camel.builder.RouteBuilder;
public class ErrorHandlerSource extends RouteBuilder {
@Override
public void configure() throws Exception {
- %s
+ errorHandler("defaultErrorHandler");
}
}
- `, errorHandlerStatement),
+ `,
},
Language: v1.LanguageJavaSource,
Type: v1.SourceTypeErrorHandler,
@@ -104,48 +95,3 @@ func addErrorHandlerBeanConfiguration(e *Environment, fqn string) error {
})
return nil
}
-
-func parseErrorHandler(e *Environment) (string, error) {
- errorHandlerSpec := e.Integration.Spec.ErrorHandler
- switch errorHandlerSpec.Type {
- case "none":
- return `errorHandler(noErrorHandler());`, nil
- case "log":
- errorHandlerConfiguration, err := parseErrorHandlerConfiguration(errorHandlerSpec.Parameters)
- if err != nil {
- return "", err
- }
-
- return fmt.Sprintf(`errorHandler(defaultErrorHandler()%v);`, errorHandlerConfiguration), nil
- case "dead-letter-channel":
- errorHandlerConfiguration, err := parseErrorHandlerConfiguration(errorHandlerSpec.Parameters)
- if err != nil {
- return "", err
- }
-
- return fmt.Sprintf(`errorHandler(deadLetterChannel("%v")%v);`, errorHandlerSpec.URI, errorHandlerConfiguration), nil
- case "ref":
- // TODO using URI temporarily, fix it properly
- return fmt.Sprintf(`errorHandler("%v");`, errorHandlerSpec.URI), nil
- case "bean":
- // TODO using URI temporarily, fix it properly
- addErrorHandlerBeanConfiguration(e, errorHandlerSpec.URI)
- return fmt.Sprintf(`errorHandler("%v");`, "defaultErrorHandler"), nil
- }
-
- return "", fmt.Errorf("Cannot recognize any error handler of type %s", errorHandlerSpec.Type)
-}
-
-func parseErrorHandlerConfiguration(conf *v1.ErrorHandlerParameters) (string, error) {
- javaPropertiesBuilder := ""
- var properties map[string]interface{}
- err := json.Unmarshal(conf.RawMessage, &properties)
- if err != nil {
- return "", err
- }
- for method, value := range properties {
- javaPropertiesBuilder = javaPropertiesBuilder + fmt.Sprintf(".%s(%v)\n", method, value)
- }
-
- return javaPropertiesBuilder, nil
-}
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index 57ec4b5..83a35a9 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -106,10 +106,11 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
return true
})
}
- // Check if a Kamelet is configured as default error handler
- if e.Integration.Spec.ErrorHandler.URI != "" {
- if strings.HasPrefix(e.Integration.Spec.ErrorHandler.URI, "kamelet:") {
- kamelets = append(kamelets, extractKamelet(e.Integration.Spec.ErrorHandler.URI))
+ // Check if a Kamelet is configured as default error handler URI
+ defaultErrorHandlerURI := e.Integration.Spec.GetDefaultErrorHandlerURI()
+ if defaultErrorHandlerURI != "" {
+ if strings.HasPrefix(defaultErrorHandlerURI, "kamelet:") {
+ kamelets = append(kamelets, extractKamelet(defaultErrorHandlerURI))
}
}
[camel-k] 10/30: doc(example): error handler DLC
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 096e5de959593a4521300e0ffe669b6ec8fbd8a2
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Apr 21 15:14:19 2021 +0200
doc(example): error handler DLC
---
.../error-handler/error-handler.kamelet.yaml | 35 +++++++++++-----------
.../kamelet-binding-error-handler.yaml | 13 ++++----
examples/kamelets/error-handler/readme.md | 30 +++++++++++--------
3 files changed, 43 insertions(+), 35 deletions(-)
diff --git a/examples/kamelets/error-handler/error-handler.kamelet.yaml b/examples/kamelets/error-handler/error-handler.kamelet.yaml
index dbfc4bb..9ace959 100644
--- a/examples/kamelets/error-handler/error-handler.kamelet.yaml
+++ b/examples/kamelets/error-handler/error-handler.kamelet.yaml
@@ -20,21 +20,22 @@ kind: Kamelet
metadata:
name: error-handler
spec:
- sources:
- - content: |
- import org.apache.camel.builder.RouteBuilder;
- public class ErrorHandlerSource extends RouteBuilder {
- @Override
- public void configure() throws Exception {
- errorHandler(deadLetterChannel("log:error?showCaughtException=true&showException=true&showHeaders=true"));
- }
- }
- name: ErrorHandlerSource.java
definition:
- title: "Error Handler Log DLC"
- description: "Dead letter channel"
-# We can use the below once this is fixed https://issues.apache.org/jira/browse/CAMEL-16486
-# flow:
-# error-handler:
-# dead-letter-channel:
-# dead-letter-uri: log:error-sink?showCaughtException=true&showException=true&showHeaders=true
+ title: "Error Log Sink"
+ description: "Consume events from a channel"
+ required:
+ - message
+ properties:
+ message:
+ title: Message
+ description: The message to log
+ type: string
+ example: "error while checking the source"
+ flow:
+ from:
+ uri: kamelet:source
+ steps:
+# - to: my-dlc
+ - set-body:
+ constant: "{{message}}"
+ - to: "log:error-sink"
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
index 3602831..ae8eb78 100644
--- a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
+++ b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
@@ -31,9 +31,12 @@ spec:
apiVersion: camel.apache.org/v1alpha1
name: log-sink
errorHandler:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: error-handler
-# uri: kamelet:error-handler
+ type: dead-letter-channel
+ endpoint:
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1alpha1
+ name: error-handler
+ properties:
+ message: "ERROR!"
diff --git a/examples/kamelets/error-handler/readme.md b/examples/kamelets/error-handler/readme.md
index 5ff4777..dc4d75b 100644
--- a/examples/kamelets/error-handler/readme.md
+++ b/examples/kamelets/error-handler/readme.md
@@ -1,5 +1,5 @@
# Kamelets Binding Error Handler example
-This example shows how to create a simple _source_ `kamelet` bound to a log _sink_ in a `KameletBinding`. With the support of the `ErrorHandler` we will be able to redirect all errors to a `Dead Letter Channel` _error-handler_ `Kamelet`.
+This example shows how to create a simple _source_ `Kamelet` which sends periodically events (and certain failures). The events are consumed by a log _sink_ in a `KameletBinding`. With the support of the `ErrorHandler` we will be able to redirect all errors to a `Dead Letter Channel` _error-handler_ `Kamelet`.
## Incremental ID Source Kamelet
First of all, you must install the _incremental-id-source_ Kamelet defined in `incremental-id-source.kamelet.yaml` file. This source will emit events every second with an autoincrement counter that will be forced to fail when the number 0 is caught. With this trick, we will simulate possible event faults.
@@ -26,8 +26,8 @@ NAME PHASE
log-sink Ready
incremental-id-source Ready
```
-## Error handler Kamelet
-We finally install an error handler as a dead letter channel as specified in `error-handler.kamelet.yaml` file. You can specify any kind of error handler as expected by Apache Camel runtime.
+## Error handler Kamelet
+We finally install an error handler as specified in `error-handler.kamelet.yaml` file. This is a simple logger, but you can use any endpoint to collect and store the failing events.
```
$ kubectl apply -f error-handler.kamelet.yaml
```
@@ -41,14 +41,18 @@ log-sink Ready
incremental-id-source Ready
```
## Error Handler Kamelet Binding
-We can create a `KameletBinding` which is triggered by the _incremental-id-source_ `Kamelet` and log events to _log-sink_ `Kamelet`. As this will sporadically fail, we can configure an _errorHandler_ as defined in `kamelet-binding-error-handler.yaml` file:
+We can create a `KameletBinding` which is started by the _incremental-id-source_ `Kamelet` and log events to _log-sink_ `Kamelet`. As this will sporadically fail, we can configure an _errorHandler_ with the _error-handler_ `Kamelet` as **Dead Letter Channel**. We can declare it as in `kamelet-binding-error-handler.yaml` file:
```
...
errorHandler:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: error-handler
+ type: dead-letter-channel
+ endpoint:
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1alpha1
+ name: error-handler
+ properties:
+ message: "ERROR!"
```
Execute the following command to start the `Integration`:
```
@@ -56,9 +60,9 @@ kubectl apply -f kamelet-binding-error-handler.yaml
```
As soon as the `Integration` starts, it will log the events on the `ok` log channel and errors on the `error` log channel:
```
-[1] 2021-04-13 10:33:38,375 INFO [ok] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #8]
-[1] 2021-04-13 10:33:39,376 INFO [ok] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #9]
-[1] 2021-04-13 10:33:40,409 INFO [error] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, Headers: {firedTime=Tue Apr 13 10:33:40 GMT 2021}, BodyType: String, Body: Producing message #10, CaughtExceptionType: org.apache.camel.CamelExecutionException, CaughtExceptionMessage: Exception occurred during execution on the exchange: Exchange[]]
-[1] 2021-04-13 10:33:41,375 INFO [ok] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #11]
+[1] 2021-04-21 13:03:43,773 INFO [sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #8]
+[1] 2021-04-21 13:03:44,774 INFO [sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #9]
+[1] 2021-04-21 13:03:45,898 INFO [error-sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: ERROR!]
+[1] 2021-04-21 13:03:46,775 INFO [sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #11]
```
-This example is useful to guide you through the configuration of an error handler. In a production environment you will likely configure the error handler with a `Dead Letter Channel` pointing to a persistent queue.
\ No newline at end of file
+This example is useful to guide you through the configuration of an error handler. In a production environment you will likely configure the error handler `Kamelet` pointing to a persistent queue.
\ No newline at end of file
[camel-k] 29/30: feat(e2e): error handler integration test
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 855f4a74faca1b241a63cf4a5835e42d08efa453
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Apr 28 14:39:06 2021 +0200
feat(e2e): error handler integration test
---
e2e/common/traits/error_handler_test.go | 57 +++++++++++++++++++++++++++++++
e2e/common/traits/files/ErroredRoute.java | 29 ++++++++++++++++
pkg/trait/error_handler.go | 8 +++--
3 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/e2e/common/traits/error_handler_test.go b/e2e/common/traits/error_handler_test.go
new file mode 100644
index 0000000..506eba4
--- /dev/null
+++ b/e2e/common/traits/error_handler_test.go
@@ -0,0 +1,57 @@
+// +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"
+
+ v1 "k8s.io/api/core/v1"
+
+ . "github.com/apache/camel-k/e2e/support"
+ camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestErrorHandlerTrait(t *testing.T) {
+ WithNewTestNamespace(t, func(ns string) {
+ Expect(Kamel("install", "-n", ns).Execute()).To(Succeed())
+
+ t.Run("Run errored integration with error handler", func(t *testing.T) {
+ name := "error-handler"
+ Expect(Kamel("run", "-n", ns, "files/ErroredRoute.java",
+ "--name", name,
+ "-t", "error-handler.enabled=true",
+ "-t", "error-handler.ref=defaultErrorHandler",
+ "-p", "camel.beans.defaultErrorHandler=#class:org.apache.camel.builder.DeadLetterChannelBuilder",
+ "-p", "camel.beans.defaultErrorHandler.deadLetterUri=log:my-special-error-handler-in-place?level=ERROR&showCaughtException=false&showBody=false&showBodyType=false&showExchangePattern=false",
+ ).Execute()).To(Succeed())
+ Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(v1.PodRunning))
+ Eventually(IntegrationCondition(ns, name, camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+ Eventually(IntegrationLogs(ns, name), TestTimeoutShort).ShouldNot(ContainSubstring("InvalidPayloadException"))
+ Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("my-special-error-handler-in-place"))
+ })
+
+ // Clean up
+ Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+ })
+}
diff --git a/e2e/common/traits/files/ErroredRoute.java b/e2e/common/traits/files/ErroredRoute.java
new file mode 100644
index 0000000..702e163
--- /dev/null
+++ b/e2e/common/traits/files/ErroredRoute.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+import org.apache.camel.builder.RouteBuilder;
+
+public class ErroredRoute extends RouteBuilder {
+ @Override
+ public void configure() throws Exception {
+ from("timer:tick")
+ .setBody().simple("Hello")
+ // We want to force a failure
+ .setBody().simple("${mandatoryBodyAs(Boolean)}")
+ .to("log:info");
+ }
+}
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index a72a94a..aa59b4e 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -28,8 +28,8 @@ import (
// +camel-k:trait=error-handler
type errorHandlerTrait struct {
BaseTrait `property:",squash"`
- // The error handler ref name found in application properties
- ErrorHandlerRef string `property:"error-handler-ref" json:"error-handler-ref,omitempty"`
+ // The error handler ref name provided or found in application properties
+ ErrorHandlerRef string `property:"ref" json:"ref,omitempty"`
}
func newErrorHandlerTrait() Trait {
@@ -52,7 +52,9 @@ func (t *errorHandlerTrait) Configure(e *Environment) (bool, error) {
return false, nil
}
- t.ErrorHandlerRef = e.Integration.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerRefName)
+ if t.ErrorHandlerRef == "" {
+ t.ErrorHandlerRef = e.Integration.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerRefName)
+ }
return t.ErrorHandlerRef != "", nil
}
[camel-k] 17/30: feat(trait): error handler Ref
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit bb48d9ae9e482117d474027320dc1a222a0b1618
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Fri Apr 23 10:04:58 2021 +0200
feat(trait): error handler Ref
---
pkg/apis/camel/v1alpha1/error_handler_types.go | 42 ++++++++++++++++++++++++++
pkg/controller/kameletbinding/error_handler.go | 6 ++++
pkg/trait/error_handler.go | 3 ++
3 files changed, 51 insertions(+)
diff --git a/pkg/apis/camel/v1alpha1/error_handler_types.go b/pkg/apis/camel/v1alpha1/error_handler_types.go
index df46324..949fbd6 100644
--- a/pkg/apis/camel/v1alpha1/error_handler_types.go
+++ b/pkg/apis/camel/v1alpha1/error_handler_types.go
@@ -36,6 +36,7 @@ type AbstractErrorHandler interface {
Type() ErrorHandlerType
Params() *ErrorHandlerProperties
Endpoint() *Endpoint
+ Ref() *string
}
// ErrorHandlerNone --
@@ -62,6 +63,11 @@ func (e ErrorHandlerNone) Endpoint() *Endpoint {
return nil
}
+// Ref --
+func (e ErrorHandlerNone) Ref() *string {
+ return nil
+}
+
// ErrorHandlerLog represent a default (log) error handler type
type ErrorHandlerLog struct {
Parameters *ErrorHandlerProperties `json:"parameters,omitempty"`
@@ -82,6 +88,11 @@ func (e ErrorHandlerLog) Endpoint() *Endpoint {
return nil
}
+// Ref --
+func (e ErrorHandlerLog) Ref() *string {
+ return nil
+}
+
// ErrorHandlerDeadLetterChannel represents a dead letter channel error handler type
type ErrorHandlerDeadLetterChannel struct {
*ErrorHandlerLog
@@ -103,6 +114,35 @@ func (e ErrorHandlerDeadLetterChannel) Endpoint() *Endpoint {
return e.DLCEndpoint
}
+// Ref --
+func (e ErrorHandlerDeadLetterChannel) Ref() *string {
+ return nil
+}
+
+// ErrorHandlerRef represents a reference to an error handler builder available in the registry
+type ErrorHandlerRef string
+
+// Type --
+func (e ErrorHandlerRef) Type() ErrorHandlerType {
+ return ErrorHandlerTypeRef
+}
+
+// Params --
+func (e ErrorHandlerRef) Params() *ErrorHandlerProperties {
+ return nil
+}
+
+// Endpoint --
+func (e ErrorHandlerRef) Endpoint() *Endpoint {
+ return nil
+}
+
+// Ref --
+func (e ErrorHandlerRef) Ref() *string {
+ s := string(e)
+ return &s
+}
+
// ErrorHandlerType --
type ErrorHandlerType string
@@ -113,4 +153,6 @@ const (
ErrorHandlerTypeLog ErrorHandlerType = "log"
// ErrorHandlerTypeDeadLetterChannel --
ErrorHandlerTypeDeadLetterChannel ErrorHandlerType = "dead-letter-channel"
+ // ErrorHandlerTypeRef --
+ ErrorHandlerTypeRef ErrorHandlerType = "ref"
)
diff --git a/pkg/controller/kameletbinding/error_handler.go b/pkg/controller/kameletbinding/error_handler.go
index 90ba3cc..c9858f9 100644
--- a/pkg/controller/kameletbinding/error_handler.go
+++ b/pkg/controller/kameletbinding/error_handler.go
@@ -43,6 +43,10 @@ func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandler, bindingContext bindin
errorHandlerURI = errorHandler.URI
}
+ if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeRef {
+ errorHandlerURI = *errorHandlerSpec.Ref()
+ }
+
err = setIntegrationErrorHandler(itSpec, errorHandlerURI, errorHandlerSpec)
if err != nil {
return nil, errors.Wrap(err, "could not set integration error handler")
@@ -72,6 +76,8 @@ func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.AbstractErrorHandler,
dst = new(v1alpha1.ErrorHandlerLog)
case v1alpha1.ErrorHandlerTypeDeadLetterChannel:
dst = new(v1alpha1.ErrorHandlerDeadLetterChannel)
+ case v1alpha1.ErrorHandlerTypeRef:
+ dst = new(v1alpha1.ErrorHandlerRef)
default:
return nil, errors.Errorf("Unknown error type %s, supported error types are: none, log, dead-letter-channel", errHandlType)
}
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index e82dcf9..7945372 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -123,6 +123,9 @@ func parseErrorHandler(errorHandlerSpec v1.ErrorHandlerSpec) (string, error) {
}
return fmt.Sprintf(`errorHandler(deadLetterChannel("%v")%v);`, errorHandlerSpec.URI, errorHandlerConfiguration), nil
+ case "ref":
+ // TODO using URI temporarily, fix it properly
+ return fmt.Sprintf(`errorHandler("%v");`, errorHandlerSpec.URI), nil
}
return "", fmt.Errorf("Cannot recognize any error handler of type %s", errorHandlerSpec.Type)
[camel-k] 01/30: feat(kamelets): error handling kamelets binding
support
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit f7ad34d9d6b8ad5f41f0be56f43171db8c9a8537
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Mar 16 16:17:56 2021 +0100
feat(kamelets): error handling kamelets binding support
* Added the capability to include an `errorHandler` support that will be converted as an `error-handler` in the generated integration.
* Fixed the inspector_yaml.go to parse the integration `error-handler` and load declared Kamelet source
---
pkg/apis/camel/v1alpha1/kamelet_binding_types.go | 9 ++++--
pkg/controller/kameletbinding/common.go | 36 +++++++++++++++++++++---
pkg/trait/kamelets.go | 1 +
pkg/util/source/inspector_yaml.go | 4 +++
pkg/util/source/types.go | 2 ++
5 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
index 8fea2ac..b91ed55 100644
--- a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
+++ b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
@@ -32,6 +32,8 @@ type KameletBindingSpec struct {
Source Endpoint `json:"source,omitempty"`
// Sink is the destination of the integration defined by this binding
Sink Endpoint `json:"sink,omitempty"`
+ // ErrorHandler is an optional handler called upon an error occuring in the integration
+ ErrorHandler Endpoint `json:"errorHandler,omitempty"`
// Steps contains an optional list of intermediate steps that are executed between the Source and the Sink
Steps []Endpoint `json:"steps,omitempty"`
}
@@ -51,9 +53,10 @@ type Endpoint struct {
type EndpointType string
const (
- EndpointTypeSource EndpointType = "source"
- EndpointTypeAction EndpointType = "action"
- EndpointTypeSink EndpointType = "sink"
+ EndpointTypeSource EndpointType = "source"
+ EndpointTypeAction EndpointType = "action"
+ EndpointTypeSink EndpointType = "sink"
+ EndpointTypeErrorHandler EndpointType = "errorHandler"
)
// EndpointProperties is a key/value struct represented as JSON raw to allow numeric/boolean values
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index 411bde8..354dfa2 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -79,6 +79,10 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
if err != nil {
return nil, errors.Wrap(err, "could not determine sink URI")
}
+ onError, err := bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler)
+ if err != nil {
+ return nil, errors.Wrap(err, "could not determine error handler URI")
+ }
steps := make([]*bindings.Binding, 0, len(kameletbinding.Spec.Steps))
for idx, step := range kameletbinding.Spec.Steps {
@@ -93,10 +97,13 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
steps = append(steps, stepBinding)
}
- allBindings := make([]*bindings.Binding, 0, len(steps)+2)
+ allBindings := make([]*bindings.Binding, 0, len(steps)+3)
allBindings = append(allBindings, from)
allBindings = append(allBindings, steps...)
allBindings = append(allBindings, to)
+ if onError != nil {
+ allBindings = append(allBindings, onError)
+ }
propList := make([]string, 0)
for _, b := range allBindings {
@@ -129,17 +136,38 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
"to": to.URI,
})
- flow := map[string]interface{}{
+ // Append Error Handler flow, if it exists
+ if onError != nil {
+ flowErrorHandler := map[string]interface{}{
+ "error-handler": map[string]interface{}{
+ "dead-letter-channel": map[string]interface{}{
+ "dead-letter-uri": onError.URI,
+ "dead-letter-handle-new-exception": true,
+ "async-delayed-redelivery": false,
+ "use-original-message": true,
+ },
+ },
+ }
+ encodedErrorHandler, err := json.Marshal(flowErrorHandler)
+
+ if err != nil {
+ return nil, err
+ }
+ it.Spec.Flows = append(it.Spec.Flows, v1.Flow{RawMessage: encodedErrorHandler})
+ }
+
+ // Append From flow: it must exist
+ flowFrom := map[string]interface{}{
"from": map[string]interface{}{
"uri": from.URI,
"steps": dslSteps,
},
}
- encodedFlow, err := json.Marshal(flow)
+ encodedFrom, err := json.Marshal(flowFrom)
if err != nil {
return nil, err
}
- it.Spec.Flows = append(it.Spec.Flows, v1.Flow{RawMessage: encodedFlow})
+ it.Spec.Flows = append(it.Spec.Flows, v1.Flow{RawMessage: encodedFrom})
return &it, nil
}
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index df437d9..9d55b19 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -103,6 +103,7 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
util.StringSliceUniqueConcat(&kamelets, extractKamelets(meta.FromURIs))
util.StringSliceUniqueConcat(&kamelets, extractKamelets(meta.ToURIs))
+ util.StringSliceUniqueConcat(&kamelets, extractKamelets(meta.ErrorHandlerURIs))
return true
})
sort.Strings(kamelets)
diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go
index 1f96ae8..4c47dc2 100644
--- a/pkg/util/source/inspector_yaml.go
+++ b/pkg/util/source/inspector_yaml.go
@@ -78,6 +78,10 @@ func (i YAMLInspector) parseStep(key string, content interface{}, meta *Metadata
}
}
}
+ case "error-handler":
+ deadLetterChannel := content.(map[interface{}]interface{})
+ deadLetterURI := deadLetterChannel["dead-letter-channel"].(map[interface{}]interface{})
+ meta.ErrorHandlerURIs = append(meta.ErrorHandlerURIs, deadLetterURI["dead-letter-uri"].(string))
}
var maybeURI string
diff --git a/pkg/util/source/types.go b/pkg/util/source/types.go
index f6f15e0..46074f8 100644
--- a/pkg/util/source/types.go
+++ b/pkg/util/source/types.go
@@ -25,6 +25,8 @@ type Metadata struct {
FromURIs []string
// All end URIs of defined routes
ToURIs []string
+ // All error handlers URIs of defined routes
+ ErrorHandlerURIs []string
// All inferred dependencies required to run the integration
Dependencies *strset.Set
// ExposesHTTPServices indicates if a route defined by the source is exposed
[camel-k] 20/30: refactor(trait): error handler using bean ref
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 5eb36ef24edd436f9ce96b005ede00f8795d7b53
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Mon Apr 26 18:22:18 2021 +0200
refactor(trait): error handler using bean ref
---
pkg/apis/camel/v1/integration_types_support.go | 18 +---
pkg/apis/camel/v1alpha1/error_handler_types.go | 119 ++++++++++++---------
pkg/controller/kameletbinding/common.go | 1 +
pkg/controller/kameletbinding/error_handler.go | 7 +-
.../kameletbinding/error_handler_test.go | 52 +++++++--
pkg/trait/error_handler.go | 19 ++--
pkg/trait/kamelets.go | 11 +-
7 files changed, 122 insertions(+), 105 deletions(-)
diff --git a/pkg/apis/camel/v1/integration_types_support.go b/pkg/apis/camel/v1/integration_types_support.go
index 295c75a..6efdc24 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -131,22 +131,8 @@ func (in *IntegrationSpec) AddDependency(dependency string) {
in.Dependencies = append(in.Dependencies, newDep)
}
-// HasDefaultErrorHandler checks the configuration properties to see if a default error handler is declared
-func (in *IntegrationSpec) HasDefaultErrorHandler() bool {
- return in.GetDefaultErrorHandler() != ""
-}
-
-// GetDefaultErrorHandler returns the default error handler, if it is declared
-func (in *IntegrationSpec) GetDefaultErrorHandler() string {
- return in.getConfigurationProperty("camel.beans.defaultErrorHandler")
-}
-
-// GetDefaultErrorHandlerURI returns the default error handler uri, if it is declared
-func (in *IntegrationSpec) GetDefaultErrorHandlerURI() string {
- return in.getConfigurationProperty("camel.beans.defaultErrorHandler.uri")
-}
-
-func (in *IntegrationSpec) getConfigurationProperty(property string) string {
+// GetConfigurationProperty returns a configuration property
+func (in *IntegrationSpec) GetConfigurationProperty(property string) string {
for _, confSpec := range in.Configuration {
if confSpec.Type == "property" && strings.HasPrefix(confSpec.Value, property) {
splitConf := strings.Split(confSpec.Value, "=")
diff --git a/pkg/apis/camel/v1alpha1/error_handler_types.go b/pkg/apis/camel/v1alpha1/error_handler_types.go
index d40bf6f..4f3f4e7 100644
--- a/pkg/apis/camel/v1alpha1/error_handler_types.go
+++ b/pkg/apis/camel/v1alpha1/error_handler_types.go
@@ -19,11 +19,19 @@ package v1alpha1
import (
"encoding/json"
+ "fmt"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
)
-const errorHandlerAppPropertiesPrefix = "camel.beans.defaultErrorHandler"
+// ErrorHandlerRefName --
+const ErrorHandlerRefName = "camel.k.errorHandler.ref"
+
+// ErrorHandlerRefDefaultName --
+const ErrorHandlerRefDefaultName = "defaultErrorHandler"
+
+// ErrorHandlerAppPropertiesPrefix --
+const ErrorHandlerAppPropertiesPrefix = "camel.beans.defaultErrorHandler"
// ErrorHandlerSpec represents an unstructured object for an error handler
type ErrorHandlerSpec struct {
@@ -32,60 +40,42 @@ type ErrorHandlerSpec struct {
// ErrorHandlerParameters represent an unstructured object for error handler parameters
type ErrorHandlerParameters struct {
- v1.RawMessage `json:",inline"`
+ v1.RawMessage `json:",omitempty"`
}
// BeanProperties represent an unstructured object properties to be set on a bean
type BeanProperties struct {
- v1.RawMessage `json:",inline"`
+ v1.RawMessage `json:",omitempty"`
}
// ErrorHandler is a generic interface that represent any type of error handler specification
type ErrorHandler interface {
Type() ErrorHandlerType
- Params() *ErrorHandlerParameters
Endpoint() *Endpoint
- Ref() *string
- Bean() *string
Configuration() (map[string]interface{}, error)
}
-type abstractErrorHandler struct {
+type baseErrorHandler struct {
}
// Type --
-func (e abstractErrorHandler) Type() ErrorHandlerType {
- return errorHandlerTypeAbstract
-}
-
-// Params --
-func (e abstractErrorHandler) Params() *ErrorHandlerParameters {
- return nil
+func (e baseErrorHandler) Type() ErrorHandlerType {
+ return errorHandlerTypeBase
}
// Endpoint --
-func (e abstractErrorHandler) Endpoint() *Endpoint {
- return nil
-}
-
-// Ref --
-func (e abstractErrorHandler) Ref() *string {
- return nil
-}
-
-// Bean --
-func (e abstractErrorHandler) Bean() *string {
+func (e baseErrorHandler) Endpoint() *Endpoint {
return nil
}
// Configuration --
-func (e abstractErrorHandler) Configuration() (map[string]interface{}, error) {
+func (e baseErrorHandler) Configuration() (map[string]interface{}, error) {
return nil, nil
}
// ErrorHandlerNone --
type ErrorHandlerNone struct {
- *abstractErrorHandler
+ baseErrorHandler
}
// Type --
@@ -96,13 +86,14 @@ func (e ErrorHandlerNone) Type() ErrorHandlerType {
// Configuration --
func (e ErrorHandlerNone) Configuration() (map[string]interface{}, error) {
return map[string]interface{}{
- errorHandlerAppPropertiesPrefix: "#class:org.apache.camel.builder.NoErrorHandlerBuilder",
+ ErrorHandlerAppPropertiesPrefix: "#class:org.apache.camel.builder.NoErrorHandlerBuilder",
+ ErrorHandlerRefName: ErrorHandlerRefDefaultName,
}, nil
}
// ErrorHandlerLog represent a default (log) error handler type
type ErrorHandlerLog struct {
- *abstractErrorHandler
+ ErrorHandlerNone
Parameters *ErrorHandlerParameters `json:"parameters,omitempty"`
}
@@ -111,25 +102,22 @@ func (e ErrorHandlerLog) Type() ErrorHandlerType {
return ErrorHandlerTypeLog
}
-// Params --
-func (e ErrorHandlerLog) Params() *ErrorHandlerParameters {
- return e.Parameters
-}
-
// Configuration --
func (e ErrorHandlerLog) Configuration() (map[string]interface{}, error) {
- properties := map[string]interface{}{
- errorHandlerAppPropertiesPrefix: "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder",
+ properties, err := e.ErrorHandlerNone.Configuration()
+ if err != nil {
+ return nil, err
}
+ properties[ErrorHandlerAppPropertiesPrefix] = "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder"
- if e.Params() != nil {
+ if e.Parameters != nil {
var parameters map[string]interface{}
- err := json.Unmarshal(e.Params().RawMessage, ¶meters)
+ err := json.Unmarshal(e.Parameters.RawMessage, ¶meters)
if err != nil {
return nil, err
}
for key, value := range parameters {
- properties[errorHandlerAppPropertiesPrefix+"."+key] = value
+ properties[ErrorHandlerAppPropertiesPrefix+"."+key] = value
}
}
@@ -138,7 +126,7 @@ func (e ErrorHandlerLog) Configuration() (map[string]interface{}, error) {
// ErrorHandlerDeadLetterChannel represents a dead letter channel error handler type
type ErrorHandlerDeadLetterChannel struct {
- *ErrorHandlerLog
+ ErrorHandlerLog
DLCEndpoint *Endpoint `json:"endpoint,omitempty"`
}
@@ -152,10 +140,21 @@ func (e ErrorHandlerDeadLetterChannel) Endpoint() *Endpoint {
return e.DLCEndpoint
}
+// Configuration --
+func (e ErrorHandlerDeadLetterChannel) Configuration() (map[string]interface{}, error) {
+ properties, err := e.ErrorHandlerLog.Configuration()
+ if err != nil {
+ return nil, err
+ }
+ properties[ErrorHandlerAppPropertiesPrefix] = "#class:org.apache.camel.builder.DeadLetterChannelBuilder"
+
+ return properties, err
+}
+
// ErrorHandlerRef represents a reference to an error handler builder available in the registry
type ErrorHandlerRef struct {
- *abstractErrorHandler
- string
+ baseErrorHandler
+ v1.RawMessage
}
// Type --
@@ -163,17 +162,25 @@ func (e ErrorHandlerRef) Type() ErrorHandlerType {
return ErrorHandlerTypeRef
}
-// Ref --
-func (e ErrorHandlerRef) Ref() *string {
- s := string(e.string)
- return &s
+// Configuration --
+func (e ErrorHandlerRef) Configuration() (map[string]interface{}, error) {
+ var refName string
+ err := json.Unmarshal(e.RawMessage, &refName)
+ if err != nil {
+ return nil, err
+ }
+
+ properties := map[string]interface{}{
+ ErrorHandlerRefName: refName,
+ }
+
+ return properties, nil
}
// ErrorHandlerBean represents a bean error handler type
type ErrorHandlerBean struct {
- *ErrorHandlerLog
- BeanType *string `json:"type,omitempty"`
- Properties *BeanProperties `json:"properties,omitempty"`
+ ErrorHandlerLog
+ BeanType *string `json:"type,omitempty"`
}
// Type --
@@ -181,16 +188,22 @@ func (e ErrorHandlerBean) Type() ErrorHandlerType {
return ErrorHandlerTypeBean
}
-// Bean --
-func (e ErrorHandlerBean) Bean() *string {
- return e.BeanType
+// Configuration --
+func (e ErrorHandlerBean) Configuration() (map[string]interface{}, error) {
+ properties, err := e.ErrorHandlerLog.Configuration()
+ if err != nil {
+ return nil, err
+ }
+ properties[ErrorHandlerAppPropertiesPrefix] = fmt.Sprintf("#class:%v", *e.BeanType)
+
+ return properties, err
}
// ErrorHandlerType --
type ErrorHandlerType string
const (
- errorHandlerTypeAbstract ErrorHandlerType = ""
+ errorHandlerTypeBase ErrorHandlerType = ""
// ErrorHandlerTypeNone --
ErrorHandlerTypeNone ErrorHandlerType = "none"
// ErrorHandlerTypeLog --
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index d434000..45509e1 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -53,6 +53,7 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
},
},
}
+
// start from the integration spec defined in the binding
if kameletbinding.Spec.Integration != nil {
it.Spec = *kameletbinding.Spec.Integration.DeepCopy()
diff --git a/pkg/controller/kameletbinding/error_handler.go b/pkg/controller/kameletbinding/error_handler.go
index 0cf95b6..0f75670 100644
--- a/pkg/controller/kameletbinding/error_handler.go
+++ b/pkg/controller/kameletbinding/error_handler.go
@@ -78,7 +78,7 @@ func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.ErrorHandler, error)
case v1alpha1.ErrorHandlerTypeBean:
dst = new(v1alpha1.ErrorHandlerBean)
default:
- return nil, errors.Errorf("Unknown error type %s, supported error types are: none, log, dead-letter-channel", errHandlType)
+ return nil, errors.Errorf("Unknown error handler type %s", errHandlType)
}
err := json.Unmarshal(errHandlValue, dst)
@@ -89,7 +89,7 @@ func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.ErrorHandler, error)
return dst, nil
}
- return nil, errors.New("You must provide any supported error handler (none, log, dead-letter-channel)")
+ return nil, errors.New("You must provide any supported error handler")
}
func setErrorHandlerConfiguration(it *v1.IntegrationSpec, errorHandlerURI string, errorHandler v1alpha1.ErrorHandler) error {
@@ -100,5 +100,8 @@ func setErrorHandlerConfiguration(it *v1.IntegrationSpec, errorHandlerURI string
for key, value := range properties {
it.AddConfiguration("property", fmt.Sprintf("%s=%v", key, value))
}
+ if errorHandler.Type() == v1alpha1.ErrorHandlerTypeDeadLetterChannel && errorHandlerURI != "" {
+ it.AddConfiguration("property", fmt.Sprintf("%s.deadLetterUri=%v", v1alpha1.ErrorHandlerAppPropertiesPrefix, errorHandlerURI))
+ }
return nil
}
diff --git a/pkg/controller/kameletbinding/error_handler_test.go b/pkg/controller/kameletbinding/error_handler_test.go
index e05caf4..c6be802 100644
--- a/pkg/controller/kameletbinding/error_handler_test.go
+++ b/pkg/controller/kameletbinding/error_handler_test.go
@@ -18,6 +18,7 @@ limitations under the License.
package kameletbinding
import (
+ "fmt"
"testing"
"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -32,7 +33,8 @@ func TestParseErrorHandlerNoneDoesSucceed(t *testing.T) {
assert.Equal(t, v1alpha1.ErrorHandlerTypeNone, noErrorHandler.Type())
parameters, err := noErrorHandler.Configuration()
assert.Nil(t, err)
- assert.Equal(t, "#class:org.apache.camel.builder.NoErrorHandlerBuilder", parameters["camel.beans.defaultErrorHandler"])
+ assert.Equal(t, "#class:org.apache.camel.builder.NoErrorHandlerBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix])
+ assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName])
}
func TestParseErrorHandlerLogDoesSucceed(t *testing.T) {
@@ -43,7 +45,8 @@ func TestParseErrorHandlerLogDoesSucceed(t *testing.T) {
assert.Equal(t, v1alpha1.ErrorHandlerTypeLog, logErrorHandler.Type())
parameters, err := logErrorHandler.Configuration()
assert.Nil(t, err)
- assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters["camel.beans.defaultErrorHandler"])
+ assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix])
+ assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName])
}
func TestParseErrorHandlerLogWithParametersDoesSucceed(t *testing.T) {
@@ -52,21 +55,27 @@ func TestParseErrorHandlerLogWithParametersDoesSucceed(t *testing.T) {
)
assert.Nil(t, err)
assert.Equal(t, v1alpha1.ErrorHandlerTypeLog, logErrorHandler.Type())
- assert.NotNil(t, logErrorHandler.Params())
parameters, err := logErrorHandler.Configuration()
assert.Nil(t, err)
- assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters["camel.beans.defaultErrorHandler"])
+ assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix])
assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"])
assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.param2"])
+ assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName])
}
func TestParseErrorHandlerDLCDoesSucceed(t *testing.T) {
+ fmt.Println("Test")
dlcErrorHandler, err := parseErrorHandler(
[]byte(`{"dead-letter-channel": {"endpoint": {"uri": "someUri"}}}`),
)
assert.Nil(t, err)
+ assert.NotNil(t, dlcErrorHandler)
assert.Equal(t, v1alpha1.ErrorHandlerTypeDeadLetterChannel, dlcErrorHandler.Type())
assert.Equal(t, "someUri", *dlcErrorHandler.Endpoint().URI)
+ parameters, err := dlcErrorHandler.Configuration()
+ assert.Nil(t, err)
+ assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix])
+ assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName])
}
func TestParseErrorHandlerDLCWithParametersDoesSucceed(t *testing.T) {
@@ -77,28 +86,49 @@ func TestParseErrorHandlerDLCWithParametersDoesSucceed(t *testing.T) {
"uri": "someUri"
},
"parameters":
- [{"param1": "value1"}]
+ {"param1": "value1", "param2": "value2"}
}
}`),
)
assert.Nil(t, err)
+ assert.NotNil(t, dlcErrorHandler)
assert.Equal(t, v1alpha1.ErrorHandlerTypeDeadLetterChannel, dlcErrorHandler.Type())
assert.Equal(t, "someUri", *dlcErrorHandler.Endpoint().URI)
- assert.NotNil(t, dlcErrorHandler.Params())
+ parameters, err := dlcErrorHandler.Configuration()
+ assert.Nil(t, err)
+ assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix])
+ assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName])
+ assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"])
+ assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.param2"])
}
-func TestParseErrorHandlerBeanWithParametersDoesSucceed(t *testing.T) {
+func TestParseErrorHandlerBeanWithParamsDoesSucceed(t *testing.T) {
beanErrorHandler, err := parseErrorHandler(
[]byte(`{
"bean": {
- "type": "com.acme.MyType",
+ "type": "com.acme.MyType",
"parameters":
- [{"param1": "value1"}]
+ {"param1": "value1", "param2": "value2"}
}
}`),
)
assert.Nil(t, err)
assert.Equal(t, v1alpha1.ErrorHandlerTypeBean, beanErrorHandler.Type())
- assert.Equal(t, "com.acme.MyType", *beanErrorHandler.Bean())
- assert.NotNil(t, beanErrorHandler.Params())
+ parameters, err := beanErrorHandler.Configuration()
+ assert.Nil(t, err)
+ assert.Equal(t, "#class:com.acme.MyType", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix])
+ assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName])
+ assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"])
+ assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.param2"])
+}
+
+func TestParseErrorHandlerRefDoesSucceed(t *testing.T) {
+ refErrorHandler, err := parseErrorHandler(
+ []byte(`{"ref": "my-registry-ref"}`),
+ )
+ assert.Nil(t, err)
+ assert.Equal(t, v1alpha1.ErrorHandlerTypeRef, refErrorHandler.Type())
+ parameters, err := refErrorHandler.Configuration()
+ assert.Nil(t, err)
+ assert.Equal(t, "my-registry-ref", parameters[v1alpha1.ErrorHandlerRefName])
}
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index b7a8c0d..e705e97 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -21,6 +21,7 @@ import (
"fmt"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
)
// The error-handler is a platform trait used to inject Error Handler source into the integration runtime.
@@ -50,7 +51,7 @@ func (t *errorHandlerTrait) Configure(e *Environment) (bool, error) {
return false, nil
}
- return e.Integration.Spec.HasDefaultErrorHandler(), nil
+ return e.Integration.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerRefName) != "", nil
}
func (t *errorHandlerTrait) Apply(e *Environment) error {
@@ -64,19 +65,20 @@ func (t *errorHandlerTrait) Apply(e *Environment) error {
}
func addErrorHandlerAsSource(e *Environment) error {
+ errorHandlerRefName := e.Integration.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerRefName)
// TODO change to yaml flow when we fix https://issues.apache.org/jira/browse/CAMEL-16486
errorHandlerSource := v1.SourceSpec{
DataSpec: v1.DataSpec{
Name: "ErrorHandlerSource.java",
- Content: `
+ Content: fmt.Sprintf(`
import org.apache.camel.builder.RouteBuilder;
public class ErrorHandlerSource extends RouteBuilder {
@Override
public void configure() throws Exception {
- errorHandler("defaultErrorHandler");
+ errorHandler("%s");
}
}
- `,
+ `, errorHandlerRefName),
},
Language: v1.LanguageJavaSource,
Type: v1.SourceTypeErrorHandler,
@@ -86,12 +88,3 @@ func addErrorHandlerAsSource(e *Environment) error {
return nil
}
-
-func addErrorHandlerBeanConfiguration(e *Environment, fqn string) error {
- // camel.beans.defaultErrorHandler = #class:the-full-qualified-class-name
- e.Integration.Status.AddConfigurationsIfMissing(v1.ConfigurationSpec{
- Type: "property",
- Value: fmt.Sprintf("camel.beans.defaultErrorHandler=#class:%s", fqn),
- })
- return nil
-}
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index 83a35a9..916b4b2 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -107,7 +107,7 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
})
}
// Check if a Kamelet is configured as default error handler URI
- defaultErrorHandlerURI := e.Integration.Spec.GetDefaultErrorHandlerURI()
+ defaultErrorHandlerURI := e.Integration.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerAppPropertiesPrefix + ".deadLetterUri")
if defaultErrorHandlerURI != "" {
if strings.HasPrefix(defaultErrorHandlerURI, "kamelet:") {
kamelets = append(kamelets, extractKamelet(defaultErrorHandlerURI))
@@ -124,16 +124,7 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
}
func (t *kameletsTrait) Apply(e *Environment) error {
-<<<<<<< HEAD
-<<<<<<< HEAD
-
if e.IntegrationInPhase(v1.IntegrationPhaseInitialization, v1.IntegrationPhaseRunning) {
-=======
-=======
-
->>>>>>> refactor(trait): error handler kamelet
- if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
->>>>>>> refactor(trait): integration error handler spec
if err := t.addKamelets(e); err != nil {
return err
}
[camel-k] 03/30: fix(kamelets): optional error handler
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit a488a3abf8f10ffe741b188401eb7f7e5c17202b
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Mar 16 17:38:14 2021 +0100
fix(kamelets): optional error handler
---
pkg/controller/kameletbinding/common.go | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index 354dfa2..32d7182 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -79,9 +79,12 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
if err != nil {
return nil, errors.Wrap(err, "could not determine sink URI")
}
- onError, err := bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler)
- if err != nil {
- return nil, errors.Wrap(err, "could not determine error handler URI")
+ var onError *bindings.Binding
+ if kameletbinding.Spec.ErrorHandler.Ref != nil || kameletbinding.Spec.ErrorHandler.URI != nil {
+ onError, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler)
+ if err != nil {
+ return nil, errors.Wrap(err, "could not determine error handler URI")
+ }
}
steps := make([]*bindings.Binding, 0, len(kameletbinding.Spec.Steps))
[camel-k] 13/30: feat(trait): error handler advanced configuration
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 647b82fba4866709c225a17b3d7a0300c26f14b2
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Apr 21 17:09:24 2021 +0200
feat(trait): error handler advanced configuration
---
.../kamelet-binding-error-handler.yaml | 5 +++-
pkg/controller/kameletbinding/common.go | 3 ++-
pkg/resources/resources.go | 4 +--
pkg/trait/error_handler.go | 30 ++++++++++++++++++----
4 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
index ae8eb78..457b173 100644
--- a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
+++ b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
@@ -38,5 +38,8 @@ spec:
apiVersion: camel.apache.org/v1alpha1
name: error-handler
properties:
- message: "ERROR!"
+ message: "ERROR!"
+ configuration:
+ maximumRedeliveries: 3
+ redeliveryDelay: 2000
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index 06b5b76..c4d4641 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -166,7 +166,8 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
func setIntegrationErrorHandler(it *v1.IntegrationSpec, errorHandlerURI string, errorHandlerSpec v1alpha1.ErrorHandler) error {
it.ErrorHandler = v1.ErrorHandlerSpec{
- Type: string(errorHandlerSpec.Type),
+ Type: string(errorHandlerSpec.Type),
+ Configuration: &v1.ErrorHandlerConfiguration{errorHandlerSpec.Configuration.RawMessage},
}
if errorHandlerURI != "" {
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 7603bbb..6b712ac 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -113,9 +113,9 @@ var assets = func() http.FileSystem {
"/crd/bases/camel.apache.org_kameletbindings.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_kameletbindings.yaml",
modTime: time.Time{},
- uncompressedSize: 68634,
+ uncompressedSize: 55181,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\xff\x6f\xdb\x38\xb2\xff\x3d\x7f\xc5\x20\x39\xa0\x2d\x10\xd9\x71\x92\x76\x77\xfd\x7e\x28\xb2\xc9\xf6\xce\xaf\xdd\x34\xc8\x97\x3b\xdc\x6b\x7b\x00\x2d\x8d\x6d\x5e\x24\x52\x47\x52\x71\xfc\xb6\xfd\xdf\x1f\x48\x4a\xb2\xfc\x45\x12\xe5\xd8\xdd\xf4\x41\x04\x8a\xc6\x16\x35\x9c\x19\x0e\x87\xdf\xe6\x33\x3e\x00\x6f\x7b\x65\xef\x00\x3e\x50\x1f\x99\xc4\x00\x14\x07\x35\x41\x38\x8b\x89\x3f\x41\xb8\xe1\x23\x35\x25\x02\xe1\x1d\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xf1\x6f\xdb\x38\xf2\xef\xef\xf9\x2b\x06\xc9\x01\x6d\x01\x4b\x8e\xe3\xb4\xbb\xeb\xf7\x43\x91\x26\xdb\x7b\x7e\xed\xa6\x45\x92\xde\xe1\x5e\xdb\x03\x68\x69\x6c\xf3\x22\x91\x3a\x92\x8a\xe3\xef\xb6\xff\xfb\x17\x24\x25\x59\x76\x2c\x99\x72\xec\x6e\x0a\x88\xc0\x62\x6b\x8b\x1a\xce\x0c\x87\xc3\x99\x21\x3f\xce\x11\x78\xbb\x6b\x07\x47\xf0\x9e\x06\xc8\x24\x86\xa0\x38\xa8\x29\xc2\x59\x42\x82\x29\xc2\x35\x1f\xab\x19\x11\x08\x [...]
},
"/crd/bases/camel.apache.org_kamelets.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_kamelets.yaml",
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index ef93d67..2b57738 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -18,6 +18,7 @@ limitations under the License.
package trait
import (
+ "encoding/json"
"fmt"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
@@ -67,7 +68,7 @@ func (t *errorHandlerTrait) Apply(e *Environment) error {
}
func addErrorHandlerAsSource(e *Environment) error {
- errorHandlerStatement, err := parseErrorHandler(e.Integration.Spec.ErrorHandler.URI, e.Integration.Spec.ErrorHandler.Type)
+ errorHandlerStatement, err := parseErrorHandler(e.Integration.Spec.ErrorHandler)
if err != nil {
return err
}
@@ -104,15 +105,34 @@ func addErrorHandlerAsSource(e *Environment) error {
return nil
}
-func parseErrorHandler(errHandlURI string, errHandlType string) (string, error) {
- switch errHandlType {
+func parseErrorHandler(errorHandlerSpec v1.ErrorHandlerSpec) (string, error) {
+ switch errorHandlerSpec.Type {
case "no":
return `errorHandler(noErrorHandler());`, nil
case "default":
return `errorHandler(defaultErrorHandler());`, nil
case "dead-letter-channel":
- return fmt.Sprintf(`errorHandler(deadLetterChannel("%v"));`, errHandlURI), nil
+ errorHandlerConfiguration, err := parseErrorHandlerConfiguration(errorHandlerSpec.Configuration)
+ if err != nil {
+ return "", err
+ }
+
+ return fmt.Sprintf(`errorHandler(deadLetterChannel("%v")%v);`, errorHandlerSpec.URI, errorHandlerConfiguration), nil
+ }
+
+ return "", fmt.Errorf("Cannot recognize any error handler of type %s", errorHandlerSpec.Type)
+}
+
+func parseErrorHandlerConfiguration(conf *v1.ErrorHandlerConfiguration) (string, error) {
+ javaPropertiesBuilder := ""
+ var properties map[string]interface{}
+ err := json.Unmarshal(conf.RawMessage, &properties)
+ if err != nil {
+ return "", err
+ }
+ for method, value := range properties {
+ javaPropertiesBuilder = javaPropertiesBuilder + fmt.Sprintf(".%s(%v)\n", method, value)
}
- return "", fmt.Errorf("Cannot recognize any error handler of type %s", errHandlType)
+ return javaPropertiesBuilder, nil
}
[camel-k] 24/30: refactor(controller): error handler bean properties
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 987fc9da7c1f0166ba29142d24fe2044b21aa735
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 27 11:09:04 2021 +0200
refactor(controller): error handler bean properties
---
.../error-handler/kamelet-binding-error-handler.yaml | 2 +-
pkg/apis/camel/v1alpha1/error_handler_types.go | 18 +++++++++++++++---
pkg/controller/kameletbinding/error_handler_test.go | 8 ++++----
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
index 6c44ca7..7a935d6 100644
--- a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
+++ b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
@@ -38,7 +38,7 @@ spec:
# ref: "something"
# bean:
# type: "org.apache.camel.builder.DeadLetterChannelBuilder"
-# parameters:
+# properties:
# deadLetterUri: log:error
dead-letter-channel:
endpoint:
diff --git a/pkg/apis/camel/v1alpha1/error_handler_types.go b/pkg/apis/camel/v1alpha1/error_handler_types.go
index 4f3f4e7..5019796 100644
--- a/pkg/apis/camel/v1alpha1/error_handler_types.go
+++ b/pkg/apis/camel/v1alpha1/error_handler_types.go
@@ -179,8 +179,9 @@ func (e ErrorHandlerRef) Configuration() (map[string]interface{}, error) {
// ErrorHandlerBean represents a bean error handler type
type ErrorHandlerBean struct {
- ErrorHandlerLog
- BeanType *string `json:"type,omitempty"`
+ ErrorHandlerNone
+ BeanType *string `json:"type,omitempty"`
+ BeanProperties *BeanProperties `json:"properties,omitempty"`
}
// Type --
@@ -190,12 +191,23 @@ func (e ErrorHandlerBean) Type() ErrorHandlerType {
// Configuration --
func (e ErrorHandlerBean) Configuration() (map[string]interface{}, error) {
- properties, err := e.ErrorHandlerLog.Configuration()
+ properties, err := e.ErrorHandlerNone.Configuration()
if err != nil {
return nil, err
}
properties[ErrorHandlerAppPropertiesPrefix] = fmt.Sprintf("#class:%v", *e.BeanType)
+ if e.BeanProperties != nil {
+ var beanProperties map[string]interface{}
+ err := json.Unmarshal(e.BeanProperties.RawMessage, &beanProperties)
+ if err != nil {
+ return nil, err
+ }
+ for key, value := range beanProperties {
+ properties[ErrorHandlerAppPropertiesPrefix+"."+key] = value
+ }
+ }
+
return properties, err
}
diff --git a/pkg/controller/kameletbinding/error_handler_test.go b/pkg/controller/kameletbinding/error_handler_test.go
index c6be802..94e6643 100644
--- a/pkg/controller/kameletbinding/error_handler_test.go
+++ b/pkg/controller/kameletbinding/error_handler_test.go
@@ -107,8 +107,8 @@ func TestParseErrorHandlerBeanWithParamsDoesSucceed(t *testing.T) {
[]byte(`{
"bean": {
"type": "com.acme.MyType",
- "parameters":
- {"param1": "value1", "param2": "value2"}
+ "properties":
+ {"beanProp1": "value1", "beanProp2": "value2"}
}
}`),
)
@@ -118,8 +118,8 @@ func TestParseErrorHandlerBeanWithParamsDoesSucceed(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "#class:com.acme.MyType", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix])
assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName])
- assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"])
- assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.param2"])
+ assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.beanProp1"])
+ assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.beanProp2"])
}
func TestParseErrorHandlerRefDoesSucceed(t *testing.T) {
[camel-k] 14/30: fix(trait): default error handler configuration
setting
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 68aaeb4ec4e3dc4721e10289e9426b9a5b23b699
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Apr 21 17:25:41 2021 +0200
fix(trait): default error handler configuration setting
---
pkg/trait/error_handler.go | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index 2b57738..eadaa70 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -110,7 +110,12 @@ func parseErrorHandler(errorHandlerSpec v1.ErrorHandlerSpec) (string, error) {
case "no":
return `errorHandler(noErrorHandler());`, nil
case "default":
- return `errorHandler(defaultErrorHandler());`, nil
+ errorHandlerConfiguration, err := parseErrorHandlerConfiguration(errorHandlerSpec.Configuration)
+ if err != nil {
+ return "", err
+ }
+
+ return fmt.Sprintf(`errorHandler(defaultErrorHandler()%v);`, errorHandlerConfiguration), nil
case "dead-letter-channel":
errorHandlerConfiguration, err := parseErrorHandlerConfiguration(errorHandlerSpec.Configuration)
if err != nil {
[camel-k] 28/30: chore(trait): polishing PR
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 82df277aa82431a0ba26188c635ce65ce4567ff2
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 27 17:19:00 2021 +0200
chore(trait): polishing PR
---
.../camel-k-dev/1.4.0/camel.apache.org_integrations.yaml | 15 ---------------
deploy/traits.yaml | 2 +-
docs/modules/traits/pages/error-handler.adoc | 2 +-
.../kamelets/error-handler/error-handler.kamelet.yaml | 3 +--
.../error-handler/incremental-id-source.kamelet.yaml | 2 +-
pkg/apis/camel/v1/integration_types_support.go | 2 +-
pkg/trait/error_handler.go | 2 +-
7 files changed, 6 insertions(+), 22 deletions(-)
diff --git a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml
index 0b1b88a..96e26b9 100644
--- a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml
+++ b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml
@@ -88,21 +88,6 @@ spec:
items:
type: string
type: array
- errorHandler:
- description: ErrorHandlerSpec respresents an integration error handler
- to be used as default at runtime
- properties:
- parameters:
- description: ErrorHandlerParameters is an unstructured object
- representing the configuration parameters available for an error
- handler
- type: object
- x-kubernetes-preserve-unknown-fields: true
- type:
- type: string
- uri:
- type: string
- type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
diff --git a/deploy/traits.yaml b/deploy/traits.yaml
index 22cc617..b2c3af3 100755
--- a/deploy/traits.yaml
+++ b/deploy/traits.yaml
@@ -284,7 +284,7 @@ traits:
type: bool
description: Can be used to enable or disable a trait. All traits share this common
property.
- - name: ',omitempty'
+ - name: error-handler-ref
type: string
description: The error handler ref name found in application properties
- name: gc
diff --git a/docs/modules/traits/pages/error-handler.adoc b/docs/modules/traits/pages/error-handler.adoc
index 149eaee..978e76f 100755
--- a/docs/modules/traits/pages/error-handler.adoc
+++ b/docs/modules/traits/pages/error-handler.adoc
@@ -27,7 +27,7 @@ The following configuration options are available:
| bool
| Can be used to enable or disable a trait. All traits share this common property.
-| error-handler.,omitempty
+| error-handler.error-handler-ref
| string
| The error handler ref name found in application properties
diff --git a/examples/kamelets/error-handler/error-handler.kamelet.yaml b/examples/kamelets/error-handler/error-handler.kamelet.yaml
index 9ace959..a5aa060 100644
--- a/examples/kamelets/error-handler/error-handler.kamelet.yaml
+++ b/examples/kamelets/error-handler/error-handler.kamelet.yaml
@@ -22,7 +22,7 @@ metadata:
spec:
definition:
title: "Error Log Sink"
- description: "Consume events from a channel"
+ description: "Error logger channel"
required:
- message
properties:
@@ -35,7 +35,6 @@ spec:
from:
uri: kamelet:source
steps:
-# - to: my-dlc
- set-body:
constant: "{{message}}"
- to: "log:error-sink"
diff --git a/examples/kamelets/error-handler/incremental-id-source.kamelet.yaml b/examples/kamelets/error-handler/incremental-id-source.kamelet.yaml
index 5e3181b..ee475da 100644
--- a/examples/kamelets/error-handler/incremental-id-source.kamelet.yaml
+++ b/examples/kamelets/error-handler/incremental-id-source.kamelet.yaml
@@ -24,7 +24,7 @@ metadata:
spec:
definition:
title: "Incremental ID Source"
- description: "Produces periodic events with an incremental ID"
+ description: "Produces periodic events with an incremental ID and fails when the ID contains any 0 character"
properties:
period:
title: Period
diff --git a/pkg/apis/camel/v1/integration_types_support.go b/pkg/apis/camel/v1/integration_types_support.go
index 6efdc24..f7e505e 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -136,7 +136,7 @@ func (in *IntegrationSpec) GetConfigurationProperty(property string) string {
for _, confSpec := range in.Configuration {
if confSpec.Type == "property" && strings.HasPrefix(confSpec.Value, property) {
splitConf := strings.Split(confSpec.Value, "=")
- if len(splitConf) > 0 {
+ if len(splitConf) > 1 {
return splitConf[1]
}
}
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index dd6e218..a72a94a 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -29,7 +29,7 @@ import (
type errorHandlerTrait struct {
BaseTrait `property:",squash"`
// The error handler ref name found in application properties
- ErrorHandlerRef string `property:",omitempty"`
+ ErrorHandlerRef string `property:"error-handler-ref" json:"error-handler-ref,omitempty"`
}
func newErrorHandlerTrait() Trait {
[camel-k] 15/30: refactor(trait): error handler spec definition
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 92d1c5db4d102ecdf26341121d83156372136169
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Thu Apr 22 15:57:40 2021 +0200
refactor(trait): error handler spec definition
---
.../crd/bases/camel.apache.org_integrations.yaml | 6 +-
.../bases/camel.apache.org_kameletbindings.yaml | 231 +--------------------
.../1.4.0/camel.apache.org_integrations.yaml | 6 +-
.../1.4.0/camel.apache.org_kameletbindings.yaml | 231 +--------------------
.../kamelet-binding-error-handler.yaml | 22 +-
examples/kamelets/error-handler/readme.md | 23 +-
helm/camel-k/crds/crd-integration.yaml | 6 +-
helm/camel-k/crds/crd-kamelet-binding.yaml | 231 +--------------------
pkg/apis/camel/v1/common_types.go | 10 +-
pkg/apis/camel/v1alpha1/error_handler_types.go | 111 ++++++++++
pkg/apis/camel/v1alpha1/kamelet_binding_types.go | 14 --
pkg/controller/kameletbinding/common.go | 33 +--
pkg/controller/kameletbinding/error_handler.go | 102 +++++++++
pkg/trait/error_handler.go | 10 +-
14 files changed, 278 insertions(+), 758 deletions(-)
diff --git a/config/crd/bases/camel.apache.org_integrations.yaml b/config/crd/bases/camel.apache.org_integrations.yaml
index c838f1f..0b1b88a 100644
--- a/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/config/crd/bases/camel.apache.org_integrations.yaml
@@ -92,8 +92,10 @@ spec:
description: ErrorHandlerSpec respresents an integration error handler
to be used as default at runtime
properties:
- configuration:
- description: ErrorHandlerConfiguration --
+ parameters:
+ description: ErrorHandlerParameters is an unstructured object
+ representing the configuration parameters available for an error
+ handler
type: object
x-kubernetes-preserve-unknown-fields: true
type:
diff --git a/config/crd/bases/camel.apache.org_kameletbindings.yaml b/config/crd/bases/camel.apache.org_kameletbindings.yaml
index 046549c..2b78d2f 100644
--- a/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -66,231 +66,8 @@ spec:
errorHandler:
description: ErrorHandler is an optional handler called upon an error
occuring in the integration
- properties:
- configuration:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- endpoint:
- description: Endpoint represents a source/sink external entity
- properties:
- properties:
- description: Properties are a key value representation of
- endpoint properties
- type: object
- x-kubernetes-preserve-unknown-fields: true
- ref:
- description: Ref can be used to declare a Kubernetes resource
- as source/sink endpoint
- properties:
- apiVersion:
- description: API version of the referent.
- type: string
- fieldPath:
- description: 'If referring to a piece of an object instead
- of an entire object, this string should contain a valid
- JSON/Go field access statement, such as desiredState.manifest.containers[2].
- For example, if the object reference is to a container
- within a pod, this would take on a value like: "spec.containers{name}"
- (where "name" refers to the name of the container that
- triggered the event) or if no container name is specified
- "spec.containers[2]" (container with index 2 in this
- pod). This syntax is chosen only to have some well-defined
- way of referencing a part of an object. TODO: this design
- is not final and this field is subject to change in
- the future.'
- type: string
- kind:
- description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- name:
- description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
- type: string
- namespace:
- description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
- type: string
- resourceVersion:
- description: 'Specific resourceVersion to which this reference
- is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
- type: string
- uid:
- description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
- type: string
- type: object
- types:
- additionalProperties:
- properties:
- mediaType:
- type: string
- schema:
- description: JSONSchemaProps is a JSON-Schema following
- Specification Draft 4 (http://json-schema.org/).
- properties:
- $schema:
- description: JSONSchemaURL represents a schema url.
- type: string
- description:
- type: string
- example:
- description: 'JSON represents any valid JSON value.
- These types are supported: bool, int64, float64,
- string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- externalDocs:
- description: ExternalDocumentation allows referencing
- an external resource for extended documentation.
- properties:
- description:
- type: string
- url:
- type: string
- type: object
- id:
- type: string
- properties:
- additionalProperties:
- properties:
- default:
- description: default is a default value for
- undefined object fields.
- x-kubernetes-preserve-unknown-fields: true
- description:
- type: string
- enum:
- items:
- description: 'JSON represents any valid
- JSON value. These types are supported:
- bool, int64, float64, string, []interface{},
- map[string]interface{} and nil.'
- x-kubernetes-preserve-unknown-fields: true
- type: array
- example:
- description: 'JSON represents any valid JSON
- value. These types are supported: bool,
- int64, float64, string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- exclusiveMaximum:
- type: boolean
- exclusiveMinimum:
- type: boolean
- format:
- description: "format is an OpenAPI v3 format
- string. Unknown formats are ignored. The
- following formats are validated: \n - bsonobjectid:
- a bson object ID, i.e. a 24 characters hex
- string - uri: an URI as parsed by Golang
- net/url.ParseRequestURI - email: an email
- address as parsed by Golang net/mail.ParseAddress
- - hostname: a valid representation for an
- Internet host name, as defined by RFC 1034,
- section 3.1 [RFC1034]. - ipv4: an IPv4 IP
- as parsed by Golang net.ParseIP - ipv6:
- an IPv6 IP as parsed by Golang net.ParseIP
- - cidr: a CIDR as parsed by Golang net.ParseCIDR
- - mac: a MAC address as parsed by Golang
- net.ParseMAC - uuid: an UUID that allows
- uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid3: an UUID3 that allows uppercase
- defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid4: an UUID4 that allows uppercase
- defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - uuid5: an UUID5 that allows uppercase
- defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - isbn: an ISBN10 or ISBN13 number string
- like \"0321751043\" or \"978-0321751041\"
- - isbn10: an ISBN10 number string like \"0321751043\"
- - isbn13: an ISBN13 number string like \"978-0321751041\"
- - creditcard: a credit card number defined
- by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
- with any non digit characters mixed in -
- ssn: a U.S. social security number following
- the regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$
- - hexcolor: an hexadecimal color code like
- \"#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
- - rgbcolor: an RGB color code like rgb like
- \"rgb(255,255,2559\" - byte: base64 encoded
- binary data - password: any kind of string
- - date: a date string like \"2006-01-02\"
- as defined by full-date in RFC3339 - duration:
- a duration string like \"22 ns\" as parsed
- by Golang time.ParseDuration or compatible
- with Scala duration format - datetime: a
- date time string like \"2014-12-15T19:30:20.000Z\"
- as defined by date-time in RFC3339."
- type: string
- id:
- type: string
- maxItems:
- format: int64
- type: integer
- maxLength:
- format: int64
- type: integer
- maxProperties:
- format: int64
- type: integer
- maximum:
- description: A Number represents a JSON number
- literal.
- type: string
- minItems:
- format: int64
- type: integer
- minLength:
- format: int64
- type: integer
- minProperties:
- format: int64
- type: integer
- minimum:
- description: A Number represents a JSON number
- literal.
- type: string
- multipleOf:
- description: A Number represents a JSON number
- literal.
- type: string
- nullable:
- type: boolean
- pattern:
- type: string
- title:
- type: string
- type:
- type: string
- uniqueItems:
- type: boolean
- x-descriptors:
- description: The list of descriptors that
- determine which UI components to use on
- different views
- items:
- type: string
- type: array
- type: object
- type: object
- required:
- items:
- type: string
- type: array
- title:
- type: string
- type:
- type: string
- type: object
- type: object
- description: Types defines the schema of the data produced/consumed
- by the endpoint
- type: object
- uri:
- description: URI can alternatively be used to specify the
- (Camel) endpoint explicitly
- type: string
- type: object
- type:
- type: string
type: object
+ x-kubernetes-preserve-unknown-fields: true
integration:
description: Integration is an optional integration used to specify
custom parameters
@@ -316,8 +93,10 @@ spec:
description: ErrorHandlerSpec respresents an integration error
handler to be used as default at runtime
properties:
- configuration:
- description: ErrorHandlerConfiguration --
+ parameters:
+ description: ErrorHandlerParameters is an unstructured object
+ representing the configuration parameters available for
+ an error handler
type: object
x-kubernetes-preserve-unknown-fields: true
type:
diff --git a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml
index c838f1f..0b1b88a 100644
--- a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml
+++ b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml
@@ -92,8 +92,10 @@ spec:
description: ErrorHandlerSpec respresents an integration error handler
to be used as default at runtime
properties:
- configuration:
- description: ErrorHandlerConfiguration --
+ parameters:
+ description: ErrorHandlerParameters is an unstructured object
+ representing the configuration parameters available for an error
+ handler
type: object
x-kubernetes-preserve-unknown-fields: true
type:
diff --git a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml
index 046549c..2b78d2f 100644
--- a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml
+++ b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml
@@ -66,231 +66,8 @@ spec:
errorHandler:
description: ErrorHandler is an optional handler called upon an error
occuring in the integration
- properties:
- configuration:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- endpoint:
- description: Endpoint represents a source/sink external entity
- properties:
- properties:
- description: Properties are a key value representation of
- endpoint properties
- type: object
- x-kubernetes-preserve-unknown-fields: true
- ref:
- description: Ref can be used to declare a Kubernetes resource
- as source/sink endpoint
- properties:
- apiVersion:
- description: API version of the referent.
- type: string
- fieldPath:
- description: 'If referring to a piece of an object instead
- of an entire object, this string should contain a valid
- JSON/Go field access statement, such as desiredState.manifest.containers[2].
- For example, if the object reference is to a container
- within a pod, this would take on a value like: "spec.containers{name}"
- (where "name" refers to the name of the container that
- triggered the event) or if no container name is specified
- "spec.containers[2]" (container with index 2 in this
- pod). This syntax is chosen only to have some well-defined
- way of referencing a part of an object. TODO: this design
- is not final and this field is subject to change in
- the future.'
- type: string
- kind:
- description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- name:
- description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
- type: string
- namespace:
- description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
- type: string
- resourceVersion:
- description: 'Specific resourceVersion to which this reference
- is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
- type: string
- uid:
- description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
- type: string
- type: object
- types:
- additionalProperties:
- properties:
- mediaType:
- type: string
- schema:
- description: JSONSchemaProps is a JSON-Schema following
- Specification Draft 4 (http://json-schema.org/).
- properties:
- $schema:
- description: JSONSchemaURL represents a schema url.
- type: string
- description:
- type: string
- example:
- description: 'JSON represents any valid JSON value.
- These types are supported: bool, int64, float64,
- string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- externalDocs:
- description: ExternalDocumentation allows referencing
- an external resource for extended documentation.
- properties:
- description:
- type: string
- url:
- type: string
- type: object
- id:
- type: string
- properties:
- additionalProperties:
- properties:
- default:
- description: default is a default value for
- undefined object fields.
- x-kubernetes-preserve-unknown-fields: true
- description:
- type: string
- enum:
- items:
- description: 'JSON represents any valid
- JSON value. These types are supported:
- bool, int64, float64, string, []interface{},
- map[string]interface{} and nil.'
- x-kubernetes-preserve-unknown-fields: true
- type: array
- example:
- description: 'JSON represents any valid JSON
- value. These types are supported: bool,
- int64, float64, string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- exclusiveMaximum:
- type: boolean
- exclusiveMinimum:
- type: boolean
- format:
- description: "format is an OpenAPI v3 format
- string. Unknown formats are ignored. The
- following formats are validated: \n - bsonobjectid:
- a bson object ID, i.e. a 24 characters hex
- string - uri: an URI as parsed by Golang
- net/url.ParseRequestURI - email: an email
- address as parsed by Golang net/mail.ParseAddress
- - hostname: a valid representation for an
- Internet host name, as defined by RFC 1034,
- section 3.1 [RFC1034]. - ipv4: an IPv4 IP
- as parsed by Golang net.ParseIP - ipv6:
- an IPv6 IP as parsed by Golang net.ParseIP
- - cidr: a CIDR as parsed by Golang net.ParseCIDR
- - mac: a MAC address as parsed by Golang
- net.ParseMAC - uuid: an UUID that allows
- uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid3: an UUID3 that allows uppercase
- defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid4: an UUID4 that allows uppercase
- defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - uuid5: an UUID5 that allows uppercase
- defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - isbn: an ISBN10 or ISBN13 number string
- like \"0321751043\" or \"978-0321751041\"
- - isbn10: an ISBN10 number string like \"0321751043\"
- - isbn13: an ISBN13 number string like \"978-0321751041\"
- - creditcard: a credit card number defined
- by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
- with any non digit characters mixed in -
- ssn: a U.S. social security number following
- the regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$
- - hexcolor: an hexadecimal color code like
- \"#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
- - rgbcolor: an RGB color code like rgb like
- \"rgb(255,255,2559\" - byte: base64 encoded
- binary data - password: any kind of string
- - date: a date string like \"2006-01-02\"
- as defined by full-date in RFC3339 - duration:
- a duration string like \"22 ns\" as parsed
- by Golang time.ParseDuration or compatible
- with Scala duration format - datetime: a
- date time string like \"2014-12-15T19:30:20.000Z\"
- as defined by date-time in RFC3339."
- type: string
- id:
- type: string
- maxItems:
- format: int64
- type: integer
- maxLength:
- format: int64
- type: integer
- maxProperties:
- format: int64
- type: integer
- maximum:
- description: A Number represents a JSON number
- literal.
- type: string
- minItems:
- format: int64
- type: integer
- minLength:
- format: int64
- type: integer
- minProperties:
- format: int64
- type: integer
- minimum:
- description: A Number represents a JSON number
- literal.
- type: string
- multipleOf:
- description: A Number represents a JSON number
- literal.
- type: string
- nullable:
- type: boolean
- pattern:
- type: string
- title:
- type: string
- type:
- type: string
- uniqueItems:
- type: boolean
- x-descriptors:
- description: The list of descriptors that
- determine which UI components to use on
- different views
- items:
- type: string
- type: array
- type: object
- type: object
- required:
- items:
- type: string
- type: array
- title:
- type: string
- type:
- type: string
- type: object
- type: object
- description: Types defines the schema of the data produced/consumed
- by the endpoint
- type: object
- uri:
- description: URI can alternatively be used to specify the
- (Camel) endpoint explicitly
- type: string
- type: object
- type:
- type: string
type: object
+ x-kubernetes-preserve-unknown-fields: true
integration:
description: Integration is an optional integration used to specify
custom parameters
@@ -316,8 +93,10 @@ spec:
description: ErrorHandlerSpec respresents an integration error
handler to be used as default at runtime
properties:
- configuration:
- description: ErrorHandlerConfiguration --
+ parameters:
+ description: ErrorHandlerParameters is an unstructured object
+ representing the configuration parameters available for
+ an error handler
type: object
x-kubernetes-preserve-unknown-fields: true
type:
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
index 457b173..5f62adc 100644
--- a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
+++ b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
@@ -31,15 +31,15 @@ spec:
apiVersion: camel.apache.org/v1alpha1
name: log-sink
errorHandler:
- type: dead-letter-channel
- endpoint:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: error-handler
- properties:
- message: "ERROR!"
- configuration:
- maximumRedeliveries: 3
- redeliveryDelay: 2000
+ dead-letter-channel:
+ endpoint:
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1alpha1
+ name: error-handler
+ properties:
+ message: "ERROR!"
+ parameters:
+ maximumRedeliveries: 3
+ redeliveryDelay: 2000
diff --git a/examples/kamelets/error-handler/readme.md b/examples/kamelets/error-handler/readme.md
index dc4d75b..42293cd 100644
--- a/examples/kamelets/error-handler/readme.md
+++ b/examples/kamelets/error-handler/readme.md
@@ -41,18 +41,21 @@ log-sink Ready
incremental-id-source Ready
```
## Error Handler Kamelet Binding
-We can create a `KameletBinding` which is started by the _incremental-id-source_ `Kamelet` and log events to _log-sink_ `Kamelet`. As this will sporadically fail, we can configure an _errorHandler_ with the _error-handler_ `Kamelet` as **Dead Letter Channel**. We can declare it as in `kamelet-binding-error-handler.yaml` file:
+We can create a `KameletBinding` which is started by the _incremental-id-source_ `Kamelet` and log events to _log-sink_ `Kamelet`. As this will sporadically fail, we can configure an _errorHandler_ with the _error-handler_ `Kamelet` as **Dead Letter Channel**. We want to configure also some redelivery policies. We can declare it as in `kamelet-binding-error-handler.yaml` file:
```
...
errorHandler:
- type: dead-letter-channel
- endpoint:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: error-handler
- properties:
- message: "ERROR!"
+ dead-letter-channel:
+ endpoint:
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1alpha1
+ name: error-handler
+ properties:
+ message: "ERROR!"
+ parameters:
+ maximumRedeliveries: 3
+ redeliveryDelay: 2000
```
Execute the following command to start the `Integration`:
```
@@ -63,6 +66,6 @@ As soon as the `Integration` starts, it will log the events on the `ok` log chan
[1] 2021-04-21 13:03:43,773 INFO [sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #8]
[1] 2021-04-21 13:03:44,774 INFO [sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #9]
[1] 2021-04-21 13:03:45,898 INFO [error-sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: ERROR!]
-[1] 2021-04-21 13:03:46,775 INFO [sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #11]
+[1] 2021-04-21 13:09:46,775 INFO [sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #11]
```
This example is useful to guide you through the configuration of an error handler. In a production environment you will likely configure the error handler `Kamelet` pointing to a persistent queue.
\ No newline at end of file
diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml
index c838f1f..0b1b88a 100644
--- a/helm/camel-k/crds/crd-integration.yaml
+++ b/helm/camel-k/crds/crd-integration.yaml
@@ -92,8 +92,10 @@ spec:
description: ErrorHandlerSpec respresents an integration error handler
to be used as default at runtime
properties:
- configuration:
- description: ErrorHandlerConfiguration --
+ parameters:
+ description: ErrorHandlerParameters is an unstructured object
+ representing the configuration parameters available for an error
+ handler
type: object
x-kubernetes-preserve-unknown-fields: true
type:
diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml
index 046549c..2b78d2f 100644
--- a/helm/camel-k/crds/crd-kamelet-binding.yaml
+++ b/helm/camel-k/crds/crd-kamelet-binding.yaml
@@ -66,231 +66,8 @@ spec:
errorHandler:
description: ErrorHandler is an optional handler called upon an error
occuring in the integration
- properties:
- configuration:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- endpoint:
- description: Endpoint represents a source/sink external entity
- properties:
- properties:
- description: Properties are a key value representation of
- endpoint properties
- type: object
- x-kubernetes-preserve-unknown-fields: true
- ref:
- description: Ref can be used to declare a Kubernetes resource
- as source/sink endpoint
- properties:
- apiVersion:
- description: API version of the referent.
- type: string
- fieldPath:
- description: 'If referring to a piece of an object instead
- of an entire object, this string should contain a valid
- JSON/Go field access statement, such as desiredState.manifest.containers[2].
- For example, if the object reference is to a container
- within a pod, this would take on a value like: "spec.containers{name}"
- (where "name" refers to the name of the container that
- triggered the event) or if no container name is specified
- "spec.containers[2]" (container with index 2 in this
- pod). This syntax is chosen only to have some well-defined
- way of referencing a part of an object. TODO: this design
- is not final and this field is subject to change in
- the future.'
- type: string
- kind:
- description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- name:
- description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
- type: string
- namespace:
- description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
- type: string
- resourceVersion:
- description: 'Specific resourceVersion to which this reference
- is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
- type: string
- uid:
- description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
- type: string
- type: object
- types:
- additionalProperties:
- properties:
- mediaType:
- type: string
- schema:
- description: JSONSchemaProps is a JSON-Schema following
- Specification Draft 4 (http://json-schema.org/).
- properties:
- $schema:
- description: JSONSchemaURL represents a schema url.
- type: string
- description:
- type: string
- example:
- description: 'JSON represents any valid JSON value.
- These types are supported: bool, int64, float64,
- string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- externalDocs:
- description: ExternalDocumentation allows referencing
- an external resource for extended documentation.
- properties:
- description:
- type: string
- url:
- type: string
- type: object
- id:
- type: string
- properties:
- additionalProperties:
- properties:
- default:
- description: default is a default value for
- undefined object fields.
- x-kubernetes-preserve-unknown-fields: true
- description:
- type: string
- enum:
- items:
- description: 'JSON represents any valid
- JSON value. These types are supported:
- bool, int64, float64, string, []interface{},
- map[string]interface{} and nil.'
- x-kubernetes-preserve-unknown-fields: true
- type: array
- example:
- description: 'JSON represents any valid JSON
- value. These types are supported: bool,
- int64, float64, string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- exclusiveMaximum:
- type: boolean
- exclusiveMinimum:
- type: boolean
- format:
- description: "format is an OpenAPI v3 format
- string. Unknown formats are ignored. The
- following formats are validated: \n - bsonobjectid:
- a bson object ID, i.e. a 24 characters hex
- string - uri: an URI as parsed by Golang
- net/url.ParseRequestURI - email: an email
- address as parsed by Golang net/mail.ParseAddress
- - hostname: a valid representation for an
- Internet host name, as defined by RFC 1034,
- section 3.1 [RFC1034]. - ipv4: an IPv4 IP
- as parsed by Golang net.ParseIP - ipv6:
- an IPv6 IP as parsed by Golang net.ParseIP
- - cidr: a CIDR as parsed by Golang net.ParseCIDR
- - mac: a MAC address as parsed by Golang
- net.ParseMAC - uuid: an UUID that allows
- uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid3: an UUID3 that allows uppercase
- defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid4: an UUID4 that allows uppercase
- defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - uuid5: an UUID5 that allows uppercase
- defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - isbn: an ISBN10 or ISBN13 number string
- like \"0321751043\" or \"978-0321751041\"
- - isbn10: an ISBN10 number string like \"0321751043\"
- - isbn13: an ISBN13 number string like \"978-0321751041\"
- - creditcard: a credit card number defined
- by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
- with any non digit characters mixed in -
- ssn: a U.S. social security number following
- the regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$
- - hexcolor: an hexadecimal color code like
- \"#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
- - rgbcolor: an RGB color code like rgb like
- \"rgb(255,255,2559\" - byte: base64 encoded
- binary data - password: any kind of string
- - date: a date string like \"2006-01-02\"
- as defined by full-date in RFC3339 - duration:
- a duration string like \"22 ns\" as parsed
- by Golang time.ParseDuration or compatible
- with Scala duration format - datetime: a
- date time string like \"2014-12-15T19:30:20.000Z\"
- as defined by date-time in RFC3339."
- type: string
- id:
- type: string
- maxItems:
- format: int64
- type: integer
- maxLength:
- format: int64
- type: integer
- maxProperties:
- format: int64
- type: integer
- maximum:
- description: A Number represents a JSON number
- literal.
- type: string
- minItems:
- format: int64
- type: integer
- minLength:
- format: int64
- type: integer
- minProperties:
- format: int64
- type: integer
- minimum:
- description: A Number represents a JSON number
- literal.
- type: string
- multipleOf:
- description: A Number represents a JSON number
- literal.
- type: string
- nullable:
- type: boolean
- pattern:
- type: string
- title:
- type: string
- type:
- type: string
- uniqueItems:
- type: boolean
- x-descriptors:
- description: The list of descriptors that
- determine which UI components to use on
- different views
- items:
- type: string
- type: array
- type: object
- type: object
- required:
- items:
- type: string
- type: array
- title:
- type: string
- type:
- type: string
- type: object
- type: object
- description: Types defines the schema of the data produced/consumed
- by the endpoint
- type: object
- uri:
- description: URI can alternatively be used to specify the
- (Camel) endpoint explicitly
- type: string
- type: object
- type:
- type: string
type: object
+ x-kubernetes-preserve-unknown-fields: true
integration:
description: Integration is an optional integration used to specify
custom parameters
@@ -316,8 +93,10 @@ spec:
description: ErrorHandlerSpec respresents an integration error
handler to be used as default at runtime
properties:
- configuration:
- description: ErrorHandlerConfiguration --
+ parameters:
+ description: ErrorHandlerParameters is an unstructured object
+ representing the configuration parameters available for
+ an error handler
type: object
x-kubernetes-preserve-unknown-fields: true
type:
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index e1b27e1..71774fc 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -164,13 +164,13 @@ type Flow struct {
// ErrorHandlerSpec respresents an integration error handler to be used as default at runtime
type ErrorHandlerSpec struct {
- Type string `json:"type,omitempty"`
- URI string `json:"uri,omitempty"`
- Configuration *ErrorHandlerConfiguration `json:"configuration,omitempty"`
+ Type string `json:"type,omitempty"`
+ URI string `json:"uri,omitempty"`
+ Parameters *ErrorHandlerParameters `json:"parameters,omitempty"`
}
-// ErrorHandlerConfiguration --
-type ErrorHandlerConfiguration struct {
+// ErrorHandlerParameters is an unstructured object representing the configuration parameters available for an error handler
+type ErrorHandlerParameters struct {
RawMessage `json:",inline"`
}
diff --git a/pkg/apis/camel/v1alpha1/error_handler_types.go b/pkg/apis/camel/v1alpha1/error_handler_types.go
new file mode 100644
index 0000000..a6b15b1
--- /dev/null
+++ b/pkg/apis/camel/v1alpha1/error_handler_types.go
@@ -0,0 +1,111 @@
+/*
+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 v1alpha1
+
+import (
+ v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+// ErrorHandler represent an unstructured object for an error handler
+type ErrorHandler struct {
+ v1.RawMessage `json:",omitempty"`
+}
+
+// AbstractErrorHandler is a generic interface that represent any type of error handler specification
+type AbstractErrorHandler interface {
+ Type() ErrorHandlerType
+ Params() *ErrorHandlerProperties
+ Endpoint() *Endpoint
+}
+
+// ErrorHandlerNone --
+type ErrorHandlerNone struct {
+}
+
+// NewErrorHandlerNone represents a no (ignore) error handler type
+func NewErrorHandlerNone() ErrorHandlerNone {
+ return ErrorHandlerNone{}
+}
+
+// Type --
+func (e ErrorHandlerNone) Type() ErrorHandlerType {
+ return ErrorHandlerTypeNone
+}
+
+// Params --
+func (e ErrorHandlerNone) Params() *ErrorHandlerProperties {
+ return nil
+}
+
+// Endpoint --
+func (e ErrorHandlerNone) Endpoint() *Endpoint {
+ return nil
+}
+
+// ErrorHandlerLog represent a default (log) error handler type
+type ErrorHandlerLog struct {
+ Parameters *ErrorHandlerProperties `json:"parameters,omitempty"`
+}
+
+// Type --
+func (e ErrorHandlerLog) Type() ErrorHandlerType {
+ return ErrorHandlerTypeLog
+}
+
+// Params --
+func (e ErrorHandlerLog) Params() *ErrorHandlerProperties {
+ return e.Parameters
+}
+
+// Endpoint --
+func (e ErrorHandlerLog) Endpoint() *Endpoint {
+ return nil
+}
+
+// ErrorHandlerDeadLetterChannel represents a dead letter channel error handler type
+type ErrorHandlerDeadLetterChannel struct {
+ *ErrorHandlerLog
+ DLCEndpoint *Endpoint `json:"endpoint,omitempty"`
+}
+
+// Type --
+func (e ErrorHandlerDeadLetterChannel) Type() ErrorHandlerType {
+ return ErrorHandlerTypeDeadLetterChannel
+}
+
+// Params --
+func (e ErrorHandlerDeadLetterChannel) Params() *ErrorHandlerProperties {
+ return e.Parameters
+}
+
+// Endpoint --
+func (e ErrorHandlerDeadLetterChannel) Endpoint() *Endpoint {
+ return e.DLCEndpoint
+}
+
+// ErrorHandlerType --
+type ErrorHandlerType string
+
+const (
+ // ErrorHandlerTypeNone --
+ ErrorHandlerTypeNone ErrorHandlerType = "none"
+ // ErrorHandlerTypeLog --
+ ErrorHandlerTypeLog ErrorHandlerType = "log"
+ // ErrorHandlerTypeDeadLetterChannel --
+ ErrorHandlerTypeDeadLetterChannel ErrorHandlerType = "dead-letter-channel"
+)
diff --git a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
index 367692c..5a279e1 100644
--- a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
+++ b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
@@ -38,20 +38,6 @@ type KameletBindingSpec struct {
Steps []Endpoint `json:"steps,omitempty"`
}
-type ErrorHandler struct {
- Endpoint Endpoint `json:"endpoint,omitempty"`
- Type ErrorHandlerType `json:"type,omitempty"`
- Configuration *ErrorHandlerProperties `json:"configuration,omitempty"`
-}
-
-type ErrorHandlerType string
-
-const (
- ErrorHandlerTypeNone ErrorHandlerType = "no"
- ErrorHandlerTypeDefault ErrorHandlerType = "default"
- ErrorHandlerTypeDeadLetterChannel ErrorHandlerType = "dead-letter-channel"
-)
-
// Endpoint represents a source/sink external entity
type Endpoint struct {
// Ref can be used to declare a Kubernetes resource as source/sink endpoint
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index c4d4641..d434000 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -79,22 +79,10 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
if err != nil {
return nil, errors.Wrap(err, "could not determine sink URI")
}
- var errorHandler *bindings.Binding
- if kameletbinding.Spec.ErrorHandler.Type != "" {
- errorHandlerURI := ""
- if kameletbinding.Spec.ErrorHandler.Endpoint.Ref != nil || kameletbinding.Spec.ErrorHandler.Endpoint.URI != nil {
- errorHandler, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler.Endpoint)
- if err != nil {
- return nil, errors.Wrap(err, "could not determine error handler URI")
- }
-
- errorHandlerURI = errorHandler.URI
- }
-
- err = setIntegrationErrorHandler(&it.Spec, errorHandlerURI, kameletbinding.Spec.ErrorHandler)
- if err != nil {
- return nil, errors.Wrap(err, "could not set integration error handler")
- }
+ // error handler is optional
+ errorHandler, err := maybeErrorHandler(kameletbinding.Spec.ErrorHandler, bindingContext, &it.Spec)
+ if err != nil {
+ return nil, errors.Wrap(err, "could not determine error handler")
}
steps := make([]*bindings.Binding, 0, len(kameletbinding.Spec.Steps))
@@ -164,19 +152,6 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
return &it, nil
}
-func setIntegrationErrorHandler(it *v1.IntegrationSpec, errorHandlerURI string, errorHandlerSpec v1alpha1.ErrorHandler) error {
- it.ErrorHandler = v1.ErrorHandlerSpec{
- Type: string(errorHandlerSpec.Type),
- Configuration: &v1.ErrorHandlerConfiguration{errorHandlerSpec.Configuration.RawMessage},
- }
-
- if errorHandlerURI != "" {
- it.ErrorHandler.URI = errorHandlerURI
- }
-
- return nil
-}
-
func determineProfile(ctx context.Context, c client.Client, binding *v1alpha1.KameletBinding) (v1.TraitProfile, error) {
if binding.Spec.Integration != nil && binding.Spec.Integration.Profile != "" {
return binding.Spec.Integration.Profile, nil
diff --git a/pkg/controller/kameletbinding/error_handler.go b/pkg/controller/kameletbinding/error_handler.go
new file mode 100644
index 0000000..90ba3cc
--- /dev/null
+++ b/pkg/controller/kameletbinding/error_handler.go
@@ -0,0 +1,102 @@
+/*
+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 kameletbinding
+
+import (
+ "encoding/json"
+
+ v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ "github.com/apache/camel-k/pkg/util/bindings"
+ "github.com/pkg/errors"
+)
+
+func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandler, bindingContext bindings.BindingContext, itSpec *v1.IntegrationSpec) (*bindings.Binding, error) {
+ var errorHandler *bindings.Binding
+ if errHandlConf.RawMessage != nil {
+ errorHandlerSpec, err := parseErrorHandler(errHandlConf.RawMessage)
+ if err != nil {
+ return nil, errors.Wrap(err, "could not parse error handler")
+ }
+ errorHandlerURI := ""
+ if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeDeadLetterChannel {
+ errorHandler, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, *errorHandlerSpec.Endpoint())
+ if err != nil {
+ return nil, errors.Wrap(err, "could not determine error handler URI")
+ }
+
+ errorHandlerURI = errorHandler.URI
+ }
+
+ err = setIntegrationErrorHandler(itSpec, errorHandlerURI, errorHandlerSpec)
+ if err != nil {
+ return nil, errors.Wrap(err, "could not set integration error handler")
+ }
+
+ return errorHandler, nil
+ }
+ return nil, nil
+}
+
+func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.AbstractErrorHandler, error) {
+ var properties map[v1alpha1.ErrorHandlerType]v1.RawMessage
+ err := json.Unmarshal(rawMessage, &properties)
+ if err != nil {
+ return nil, err
+ }
+ if len(properties) > 1 {
+ return nil, errors.Errorf("You must provide just 1 error handler, provided %d", len(properties))
+ }
+
+ for errHandlType, errHandlValue := range properties {
+ var dst v1alpha1.AbstractErrorHandler
+ switch errHandlType {
+ case v1alpha1.ErrorHandlerTypeNone:
+ dst = new(v1alpha1.ErrorHandlerNone)
+ case v1alpha1.ErrorHandlerTypeLog:
+ dst = new(v1alpha1.ErrorHandlerLog)
+ case v1alpha1.ErrorHandlerTypeDeadLetterChannel:
+ dst = new(v1alpha1.ErrorHandlerDeadLetterChannel)
+ default:
+ return nil, errors.Errorf("Unknown error type %s, supported error types are: none, log, dead-letter-channel", errHandlType)
+ }
+
+ err := json.Unmarshal(errHandlValue, dst)
+ if err != nil {
+ return nil, err
+ }
+
+ return dst, nil
+ }
+
+ return nil, errors.New("You must provide any supported error handler (none, log, dead-letter-channel)")
+}
+
+func setIntegrationErrorHandler(it *v1.IntegrationSpec, errorHandlerURI string, errorHandlerSpec v1alpha1.AbstractErrorHandler) error {
+ it.ErrorHandler = v1.ErrorHandlerSpec{
+ Type: string(errorHandlerSpec.Type()),
+ }
+ if errorHandlerSpec.Params() != nil {
+ it.ErrorHandler.Parameters = &v1.ErrorHandlerParameters{errorHandlerSpec.Params().RawMessage}
+ }
+ if errorHandlerURI != "" {
+ it.ErrorHandler.URI = errorHandlerURI
+ }
+
+ return nil
+}
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index eadaa70..e82dcf9 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -107,17 +107,17 @@ func addErrorHandlerAsSource(e *Environment) error {
func parseErrorHandler(errorHandlerSpec v1.ErrorHandlerSpec) (string, error) {
switch errorHandlerSpec.Type {
- case "no":
+ case "none":
return `errorHandler(noErrorHandler());`, nil
- case "default":
- errorHandlerConfiguration, err := parseErrorHandlerConfiguration(errorHandlerSpec.Configuration)
+ case "log":
+ errorHandlerConfiguration, err := parseErrorHandlerConfiguration(errorHandlerSpec.Parameters)
if err != nil {
return "", err
}
return fmt.Sprintf(`errorHandler(defaultErrorHandler()%v);`, errorHandlerConfiguration), nil
case "dead-letter-channel":
- errorHandlerConfiguration, err := parseErrorHandlerConfiguration(errorHandlerSpec.Configuration)
+ errorHandlerConfiguration, err := parseErrorHandlerConfiguration(errorHandlerSpec.Parameters)
if err != nil {
return "", err
}
@@ -128,7 +128,7 @@ func parseErrorHandler(errorHandlerSpec v1.ErrorHandlerSpec) (string, error) {
return "", fmt.Errorf("Cannot recognize any error handler of type %s", errorHandlerSpec.Type)
}
-func parseErrorHandlerConfiguration(conf *v1.ErrorHandlerConfiguration) (string, error) {
+func parseErrorHandlerConfiguration(conf *v1.ErrorHandlerParameters) (string, error) {
javaPropertiesBuilder := ""
var properties map[string]interface{}
err := json.Unmarshal(conf.RawMessage, &properties)
[camel-k] 18/30: feat(trait): error handler bean
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 77282611649987f18ddf4249521efb2c211093dc
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Fri Apr 23 15:01:46 2021 +0200
feat(trait): error handler bean
Adding capability to support a bean as expected by Camel Main - https://camel.apache.org/components/3.7.x/others/main.html#_specifying_custom_beans
---
pkg/apis/camel/v1alpha1/error_handler_types.go | 113 +++++++++++----------
pkg/apis/camel/v1alpha1/kamelet_binding_types.go | 2 +-
pkg/controller/kameletbinding/error_handler.go | 16 +--
.../kameletbinding/error_handler_test.go | 16 +++
pkg/resources/resources.go | 44 ++++----
pkg/trait/error_handler.go | 29 +++---
6 files changed, 126 insertions(+), 94 deletions(-)
diff --git a/pkg/apis/camel/v1alpha1/error_handler_types.go b/pkg/apis/camel/v1alpha1/error_handler_types.go
index 949fbd6..1969e2b 100644
--- a/pkg/apis/camel/v1alpha1/error_handler_types.go
+++ b/pkg/apis/camel/v1alpha1/error_handler_types.go
@@ -21,56 +21,72 @@ import (
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
)
-// ErrorHandler represents an unstructured object for an error handler
-type ErrorHandler struct {
+// ErrorHandlerSpec represents an unstructured object for an error handler
+type ErrorHandlerSpec struct {
v1.RawMessage `json:",omitempty"`
}
-// ErrorHandlerProperties represent an unstructured object for error handler parameters
-type ErrorHandlerProperties struct {
+// ErrorHandlerParameters represent an unstructured object for error handler parameters
+type ErrorHandlerParameters struct {
v1.RawMessage `json:",inline"`
}
-// AbstractErrorHandler is a generic interface that represent any type of error handler specification
-type AbstractErrorHandler interface {
+// BeanProperties represent an unstructured object properties to be set on a bean
+type BeanProperties struct {
+ v1.RawMessage `json:",inline"`
+}
+
+// ErrorHandler is a generic interface that represent any type of error handler specification
+type ErrorHandler interface {
Type() ErrorHandlerType
- Params() *ErrorHandlerProperties
+ Params() *ErrorHandlerParameters
Endpoint() *Endpoint
Ref() *string
+ Bean() *string
}
-// ErrorHandlerNone --
-type ErrorHandlerNone struct {
-}
-
-// NewErrorHandlerNone represents a no (ignore) error handler type
-func NewErrorHandlerNone() ErrorHandlerNone {
- return ErrorHandlerNone{}
+type abstractErrorHandler struct {
}
// Type --
-func (e ErrorHandlerNone) Type() ErrorHandlerType {
- return ErrorHandlerTypeNone
+func (e abstractErrorHandler) Type() ErrorHandlerType {
+ return errorHandlerTypeAbstract
}
// Params --
-func (e ErrorHandlerNone) Params() *ErrorHandlerProperties {
+func (e abstractErrorHandler) Params() *ErrorHandlerParameters {
return nil
}
// Endpoint --
-func (e ErrorHandlerNone) Endpoint() *Endpoint {
+func (e abstractErrorHandler) Endpoint() *Endpoint {
return nil
}
// Ref --
-func (e ErrorHandlerNone) Ref() *string {
+func (e abstractErrorHandler) Ref() *string {
return nil
}
+// Ref --
+func (e abstractErrorHandler) Bean() *string {
+ return nil
+}
+
+// ErrorHandlerNone --
+type ErrorHandlerNone struct {
+ *abstractErrorHandler
+}
+
+// Type --
+func (e ErrorHandlerNone) Type() ErrorHandlerType {
+ return ErrorHandlerTypeNone
+}
+
// ErrorHandlerLog represent a default (log) error handler type
type ErrorHandlerLog struct {
- Parameters *ErrorHandlerProperties `json:"parameters,omitempty"`
+ *abstractErrorHandler
+ Parameters *ErrorHandlerParameters `json:"parameters,omitempty"`
}
// Type --
@@ -79,20 +95,10 @@ func (e ErrorHandlerLog) Type() ErrorHandlerType {
}
// Params --
-func (e ErrorHandlerLog) Params() *ErrorHandlerProperties {
+func (e ErrorHandlerLog) Params() *ErrorHandlerParameters {
return e.Parameters
}
-// Endpoint --
-func (e ErrorHandlerLog) Endpoint() *Endpoint {
- return nil
-}
-
-// Ref --
-func (e ErrorHandlerLog) Ref() *string {
- return nil
-}
-
// ErrorHandlerDeadLetterChannel represents a dead letter channel error handler type
type ErrorHandlerDeadLetterChannel struct {
*ErrorHandlerLog
@@ -104,49 +110,50 @@ func (e ErrorHandlerDeadLetterChannel) Type() ErrorHandlerType {
return ErrorHandlerTypeDeadLetterChannel
}
-// Params --
-func (e ErrorHandlerDeadLetterChannel) Params() *ErrorHandlerProperties {
- return e.Parameters
-}
-
// Endpoint --
func (e ErrorHandlerDeadLetterChannel) Endpoint() *Endpoint {
return e.DLCEndpoint
}
-// Ref --
-func (e ErrorHandlerDeadLetterChannel) Ref() *string {
- return nil
-}
-
// ErrorHandlerRef represents a reference to an error handler builder available in the registry
-type ErrorHandlerRef string
+type ErrorHandlerRef struct {
+ *abstractErrorHandler
+ string
+}
// Type --
func (e ErrorHandlerRef) Type() ErrorHandlerType {
return ErrorHandlerTypeRef
}
-// Params --
-func (e ErrorHandlerRef) Params() *ErrorHandlerProperties {
- return nil
+// Ref --
+func (e ErrorHandlerRef) Ref() *string {
+ s := string(e.string)
+ return &s
}
-// Endpoint --
-func (e ErrorHandlerRef) Endpoint() *Endpoint {
- return nil
+// ErrorHandlerBean represents a bean error handler type
+type ErrorHandlerBean struct {
+ *ErrorHandlerLog
+ BeanType *string `json:"type,omitempty"`
+ Properties *BeanProperties `json:"properties,omitempty"`
}
-// Ref --
-func (e ErrorHandlerRef) Ref() *string {
- s := string(e)
- return &s
+// Type --
+func (e ErrorHandlerBean) Type() ErrorHandlerType {
+ return ErrorHandlerTypeBean
+}
+
+// Bean --
+func (e ErrorHandlerBean) Bean() *string {
+ return e.BeanType
}
// ErrorHandlerType --
type ErrorHandlerType string
const (
+ errorHandlerTypeAbstract ErrorHandlerType = ""
// ErrorHandlerTypeNone --
ErrorHandlerTypeNone ErrorHandlerType = "none"
// ErrorHandlerTypeLog --
@@ -155,4 +162,6 @@ const (
ErrorHandlerTypeDeadLetterChannel ErrorHandlerType = "dead-letter-channel"
// ErrorHandlerTypeRef --
ErrorHandlerTypeRef ErrorHandlerType = "ref"
+ // ErrorHandlerTypeBean --
+ ErrorHandlerTypeBean ErrorHandlerType = "bean"
)
diff --git a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
index 62e8079..cfe8779 100644
--- a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
+++ b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
@@ -33,7 +33,7 @@ type KameletBindingSpec struct {
// Sink is the destination of the integration defined by this binding
Sink Endpoint `json:"sink,omitempty"`
// ErrorHandler is an optional handler called upon an error occuring in the integration
- ErrorHandler ErrorHandler `json:"errorHandler,omitempty"`
+ ErrorHandler ErrorHandlerSpec `json:"errorHandler,omitempty"`
// Steps contains an optional list of intermediate steps that are executed between the Source and the Sink
Steps []Endpoint `json:"steps,omitempty"`
}
diff --git a/pkg/controller/kameletbinding/error_handler.go b/pkg/controller/kameletbinding/error_handler.go
index c9858f9..15e72bb 100644
--- a/pkg/controller/kameletbinding/error_handler.go
+++ b/pkg/controller/kameletbinding/error_handler.go
@@ -26,7 +26,7 @@ import (
"github.com/pkg/errors"
)
-func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandler, bindingContext bindings.BindingContext, itSpec *v1.IntegrationSpec) (*bindings.Binding, error) {
+func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandlerSpec, bindingContext bindings.BindingContext, itSpec *v1.IntegrationSpec) (*bindings.Binding, error) {
var errorHandler *bindings.Binding
if errHandlConf.RawMessage != nil {
errorHandlerSpec, err := parseErrorHandler(errHandlConf.RawMessage)
@@ -41,10 +41,10 @@ func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandler, bindingContext bindin
}
errorHandlerURI = errorHandler.URI
- }
-
- if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeRef {
+ } else if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeRef {
errorHandlerURI = *errorHandlerSpec.Ref()
+ } else if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeBean {
+ errorHandlerURI = *errorHandlerSpec.Bean()
}
err = setIntegrationErrorHandler(itSpec, errorHandlerURI, errorHandlerSpec)
@@ -57,7 +57,7 @@ func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandler, bindingContext bindin
return nil, nil
}
-func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.AbstractErrorHandler, error) {
+func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.ErrorHandler, error) {
var properties map[v1alpha1.ErrorHandlerType]v1.RawMessage
err := json.Unmarshal(rawMessage, &properties)
if err != nil {
@@ -68,7 +68,7 @@ func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.AbstractErrorHandler,
}
for errHandlType, errHandlValue := range properties {
- var dst v1alpha1.AbstractErrorHandler
+ var dst v1alpha1.ErrorHandler
switch errHandlType {
case v1alpha1.ErrorHandlerTypeNone:
dst = new(v1alpha1.ErrorHandlerNone)
@@ -78,6 +78,8 @@ func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.AbstractErrorHandler,
dst = new(v1alpha1.ErrorHandlerDeadLetterChannel)
case v1alpha1.ErrorHandlerTypeRef:
dst = new(v1alpha1.ErrorHandlerRef)
+ case v1alpha1.ErrorHandlerTypeBean:
+ dst = new(v1alpha1.ErrorHandlerBean)
default:
return nil, errors.Errorf("Unknown error type %s, supported error types are: none, log, dead-letter-channel", errHandlType)
}
@@ -93,7 +95,7 @@ func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.AbstractErrorHandler,
return nil, errors.New("You must provide any supported error handler (none, log, dead-letter-channel)")
}
-func setIntegrationErrorHandler(it *v1.IntegrationSpec, errorHandlerURI string, errorHandlerSpec v1alpha1.AbstractErrorHandler) error {
+func setIntegrationErrorHandler(it *v1.IntegrationSpec, errorHandlerURI string, errorHandlerSpec v1alpha1.ErrorHandler) error {
it.ErrorHandler = v1.ErrorHandlerSpec{
Type: string(errorHandlerSpec.Type()),
}
diff --git a/pkg/controller/kameletbinding/error_handler_test.go b/pkg/controller/kameletbinding/error_handler_test.go
index 1600707..40864b9 100644
--- a/pkg/controller/kameletbinding/error_handler_test.go
+++ b/pkg/controller/kameletbinding/error_handler_test.go
@@ -75,3 +75,19 @@ func TestParseErrorHandlerDLCWithParametersDoesSucceed(t *testing.T) {
assert.Equal(t, "someUri", *dlcErrorHandler.Endpoint().URI)
assert.NotNil(t, dlcErrorHandler.Params())
}
+
+func TestParseErrorHandlerBeanWithParametersDoesSucceed(t *testing.T) {
+ beanErrorHandler, err := parseErrorHandler(
+ []byte(`{
+ "bean": {
+ "type": "com.acme.MyType",
+ "parameters":
+ [{"param1": "value1"}]
+ }
+ }`),
+ )
+ assert.Nil(t, err)
+ assert.Equal(t, v1alpha1.ErrorHandlerTypeBean, beanErrorHandler.Type())
+ assert.Equal(t, "com.acme.MyType", *beanErrorHandler.Bean())
+ assert.NotNil(t, beanErrorHandler.Params())
+}
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 6b712ac..5c771bb 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -106,16 +106,16 @@ var assets = func() http.FileSystem {
"/crd/bases/camel.apache.org_integrations.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_integrations.yaml",
modTime: time.Time{},
- uncompressedSize: 23405,
+ uncompressedSize: 24066,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3c\x5d\x73\xdb\xba\x95\xef\xfa\x15\x67\xec\x87\xdc\xcc\x48\x54\x93\xb4\xb3\x3b\xde\x27\xd7\x89\x77\xb5\xf1\xb5\x33\x96\xd3\x3b\x77\x3a\x7d\x80\xc8\x43\x0a\x35\x08\x70\x01\xd0\xb2\xda\xe9\x7f\xdf\x39\x07\x24\x45\x4a\xa4\xac\xc8\xb9\xf7\x76\xbb\xe2\x4b\x62\x12\x38\x38\xdf\x5f\x00\x74\x0e\x93\xef\xf7\x8c\xce\xe1\x46\xc6\xa8\x1d\x26\xe0\x0d\xf8\x25\xc2\x65\x21\xe2\x25\xc2\xdc\xa4\x7e\x25\x2c\xc2\xb5\x29\x75\x22\xbc\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3c\x5d\x73\xe3\xb8\x91\xef\xfa\x15\x5d\xf6\xc3\xec\x56\x49\x54\x66\x26\xa9\xbb\xf2\x3d\x79\x3d\x33\x17\xdd\x78\x6d\x97\xe5\xc9\xd6\x56\x2a\x0f\x10\xd9\x12\x11\x83\x00\x0f\x00\x25\x2b\xa9\xfc\xf7\xab\x6e\x90\x14\x29\x91\xb4\xc6\x9e\xdd\xcd\x25\xe2\xcb\x8c\x49\xa0\xd1\xdf\x5f\x00\x74\x0e\x93\x6f\xf7\x8c\xce\xe1\x5a\xc6\xa8\x1d\x26\xe0\x0d\xf8\x14\xe1\x32\x17\x71\x8a\x30\x37\x4b\xbf\x11\x16\xe1\x93\x29\x74\x22\xbc\x [...]
},
"/crd/bases/camel.apache.org_kameletbindings.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_kameletbindings.yaml",
modTime: time.Time{},
- uncompressedSize: 55181,
+ uncompressedSize: 56150,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xf1\x6f\xdb\x38\xf2\xef\xef\xf9\x2b\x06\xc9\x01\x6d\x01\x4b\x8e\xe3\xb4\xbb\xeb\xf7\x43\x91\x26\xdb\x7b\x7e\xed\xa6\x45\x92\xde\xe1\x5e\xdb\x03\x68\x69\x6c\xf3\x22\x91\x3a\x92\x8a\xe3\xef\xb6\xff\xfb\x17\x24\x25\x59\x76\x2c\x99\x72\xec\x6e\x0a\x88\xc0\x62\x6b\x8b\x1a\xce\x0c\x87\xc3\x99\x21\x3f\xce\x11\x78\xbb\x6b\x07\x47\xf0\x9e\x06\xc8\x24\x86\xa0\x38\xa8\x29\xc2\x59\x42\x82\x29\xc2\x35\x1f\xab\x19\x11\x08\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xf1\x6f\xdb\x38\xf2\xef\xef\xf9\x2b\x06\xc9\x01\x6d\x81\x48\x8e\x93\xb4\xbb\xeb\xf7\x43\x91\x26\xdb\xfb\xfa\xb5\x9b\x06\x49\x7a\x87\x7b\x6d\x0f\xa0\xa5\xb1\xcd\x8b\x44\xea\x48\x2a\x8e\xdf\xb6\xff\xfb\x17\x24\x25\x59\x76\x2c\x89\x72\xec\x6e\x0b\x88\x40\xd1\xd8\xa6\x86\x33\xc3\x99\xe1\x70\xc8\x8f\x7d\x00\xde\xf6\xda\xde\x01\xbc\xa7\x01\x32\x89\x21\x28\x0e\x6a\x8a\x70\x96\x90\x60\x8a\x70\xc3\xc7\x6a\x46\x04\xc2\x [...]
},
"/crd/bases/camel.apache.org_kamelets.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_kamelets.yaml",
@@ -238,13 +238,6 @@ var assets = func() http.FileSystem {
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x6f\xab\x46\x14\xdd\xcf\xaf\x38\x32\x9b\xf7\x24\x1b\xb7\x5d\x55\xee\x8a\x97\xd8\x2d\x6a\x64\x4b\xc6\x69\x94\xe5\x78\xb8\xc0\xad\x61\x2e\x9d\x19\x42\xdc\x5f\x5f\x0d\xb6\x9b\x44\x55\xab\x2e\x32\x2b\x10\x97\xf3\x71\xcf\x99\x04\x8b\xcf\x3b\x2a\xc1\x03\x1b\xb2\x9e\x4a\x04\x41\x68\x08\x59\xaf\x4d\x43\x28\xa4\x0a\xa3\x76\x84\x8d\x0c\xb6\xd4\x81\xc5\xe2\x4b\x56\x6c\xbe\x62\xb0\x25\x39\x88\x25\x88\x43\x27\x8e\x54\x [...]
},
- "/rbac/operator-role-binding-podmonitors.yaml": &vfsgen۰CompressedFileInfo{
- name: "operator-role-binding-podmonitors.yaml",
- modTime: time.Time{},
- uncompressedSize: 1229,
-
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x4f\x85\x7b\x72\x36\xbb\xad\xd0\xc0\x06\x2c\xa7\x41\x8e\x34\x35\x96\xa6\x2b\x71\xd8\x21\xb5\x8a\xfb\xeb\x0b\xca\x76\x77\x83\xa2\x45\x0f\xe1\x4d\xd0\xf0\x7d\xcc\x7b\x2c\xb0\xfc\x76\xc7\x14\xf8\xc0\x8e\x7c\xa4\x06\x49\x90\x3a\xc2\x26\x58\xd7\x11\x6a\x39\xa5\xc9\x2a\xe1\x51\x46\xdf\xd8\xc4\xe2\xf1\x66\x53\x3f\xbe\xc5\xe8\x1b\x52\x88\x27\x88\x62\x10\x25\x [...]
- },
"/rbac/operator-role-binding-service-binding.yaml": &vfsgen۰CompressedFileInfo{
name: "operator-role-binding-service-binding.yaml",
modTime: time.Time{},
@@ -252,6 +245,13 @@ var assets = func() http.FileSystem {
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xcf\x6f\xf2\x46\x10\xbd\xef\x5f\xf1\x84\x2f\xdf\x27\x81\x69\x7b\xaa\xe8\xc9\x5f\x02\xad\xd5\x08\x24\x4c\x1a\xe5\xb8\x5e\x0f\xf6\x14\x7b\xc7\xdd\x5d\xc7\xa1\x7f\x7d\xb5\x06\x9a\x44\x55\x2b\x55\xca\xde\x10\x33\xef\xc7\xbc\xe7\x04\x8b\xcf\x7b\x2a\xc1\x03\x1b\xb2\x9e\x2a\x04\x41\x68\x08\x59\xaf\x4d\x43\x28\xe4\x18\x46\xed\x08\x1b\x19\x6c\xa5\x03\x8b\xc5\x97\xac\xd8\x7c\xc5\x60\x2b\x72\x10\x4b\x10\x87\x4e\x1c\xa9\x [...]
},
+ "/rbac/operator-role-binding-servicemonitors.yaml": &vfsgen۰CompressedFileInfo{
+ name: "operator-role-binding-servicemonitors.yaml",
+ modTime: time.Time{},
+ uncompressedSize: 1237,
+
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x4f\x85\x7b\x52\x36\xeb\x56\x68\x60\x03\x96\xd3\x20\x47\x9a\x1a\x4b\x53\x4b\x1c\x75\x48\xad\xe2\xfe\xfa\x82\xb2\xdd\xdd\xa0\x68\x81\x02\xe1\xcd\xf0\xcc\xfb\x98\xf7\x94\x61\xf9\xed\x9e\xc9\xf0\x81\x1d\xf9\x40\x35\xa2\x20\xb6\x84\x62\xb0\xae\x25\x54\x72\x8a\x93\x55\xc2\x46\x46\x5f\xdb\xc8\xe2\xf1\xa6\xa8\x36\x6f\x31\xfa\x9a\x14\xe2\x09\xa2\xe8\x45\xc9\x [...]
+ },
"/rbac/operator-role-binding-strimzi.yaml": &vfsgen۰CompressedFileInfo{
name: "operator-role-binding-strimzi.yaml",
modTime: time.Time{},
@@ -301,13 +301,6 @@ var assets = func() http.FileSystem {
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x53\xc1\x8e\xdb\x46\x0c\xbd\xeb\x2b\x1e\xac\x4b\x02\xac\xe5\xb6\xa7\xc2\x3d\xb9\xc9\x6e\x6b\x34\xb0\x81\x95\xd3\x20\x47\x7a\x44\x4b\xc4\x8e\x86\xea\xcc\x68\x95\xed\xd7\x17\x33\xb6\x13\x6f\xdd\x6d\x2e\x01\xa2\x8b\x68\xf2\x89\x7c\x8f\x8f\x2e\x31\xff\x76\x4f\x51\xe2\x9d\x18\x76\x81\x1b\x44\x45\xec\x18\xab\x81\x4c\xc7\xa8\xf5\x10\x27\xf2\x8c\x3b\x1d\x5d\x43\x51\xd4\xe1\xd5\xaa\xbe\x7b\x8d\xd1\x35\xec\xa1\x8e\xa1\x1e\x [...]
},
- "/rbac/operator-role-podmonitors.yaml": &vfsgen۰CompressedFileInfo{
- name: "operator-role-podmonitors.yaml",
- modTime: time.Time{},
- uncompressedSize: 1242,
-
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x4f\x85\x7b\x72\x37\xbb\xad\xd0\xc0\x06\x56\x4e\x83\x1c\x69\x6a\x2c\x0d\x96\xe2\xb0\x43\x6a\x95\xed\xaf\x2f\x24\xcb\xcd\x1a\xb9\x86\x17\x8f\xc9\xe1\xfb\xe0\x1b\x15\x58\xff\xb8\x65\x0a\x7c\x64\x47\x21\x51\x83\x2c\xc8\x1d\x61\x17\xad\xeb\x08\xb5\x9c\xf3\x68\x95\xf0\x28\x43\x68\x6c\x66\x09\x78\xb7\xab\x1f\xdf\x63\x08\x0d\x29\x24\x10\x44\xd1\x8b\x92\x29\x [...]
- },
"/rbac/operator-role-service-binding.yaml": &vfsgen۰CompressedFileInfo{
name: "operator-role-service-binding.yaml",
modTime: time.Time{},
@@ -315,6 +308,13 @@ var assets = func() http.FileSystem {
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x6e\xdc\x36\x10\xbd\xf3\x2b\x1e\x56\x97\x04\xb0\xe4\xb6\xa7\x62\x7b\xda\x3a\x76\x2b\x34\xd8\x05\xac\x4d\x83\x1c\xb9\xd4\xac\x34\x30\xc5\x51\x87\x94\x15\xf7\xeb\x0b\x6a\xb5\x89\x8d\x5e\xa3\x0b\x47\xe4\xcc\x9b\xf7\xf8\x86\x05\xca\x1f\xf7\x99\x02\x1f\xd9\x51\x88\xd4\x22\x09\x52\x4f\xd8\x8d\xd6\xf5\x84\x46\xce\x69\xb6\x4a\x78\x90\x29\xb4\x36\xb1\x04\xbc\xdb\x35\x0f\xef\x31\x85\x96\x14\x12\x08\xa2\x18\x44\xc9\x [...]
},
+ "/rbac/operator-role-servicemonitors.yaml": &vfsgen۰CompressedFileInfo{
+ name: "operator-role-servicemonitors.yaml",
+ modTime: time.Time{},
+ uncompressedSize: 1250,
+
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x8e\xdb\x36\x10\xbd\xf3\x2b\x1e\xac\x4b\x02\xac\xe5\xb6\xa7\xc2\x3d\xb9\x9b\xdd\x56\x68\x60\x03\x2b\xa7\x41\x8e\x34\x35\x96\x06\x4b\x71\xd4\x21\xb5\x8a\xfb\xf5\x85\x68\xb9\xd9\x45\xae\xe1\xc5\x63\x72\x66\xde\x7b\xf3\x46\x05\xd6\x3f\xee\x98\x02\x1f\xd9\x51\x88\xd4\x20\x09\x52\x47\xd8\x0d\xd6\x75\x84\x5a\xce\x69\xb2\x4a\x78\x94\x31\x34\x36\xb1\x04\xbc\xdb\xd5\x8f\xef\x31\x86\x86\x14\x12\x08\xa2\xe8\x45\xc9\x [...]
+ },
"/rbac/operator-role-strimzi.yaml": &vfsgen۰CompressedFileInfo{
name: "operator-role-strimzi.yaml",
modTime: time.Time{},
@@ -467,9 +467,9 @@ var assets = func() http.FileSystem {
"/traits.yaml": &vfsgen۰CompressedFileInfo{
name: "traits.yaml",
modTime: time.Time{},
- uncompressedSize: 36744,
+ uncompressedSize: 37171,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6d\x73\x1c\xb7\xd1\xe0\x77\xfd\x0a\x14\x9f\xab\xe2\x4b\xed\x0e\x29\xa7\x9c\xf8\xf6\x4e\x97\xa2\x25\x25\xa1\x6d\x49\x3c\x51\x71\xea\x4a\xa7\xca\x62\x67\x7a\x77\x21\x62\x80\x09\x80\x59\x6a\x73\x75\xff\xfd\x0a\xdd\x00\x06\x33\x3b\x24\x97\xb2\xe9\x32\xaf\x9e\xe4\x83\x45\x72\xa6\xd1\x68\x34\xfa\xbd\x7b\x9c\xe1\xc2\xd9\xd9\xb3\x29\x53\xbc\x86\x19\xe3\xcb\xa5\x50\xc2\x6d\x9f\x31\xd6\x48\xee\x96\xda\xd4\x33\xb6\xe4\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xed\x72\x1c\xb7\x11\xe0\x7f\x3d\x05\x8a\xb9\x2a\x7e\xd4\xee\x90\x72\xca\xb1\xb3\x77\xba\x14\x2d\x29\x09\x6d\x4b\xe2\x89\x8a\x53\x57\x3a\x57\x16\x3b\xd3\xbb\x0b\x11\x03\x4c\x00\x0c\xa9\xcd\xd5\xbd\xfb\x15\xba\x01\x0c\x66\x77\xb8\x1c\xca\xa6\xcb\xbc\xba\xe4\x87\x45\x72\xa6\xd1\x68\x34\xfa\xbb\x7b\x9c\xe1\xc2\xd9\xd9\xb3\x29\x53\xbc\x86\x19\xe3\xcb\xa5\x50\xc2\x6d\x9e\x31\xd6\x48\xee\x96\xda\xd4\x33\xb6\xe4\xd2\x [...]
},
}
fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
@@ -524,8 +524,8 @@ var assets = func() http.FileSystem {
fs["/rbac/operator-role-binding-knative.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding-leases.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding-openshift.yaml"].(os.FileInfo),
- fs["/rbac/operator-role-binding-podmonitors.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding-service-binding.yaml"].(os.FileInfo),
+ fs["/rbac/operator-role-binding-servicemonitors.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding-strimzi.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding.yaml"].(os.FileInfo),
fs["/rbac/operator-role-events.yaml"].(os.FileInfo),
@@ -533,8 +533,8 @@ var assets = func() http.FileSystem {
fs["/rbac/operator-role-kubernetes.yaml"].(os.FileInfo),
fs["/rbac/operator-role-leases.yaml"].(os.FileInfo),
fs["/rbac/operator-role-openshift.yaml"].(os.FileInfo),
- fs["/rbac/operator-role-podmonitors.yaml"].(os.FileInfo),
fs["/rbac/operator-role-service-binding.yaml"].(os.FileInfo),
+ fs["/rbac/operator-role-servicemonitors.yaml"].(os.FileInfo),
fs["/rbac/operator-role-strimzi.yaml"].(os.FileInfo),
fs["/rbac/user-cluster-role.yaml"].(os.FileInfo),
fs["/rbac/user-global-kamelet-viewer-role-binding.yaml"].(os.FileInfo),
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index 7945372..c2aee73 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -68,7 +68,7 @@ func (t *errorHandlerTrait) Apply(e *Environment) error {
}
func addErrorHandlerAsSource(e *Environment) error {
- errorHandlerStatement, err := parseErrorHandler(e.Integration.Spec.ErrorHandler)
+ errorHandlerStatement, err := parseErrorHandler(e)
if err != nil {
return err
}
@@ -91,21 +91,22 @@ func addErrorHandlerAsSource(e *Environment) error {
Type: v1.SourceTypeErrorHandler,
}
- replaced := false
- for idx, existing := range e.Integration.Status.GeneratedSources {
- if existing.Name == errorHandlerSource.Name {
- replaced = true
- e.Integration.Status.GeneratedSources[idx] = errorHandlerSource
- }
- }
- if !replaced {
- e.Integration.Status.GeneratedSources = append(e.Integration.Status.GeneratedSources, errorHandlerSource)
- }
+ e.Integration.Status.AddOrReplaceGeneratedSources(errorHandlerSource)
return nil
}
-func parseErrorHandler(errorHandlerSpec v1.ErrorHandlerSpec) (string, error) {
+func addErrorHandlerBeanConfiguration(e *Environment, fqn string) error {
+ // camel.beans.defaultErrorHandler = #class:the-full-qualified-class-name
+ e.Integration.Status.AddConfigurationsIfMissing(v1.ConfigurationSpec{
+ Type: "property",
+ Value: fmt.Sprintf("camel.beans.defaultErrorHandler=#class:%s", fqn),
+ })
+ return nil
+}
+
+func parseErrorHandler(e *Environment) (string, error) {
+ errorHandlerSpec := e.Integration.Spec.ErrorHandler
switch errorHandlerSpec.Type {
case "none":
return `errorHandler(noErrorHandler());`, nil
@@ -126,6 +127,10 @@ func parseErrorHandler(errorHandlerSpec v1.ErrorHandlerSpec) (string, error) {
case "ref":
// TODO using URI temporarily, fix it properly
return fmt.Sprintf(`errorHandler("%v");`, errorHandlerSpec.URI), nil
+ case "bean":
+ // TODO using URI temporarily, fix it properly
+ addErrorHandlerBeanConfiguration(e, errorHandlerSpec.URI)
+ return fmt.Sprintf(`errorHandler("%v");`, "defaultErrorHandler"), nil
}
return "", fmt.Errorf("Cannot recognize any error handler of type %s", errorHandlerSpec.Type)
[camel-k] 06/30: doc(example): error handling kamelet binding
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 924378e018a7b458754a8f18e9a9484d39cb4007
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 13 14:22:32 2021 +0200
doc(example): error handling kamelet binding
---
...ror-handler.yaml => error-handler.kamelet.yaml} | 38 ++++++++-------
.../kamelets/error-handler/error-sink.kamelet.yaml | 44 -----------------
...ler.yaml => incremental-id-source.kamelet.yaml} | 47 +++++++++++-------
.../kamelet-binding-error-handler.yaml | 17 ++++---
...ng-error-handler.yaml => log-sink.kamelet.yaml} | 30 +++++-------
examples/kamelets/error-handler/readme.md | 57 ++++++++++++++--------
.../error-handler/timer-source.kamelet.yaml | 54 --------------------
7 files changed, 107 insertions(+), 180 deletions(-)
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/error-handler.kamelet.yaml
similarity index 56%
copy from examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
copy to examples/kamelets/error-handler/error-handler.kamelet.yaml
index d731d1f..dbfc4bb 100644
--- a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
+++ b/examples/kamelets/error-handler/error-handler.kamelet.yaml
@@ -16,23 +16,25 @@
# ---------------------------------------------------------------------------
apiVersion: camel.apache.org/v1alpha1
-kind: KameletBinding
+kind: Kamelet
metadata:
- name: http-error-source
+ name: error-handler
spec:
- source:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: timer-source
- properties:
- message: "Hello world!"
- sink:
- uri: https://log-source/failing-service
- errorHandler:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: error-sink
- properties:
- defaultMessage: "ERROR ERROR!"
+ sources:
+ - content: |
+ import org.apache.camel.builder.RouteBuilder;
+ public class ErrorHandlerSource extends RouteBuilder {
+ @Override
+ public void configure() throws Exception {
+ errorHandler(deadLetterChannel("log:error?showCaughtException=true&showException=true&showHeaders=true"));
+ }
+ }
+ name: ErrorHandlerSource.java
+ definition:
+ title: "Error Handler Log DLC"
+ description: "Dead letter channel"
+# We can use the below once this is fixed https://issues.apache.org/jira/browse/CAMEL-16486
+# flow:
+# error-handler:
+# dead-letter-channel:
+# dead-letter-uri: log:error-sink?showCaughtException=true&showException=true&showHeaders=true
diff --git a/examples/kamelets/error-handler/error-sink.kamelet.yaml b/examples/kamelets/error-handler/error-sink.kamelet.yaml
deleted file mode 100644
index e35a54d..0000000
--- a/examples/kamelets/error-handler/error-sink.kamelet.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-# ---------------------------------------------------------------------------
-# 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.
-# ---------------------------------------------------------------------------
-
-apiVersion: camel.apache.org/v1alpha1
-kind: Kamelet
-metadata:
- name: error-sink
- annotations:
- camel.apache.org/kamelet.icon: "data:image/svg+xml;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAACcBJREFUeJzt3XmsHVUdwPHva21poWGTUpAiVRQSFjWAyi5LcCmKLCEouLwQccMgGsISEkQRXMIfSKMGhQSMCCibkRIgghQEF4RIQYtG4YFsraRlb6G+1j9+94a50/fmvuW+OTN3vp9kkrnnzj3zu+/N786ZmTNnQJIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZKkfjOQOoAKGQA+DJwAvBfYCpieNKKJexk4E/h56kDUH94O3AOs76NpHfDlXv6R1Ey7ACtIv0FP1XRa7/5Uapo5wL9JvxFP9fSNXv3Bmu [...]
- labels:
- camel.apache.org/kamelet.type: "sink"
-spec:
- definition:
- title: "Error Log Sink"
- description: "Consume events from a channel"
- required:
- - defaultMessage
- properties:
- defaultMessage:
- title: Message
- description: The default message to log
- type: string
- example: "error while checking the source"
- flow:
- from:
- uri: kamelet:source
- steps:
- - set-body:
- constant: "{{defaultMessage}}"
- - to: "log:error-sink"
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/incremental-id-source.kamelet.yaml
similarity index 55%
copy from examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
copy to examples/kamelets/error-handler/incremental-id-source.kamelet.yaml
index d731d1f..5e3181b 100644
--- a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
+++ b/examples/kamelets/error-handler/incremental-id-source.kamelet.yaml
@@ -16,23 +16,36 @@
# ---------------------------------------------------------------------------
apiVersion: camel.apache.org/v1alpha1
-kind: KameletBinding
+kind: Kamelet
metadata:
- name: http-error-source
+ name: incremental-id-source
+ labels:
+ camel.apache.org/kamelet.type: "source"
spec:
- source:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: timer-source
+ definition:
+ title: "Incremental ID Source"
+ description: "Produces periodic events with an incremental ID"
properties:
- message: "Hello world!"
- sink:
- uri: https://log-source/failing-service
- errorHandler:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: error-sink
- properties:
- defaultMessage: "ERROR ERROR!"
+ period:
+ title: Period
+ description: The interval between two events
+ type: integer
+ default: 1000
+ types:
+ out:
+ mediaType: text/plain
+ flow:
+ from:
+ uri: timer:tick
+ parameters:
+ period: "{{period}}"
+ steps:
+ - set-body:
+ simple: "Producing message #${exchangeProperty.CamelTimerCounter}"
+ - choice:
+ when:
+ - simple: "${bodyAs(String)} contains 0"
+ steps:
+ - set-body:
+ simple: "${mandatoryBodyAs(Boolean)}"
+ - to: "kamelet:sink"
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
index d731d1f..3602831 100644
--- a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
+++ b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
@@ -18,21 +18,22 @@
apiVersion: camel.apache.org/v1alpha1
kind: KameletBinding
metadata:
- name: http-error-source
+ name: kamelet-binding-error-handler
spec:
source:
ref:
kind: Kamelet
apiVersion: camel.apache.org/v1alpha1
- name: timer-source
- properties:
- message: "Hello world!"
+ name: incremental-id-source
sink:
- uri: https://log-source/failing-service
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1alpha1
+ name: log-sink
errorHandler:
ref:
kind: Kamelet
apiVersion: camel.apache.org/v1alpha1
- name: error-sink
- properties:
- defaultMessage: "ERROR ERROR!"
+ name: error-handler
+# uri: kamelet:error-handler
+
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/log-sink.kamelet.yaml
similarity index 70%
copy from examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
copy to examples/kamelets/error-handler/log-sink.kamelet.yaml
index d731d1f..aa11481 100644
--- a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
+++ b/examples/kamelets/error-handler/log-sink.kamelet.yaml
@@ -16,23 +16,17 @@
# ---------------------------------------------------------------------------
apiVersion: camel.apache.org/v1alpha1
-kind: KameletBinding
+kind: Kamelet
metadata:
- name: http-error-source
+ name: log-sink
+ labels:
+ camel.apache.org/kamelet.type: "sink"
spec:
- source:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: timer-source
- properties:
- message: "Hello world!"
- sink:
- uri: https://log-source/failing-service
- errorHandler:
- ref:
- kind: Kamelet
- apiVersion: camel.apache.org/v1alpha1
- name: error-sink
- properties:
- defaultMessage: "ERROR ERROR!"
+ definition:
+ title: "Regular Log Sink"
+ description: "Consume events from a channel"
+ flow:
+ from:
+ uri: kamelet:source
+ steps:
+ - to: "log:ok"
diff --git a/examples/kamelets/error-handler/readme.md b/examples/kamelets/error-handler/readme.md
index 5438050..5ff4777 100644
--- a/examples/kamelets/error-handler/readme.md
+++ b/examples/kamelets/error-handler/readme.md
@@ -1,49 +1,64 @@
# Kamelets Binding Error Handler example
-This example shows how to create a simple _timer-source_ `kamelet` bound to a failing sink in a `KameletBinding`. With the support of the `ErrorHandler` we will be able to redirect all errors to a `Dead Letter Channel` _error-sink_ `Kamelet`.
+This example shows how to create a simple _source_ `kamelet` bound to a log _sink_ in a `KameletBinding`. With the support of the `ErrorHandler` we will be able to redirect all errors to a `Dead Letter Channel` _error-handler_ `Kamelet`.
-## Timer Source Kamelet
-First of all, you must install the _timer-source_ Kamelet defined in `timer-source.kamelet.yaml` file:
+## Incremental ID Source Kamelet
+First of all, you must install the _incremental-id-source_ Kamelet defined in `incremental-id-source.kamelet.yaml` file. This source will emit events every second with an autoincrement counter that will be forced to fail when the number 0 is caught. With this trick, we will simulate possible event faults.
```
-$ kubectl apply -f timer-source.kamelet.yaml
+$ kubectl apply -f incremental-id-source.kamelet.yaml
```
You can check the newly created `kamelet` checking the list of kamelets available:
```
$ kubectl get kamelets
-NAME PHASE
-timer-source Ready
+NAME PHASE
+incremental-id-source Ready
```
-## Error Sink Kamelet
-Now it's the turn of installing the _error-sink_ Kamelet defined in `error-sink.kamelet.yaml` file:
+## Log Sink Kamelet
+Now it's the turn of installing the log-sink_ Kamelet defined in `log-sink.kamelet.yaml` file:
```
-$ kubectl apply -f error-sink.kamelet.yaml
+$ kubectl apply -f log-sink.kamelet.yaml
```
You can check the newly created `kamelet` checking the list of kamelets available:
```
$ kubectl get kamelets
-NAME PHASE
-error-sink Ready
-timer-source Ready
+NAME PHASE
+log-sink Ready
+incremental-id-source Ready
+```
+## Error handler Kamelet
+We finally install an error handler as a dead letter channel as specified in `error-handler.kamelet.yaml` file. You can specify any kind of error handler as expected by Apache Camel runtime.
+```
+$ kubectl apply -f error-handler.kamelet.yaml
+```
+You can check the newly created `kamelet` checking the list of kamelets available:
+```
+$ kubectl get kamelets
+
+NAME PHASE
+error-handler Ready
+log-sink Ready
+incremental-id-source Ready
```
## Error Handler Kamelet Binding
-We can create a `KameletBinding` which is triggered by the _timer-source_ `Kamelet` and define a fake sink URI in order to make it fail on purpose. Then we can configure an _errorHandler_ as defined in `kamelet-binding-error-handler.yaml` file:
+We can create a `KameletBinding` which is triggered by the _incremental-id-source_ `Kamelet` and log events to _log-sink_ `Kamelet`. As this will sporadically fail, we can configure an _errorHandler_ as defined in `kamelet-binding-error-handler.yaml` file:
```
+...
errorHandler:
ref:
kind: Kamelet
apiVersion: camel.apache.org/v1alpha1
- name: log-sink
- properties:
- defaultMessage: "ERROR ERROR!"
+ name: error-handler
```
Execute the following command to start the `Integration`:
```
kubectl apply -f kamelet-binding-error-handler.yaml
```
-As soon as the `Integration` starts, it will log a message error for every failure it will print:
+As soon as the `Integration` starts, it will log the events on the `ok` log channel and errors on the `error` log channel:
+```
+[1] 2021-04-13 10:33:38,375 INFO [ok] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #8]
+[1] 2021-04-13 10:33:39,376 INFO [ok] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #9]
+[1] 2021-04-13 10:33:40,409 INFO [error] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, Headers: {firedTime=Tue Apr 13 10:33:40 GMT 2021}, BodyType: String, Body: Producing message #10, CaughtExceptionType: org.apache.camel.CamelExecutionException, CaughtExceptionMessage: Exception occurred during execution on the exchange: Exchange[]]
+[1] 2021-04-13 10:33:41,375 INFO [ok] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Producing message #11]
```
-[1] 2021-03-16 15:11:33,099 INFO [error-sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: ERROR ERROR!]
-[1] 2021-03-16 15:11:33,988 INFO [error-sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: ERROR ERROR!]
-[1] 2021-03-16 15:11:34,988 INFO [error-sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: ERROR ERROR!]
-```
\ No newline at end of file
+This example is useful to guide you through the configuration of an error handler. In a production environment you will likely configure the error handler with a `Dead Letter Channel` pointing to a persistent queue.
\ No newline at end of file
diff --git a/examples/kamelets/error-handler/timer-source.kamelet.yaml b/examples/kamelets/error-handler/timer-source.kamelet.yaml
deleted file mode 100644
index f837fb5..0000000
--- a/examples/kamelets/error-handler/timer-source.kamelet.yaml
+++ /dev/null
@@ -1,54 +0,0 @@
-# ---------------------------------------------------------------------------
-# 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.
-# ---------------------------------------------------------------------------
-
-apiVersion: camel.apache.org/v1alpha1
-kind: Kamelet
-metadata:
- name: timer-source
- annotations:
- camel.apache.org/kamelet.icon: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gU3ZnIFZlY3RvciBJY29ucyA6IGh0dHA6Ly93d3cub25saW5ld2ViZm9udHMuY29tL2ljb24gLS0+DQo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm [...]
- labels:
- camel.apache.org/kamelet.type: "source"
-spec:
- definition:
- title: "Timer Source"
- description: "Produces periodic events with a custom payload"
- required:
- - message
- properties:
- period:
- title: Period
- description: The interval between two events
- type: integer
- default: 1000
- message:
- title: Message
- description: The message to generate
- type: string
- example: "hello world"
- types:
- out:
- mediaType: text/plain
- flow:
- from:
- uri: timer:tick
- parameters:
- period: "{{period}}"
- steps:
- - set-body:
- constant: "{{message}}"
- - to: "kamelet:sink"
[camel-k] 23/30: refactor(controller): error handler useless uri
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 2f621da116d86429e3a52c8748171919b68c5819
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 27 10:52:21 2021 +0200
refactor(controller): error handler useless uri
---
pkg/controller/kameletbinding/error_handler.go | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/pkg/controller/kameletbinding/error_handler.go b/pkg/controller/kameletbinding/error_handler.go
index 1d71683..5325324 100644
--- a/pkg/controller/kameletbinding/error_handler.go
+++ b/pkg/controller/kameletbinding/error_handler.go
@@ -41,9 +41,8 @@ func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandlerSpec, bindingContext bi
return nil, errors.Wrap(err, "could not determine error handler URI")
}
} else {
- // Create a new binding otherwise in order to store application properties
+ // Create a new binding otherwise in order to store error handler application properties
errorHandlerBinding = &bindings.Binding{
- URI: "error-handler",
ApplicationProperties: make(map[string]string),
}
}
[camel-k] 25/30: chore(crd): error handler generated crds
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 88d3706f0ffcce829ebaa07082824241526238fc
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 27 11:28:29 2021 +0200
chore(crd): error handler generated crds
---
config/crd/bases/camel.apache.org_integrations.yaml | 15 ---------------
config/crd/bases/camel.apache.org_kameletbindings.yaml | 15 ---------------
.../1.5.0-snapshot/camel.apache.org_kameletbindings.yaml | 5 +++++
helm/camel-k/crds/crd-integration.yaml | 15 ---------------
helm/camel-k/crds/crd-kamelet-binding.yaml | 15 ---------------
5 files changed, 5 insertions(+), 60 deletions(-)
diff --git a/config/crd/bases/camel.apache.org_integrations.yaml b/config/crd/bases/camel.apache.org_integrations.yaml
index 0b1b88a..96e26b9 100644
--- a/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/config/crd/bases/camel.apache.org_integrations.yaml
@@ -88,21 +88,6 @@ spec:
items:
type: string
type: array
- errorHandler:
- description: ErrorHandlerSpec respresents an integration error handler
- to be used as default at runtime
- properties:
- parameters:
- description: ErrorHandlerParameters is an unstructured object
- representing the configuration parameters available for an error
- handler
- type: object
- x-kubernetes-preserve-unknown-fields: true
- type:
- type: string
- uri:
- type: string
- type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
diff --git a/config/crd/bases/camel.apache.org_kameletbindings.yaml b/config/crd/bases/camel.apache.org_kameletbindings.yaml
index 2b78d2f..60ac3ba 100644
--- a/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -89,21 +89,6 @@ spec:
items:
type: string
type: array
- errorHandler:
- description: ErrorHandlerSpec respresents an integration error
- handler to be used as default at runtime
- properties:
- parameters:
- description: ErrorHandlerParameters is an unstructured object
- representing the configuration parameters available for
- an error handler
- type: object
- x-kubernetes-preserve-unknown-fields: true
- type:
- type: string
- uri:
- type: string
- type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
diff --git a/deploy/olm-catalog/camel-k-dev/1.5.0-snapshot/camel.apache.org_kameletbindings.yaml b/deploy/olm-catalog/camel-k-dev/1.5.0-snapshot/camel.apache.org_kameletbindings.yaml
index c9a8b87..60ac3ba 100644
--- a/deploy/olm-catalog/camel-k-dev/1.5.0-snapshot/camel.apache.org_kameletbindings.yaml
+++ b/deploy/olm-catalog/camel-k-dev/1.5.0-snapshot/camel.apache.org_kameletbindings.yaml
@@ -63,6 +63,11 @@ spec:
spec:
description: KameletBindingSpec --
properties:
+ errorHandler:
+ description: ErrorHandler is an optional handler called upon an error
+ occuring in the integration
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
integration:
description: Integration is an optional integration used to specify
custom parameters
diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml
index 0b1b88a..96e26b9 100644
--- a/helm/camel-k/crds/crd-integration.yaml
+++ b/helm/camel-k/crds/crd-integration.yaml
@@ -88,21 +88,6 @@ spec:
items:
type: string
type: array
- errorHandler:
- description: ErrorHandlerSpec respresents an integration error handler
- to be used as default at runtime
- properties:
- parameters:
- description: ErrorHandlerParameters is an unstructured object
- representing the configuration parameters available for an error
- handler
- type: object
- x-kubernetes-preserve-unknown-fields: true
- type:
- type: string
- uri:
- type: string
- type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml
index 2b78d2f..60ac3ba 100644
--- a/helm/camel-k/crds/crd-kamelet-binding.yaml
+++ b/helm/camel-k/crds/crd-kamelet-binding.yaml
@@ -89,21 +89,6 @@ spec:
items:
type: string
type: array
- errorHandler:
- description: ErrorHandlerSpec respresents an integration error
- handler to be used as default at runtime
- properties:
- parameters:
- description: ErrorHandlerParameters is an unstructured object
- representing the configuration parameters available for
- an error handler
- type: object
- x-kubernetes-preserve-unknown-fields: true
- type:
- type: string
- uri:
- type: string
- type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
[camel-k] 07/30: feat(trait): error handler trait
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 92873431e970b65a1dee3aff8fc8ebd5b07a8fd7
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 20 16:14:41 2021 +0200
feat(trait): error handler trait
* KameletBinding can specify the error handler type
* Introduced a trait to parse and create an error handler source type as expected by runtime.
---
pkg/apis/camel/v1alpha1/kamelet_binding_types.go | 20 ++-
pkg/controller/kameletbinding/common.go | 17 +--
pkg/resources/resources.go | 4 +-
pkg/trait/error_handler.go | 162 +++++++++++++++++++++++
pkg/trait/kamelets.go | 48 +++----
pkg/trait/trait_register.go | 1 +
pkg/trait/trait_test.go | 2 +-
7 files changed, 207 insertions(+), 47 deletions(-)
diff --git a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
index b91ed55..367692c 100644
--- a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
+++ b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
@@ -33,11 +33,25 @@ type KameletBindingSpec struct {
// Sink is the destination of the integration defined by this binding
Sink Endpoint `json:"sink,omitempty"`
// ErrorHandler is an optional handler called upon an error occuring in the integration
- ErrorHandler Endpoint `json:"errorHandler,omitempty"`
+ ErrorHandler ErrorHandler `json:"errorHandler,omitempty"`
// Steps contains an optional list of intermediate steps that are executed between the Source and the Sink
Steps []Endpoint `json:"steps,omitempty"`
}
+type ErrorHandler struct {
+ Endpoint Endpoint `json:"endpoint,omitempty"`
+ Type ErrorHandlerType `json:"type,omitempty"`
+ Configuration *ErrorHandlerProperties `json:"configuration,omitempty"`
+}
+
+type ErrorHandlerType string
+
+const (
+ ErrorHandlerTypeNone ErrorHandlerType = "no"
+ ErrorHandlerTypeDefault ErrorHandlerType = "default"
+ ErrorHandlerTypeDeadLetterChannel ErrorHandlerType = "dead-letter-channel"
+)
+
// Endpoint represents a source/sink external entity
type Endpoint struct {
// Ref can be used to declare a Kubernetes resource as source/sink endpoint
@@ -59,6 +73,10 @@ const (
EndpointTypeErrorHandler EndpointType = "errorHandler"
)
+type ErrorHandlerProperties struct {
+ v1.RawMessage `json:",inline"`
+}
+
// EndpointProperties is a key/value struct represented as JSON raw to allow numeric/boolean values
type EndpointProperties struct {
v1.RawMessage `json:",inline"`
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index fdeab95..a63780f 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -22,7 +22,6 @@ import (
"encoding/json"
"fmt"
"sort"
- "strings"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -81,8 +80,8 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
return nil, errors.Wrap(err, "could not determine sink URI")
}
var errorHandler *bindings.Binding
- if kameletbinding.Spec.ErrorHandler.Ref != nil || kameletbinding.Spec.ErrorHandler.URI != nil {
- errorHandler, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler)
+ if kameletbinding.Spec.ErrorHandler.Endpoint.Ref != nil || kameletbinding.Spec.ErrorHandler.Endpoint.URI != nil {
+ errorHandler, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler.Endpoint)
if err != nil {
return nil, errors.Wrap(err, "could not determine error handler URI")
}
@@ -160,20 +159,14 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
return &it, nil
}
-func setErrorHandlerKamelet(errorHandler *bindings.Binding, kameletSpec v1alpha1.Endpoint) error {
+func setErrorHandlerKamelet(errorHandler *bindings.Binding, errorHandlerSpec v1alpha1.ErrorHandler) error {
if errorHandler.ApplicationProperties == nil {
errorHandler.ApplicationProperties = make(map[string]string)
}
- if kameletSpec.URI != nil {
- if !strings.HasPrefix(*kameletSpec.URI, "kamelet") {
- return fmt.Errorf("Kamelet Binding only supports kamelet as error handler, provided: %s", *kameletSpec.URI)
- }
- errorHandler.ApplicationProperties["camel.k.default-error-handler"] = *kameletSpec.URI
- return nil
- }
+ errorHandler.ApplicationProperties["camel.k.default-error-handler.uri"] = errorHandler.URI
+ errorHandler.ApplicationProperties["camel.k.default-error-handler.type"] = string(errorHandlerSpec.Type)
- errorHandler.ApplicationProperties["camel.k.default-error-handler"] = kameletSpec.Ref.Name
return nil
}
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 6b712ac..7603bbb 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -113,9 +113,9 @@ var assets = func() http.FileSystem {
"/crd/bases/camel.apache.org_kameletbindings.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_kameletbindings.yaml",
modTime: time.Time{},
- uncompressedSize: 55181,
+ uncompressedSize: 68634,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xf1\x6f\xdb\x38\xf2\xef\xef\xf9\x2b\x06\xc9\x01\x6d\x01\x4b\x8e\xe3\xb4\xbb\xeb\xf7\x43\x91\x26\xdb\x7b\x7e\xed\xa6\x45\x92\xde\xe1\x5e\xdb\x03\x68\x69\x6c\xf3\x22\x91\x3a\x92\x8a\xe3\xef\xb6\xff\xfb\x17\x24\x25\x59\x76\x2c\x99\x72\xec\x6e\x0a\x88\xc0\x62\x6b\x8b\x1a\xce\x0c\x87\xc3\x99\x21\x3f\xce\x11\x78\xbb\x6b\x07\x47\xf0\x9e\x06\xc8\x24\x86\xa0\x38\xa8\x29\xc2\x59\x42\x82\x29\xc2\x35\x1f\xab\x19\x11\x08\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\xff\x6f\xdb\x38\xb2\xff\x3d\x7f\xc5\x20\x39\xa0\x2d\x10\xd9\x71\x92\x76\x77\xfd\x7e\x28\xb2\xc9\xf6\xce\xaf\xdd\x34\xc8\x97\x3b\xdc\x6b\x7b\x00\x2d\x8d\x6d\x5e\x24\x52\x47\x52\x71\xfc\xb6\xfd\xdf\x1f\x48\x4a\xb2\xfc\x45\x12\xe5\xd8\xdd\xf4\x41\x04\x8a\xc6\x16\x35\x9c\x19\x0e\x87\xdf\xe6\x33\x3e\x00\x6f\x7b\x65\xef\x00\x3e\x50\x1f\x99\xc4\x00\x14\x07\x35\x41\x38\x8b\x89\x3f\x41\xb8\xe1\x23\x35\x25\x02\xe1\x1d\x [...]
},
"/crd/bases/camel.apache.org_kamelets.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_kamelets.yaml",
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
new file mode 100644
index 0000000..7101d9e
--- /dev/null
+++ b/pkg/trait/error_handler.go
@@ -0,0 +1,162 @@
+/*
+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 trait
+
+import (
+ "fmt"
+ "strings"
+
+ v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+)
+
+// The error handler is a platform trait used to inject Error Handler source into the integration runtime.
+//
+// +camel-k:trait=error-handler
+type errorHandlerTrait struct {
+ BaseTrait `property:",squash"`
+ // Automatically inject all referenced Kamelets and their default configuration (enabled by default)
+ Auto *bool `property:"auto"`
+
+ // TODO move into a struct
+ ErrorHandlerURI string
+ ErrorHandlerType string
+}
+
+func newErrorHandlerTrait() Trait {
+ return &errorHandlerTrait{
+ BaseTrait: NewBaseTrait("errorHandler", 500),
+ }
+}
+
+// IsPlatformTrait overrides base class method
+func (t *errorHandlerTrait) IsPlatformTrait() bool {
+ return true
+}
+
+func (t *errorHandlerTrait) Configure(e *Environment) (bool, error) {
+ if t.Enabled != nil && !*t.Enabled {
+ return false, nil
+ }
+
+ if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization, v1.IntegrationPhaseDeploying, v1.IntegrationPhaseRunning) {
+ return false, nil
+ }
+
+ if t.Auto == nil || *t.Auto {
+ if t.ErrorHandlerType == "" {
+ t.ErrorHandlerType = maybeErrorHandler(e.Integration.Configurations())
+ if t.ErrorHandlerType != "" && v1alpha1.ErrorHandlerType(t.ErrorHandlerType) == v1alpha1.ErrorHandlerTypeDeadLetterChannel {
+ t.ErrorHandlerURI = maybeKameletAsDefaultErrorHandler(e.Integration.Configurations())
+ }
+ }
+ }
+
+ return t.ErrorHandlerType != "", nil
+}
+
+func maybeErrorHandler(properties []v1.ConfigurationSpec) string {
+ for _, property := range properties {
+ if strings.HasPrefix(property.Value, "camel.k.default-error-handler.type=") {
+ split := strings.Split(property.Value, "=")
+ if len(split) > 0 {
+ return split[1]
+ }
+ }
+ }
+
+ return ""
+}
+
+func maybeKameletAsDefaultErrorHandler(properties []v1.ConfigurationSpec) string {
+ for _, property := range properties {
+ if strings.HasPrefix(property.Value, "camel.k.default-error-handler.uri=") {
+ split := strings.Split(property.Value, "=")
+ if len(split) > 0 {
+ return split[1]
+ }
+ }
+ }
+
+ return ""
+}
+
+func (t *errorHandlerTrait) Apply(e *Environment) error {
+
+ if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
+ if t.ErrorHandlerType != "" {
+ // Possible error handler
+ err := addErrorHandlerAsSource(e, t.ErrorHandlerURI, t.ErrorHandlerType)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func addErrorHandlerAsSource(e *Environment, errorHandlerURI string, errorHandlerType string) error {
+ errorHandlerStatement, err := parseErrorHandler(errorHandlerURI, errorHandlerType)
+ if err != nil {
+ return err
+ }
+
+ // TODO change to yaml flow when we fix https://issues.apache.org/jira/browse/CAMEL-16486
+ errorHandlerSource := v1.SourceSpec{
+ DataSpec: v1.DataSpec{
+ Name: "ErrorHandlerSource.java",
+ Content: fmt.Sprintf(`
+ import org.apache.camel.builder.RouteBuilder;
+ public class ErrorHandlerSource extends RouteBuilder {
+ @Override
+ public void configure() throws Exception {
+ %s
+ }
+ }
+ `, errorHandlerStatement),
+ },
+ Language: v1.LanguageJavaSource,
+ Type: v1.SourceTypeErrorHandler,
+ }
+
+ replaced := false
+ for idx, existing := range e.Integration.Status.GeneratedSources {
+ if existing.Name == errorHandlerSource.Name {
+ replaced = true
+ e.Integration.Status.GeneratedSources[idx] = errorHandlerSource
+ }
+ }
+ if !replaced {
+ e.Integration.Status.GeneratedSources = append(e.Integration.Status.GeneratedSources, errorHandlerSource)
+ }
+
+ return nil
+}
+
+func parseErrorHandler(errHandlUri string, errHandlType string) (string, error) {
+ switch errHandlType {
+ case "no":
+ return `errorHandler(noErrorHandler());`, nil
+ case "default":
+ return `errorHandler(defaultErrorHandler());`, nil
+ case "dead-letter-channel":
+ return fmt.Sprintf(`errorHandler(deadLetterChannel("%v"));`, errHandlUri), nil
+ }
+
+ return "", fmt.Errorf("Cannot recognize any error handler of type %s", errHandlType)
+}
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index 053678d..dd4c3bb 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -47,8 +47,10 @@ type kameletsTrait struct {
Auto *bool `property:"auto"`
// Comma separated list of Kamelet names to load into the current integration
List string `property:"list"`
- // Kamelet name used as error handler
- ErrorHandler string `property:"error-handler"`
+
+ // TODO move into a struct
+ ErrorHandlerURI string
+ ErrorHandlerType string
}
type configurationKey struct {
@@ -96,8 +98,8 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
}
if t.Auto == nil || *t.Auto {
+ var kamelets []string
if t.List == "" {
- var kamelets []string
sources, err := kubernetes.ResolveIntegrationSources(e.C, e.Client, e.Integration, e.Resources)
if err != nil {
return false, err
@@ -108,34 +110,25 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
return true
})
sort.Strings(kamelets)
- t.List = strings.Join(kamelets, ",")
- }
- if t.ErrorHandler == "" {
- t.ErrorHandler = maybeKameletAsDefaultErrorHandler(e.Integration.Configurations())
}
- }
-
- return t.declareKamelets(), nil
-}
-
-func maybeKameletAsDefaultErrorHandler(properties []v1.ConfigurationSpec) string {
- for _, property := range properties {
- if strings.HasPrefix(property.Value, "camel.k.default-error-handler=") {
- split := strings.Split(property.Value, "=")
- if len(split) > 0 {
- if strings.HasPrefix(split[1], "kamelet:") {
- return extractKamelet(split[1])
+ if t.ErrorHandlerType == "" {
+ t.ErrorHandlerType = maybeErrorHandler(e.Integration.Configurations())
+ if t.ErrorHandlerType != "" && v1alpha1.ErrorHandlerType(t.ErrorHandlerType) == v1alpha1.ErrorHandlerTypeDeadLetterChannel {
+ t.ErrorHandlerURI = maybeKameletAsDefaultErrorHandler(e.Integration.Configurations())
+ if strings.HasPrefix(t.ErrorHandlerURI, "kamelet:") {
+ kamelets = append(kamelets, extractKamelet(t.ErrorHandlerURI))
}
- return split[1]
}
}
+
+ t.List = strings.Join(kamelets, ",")
}
- return ""
+ return t.declaredKamelets(), nil
}
-func (t *kameletsTrait) declareKamelets() bool {
- return len(t.getKameletKeys()) > 0 || t.ErrorHandler != ""
+func (t *kameletsTrait) declaredKamelets() bool {
+ return len(t.getKameletKeys()) > 0
}
func (t *kameletsTrait) Apply(e *Environment) error {
@@ -156,7 +149,7 @@ func (t *kameletsTrait) Apply(e *Environment) error {
}
func (t *kameletsTrait) addKamelets(e *Environment) error {
- if t.declareKamelets() {
+ if t.declaredKamelets() {
repo, err := repository.NewForPlatform(e.C, e.Client, e.Platform, e.Integration.Namespace, platform.GetOperatorNamespace())
if err != nil {
return err
@@ -169,13 +162,6 @@ func (t *kameletsTrait) addKamelets(e *Environment) error {
return err
}
}
- if t.ErrorHandler != "" {
- // Possible error handler
- err = initializeKamelet(repo, e, t.ErrorHandler, t, v1.SourceTypeErrorHandler)
- if err != nil {
- return err
- }
- }
// resort dependencies
sort.Strings(e.Integration.Status.Dependencies)
diff --git a/pkg/trait/trait_register.go b/pkg/trait/trait_register.go
index 4c06b37..30e89bd 100644
--- a/pkg/trait/trait_register.go
+++ b/pkg/trait/trait_register.go
@@ -26,6 +26,7 @@ func init() {
AddToTraits(newOpenAPITrait)
AddToTraits(newKnativeTrait)
AddToTraits(newKameletsTrait)
+ AddToTraits(newErrorHandlerTrait)
AddToTraits(newDependenciesTrait)
AddToTraits(newBuilderTrait)
AddToTraits(newQuarkusTrait)
diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go
index f8f75af..b8fdca8 100644
--- a/pkg/trait/trait_test.go
+++ b/pkg/trait/trait_test.go
@@ -507,7 +507,7 @@ func TestOnlySomeTraitsInfluenceBuild(t *testing.T) {
func TestOnlySomeTraitsArePlatform(t *testing.T) {
c := NewTraitTestCatalog()
- platformTraits := []string{"builder", "camel", "jvm", "container", "dependencies", "deployer", "deployment", "environment", "kamelets", "openapi", "owner", "platform", "quarkus"}
+ platformTraits := []string{"builder", "camel", "jvm", "container", "dependencies", "deployer", "deployment", "environment", "errorHandler", "kamelets", "openapi", "owner", "platform", "quarkus"}
for _, trait := range c.allTraits() {
if trait.IsPlatformTrait() {
[camel-k] 16/30: chore(controller): error handler unit test
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit d922c4a3d12a602772450bd836e2a60e65fee1a2
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Thu Apr 22 16:47:36 2021 +0200
chore(controller): error handler unit test
---
pkg/apis/camel/v1alpha1/error_handler_types.go | 7 +-
pkg/apis/camel/v1alpha1/kamelet_binding_types.go | 4 --
.../kameletbinding/error_handler_test.go | 77 ++++++++++++++++++++++
3 files changed, 83 insertions(+), 5 deletions(-)
diff --git a/pkg/apis/camel/v1alpha1/error_handler_types.go b/pkg/apis/camel/v1alpha1/error_handler_types.go
index a6b15b1..df46324 100644
--- a/pkg/apis/camel/v1alpha1/error_handler_types.go
+++ b/pkg/apis/camel/v1alpha1/error_handler_types.go
@@ -21,11 +21,16 @@ import (
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
)
-// ErrorHandler represent an unstructured object for an error handler
+// ErrorHandler represents an unstructured object for an error handler
type ErrorHandler struct {
v1.RawMessage `json:",omitempty"`
}
+// ErrorHandlerProperties represent an unstructured object for error handler parameters
+type ErrorHandlerProperties struct {
+ v1.RawMessage `json:",inline"`
+}
+
// AbstractErrorHandler is a generic interface that represent any type of error handler specification
type AbstractErrorHandler interface {
Type() ErrorHandlerType
diff --git a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
index 5a279e1..62e8079 100644
--- a/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
+++ b/pkg/apis/camel/v1alpha1/kamelet_binding_types.go
@@ -59,10 +59,6 @@ const (
EndpointTypeErrorHandler EndpointType = "errorHandler"
)
-type ErrorHandlerProperties struct {
- v1.RawMessage `json:",inline"`
-}
-
// EndpointProperties is a key/value struct represented as JSON raw to allow numeric/boolean values
type EndpointProperties struct {
v1.RawMessage `json:",inline"`
diff --git a/pkg/controller/kameletbinding/error_handler_test.go b/pkg/controller/kameletbinding/error_handler_test.go
new file mode 100644
index 0000000..1600707
--- /dev/null
+++ b/pkg/controller/kameletbinding/error_handler_test.go
@@ -0,0 +1,77 @@
+/*
+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 kameletbinding
+
+import (
+ "testing"
+
+ "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestParseErrorHandlerNoneDoesSucceed(t *testing.T) {
+ noErrorHandler, err := parseErrorHandler(
+ []byte(`{"none": null}`),
+ )
+ assert.Nil(t, err)
+ assert.Equal(t, v1alpha1.ErrorHandlerTypeNone, noErrorHandler.Type())
+}
+
+func TestParseErrorHandlerLogDoesSucceed(t *testing.T) {
+ logErrorHandler, err := parseErrorHandler(
+ []byte(`{"log": null}`),
+ )
+ assert.Nil(t, err)
+ assert.Equal(t, v1alpha1.ErrorHandlerTypeLog, logErrorHandler.Type())
+}
+
+func TestParseErrorHandlerLogWithParametersDoesSucceed(t *testing.T) {
+ logErrorHandler, err := parseErrorHandler(
+ []byte(`{"log": {"parameters": [{"param1": "value1"}, {"param2": "value2"}]}}`),
+ )
+ assert.Nil(t, err)
+ assert.Equal(t, v1alpha1.ErrorHandlerTypeLog, logErrorHandler.Type())
+ assert.NotNil(t, logErrorHandler.Params())
+}
+
+func TestParseErrorHandlerDLCDoesSucceed(t *testing.T) {
+ dlcErrorHandler, err := parseErrorHandler(
+ []byte(`{"dead-letter-channel": {"endpoint": {"uri": "someUri"}}}`),
+ )
+ assert.Nil(t, err)
+ assert.Equal(t, v1alpha1.ErrorHandlerTypeDeadLetterChannel, dlcErrorHandler.Type())
+ assert.Equal(t, "someUri", *dlcErrorHandler.Endpoint().URI)
+}
+
+func TestParseErrorHandlerDLCWithParametersDoesSucceed(t *testing.T) {
+ dlcErrorHandler, err := parseErrorHandler(
+ []byte(`{
+ "dead-letter-channel": {
+ "endpoint": {
+ "uri": "someUri"
+ },
+ "parameters":
+ [{"param1": "value1"}]
+ }
+ }`),
+ )
+ assert.Nil(t, err)
+ assert.Equal(t, v1alpha1.ErrorHandlerTypeDeadLetterChannel, dlcErrorHandler.Type())
+ assert.Equal(t, "someUri", *dlcErrorHandler.Endpoint().URI)
+ assert.NotNil(t, dlcErrorHandler.Params())
+}
[camel-k] 11/30: refactor(crd): updated crd after error-handler
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 5eaff76b0ecc0e2d41c90dbc6f26b203af3ab49e
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Apr 21 15:15:45 2021 +0200
refactor(crd): updated crd after error-handler
---
.../crd/bases/camel.apache.org_integrations.yaml | 13 +
.../bases/camel.apache.org_kameletbindings.yaml | 413 +++++++++++----------
.../1.4.0/camel.apache.org_integrations.yaml | 13 +
.../1.4.0/camel.apache.org_kameletbindings.yaml | 413 +++++++++++----------
helm/camel-k/crds/crd-integration.yaml | 13 +
helm/camel-k/crds/crd-kamelet-binding.yaml | 413 +++++++++++----------
6 files changed, 699 insertions(+), 579 deletions(-)
diff --git a/config/crd/bases/camel.apache.org_integrations.yaml b/config/crd/bases/camel.apache.org_integrations.yaml
index 96e26b9..c838f1f 100644
--- a/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/config/crd/bases/camel.apache.org_integrations.yaml
@@ -88,6 +88,19 @@ spec:
items:
type: string
type: array
+ errorHandler:
+ description: ErrorHandlerSpec respresents an integration error handler
+ to be used as default at runtime
+ properties:
+ configuration:
+ description: ErrorHandlerConfiguration --
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type:
+ type: string
+ uri:
+ type: string
+ type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
diff --git a/config/crd/bases/camel.apache.org_kameletbindings.yaml b/config/crd/bases/camel.apache.org_kameletbindings.yaml
index 7c43c55..046549c 100644
--- a/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -67,214 +67,228 @@ spec:
description: ErrorHandler is an optional handler called upon an error
occuring in the integration
properties:
- properties:
- description: Properties are a key value representation of endpoint
- properties
+ configuration:
type: object
x-kubernetes-preserve-unknown-fields: true
- ref:
- description: Ref can be used to declare a Kubernetes resource
- as source/sink endpoint
+ endpoint:
+ description: Endpoint represents a source/sink external entity
properties:
- apiVersion:
- description: API version of the referent.
- type: string
- fieldPath:
- description: 'If referring to a piece of an object instead
- of an entire object, this string should contain a valid
- JSON/Go field access statement, such as desiredState.manifest.containers[2].
- For example, if the object reference is to a container within
- a pod, this would take on a value like: "spec.containers{name}"
- (where "name" refers to the name of the container that triggered
- the event) or if no container name is specified "spec.containers[2]"
- (container with index 2 in this pod). This syntax is chosen
- only to have some well-defined way of referencing a part
- of an object. TODO: this design is not final and this field
- is subject to change in the future.'
- type: string
- kind:
- description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- name:
- description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
- type: string
- namespace:
- description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
- type: string
- resourceVersion:
- description: 'Specific resourceVersion to which this reference
- is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
- type: string
- uid:
- description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
- type: string
- type: object
- types:
- additionalProperties:
properties:
- mediaType:
- type: string
- schema:
- description: JSONSchemaProps is a JSON-Schema following
- Specification Draft 4 (http://json-schema.org/).
+ description: Properties are a key value representation of
+ endpoint properties
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ ref:
+ description: Ref can be used to declare a Kubernetes resource
+ as source/sink endpoint
+ properties:
+ apiVersion:
+ description: API version of the referent.
+ type: string
+ fieldPath:
+ description: 'If referring to a piece of an object instead
+ of an entire object, this string should contain a valid
+ JSON/Go field access statement, such as desiredState.manifest.containers[2].
+ For example, if the object reference is to a container
+ within a pod, this would take on a value like: "spec.containers{name}"
+ (where "name" refers to the name of the container that
+ triggered the event) or if no container name is specified
+ "spec.containers[2]" (container with index 2 in this
+ pod). This syntax is chosen only to have some well-defined
+ way of referencing a part of an object. TODO: this design
+ is not final and this field is subject to change in
+ the future.'
+ type: string
+ kind:
+ description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
+ type: string
+ namespace:
+ description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
+ type: string
+ resourceVersion:
+ description: 'Specific resourceVersion to which this reference
+ is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
+ type: string
+ uid:
+ description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
+ type: string
+ type: object
+ types:
+ additionalProperties:
properties:
- $schema:
- description: JSONSchemaURL represents a schema url.
+ mediaType:
type: string
- description:
- type: string
- example:
- description: 'JSON represents any valid JSON value.
- These types are supported: bool, int64, float64, string,
- []interface{}, map[string]interface{} and nil.'
- x-kubernetes-preserve-unknown-fields: true
- externalDocs:
- description: ExternalDocumentation allows referencing
- an external resource for extended documentation.
+ schema:
+ description: JSONSchemaProps is a JSON-Schema following
+ Specification Draft 4 (http://json-schema.org/).
properties:
+ $schema:
+ description: JSONSchemaURL represents a schema url.
+ type: string
description:
type: string
- url:
+ example:
+ description: 'JSON represents any valid JSON value.
+ These types are supported: bool, int64, float64,
+ string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ externalDocs:
+ description: ExternalDocumentation allows referencing
+ an external resource for extended documentation.
+ properties:
+ description:
+ type: string
+ url:
+ type: string
+ type: object
+ id:
type: string
- type: object
- id:
- type: string
- properties:
- additionalProperties:
properties:
- default:
- description: default is a default value for undefined
- object fields.
- x-kubernetes-preserve-unknown-fields: true
- description:
- type: string
- enum:
- items:
- description: 'JSON represents any valid JSON
- value. These types are supported: bool, int64,
- float64, string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- type: array
- example:
- description: 'JSON represents any valid JSON value.
- These types are supported: bool, int64, float64,
- string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- exclusiveMaximum:
- type: boolean
- exclusiveMinimum:
- type: boolean
- format:
- description: "format is an OpenAPI v3 format string.
- Unknown formats are ignored. The following formats
- are validated: \n - bsonobjectid: a bson object
- ID, i.e. a 24 characters hex string - uri: an
- URI as parsed by Golang net/url.ParseRequestURI
- - email: an email address as parsed by Golang
- net/mail.ParseAddress - hostname: a valid representation
- for an Internet host name, as defined by RFC
- 1034, section 3.1 [RFC1034]. - ipv4: an IPv4
- IP as parsed by Golang net.ParseIP - ipv6: an
- IPv6 IP as parsed by Golang net.ParseIP - cidr:
- a CIDR as parsed by Golang net.ParseCIDR - mac:
- a MAC address as parsed by Golang net.ParseMAC
- - uuid: an UUID that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid3: an UUID3 that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid4: an UUID4 that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - uuid5: an UUID5 that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - isbn: an ISBN10 or ISBN13 number string like
- \"0321751043\" or \"978-0321751041\" - isbn10:
- an ISBN10 number string like \"0321751043\"
- - isbn13: an ISBN13 number string like \"978-0321751041\"
- - creditcard: a credit card number defined by
- the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
- with any non digit characters mixed in - ssn:
- a U.S. social security number following the
- regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$ -
- hexcolor: an hexadecimal color code like \"#FFFFFF:
- following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
- - rgbcolor: an RGB color code like rgb like
- \"rgb(255,255,2559\" - byte: base64 encoded
- binary data - password: any kind of string -
- date: a date string like \"2006-01-02\" as defined
- by full-date in RFC3339 - duration: a duration
- string like \"22 ns\" as parsed by Golang time.ParseDuration
- or compatible with Scala duration format - datetime:
- a date time string like \"2014-12-15T19:30:20.000Z\"
- as defined by date-time in RFC3339."
- type: string
- id:
- type: string
- maxItems:
- format: int64
- type: integer
- maxLength:
- format: int64
- type: integer
- maxProperties:
- format: int64
- type: integer
- maximum:
- description: A Number represents a JSON number
- literal.
- type: string
- minItems:
- format: int64
- type: integer
- minLength:
- format: int64
- type: integer
- minProperties:
- format: int64
- type: integer
- minimum:
- description: A Number represents a JSON number
- literal.
- type: string
- multipleOf:
- description: A Number represents a JSON number
- literal.
- type: string
- nullable:
- type: boolean
- pattern:
- type: string
- title:
- type: string
- type:
+ additionalProperties:
+ properties:
+ default:
+ description: default is a default value for
+ undefined object fields.
+ x-kubernetes-preserve-unknown-fields: true
+ description:
+ type: string
+ enum:
+ items:
+ description: 'JSON represents any valid
+ JSON value. These types are supported:
+ bool, int64, float64, string, []interface{},
+ map[string]interface{} and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ type: array
+ example:
+ description: 'JSON represents any valid JSON
+ value. These types are supported: bool,
+ int64, float64, string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ exclusiveMaximum:
+ type: boolean
+ exclusiveMinimum:
+ type: boolean
+ format:
+ description: "format is an OpenAPI v3 format
+ string. Unknown formats are ignored. The
+ following formats are validated: \n - bsonobjectid:
+ a bson object ID, i.e. a 24 characters hex
+ string - uri: an URI as parsed by Golang
+ net/url.ParseRequestURI - email: an email
+ address as parsed by Golang net/mail.ParseAddress
+ - hostname: a valid representation for an
+ Internet host name, as defined by RFC 1034,
+ section 3.1 [RFC1034]. - ipv4: an IPv4 IP
+ as parsed by Golang net.ParseIP - ipv6:
+ an IPv6 IP as parsed by Golang net.ParseIP
+ - cidr: a CIDR as parsed by Golang net.ParseCIDR
+ - mac: a MAC address as parsed by Golang
+ net.ParseMAC - uuid: an UUID that allows
+ uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid3: an UUID3 that allows uppercase
+ defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid4: an UUID4 that allows uppercase
+ defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - uuid5: an UUID5 that allows uppercase
+ defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - isbn: an ISBN10 or ISBN13 number string
+ like \"0321751043\" or \"978-0321751041\"
+ - isbn10: an ISBN10 number string like \"0321751043\"
+ - isbn13: an ISBN13 number string like \"978-0321751041\"
+ - creditcard: a credit card number defined
+ by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
+ with any non digit characters mixed in -
+ ssn: a U.S. social security number following
+ the regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$
+ - hexcolor: an hexadecimal color code like
+ \"#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
+ - rgbcolor: an RGB color code like rgb like
+ \"rgb(255,255,2559\" - byte: base64 encoded
+ binary data - password: any kind of string
+ - date: a date string like \"2006-01-02\"
+ as defined by full-date in RFC3339 - duration:
+ a duration string like \"22 ns\" as parsed
+ by Golang time.ParseDuration or compatible
+ with Scala duration format - datetime: a
+ date time string like \"2014-12-15T19:30:20.000Z\"
+ as defined by date-time in RFC3339."
+ type: string
+ id:
+ type: string
+ maxItems:
+ format: int64
+ type: integer
+ maxLength:
+ format: int64
+ type: integer
+ maxProperties:
+ format: int64
+ type: integer
+ maximum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ minItems:
+ format: int64
+ type: integer
+ minLength:
+ format: int64
+ type: integer
+ minProperties:
+ format: int64
+ type: integer
+ minimum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ multipleOf:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ nullable:
+ type: boolean
+ pattern:
+ type: string
+ title:
+ type: string
+ type:
+ type: string
+ uniqueItems:
+ type: boolean
+ x-descriptors:
+ description: The list of descriptors that
+ determine which UI components to use on
+ different views
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ required:
+ items:
type: string
- uniqueItems:
- type: boolean
- x-descriptors:
- description: The list of descriptors that determine
- which UI components to use on different views
- items:
- type: string
- type: array
- type: object
+ type: array
+ title:
+ type: string
+ type:
+ type: string
type: object
- required:
- items:
- type: string
- type: array
- title:
- type: string
- type:
- type: string
type: object
- type: object
- description: Types defines the schema of the data produced/consumed
- by the endpoint
+ description: Types defines the schema of the data produced/consumed
+ by the endpoint
+ type: object
+ uri:
+ description: URI can alternatively be used to specify the
+ (Camel) endpoint explicitly
+ type: string
type: object
- uri:
- description: URI can alternatively be used to specify the (Camel)
- endpoint explicitly
+ type:
type: string
type: object
integration:
@@ -298,6 +312,19 @@ spec:
items:
type: string
type: array
+ errorHandler:
+ description: ErrorHandlerSpec respresents an integration error
+ handler to be used as default at runtime
+ properties:
+ configuration:
+ description: ErrorHandlerConfiguration --
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type:
+ type: string
+ uri:
+ type: string
+ type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
diff --git a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml
index 96e26b9..c838f1f 100644
--- a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml
+++ b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_integrations.yaml
@@ -88,6 +88,19 @@ spec:
items:
type: string
type: array
+ errorHandler:
+ description: ErrorHandlerSpec respresents an integration error handler
+ to be used as default at runtime
+ properties:
+ configuration:
+ description: ErrorHandlerConfiguration --
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type:
+ type: string
+ uri:
+ type: string
+ type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
diff --git a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml
index 7c43c55..046549c 100644
--- a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml
+++ b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml
@@ -67,214 +67,228 @@ spec:
description: ErrorHandler is an optional handler called upon an error
occuring in the integration
properties:
- properties:
- description: Properties are a key value representation of endpoint
- properties
+ configuration:
type: object
x-kubernetes-preserve-unknown-fields: true
- ref:
- description: Ref can be used to declare a Kubernetes resource
- as source/sink endpoint
+ endpoint:
+ description: Endpoint represents a source/sink external entity
properties:
- apiVersion:
- description: API version of the referent.
- type: string
- fieldPath:
- description: 'If referring to a piece of an object instead
- of an entire object, this string should contain a valid
- JSON/Go field access statement, such as desiredState.manifest.containers[2].
- For example, if the object reference is to a container within
- a pod, this would take on a value like: "spec.containers{name}"
- (where "name" refers to the name of the container that triggered
- the event) or if no container name is specified "spec.containers[2]"
- (container with index 2 in this pod). This syntax is chosen
- only to have some well-defined way of referencing a part
- of an object. TODO: this design is not final and this field
- is subject to change in the future.'
- type: string
- kind:
- description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- name:
- description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
- type: string
- namespace:
- description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
- type: string
- resourceVersion:
- description: 'Specific resourceVersion to which this reference
- is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
- type: string
- uid:
- description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
- type: string
- type: object
- types:
- additionalProperties:
properties:
- mediaType:
- type: string
- schema:
- description: JSONSchemaProps is a JSON-Schema following
- Specification Draft 4 (http://json-schema.org/).
+ description: Properties are a key value representation of
+ endpoint properties
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ ref:
+ description: Ref can be used to declare a Kubernetes resource
+ as source/sink endpoint
+ properties:
+ apiVersion:
+ description: API version of the referent.
+ type: string
+ fieldPath:
+ description: 'If referring to a piece of an object instead
+ of an entire object, this string should contain a valid
+ JSON/Go field access statement, such as desiredState.manifest.containers[2].
+ For example, if the object reference is to a container
+ within a pod, this would take on a value like: "spec.containers{name}"
+ (where "name" refers to the name of the container that
+ triggered the event) or if no container name is specified
+ "spec.containers[2]" (container with index 2 in this
+ pod). This syntax is chosen only to have some well-defined
+ way of referencing a part of an object. TODO: this design
+ is not final and this field is subject to change in
+ the future.'
+ type: string
+ kind:
+ description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
+ type: string
+ namespace:
+ description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
+ type: string
+ resourceVersion:
+ description: 'Specific resourceVersion to which this reference
+ is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
+ type: string
+ uid:
+ description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
+ type: string
+ type: object
+ types:
+ additionalProperties:
properties:
- $schema:
- description: JSONSchemaURL represents a schema url.
+ mediaType:
type: string
- description:
- type: string
- example:
- description: 'JSON represents any valid JSON value.
- These types are supported: bool, int64, float64, string,
- []interface{}, map[string]interface{} and nil.'
- x-kubernetes-preserve-unknown-fields: true
- externalDocs:
- description: ExternalDocumentation allows referencing
- an external resource for extended documentation.
+ schema:
+ description: JSONSchemaProps is a JSON-Schema following
+ Specification Draft 4 (http://json-schema.org/).
properties:
+ $schema:
+ description: JSONSchemaURL represents a schema url.
+ type: string
description:
type: string
- url:
+ example:
+ description: 'JSON represents any valid JSON value.
+ These types are supported: bool, int64, float64,
+ string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ externalDocs:
+ description: ExternalDocumentation allows referencing
+ an external resource for extended documentation.
+ properties:
+ description:
+ type: string
+ url:
+ type: string
+ type: object
+ id:
type: string
- type: object
- id:
- type: string
- properties:
- additionalProperties:
properties:
- default:
- description: default is a default value for undefined
- object fields.
- x-kubernetes-preserve-unknown-fields: true
- description:
- type: string
- enum:
- items:
- description: 'JSON represents any valid JSON
- value. These types are supported: bool, int64,
- float64, string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- type: array
- example:
- description: 'JSON represents any valid JSON value.
- These types are supported: bool, int64, float64,
- string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- exclusiveMaximum:
- type: boolean
- exclusiveMinimum:
- type: boolean
- format:
- description: "format is an OpenAPI v3 format string.
- Unknown formats are ignored. The following formats
- are validated: \n - bsonobjectid: a bson object
- ID, i.e. a 24 characters hex string - uri: an
- URI as parsed by Golang net/url.ParseRequestURI
- - email: an email address as parsed by Golang
- net/mail.ParseAddress - hostname: a valid representation
- for an Internet host name, as defined by RFC
- 1034, section 3.1 [RFC1034]. - ipv4: an IPv4
- IP as parsed by Golang net.ParseIP - ipv6: an
- IPv6 IP as parsed by Golang net.ParseIP - cidr:
- a CIDR as parsed by Golang net.ParseCIDR - mac:
- a MAC address as parsed by Golang net.ParseMAC
- - uuid: an UUID that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid3: an UUID3 that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid4: an UUID4 that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - uuid5: an UUID5 that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - isbn: an ISBN10 or ISBN13 number string like
- \"0321751043\" or \"978-0321751041\" - isbn10:
- an ISBN10 number string like \"0321751043\"
- - isbn13: an ISBN13 number string like \"978-0321751041\"
- - creditcard: a credit card number defined by
- the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
- with any non digit characters mixed in - ssn:
- a U.S. social security number following the
- regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$ -
- hexcolor: an hexadecimal color code like \"#FFFFFF:
- following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
- - rgbcolor: an RGB color code like rgb like
- \"rgb(255,255,2559\" - byte: base64 encoded
- binary data - password: any kind of string -
- date: a date string like \"2006-01-02\" as defined
- by full-date in RFC3339 - duration: a duration
- string like \"22 ns\" as parsed by Golang time.ParseDuration
- or compatible with Scala duration format - datetime:
- a date time string like \"2014-12-15T19:30:20.000Z\"
- as defined by date-time in RFC3339."
- type: string
- id:
- type: string
- maxItems:
- format: int64
- type: integer
- maxLength:
- format: int64
- type: integer
- maxProperties:
- format: int64
- type: integer
- maximum:
- description: A Number represents a JSON number
- literal.
- type: string
- minItems:
- format: int64
- type: integer
- minLength:
- format: int64
- type: integer
- minProperties:
- format: int64
- type: integer
- minimum:
- description: A Number represents a JSON number
- literal.
- type: string
- multipleOf:
- description: A Number represents a JSON number
- literal.
- type: string
- nullable:
- type: boolean
- pattern:
- type: string
- title:
- type: string
- type:
+ additionalProperties:
+ properties:
+ default:
+ description: default is a default value for
+ undefined object fields.
+ x-kubernetes-preserve-unknown-fields: true
+ description:
+ type: string
+ enum:
+ items:
+ description: 'JSON represents any valid
+ JSON value. These types are supported:
+ bool, int64, float64, string, []interface{},
+ map[string]interface{} and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ type: array
+ example:
+ description: 'JSON represents any valid JSON
+ value. These types are supported: bool,
+ int64, float64, string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ exclusiveMaximum:
+ type: boolean
+ exclusiveMinimum:
+ type: boolean
+ format:
+ description: "format is an OpenAPI v3 format
+ string. Unknown formats are ignored. The
+ following formats are validated: \n - bsonobjectid:
+ a bson object ID, i.e. a 24 characters hex
+ string - uri: an URI as parsed by Golang
+ net/url.ParseRequestURI - email: an email
+ address as parsed by Golang net/mail.ParseAddress
+ - hostname: a valid representation for an
+ Internet host name, as defined by RFC 1034,
+ section 3.1 [RFC1034]. - ipv4: an IPv4 IP
+ as parsed by Golang net.ParseIP - ipv6:
+ an IPv6 IP as parsed by Golang net.ParseIP
+ - cidr: a CIDR as parsed by Golang net.ParseCIDR
+ - mac: a MAC address as parsed by Golang
+ net.ParseMAC - uuid: an UUID that allows
+ uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid3: an UUID3 that allows uppercase
+ defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid4: an UUID4 that allows uppercase
+ defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - uuid5: an UUID5 that allows uppercase
+ defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - isbn: an ISBN10 or ISBN13 number string
+ like \"0321751043\" or \"978-0321751041\"
+ - isbn10: an ISBN10 number string like \"0321751043\"
+ - isbn13: an ISBN13 number string like \"978-0321751041\"
+ - creditcard: a credit card number defined
+ by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
+ with any non digit characters mixed in -
+ ssn: a U.S. social security number following
+ the regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$
+ - hexcolor: an hexadecimal color code like
+ \"#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
+ - rgbcolor: an RGB color code like rgb like
+ \"rgb(255,255,2559\" - byte: base64 encoded
+ binary data - password: any kind of string
+ - date: a date string like \"2006-01-02\"
+ as defined by full-date in RFC3339 - duration:
+ a duration string like \"22 ns\" as parsed
+ by Golang time.ParseDuration or compatible
+ with Scala duration format - datetime: a
+ date time string like \"2014-12-15T19:30:20.000Z\"
+ as defined by date-time in RFC3339."
+ type: string
+ id:
+ type: string
+ maxItems:
+ format: int64
+ type: integer
+ maxLength:
+ format: int64
+ type: integer
+ maxProperties:
+ format: int64
+ type: integer
+ maximum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ minItems:
+ format: int64
+ type: integer
+ minLength:
+ format: int64
+ type: integer
+ minProperties:
+ format: int64
+ type: integer
+ minimum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ multipleOf:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ nullable:
+ type: boolean
+ pattern:
+ type: string
+ title:
+ type: string
+ type:
+ type: string
+ uniqueItems:
+ type: boolean
+ x-descriptors:
+ description: The list of descriptors that
+ determine which UI components to use on
+ different views
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ required:
+ items:
type: string
- uniqueItems:
- type: boolean
- x-descriptors:
- description: The list of descriptors that determine
- which UI components to use on different views
- items:
- type: string
- type: array
- type: object
+ type: array
+ title:
+ type: string
+ type:
+ type: string
type: object
- required:
- items:
- type: string
- type: array
- title:
- type: string
- type:
- type: string
type: object
- type: object
- description: Types defines the schema of the data produced/consumed
- by the endpoint
+ description: Types defines the schema of the data produced/consumed
+ by the endpoint
+ type: object
+ uri:
+ description: URI can alternatively be used to specify the
+ (Camel) endpoint explicitly
+ type: string
type: object
- uri:
- description: URI can alternatively be used to specify the (Camel)
- endpoint explicitly
+ type:
type: string
type: object
integration:
@@ -298,6 +312,19 @@ spec:
items:
type: string
type: array
+ errorHandler:
+ description: ErrorHandlerSpec respresents an integration error
+ handler to be used as default at runtime
+ properties:
+ configuration:
+ description: ErrorHandlerConfiguration --
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type:
+ type: string
+ uri:
+ type: string
+ type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml
index 96e26b9..c838f1f 100644
--- a/helm/camel-k/crds/crd-integration.yaml
+++ b/helm/camel-k/crds/crd-integration.yaml
@@ -88,6 +88,19 @@ spec:
items:
type: string
type: array
+ errorHandler:
+ description: ErrorHandlerSpec respresents an integration error handler
+ to be used as default at runtime
+ properties:
+ configuration:
+ description: ErrorHandlerConfiguration --
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type:
+ type: string
+ uri:
+ type: string
+ type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml
index 7c43c55..046549c 100644
--- a/helm/camel-k/crds/crd-kamelet-binding.yaml
+++ b/helm/camel-k/crds/crd-kamelet-binding.yaml
@@ -67,214 +67,228 @@ spec:
description: ErrorHandler is an optional handler called upon an error
occuring in the integration
properties:
- properties:
- description: Properties are a key value representation of endpoint
- properties
+ configuration:
type: object
x-kubernetes-preserve-unknown-fields: true
- ref:
- description: Ref can be used to declare a Kubernetes resource
- as source/sink endpoint
+ endpoint:
+ description: Endpoint represents a source/sink external entity
properties:
- apiVersion:
- description: API version of the referent.
- type: string
- fieldPath:
- description: 'If referring to a piece of an object instead
- of an entire object, this string should contain a valid
- JSON/Go field access statement, such as desiredState.manifest.containers[2].
- For example, if the object reference is to a container within
- a pod, this would take on a value like: "spec.containers{name}"
- (where "name" refers to the name of the container that triggered
- the event) or if no container name is specified "spec.containers[2]"
- (container with index 2 in this pod). This syntax is chosen
- only to have some well-defined way of referencing a part
- of an object. TODO: this design is not final and this field
- is subject to change in the future.'
- type: string
- kind:
- description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- name:
- description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
- type: string
- namespace:
- description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
- type: string
- resourceVersion:
- description: 'Specific resourceVersion to which this reference
- is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
- type: string
- uid:
- description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
- type: string
- type: object
- types:
- additionalProperties:
properties:
- mediaType:
- type: string
- schema:
- description: JSONSchemaProps is a JSON-Schema following
- Specification Draft 4 (http://json-schema.org/).
+ description: Properties are a key value representation of
+ endpoint properties
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ ref:
+ description: Ref can be used to declare a Kubernetes resource
+ as source/sink endpoint
+ properties:
+ apiVersion:
+ description: API version of the referent.
+ type: string
+ fieldPath:
+ description: 'If referring to a piece of an object instead
+ of an entire object, this string should contain a valid
+ JSON/Go field access statement, such as desiredState.manifest.containers[2].
+ For example, if the object reference is to a container
+ within a pod, this would take on a value like: "spec.containers{name}"
+ (where "name" refers to the name of the container that
+ triggered the event) or if no container name is specified
+ "spec.containers[2]" (container with index 2 in this
+ pod). This syntax is chosen only to have some well-defined
+ way of referencing a part of an object. TODO: this design
+ is not final and this field is subject to change in
+ the future.'
+ type: string
+ kind:
+ description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
+ type: string
+ namespace:
+ description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
+ type: string
+ resourceVersion:
+ description: 'Specific resourceVersion to which this reference
+ is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
+ type: string
+ uid:
+ description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
+ type: string
+ type: object
+ types:
+ additionalProperties:
properties:
- $schema:
- description: JSONSchemaURL represents a schema url.
+ mediaType:
type: string
- description:
- type: string
- example:
- description: 'JSON represents any valid JSON value.
- These types are supported: bool, int64, float64, string,
- []interface{}, map[string]interface{} and nil.'
- x-kubernetes-preserve-unknown-fields: true
- externalDocs:
- description: ExternalDocumentation allows referencing
- an external resource for extended documentation.
+ schema:
+ description: JSONSchemaProps is a JSON-Schema following
+ Specification Draft 4 (http://json-schema.org/).
properties:
+ $schema:
+ description: JSONSchemaURL represents a schema url.
+ type: string
description:
type: string
- url:
+ example:
+ description: 'JSON represents any valid JSON value.
+ These types are supported: bool, int64, float64,
+ string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ externalDocs:
+ description: ExternalDocumentation allows referencing
+ an external resource for extended documentation.
+ properties:
+ description:
+ type: string
+ url:
+ type: string
+ type: object
+ id:
type: string
- type: object
- id:
- type: string
- properties:
- additionalProperties:
properties:
- default:
- description: default is a default value for undefined
- object fields.
- x-kubernetes-preserve-unknown-fields: true
- description:
- type: string
- enum:
- items:
- description: 'JSON represents any valid JSON
- value. These types are supported: bool, int64,
- float64, string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- type: array
- example:
- description: 'JSON represents any valid JSON value.
- These types are supported: bool, int64, float64,
- string, []interface{}, map[string]interface{}
- and nil.'
- x-kubernetes-preserve-unknown-fields: true
- exclusiveMaximum:
- type: boolean
- exclusiveMinimum:
- type: boolean
- format:
- description: "format is an OpenAPI v3 format string.
- Unknown formats are ignored. The following formats
- are validated: \n - bsonobjectid: a bson object
- ID, i.e. a 24 characters hex string - uri: an
- URI as parsed by Golang net/url.ParseRequestURI
- - email: an email address as parsed by Golang
- net/mail.ParseAddress - hostname: a valid representation
- for an Internet host name, as defined by RFC
- 1034, section 3.1 [RFC1034]. - ipv4: an IPv4
- IP as parsed by Golang net.ParseIP - ipv6: an
- IPv6 IP as parsed by Golang net.ParseIP - cidr:
- a CIDR as parsed by Golang net.ParseCIDR - mac:
- a MAC address as parsed by Golang net.ParseMAC
- - uuid: an UUID that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid3: an UUID3 that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
- - uuid4: an UUID4 that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - uuid5: an UUID5 that allows uppercase defined
- by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
- - isbn: an ISBN10 or ISBN13 number string like
- \"0321751043\" or \"978-0321751041\" - isbn10:
- an ISBN10 number string like \"0321751043\"
- - isbn13: an ISBN13 number string like \"978-0321751041\"
- - creditcard: a credit card number defined by
- the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
- with any non digit characters mixed in - ssn:
- a U.S. social security number following the
- regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$ -
- hexcolor: an hexadecimal color code like \"#FFFFFF:
- following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
- - rgbcolor: an RGB color code like rgb like
- \"rgb(255,255,2559\" - byte: base64 encoded
- binary data - password: any kind of string -
- date: a date string like \"2006-01-02\" as defined
- by full-date in RFC3339 - duration: a duration
- string like \"22 ns\" as parsed by Golang time.ParseDuration
- or compatible with Scala duration format - datetime:
- a date time string like \"2014-12-15T19:30:20.000Z\"
- as defined by date-time in RFC3339."
- type: string
- id:
- type: string
- maxItems:
- format: int64
- type: integer
- maxLength:
- format: int64
- type: integer
- maxProperties:
- format: int64
- type: integer
- maximum:
- description: A Number represents a JSON number
- literal.
- type: string
- minItems:
- format: int64
- type: integer
- minLength:
- format: int64
- type: integer
- minProperties:
- format: int64
- type: integer
- minimum:
- description: A Number represents a JSON number
- literal.
- type: string
- multipleOf:
- description: A Number represents a JSON number
- literal.
- type: string
- nullable:
- type: boolean
- pattern:
- type: string
- title:
- type: string
- type:
+ additionalProperties:
+ properties:
+ default:
+ description: default is a default value for
+ undefined object fields.
+ x-kubernetes-preserve-unknown-fields: true
+ description:
+ type: string
+ enum:
+ items:
+ description: 'JSON represents any valid
+ JSON value. These types are supported:
+ bool, int64, float64, string, []interface{},
+ map[string]interface{} and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ type: array
+ example:
+ description: 'JSON represents any valid JSON
+ value. These types are supported: bool,
+ int64, float64, string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ exclusiveMaximum:
+ type: boolean
+ exclusiveMinimum:
+ type: boolean
+ format:
+ description: "format is an OpenAPI v3 format
+ string. Unknown formats are ignored. The
+ following formats are validated: \n - bsonobjectid:
+ a bson object ID, i.e. a 24 characters hex
+ string - uri: an URI as parsed by Golang
+ net/url.ParseRequestURI - email: an email
+ address as parsed by Golang net/mail.ParseAddress
+ - hostname: a valid representation for an
+ Internet host name, as defined by RFC 1034,
+ section 3.1 [RFC1034]. - ipv4: an IPv4 IP
+ as parsed by Golang net.ParseIP - ipv6:
+ an IPv6 IP as parsed by Golang net.ParseIP
+ - cidr: a CIDR as parsed by Golang net.ParseCIDR
+ - mac: a MAC address as parsed by Golang
+ net.ParseMAC - uuid: an UUID that allows
+ uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid3: an UUID3 that allows uppercase
+ defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid4: an UUID4 that allows uppercase
+ defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - uuid5: an UUID5 that allows uppercase
+ defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - isbn: an ISBN10 or ISBN13 number string
+ like \"0321751043\" or \"978-0321751041\"
+ - isbn10: an ISBN10 number string like \"0321751043\"
+ - isbn13: an ISBN13 number string like \"978-0321751041\"
+ - creditcard: a credit card number defined
+ by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
+ with any non digit characters mixed in -
+ ssn: a U.S. social security number following
+ the regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$
+ - hexcolor: an hexadecimal color code like
+ \"#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
+ - rgbcolor: an RGB color code like rgb like
+ \"rgb(255,255,2559\" - byte: base64 encoded
+ binary data - password: any kind of string
+ - date: a date string like \"2006-01-02\"
+ as defined by full-date in RFC3339 - duration:
+ a duration string like \"22 ns\" as parsed
+ by Golang time.ParseDuration or compatible
+ with Scala duration format - datetime: a
+ date time string like \"2014-12-15T19:30:20.000Z\"
+ as defined by date-time in RFC3339."
+ type: string
+ id:
+ type: string
+ maxItems:
+ format: int64
+ type: integer
+ maxLength:
+ format: int64
+ type: integer
+ maxProperties:
+ format: int64
+ type: integer
+ maximum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ minItems:
+ format: int64
+ type: integer
+ minLength:
+ format: int64
+ type: integer
+ minProperties:
+ format: int64
+ type: integer
+ minimum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ multipleOf:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ nullable:
+ type: boolean
+ pattern:
+ type: string
+ title:
+ type: string
+ type:
+ type: string
+ uniqueItems:
+ type: boolean
+ x-descriptors:
+ description: The list of descriptors that
+ determine which UI components to use on
+ different views
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ required:
+ items:
type: string
- uniqueItems:
- type: boolean
- x-descriptors:
- description: The list of descriptors that determine
- which UI components to use on different views
- items:
- type: string
- type: array
- type: object
+ type: array
+ title:
+ type: string
+ type:
+ type: string
type: object
- required:
- items:
- type: string
- type: array
- title:
- type: string
- type:
- type: string
type: object
- type: object
- description: Types defines the schema of the data produced/consumed
- by the endpoint
+ description: Types defines the schema of the data produced/consumed
+ by the endpoint
+ type: object
+ uri:
+ description: URI can alternatively be used to specify the
+ (Camel) endpoint explicitly
+ type: string
type: object
- uri:
- description: URI can alternatively be used to specify the (Camel)
- endpoint explicitly
+ type:
type: string
type: object
integration:
@@ -298,6 +312,19 @@ spec:
items:
type: string
type: array
+ errorHandler:
+ description: ErrorHandlerSpec respresents an integration error
+ handler to be used as default at runtime
+ properties:
+ configuration:
+ description: ErrorHandlerConfiguration --
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type:
+ type: string
+ uri:
+ type: string
+ type: object
flows:
items:
description: Flow is an unstructured object representing a Camel
[camel-k] 22/30: refactor(trait): error handler language to yaml
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit d1a72fd77246b93c13a834db5e65bbcc8eb4112e
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 27 10:44:19 2021 +0200
refactor(trait): error handler language to yaml
---
.../kamelet-binding-error-handler.yaml | 11 +++-
pkg/trait/error_handler.go | 61 ++++++++--------------
2 files changed, 31 insertions(+), 41 deletions(-)
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
index 5f62adc..6c44ca7 100644
--- a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
+++ b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
@@ -30,7 +30,16 @@ spec:
kind: Kamelet
apiVersion: camel.apache.org/v1alpha1
name: log-sink
- errorHandler:
+ errorHandler:
+# log:
+# parameters:
+# maximumRedeliveries: 3
+# redeliveryDelay: 2000
+# ref: "something"
+# bean:
+# type: "org.apache.camel.builder.DeadLetterChannelBuilder"
+# parameters:
+# deadLetterUri: log:error
dead-letter-channel:
endpoint:
ref:
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index fbd757f..dd6e218 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -18,10 +18,9 @@ limitations under the License.
package trait
import (
- "fmt"
-
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+ "gopkg.in/yaml.v2"
)
// The error-handler is a platform trait used to inject Error Handler source into the integration runtime.
@@ -29,6 +28,8 @@ import (
// +camel-k:trait=error-handler
type errorHandlerTrait struct {
BaseTrait `property:",squash"`
+ // The error handler ref name found in application properties
+ ErrorHandlerRef string `property:",omitempty"`
}
func newErrorHandlerTrait() Trait {
@@ -51,57 +52,37 @@ func (t *errorHandlerTrait) Configure(e *Environment) (bool, error) {
return false, nil
}
- return e.Integration.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerRefName) != "", nil
+ t.ErrorHandlerRef = e.Integration.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerRefName)
+
+ return t.ErrorHandlerRef != "", nil
}
func (t *errorHandlerTrait) Apply(e *Environment) error {
if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
- err := addErrorHandlerAsSource(e)
- if err != nil {
- return err
- }
+ return t.addErrorHandlerAsSource(e)
}
return nil
}
-func addErrorHandlerAsSource(e *Environment) error {
- errorHandlerRefName := e.Integration.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerRefName)
- // TODO change to yaml flow when we fix https://issues.apache.org/jira/browse/CAMEL-16486
+func (t *errorHandlerTrait) addErrorHandlerAsSource(e *Environment) error {
+ flowErrorHandler := map[string]interface{}{
+ "error-handler": map[string]string{
+ "ref": t.ErrorHandlerRef,
+ },
+ }
+ encodedFlowErrorHandler, err := yaml.Marshal([]map[string]interface{}{flowErrorHandler})
+ if err != nil {
+ return err
+ }
errorHandlerSource := v1.SourceSpec{
DataSpec: v1.DataSpec{
- Name: "ErrorHandlerSource.java",
- Content: fmt.Sprintf(`
- import org.apache.camel.builder.RouteBuilder;
- public class ErrorHandlerSource extends RouteBuilder {
- @Override
- public void configure() throws Exception {
- errorHandler("%s");
- }
- }
- `, errorHandlerRefName),
+ Name: "camel-k-embedded-error-handler.yaml",
+ Content: string(encodedFlowErrorHandler),
},
- Language: v1.LanguageJavaSource,
+ Language: v1.LanguageYaml,
Type: v1.SourceTypeErrorHandler,
}
- /*
- flowErrorHandler := map[string]interface{}{
- "error-handler": map[string]string{
- "ref": errorHandlerRefName,
- },
- }
- encodedFlowErrorHandler, err := yaml.Marshal(flowErrorHandler)
- if err != nil {
- return err
- }
- errorHandlerSource := v1.SourceSpec{
- DataSpec: v1.DataSpec{
- Name: "ErrorHandlerSource.yaml",
- Content: string(encodedFlowErrorHandler),
- },
- Language: v1.LanguageYaml,
- Type: v1.SourceTypeErrorHandler,
- }
- */
+
e.Integration.Status.AddOrReplaceGeneratedSources(errorHandlerSource)
return nil
[camel-k] 05/30: feat(crd): kameletbinding error handler
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 619806dccddc3311554117e731f8ddba373631ef
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 13 14:21:16 2021 +0200
feat(crd): kameletbinding error handler
---
.../bases/camel.apache.org_kameletbindings.yaml | 214 +++++++++++++++++++++
.../1.4.0/camel.apache.org_kameletbindings.yaml | 214 +++++++++++++++++++++
helm/camel-k/crds/crd-kamelet-binding.yaml | 214 +++++++++++++++++++++
3 files changed, 642 insertions(+)
diff --git a/config/crd/bases/camel.apache.org_kameletbindings.yaml b/config/crd/bases/camel.apache.org_kameletbindings.yaml
index c9a8b87..7c43c55 100644
--- a/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -63,6 +63,220 @@ spec:
spec:
description: KameletBindingSpec --
properties:
+ errorHandler:
+ description: ErrorHandler is an optional handler called upon an error
+ occuring in the integration
+ properties:
+ properties:
+ description: Properties are a key value representation of endpoint
+ properties
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ ref:
+ description: Ref can be used to declare a Kubernetes resource
+ as source/sink endpoint
+ properties:
+ apiVersion:
+ description: API version of the referent.
+ type: string
+ fieldPath:
+ description: 'If referring to a piece of an object instead
+ of an entire object, this string should contain a valid
+ JSON/Go field access statement, such as desiredState.manifest.containers[2].
+ For example, if the object reference is to a container within
+ a pod, this would take on a value like: "spec.containers{name}"
+ (where "name" refers to the name of the container that triggered
+ the event) or if no container name is specified "spec.containers[2]"
+ (container with index 2 in this pod). This syntax is chosen
+ only to have some well-defined way of referencing a part
+ of an object. TODO: this design is not final and this field
+ is subject to change in the future.'
+ type: string
+ kind:
+ description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
+ type: string
+ namespace:
+ description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
+ type: string
+ resourceVersion:
+ description: 'Specific resourceVersion to which this reference
+ is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
+ type: string
+ uid:
+ description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
+ type: string
+ type: object
+ types:
+ additionalProperties:
+ properties:
+ mediaType:
+ type: string
+ schema:
+ description: JSONSchemaProps is a JSON-Schema following
+ Specification Draft 4 (http://json-schema.org/).
+ properties:
+ $schema:
+ description: JSONSchemaURL represents a schema url.
+ type: string
+ description:
+ type: string
+ example:
+ description: 'JSON represents any valid JSON value.
+ These types are supported: bool, int64, float64, string,
+ []interface{}, map[string]interface{} and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ externalDocs:
+ description: ExternalDocumentation allows referencing
+ an external resource for extended documentation.
+ properties:
+ description:
+ type: string
+ url:
+ type: string
+ type: object
+ id:
+ type: string
+ properties:
+ additionalProperties:
+ properties:
+ default:
+ description: default is a default value for undefined
+ object fields.
+ x-kubernetes-preserve-unknown-fields: true
+ description:
+ type: string
+ enum:
+ items:
+ description: 'JSON represents any valid JSON
+ value. These types are supported: bool, int64,
+ float64, string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ type: array
+ example:
+ description: 'JSON represents any valid JSON value.
+ These types are supported: bool, int64, float64,
+ string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ exclusiveMaximum:
+ type: boolean
+ exclusiveMinimum:
+ type: boolean
+ format:
+ description: "format is an OpenAPI v3 format string.
+ Unknown formats are ignored. The following formats
+ are validated: \n - bsonobjectid: a bson object
+ ID, i.e. a 24 characters hex string - uri: an
+ URI as parsed by Golang net/url.ParseRequestURI
+ - email: an email address as parsed by Golang
+ net/mail.ParseAddress - hostname: a valid representation
+ for an Internet host name, as defined by RFC
+ 1034, section 3.1 [RFC1034]. - ipv4: an IPv4
+ IP as parsed by Golang net.ParseIP - ipv6: an
+ IPv6 IP as parsed by Golang net.ParseIP - cidr:
+ a CIDR as parsed by Golang net.ParseCIDR - mac:
+ a MAC address as parsed by Golang net.ParseMAC
+ - uuid: an UUID that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid3: an UUID3 that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid4: an UUID4 that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - uuid5: an UUID5 that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - isbn: an ISBN10 or ISBN13 number string like
+ \"0321751043\" or \"978-0321751041\" - isbn10:
+ an ISBN10 number string like \"0321751043\"
+ - isbn13: an ISBN13 number string like \"978-0321751041\"
+ - creditcard: a credit card number defined by
+ the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
+ with any non digit characters mixed in - ssn:
+ a U.S. social security number following the
+ regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$ -
+ hexcolor: an hexadecimal color code like \"#FFFFFF:
+ following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
+ - rgbcolor: an RGB color code like rgb like
+ \"rgb(255,255,2559\" - byte: base64 encoded
+ binary data - password: any kind of string -
+ date: a date string like \"2006-01-02\" as defined
+ by full-date in RFC3339 - duration: a duration
+ string like \"22 ns\" as parsed by Golang time.ParseDuration
+ or compatible with Scala duration format - datetime:
+ a date time string like \"2014-12-15T19:30:20.000Z\"
+ as defined by date-time in RFC3339."
+ type: string
+ id:
+ type: string
+ maxItems:
+ format: int64
+ type: integer
+ maxLength:
+ format: int64
+ type: integer
+ maxProperties:
+ format: int64
+ type: integer
+ maximum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ minItems:
+ format: int64
+ type: integer
+ minLength:
+ format: int64
+ type: integer
+ minProperties:
+ format: int64
+ type: integer
+ minimum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ multipleOf:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ nullable:
+ type: boolean
+ pattern:
+ type: string
+ title:
+ type: string
+ type:
+ type: string
+ uniqueItems:
+ type: boolean
+ x-descriptors:
+ description: The list of descriptors that determine
+ which UI components to use on different views
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ required:
+ items:
+ type: string
+ type: array
+ title:
+ type: string
+ type:
+ type: string
+ type: object
+ type: object
+ description: Types defines the schema of the data produced/consumed
+ by the endpoint
+ type: object
+ uri:
+ description: URI can alternatively be used to specify the (Camel)
+ endpoint explicitly
+ type: string
+ type: object
integration:
description: Integration is an optional integration used to specify
custom parameters
diff --git a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml
index c9a8b87..7c43c55 100644
--- a/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml
+++ b/deploy/olm-catalog/camel-k-dev/1.4.0/camel.apache.org_kameletbindings.yaml
@@ -63,6 +63,220 @@ spec:
spec:
description: KameletBindingSpec --
properties:
+ errorHandler:
+ description: ErrorHandler is an optional handler called upon an error
+ occuring in the integration
+ properties:
+ properties:
+ description: Properties are a key value representation of endpoint
+ properties
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ ref:
+ description: Ref can be used to declare a Kubernetes resource
+ as source/sink endpoint
+ properties:
+ apiVersion:
+ description: API version of the referent.
+ type: string
+ fieldPath:
+ description: 'If referring to a piece of an object instead
+ of an entire object, this string should contain a valid
+ JSON/Go field access statement, such as desiredState.manifest.containers[2].
+ For example, if the object reference is to a container within
+ a pod, this would take on a value like: "spec.containers{name}"
+ (where "name" refers to the name of the container that triggered
+ the event) or if no container name is specified "spec.containers[2]"
+ (container with index 2 in this pod). This syntax is chosen
+ only to have some well-defined way of referencing a part
+ of an object. TODO: this design is not final and this field
+ is subject to change in the future.'
+ type: string
+ kind:
+ description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
+ type: string
+ namespace:
+ description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
+ type: string
+ resourceVersion:
+ description: 'Specific resourceVersion to which this reference
+ is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
+ type: string
+ uid:
+ description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
+ type: string
+ type: object
+ types:
+ additionalProperties:
+ properties:
+ mediaType:
+ type: string
+ schema:
+ description: JSONSchemaProps is a JSON-Schema following
+ Specification Draft 4 (http://json-schema.org/).
+ properties:
+ $schema:
+ description: JSONSchemaURL represents a schema url.
+ type: string
+ description:
+ type: string
+ example:
+ description: 'JSON represents any valid JSON value.
+ These types are supported: bool, int64, float64, string,
+ []interface{}, map[string]interface{} and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ externalDocs:
+ description: ExternalDocumentation allows referencing
+ an external resource for extended documentation.
+ properties:
+ description:
+ type: string
+ url:
+ type: string
+ type: object
+ id:
+ type: string
+ properties:
+ additionalProperties:
+ properties:
+ default:
+ description: default is a default value for undefined
+ object fields.
+ x-kubernetes-preserve-unknown-fields: true
+ description:
+ type: string
+ enum:
+ items:
+ description: 'JSON represents any valid JSON
+ value. These types are supported: bool, int64,
+ float64, string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ type: array
+ example:
+ description: 'JSON represents any valid JSON value.
+ These types are supported: bool, int64, float64,
+ string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ exclusiveMaximum:
+ type: boolean
+ exclusiveMinimum:
+ type: boolean
+ format:
+ description: "format is an OpenAPI v3 format string.
+ Unknown formats are ignored. The following formats
+ are validated: \n - bsonobjectid: a bson object
+ ID, i.e. a 24 characters hex string - uri: an
+ URI as parsed by Golang net/url.ParseRequestURI
+ - email: an email address as parsed by Golang
+ net/mail.ParseAddress - hostname: a valid representation
+ for an Internet host name, as defined by RFC
+ 1034, section 3.1 [RFC1034]. - ipv4: an IPv4
+ IP as parsed by Golang net.ParseIP - ipv6: an
+ IPv6 IP as parsed by Golang net.ParseIP - cidr:
+ a CIDR as parsed by Golang net.ParseCIDR - mac:
+ a MAC address as parsed by Golang net.ParseMAC
+ - uuid: an UUID that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid3: an UUID3 that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid4: an UUID4 that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - uuid5: an UUID5 that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - isbn: an ISBN10 or ISBN13 number string like
+ \"0321751043\" or \"978-0321751041\" - isbn10:
+ an ISBN10 number string like \"0321751043\"
+ - isbn13: an ISBN13 number string like \"978-0321751041\"
+ - creditcard: a credit card number defined by
+ the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
+ with any non digit characters mixed in - ssn:
+ a U.S. social security number following the
+ regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$ -
+ hexcolor: an hexadecimal color code like \"#FFFFFF:
+ following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
+ - rgbcolor: an RGB color code like rgb like
+ \"rgb(255,255,2559\" - byte: base64 encoded
+ binary data - password: any kind of string -
+ date: a date string like \"2006-01-02\" as defined
+ by full-date in RFC3339 - duration: a duration
+ string like \"22 ns\" as parsed by Golang time.ParseDuration
+ or compatible with Scala duration format - datetime:
+ a date time string like \"2014-12-15T19:30:20.000Z\"
+ as defined by date-time in RFC3339."
+ type: string
+ id:
+ type: string
+ maxItems:
+ format: int64
+ type: integer
+ maxLength:
+ format: int64
+ type: integer
+ maxProperties:
+ format: int64
+ type: integer
+ maximum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ minItems:
+ format: int64
+ type: integer
+ minLength:
+ format: int64
+ type: integer
+ minProperties:
+ format: int64
+ type: integer
+ minimum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ multipleOf:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ nullable:
+ type: boolean
+ pattern:
+ type: string
+ title:
+ type: string
+ type:
+ type: string
+ uniqueItems:
+ type: boolean
+ x-descriptors:
+ description: The list of descriptors that determine
+ which UI components to use on different views
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ required:
+ items:
+ type: string
+ type: array
+ title:
+ type: string
+ type:
+ type: string
+ type: object
+ type: object
+ description: Types defines the schema of the data produced/consumed
+ by the endpoint
+ type: object
+ uri:
+ description: URI can alternatively be used to specify the (Camel)
+ endpoint explicitly
+ type: string
+ type: object
integration:
description: Integration is an optional integration used to specify
custom parameters
diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml
index c9a8b87..7c43c55 100644
--- a/helm/camel-k/crds/crd-kamelet-binding.yaml
+++ b/helm/camel-k/crds/crd-kamelet-binding.yaml
@@ -63,6 +63,220 @@ spec:
spec:
description: KameletBindingSpec --
properties:
+ errorHandler:
+ description: ErrorHandler is an optional handler called upon an error
+ occuring in the integration
+ properties:
+ properties:
+ description: Properties are a key value representation of endpoint
+ properties
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ ref:
+ description: Ref can be used to declare a Kubernetes resource
+ as source/sink endpoint
+ properties:
+ apiVersion:
+ description: API version of the referent.
+ type: string
+ fieldPath:
+ description: 'If referring to a piece of an object instead
+ of an entire object, this string should contain a valid
+ JSON/Go field access statement, such as desiredState.manifest.containers[2].
+ For example, if the object reference is to a container within
+ a pod, this would take on a value like: "spec.containers{name}"
+ (where "name" refers to the name of the container that triggered
+ the event) or if no container name is specified "spec.containers[2]"
+ (container with index 2 in this pod). This syntax is chosen
+ only to have some well-defined way of referencing a part
+ of an object. TODO: this design is not final and this field
+ is subject to change in the future.'
+ type: string
+ kind:
+ description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
+ type: string
+ namespace:
+ description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
+ type: string
+ resourceVersion:
+ description: 'Specific resourceVersion to which this reference
+ is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
+ type: string
+ uid:
+ description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
+ type: string
+ type: object
+ types:
+ additionalProperties:
+ properties:
+ mediaType:
+ type: string
+ schema:
+ description: JSONSchemaProps is a JSON-Schema following
+ Specification Draft 4 (http://json-schema.org/).
+ properties:
+ $schema:
+ description: JSONSchemaURL represents a schema url.
+ type: string
+ description:
+ type: string
+ example:
+ description: 'JSON represents any valid JSON value.
+ These types are supported: bool, int64, float64, string,
+ []interface{}, map[string]interface{} and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ externalDocs:
+ description: ExternalDocumentation allows referencing
+ an external resource for extended documentation.
+ properties:
+ description:
+ type: string
+ url:
+ type: string
+ type: object
+ id:
+ type: string
+ properties:
+ additionalProperties:
+ properties:
+ default:
+ description: default is a default value for undefined
+ object fields.
+ x-kubernetes-preserve-unknown-fields: true
+ description:
+ type: string
+ enum:
+ items:
+ description: 'JSON represents any valid JSON
+ value. These types are supported: bool, int64,
+ float64, string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ type: array
+ example:
+ description: 'JSON represents any valid JSON value.
+ These types are supported: bool, int64, float64,
+ string, []interface{}, map[string]interface{}
+ and nil.'
+ x-kubernetes-preserve-unknown-fields: true
+ exclusiveMaximum:
+ type: boolean
+ exclusiveMinimum:
+ type: boolean
+ format:
+ description: "format is an OpenAPI v3 format string.
+ Unknown formats are ignored. The following formats
+ are validated: \n - bsonobjectid: a bson object
+ ID, i.e. a 24 characters hex string - uri: an
+ URI as parsed by Golang net/url.ParseRequestURI
+ - email: an email address as parsed by Golang
+ net/mail.ParseAddress - hostname: a valid representation
+ for an Internet host name, as defined by RFC
+ 1034, section 3.1 [RFC1034]. - ipv4: an IPv4
+ IP as parsed by Golang net.ParseIP - ipv6: an
+ IPv6 IP as parsed by Golang net.ParseIP - cidr:
+ a CIDR as parsed by Golang net.ParseCIDR - mac:
+ a MAC address as parsed by Golang net.ParseMAC
+ - uuid: an UUID that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid3: an UUID3 that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$
+ - uuid4: an UUID4 that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - uuid5: an UUID5 that allows uppercase defined
+ by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$
+ - isbn: an ISBN10 or ISBN13 number string like
+ \"0321751043\" or \"978-0321751041\" - isbn10:
+ an ISBN10 number string like \"0321751043\"
+ - isbn13: an ISBN13 number string like \"978-0321751041\"
+ - creditcard: a credit card number defined by
+ the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$
+ with any non digit characters mixed in - ssn:
+ a U.S. social security number following the
+ regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$ -
+ hexcolor: an hexadecimal color code like \"#FFFFFF:
+ following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
+ - rgbcolor: an RGB color code like rgb like
+ \"rgb(255,255,2559\" - byte: base64 encoded
+ binary data - password: any kind of string -
+ date: a date string like \"2006-01-02\" as defined
+ by full-date in RFC3339 - duration: a duration
+ string like \"22 ns\" as parsed by Golang time.ParseDuration
+ or compatible with Scala duration format - datetime:
+ a date time string like \"2014-12-15T19:30:20.000Z\"
+ as defined by date-time in RFC3339."
+ type: string
+ id:
+ type: string
+ maxItems:
+ format: int64
+ type: integer
+ maxLength:
+ format: int64
+ type: integer
+ maxProperties:
+ format: int64
+ type: integer
+ maximum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ minItems:
+ format: int64
+ type: integer
+ minLength:
+ format: int64
+ type: integer
+ minProperties:
+ format: int64
+ type: integer
+ minimum:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ multipleOf:
+ description: A Number represents a JSON number
+ literal.
+ type: string
+ nullable:
+ type: boolean
+ pattern:
+ type: string
+ title:
+ type: string
+ type:
+ type: string
+ uniqueItems:
+ type: boolean
+ x-descriptors:
+ description: The list of descriptors that determine
+ which UI components to use on different views
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ required:
+ items:
+ type: string
+ type: array
+ title:
+ type: string
+ type:
+ type: string
+ type: object
+ type: object
+ description: Types defines the schema of the data produced/consumed
+ by the endpoint
+ type: object
+ uri:
+ description: URI can alternatively be used to specify the (Camel)
+ endpoint explicitly
+ type: string
+ type: object
integration:
description: Integration is an optional integration used to specify
custom parameters
[camel-k] 04/30: feat(kamelets): error handling kamelets binding
support
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 1849ca5223a865eb1cf3b7acab7a78c3540f8ea0
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 13 14:20:45 2021 +0200
feat(kamelets): error handling kamelets binding support
Mark error-handler kamelet source with errorHandler source type
---
pkg/apis/camel/v1/common_types.go | 5 +-
pkg/controller/kameletbinding/common.go | 52 ++++++++--------
pkg/trait/kamelets.go | 106 ++++++++++++++++++++++++--------
pkg/util/source/inspector_yaml.go | 4 --
pkg/util/source/types.go | 2 -
5 files changed, 109 insertions(+), 60 deletions(-)
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index a94d604..e5b327b 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -206,8 +206,9 @@ type SourceSpec struct {
type SourceType string
const (
- SourceTypeDefault SourceType = ""
- SourceTypeTemplate SourceType = "template"
+ SourceTypeDefault SourceType = ""
+ SourceTypeTemplate SourceType = "template"
+ SourceTypeErrorHandler SourceType = "errorHandler"
)
// DataSpec --
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index 32d7182..fdeab95 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -22,6 +22,7 @@ import (
"encoding/json"
"fmt"
"sort"
+ "strings"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -79,12 +80,17 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
if err != nil {
return nil, errors.Wrap(err, "could not determine sink URI")
}
- var onError *bindings.Binding
+ var errorHandler *bindings.Binding
if kameletbinding.Spec.ErrorHandler.Ref != nil || kameletbinding.Spec.ErrorHandler.URI != nil {
- onError, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler)
+ errorHandler, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler)
if err != nil {
return nil, errors.Wrap(err, "could not determine error handler URI")
}
+
+ err = setErrorHandlerKamelet(errorHandler, kameletbinding.Spec.ErrorHandler)
+ if err != nil {
+ return nil, errors.Wrap(err, "could not set error handler")
+ }
}
steps := make([]*bindings.Binding, 0, len(kameletbinding.Spec.Steps))
@@ -104,8 +110,8 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
allBindings = append(allBindings, from)
allBindings = append(allBindings, steps...)
allBindings = append(allBindings, to)
- if onError != nil {
- allBindings = append(allBindings, onError)
+ if errorHandler != nil {
+ allBindings = append(allBindings, errorHandler)
}
propList := make([]string, 0)
@@ -139,27 +145,6 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
"to": to.URI,
})
- // Append Error Handler flow, if it exists
- if onError != nil {
- flowErrorHandler := map[string]interface{}{
- "error-handler": map[string]interface{}{
- "dead-letter-channel": map[string]interface{}{
- "dead-letter-uri": onError.URI,
- "dead-letter-handle-new-exception": true,
- "async-delayed-redelivery": false,
- "use-original-message": true,
- },
- },
- }
- encodedErrorHandler, err := json.Marshal(flowErrorHandler)
-
- if err != nil {
- return nil, err
- }
- it.Spec.Flows = append(it.Spec.Flows, v1.Flow{RawMessage: encodedErrorHandler})
- }
-
- // Append From flow: it must exist
flowFrom := map[string]interface{}{
"from": map[string]interface{}{
"uri": from.URI,
@@ -175,6 +160,23 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
return &it, nil
}
+func setErrorHandlerKamelet(errorHandler *bindings.Binding, kameletSpec v1alpha1.Endpoint) error {
+ if errorHandler.ApplicationProperties == nil {
+ errorHandler.ApplicationProperties = make(map[string]string)
+ }
+ if kameletSpec.URI != nil {
+ if !strings.HasPrefix(*kameletSpec.URI, "kamelet") {
+ return fmt.Errorf("Kamelet Binding only supports kamelet as error handler, provided: %s", *kameletSpec.URI)
+ }
+
+ errorHandler.ApplicationProperties["camel.k.default-error-handler"] = *kameletSpec.URI
+ return nil
+ }
+
+ errorHandler.ApplicationProperties["camel.k.default-error-handler"] = kameletSpec.Ref.Name
+ return nil
+}
+
func determineProfile(ctx context.Context, c client.Client, binding *v1alpha1.KameletBinding) (v1.TraitProfile, error) {
if binding.Spec.Integration != nil && binding.Spec.Integration.Profile != "" {
return binding.Spec.Integration.Profile, nil
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index 9d55b19..053678d 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -47,6 +47,8 @@ type kameletsTrait struct {
Auto *bool `property:"auto"`
// Comma separated list of Kamelet names to load into the current integration
List string `property:"list"`
+ // Kamelet name used as error handler
+ ErrorHandler string `property:"error-handler"`
}
type configurationKey struct {
@@ -103,16 +105,37 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
util.StringSliceUniqueConcat(&kamelets, extractKamelets(meta.FromURIs))
util.StringSliceUniqueConcat(&kamelets, extractKamelets(meta.ToURIs))
- util.StringSliceUniqueConcat(&kamelets, extractKamelets(meta.ErrorHandlerURIs))
return true
})
sort.Strings(kamelets)
t.List = strings.Join(kamelets, ",")
}
+ if t.ErrorHandler == "" {
+ t.ErrorHandler = maybeKameletAsDefaultErrorHandler(e.Integration.Configurations())
+ }
+ }
+
+ return t.declareKamelets(), nil
+}
+func maybeKameletAsDefaultErrorHandler(properties []v1.ConfigurationSpec) string {
+ for _, property := range properties {
+ if strings.HasPrefix(property.Value, "camel.k.default-error-handler=") {
+ split := strings.Split(property.Value, "=")
+ if len(split) > 0 {
+ if strings.HasPrefix(split[1], "kamelet:") {
+ return extractKamelet(split[1])
+ }
+ return split[1]
+ }
+ }
}
- return len(t.getKameletKeys()) > 0, nil
+ return ""
+}
+
+func (t *kameletsTrait) declareKamelets() bool {
+ return len(t.getKameletKeys()) > 0 || t.ErrorHandler != ""
}
func (t *kameletsTrait) Apply(e *Environment) error {
@@ -133,44 +156,62 @@ func (t *kameletsTrait) Apply(e *Environment) error {
}
func (t *kameletsTrait) addKamelets(e *Environment) error {
- kameletKeys := t.getKameletKeys()
- if len(kameletKeys) > 0 {
+ if t.declareKamelets() {
repo, err := repository.NewForPlatform(e.C, e.Client, e.Platform, e.Integration.Namespace, platform.GetOperatorNamespace())
if err != nil {
return err
}
+
+ // Declared kamelets
for _, k := range t.getKameletKeys() {
- kamelet, err := repo.Get(e.C, k)
+ err := initializeKamelet(repo, e, k, t, v1.SourceTypeTemplate)
if err != nil {
return err
}
- if kamelet == nil {
- return fmt.Errorf("kamelet %s not found in any of the defined repositories: %s", k, repo.String())
- }
-
- // Initialize remote kamelets
- kamelet, err = kameletutils.Initialize(kamelet)
+ }
+ if t.ErrorHandler != "" {
+ // Possible error handler
+ err = initializeKamelet(repo, e, t.ErrorHandler, t, v1.SourceTypeErrorHandler)
if err != nil {
return err
}
-
- if kamelet.Status.Phase != v1alpha1.KameletPhaseReady {
- return fmt.Errorf("kamelet %q is not %s: %s", k, v1alpha1.KameletPhaseReady, kamelet.Status.Phase)
- }
-
- if err := t.addKameletAsSource(e, kamelet); err != nil {
- return err
- }
-
- // Adding dependencies from Kamelets
- util.StringSliceUniqueConcat(&e.Integration.Status.Dependencies, kamelet.Spec.Dependencies)
}
+
// resort dependencies
sort.Strings(e.Integration.Status.Dependencies)
}
return nil
}
+func initializeKamelet(repo repository.KameletRepository, e *Environment, k string, t *kameletsTrait, sourceType v1.SourceType) error {
+ kamelet, err := repo.Get(e.C, k)
+ if err != nil {
+ return err
+ }
+ if kamelet == nil {
+ return fmt.Errorf("kamelet %s not found in any of the defined repositories: %s", k, repo.String())
+ }
+
+ // Initialize remote kamelets
+ kamelet, err = kameletutils.Initialize(kamelet)
+ if err != nil {
+ return err
+ }
+
+ if kamelet.Status.Phase != v1alpha1.KameletPhaseReady {
+ return fmt.Errorf("kamelet %q is not %s: %s", k, v1alpha1.KameletPhaseReady, kamelet.Status.Phase)
+ }
+
+ if err := t.addKameletAsSource(e, kamelet, sourceType); err != nil {
+ return err
+ }
+
+ // Adding dependencies from Kamelets
+ util.StringSliceUniqueConcat(&e.Integration.Status.Dependencies, kamelet.Spec.Dependencies)
+
+ return nil
+}
+
func (t *kameletsTrait) configureApplicationProperties(e *Environment) error {
if len(t.getKameletKeys()) > 0 {
repo, err := repository.NewForPlatform(e.C, e.Client, e.Platform, e.Integration.Namespace, platform.GetOperatorNamespace())
@@ -215,7 +256,7 @@ func (t *kameletsTrait) configureApplicationProperties(e *Environment) error {
return nil
}
-func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kamelet) error {
+func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kamelet, sourceType v1.SourceType) error {
sources := make([]v1.SourceSpec, 0)
if kamelet.Spec.Flow != nil {
@@ -236,7 +277,7 @@ func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kam
Content: string(flowData),
},
Language: v1.LanguageYaml,
- Type: v1.SourceTypeTemplate,
+ Type: sourceType,
PropertyNames: propertyNames,
}
flowSource, err = integrationSourceFromKameletSource(e, kamelet, flowSource, fmt.Sprintf("%s-kamelet-%s-flow", e.Integration.Name, kamelet.Name))
@@ -247,6 +288,9 @@ func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kam
}
for idx, s := range kamelet.Spec.Sources {
+ if sourceType == v1.SourceTypeErrorHandler {
+ s.Type = sourceType
+ }
intSource, err := integrationSourceFromKameletSource(e, kamelet, s, fmt.Sprintf("%s-kamelet-%s-%03d", e.Integration.Name, kamelet.Name, idx))
if err != nil {
return err
@@ -405,10 +449,18 @@ func integrationSourceFromKameletSource(e *Environment, kamelet *v1alpha1.Kamele
func extractKamelets(uris []string) (kamelets []string) {
for _, uri := range uris {
- matches := kameletNameRegexp.FindStringSubmatch(uri)
- if len(matches) > 1 {
- kamelets = append(kamelets, matches[1])
+ kamelet := extractKamelet(uri)
+ if kamelet != "" {
+ kamelets = append(kamelets, kamelet)
}
}
return
}
+
+func extractKamelet(uri string) (kamelet string) {
+ matches := kameletNameRegexp.FindStringSubmatch(uri)
+ if len(matches) > 1 {
+ return matches[1]
+ }
+ return ""
+}
diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go
index 4c47dc2..1f96ae8 100644
--- a/pkg/util/source/inspector_yaml.go
+++ b/pkg/util/source/inspector_yaml.go
@@ -78,10 +78,6 @@ func (i YAMLInspector) parseStep(key string, content interface{}, meta *Metadata
}
}
}
- case "error-handler":
- deadLetterChannel := content.(map[interface{}]interface{})
- deadLetterURI := deadLetterChannel["dead-letter-channel"].(map[interface{}]interface{})
- meta.ErrorHandlerURIs = append(meta.ErrorHandlerURIs, deadLetterURI["dead-letter-uri"].(string))
}
var maybeURI string
diff --git a/pkg/util/source/types.go b/pkg/util/source/types.go
index 46074f8..f6f15e0 100644
--- a/pkg/util/source/types.go
+++ b/pkg/util/source/types.go
@@ -25,8 +25,6 @@ type Metadata struct {
FromURIs []string
// All end URIs of defined routes
ToURIs []string
- // All error handlers URIs of defined routes
- ErrorHandlerURIs []string
// All inferred dependencies required to run the integration
Dependencies *strset.Set
// ExposesHTTPServices indicates if a route defined by the source is exposed
[camel-k] 21/30: refactor(controller): app properties binding
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 71e06243d44e6533d648b58b4c38e0d7f17a0c45
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 27 10:24:04 2021 +0200
refactor(controller): app properties binding
Error handler application properties set via binding
---
pkg/controller/kameletbinding/common.go | 2 +-
pkg/controller/kameletbinding/error_handler.go | 26 +++++++++++--------
pkg/resources/resources.go | 36 +++++++++++++-------------
pkg/trait/error_handler.go | 20 +++++++++++++-
4 files changed, 53 insertions(+), 31 deletions(-)
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index 45509e1..5da336a 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -81,7 +81,7 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
return nil, errors.Wrap(err, "could not determine sink URI")
}
// error handler is optional
- errorHandler, err := maybeErrorHandler(kameletbinding.Spec.ErrorHandler, bindingContext, &it.Spec)
+ errorHandler, err := maybeErrorHandler(kameletbinding.Spec.ErrorHandler, bindingContext)
if err != nil {
return nil, errors.Wrap(err, "could not determine error handler")
}
diff --git a/pkg/controller/kameletbinding/error_handler.go b/pkg/controller/kameletbinding/error_handler.go
index 0f75670..1d71683 100644
--- a/pkg/controller/kameletbinding/error_handler.go
+++ b/pkg/controller/kameletbinding/error_handler.go
@@ -27,29 +27,33 @@ import (
"github.com/pkg/errors"
)
-func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandlerSpec, bindingContext bindings.BindingContext, itSpec *v1.IntegrationSpec) (*bindings.Binding, error) {
- var errorHandler *bindings.Binding
+func maybeErrorHandler(errHandlConf v1alpha1.ErrorHandlerSpec, bindingContext bindings.BindingContext) (*bindings.Binding, error) {
+ var errorHandlerBinding *bindings.Binding
if errHandlConf.RawMessage != nil {
errorHandlerSpec, err := parseErrorHandler(errHandlConf.RawMessage)
if err != nil {
return nil, errors.Wrap(err, "could not parse error handler")
}
// We need to get the translated URI from any referenced resource (ie, kamelets)
- errorHandlerURI := ""
if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeDeadLetterChannel {
- errorHandler, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, *errorHandlerSpec.Endpoint())
+ errorHandlerBinding, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, *errorHandlerSpec.Endpoint())
if err != nil {
return nil, errors.Wrap(err, "could not determine error handler URI")
}
- errorHandlerURI = errorHandler.URI
+ } else {
+ // Create a new binding otherwise in order to store application properties
+ errorHandlerBinding = &bindings.Binding{
+ URI: "error-handler",
+ ApplicationProperties: make(map[string]string),
+ }
}
- err = setErrorHandlerConfiguration(itSpec, errorHandlerURI, errorHandlerSpec)
+ err = setErrorHandlerConfiguration(errorHandlerBinding, errorHandlerSpec)
if err != nil {
return nil, errors.Wrap(err, "could not set integration error handler")
}
- return errorHandler, nil
+ return errorHandlerBinding, nil
}
return nil, nil
}
@@ -92,16 +96,16 @@ func parseErrorHandler(rawMessage v1.RawMessage) (v1alpha1.ErrorHandler, error)
return nil, errors.New("You must provide any supported error handler")
}
-func setErrorHandlerConfiguration(it *v1.IntegrationSpec, errorHandlerURI string, errorHandler v1alpha1.ErrorHandler) error {
+func setErrorHandlerConfiguration(errorHandlerBinding *bindings.Binding, errorHandler v1alpha1.ErrorHandler) error {
properties, err := errorHandler.Configuration()
if err != nil {
return err
}
for key, value := range properties {
- it.AddConfiguration("property", fmt.Sprintf("%s=%v", key, value))
+ errorHandlerBinding.ApplicationProperties[key] = fmt.Sprintf("%v", value)
}
- if errorHandler.Type() == v1alpha1.ErrorHandlerTypeDeadLetterChannel && errorHandlerURI != "" {
- it.AddConfiguration("property", fmt.Sprintf("%s.deadLetterUri=%v", v1alpha1.ErrorHandlerAppPropertiesPrefix, errorHandlerURI))
+ if errorHandler.Type() == v1alpha1.ErrorHandlerTypeDeadLetterChannel && errorHandlerBinding.URI != "" {
+ errorHandlerBinding.ApplicationProperties[fmt.Sprintf("%s.deadLetterUri", v1alpha1.ErrorHandlerAppPropertiesPrefix)] = fmt.Sprintf("%v", errorHandlerBinding.URI)
}
return nil
}
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 5c771bb..9f43b93 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -238,19 +238,19 @@ var assets = func() http.FileSystem {
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x6f\xab\x46\x14\xdd\xcf\xaf\x38\x32\x9b\xf7\x24\x1b\xb7\x5d\x55\xee\x8a\x97\xd8\x2d\x6a\x64\x4b\xc6\x69\x94\xe5\x78\xb8\xc0\xad\x61\x2e\x9d\x19\x42\xdc\x5f\x5f\x0d\xb6\x9b\x44\x55\xab\x2e\x32\x2b\x10\x97\xf3\x71\xcf\x99\x04\x8b\xcf\x3b\x2a\xc1\x03\x1b\xb2\x9e\x4a\x04\x41\x68\x08\x59\xaf\x4d\x43\x28\xa4\x0a\xa3\x76\x84\x8d\x0c\xb6\xd4\x81\xc5\xe2\x4b\x56\x6c\xbe\x62\xb0\x25\x39\x88\x25\x88\x43\x27\x8e\x54\x [...]
},
- "/rbac/operator-role-binding-service-binding.yaml": &vfsgen۰CompressedFileInfo{
- name: "operator-role-binding-service-binding.yaml",
+ "/rbac/operator-role-binding-podmonitors.yaml": &vfsgen۰CompressedFileInfo{
+ name: "operator-role-binding-podmonitors.yaml",
modTime: time.Time{},
- uncompressedSize: 1237,
+ uncompressedSize: 1229,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xcf\x6f\xf2\x46\x10\xbd\xef\x5f\xf1\x84\x2f\xdf\x27\x81\x69\x7b\xaa\xe8\xc9\x5f\x02\xad\xd5\x08\x24\x4c\x1a\xe5\xb8\x5e\x0f\xf6\x14\x7b\xc7\xdd\x5d\xc7\xa1\x7f\x7d\xb5\x06\x9a\x44\x55\x2b\x55\xca\xde\x10\x33\xef\xc7\xbc\xe7\x04\x8b\xcf\x7b\x2a\xc1\x03\x1b\xb2\x9e\x2a\x04\x41\x68\x08\x59\xaf\x4d\x43\x28\xe4\x18\x46\xed\x08\x1b\x19\x6c\xa5\x03\x8b\xc5\x97\xac\xd8\x7c\xc5\x60\x2b\x72\x10\x4b\x10\x87\x4e\x1c\xa9\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x4f\x85\x7b\x72\x36\xbb\xad\xd0\xc0\x06\x2c\xa7\x41\x8e\x34\x35\x96\xa6\x2b\x71\xd8\x21\xb5\x8a\xfb\xeb\x0b\xca\x76\x77\x83\xa2\x45\x0f\xe1\x4d\xd0\xf0\x7d\xcc\x7b\x2c\xb0\xfc\x76\xc7\x14\xf8\xc0\x8e\x7c\xa4\x06\x49\x90\x3a\xc2\x26\x58\xd7\x11\x6a\x39\xa5\xc9\x2a\xe1\x51\x46\xdf\xd8\xc4\xe2\xf1\x66\x53\x3f\xbe\xc5\xe8\x1b\x52\x88\x27\x88\x62\x10\x25\x [...]
},
- "/rbac/operator-role-binding-servicemonitors.yaml": &vfsgen۰CompressedFileInfo{
- name: "operator-role-binding-servicemonitors.yaml",
+ "/rbac/operator-role-binding-service-binding.yaml": &vfsgen۰CompressedFileInfo{
+ name: "operator-role-binding-service-binding.yaml",
modTime: time.Time{},
uncompressedSize: 1237,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x4f\x85\x7b\x52\x36\xeb\x56\x68\x60\x03\x96\xd3\x20\x47\x9a\x1a\x4b\x53\x4b\x1c\x75\x48\xad\xe2\xfe\xfa\x82\xb2\xdd\xdd\xa0\x68\x81\x02\xe1\xcd\xf0\xcc\xfb\x98\xf7\x94\x61\xf9\xed\x9e\xc9\xf0\x81\x1d\xf9\x40\x35\xa2\x20\xb6\x84\x62\xb0\xae\x25\x54\x72\x8a\x93\x55\xc2\x46\x46\x5f\xdb\xc8\xe2\xf1\xa6\xa8\x36\x6f\x31\xfa\x9a\x14\xe2\x09\xa2\xe8\x45\xc9\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xcf\x6f\xf2\x46\x10\xbd\xef\x5f\xf1\x84\x2f\xdf\x27\x81\x69\x7b\xaa\xe8\xc9\x5f\x02\xad\xd5\x08\x24\x4c\x1a\xe5\xb8\x5e\x0f\xf6\x14\x7b\xc7\xdd\x5d\xc7\xa1\x7f\x7d\xb5\x06\x9a\x44\x55\x2b\x55\xca\xde\x10\x33\xef\xc7\xbc\xe7\x04\x8b\xcf\x7b\x2a\xc1\x03\x1b\xb2\x9e\x2a\x04\x41\x68\x08\x59\xaf\x4d\x43\x28\xe4\x18\x46\xed\x08\x1b\x19\x6c\xa5\x03\x8b\xc5\x97\xac\xd8\x7c\xc5\x60\x2b\x72\x10\x4b\x10\x87\x4e\x1c\xa9\x [...]
},
"/rbac/operator-role-binding-strimzi.yaml": &vfsgen۰CompressedFileInfo{
name: "operator-role-binding-strimzi.yaml",
@@ -301,6 +301,13 @@ var assets = func() http.FileSystem {
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x53\xc1\x8e\xdb\x46\x0c\xbd\xeb\x2b\x1e\xac\x4b\x02\xac\xe5\xb6\xa7\xc2\x3d\xb9\xc9\x6e\x6b\x34\xb0\x81\x95\xd3\x20\x47\x7a\x44\x4b\xc4\x8e\x86\xea\xcc\x68\x95\xed\xd7\x17\x33\xb6\x13\x6f\xdd\x6d\x2e\x01\xa2\x8b\x68\xf2\x89\x7c\x8f\x8f\x2e\x31\xff\x76\x4f\x51\xe2\x9d\x18\x76\x81\x1b\x44\x45\xec\x18\xab\x81\x4c\xc7\xa8\xf5\x10\x27\xf2\x8c\x3b\x1d\x5d\x43\x51\xd4\xe1\xd5\xaa\xbe\x7b\x8d\xd1\x35\xec\xa1\x8e\xa1\x1e\x [...]
},
+ "/rbac/operator-role-podmonitors.yaml": &vfsgen۰CompressedFileInfo{
+ name: "operator-role-podmonitors.yaml",
+ modTime: time.Time{},
+ uncompressedSize: 1242,
+
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x4f\x85\x7b\x72\x37\xbb\xad\xd0\xc0\x06\x56\x4e\x83\x1c\x69\x6a\x2c\x0d\x96\xe2\xb0\x43\x6a\x95\xed\xaf\x2f\x24\xcb\xcd\x1a\xb9\x86\x17\x8f\xc9\xe1\xfb\xe0\x1b\x15\x58\xff\xb8\x65\x0a\x7c\x64\x47\x21\x51\x83\x2c\xc8\x1d\x61\x17\xad\xeb\x08\xb5\x9c\xf3\x68\x95\xf0\x28\x43\x68\x6c\x66\x09\x78\xb7\xab\x1f\xdf\x63\x08\x0d\x29\x24\x10\x44\xd1\x8b\x92\x29\x [...]
+ },
"/rbac/operator-role-service-binding.yaml": &vfsgen۰CompressedFileInfo{
name: "operator-role-service-binding.yaml",
modTime: time.Time{},
@@ -308,13 +315,6 @@ var assets = func() http.FileSystem {
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x6e\xdc\x36\x10\xbd\xf3\x2b\x1e\x56\x97\x04\xb0\xe4\xb6\xa7\x62\x7b\xda\x3a\x76\x2b\x34\xd8\x05\xac\x4d\x83\x1c\xb9\xd4\xac\x34\x30\xc5\x51\x87\x94\x15\xf7\xeb\x0b\x6a\xb5\x89\x8d\x5e\xa3\x0b\x47\xe4\xcc\x9b\xf7\xf8\x86\x05\xca\x1f\xf7\x99\x02\x1f\xd9\x51\x88\xd4\x22\x09\x52\x4f\xd8\x8d\xd6\xf5\x84\x46\xce\x69\xb6\x4a\x78\x90\x29\xb4\x36\xb1\x04\xbc\xdb\x35\x0f\xef\x31\x85\x96\x14\x12\x08\xa2\x18\x44\xc9\x [...]
},
- "/rbac/operator-role-servicemonitors.yaml": &vfsgen۰CompressedFileInfo{
- name: "operator-role-servicemonitors.yaml",
- modTime: time.Time{},
- uncompressedSize: 1250,
-
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x8e\xdb\x36\x10\xbd\xf3\x2b\x1e\xac\x4b\x02\xac\xe5\xb6\xa7\xc2\x3d\xb9\x9b\xdd\x56\x68\x60\x03\x2b\xa7\x41\x8e\x34\x35\x96\x06\x4b\x71\xd4\x21\xb5\x8a\xfb\xf5\x85\x68\xb9\xd9\x45\xae\xe1\xc5\x63\x72\x66\xde\x7b\xf3\x46\x05\xd6\x3f\xee\x98\x02\x1f\xd9\x51\x88\xd4\x20\x09\x52\x47\xd8\x0d\xd6\x75\x84\x5a\xce\x69\xb2\x4a\x78\x94\x31\x34\x36\xb1\x04\xbc\xdb\xd5\x8f\xef\x31\x86\x86\x14\x12\x08\xa2\xe8\x45\xc9\x [...]
- },
"/rbac/operator-role-strimzi.yaml": &vfsgen۰CompressedFileInfo{
name: "operator-role-strimzi.yaml",
modTime: time.Time{},
@@ -467,9 +467,9 @@ var assets = func() http.FileSystem {
"/traits.yaml": &vfsgen۰CompressedFileInfo{
name: "traits.yaml",
modTime: time.Time{},
- uncompressedSize: 37171,
+ uncompressedSize: 36976,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xed\x72\x1c\xb7\x11\xe0\x7f\x3d\x05\x8a\xb9\x2a\x7e\xd4\xee\x90\x72\xca\xb1\xb3\x77\xba\x14\x2d\x29\x09\x6d\x4b\xe2\x89\x8a\x53\x57\x3a\x57\x16\x3b\xd3\xbb\x0b\x11\x03\x4c\x00\x0c\xa9\xcd\xd5\xbd\xfb\x15\xba\x01\x0c\x66\x77\xb8\x1c\xca\xa6\xcb\xbc\xba\xe4\x87\x45\x72\xa6\xd1\x68\x34\xfa\xbb\x7b\x9c\xe1\xc2\xd9\xd9\xb3\x29\x53\xbc\x86\x19\xe3\xcb\xa5\x50\xc2\x6d\x9e\x31\xd6\x48\xee\x96\xda\xd4\x33\xb6\xe4\xd2\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6d\x73\x1c\xb7\xd1\xe0\x77\xfd\x0a\x14\x9f\xab\xe2\x4b\xed\x0c\x29\xa7\x9c\xf8\xf6\x4e\x97\xa2\x25\x25\xa1\x6d\x49\x3c\x51\x71\xea\x4a\xa7\xca\x62\x67\x7a\x77\x21\x62\x80\x09\x80\x21\xb5\xb9\xba\xff\x7e\x85\x6e\x00\x83\xd9\x1d\x2e\x97\xb2\xe9\x32\xaf\x9e\xe4\x83\x45\x72\xa6\xd1\x68\x34\xfa\xbd\x7b\x9c\xe1\xc2\xd9\xe9\xb3\x82\x29\xde\xc0\x94\xf1\xc5\x42\x28\xe1\xd6\xcf\x18\x6b\x25\x77\x0b\x6d\x9a\x29\x5b\x70\x [...]
},
}
fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
@@ -524,8 +524,8 @@ var assets = func() http.FileSystem {
fs["/rbac/operator-role-binding-knative.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding-leases.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding-openshift.yaml"].(os.FileInfo),
+ fs["/rbac/operator-role-binding-podmonitors.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding-service-binding.yaml"].(os.FileInfo),
- fs["/rbac/operator-role-binding-servicemonitors.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding-strimzi.yaml"].(os.FileInfo),
fs["/rbac/operator-role-binding.yaml"].(os.FileInfo),
fs["/rbac/operator-role-events.yaml"].(os.FileInfo),
@@ -533,8 +533,8 @@ var assets = func() http.FileSystem {
fs["/rbac/operator-role-kubernetes.yaml"].(os.FileInfo),
fs["/rbac/operator-role-leases.yaml"].(os.FileInfo),
fs["/rbac/operator-role-openshift.yaml"].(os.FileInfo),
+ fs["/rbac/operator-role-podmonitors.yaml"].(os.FileInfo),
fs["/rbac/operator-role-service-binding.yaml"].(os.FileInfo),
- fs["/rbac/operator-role-servicemonitors.yaml"].(os.FileInfo),
fs["/rbac/operator-role-strimzi.yaml"].(os.FileInfo),
fs["/rbac/user-cluster-role.yaml"].(os.FileInfo),
fs["/rbac/user-global-kamelet-viewer-role-binding.yaml"].(os.FileInfo),
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index e705e97..fbd757f 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -83,7 +83,25 @@ func addErrorHandlerAsSource(e *Environment) error {
Language: v1.LanguageJavaSource,
Type: v1.SourceTypeErrorHandler,
}
-
+ /*
+ flowErrorHandler := map[string]interface{}{
+ "error-handler": map[string]string{
+ "ref": errorHandlerRefName,
+ },
+ }
+ encodedFlowErrorHandler, err := yaml.Marshal(flowErrorHandler)
+ if err != nil {
+ return err
+ }
+ errorHandlerSource := v1.SourceSpec{
+ DataSpec: v1.DataSpec{
+ Name: "ErrorHandlerSource.yaml",
+ Content: string(encodedFlowErrorHandler),
+ },
+ Language: v1.LanguageYaml,
+ Type: v1.SourceTypeErrorHandler,
+ }
+ */
e.Integration.Status.AddOrReplaceGeneratedSources(errorHandlerSource)
return nil
[camel-k] 02/30: doc(example): kameletbinding error handler
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 1cbec513d0304004a8a8d3b97626689c279790d4
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Mar 16 16:18:52 2021 +0100
doc(example): kameletbinding error handler
---
.../kamelets/error-handler/error-sink.kamelet.yaml | 44 ++++++++++++++++++
.../kamelet-binding-error-handler.yaml | 38 +++++++++++++++
examples/kamelets/error-handler/readme.md | 49 ++++++++++++++++++++
.../error-handler/timer-source.kamelet.yaml | 54 ++++++++++++++++++++++
4 files changed, 185 insertions(+)
diff --git a/examples/kamelets/error-handler/error-sink.kamelet.yaml b/examples/kamelets/error-handler/error-sink.kamelet.yaml
new file mode 100644
index 0000000..e35a54d
--- /dev/null
+++ b/examples/kamelets/error-handler/error-sink.kamelet.yaml
@@ -0,0 +1,44 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+
+apiVersion: camel.apache.org/v1alpha1
+kind: Kamelet
+metadata:
+ name: error-sink
+ annotations:
+ camel.apache.org/kamelet.icon: "data:image/svg+xml;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAACcBJREFUeJzt3XmsHVUdwPHva21poWGTUpAiVRQSFjWAyi5LcCmKLCEouLwQccMgGsISEkQRXMIfSKMGhQSMCCibkRIgghQEF4RIQYtG4YFsraRlb6G+1j9+94a50/fmvuW+OTN3vp9kkrnnzj3zu+/N786ZmTNnQJIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZKkfjOQOoAKGQA+DJwAvBfYCpieNKKJexk4E/h56kDUH94O3AOs76NpHfDlXv6R1Ey7ACtIv0FP1XRa7/5Uapo5wL9JvxFP9fSNXv3Bmu [...]
+ labels:
+ camel.apache.org/kamelet.type: "sink"
+spec:
+ definition:
+ title: "Error Log Sink"
+ description: "Consume events from a channel"
+ required:
+ - defaultMessage
+ properties:
+ defaultMessage:
+ title: Message
+ description: The default message to log
+ type: string
+ example: "error while checking the source"
+ flow:
+ from:
+ uri: kamelet:source
+ steps:
+ - set-body:
+ constant: "{{defaultMessage}}"
+ - to: "log:error-sink"
diff --git a/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
new file mode 100644
index 0000000..d731d1f
--- /dev/null
+++ b/examples/kamelets/error-handler/kamelet-binding-error-handler.yaml
@@ -0,0 +1,38 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+
+apiVersion: camel.apache.org/v1alpha1
+kind: KameletBinding
+metadata:
+ name: http-error-source
+spec:
+ source:
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1alpha1
+ name: timer-source
+ properties:
+ message: "Hello world!"
+ sink:
+ uri: https://log-source/failing-service
+ errorHandler:
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1alpha1
+ name: error-sink
+ properties:
+ defaultMessage: "ERROR ERROR!"
diff --git a/examples/kamelets/error-handler/readme.md b/examples/kamelets/error-handler/readme.md
new file mode 100644
index 0000000..5438050
--- /dev/null
+++ b/examples/kamelets/error-handler/readme.md
@@ -0,0 +1,49 @@
+# Kamelets Binding Error Handler example
+This example shows how to create a simple _timer-source_ `kamelet` bound to a failing sink in a `KameletBinding`. With the support of the `ErrorHandler` we will be able to redirect all errors to a `Dead Letter Channel` _error-sink_ `Kamelet`.
+
+## Timer Source Kamelet
+First of all, you must install the _timer-source_ Kamelet defined in `timer-source.kamelet.yaml` file:
+```
+$ kubectl apply -f timer-source.kamelet.yaml
+```
+You can check the newly created `kamelet` checking the list of kamelets available:
+```
+$ kubectl get kamelets
+
+NAME PHASE
+timer-source Ready
+```
+## Error Sink Kamelet
+Now it's the turn of installing the _error-sink_ Kamelet defined in `error-sink.kamelet.yaml` file:
+```
+$ kubectl apply -f error-sink.kamelet.yaml
+```
+You can check the newly created `kamelet` checking the list of kamelets available:
+```
+$ kubectl get kamelets
+
+NAME PHASE
+error-sink Ready
+timer-source Ready
+```
+## Error Handler Kamelet Binding
+We can create a `KameletBinding` which is triggered by the _timer-source_ `Kamelet` and define a fake sink URI in order to make it fail on purpose. Then we can configure an _errorHandler_ as defined in `kamelet-binding-error-handler.yaml` file:
+```
+ errorHandler:
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1alpha1
+ name: log-sink
+ properties:
+ defaultMessage: "ERROR ERROR!"
+```
+Execute the following command to start the `Integration`:
+```
+kubectl apply -f kamelet-binding-error-handler.yaml
+```
+As soon as the `Integration` starts, it will log a message error for every failure it will print:
+```
+[1] 2021-03-16 15:11:33,099 INFO [error-sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: ERROR ERROR!]
+[1] 2021-03-16 15:11:33,988 INFO [error-sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: ERROR ERROR!]
+[1] 2021-03-16 15:11:34,988 INFO [error-sink] (Camel (camel-1) thread #0 - timer://tick) Exchange[ExchangePattern: InOnly, BodyType: String, Body: ERROR ERROR!]
+```
\ No newline at end of file
diff --git a/examples/kamelets/error-handler/timer-source.kamelet.yaml b/examples/kamelets/error-handler/timer-source.kamelet.yaml
new file mode 100644
index 0000000..f837fb5
--- /dev/null
+++ b/examples/kamelets/error-handler/timer-source.kamelet.yaml
@@ -0,0 +1,54 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+
+apiVersion: camel.apache.org/v1alpha1
+kind: Kamelet
+metadata:
+ name: timer-source
+ annotations:
+ camel.apache.org/kamelet.icon: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gU3ZnIFZlY3RvciBJY29ucyA6IGh0dHA6Ly93d3cub25saW5ld2ViZm9udHMuY29tL2ljb24gLS0+DQo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm [...]
+ labels:
+ camel.apache.org/kamelet.type: "source"
+spec:
+ definition:
+ title: "Timer Source"
+ description: "Produces periodic events with a custom payload"
+ required:
+ - message
+ properties:
+ period:
+ title: Period
+ description: The interval between two events
+ type: integer
+ default: 1000
+ message:
+ title: Message
+ description: The message to generate
+ type: string
+ example: "hello world"
+ types:
+ out:
+ mediaType: text/plain
+ flow:
+ from:
+ uri: timer:tick
+ parameters:
+ period: "{{period}}"
+ steps:
+ - set-body:
+ constant: "{{message}}"
+ - to: "kamelet:sink"
[camel-k] 09/30: refactor(trait): error handler kamelet
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 3b8ae4a22a6dbcca65c2bfd4f580020990c02b4b
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Apr 21 10:15:17 2021 +0200
refactor(trait): error handler kamelet
Just look for a possible error handler kamelet, it it was configured
---
pkg/controller/kameletbinding/common.go | 22 +++++++---
pkg/trait/kamelets.go | 78 ++++++++++++++-------------------
2 files changed, 48 insertions(+), 52 deletions(-)
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index 13e13fe..06b5b76 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -80,13 +80,18 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
return nil, errors.Wrap(err, "could not determine sink URI")
}
var errorHandler *bindings.Binding
- if kameletbinding.Spec.ErrorHandler.Endpoint.Ref != nil || kameletbinding.Spec.ErrorHandler.Endpoint.URI != nil {
- errorHandler, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler.Endpoint)
- if err != nil {
- return nil, errors.Wrap(err, "could not determine error handler URI")
+ if kameletbinding.Spec.ErrorHandler.Type != "" {
+ errorHandlerURI := ""
+ if kameletbinding.Spec.ErrorHandler.Endpoint.Ref != nil || kameletbinding.Spec.ErrorHandler.Endpoint.URI != nil {
+ errorHandler, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, kameletbinding.Spec.ErrorHandler.Endpoint)
+ if err != nil {
+ return nil, errors.Wrap(err, "could not determine error handler URI")
+ }
+
+ errorHandlerURI = errorHandler.URI
}
- err = setIntegrationErrorHandler(&it.Spec, errorHandler, kameletbinding.Spec.ErrorHandler)
+ err = setIntegrationErrorHandler(&it.Spec, errorHandlerURI, kameletbinding.Spec.ErrorHandler)
if err != nil {
return nil, errors.Wrap(err, "could not set integration error handler")
}
@@ -159,12 +164,15 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *
return &it, nil
}
-func setIntegrationErrorHandler(it *v1.IntegrationSpec, errorHandler *bindings.Binding, errorHandlerSpec v1alpha1.ErrorHandler) error {
+func setIntegrationErrorHandler(it *v1.IntegrationSpec, errorHandlerURI string, errorHandlerSpec v1alpha1.ErrorHandler) error {
it.ErrorHandler = v1.ErrorHandlerSpec{
- URI: errorHandler.URI,
Type: string(errorHandlerSpec.Type),
}
+ if errorHandlerURI != "" {
+ it.ErrorHandler.URI = errorHandlerURI
+ }
+
return nil
}
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index 190c17e..57ec4b5 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -105,7 +105,6 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
util.StringSliceUniqueConcat(&kamelets, extractKamelets(meta.ToURIs))
return true
})
- sort.Strings(kamelets)
}
// Check if a Kamelet is configured as default error handler
if e.Integration.Spec.ErrorHandler.URI != "" {
@@ -114,21 +113,24 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) {
}
}
- t.List = strings.Join(kamelets, ",")
+ if len(kamelets) > 0 {
+ sort.Strings(kamelets)
+ t.List = strings.Join(kamelets, ",")
+ }
}
- return t.declaredKamelets(), nil
-}
-
-func (t *kameletsTrait) declaredKamelets() bool {
- return len(t.getKameletKeys()) > 0
+ return len(t.getKameletKeys()) > 0, nil
}
func (t *kameletsTrait) Apply(e *Environment) error {
<<<<<<< HEAD
+<<<<<<< HEAD
if e.IntegrationInPhase(v1.IntegrationPhaseInitialization, v1.IntegrationPhaseRunning) {
=======
+=======
+
+>>>>>>> refactor(trait): error handler kamelet
if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
>>>>>>> refactor(trait): integration error handler spec
if err := t.addKamelets(e); err != nil {
@@ -146,52 +148,41 @@ func (t *kameletsTrait) Apply(e *Environment) error {
}
func (t *kameletsTrait) addKamelets(e *Environment) error {
- if t.declaredKamelets() {
+ kameletKeys := t.getKameletKeys()
+ if len(kameletKeys) > 0 {
repo, err := repository.NewForPlatform(e.C, e.Client, e.Platform, e.Integration.Namespace, platform.GetOperatorNamespace())
if err != nil {
return err
}
-
- // Declared kamelets
for _, k := range t.getKameletKeys() {
- err := initializeKamelet(repo, e, k, t, v1.SourceTypeTemplate)
+ kamelet, err := repo.Get(e.C, k)
if err != nil {
return err
}
- }
-
- // resort dependencies
- sort.Strings(e.Integration.Status.Dependencies)
- }
- return nil
-}
+ if kamelet == nil {
+ return fmt.Errorf("kamelet %s not found in any of the defined repositories: %s", k, repo.String())
+ }
-func initializeKamelet(repo repository.KameletRepository, e *Environment, k string, t *kameletsTrait, sourceType v1.SourceType) error {
- kamelet, err := repo.Get(e.C, k)
- if err != nil {
- return err
- }
- if kamelet == nil {
- return fmt.Errorf("kamelet %s not found in any of the defined repositories: %s", k, repo.String())
- }
+ // Initialize remote kamelets
+ kamelet, err = kameletutils.Initialize(kamelet)
+ if err != nil {
+ return err
+ }
- // Initialize remote kamelets
- kamelet, err = kameletutils.Initialize(kamelet)
- if err != nil {
- return err
- }
+ if kamelet.Status.Phase != v1alpha1.KameletPhaseReady {
+ return fmt.Errorf("kamelet %q is not %s: %s", k, v1alpha1.KameletPhaseReady, kamelet.Status.Phase)
+ }
- if kamelet.Status.Phase != v1alpha1.KameletPhaseReady {
- return fmt.Errorf("kamelet %q is not %s: %s", k, v1alpha1.KameletPhaseReady, kamelet.Status.Phase)
- }
+ if err := t.addKameletAsSource(e, kamelet); err != nil {
+ return err
+ }
- if err := t.addKameletAsSource(e, kamelet, sourceType); err != nil {
- return err
+ // Adding dependencies from Kamelets
+ util.StringSliceUniqueConcat(&e.Integration.Status.Dependencies, kamelet.Spec.Dependencies)
+ }
+ // resort dependencies
+ sort.Strings(e.Integration.Status.Dependencies)
}
-
- // Adding dependencies from Kamelets
- util.StringSliceUniqueConcat(&e.Integration.Status.Dependencies, kamelet.Spec.Dependencies)
-
return nil
}
@@ -239,7 +230,7 @@ func (t *kameletsTrait) configureApplicationProperties(e *Environment) error {
return nil
}
-func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kamelet, sourceType v1.SourceType) error {
+func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kamelet) error {
sources := make([]v1.SourceSpec, 0)
if kamelet.Spec.Flow != nil {
@@ -260,7 +251,7 @@ func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kam
Content: string(flowData),
},
Language: v1.LanguageYaml,
- Type: sourceType,
+ Type: v1.SourceTypeTemplate,
PropertyNames: propertyNames,
}
flowSource, err = integrationSourceFromKameletSource(e, kamelet, flowSource, fmt.Sprintf("%s-kamelet-%s-flow", e.Integration.Name, kamelet.Name))
@@ -271,9 +262,6 @@ func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kam
}
for idx, s := range kamelet.Spec.Sources {
- if sourceType == v1.SourceTypeErrorHandler {
- s.Type = sourceType
- }
intSource, err := integrationSourceFromKameletSource(e, kamelet, s, fmt.Sprintf("%s-kamelet-%s-%03d", e.Integration.Name, kamelet.Name, idx))
if err != nil {
return err
[camel-k] 12/30: doc(trait): error-handler generated doc
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 0aae94245ba436fb6a8cda3765bb7bbfa435fb0f
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Wed Apr 21 16:12:32 2021 +0200
doc(trait): error-handler generated doc
---
deploy/traits.yaml | 9 ++++++++
docs/modules/ROOT/nav.adoc | 1 +
docs/modules/traits/pages/error-handler.adoc | 32 ++++++++++++++++++++++++++++
pkg/trait/error_handler.go | 5 ++---
pkg/trait/trait_test.go | 2 +-
5 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/deploy/traits.yaml b/deploy/traits.yaml
index 75522d2..0c567dd 100755
--- a/deploy/traits.yaml
+++ b/deploy/traits.yaml
@@ -271,6 +271,15 @@ traits:
type: bool
description: Enables injection of `NAMESPACE` and `POD_NAME` environment variables
(default `true`)
+- name: error-handler
+ platform: true
+ profiles:
+ - Kubernetes
+ - Knative
+ - OpenShift
+ description: The error-handler is a platform trait used to inject Error Handler
+ source into the integration runtime.
+ properties: []
- name: gc
platform: false
profiles:
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index ea9558a..e3d322e 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -41,6 +41,7 @@
** xref:traits:deployer.adoc[Deployer]
** xref:traits:deployment.adoc[Deployment]
** xref:traits:environment.adoc[Environment]
+** xref:traits:error-handler.adoc[Error Handler]
** xref:traits:gc.adoc[Gc]
** xref:traits:ingress.adoc[Ingress]
** xref:traits:istio.adoc[Istio]
diff --git a/docs/modules/traits/pages/error-handler.adoc b/docs/modules/traits/pages/error-handler.adoc
new file mode 100755
index 0000000..0c38c7d
--- /dev/null
+++ b/docs/modules/traits/pages/error-handler.adoc
@@ -0,0 +1,32 @@
+= Error Handler Trait
+
+// Start of autogenerated code - DO NOT EDIT! (description)
+The error-handler is a platform trait used to inject Error Handler source into the integration runtime.
+
+
+This trait is available in the following profiles: **Kubernetes, Knative, OpenShift**.
+
+WARNING: The error-handler trait is a *platform trait*: disabling it may compromise the platform functionality.
+
+// End of autogenerated code - DO NOT EDIT! (description)
+// Start of autogenerated code - DO NOT EDIT! (configuration)
+== Configuration
+
+Trait properties can be specified when running any integration with the CLI:
+[source,console]
+----
+$ kamel run --trait error-handler.[key]=[value] integration.groovy
+----
+The following configuration options are available:
+
+[cols="2m,1m,5a"]
+|===
+|Property | Type | Description
+
+| error-handler.enabled
+| bool
+| Can be used to enable or disable a trait. All traits share this common property.
+
+|===
+
+// End of autogenerated code - DO NOT EDIT! (configuration)
diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go
index 228ed12..ef93d67 100644
--- a/pkg/trait/error_handler.go
+++ b/pkg/trait/error_handler.go
@@ -23,17 +23,16 @@ import (
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
)
-// The error handler is a platform trait used to inject Error Handler source into the integration runtime.
+// The error-handler is a platform trait used to inject Error Handler source into the integration runtime.
//
// +camel-k:trait=error-handler
type errorHandlerTrait struct {
BaseTrait `property:",squash"`
- Auto *bool `property:"auto"`
}
func newErrorHandlerTrait() Trait {
return &errorHandlerTrait{
- BaseTrait: NewBaseTrait("errorHandler", 500),
+ BaseTrait: NewBaseTrait("error-handler", 500),
}
}
diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go
index b8fdca8..e1bea3b 100644
--- a/pkg/trait/trait_test.go
+++ b/pkg/trait/trait_test.go
@@ -507,7 +507,7 @@ func TestOnlySomeTraitsInfluenceBuild(t *testing.T) {
func TestOnlySomeTraitsArePlatform(t *testing.T) {
c := NewTraitTestCatalog()
- platformTraits := []string{"builder", "camel", "jvm", "container", "dependencies", "deployer", "deployment", "environment", "errorHandler", "kamelets", "openapi", "owner", "platform", "quarkus"}
+ platformTraits := []string{"builder", "camel", "jvm", "container", "dependencies", "deployer", "deployment", "environment", "error-handler", "kamelets", "openapi", "owner", "platform", "quarkus"}
for _, trait := range c.allTraits() {
if trait.IsPlatformTrait() {
[camel-k] 27/30: doc(kamelets): kamelet bindings error handler
Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 8f9108672e1854357404c62295917258a34af581
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Apr 27 14:55:20 2021 +0200
doc(kamelets): kamelet bindings error handler
---
.../kamelets/kameletbindings-error-handler.adoc | 156 +++++++++++++++++++++
.../modules/ROOT/pages/kamelets/kamelets-user.adoc | 4 +
docs/modules/ROOT/pages/kamelets/kamelets.adoc | 1 +
pkg/resources/resources.go | 14 +-
4 files changed, 168 insertions(+), 7 deletions(-)
diff --git a/docs/modules/ROOT/pages/kamelets/kameletbindings-error-handler.adoc b/docs/modules/ROOT/pages/kamelets/kameletbindings-error-handler.adoc
new file mode 100644
index 0000000..fe3f1ce
--- /dev/null
+++ b/docs/modules/ROOT/pages/kamelets/kameletbindings-error-handler.adoc
@@ -0,0 +1,156 @@
+[[kameletbindings-error-handler]]
+= Kamelet Bindings Error Handler
+
+`Kamelet Binding`s offer a mechanism to specify an error policy to adopt in case an event produced by a `source` or consumed by a `sink`. Through the definition of an `errorHandler` you will be able to apply certain logic to the failing event, such as simply logging, ignoring the event or posting the event to a `Dead Letter Channel`.
+
+[source,yaml]
+----
+apiVersion: camel.apache.org/v1alpha1
+kind: KameletBinding
+metadata:
+ name: my-kamelet-binding
+spec:
+ source: # <1>
+...
+ sink: # <2>
+...
+ errorHandler: # <3>
+----
+<1> Reference to the source that provides data
+<2> Reference to the sink where data should be sent to
+<3> Error Handler Configuration
+
+[[kameletbindings-error-handler-types]]
+== Error Handler Types
+
+We have different types of error handler: `ǹone`, `log`, `dead-letter-channel`, `bean`, `ref`. The `errorHandler` parameter is optional. The runtime will use the configuration to create an https://camel.apache.org/manual/latest/error-handler.html[Error Handler] as specified by Apache Camel.
+
+[[kameletbindings-error-handler-none]]
+=== No error handler
+
+There may be certain cases where you want to just ignore any failure happening on your integration. In this situation just use a `ǹone` error handler. Under the hood the configuration will create a https://camel.apache.org/manual/latest/error-handler.html#ErrorHandler-NoErrorHandler[`No` error handler builder].
+
+[source,yaml]
+----
+apiVersion: camel.apache.org/v1alpha1
+kind: KameletBinding
+metadata:
+ name: my-kamelet-binding
+spec:
+ source:
+...
+ sink:
+...
+ errorHandler:
+ none: # <1>
+----
+<1> `none` error handler does not expect any configuration
+
+[[kameletbindings-error-handler-log]]
+=== Log error handler
+
+Apache Camel offers a default behavior for handling any failure: log to standard output. However you can use the `log` error handler to specify other behaviors such as redelivery or delay policy. Under the hood the configuration will create a https://camel.apache.org/manual/latest/error-handler.html#_defaulterrorhandler[`Default` error handler builder].
+
+
+[source,yaml]
+----
+apiVersion: camel.apache.org/v1alpha1
+kind: KameletBinding
+metadata:
+ name: my-kamelet-binding
+spec:
+ source:
+...
+ sink:
+...
+ errorHandler:
+ log:
+ parameters: # <1>
+ maximumRedeliveries: 3
+ redeliveryDelay: 2000
+----
+<1> Parameters belonging to the `log` error handler type
+
+[[kameletbindings-error-handler-dlc]]
+=== Dead Letter Channel error handler
+
+The `Dead Letter Channel` is probably the most interesting error handler type as it allows you to redirect any failing event to any other component, such as a third party URI, a queue or even another `Kamelet` which will be performing certain logic with the failing event. Under the hood the configuration will create a https://camel.apache.org/manual/latest/error-handler.html#_dead_letter_channel[`Dead Letter Channel` error handler builder].
+
+[source,yaml]
+----
+apiVersion: camel.apache.org/v1alpha1
+kind: KameletBinding
+metadata:
+ name: my-kamelet-binding
+spec:
+ source:
+...
+ sink:
+...
+ errorHandler:
+ dead-letter-channel:
+ endpoint:
+ ref: # <1>
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1alpha1
+ name: error-handler
+ properties:
+ message: "ERROR!" # <2>
+ ...
+ parameters:
+ maximumRedeliveries: 1 # <3>
+ ...
+----
+<1> You can use `ref` or `uri`. `ref` will be interpreted by the operator according the `kind`, `apiVersion` and `name`. You can use any `Kamelet`, `KafkaTopic` channel or `Knative` destination.
+<2> Properties belonging to the endpoint (in this example, to the `Kamelet` named error handler)
+<3> Parameters belonging to the `dead-letter-channel` error handler type
+
+[[kameletbindings-error-handler-bean]]
+=== Bean error handler
+
+With the `Bean` error handler you can extend the functionality of the Error Handler by providing a custom bean to be used as Error Handler.
+
+[source,yaml]
+----
+apiVersion: camel.apache.org/v1alpha1
+kind: KameletBinding
+metadata:
+ name: my-kamelet-binding
+spec:
+ source:
+...
+ sink:
+...
+ errorHandler:
+ bean:
+ type: "org.apache.camel.builder.DeadLetterChannelBuilder" # <1>
+ properties: # <2>
+ deadLetterUri: log:error
+ ...
+----
+<1> Fully qualified name of the ErrorHandlerBuilder
+<2> Properties expected by your type
+
+[[kameletbindings-error-handler-ref]]
+=== Ref error handler
+
+With the `Ref` error handler you can use any `Bean` that is expected to be found in the Camel registry at runtime.
+
+[source,yaml]
+----
+apiVersion: camel.apache.org/v1alpha1
+kind: KameletBinding
+metadata:
+ name: my-kamelet-binding
+spec:
+ source:
+...
+ sink:
+...
+ errorHandler:
+ ref: my-custom-builder # <1>
+...
+----
+<1> The name of the bean to be looked up at runtime
+
+NOTE: make sure to have the `ref` correctly bind at runtime.
\ No newline at end of file
diff --git a/docs/modules/ROOT/pages/kamelets/kamelets-user.adoc b/docs/modules/ROOT/pages/kamelets/kamelets-user.adoc
index 4a334cb..ef48761 100644
--- a/docs/modules/ROOT/pages/kamelets/kamelets-user.adoc
+++ b/docs/modules/ROOT/pages/kamelets/kamelets-user.adoc
@@ -356,6 +356,10 @@ This KameletBinding explicitly defines an URI where data is going to be pushed.
NOTE: the `uri` option is also conventionally used in Knative to specify a non-kubernetes destination.
To comply with the Knative specifications, in case an "http" or "https" URI is used, Camel will send https://cloudevents.io/[CloudEvents] to the destination.
+=== Error Handling
+
+You can configure an error handler in order to specify what to do when some event ends up with failure. See xref:kamelets/kameletbindings-error-handler.adoc[Kamelet Bindings Error Handler User Guide] for more detail.
+
[[kamelets-specification]]
== Kamelet Specification
diff --git a/docs/modules/ROOT/pages/kamelets/kamelets.adoc b/docs/modules/ROOT/pages/kamelets/kamelets.adoc
index 6ba3ff5..c0d0327 100644
--- a/docs/modules/ROOT/pages/kamelets/kamelets.adoc
+++ b/docs/modules/ROOT/pages/kamelets/kamelets.adoc
@@ -4,4 +4,5 @@
This section of the documentation contains information about Kamelets from both a user and a developer point of view:
- The xref:kamelets/kamelets-user.adoc[Kamelets User Guide] is for users that want to use Kamelets for connecting systems with their applications
+- The xref:kamelets/kameletbindings-error-handler.adoc[Kamelet Bindings Error Handler User Guide] explains how to configure an error handler on a `Kamelet Binding`
- The xref:kamelets/kamelets-dev.adoc[Kamelets Developer Guide] is a reference for developers that want to create new Kamelets and share them with users
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 9f43b93..94a6ac4 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -106,16 +106,16 @@ var assets = func() http.FileSystem {
"/crd/bases/camel.apache.org_integrations.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_integrations.yaml",
modTime: time.Time{},
- uncompressedSize: 24066,
+ uncompressedSize: 23405,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3c\x5d\x73\xe3\xb8\x91\xef\xfa\x15\x5d\xf6\xc3\xec\x56\x49\x54\x66\x26\xa9\xbb\xf2\x3d\x79\x3d\x33\x17\xdd\x78\x6d\x97\xe5\xc9\xd6\x56\x2a\x0f\x10\xd9\x12\x11\x83\x00\x0f\x00\x25\x2b\xa9\xfc\xf7\xab\x6e\x90\x14\x29\x91\xb4\xc6\x9e\xdd\xcd\x25\xe2\xcb\x8c\x49\xa0\xd1\xdf\x5f\x00\x74\x0e\x93\x6f\xf7\x8c\xce\xe1\x5a\xc6\xa8\x1d\x26\xe0\x0d\xf8\x14\xe1\x32\x17\x71\x8a\x30\x37\x4b\xbf\x11\x16\xe1\x93\x29\x74\x22\xbc\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3c\x5d\x73\xdb\xba\x95\xef\xfa\x15\x67\xec\x87\xdc\xcc\x48\x54\x93\xb4\xb3\x3b\xde\x27\xd7\x89\x77\xb5\xf1\xb5\x33\x96\xd3\x3b\x77\x3a\x7d\x80\xc8\x43\x0a\x35\x08\x70\x01\xd0\xb2\xda\xe9\x7f\xdf\x39\x07\x24\x45\x4a\xa4\xac\xc8\xb9\xf7\x76\xbb\xe2\x4b\x62\x12\x38\x38\xdf\x5f\x00\x74\x0e\x93\xef\xf7\x8c\xce\xe1\x46\xc6\xa8\x1d\x26\xe0\x0d\xf8\x25\xc2\x65\x21\xe2\x25\xc2\xdc\xa4\x7e\x25\x2c\xc2\xb5\x29\x75\x22\xbc\x [...]
},
"/crd/bases/camel.apache.org_kameletbindings.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_kameletbindings.yaml",
modTime: time.Time{},
- uncompressedSize: 56150,
+ uncompressedSize: 55181,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xf1\x6f\xdb\x38\xf2\xef\xef\xf9\x2b\x06\xc9\x01\x6d\x81\x48\x8e\x93\xb4\xbb\xeb\xf7\x43\x91\x26\xdb\xfb\xfa\xb5\x9b\x06\x49\x7a\x87\x7b\x6d\x0f\xa0\xa5\xb1\xcd\x8b\x44\xea\x48\x2a\x8e\xdf\xb6\xff\xfb\x17\x24\x25\x59\x76\x2c\x89\x72\xec\x6e\x0b\x88\x40\xd1\xd8\xa6\x86\x33\xc3\x99\xe1\x70\xc8\x8f\x7d\x00\xde\xf6\xda\xde\x01\xbc\xa7\x01\x32\x89\x21\x28\x0e\x6a\x8a\x70\x96\x90\x60\x8a\x70\xc3\xc7\x6a\x46\x04\xc2\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\xf1\x6f\xdb\x38\xf2\xef\xef\xf9\x2b\x06\xc9\x01\x6d\x01\x4b\x8e\xe3\xb4\xbb\xeb\xf7\x43\x91\x26\xdb\x7b\x7e\xed\xa6\x45\x92\xde\xe1\x5e\xdb\x03\x68\x69\x6c\xf3\x22\x91\x3a\x92\x8a\xe3\xef\xb6\xff\xfb\x17\x24\x25\x59\x76\x2c\x99\x72\xec\x6e\x0a\x88\xc0\x62\x6b\x8b\x1a\xce\x0c\x87\xc3\x99\x21\x3f\xce\x11\x78\xbb\x6b\x07\x47\xf0\x9e\x06\xc8\x24\x86\xa0\x38\xa8\x29\xc2\x59\x42\x82\x29\xc2\x35\x1f\xab\x19\x11\x08\x [...]
},
"/crd/bases/camel.apache.org_kamelets.yaml": &vfsgen۰CompressedFileInfo{
name: "camel.apache.org_kamelets.yaml",
@@ -144,7 +144,7 @@ var assets = func() http.FileSystem {
modTime: time.Time{},
uncompressedSize: 2397,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x55\xc1\x6e\xe3\x36\x10\xbd\xeb\x2b\x1e\xac\xcb\x2e\x10\xdb\xc9\x02\x05\x16\xea\x49\x4d\x9c\xc6\x68\x6a\x1b\x96\xb7\xc1\x9e\x0a\x9a\x1a\x4b\x44\x28\x8e\x4a\x52\xf6\xaa\x5f\x5f\x50\xb6\x1c\xdb\x9b\xa6\x3d\x04\x58\x9e\x2c\xcd\xcc\x9b\xf7\x66\x9e\xe8\x18\xc3\xf7\x3b\x51\x8c\x47\x25\xc9\x38\xca\xe1\x19\xbe\x24\xa4\xb5\x90\x25\x21\xe3\x8d\xdf\x09\x4b\xb8\xe7\xc6\xe4\xc2\x2b\x36\xf8\x90\x66\xf7\x1f\xd1\x98\x9c\x2c\xd8\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x55\xc1\x6e\xe3\x36\x10\xbd\xeb\x2b\x1e\xac\xcb\x2e\x10\xdb\xc9\xa2\x87\x85\x7a\x52\x13\xa7\x31\x9a\xda\x86\xe5\x6d\xb0\xa7\x82\xa6\xc6\x12\x11\x8a\xa3\x92\x94\xbd\xea\xd7\x17\x94\x2d\xc7\xf6\xa6\x69\x0f\x01\x96\x27\x4b\x33\xf3\xe6\xbd\x99\x27\x3a\xc6\xf0\xfd\x4e\x14\xe3\x51\x49\x32\x8e\x72\x78\x86\x2f\x09\x69\x2d\x64\x49\xc8\x78\xe3\x77\xc2\x12\xee\xb9\x31\xb9\xf0\x8a\x0d\x3e\xa4\xd9\xfd\x47\x34\x26\x27\x0b\x36\x [...]
},
"/manager/operator-service-account.yaml": &vfsgen۰CompressedFileInfo{
name: "operator-service-account.yaml",
@@ -467,9 +467,9 @@ var assets = func() http.FileSystem {
"/traits.yaml": &vfsgen۰CompressedFileInfo{
name: "traits.yaml",
modTime: time.Time{},
- uncompressedSize: 36976,
+ uncompressedSize: 36744,
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6d\x73\x1c\xb7\xd1\xe0\x77\xfd\x0a\x14\x9f\xab\xe2\x4b\xed\x0c\x29\xa7\x9c\xf8\xf6\x4e\x97\xa2\x25\x25\xa1\x6d\x49\x3c\x51\x71\xea\x4a\xa7\xca\x62\x67\x7a\x77\x21\x62\x80\x09\x80\x21\xb5\xb9\xba\xff\x7e\x85\x6e\x00\x83\xd9\x1d\x2e\x97\xb2\xe9\x32\xaf\x9e\xe4\x83\x45\x72\xa6\xd1\x68\x34\xfa\xbd\x7b\x9c\xe1\xc2\xd9\xe9\xb3\x82\x29\xde\xc0\x94\xf1\xc5\x42\x28\xe1\xd6\xcf\x18\x6b\x25\x77\x0b\x6d\x9a\x29\x5b\x70\x [...]
+ compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6d\x73\x1c\xb7\xd1\xe0\x77\xfd\x0a\x14\x9f\xab\xe2\x4b\xed\x0e\x29\xa7\x9c\xf8\xf6\x4e\x97\xa2\x25\x25\xa1\x6d\x49\x3c\x51\x71\xea\x4a\xa7\xca\x62\x67\x7a\x77\x21\x62\x80\x09\x80\x59\x6a\x73\x75\xff\xfd\x0a\xdd\x00\x06\x33\x3b\x24\x97\xb2\xe9\x32\xaf\x9e\xe4\x83\x45\x72\xa6\xd1\x68\x34\xfa\xbd\x7b\x9c\xe1\xc2\xd9\xd9\xb3\x29\x53\xbc\x86\x19\xe3\xcb\xa5\x50\xc2\x6d\x9f\x31\xd6\x48\xee\x96\xda\xd4\x33\xb6\xe4\x [...]
},
}
fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{