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 2019/07/24 09:13:49 UTC
[camel-k] 01/02: Fix #856: lookup destination in multiple places
and add e2e tests
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit d0366d8436c45b23661e71e79ba491c4d6001e35
Author: nferraro <ni...@gmail.com>
AuthorDate: Tue Jul 23 23:21:44 2019 +0200
Fix #856: lookup destination in multiple places and add e2e tests
---
e2e/files/knative1.groovy | 20 +++++++
e2e/files/knative2.groovy | 19 +++++++
e2e/files/knativech1.groovy | 20 +++++++
e2e/files/knativech2.groovy | 19 +++++++
e2e/knative_test.go | 57 +++++++++++++++++++
e2e/test_support.go | 31 +++++++++-
pkg/apis/camel/v1alpha1/knative/types_support.go | 10 +---
pkg/cmd/install.go | 13 +++++
pkg/trait/knative.go | 72 +++++++++++++++---------
script/Makefile | 5 +-
10 files changed, 230 insertions(+), 36 deletions(-)
diff --git a/e2e/files/knative1.groovy b/e2e/files/knative1.groovy
new file mode 100644
index 0000000..b69fc82
--- /dev/null
+++ b/e2e/files/knative1.groovy
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+from('timer:tick')
+ .to('knative:endpoint/knative2')
+ .log('Received: ${body}')
diff --git a/e2e/files/knative2.groovy b/e2e/files/knative2.groovy
new file mode 100644
index 0000000..cb1c6fb
--- /dev/null
+++ b/e2e/files/knative2.groovy
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+from('knative:endpoint/knative2')
+ .setBody().constant("Hello from knative2")
diff --git a/e2e/files/knativech1.groovy b/e2e/files/knativech1.groovy
new file mode 100644
index 0000000..1a32a64
--- /dev/null
+++ b/e2e/files/knativech1.groovy
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+from('timer:tick')
+ .setBody().constant("Hello from knativech1")
+ .to('knative:channel/messages')
diff --git a/e2e/files/knativech2.groovy b/e2e/files/knativech2.groovy
new file mode 100644
index 0000000..65eeb2e
--- /dev/null
+++ b/e2e/files/knativech2.groovy
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+from('knative:channel/messages')
+ .log('Received: ${body}')
diff --git a/e2e/knative_test.go b/e2e/knative_test.go
new file mode 100644
index 0000000..371add2
--- /dev/null
+++ b/e2e/knative_test.go
@@ -0,0 +1,57 @@
+// +build knative
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "knative"
+
+/*
+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 e2e
+
+import (
+ "testing"
+ "time"
+
+ . "github.com/onsi/gomega"
+ v1 "k8s.io/api/core/v1"
+)
+
+func TestRunServiceCombo(t *testing.T) {
+ withNewTestNamespace(func(ns string) {
+ RegisterTestingT(t)
+ Expect(kamel("install", "-n", ns, "--trait-profile", "knative").Execute()).Should(BeNil())
+ Expect(kamel("run", "-n", ns, "files/knative2.groovy").Execute()).Should(BeNil())
+ Expect(kamel("run", "-n", ns, "files/knative1.groovy").Execute()).Should(BeNil())
+ Eventually(integrationPodPhase(ns, "knative2"), 10*time.Minute).Should(Equal(v1.PodRunning))
+ Eventually(integrationPodPhase(ns, "knative1"), 10*time.Minute).Should(Equal(v1.PodRunning))
+ Eventually(integrationLogs(ns, "knative1"), 5*time.Minute).Should(ContainSubstring("Received: Hello from knative2"))
+ Expect(kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
+ })
+}
+
+func TestRunChannelCombo(t *testing.T) {
+ withNewTestNamespace(func(ns string) {
+ RegisterTestingT(t)
+ Expect(createKnativeChannel(ns, "messages")()).Should(BeNil())
+ Expect(kamel("install", "-n", ns, "--trait-profile", "knative").Execute()).Should(BeNil())
+ Expect(kamel("run", "-n", ns, "files/knativech2.groovy").Execute()).Should(BeNil())
+ Expect(kamel("run", "-n", ns, "files/knativech1.groovy").Execute()).Should(BeNil())
+ Eventually(integrationPodPhase(ns, "knativech2"), 10*time.Minute).Should(Equal(v1.PodRunning))
+ Eventually(integrationPodPhase(ns, "knativech1"), 10*time.Minute).Should(Equal(v1.PodRunning))
+ Eventually(integrationLogs(ns, "knativech2"), 5*time.Minute).Should(ContainSubstring("Received: Hello from knativech1"))
+ Expect(kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
+ })
+}
diff --git a/e2e/test_support.go b/e2e/test_support.go
index 134c825..5a0ca40 100644
--- a/e2e/test_support.go
+++ b/e2e/test_support.go
@@ -1,4 +1,4 @@
-// +build integration
+// +build integration knative
// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
@@ -35,6 +35,7 @@ import (
"github.com/apache/camel-k/pkg/util/log"
"github.com/apache/camel-k/pkg/util/openshift"
"github.com/google/uuid"
+ eventing "github.com/knative/eventing/pkg/apis/eventing/v1alpha1"
"github.com/onsi/gomega"
projectv1 "github.com/openshift/api/project/v1"
"github.com/spf13/cobra"
@@ -409,6 +410,34 @@ func scaleOperator(ns string, replicas int32) func() error {
}
/*
+ Knative
+ */
+
+func createKnativeChannel(ns string, name string) func() error {
+ return func() error {
+ channel := eventing.Channel{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "Channel",
+ APIVersion: eventing.SchemeGroupVersion.String(),
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: ns,
+ Name: name,
+ },
+ Spec: eventing.ChannelSpec{
+ Provisioner: &v1.ObjectReference{
+ APIVersion: "eventing.knative.dev/v1alpha1",
+ Kind: "ClusterChannelProvisioner",
+ Name: "in-memory",
+ },
+ },
+ }
+ return testClient.Create(testContext, &channel)
+ }
+}
+
+
+/*
Namespace testing functions
*/
diff --git a/pkg/apis/camel/v1alpha1/knative/types_support.go b/pkg/apis/camel/v1alpha1/knative/types_support.go
index 4c9e53e..f18f35b 100644
--- a/pkg/apis/camel/v1alpha1/knative/types_support.go
+++ b/pkg/apis/camel/v1alpha1/knative/types_support.go
@@ -24,11 +24,7 @@ import (
)
// BuildCamelServiceDefinition creates a CamelServiceDefinition from a given URL
-func BuildCamelServiceDefinition(name string, serviceType CamelServiceType, rawurl string) (*CamelServiceDefinition, error) {
- serviceURL, err := url.Parse(rawurl)
- if err != nil {
- return nil, err
- }
+func BuildCamelServiceDefinition(name string, serviceType CamelServiceType, serviceURL url.URL) (CamelServiceDefinition, error) {
protocol := CamelProtocol(serviceURL.Scheme)
definition := CamelServiceDefinition{
Name: name,
@@ -42,7 +38,7 @@ func BuildCamelServiceDefinition(name string, serviceType CamelServiceType, rawu
if portStr != "" {
port, err := strconv.Atoi(portStr)
if err != nil {
- return nil, err
+ return CamelServiceDefinition{}, err
}
definition.Port = port
}
@@ -52,7 +48,7 @@ func BuildCamelServiceDefinition(name string, serviceType CamelServiceType, rawu
} else {
definition.Metadata[CamelMetaServicePath] = "/"
}
- return &definition, nil
+ return definition, nil
}
func defaultCamelProtocolPort(prot CamelProtocol) int {
diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index 9f13bb6..166b862 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -73,6 +73,7 @@ func newCmdInstall(rootCmdOptions *RootCmdOptions) *cobra.Command {
cmd.Flags().StringSliceVar(&impl.kits, "kit", nil, "Add an integration kit to build at startup")
cmd.Flags().StringVar(&impl.buildStrategy, "build-strategy", "", "Set the build strategy")
cmd.Flags().StringVar(&impl.buildTimeout, "build-timeout", "", "Set how long the build process can last")
+ cmd.Flags().StringVar(&impl.traitProfile, "trait-profile", "", "The profile to use for traits")
// maven settings
cmd.Flags().StringVar(&impl.localRepository, "local-repository", "", "Location of the local maven repository")
@@ -112,6 +113,7 @@ type installCmdOptions struct {
properties []string
kits []string
registry v1alpha1.IntegrationPlatformRegistrySpec
+ traitProfile string
}
// nolint: gocyclo
@@ -208,6 +210,9 @@ func (o *installCmdOptions) install(_ *cobra.Command, _ []string) error {
platform.Spec.Build.Timeout.Duration = d
}
+ if o.traitProfile != "" {
+ platform.Spec.Profile = v1alpha1.TraitProfileByName(o.traitProfile)
+ }
if len(o.mavenRepositories) > 0 {
for _, r := range o.mavenRepositories {
@@ -318,6 +323,14 @@ func (o *installCmdOptions) validate(_ *cobra.Command, _ []string) error {
result = multierr.Append(result, err)
}
+ if o.traitProfile != "" {
+ tp := v1alpha1.TraitProfileByName(o.traitProfile)
+ if tp == v1alpha1.TraitProfile("") {
+ err := fmt.Errorf("unknown trait profile %s", o.traitProfile)
+ result = multierr.Append(result, err)
+ }
+ }
+
return result
}
diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go
index 698bee5..6f672ff 100644
--- a/pkg/trait/knative.go
+++ b/pkg/trait/knative.go
@@ -19,18 +19,19 @@ package trait
import (
"fmt"
+ "net/url"
"strings"
- "github.com/pkg/errors"
-
- "github.com/scylladb/go-set/strset"
-
"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
"github.com/apache/camel-k/pkg/metadata"
"github.com/apache/camel-k/pkg/util/envvar"
+ "github.com/pkg/errors"
+ "github.com/scylladb/go-set/strset"
knativeapi "github.com/apache/camel-k/pkg/apis/camel/v1alpha1/knative"
knativeutil "github.com/apache/camel-k/pkg/util/knative"
+ duck "github.com/knative/pkg/apis/duck/v1alpha1"
+ serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
)
type knativeTrait struct {
@@ -210,19 +211,13 @@ func (t *knativeTrait) configureChannels(e *Environment, env *knativeapi.CamelEn
if err != nil {
return err
}
- if c == nil || c.Status.Address.Hostname == "" {
- return errors.New("cannot find address of channel " + ch)
+ if c == nil {
+ return errors.Errorf("cannot find channel %s", ch)
}
- svc := knativeapi.CamelServiceDefinition{
- Name: ch,
- Host: c.Status.Address.Hostname,
- Port: 80,
- Protocol: knativeapi.CamelProtocolHTTP,
- ServiceType: knativeapi.CamelServiceTypeChannel,
- Metadata: map[string]string{
- knativeapi.CamelMetaServicePath: "/",
- },
+ svc, err := buildCamelServiceDefinitionFromAddressable(ch, knativeapi.CamelServiceTypeChannel, c.Status.Address)
+ if err != nil {
+ return errors.Wrapf(err, "cannot determine address of channel %s", ch)
}
env.Services = append(env.Services, svc)
}
@@ -270,19 +265,12 @@ func (t *knativeTrait) configureEndpoints(e *Environment, env *knativeapi.CamelE
if err != nil {
return err
}
- if s == nil || s.Status.Address == nil || s.Status.Address.Hostname == "" {
- return errors.New("cannot find address of endpoint " + endpoint)
+ if s == nil {
+ return errors.Errorf("cannot find endpoint %s", endpoint)
}
-
- svc := knativeapi.CamelServiceDefinition{
- Name: endpoint,
- Host: s.Status.Address.Hostname,
- Port: 80,
- Protocol: knativeapi.CamelProtocolHTTP,
- ServiceType: knativeapi.CamelServiceTypeEndpoint,
- Metadata: map[string]string{
- knativeapi.CamelMetaServicePath: "/",
- },
+ svc, err := buildCamelServiceDefinitionFromServiceStatus(endpoint, knativeapi.CamelServiceTypeEndpoint, s.Status)
+ if err != nil {
+ return errors.Wrapf(err, "cannot determine address of endpoint %s", endpoint)
}
env.Services = append(env.Services, svc)
}
@@ -301,3 +289,33 @@ func (t *knativeTrait) extractNames(names string) []string {
return answer
}
+
+// buildCamelServiceDefinitionFromServiceStatus creates a CamelServiceDefinition from a Knative ServiceStatus
+func buildCamelServiceDefinitionFromServiceStatus(name string, serviceType knativeapi.CamelServiceType, status serving.ServiceStatus) (knativeapi.CamelServiceDefinition, error) {
+ // build it using the Route URL information if available
+ if status.URL != nil && status.URL.Host != "" {
+ return knativeapi.BuildCamelServiceDefinition(name, serviceType, url.URL(*status.URL))
+ }
+ // fallback to using the addressable
+ if status.Address != nil {
+ return buildCamelServiceDefinitionFromAddressable(name, serviceType, *status.Address)
+ }
+ return knativeapi.CamelServiceDefinition{}, errors.New("cannot determine service hostname")
+}
+
+// buildCamelServiceDefinitionFromAddressable creates a CamelServiceDefinition from a Knative Addressable
+func buildCamelServiceDefinitionFromAddressable(name string, serviceType knativeapi.CamelServiceType, addressable duck.Addressable) (knativeapi.CamelServiceDefinition, error) {
+ // build it using the URL information if available
+ if addressable.URL != nil && addressable.URL.Host != "" {
+ return knativeapi.BuildCamelServiceDefinition(name, serviceType, url.URL(*addressable.URL))
+ }
+ // fallback to using hostname
+ if addressable.Hostname == "" {
+ return knativeapi.CamelServiceDefinition{}, errors.New("cannot determine addressable hostname")
+ }
+ serviceURL, err := url.Parse(fmt.Sprintf("http://%s", addressable.Hostname))
+ if err != nil {
+ return knativeapi.CamelServiceDefinition{}, err
+ }
+ return knativeapi.BuildCamelServiceDefinition(name, serviceType, *serviceURL)
+}
diff --git a/script/Makefile b/script/Makefile
index 90e2a15..f13df4c 100644
--- a/script/Makefile
+++ b/script/Makefile
@@ -106,6 +106,9 @@ test: build
test-integration: build
go test -timeout 30m -v ./e2e/... -tags=integration
+test-knative: build
+ go test -timeout 30m -v ./e2e/... -tags=knative
+
build-operator:
go build $(GOFLAGS) -o camel-k ./cmd/manager/*.go
@@ -124,7 +127,7 @@ build-olm:
./script/build_olm.sh $(VERSION)
build-compile-integration-tests:
- go test -c -tags=integration ./e2e/*.go
+ go test -c -tags="integration knative" ./e2e/*.go
clean:
# go clean fails if modules support are turned on as it tries to