This is an automated email from the ASF dual-hosted git repository. astefanutti pushed a commit to branch release-1.4.x in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit c7da379ade9a22cbfb3d1e9d032de57dcd03db0c Author: Pasquale Congiusti <pasquale.congiu...@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 }