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 d1c4284bacb4496ef4957f1e26f12fe07058452b Author: Pasquale Congiusti <pasquale.congiu...@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)) } }