This is an automated email from the ASF dual-hosted git repository.
astefanutti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/main by this push:
new 4cd5695 feat(trait): jvm classpath
4cd5695 is described below
commit 4cd569535996415befb77b4f9a881d40b684b04a
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Tue Jun 22 10:43:31 2021 +0200
feat(trait): jvm classpath
* Added a new option to include classpaths
* E2E test
* Examples and docs
Closes #2414
---
deploy/traits.yaml | 3 ++
docs/modules/ROOT/pages/apis/crds-html.adoc | 14 +++++++
docs/modules/traits/pages/jvm.adoc | 11 +++++
e2e/common/traits/files/jvm/Classpath.java | 27 ++++++++++++
e2e/common/traits/files/jvm/sample-1.0.jar | Bin 0 -> 2372 bytes
e2e/common/traits/jvm_test.go | 61 ++++++++++++++++++++++++++++
e2e/support/test_support.go | 15 +++++++
examples/README.md | 10 ++++-
examples/traits/README.md | 3 ++
examples/traits/jvm/Classpath.java | 32 +++++++++++++++
examples/traits/jvm/README.md | 3 ++
examples/traits/jvm/sample-1.0.jar | Bin 0 -> 2372 bytes
pkg/trait/jvm.go | 5 +++
pkg/trait/jvm_test.go | 33 +++++++++++++++
14 files changed, 216 insertions(+), 1 deletion(-)
diff --git a/deploy/traits.yaml b/deploy/traits.yaml
index 64e7f7a..9f3ed55 100755
--- a/deploy/traits.yaml
+++ b/deploy/traits.yaml
@@ -446,6 +446,9 @@ traits:
- name: options
type: '[]string'
description: A list of JVM options
+ - name: classpath
+ type: string
+ description: Additional JVM classpath (use `Linux` classpath separator)
- name: kamelets
platform: true
profiles:
diff --git a/docs/modules/ROOT/pages/apis/crds-html.adoc
b/docs/modules/ROOT/pages/apis/crds-html.adoc
index 158c2c9..7fe37e6 100644
--- a/docs/modules/ROOT/pages/apis/crds-html.adoc
+++ b/docs/modules/ROOT/pages/apis/crds-html.adoc
@@ -3688,6 +3688,7 @@ string
<a
href="#camel.apache.org/v1.CamelArtifactDependency">CamelArtifactDependency</a>,
<a href="#camel.apache.org/v1.CamelLoader">CamelLoader</a>,
<a href="#camel.apache.org/v1.Capability">Capability</a>,
+<a href="#camel.apache.org/v1.MavenSpec">MavenSpec</a>,
<a href="#camel.apache.org/v1.RuntimeSpec">RuntimeSpec</a>)
</p>
<div>
@@ -3830,6 +3831,19 @@ Kubernetes meta/v1.Duration
<td>
</td>
</tr>
+<tr>
+<td>
+<code>extension</code><br/>
+<em>
+<a href="#camel.apache.org/v1.MavenArtifact">
+[]MavenArtifact
+</a>
+</em>
+</td>
+<td>
+<p>Maven build extensions <a
href="https://maven.apache.org/guides/mini/guide-using-extensions.html">https://maven.apache.org/guides/mini/guide-using-extensions.html</a></p>
+</td>
+</tr>
</tbody>
</table>
<h3 id="camel.apache.org/v1.PlatformInjectable">PlatformInjectable
diff --git a/docs/modules/traits/pages/jvm.adoc
b/docs/modules/traits/pages/jvm.adoc
index dcf5705..e60a5e1 100755
--- a/docs/modules/traits/pages/jvm.adoc
+++ b/docs/modules/traits/pages/jvm.adoc
@@ -47,6 +47,17 @@ The following configuration options are available:
| []string
| A list of JVM options
+| jvm.classpath
+| string
+| Additional JVM classpath (use `Linux` classpath separator)
+
|===
// End of autogenerated code - DO NOT EDIT! (configuration)
+
+== Examples
+
+* Include an additional classpath to the `Integration`:
++
+[source,console]
+$ kamel run -t
jvm.classpath=/path/to/my-dependency.jar:/path/to/another-dependency.jar ...
diff --git a/e2e/common/traits/files/jvm/Classpath.java
b/e2e/common/traits/files/jvm/Classpath.java
new file mode 100644
index 0000000..a405eea
--- /dev/null
+++ b/e2e/common/traits/files/jvm/Classpath.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.example.MyClass;
+
+public class Classpath extends RouteBuilder {
+ @Override
+ public void configure() throws Exception {
+ from("timer:tick")
+ .log(MyClass.sayHello());
+ }
+}
\ No newline at end of file
diff --git a/e2e/common/traits/files/jvm/sample-1.0.jar
b/e2e/common/traits/files/jvm/sample-1.0.jar
new file mode 100644
index 0000000..4996795
Binary files /dev/null and b/e2e/common/traits/files/jvm/sample-1.0.jar differ
diff --git a/e2e/common/traits/jvm_test.go b/e2e/common/traits/jvm_test.go
new file mode 100644
index 0000000..c15c977
--- /dev/null
+++ b/e2e/common/traits/jvm_test.go
@@ -0,0 +1,61 @@
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go ->
Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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 traits
+
+import (
+ "io/ioutil"
+ "testing"
+
+ . "github.com/onsi/gomega"
+ "github.com/stretchr/testify/assert"
+
+ v1 "k8s.io/api/core/v1"
+
+ . "github.com/apache/camel-k/e2e/support"
+ camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestJVMTrait(t *testing.T) {
+ WithNewTestNamespace(t, func(ns string) {
+ Expect(Kamel("install", "-n", ns).Execute()).To(Succeed())
+
+ // Store a configmap holding a jar
+ var cmData = make(map[string][]byte)
+ // We calculate the expected content
+ source, err := ioutil.ReadFile("./files/jvm/sample-1.0.jar")
+ assert.Nil(t, err)
+ cmData["sample-1.0.jar"] = source
+ err = NewBinaryConfigmap(ns, "my-deps", cmData)
+ assert.Nil(t, err)
+
+ t.Run("JVM trait classpath", func(t *testing.T) {
+ Expect(Kamel("run", "-n", ns,
"./files/jvm/Classpath.java",
+ "--resource", "configmap:my-deps",
+ "-t",
"jvm.classpath=/etc/camel/resources/my-deps/sample-1.0.jar",
+ ).Execute()).To(Succeed())
+ Eventually(IntegrationPodPhase(ns, "classpath"),
TestTimeoutMedium).Should(Equal(v1.PodRunning))
+ Eventually(IntegrationCondition(ns, "classpath",
camelv1.IntegrationConditionReady),
TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+ Eventually(IntegrationLogs(ns, "classpath"),
TestTimeoutShort).Should(ContainSubstring("Hello World!"))
+ Expect(Kamel("delete", "--all", "-n",
ns).Execute()).To(Succeed())
+ })
+ })
+}
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index d49c63f..01ca502 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -675,6 +675,21 @@ func NewPlainTextConfigmap(ns string, name string, data
map[string]string) error
return TestClient().Create(TestContext, &cm)
}
+func NewBinaryConfigmap(ns string, name string, data map[string][]byte) error {
+ cm := corev1.ConfigMap{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "ConfigMap",
+ APIVersion: corev1.SchemeGroupVersion.String(),
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: ns,
+ Name: name,
+ },
+ BinaryData: data,
+ }
+ return TestClient().Create(TestContext, &cm)
+}
+
func NewPlainTextSecret(ns string, name string, data map[string]string) error {
sec := corev1.Secret{
TypeMeta: metav1.TypeMeta{
diff --git a/examples/README.md b/examples/README.md
index c6fe58d..03b605f 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -42,4 +42,12 @@ As soon as you will learn the basic stuff, you will like to
try the new advanced
| Polyglot | Polyglot integration examples | [see examples](./polyglot/)|
| Pulsar | Pulsar usage | [see examples](./pulsar/)|
| Saga | Saga pattern example | [see examples](./saga/)|
-| Tekton | Tekton tutorial | [see examples](./tekton/)|
\ No newline at end of file
+| Tekton | Tekton tutorial | [see examples](./tekton/)|
+
+## Traits usage examples
+
+Traits configuration will be very helpful to fine tune your `Integration`.
Here a few examples:
+
+| Type | Description | Link |
+|---|---|---|
+| JVM | How to use `JVM` trait| [see examples](./traits/jvm/)|
\ No newline at end of file
diff --git a/examples/traits/README.md b/examples/traits/README.md
new file mode 100644
index 0000000..6ddb21e
--- /dev/null
+++ b/examples/traits/README.md
@@ -0,0 +1,3 @@
+# Camel K Traits
+
+In this section you will find examples about fine tuning your `Integration`
using `trait` capability. Have a look at each directory containing example for
the available traits.
diff --git a/examples/traits/jvm/Classpath.java
b/examples/traits/jvm/Classpath.java
new file mode 100644
index 0000000..40d76cd
--- /dev/null
+++ b/examples/traits/jvm/Classpath.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+// Create a configmap holding a jar in order to simulate the presence of a
dependency on the runtime image
+// kubectl create configmap my-dep --from-file=sample-1.0.jar
+
+//kamel run --resource configmap:my-dep -t
jvm.classpath=/etc/camel/resources/my-dep/sample-1.0.jar Classpath.java --dev
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.example.MyClass;
+
+public class Classpath extends RouteBuilder {
+ @Override
+ public void configure() throws Exception {
+ from("timer:tick")
+ .log(MyClass.sayHello());
+ }
+}
\ No newline at end of file
diff --git a/examples/traits/jvm/README.md b/examples/traits/jvm/README.md
new file mode 100644
index 0000000..f7a2896
--- /dev/null
+++ b/examples/traits/jvm/README.md
@@ -0,0 +1,3 @@
+# Camel K JVM Trait
+
+In this section you will find examples about fine tuning your `Integration`
using **JVM** `trait` capability.
\ No newline at end of file
diff --git a/examples/traits/jvm/sample-1.0.jar
b/examples/traits/jvm/sample-1.0.jar
new file mode 100644
index 0000000..4996795
Binary files /dev/null and b/examples/traits/jvm/sample-1.0.jar differ
diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go
index 44da721..1371e03 100644
--- a/pkg/trait/jvm.go
+++ b/pkg/trait/jvm.go
@@ -54,6 +54,8 @@ type jvmTrait struct {
DebugAddress string `property:"debug-address"
json:"debugAddress,omitempty"`
// A list of JVM options
Options []string `property:"options" json:"options,omitempty"`
+ // Additional JVM classpath (use `Linux` classpath separator)
+ Classpath string `property:"classpath" json:"classpath,omitempty"`
}
func newJvmTrait() Trait {
@@ -98,6 +100,9 @@ func (t *jvmTrait) Apply(e *Environment) error {
classpath.Add("./resources")
classpath.Add(configResourcesMountPath)
classpath.Add(resourcesDefaultMountPath)
+ if t.Classpath != "" {
+ classpath.Add(strings.Split(t.Classpath, ":")...)
+ }
for _, artifact := range kit.Status.Artifacts {
classpath.Add(artifact.Target)
diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go
index b568133..ebf7909b 100644
--- a/pkg/trait/jvm_test.go
+++ b/pkg/trait/jvm_test.go
@@ -218,6 +218,39 @@ func TestApplyJvmTraitWithExternalKitType(t *testing.T) {
assert.Equal(t, "io.quarkus.bootstrap.runner.QuarkusEntryPoint",
container.Args[2])
}
+func TestApplyJvmTraitWithClasspath(t *testing.T) {
+ trait, environment :=
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+ trait.Classpath = "/path/to/my-dep.jar:/path/to/another/dep.jar"
+ d := appsv1.Deployment{
+ Spec: appsv1.DeploymentSpec{
+ Template: corev1.PodTemplateSpec{
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name:
defaultContainerName,
+ VolumeMounts:
[]corev1.VolumeMount{
+ {
+
MountPath: "/mount/path",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ environment.Resources.Add(&d)
+ err := trait.Apply(environment)
+
+ assert.Nil(t, err)
+ assert.Equal(t, []string{
+ "-cp",
+ fmt.Sprintf("./resources:%s:%s:/mount/path:%s:%s",
configResourcesMountPath, resourcesDefaultMountPath,
+ "/path/to/another/dep.jar", "/path/to/my-dep.jar"),
+ "io.quarkus.bootstrap.runner.QuarkusEntryPoint",
+ }, d.Spec.Template.Spec.Containers[0].Args)
+}
+
func createNominalJvmTest(kitType string) (*jvmTrait, *Environment) {
catalog, _ := camel.DefaultCatalog()