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:34 UTC
[camel-k] 20/30: refactor(trait): error handler using bean ref
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
}