This is an automated email from the ASF dual-hosted git repository. orpiske pushed a commit to branch camel-main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit f892f2c0f54338e78c21d9cda18d5e077e2d9e18 Author: nicolaferraro <ni.ferr...@gmail.com> AuthorDate: Tue Jun 8 00:16:07 2021 +0200 Fix #2361: refactor code --- pkg/cmd/run.go | 24 +++--------- pkg/cmd/run_test.go | 17 +++++++-- pkg/controller/kameletbinding/common.go | 33 ++++++++++++---- pkg/trait/builder.go | 8 ++-- pkg/trait/trait_types.go | 10 +---- pkg/trait/util.go | 10 +---- pkg/util/property/property.go | 67 +++++++++++++++++++++++++++++++++ 7 files changed, 120 insertions(+), 49 deletions(-) diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index 1d292ff..e82be77 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -18,7 +18,6 @@ limitations under the License. package cmd import ( - "bytes" "context" "encoding/json" "fmt" @@ -31,6 +30,7 @@ import ( "strings" "syscall" + "github.com/apache/camel-k/pkg/util/property" "github.com/magiconair/properties" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" @@ -585,9 +585,9 @@ func (o *runCmdOptions) updateIntegrationCode(c client.Client, sources []string, return nil, err } for _, k := range props.Keys() { - _, ok := props.Get(k) + v, ok := props.Get(k) if ok { - entry, err := toPropertyEntry(props, k) + entry, err := property.EncodePropertyFileEntry(k, v) if err != nil { return nil, err } @@ -793,7 +793,8 @@ func isLocalAndFileExists(fileName string) (bool, error) { func addIntegrationProperties(props *properties.Properties, spec *v1.IntegrationSpec) error { for _, k := range props.Keys() { - entry, err := toPropertyEntry(props, k) + v, _ := props.Get(k) + entry, err := property.EncodePropertyFileEntry(k, v) if err != nil { return err } @@ -817,21 +818,6 @@ func loadPropertyFile(fileName string) (*properties.Properties, error) { return p, nil } -func toPropertyEntry(props *properties.Properties, key string) (string, error) { - value, _ := props.Get(key) - p := properties.NewProperties() - p.DisableExpansion = true - if _, _, err := p.Set(key, value); err != nil { - return "", err - } - buf := new(bytes.Buffer) - if _, err := p.Write(buf, properties.UTF8); err != nil { - return "", err - } - pair := strings.TrimSuffix(buf.String(), "\n") - return pair, nil -} - func resolvePodTemplate(ctx context.Context, templateSrc string, spec *v1.IntegrationSpec) (err error) { // check if template is set if templateSrc == "" { diff --git a/pkg/cmd/run_test.go b/pkg/cmd/run_test.go index 36242de..fff9032 100644 --- a/pkg/cmd/run_test.go +++ b/pkg/cmd/run_test.go @@ -251,6 +251,7 @@ a=b #d=c\=e #ignore=me f=g:h +i=j\nk ` func TestAddPropertyFile(t *testing.T) { @@ -267,11 +268,12 @@ func TestAddPropertyFile(t *testing.T) { properties, err := extractProperties("file:" + tmpFile.Name()) assert.Nil(t, err) assert.Nil(t, addIntegrationProperties(properties, &spec)) - assert.Equal(t, 2, len(spec.Configuration)) + assert.Equal(t, 3, len(spec.Configuration)) assert.Equal(t, `a = b`, spec.Configuration[0].Value) - //assert.Equal(t, `c\=d=e`, spec.Configuration[1].Value) - //assert.Equal(t, `d=c\=e`, spec.Configuration[2].Value) + //assert.Equal(t, `c\=d = e`, spec.Configuration[1].Value) + //assert.Equal(t, `d = c\=e`, spec.Configuration[2].Value) assert.Equal(t, `f = g:h`, spec.Configuration[1].Value) + assert.Equal(t, `i = j\nk`, spec.Configuration[2].Value) } func TestRunPropertyFileFlag(t *testing.T) { @@ -293,6 +295,15 @@ func TestRunPropertyFileFlag(t *testing.T) { assert.Equal(t, tmpFile.Name(), runCmdOptions.PropertyFiles[0]) } +func TestRunProperty(t *testing.T) { + spec := v1.IntegrationSpec{} + properties, err := extractProperties(`key=value\nnewline`) + assert.Nil(t, err) + assert.Nil(t, addIntegrationProperties(properties, &spec)) + assert.Equal(t, 1, len(spec.Configuration)) + assert.Equal(t, `key = value\nnewline`, spec.Configuration[0].Value) +} + func TestRunResourceFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go index c68e312..0697a71 100644 --- a/pkg/controller/kameletbinding/common.go +++ b/pkg/controller/kameletbinding/common.go @@ -20,7 +20,6 @@ package kameletbinding import ( "context" "encoding/json" - "fmt" "sort" v1 "github.com/apache/camel-k/pkg/apis/camel/v1" @@ -31,6 +30,7 @@ import ( "github.com/apache/camel-k/pkg/util/bindings" "github.com/apache/camel-k/pkg/util/knative" "github.com/apache/camel-k/pkg/util/kubernetes" + "github.com/apache/camel-k/pkg/util/property" "github.com/pkg/errors" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -125,10 +125,21 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding * } } - configureBinding(&it, from) - configureBinding(&it, steps...) - configureBinding(&it, to) - configureBinding(&it, errorHandler) + if err := configureBinding(&it, from); err != nil { + return nil, err + } + + if err := configureBinding(&it, steps...); err != nil { + return nil, err + } + + if err := configureBinding(&it, to); err != nil { + return nil, err + } + + if err := configureBinding(&it, errorHandler); err != nil { + return nil, err + } if it.Spec.Configuration != nil { sort.SliceStable(it.Spec.Configuration, func(i, j int) bool { @@ -178,7 +189,7 @@ func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding * return &it, nil } -func configureBinding(integration *v1.Integration, bindings ...*bindings.Binding) { +func configureBinding(integration *v1.Integration, bindings ...*bindings.Binding) error { for _, b := range bindings { if b == nil { continue @@ -190,12 +201,20 @@ func configureBinding(integration *v1.Integration, bindings ...*bindings.Binding integration.Spec.Traits[k] = v } for k, v := range b.ApplicationProperties { + entry, err := property.EncodePropertyFileEntry(k, v) + + if err != nil { + return err + } + integration.Spec.Configuration = append(integration.Spec.Configuration, v1.ConfigurationSpec{ Type: "property", - Value: fmt.Sprintf("%s=%s", k, v), + Value: entry, }) } } + + return nil } func determineProfile(ctx context.Context, c client.Client, binding *v1alpha1.KameletBinding) (v1.TraitProfile, error) { diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go index 639a55c..ec82807 100644 --- a/pkg/trait/builder.go +++ b/pkg/trait/builder.go @@ -20,8 +20,8 @@ package trait import ( "fmt" "sort" - "strings" + "github.com/apache/camel-k/pkg/util/property" corev1 "k8s.io/api/core/v1" v1 "github.com/apache/camel-k/pkg/apis/camel/v1" @@ -156,12 +156,12 @@ func (t *builderTrait) builderTask(e *Environment) (*v1.BuilderTask, error) { // User provided Maven properties if t.Properties != nil { for _, v := range t.Properties { - split := strings.SplitN(v, "=", 2) - if len(split) != 2 { + key, value := property.SplitPropertyFileEntry(v) + if len(key) == 0 || len(value) == 0 { return nil, fmt.Errorf("maven property must have key=value format, it was %v", v) } - task.Maven.Properties[split[0]] = split[1] + task.Maven.Properties[key] = value } } diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go index af884d5..6e7426c 100644 --- a/pkg/trait/trait_types.go +++ b/pkg/trait/trait_types.go @@ -18,7 +18,6 @@ limitations under the License. package trait import ( - "bytes" "context" "fmt" "path" @@ -26,7 +25,7 @@ import ( "strconv" "strings" - "github.com/magiconair/properties" + "github.com/apache/camel-k/pkg/util/property" "github.com/pkg/errors" appsv1 "k8s.io/api/apps/v1" "k8s.io/api/batch/v1beta1" @@ -368,15 +367,10 @@ func (e *Environment) DetermineCatalogNamespace() string { func (e *Environment) computeApplicationProperties() (*corev1.ConfigMap, error) { // application properties - props := properties.LoadMap(e.ApplicationProperties) - props.DisableExpansion = true - props.Sort() - buf := new(bytes.Buffer) - _, err := props.Write(buf, properties.UTF8) + applicationProperties, err := property.EncodePropertyFile(e.ApplicationProperties) if err != nil { return nil, errors.Wrapf(err, "could not compute application properties") } - applicationProperties := buf.String() if applicationProperties != "" { return &corev1.ConfigMap{ diff --git a/pkg/trait/util.go b/pkg/trait/util.go index 695b7ee..366d594 100644 --- a/pkg/trait/util.go +++ b/pkg/trait/util.go @@ -25,6 +25,7 @@ import ( "sort" "strings" + "github.com/apache/camel-k/pkg/util/property" user "github.com/mitchellh/go-homedir" "github.com/scylladb/go-set/strset" @@ -93,14 +94,7 @@ func collectConfigurationPairs(configurationType string, configurable ...v1.Conf for _, entry := range entries { if entry.Type == configurationType { - pair := strings.SplitN(entry.Value, "=", 2) - var k, v string - if len(pair) >= 1 { - k = strings.TrimSpace(pair[0]) - } - if len(pair) == 2 { - v = strings.TrimSpace(pair[1]) - } + k, v := property.SplitPropertyFileEntry(entry.Value) if k == "" { continue } diff --git a/pkg/util/property/property.go b/pkg/util/property/property.go new file mode 100644 index 0000000..e321d03 --- /dev/null +++ b/pkg/util/property/property.go @@ -0,0 +1,67 @@ +/* +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. +*/ + +package property + +import ( + "bytes" + "strings" + + "github.com/magiconair/properties" + "github.com/pkg/errors" +) + +// EncodePropertyFileEntry converts the given key/value pair into a .properties file entry +func EncodePropertyFileEntry(key, value string) (string, error) { + p := properties.NewProperties() + p.DisableExpansion = true + if _, _, err := p.Set(key, value); err != nil { + return "", err + } + buf := new(bytes.Buffer) + if _, err := p.Write(buf, properties.UTF8); err != nil { + return "", err + } + pair := strings.TrimSuffix(buf.String(), "\n") + return pair, nil +} + +// EncodePropertyFile encodes a property map into a .properties file +func EncodePropertyFile(sourceProperties map[string]string) (string, error) { + props := properties.LoadMap(sourceProperties) + props.DisableExpansion = true + props.Sort() + buf := new(bytes.Buffer) + _, err := props.Write(buf, properties.UTF8) + if err != nil { + return "", errors.Wrapf(err, "could not compute application properties") + } + return buf.String(), nil +} + +// SplitPropertyFileEntry splits an encoded property into key/value pair, without decoding the content +func SplitPropertyFileEntry(entry string) (string, string) { + pair := strings.SplitN(entry, "=", 2) + var k, v string + if len(pair) >= 1 { + k = strings.TrimSpace(pair[0]) + } + if len(pair) == 2 { + v = strings.TrimSpace(pair[1]) + } + return k, v +}