Skip to content

Commit

Permalink
feat(ctrl): leverage core error handler vs trait
Browse files Browse the repository at this point in the history
* Trait was internal and it is removed as no longer needed
  • Loading branch information
squakez committed Jan 19, 2025
1 parent 09ddabc commit 0d523af
Show file tree
Hide file tree
Showing 15 changed files with 156 additions and 331 deletions.
2 changes: 2 additions & 0 deletions docs/modules/ROOT/partials/apis/camel-k-crds.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7030,6 +7030,8 @@ These take precedence over any previously defined environment variables.
* <<#_camel_apache_org_v1_Traits, Traits>>
WARNING: This trait is no longer in use.
The error-handler is a platform trait used to inject Error Handler source into the integration runtime.
Expand Down
49 changes: 0 additions & 49 deletions e2e/common/traits/error_handler_test.go

This file was deleted.

9 changes: 0 additions & 9 deletions pkg/apis/camel/v1/error_handler_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@ limitations under the License.

package v1

const (
// ErrorHandlerRefName the reference name to use when looking for an error handler.
ErrorHandlerRefName = "camel.k.errorHandler.ref"
// ErrorHandlerRefDefaultName the default name of the error handler.
ErrorHandlerRefDefaultName = "defaultErrorHandler"
// ErrorHandlerAppPropertiesPrefix the prefix used for the error handler bean.
ErrorHandlerAppPropertiesPrefix = "camel.beans.defaultErrorHandler"
)

// ErrorHandlerSpec represents an unstructured object for an error handler.
type ErrorHandlerSpec struct {
RawMessage `json:",inline,omitempty"`
Expand Down
11 changes: 1 addition & 10 deletions pkg/apis/camel/v1/error_handler_types_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,7 @@ 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",
ErrorHandlerRefName: ErrorHandlerRefDefaultName,
}, nil
return map[string]interface{}{}, nil
}

// ErrorHandlerLog represent a default (log) error handler type.
Expand All @@ -91,17 +88,12 @@ func (e ErrorHandlerLog) Configuration() (map[string]interface{}, error) {
if err != nil {
return nil, err
}
properties[ErrorHandlerAppPropertiesPrefix] = "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder"

if e.Parameters != nil {
var parameters map[string]interface{}
err := json.Unmarshal(e.Parameters.RawMessage, &parameters)
if err != nil {
return nil, err
}
for key, value := range parameters {
properties[ErrorHandlerAppPropertiesPrefix+"."+key] = value
}
}

return properties, nil
Expand Down Expand Up @@ -129,7 +121,6 @@ func (e ErrorHandlerSink) Configuration() (map[string]interface{}, error) {
if err != nil {
return nil, err
}
properties[ErrorHandlerAppPropertiesPrefix] = "#class:org.apache.camel.builder.DeadLetterChannelBuilder"

return properties, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/camel/v1/integration_types_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ func ToYamlDSL(flows []Flow) ([]byte, error) {
if err != nil {
return nil, err
}
jsondata := make([]map[string]interface{}, 0)
var jsondata interface{}
d := json.NewDecoder(bytes.NewReader(data))
d.UseNumber()
if err := d.Decode(&jsondata); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/camel/v1/trait/error_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.

package trait

// WARNING: This trait is no longer in use.
//
// The error-handler is a platform trait used to inject Error Handler source into the integration runtime.
//
// +camel-k:trait=error-handler.
Expand Down
42 changes: 38 additions & 4 deletions pkg/controller/pipe/error_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ import (
"github.com/apache/camel-k/v2/pkg/util/bindings"
)

const defaultCamelErrorHandler = "defaultErrorHandler"

// maybeErrorHandler will return a Binding mapping a DeadLetterChannel, a Log or a None Error Handler.
// If the bindings has no URI, then, you can assume it's a none Error Handler.
func maybeErrorHandler(errHandlConf *v1.ErrorHandlerSpec, bindingContext bindings.BindingContext) (*bindings.Binding, error) {
if errHandlConf == nil {
return nil, nil
Expand All @@ -39,7 +43,11 @@ func maybeErrorHandler(errHandlConf *v1.ErrorHandlerSpec, bindingContext binding
}
// We need to get the translated URI from any referenced resource (ie, kamelets)
if errorHandlerSpec.Type() == v1.ErrorHandlerTypeSink {
errorHandlerBinding, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1.EndpointTypeErrorHandler}, *errorHandlerSpec.Endpoint())
errorHandlerBinding, err = bindings.Translate(
bindingContext,
bindings.EndpointContext{Type: v1.EndpointTypeErrorHandler},
*errorHandlerSpec.Endpoint(),
)
if err != nil {
return nil, fmt.Errorf("could not determine error handler URI: %w", err)
}
Expand All @@ -48,6 +56,9 @@ func maybeErrorHandler(errHandlConf *v1.ErrorHandlerSpec, bindingContext binding
errorHandlerBinding = &bindings.Binding{
ApplicationProperties: make(map[string]string),
}
if errorHandlerSpec.Type() == v1.ErrorHandlerTypeLog {
errorHandlerBinding.URI = defaultCamelErrorHandler
}
}

err = setErrorHandlerConfiguration(errorHandlerBinding, errorHandlerSpec)
Expand Down Expand Up @@ -106,8 +117,31 @@ func setErrorHandlerConfiguration(errorHandlerBinding *bindings.Binding, errorHa
for key, value := range properties {
errorHandlerBinding.ApplicationProperties[key] = fmt.Sprintf("%v", value)
}
if errorHandler.Type() == v1.ErrorHandlerTypeSink && errorHandlerBinding.URI != "" {
errorHandlerBinding.ApplicationProperties[fmt.Sprintf("%s.deadLetterUri", v1.ErrorHandlerAppPropertiesPrefix)] = errorHandlerBinding.URI
}

return nil
}

// translateCamelErrorHandler will translate a binding as an error handler YAML as expected by Camel.
func translateCamelErrorHandler(b *bindings.Binding) map[string]interface{} {
yamlCode := map[string]interface{}{}
switch b.URI {
case "":
yamlCode["errorHandler"] = map[string]interface{}{
"noErrorHandler": map[string]interface{}{},
}
case defaultCamelErrorHandler:
yamlCode["errorHandler"] = map[string]interface{}{
"defaultErrorHandler": map[string]interface{}{
"logName": "err",
},
}
default:
yamlCode["errorHandler"] = map[string]interface{}{
"deadLetterChannel": map[string]interface{}{
"deadLetterUri": b.URI,
},
}
}

return yamlCode
}
24 changes: 5 additions & 19 deletions pkg/controller/pipe/error_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@ func TestParseErrorHandlerNoneDoesSucceed(t *testing.T) {
)
require.NoError(t, err)
assert.Equal(t, v1.ErrorHandlerTypeNone, noErrorHandler.Type())
parameters, err := noErrorHandler.Configuration()
_, err = noErrorHandler.Configuration()
require.NoError(t, err)
assert.Equal(t, "#class:org.apache.camel.builder.NoErrorHandlerBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix])
assert.Equal(t, v1.ErrorHandlerRefDefaultName, parameters[v1.ErrorHandlerRefName])
}

func TestParseErrorHandlerLogDoesSucceed(t *testing.T) {
Expand All @@ -43,10 +41,8 @@ func TestParseErrorHandlerLogDoesSucceed(t *testing.T) {
)
require.NoError(t, err)
assert.Equal(t, v1.ErrorHandlerTypeLog, logErrorHandler.Type())
parameters, err := logErrorHandler.Configuration()
_, err = logErrorHandler.Configuration()
require.NoError(t, err)
assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix])
assert.Equal(t, v1.ErrorHandlerRefDefaultName, parameters[v1.ErrorHandlerRefName])
}

func TestParseErrorHandlerLogWithParametersDoesSucceed(t *testing.T) {
Expand All @@ -55,12 +51,8 @@ func TestParseErrorHandlerLogWithParametersDoesSucceed(t *testing.T) {
)
require.NoError(t, err)
assert.Equal(t, v1.ErrorHandlerTypeLog, logErrorHandler.Type())
parameters, err := logErrorHandler.Configuration()
_, err = logErrorHandler.Configuration()
require.NoError(t, err)
assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix])
assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"])
assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.param2"])
assert.Equal(t, v1.ErrorHandlerRefDefaultName, parameters[v1.ErrorHandlerRefName])
}

