Chapter 3. Developing and running Camel K integrations This chapter explains how to set up your development environment and how to develop and deploy simple Camel K integrations written in Java and YAML. It also shows how to use the kamel command line to manage Camel K integrations at runtime. For example, this includes running, describing, logging, and deleting integrations. Section 3.1, "Setting up your Camel K development environment" Section 3.2, "Developing Camel K integrations in Java" Section 3.3, "Developing Camel K integrations in YAML" Section 3.4, "Running Camel K integrations" Section 3.5, "Running Camel K integrations in development mode" Section 3.6, "Running Camel K integrations using modeline" Section 3.7, "Camel Runtimes (aka "sourceless" Integrations)" Section 3.8, "Importing existing Camel applications" Section 3.9, "Build" Section 3.10, "Promoting across environments" 3.1. Setting up your Camel K development environment You must set up your environment with the recommended development tooling before you can automatically deploy the Camel K quick start tutorials. This section explains how to install the recommended Visual Studio (VS) Code IDE and the extensions that it provides for Camel K. Note The Camel K VS Code extensions are community features. VS Code is recommended for ease of use and the best developer experience of Camel K. This includes automatic completion of Camel DSL code and Camel K traits. However, you can manually enter your code and tutorial commands using your chosen IDE instead of VS Code. Prerequisites You must have access to an OpenShift cluster on which the Camel K Operator and OpenShift Serverless Operator are installed: Installing Camel K Installing OpenShift Serverless from the OperatorHub Procedure Install VS Code on your development platform. For example, on Red Hat Enterprise Linux: Install the required key and repository: USD sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc USD sudo sh -c 'echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo' Update the cache and install the VS Code package: USD yum check-update USD sudo yum install code For details on installing on other platforms, see the VS Code installation documentation . Enter the code command to launch the VS Code editor. For more details, see the VS Code command line documentation . Install the VS Code Camel Extension Pack, which includes the extensions required for Camel K. For example, in VS Code: In the left navigation bar, click Extensions . In the search box, enter Apache Camel . Select the Extension Pack for Apache Camel by Red Hat , and click Install . For more details, see the instructions for the Extension Pack for Apache Camel by Red Hat . Additional resources VS Code Getting Started documentation VS Code Tooling for Apache Camel K by Red Hat extension VS Code Language Support for Apache Camel by Red Hat extension Apache Camel K and VS Code tooling example To upgrade your Camel application from Camel 3.x to 3.y see, Camel 3.x Upgrade Guide . 3.2. Developing Camel K integrations in Java This section shows how to develop a simple Camel K integration in Java DSL. Writing an integration in Java to be deployed using Camel K is the same as defining your routing rules in Camel. However, you do not need to build and package the integration as a JAR when using Camel K. You can use any Camel component directly in your integration routes. Camel K automatically handles the dependency management and imports all the required libraries from the Camel catalog using code inspection. Prerequisites Setting up your Camel K development environment Procedure Enter the camel init command to generate a simple Java integration file. For example: USD camel init HelloCamelK.java Open the generated integration file in your IDE and edit as appropriate. For example, the HelloCamelK.java integration automatically includes the Camel timer and log components to help you get started: // camel-k: language=java import org.apache.camel.builder.RouteBuilder; public class HelloCamelK extends RouteBuilder { @Override public void configure() throws Exception { // Write your routes here, for example: from("timer:java?period=1s") .routeId("java") .setBody() .simple("Hello Camel K from USD{routeId}") .to("log:info"); } } steps Running Camel K integrations 3.3. Developing Camel K integrations in YAML This section explains how to develop a simple Camel K integration in YAML DSL. Writing an integration in YAML to be deployed using Camel K is the same as defining your routing rules in Camel. You can use any Camel component directly in your integration routes. Camel K automatically handles the dependency management and imports all the required libraries from the Camel catalog using code inspection. Prerequisites Setting up your Camel K development environment Procedure Enter the camel init command to generate a simple YAML integration file. For example: USD camel init hello.camelk.yaml Open the generated integration file in your IDE and edit as appropriate. For example, the hello.camelk.yaml integration automatically includes the Camel timer and log components to help you get started: # Write your routes here, for example: - from: uri: "timer:yaml" parameters: period: "1s" steps: - set-body: constant: "Hello Camel K from yaml" - to: "log:info" 3.4. Running Camel K integrations You can run Camel K integrations in the cloud on your OpenShift cluster from the command line using the kamel run command. Prerequisites Setting up your Camel K development environment . You must already have a Camel integration written in Java or YAML DSL. Procedure Log into your OpenShift cluster using the oc client tool, for example: USD oc login --token=my-token --server=https://my-cluster.example.com:6443 Ensure that the Camel K Operator is running, for example: USD oc get pod NAME READY STATUS RESTARTS AGE camel-k-operator-86b8d94b4-pk7d6 1/1 Running 0 6m28s Enter the kamel run command to run your integration in the cloud on OpenShift. For example: Java example USD kamel run HelloCamelK.java integration "hello-camel-k" created YAML example USD kamel run hello.camelk.yaml integration "hello" created Enter the kamel get command to check the status of the integration: USD kamel get NAME PHASE KIT hello Building Kit myproject/kit-bq666mjej725sk8sn12g When the integration runs for the first time, Camel K builds the integration kit for the container image, which downloads all the required Camel modules and adds them to the image classpath. Enter kamel get again to verify that the integration is running: USD kamel get NAME PHASE KIT hello Running myproject/kit-bq666mjej725sk8sn12g Enter the kamel log command to print the log to stdout : USD kamel log hello [1] 2021-08-11 17:58:40,573 INFO [org.apa.cam.k.Runtime] (main) Apache Camel K Runtime 1.7.1.fuse-800025-redhat-00001 [1] 2021-08-11 17:58:40,653 INFO [org.apa.cam.qua.cor.CamelBootstrapRecorder] (main) bootstrap runtime: org.apache.camel.quarkus.main.CamelMainRuntime [1] 2021-08-11 17:58:40,844 INFO [org.apa.cam.k.lis.SourcesConfigurer] (main) Loading routes from: SourceDefinition{name='camel-k-embedded-flow', language='yaml', location='file:/etc/camel/sources/camel-k-embedded-flow.yaml', } [1] 2021-08-11 17:58:41,216 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Routes startup summary (total:1 started:1) [1] 2021-08-11 17:58:41,217 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started route1 (timer://yaml) [1] 2021-08-11 17:58:41,217 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 3.10.0.fuse-800010-redhat-00001 (camel-1) started in 136ms (build:0ms init:100ms start:36ms) [1] 2021-08-11 17:58:41,268 INFO [io.quarkus] (main) camel-k-integration 1.6.6 on JVM (powered by Quarkus 1.11.7.Final-redhat-00009) started in 2.064s. [1] 2021-08-11 17:58:41,269 INFO [io.quarkus] (main) Profile prod activated. [1] 2021-08-11 17:58:41,269 INFO [io.quarkus] (main) Installed features: [camel-bean, camel-core, camel-k-core, camel-k-runtime, camel-log, camel-support-common, camel-timer, camel-yaml-dsl, cdi] [1] 2021-08-11 17:58:42,423 INFO [info] (Camel (camel-1) thread #0 - timer://yaml) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from yaml] ... Press Ctrl-C to terminate logging in the terminal. Additional resources For more details on the kamel run command, enter kamel run --help For faster deployment turnaround times, see Running Camel K integrations in development mode For details of development tools to run integrations, see VS Code Tooling for Apache Camel K by Red Hat See also Managing Camel K integrations Running An Integration Without CLI You can run an integration without a CLI (Command Line Interface) and create an Integration Custom Resource with the configuration to run your application. For example, execute the following sample route. It returns the expected Integration Custom Resource. Save this custom resource in a yaml file, my-integration.yaml . Now, run the integration that contains the Integration Custom Resource using the oc command line, the UI, or the API to call the OpenShift cluster. In the following example, oc CLI is used from the command line. The operator runs the Integration. Note Kubernetes supports Structural Schemas for CustomResourceDefinitions. For more details about Camel K traits see, Camel K trait configuration reference . Schema changes on Custom Resources The strongly-typed Trait API imposes changes on the following CustomResourceDefinitions: integrations , integrationkits', and `integrationplatforms. Trait properties under spec.traits.<trait-id>.configuration are now defined directly under spec.traits.<trait-id>. vvv Backward compatibility is possible in this implementation. To achieve backward compatibility, the Configuration field with RawMessage type is provided for each trait type, so that the existing integrations and resources are read from the new Red Hat build of Apache Camel K version. When the old integrations and resources are read, the legacy configuration in each trait (if any) is migrated to the new Trait API fields. If the values are predefined on the new API fields, they precede the legacy ones. 3.5. Running Camel K integrations in development mode You can run Camel K integrations in development mode on your OpenShift cluster from the command line. Using development mode, you can iterate quickly on integrations in development and get fast feedback on your code. When you specify the kamel run command with the --dev option, this deploys the integration in the cloud immediately and shows the integration logs in the terminal. You can then change the code and see the changes automatically applied instantly to the remote integration Pod on OpenShift. The terminal automatically displays all redeployments of the remote integration in the cloud. Note The artifacts generated by Camel K in development mode are identical to those that you run in production. The purpose of development mode is faster development. Prerequisites Setting up your Camel K development environment . You must already have a Camel integration written in Java or YAML DSL. Procedure Log into your OpenShift cluster using the oc client tool, for example: USD oc login --token=my-token --server=https://my-cluster.example.com:6443 Ensure that the Camel K Operator is running, for example: USD oc get pod NAME READY STATUS RESTARTS AGE camel-k-operator-86b8d94b4-pk7d6 1/1 Running 0 6m28s Enter the kamel run command with --dev to run your integration in development mode on OpenShift in the cloud. The following shows a simple Java example: USD kamel run HelloCamelK.java --dev Condition "IntegrationPlatformAvailable" is "True" for Integration hello-camel-k: test/camel-k Integration hello-camel-k in phase "Initialization" Integration hello-camel-k in phase "Building Kit" Condition "IntegrationKitAvailable" is "True" for Integration hello-camel-k: kit-c49sqn4apkb4qgn55ak0 Integration hello-camel-k in phase "Deploying" Progress: integration "hello-camel-k" in phase Initialization Progress: integration "hello-camel-k" in phase Building Kit Progress: integration "hello-camel-k" in phase Deploying Integration hello-camel-k in phase "Running" Condition "DeploymentAvailable" is "True" for Integration hello-camel-k: deployment name is hello-camel-k Progress: integration "hello-camel-k" in phase Running Condition "CronJobAvailable" is "False" for Integration hello-camel-k: different controller strategy used (deployment) Condition "KnativeServiceAvailable" is "False" for Integration hello-camel-k: different controller strategy used (deployment) Condition "Ready" is "False" for Integration hello-camel-k Condition "Ready" is "True" for Integration hello-camel-k [1] Monitoring pod hello-camel-k-7f85df47b8-js7cb ... ... [1] 2021-08-11 18:34:44,069 INFO [org.apa.cam.k.Runtime] (main) Apache Camel K Runtime 1.7.1.fuse-800025-redhat-00001 [1] 2021-08-11 18:34:44,167 INFO [org.apa.cam.qua.cor.CamelBootstrapRecorder] (main) bootstrap runtime: org.apache.camel.quarkus.main.CamelMainRuntime [1] 2021-08-11 18:34:44,362 INFO [org.apa.cam.k.lis.SourcesConfigurer] (main) Loading routes from: SourceDefinition{name='HelloCamelK', language='java', location='file:/etc/camel/sources/HelloCamelK.java', } [1] 2021-08-11 18:34:46,180 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Routes startup summary (total:1 started:1) [1] 2021-08-11 18:34:46,180 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started java (timer://java) [1] 2021-08-11 18:34:46,180 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 3.10.0.fuse-800010-redhat-00001 (camel-1) started in 243ms (build:0ms init:213ms start:30ms) [1] 2021-08-11 18:34:46,190 INFO [io.quarkus] (main) camel-k-integration 1.6.6 on JVM (powered by Quarkus 1.11.7.Final-redhat-00009) started in 3.457s. [1] 2021-08-11 18:34:46,190 INFO [io.quarkus] (main) Profile prod activated. [1] 2021-08-11 18:34:46,191 INFO [io.quarkus] (main) Installed features: [camel-bean, camel-core, camel-java-joor-dsl, camel-k-core, camel-k-runtime, camel-log, camel-support-common, camel-timer, cdi] [1] 2021-08-11 18:34:47,200 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java] [1] 2021-08-11 18:34:48,180 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java] [1] 2021-08-11 18:34:49,180 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java] ... Edit the content of your integration DSL file, save your changes, and see the changes displayed instantly in the terminal. For example: ... integration "hello-camel-k" updated ... [2] 2021-08-11 18:40:54,173 INFO [org.apa.cam.k.Runtime] (main) Apache Camel K Runtime 1.7.1.fuse-800025-redhat-00001 [2] 2021-08-11 18:40:54,209 INFO [org.apa.cam.qua.cor.CamelBootstrapRecorder] (main) bootstrap runtime: org.apache.camel.quarkus.main.CamelMainRuntime [2] 2021-08-11 18:40:54,301 INFO [org.apa.cam.k.lis.SourcesConfigurer] (main) Loading routes from: SourceDefinition{name='HelloCamelK', language='java', location='file:/etc/camel/sources/HelloCamelK.java', } [2] 2021-08-11 18:40:55,796 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Routes startup summary (total:1 started:1) [2] 2021-08-11 18:40:55,796 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started java (timer://java) [2] 2021-08-11 18:40:55,797 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 3.10.0.fuse-800010-redhat-00001 (camel-1) started in 174ms (build:0ms init:147ms start:27ms) [2] 2021-08-11 18:40:55,803 INFO [io.quarkus] (main) camel-k-integration 1.6.6 on JVM (powered by Quarkus 1.11.7.Final-redhat-00009) started in 3.025s. [2] 2021-08-11 18:40:55,808 INFO [io.quarkus] (main) Profile prod activated. [2] 2021-08-11 18:40:55,809 INFO [io.quarkus] (main) Installed features: [camel-bean, camel-core, camel-java-joor-dsl, camel-k-core, camel-k-runtime, camel-log, camel-support-common, camel-timer, cdi] [2] 2021-08-11 18:40:56,810 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java] [2] 2021-08-11 18:40:57,793 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java] ... Press Ctrl-C to terminate logging in the terminal. Additional resources For more details on the kamel run command, enter kamel run --help For details of development tools to run integrations, see VS Code Tooling for Apache Camel K by Red Hat Managing Camel K integrations Configuring Camel K integration dependencies 3.6. Running Camel K integrations using modeline You can use the Camel K modeline to specify multiple configuration options in a Camel K integration source file, which are executed at runtime. This creates efficiencies by saving you the time of re-entering multiple command line options and helps to prevent input errors. The following example shows a modeline entry from a Java integration file that enables 3scale and limits the integration container memory. Prerequisites Setting up your Camel K development environment You must already have a Camel integration written in Java or YAML DSL. Procedure Add a Camel K modeline entry to your integration file. For example: ThreeScaleRest.java // camel-k: trait=3scale.enabled=true trait=container.limit-memory=256Mi 1 import org.apache.camel.builder.RouteBuilder; public class ThreeScaleRest extends RouteBuilder { @Override public void configure() throws Exception { rest().get("/") .to("direct:x"); from("direct:x") .setBody().constant("Hello"); } } Enables both the container and 3scale traits, to expose the route through 3scale and to limit the container memory. Run the integration, for example: The kamel run command outputs any modeline options specified in the integration, for example: Modeline options have been loaded from source files Full command: kamel run ThreeScaleRest.java --trait=3scale.enabled=true --trait=container.limit-memory=256Mi Additional resources Camel K modeline options For details of development tools to run modeline integrations, see Introducing IDE support for Apache Camel K Modeline . 3.7. Camel Runtimes (aka "sourceless" Integrations) Camel K can run any runtime available in Apache Camel. However, this is possible only when the Camel application was previously built and packaged into a container image. Also, if you run through this option, some of the features offered by the operator may not be available. For example, you cannot discover Camel capabilities because the source is not available to the operator but embedded in the container image. This option is good if you are building your applications externally, that is, via a CICD technology, and you want to delegate the operator only the "operational" part, taking care on your own of the building and publishing part. Note You may loose more features, such as incremental image and container kit reusability. 3.7.1. Build externally, run via Operator Let us see the following example. You can have your own Camel application or just create a basic one for the purpose via Camel JBang ( camel init test.yaml ). Once your development is over, you can test locally via camel run test.yaml and export in the runtime of your choice via camel export test.yaml --runtime ... . The above step is a quick way to create a basic Camel application in any of the available runtime. Let us imagine we have done this for Camel Main or we already have a Camel application as a Maven project. As we want to take care of the build part by ourselves, we create a pipeline to build, containerize and push the container to a registry (see as a reference Camel K Tekton example ). At this stage we do have a container image with our Camel application. We can use the kamel CLI to run our Camel application via kamel run --image docker.io/my-org/my-app:1.0.0 tuning, if it is the case, with any of the trait or configuration required. Remember that when you run an Integration with this option, the operator creates a synthetic IntegrationKit. Note Certain traits (that is, builder traits) are not available when running an application built externally. In a few seconds (there is no build involved) you must have your application up and running and you can monitor and operate with Camel K as usual. 3.7.2. Traits and dependencies Certain Camel K operational aspect may be driven by traits. When you are building the application outside the operator, some of those traits are not executed as they are executed during the building phase that we are skipping when running sourceless Integrations . 3.8. Importing existing Camel applications You already have a Camel application running on your cluster, and you have created it via a manual deployment, a CICD or any other deployment mechanism you have in place. Since the Camel K operator is meant to operate any Camel application out there, you are able to import it and monitor in a similar method of any other Camel K managed Integration . This feature is disabled by default. To enable it, you must run the operator deployment with an environment variable, CAMEL_K_SYNTHETIC_INTEGRATIONS , set to true . Note You are only able to monitor the synthetic Integrations. Camel K does not alter the lifecycle of non managed Integrations (that is, rebuild the original application). Important The operator does not alter any field of the original application to avoid breaking any deployment procedure which is already in place. As it cannot make any assumption on the way the application is built and deployed, it is only able to watch for any changes happening around it. 3.8.1. Deploy externally, monitor via Camel K Operator An imported Integration is known as synthetic Integration . You can import any Camel application deployed as a Deployment , CronJob or Knative Service . We control this behavior via a label ( camel.apache.org/integration ) that the user must apply on the Camel application (either manually or introducing in the deployment process, that is, via CICD). Note The example here works in a similar way using CronJob and Knative Service. As an example, we show how to import a Camel application which was deployed with the Deployment kind. Let us assume it is called my-deploy . USD oc label deploy my-camel-sb-svc camel.apache.org/integration=my-it The operator immediately creates a synthetic Integration. USD oc get it NAMESPACE NAME PHASE RUNTIME PROVIDER RUNTIME VERSION KIT REPLICAS test-79c385c3-d58e-4c28-826d-b14b6245f908 my-it Running You can see, it is in Running status phase. However, after checking the conditions, you now see that the Integration is not yet fully monitored. This is expected because of the way Camel K operator monitor Pods. It requires the same label applied to the Deployment is inherited by the generated Pods. For this reason, beside labelling the Deployment, we must add a label in the Deployment template. USD oc patch deployment my-camel-sb-svc --patch '{"spec": {"template": {"metadata": {"labels": {"camel.apache.org/integration": "my-it"}}}}}' This operation can also be performed manually or automated in the deployment procedure. We can now see that the operator is able to monitor the status of the Pods. USD oc get it NAMESPACE NAME PHASE RUNTIME PROVIDER RUNTIME VERSION KIT REPLICAS test-79c385c3-d58e-4c28-826d-b14b6245f908 my-it Running 1 From now on, you are able to monitor the status of the synthetic Integration in a similar method as you do with managed Integrations. If, for example, your Deployment scales up or down, then, you see this information reflecting accordingly. USD oc scale deployment my-camel-sb-svc --replicas 2 USD oc get it NAMESPACE NAME PHASE RUNTIME PROVIDER RUNTIME VERSION KIT REPLICAS test-79c385c3-d58e-4c28-826d-b14b6245f908 my-it Running 2 3.9. Build A Build resource describes the process of assembling a container image that copes with the requirement of an Integration or IntegrationKit . The result of a build is an IntegrationKit that must be reused for multiple Integrations . type Build struct { Spec BuildSpec 1 Status BuildStatus 2 } type BuildSpec struct { Tasks []Task 3 } 1 The desired state 2 The status of the object at current time 3 The build tasks Note The full go definition can be found here . 3.9.1. Build strategy You can choose from different build strategies. The build strategy defines how a build must be executed and following are the available strategies. buildStrategy: pod (each build is ran in a separate pod, the operator monitors the pod state) buildStrategy: routine (each build is ran as a go routine inside the operator pod) Note Routine is the default strategy. The following description allows you to decide when to use which strategy. Routine : provides slightly faster builds as no additional pod is started, and loaded build dependencies (e.g. Maven dependencies) are cached between builds. Good for normal amount of builds being executed and only few builds running in parallel. Pod : prevents memory pressure on the operator as the build does not consume CPU and memory from the operator go runtime. Good for many builds being executed and many parallel builds. 3.9.2. Build queues IntegrationKits and its base images must be reused for multiple Integrations to accomplish an efficient resource management and to optimize build and startup times for Camel K Integrations. To reuse images, the operator is going to queue builds in sequential order. This way the operator is able to use efficient image layering for Integrations. Note By default, builds are queued sequentially based on their layout (e.g. native, fast-jar) and the build namespace. However, builds may not run sequentially but in parallel to each other based on certain criteria. For instance, native builds will always run in parallel to other builds. Also, when the build requires to run with a custom IntegrationPlatform it may run in parallel to other builds that run with the default operator IntegrationPlatform. In general, when there is no chance to reuse the build's image layers, the build is eager to run in parallel to other builds. Therefore, to avoid having many builds running in parallel, the operator uses a maximum number of running builds setting that limits the amount of builds running. You can set this limit in the IntegrationPlatform settings. The default values for this limitation is based on the build strategy. buildStrategy: pod (MaxRunningBuilds=10) buildStrategy: routine (MaxRunningBuilds=3) 3.10. Promoting across environments As soon as you have an Integration running in your cluster, you can move that integration to a higher environment. That is, you can test your integration in a development environment, and, after obtaining the result, you can move it into a production environment. Camel K achieves this goal by using the kamel promote command. With this command you can move an integration from one namespace to another. Prerequisites Setting up your Camel K development environment You must already have a Camel integration written in Java or YAML DSL. Ensure that both the source operator and the destination operator are using the same container registry, default registry (if Camel K operator is installed via OperatorHub) is registry.redhat.io Also ensure that the destination namespace provides the required Configmaps, Secrets or Kamelets required by the integration. Note To use the same container registry, you can use the --registry option during installation phase or change the IntegrationPlatform to reflect that accordingly. Code example Following is a simple integration that uses a Configmap to expose some message on an HTTP endpoint. You can start creating such an integration and testing in a namespace called development . kubectl create configmap my-cm --from-literal=greeting="hello, I am development!" -n development PromoteServer.java import org.apache.camel.builder.RouteBuilder; public class PromoteServer extends RouteBuilder { @Override public void configure() throws Exception { from("platform-http:/hello?httpMethodRestrict=GET").setBody(simple("resource:classpath:greeting")); } } Now run it. kamel run --dev -n development PromoteServer.java --config configmap:my-cm [-t service.node-port=true] You must tweak the service trait, depending on the Kubernetes platform and the level of exposure you want to provide. After that you can test it. curl http://192.168.49.2:32116/hello hello, I am development! After testing of your integration, you can move it to a production environment. You must have the destination environment (a Openshift namespace) ready with an operator (sharing the same operator source container registry) and any configuration, such as the configmap you have used here. For that scope, create one on the destination namespace. kubectl create configmap my-cm --from-literal=greeting="hello, I am production!" -n production Note For security reasons, there is a check to ensure that the expected resources such as Configmaps, Secrets and Kamelets are present on the destination. If any of these resources are missing, the integration does not move. You can now promote your integration. kamel promote promote-server -n development --to production kamel logs promote-server -n production Test the promoted integration. curl http://192.168.49.2:30764/hello hello, I am production! Since the Integration is reusing the same container image, the new application is executed immediately. Also, the immutability of the Integration is assured as the container used is exactly the same as the one tested in development (changes are just the configurations). Note The integration running in the test is not altered in any way and keeps running until you stop it.

