This is an automated email from the ASF dual-hosted git repository. nferraro pushed a commit to branch camel-main in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/camel-main by this push: new daae799 Fix #2271: add support for beans in kamelets daae799 is described below commit daae7990546fd75e139142899f4812f98135e734 Author: nicolaferraro <ni.ferr...@gmail.com> AuthorDate: Tue Jun 8 23:29:01 2021 +0200 Fix #2271: add support for beans in kamelets --- config/crd/bases/camel.apache.org_kamelets.yaml | 8 ++- .../1.5.0-snapshot/camel.apache.org_kamelets.yaml | 8 ++- e2e/knative/knative_platform_test.go | 6 +- .../common/kamelet-beans/beans-source.kamelet.yaml | 36 ++++++++++++ e2e/yaks/common/kamelet-beans/kamelet.feature | 15 +++++ e2e/yaks/common/kamelet-beans/yaks-config.yaml | 26 +++++++++ helm/camel-k/crds/crd-kamelet.yaml | 8 ++- pkg/apis/camel/v1/common_types.go | 5 ++ pkg/apis/camel/v1alpha1/kamelet_types.go | 8 ++- pkg/apis/camel/v1alpha1/kamelet_types_support.go | 10 ++++ pkg/cmd/run.go | 4 +- pkg/kamelet/initialize.go | 9 +++ pkg/trait/init.go | 4 +- pkg/trait/kamelets.go | 33 ++++------- pkg/trait/kamelets_test.go | 60 ++++---------------- pkg/util/digest/digest.go | 4 +- pkg/util/{flow => dsl}/flow.go | 2 +- pkg/util/{flow => dsl}/flow_test.go | 2 +- pkg/util/{flow/flow.go => dsl/template.go} | 49 +++++------------ .../{flow/flow_test.go => dsl/template_test.go} | 64 +++++++++++++--------- 20 files changed, 209 insertions(+), 152 deletions(-) diff --git a/config/crd/bases/camel.apache.org_kamelets.yaml b/config/crd/bases/camel.apache.org_kamelets.yaml index e8371f9..dcd7a52 100644 --- a/config/crd/bases/camel.apache.org_kamelets.yaml +++ b/config/crd/bases/camel.apache.org_kamelets.yaml @@ -214,8 +214,7 @@ spec: type: string type: array flow: - description: Flow is an unstructured object representing a Camel Flow - in YAML/JSON DSL + description: 'Deprecated: use template' type: object x-kubernetes-preserve-unknown-fields: true sources: @@ -262,6 +261,11 @@ spec: type: string type: object type: array + template: + description: Template is an unstructured object representing a Kamelet + template in YAML/JSON DSL + type: object + x-kubernetes-preserve-unknown-fields: true types: additionalProperties: properties: diff --git a/deploy/olm-catalog/camel-k-dev/1.5.0-snapshot/camel.apache.org_kamelets.yaml b/deploy/olm-catalog/camel-k-dev/1.5.0-snapshot/camel.apache.org_kamelets.yaml index e8371f9..dcd7a52 100644 --- a/deploy/olm-catalog/camel-k-dev/1.5.0-snapshot/camel.apache.org_kamelets.yaml +++ b/deploy/olm-catalog/camel-k-dev/1.5.0-snapshot/camel.apache.org_kamelets.yaml @@ -214,8 +214,7 @@ spec: type: string type: array flow: - description: Flow is an unstructured object representing a Camel Flow - in YAML/JSON DSL + description: 'Deprecated: use template' type: object x-kubernetes-preserve-unknown-fields: true sources: @@ -262,6 +261,11 @@ spec: type: string type: object type: array + template: + description: Template is an unstructured object representing a Kamelet + template in YAML/JSON DSL + type: object + x-kubernetes-preserve-unknown-fields: true types: additionalProperties: properties: diff --git a/e2e/knative/knative_platform_test.go b/e2e/knative/knative_platform_test.go index 4bb5952..75b4321 100644 --- a/e2e/knative/knative_platform_test.go +++ b/e2e/knative/knative_platform_test.go @@ -33,7 +33,7 @@ import ( . "github.com/apache/camel-k/e2e/support" "github.com/apache/camel-k/pkg/apis/camel/v1" - "github.com/apache/camel-k/pkg/util/flow" + "github.com/apache/camel-k/pkg/util/dsl" "github.com/apache/camel-k/pkg/util/knative" ) @@ -57,10 +57,10 @@ func TestKnativePlatform(t *testing.T) { // Change something in the integration to produce a redeploy Expect(UpdateIntegration(ns, "yaml", func(it *v1.Integration) { it.Spec.Profile = "" - content, err := flow.ToYamlDSL(it.Spec.Flows) + content, err := dsl.ToYamlDSL(it.Spec.Flows) assert.NoError(t, err) newData := strings.ReplaceAll(string(content), "string!", "string!!!") - newFlows, err := flow.FromYamlDSLString(newData) + newFlows, err := dsl.FromYamlDSLString(newData) assert.NoError(t, err) it.Spec.Flows = newFlows })).To(Succeed()) diff --git a/e2e/yaks/common/kamelet-beans/beans-source.kamelet.yaml b/e2e/yaks/common/kamelet-beans/beans-source.kamelet.yaml new file mode 100644 index 0000000..3b5a279 --- /dev/null +++ b/e2e/yaks/common/kamelet-beans/beans-source.kamelet.yaml @@ -0,0 +1,36 @@ +# --------------------------------------------------------------------------- +# 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: beans-source + labels: + camel.apache.org/kamelet.type: "source" +spec: + template: + beans: + - name: myBean + type: "#class:java.util.Date" + properties: + time: 0 + from: + uri: timer:tick + steps: + - set-body: + simple: "Bean time is ${bean:{{myBean}}?method=getTime}!" + - to: "kamelet:sink" diff --git a/e2e/yaks/common/kamelet-beans/kamelet.feature b/e2e/yaks/common/kamelet-beans/kamelet.feature new file mode 100644 index 0000000..97e5c0d --- /dev/null +++ b/e2e/yaks/common/kamelet-beans/kamelet.feature @@ -0,0 +1,15 @@ +Feature: Kamelets can declare local beans + + Background: + Given Disable auto removal of Kamelet resources + Given Disable auto removal of Kubernetes resources + Given Camel-K resource polling configuration + | maxAttempts | 40 | + | delayBetweenAttempts | 3000 | + + Scenario: Kamelets templates can use beans + Given bind Kamelet beans-source to uri log:info + When create KameletBinding binding + Then KameletBinding binding should be available + Then Camel-K integration binding should be running + Then Camel-K integration binding should print Bean time is 0! diff --git a/e2e/yaks/common/kamelet-beans/yaks-config.yaml b/e2e/yaks/common/kamelet-beans/yaks-config.yaml new file mode 100644 index 0000000..22e1b0e --- /dev/null +++ b/e2e/yaks/common/kamelet-beans/yaks-config.yaml @@ -0,0 +1,26 @@ +# --------------------------------------------------------------------------- +# 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. +# --------------------------------------------------------------------------- + +config: + namespace: + temporary: true +pre: +- name: installation + run: | + kamel install -n $YAKS_NAMESPACE + + kubectl apply -f beans-source.kamelet.yaml -n $YAKS_NAMESPACE diff --git a/helm/camel-k/crds/crd-kamelet.yaml b/helm/camel-k/crds/crd-kamelet.yaml index e8371f9..dcd7a52 100644 --- a/helm/camel-k/crds/crd-kamelet.yaml +++ b/helm/camel-k/crds/crd-kamelet.yaml @@ -214,8 +214,7 @@ spec: type: string type: array flow: - description: Flow is an unstructured object representing a Camel Flow - in YAML/JSON DSL + description: 'Deprecated: use template' type: object x-kubernetes-preserve-unknown-fields: true sources: @@ -262,6 +261,11 @@ spec: type: string type: object type: array + template: + description: Template is an unstructured object representing a Kamelet + template in YAML/JSON DSL + type: object + x-kubernetes-preserve-unknown-fields: true types: additionalProperties: properties: diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go index 2bcc733..99baf6c 100644 --- a/pkg/apis/camel/v1/common_types.go +++ b/pkg/apis/camel/v1/common_types.go @@ -175,6 +175,11 @@ type Flow struct { RawMessage `json:",inline"` } +// Template is an unstructured object representing a Kamelet template in YAML/JSON DSL +type Template struct { + RawMessage `json:",inline"` +} + // RuntimeProvider -- type RuntimeProvider string diff --git a/pkg/apis/camel/v1alpha1/kamelet_types.go b/pkg/apis/camel/v1alpha1/kamelet_types.go index 5a6def7..2b85920 100644 --- a/pkg/apis/camel/v1alpha1/kamelet_types.go +++ b/pkg/apis/camel/v1alpha1/kamelet_types.go @@ -43,8 +43,10 @@ var ( // KameletSpec defines the desired state of Kamelet type KameletSpec struct { - Definition *JSONSchemaProps `json:"definition,omitempty"` - Sources []camelv1.SourceSpec `json:"sources,omitempty"` + Definition *JSONSchemaProps `json:"definition,omitempty"` + Sources []camelv1.SourceSpec `json:"sources,omitempty"` + Template *camelv1.Template `json:"template,omitempty"` + // Deprecated: use template Flow *camelv1.Flow `json:"flow,omitempty"` Authorization *AuthorizationSpec `json:"authorization,omitempty"` Types map[EventSlot]EventTypeSpec `json:"types,omitempty"` @@ -108,6 +110,8 @@ const ( KameletConditionReasonInvalidName string = "InvalidName" // KameletConditionReasonInvalidProperty -- KameletConditionReasonInvalidProperty string = "InvalidProperty" + // KameletConditionReasonInvalidTemplate -- + KameletConditionReasonInvalidTemplate string = "InvalidTemplate" ) type KameletPhase string diff --git a/pkg/apis/camel/v1alpha1/kamelet_types_support.go b/pkg/apis/camel/v1alpha1/kamelet_types_support.go index 52635f2..e363204 100644 --- a/pkg/apis/camel/v1alpha1/kamelet_types_support.go +++ b/pkg/apis/camel/v1alpha1/kamelet_types_support.go @@ -192,6 +192,16 @@ func ValidKameletProperties(kamelet *Kamelet) bool { return true } +func ValidKameletTemplate(kamelet *Kamelet) bool { + if kamelet == nil { + return true + } + if kamelet.Spec.Template != nil && kamelet.Spec.Flow != nil { + return false + } + return true +} + // NewKamelet creates a new kamelet func NewKamelet(namespace string, name string) Kamelet { return Kamelet{ diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index b097cf1..3d7c1eb 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -47,7 +47,7 @@ import ( "github.com/apache/camel-k/pkg/client" "github.com/apache/camel-k/pkg/trait" "github.com/apache/camel-k/pkg/util" - "github.com/apache/camel-k/pkg/util/flow" + "github.com/apache/camel-k/pkg/util/dsl" "github.com/apache/camel-k/pkg/util/kubernetes" k8slog "github.com/apache/camel-k/pkg/util/kubernetes/log" "github.com/apache/camel-k/pkg/util/sync" @@ -523,7 +523,7 @@ func (o *runCmdOptions) updateIntegrationCode(c client.Client, sources []string, for _, source := range resolvedSources { if o.UseFlows && !o.Compression && (strings.HasSuffix(source.Name, ".yaml") || strings.HasSuffix(source.Name, ".yml")) { - flows, err := flow.FromYamlDSLString(source.Content) + flows, err := dsl.FromYamlDSLString(source.Content) if err != nil { return nil, err } diff --git a/pkg/kamelet/initialize.go b/pkg/kamelet/initialize.go index 7fd4373..d3b38a1 100644 --- a/pkg/kamelet/initialize.go +++ b/pkg/kamelet/initialize.go @@ -49,6 +49,15 @@ func Initialize(kamelet *v1alpha1.Kamelet) (*v1alpha1.Kamelet, error) { fmt.Sprintf("Kamelet property %q is reserved and cannot be part of the schema", v1alpha1.KameletIDProperty), ) } + if !v1alpha1.ValidKameletTemplate(kamelet) { + ok = false + target.Status.SetCondition( + v1alpha1.KameletConditionReady, + corev1.ConditionFalse, + v1alpha1.KameletConditionReasonInvalidTemplate, + `Kamelet can only specify one of "flow" or "template"`, + ) + } if !ok { target.Status.Phase = v1alpha1.KameletPhaseError diff --git a/pkg/trait/init.go b/pkg/trait/init.go index 07b923d..afd9d32 100644 --- a/pkg/trait/init.go +++ b/pkg/trait/init.go @@ -24,7 +24,7 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/util" - "github.com/apache/camel-k/pkg/util/flow" + "github.com/apache/camel-k/pkg/util/dsl" ) const flowsInternalSourceName = "camel-k-embedded-flow.yaml" @@ -53,7 +53,7 @@ func (t *initTrait) Apply(e *Environment) error { // Flows need to be turned into a generated source if len(e.Integration.Spec.Flows) > 0 { - content, err := flow.ToYamlDSL(e.Integration.Spec.Flows) + content, err := dsl.ToYamlDSL(e.Integration.Spec.Flows) if err != nil { return err } diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go index 1f3cdef..2a3a2cf 100644 --- a/pkg/trait/kamelets.go +++ b/pkg/trait/kamelets.go @@ -34,7 +34,7 @@ import ( "github.com/apache/camel-k/pkg/platform" "github.com/apache/camel-k/pkg/util" "github.com/apache/camel-k/pkg/util/digest" - "github.com/apache/camel-k/pkg/util/flow" + "github.com/apache/camel-k/pkg/util/dsl" "github.com/apache/camel-k/pkg/util/kubernetes" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -260,28 +260,27 @@ func (t *kameletsTrait) configureApplicationProperties(e *Environment) error { func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kamelet) error { sources := make([]v1.SourceSpec, 0) - if kamelet.Spec.Flow != nil { - - flowData, err := flow.ToYamlDSL([]v1.Flow{*kamelet.Spec.Flow}) + if kamelet.Spec.Template != nil || kamelet.Spec.Flow != nil { + template := kamelet.Spec.Template + if template == nil { + // Backward compatibility with Kamelets using flow + template = &v1.Template{ + RawMessage: kamelet.Spec.Flow.RawMessage, + } + } + flowData, err := dsl.TemplateToYamlDSL(*template, kamelet.Name) if err != nil { return err } - propertyNames := make([]string, 0, len(kamelet.Status.Properties)) - for _, p := range kamelet.Status.Properties { - propertyNames = append(propertyNames, p.Name) - } - flowSource := v1.SourceSpec{ DataSpec: v1.DataSpec{ Name: fmt.Sprintf("%s.yaml", kamelet.Name), Content: string(flowData), }, - Language: v1.LanguageYaml, - Type: v1.SourceTypeTemplate, - PropertyNames: propertyNames, + Language: v1.LanguageYaml, } - flowSource, err = integrationSourceFromKameletSource(e, kamelet, flowSource, fmt.Sprintf("%s-kamelet-%s-flow", e.Integration.Name, kamelet.Name)) + flowSource, err = integrationSourceFromKameletSource(e, kamelet, flowSource, fmt.Sprintf("%s-kamelet-%s-template", e.Integration.Name, kamelet.Name)) if err != nil { return err } @@ -296,11 +295,7 @@ func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kam sources = append(sources, intSource) } - kameletCounter := 0 for _, source := range sources { - if source.Type == v1.SourceTypeTemplate { - kameletCounter++ - } replaced := false for idx, existing := range e.Integration.Status.GeneratedSources { if existing.Name == source.Name { @@ -313,10 +308,6 @@ func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1alpha1.Kam } } - if kameletCounter > 1 { - return fmt.Errorf(`kamelet %s contains %d sources of type "kamelet": at most one is allowed`, kamelet.Name, kameletCounter) - } - return nil } diff --git a/pkg/trait/kamelets_test.go b/pkg/trait/kamelets_test.go index 942536a..1e34eae 100644 --- a/pkg/trait/kamelets_test.go +++ b/pkg/trait/kamelets_test.go @@ -109,13 +109,13 @@ func TestKameletLookup(t *testing.T) { assert.NoError(t, err) cm := environment.Resources.GetConfigMap(func(_ *corev1.ConfigMap) bool { return true }) assert.NotNil(t, cm) - assert.Equal(t, "it-kamelet-timer-flow", cm.Name) + assert.Equal(t, "it-kamelet-timer-template", cm.Name) assert.Equal(t, "test", cm.Namespace) assert.Len(t, environment.Integration.Status.GeneratedSources, 1) source := environment.Integration.Status.GeneratedSources[0] assert.Equal(t, "timer.yaml", source.Name) - assert.Equal(t, "template", string(source.Type)) + assert.Equal(t, "", string(source.Type)) assert.Equal(t, []string{"camel:log", "camel:timer"}, environment.Integration.Status.Dependencies) } @@ -156,7 +156,7 @@ func TestKameletSecondarySourcesLookup(t *testing.T) { err = trait.Apply(environment) assert.NoError(t, err) - cmFlow := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-timer-flow" }) + cmFlow := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-timer-template" }) assert.NotNil(t, cmFlow) cmRes := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-timer-000" }) assert.NotNil(t, cmRes) @@ -165,8 +165,8 @@ func TestKameletSecondarySourcesLookup(t *testing.T) { flowSource := environment.Integration.Status.GeneratedSources[0] assert.Equal(t, "timer.yaml", flowSource.Name) - assert.Equal(t, "template", string(flowSource.Type)) - assert.Equal(t, "it-kamelet-timer-flow", flowSource.ContentRef) + assert.Equal(t, "", string(flowSource.Type)) + assert.Equal(t, "it-kamelet-timer-template", flowSource.ContentRef) assert.Equal(t, "content", flowSource.ContentKey) supportSource := environment.Integration.Status.GeneratedSources[1] @@ -218,44 +218,6 @@ func TestNonYAMLKameletLookup(t *testing.T) { assert.Equal(t, "template", string(source.Type)) } -func TestErrorMultipleKameletSources(t *testing.T) { - trait, environment := createKameletsTestEnvironment(` -- from: - uri: kamelet:timer - steps: - - to: log:info -`, &v1alpha1.Kamelet{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "test", - Name: "timer", - }, - Spec: v1alpha1.KameletSpec{ - Sources: []v1.SourceSpec{ - { - DataSpec: v1.DataSpec{ - Name: "mykamelet.groovy", - Content: `from("timer").to("log:info")`, - }, - Type: v1.SourceTypeTemplate, - }, - }, - Flow: marshalOrFail(map[string]interface{}{ - "from": map[string]interface{}{ - "uri": "timer:tick", - }, - }), - }, - Status: v1alpha1.KameletStatus{Phase: v1alpha1.KameletPhaseReady}, - }) - enabled, err := trait.Configure(environment) - assert.NoError(t, err) - assert.True(t, enabled) - assert.Equal(t, []string{"timer"}, trait.getKameletKeys()) - - err = trait.Apply(environment) - assert.Error(t, err) -} - func TestMultipleKamelets(t *testing.T) { trait, environment := createKameletsTestEnvironment(` - from: @@ -322,25 +284,25 @@ func TestMultipleKamelets(t *testing.T) { err = trait.Apply(environment) assert.NoError(t, err) - cmFlow := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-timer-flow" }) + cmFlow := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-timer-template" }) assert.NotNil(t, cmFlow) cmRes := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-timer-000" }) assert.NotNil(t, cmRes) - cmFlow2 := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-logger-flow" }) + cmFlow2 := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-logger-template" }) assert.NotNil(t, cmFlow2) assert.Len(t, environment.Integration.Status.GeneratedSources, 3) flowSource2 := environment.Integration.Status.GeneratedSources[0] assert.Equal(t, "logger.yaml", flowSource2.Name) - assert.Equal(t, "template", string(flowSource2.Type)) - assert.Equal(t, "it-kamelet-logger-flow", flowSource2.ContentRef) + assert.Equal(t, "", string(flowSource2.Type)) + assert.Equal(t, "it-kamelet-logger-template", flowSource2.ContentRef) assert.Equal(t, "content", flowSource2.ContentKey) flowSource := environment.Integration.Status.GeneratedSources[1] assert.Equal(t, "timer.yaml", flowSource.Name) - assert.Equal(t, "template", string(flowSource.Type)) - assert.Equal(t, "it-kamelet-timer-flow", flowSource.ContentRef) + assert.Equal(t, "", string(flowSource.Type)) + assert.Equal(t, "it-kamelet-timer-template", flowSource.ContentRef) assert.Equal(t, "content", flowSource.ContentKey) supportSource := environment.Integration.Status.GeneratedSources[2] diff --git a/pkg/util/digest/digest.go b/pkg/util/digest/digest.go index e3baad4..6b2bf59 100644 --- a/pkg/util/digest/digest.go +++ b/pkg/util/digest/digest.go @@ -34,7 +34,7 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/util" "github.com/apache/camel-k/pkg/util/defaults" - "github.com/apache/camel-k/pkg/util/flow" + "github.com/apache/camel-k/pkg/util/dsl" ) // ComputeForIntegration a digest of the fields that are relevant for the deployment @@ -74,7 +74,7 @@ func ComputeForIntegration(integration *v1.Integration) (string, error) { // Integration flows if len(integration.Spec.Flows) > 0 { - flows, err := flow.ToYamlDSL(integration.Spec.Flows) + flows, err := dsl.ToYamlDSL(integration.Spec.Flows) if err != nil { return "", err } diff --git a/pkg/util/flow/flow.go b/pkg/util/dsl/flow.go similarity index 99% copy from pkg/util/flow/flow.go copy to pkg/util/dsl/flow.go index fa963cf..8ffeaac 100644 --- a/pkg/util/flow/flow.go +++ b/pkg/util/dsl/flow.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package flow +package dsl import ( "bytes" diff --git a/pkg/util/flow/flow_test.go b/pkg/util/dsl/flow_test.go similarity index 99% copy from pkg/util/flow/flow_test.go copy to pkg/util/dsl/flow_test.go index 731e2ff..cd6cbcc 100644 --- a/pkg/util/flow/flow_test.go +++ b/pkg/util/dsl/flow_test.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package flow +package dsl import ( "bytes" diff --git a/pkg/util/flow/flow.go b/pkg/util/dsl/template.go similarity index 51% rename from pkg/util/flow/flow.go rename to pkg/util/dsl/template.go index fa963cf..7abf08f 100644 --- a/pkg/util/flow/flow.go +++ b/pkg/util/dsl/template.go @@ -15,59 +15,36 @@ See the License for the specific language governing permissions and limitations under the License. */ -package flow +package dsl import ( - "bytes" "encoding/json" "fmt" - "io" - "io/ioutil" yaml2 "gopkg.in/yaml.v2" - "k8s.io/apimachinery/pkg/util/yaml" - v1 "github.com/apache/camel-k/pkg/apis/camel/v1" ) -// FromYamlDSLString creates a slice of flows from a Camel YAML DSL string -func FromYamlDSLString(flowsString string) ([]v1.Flow, error) { - return FromYamlDSL(bytes.NewReader([]byte(flowsString))) -} - -// FromYamlDSL creates a slice of flows from a Camel YAML DSL stream -func FromYamlDSL(reader io.Reader) ([]v1.Flow, error) { - buffered, err := ioutil.ReadAll(reader) - if err != nil { - return nil, err - } - var flows []v1.Flow - // Using the Kubernetes decoder to turn them into JSON before unmarshal. - // This avoids having map[interface{}]interface{} objects which are not JSON compatible. - jsonData, err := yaml.ToJSON(buffered) +// TemplateToYamlDSL converts a kamelet template into its Camel YAML DSL equivalent +func TemplateToYamlDSL(template v1.Template, id string) ([]byte, error) { + data, err := json.Marshal(&template) if err != nil { return nil, err } - - if err = json.Unmarshal(jsonData, &flows); err != nil { - return nil, err - } - return flows, err -} - -// ToYamlDSL converts a flow into its Camel YAML DSL equivalent -func ToYamlDSL(flows []v1.Flow) ([]byte, error) { - data, err := json.Marshal(&flows) - if err != nil { - return nil, err - } - jsondata := make([]map[string]interface{}, 0) + jsondata := make(map[string]interface{}, 0) err = json.Unmarshal(data, &jsondata) if err != nil { return nil, fmt.Errorf("error unmarshalling json: %v", err) } - yamldata, err := yaml2.Marshal(&jsondata) + if _, present := jsondata["id"]; !present { + jsondata["id"] = id + } + templateWrapper := make(map[string]interface{}, 2) + templateWrapper["template"] = jsondata + listWrapper := make([]interface{}, 0, 1) + listWrapper = append(listWrapper, templateWrapper) + yamldata, err := yaml2.Marshal(listWrapper) if err != nil { return nil, fmt.Errorf("error marshalling to yaml: %v", err) } diff --git a/pkg/util/flow/flow_test.go b/pkg/util/dsl/template_test.go similarity index 56% rename from pkg/util/flow/flow_test.go rename to pkg/util/dsl/template_test.go index 731e2ff..b2fb016 100644 --- a/pkg/util/flow/flow_test.go +++ b/pkg/util/dsl/template_test.go @@ -15,39 +15,49 @@ See the License for the specific language governing permissions and limitations under the License. */ -package flow +package dsl import ( - "bytes" - "encoding/json" "testing" + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" ) -func TestReadWriteYaml(t *testing.T) { - // yaml in conventional form as marshalled by the go runtime - yaml := `- from: - steps: - - to: log:info - uri: timer:tick -` - - yamlReader := bytes.NewReader([]byte(yaml)) - flows, err := FromYamlDSL(yamlReader) - assert.NoError(t, err) - assert.NotNil(t, flows) - assert.Len(t, flows, 1) - - flow := map[string]interface{}{} - err = json.Unmarshal(flows[0].RawMessage, &flow) +func TestTemplateReadWrite(t *testing.T) { + templateJSON := v1.Template{ + RawMessage: []byte(` + { + "beans": [ + { + "name": "myBean", + "type": "com.acme.MyBean" + } + ], + "from": { + "uri": "kamelet:source", + "steps": [ + { + "uri": "log:info" + } + ] + } + } + `), + } + + yamlBytes, err := TemplateToYamlDSL(templateJSON, "myid") assert.NoError(t, err) - - assert.NotNil(t, flow["from"]) - assert.Nil(t, flow["xx"]) - - data, err := ToYamlDSL(flows) - assert.NoError(t, err) - assert.NotNil(t, data) - assert.Equal(t, yaml, string(data)) + yaml := string(yamlBytes) + expected := `- template: + beans: + - name: myBean + type: com.acme.MyBean + from: + steps: + - uri: log:info + uri: kamelet:source + id: myid +` + assert.Equal(t, expected, yaml) }