func TestParseErrorHandlerSinkDoesSucceed(t *testing.T) {
Expand All @@ -71,10 +63,8 @@ func TestParseErrorHandlerSinkDoesSucceed(t *testing.T) {
assert.NotNil(t, sinkErrorHandler)
assert.Equal(t, v1.ErrorHandlerTypeSink, sinkErrorHandler.Type())
assert.Equal(t, "someUri", *sinkErrorHandler.Endpoint().URI)
parameters, err := sinkErrorHandler.Configuration()
_, err = sinkErrorHandler.Configuration()
require.NoError(t, err)
assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix])
assert.Equal(t, v1.ErrorHandlerRefDefaultName, parameters[v1.ErrorHandlerRefName])
}

func TestParseErrorHandlerSinkWithParametersDoesSucceed(t *testing.T) {
Expand All @@ -93,12 +83,8 @@ func TestParseErrorHandlerSinkWithParametersDoesSucceed(t *testing.T) {
assert.NotNil(t, sinkErrorHandler)
assert.Equal(t, v1.ErrorHandlerTypeSink, sinkErrorHandler.Type())
assert.Equal(t, "someUri", *sinkErrorHandler.Endpoint().URI)
parameters, err := sinkErrorHandler.Configuration()
_, err = sinkErrorHandler.Configuration()
require.NoError(t, err)
assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix])
assert.Equal(t, v1.ErrorHandlerRefDefaultName, parameters[v1.ErrorHandlerRefName])
assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"])
assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.param2"])
}

func TestParseErrorHandlerSinkFail(t *testing.T) {
Expand Down
11 changes: 11 additions & 0 deletions pkg/controller/pipe/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,21 @@ func CreateIntegrationFor(ctx context.Context, c client.Client, binding *v1.Pipe
"from": fromWrapper,
},
}

if errorHandler != nil {
eh := translateCamelErrorHandler(errorHandler)
encodedErrorHandler, err := json.Marshal(eh)
if err != nil {
return nil, err
}
it.Spec.Flows = append(it.Spec.Flows, v1.Flow{RawMessage: encodedErrorHandler})
}

encodedRoute, err := json.Marshal(flowRoute)
if err != nil {
return nil, err
}

it.Spec.Flows = append(it.Spec.Flows, v1.Flow{RawMessage: encodedRoute})

return &it, nil
Expand Down
Loading

0 comments on commit 0d523af

Please sign in to comment.