Commands:
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo sh -c 'echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo'
yum check-update sudo yum install code
camel init HelloCamelK.java
// camel-k: language=java import org.apache.camel.builder.RouteBuilder; public class HelloCamelK extends RouteBuilder { @Override public void configure() throws Exception { // Write your routes here, for example: from("timer:java?period=1s") .routeId("java") .setBody() .simple("Hello Camel K from USD{routeId}") .to("log:info"); } }
camel init hello.camelk.yaml
Write your routes here, for example: - from: uri: "timer:yaml" parameters: period: "1s" steps: - set-body: constant: "Hello Camel K from yaml" - to: "log:info"
oc login --token=my-token --server=https://my-cluster.example.com:6443
oc get pod NAME READY STATUS RESTARTS AGE camel-k-operator-86b8d94b4-pk7d6 1/1 Running 0 6m28s
kamel run HelloCamelK.java integration "hello-camel-k" created
kamel run hello.camelk.yaml integration "hello" created
kamel get NAME PHASE KIT hello Building Kit myproject/kit-bq666mjej725sk8sn12g
kamel get NAME PHASE KIT hello Running myproject/kit-bq666mjej725sk8sn12g
kamel log hello [1] 2021-08-11 17:58:40,573 INFO [org.apa.cam.k.Runtime] (main) Apache Camel K Runtime 1.7.1.fuse-800025-redhat-00001 [1] 2021-08-11 17:58:40,653 INFO [org.apa.cam.qua.cor.CamelBootstrapRecorder] (main) bootstrap runtime: org.apache.camel.quarkus.main.CamelMainRuntime [1] 2021-08-11 17:58:40,844 INFO [org.apa.cam.k.lis.SourcesConfigurer] (main) Loading routes from: SourceDefinition{name='camel-k-embedded-flow', language='yaml', location='file:/etc/camel/sources/camel-k-embedded-flow.yaml', } [1] 2021-08-11 17:58:41,216 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Routes startup summary (total:1 started:1) [1] 2021-08-11 17:58:41,217 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started route1 (timer://yaml) [1] 2021-08-11 17:58:41,217 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 3.10.0.fuse-800010-redhat-00001 (camel-1) started in 136ms (build:0ms init:100ms start:36ms) [1] 2021-08-11 17:58:41,268 INFO [io.quarkus] (main) camel-k-integration 1.6.6 on JVM (powered by Quarkus 1.11.7.Final-redhat-00009) started in 2.064s. [1] 2021-08-11 17:58:41,269 INFO [io.quarkus] (main) Profile prod activated. [1] 2021-08-11 17:58:41,269 INFO [io.quarkus] (main) Installed features: [camel-bean, camel-core, camel-k-core, camel-k-runtime, camel-log, camel-support-common, camel-timer, camel-yaml-dsl, cdi] [1] 2021-08-11 17:58:42,423 INFO [info] (Camel (camel-1) thread #0 - timer://yaml) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from yaml]
kamel run Sample.java -o yaml
apiVersion: camel.apache.org/v1 kind: Integration metadata: creationTimestamp: null name: my-integration namespace: default spec: sources: - content: " import org.apache.camel.builder.RouteBuilder; public class Sample extends RouteBuilder { @Override public void configure() throws Exception { from(\"timer:tick\") .log(\"Hello Integration!\"); } }" name: Sample.java status: {}
apply -f my-integration.yaml integration.camel.apache.org/my-integration created
traits: container: configuration: enabled: true name: my-integration
traits: container: enabled: true name: my-integration
type Trait struct { // Can be used to enable or disable a trait. All traits share this common property. Enabled *bool `property:"enabled" json:"enabled,omitempty"` // Legacy trait configuration parameters. // Deprecated: for backward compatibility. Configuration *Configuration `json:"configuration,omitempty"` } // Deprecated: for backward compatibility. type Configuration struct { RawMessage `json:",inline"` }
oc login --token=my-token --server=https://my-cluster.example.com:6443
oc get pod NAME READY STATUS RESTARTS AGE camel-k-operator-86b8d94b4-pk7d6 1/1 Running 0 6m28s
kamel run HelloCamelK.java --dev Condition "IntegrationPlatformAvailable" is "True" for Integration hello-camel-k: test/camel-k Integration hello-camel-k in phase "Initialization" Integration hello-camel-k in phase "Building Kit" Condition "IntegrationKitAvailable" is "True" for Integration hello-camel-k: kit-c49sqn4apkb4qgn55ak0 Integration hello-camel-k in phase "Deploying" Progress: integration "hello-camel-k" in phase Initialization Progress: integration "hello-camel-k" in phase Building Kit Progress: integration "hello-camel-k" in phase Deploying Integration hello-camel-k in phase "Running" Condition "DeploymentAvailable" is "True" for Integration hello-camel-k: deployment name is hello-camel-k Progress: integration "hello-camel-k" in phase Running Condition "CronJobAvailable" is "False" for Integration hello-camel-k: different controller strategy used (deployment) Condition "KnativeServiceAvailable" is "False" for Integration hello-camel-k: different controller strategy used (deployment) Condition "Ready" is "False" for Integration hello-camel-k Condition "Ready" is "True" for Integration hello-camel-k [1] Monitoring pod hello-camel-k-7f85df47b8-js7cb [1] 2021-08-11 18:34:44,069 INFO [org.apa.cam.k.Runtime] (main) Apache Camel K Runtime 1.7.1.fuse-800025-redhat-00001 [1] 2021-08-11 18:34:44,167 INFO [org.apa.cam.qua.cor.CamelBootstrapRecorder] (main) bootstrap runtime: org.apache.camel.quarkus.main.CamelMainRuntime [1] 2021-08-11 18:34:44,362 INFO [org.apa.cam.k.lis.SourcesConfigurer] (main) Loading routes from: SourceDefinition{name='HelloCamelK', language='java', location='file:/etc/camel/sources/HelloCamelK.java', } [1] 2021-08-11 18:34:46,180 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Routes startup summary (total:1 started:1) [1] 2021-08-11 18:34:46,180 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started java (timer://java) [1] 2021-08-11 18:34:46,180 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 3.10.0.fuse-800010-redhat-00001 (camel-1) started in 243ms (build:0ms init:213ms start:30ms) [1] 2021-08-11 18:34:46,190 INFO [io.quarkus] (main) camel-k-integration 1.6.6 on JVM (powered by Quarkus 1.11.7.Final-redhat-00009) started in 3.457s. [1] 2021-08-11 18:34:46,190 INFO [io.quarkus] (main) Profile prod activated. [1] 2021-08-11 18:34:46,191 INFO [io.quarkus] (main) Installed features: [camel-bean, camel-core, camel-java-joor-dsl, camel-k-core, camel-k-runtime, camel-log, camel-support-common, camel-timer, cdi] [1] 2021-08-11 18:34:47,200 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java] [1] 2021-08-11 18:34:48,180 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java] [1] 2021-08-11 18:34:49,180 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java]
integration "hello-camel-k" updated [2] 2021-08-11 18:40:54,173 INFO [org.apa.cam.k.Runtime] (main) Apache Camel K Runtime 1.7.1.fuse-800025-redhat-00001 [2] 2021-08-11 18:40:54,209 INFO [org.apa.cam.qua.cor.CamelBootstrapRecorder] (main) bootstrap runtime: org.apache.camel.quarkus.main.CamelMainRuntime [2] 2021-08-11 18:40:54,301 INFO [org.apa.cam.k.lis.SourcesConfigurer] (main) Loading routes from: SourceDefinition{name='HelloCamelK', language='java', location='file:/etc/camel/sources/HelloCamelK.java', } [2] 2021-08-11 18:40:55,796 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Routes startup summary (total:1 started:1) [2] 2021-08-11 18:40:55,796 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Started java (timer://java) [2] 2021-08-11 18:40:55,797 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (main) Apache Camel 3.10.0.fuse-800010-redhat-00001 (camel-1) started in 174ms (build:0ms init:147ms start:27ms) [2] 2021-08-11 18:40:55,803 INFO [io.quarkus] (main) camel-k-integration 1.6.6 on JVM (powered by Quarkus 1.11.7.Final-redhat-00009) started in 3.025s. [2] 2021-08-11 18:40:55,808 INFO [io.quarkus] (main) Profile prod activated. [2] 2021-08-11 18:40:55,809 INFO [io.quarkus] (main) Installed features: [camel-bean, camel-core, camel-java-joor-dsl, camel-k-core, camel-k-runtime, camel-log, camel-support-common, camel-timer, cdi] [2] 2021-08-11 18:40:56,810 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java] [2] 2021-08-11 18:40:57,793 INFO [info] (Camel (camel-1) thread #0 - timer://java) Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java]
// camel-k: trait=3scale.enabled=true trait=container.limit-memory=256Mi 1 import org.apache.camel.builder.RouteBuilder; public class ThreeScaleRest extends RouteBuilder { @Override public void configure() throws Exception { rest().get("/") .to("direct:x"); from("direct:x") .setBody().constant("Hello"); } }
kamel run ThreeScaleRest.java
Modeline options have been loaded from source files Full command: kamel run ThreeScaleRest.java --trait=3scale.enabled=true --trait=container.limit-memory=256Mi
oc label deploy my-camel-sb-svc camel.apache.org/integration=my-it
oc get it NAMESPACE NAME PHASE RUNTIME PROVIDER RUNTIME VERSION KIT REPLICAS test-79c385c3-d58e-4c28-826d-b14b6245f908 my-it Running
oc patch deployment my-camel-sb-svc --patch '{"spec": {"template": {"metadata": {"labels": {"camel.apache.org/integration": "my-it"}}}}}'
oc get it NAMESPACE NAME PHASE RUNTIME PROVIDER RUNTIME VERSION KIT REPLICAS test-79c385c3-d58e-4c28-826d-b14b6245f908 my-it Running 1
oc scale deployment my-camel-sb-svc --replicas 2 oc get it NAMESPACE NAME PHASE RUNTIME PROVIDER RUNTIME VERSION KIT REPLICAS test-79c385c3-d58e-4c28-826d-b14b6245f908 my-it Running 2
type Build struct { Spec BuildSpec 1 Status BuildStatus 2 } type BuildSpec struct { Tasks []Task 3 }
create configmap my-cm --from-literal=greeting="hello, I am development!" -n development
import org.apache.camel.builder.RouteBuilder; public class PromoteServer extends RouteBuilder { @Override public void configure() throws Exception { from("platform-http:/hello?httpMethodRestrict=GET").setBody(simple("resource:classpath:greeting")); } }
kamel run --dev -n development PromoteServer.java --config configmap:my-cm [-t service.node-port=true]
curl http://192.168.49.2:32116/hello hello, I am development!
create configmap my-cm --from-literal=greeting="hello, I am production!" -n production
kamel promote promote-server -n development --to production kamel logs promote-server -n production
curl http://192.168.49.2:30764/hello hello, I am production!