Camel K Eventing

At the end of this chapter you will be able to:

  • How to use Knative Eventing Channels with Apache Camel K

  • Using Knative Kamelet

  • Connect Apache Camel K source to Sink

Navigate to the tutorial chapter’s folder advanced/camel-k:

cd $TUTORIAL_HOME/advanced/camel-k

Install the kn kamelet source plugin

You can use the Camel K integration as part of the Knative Eventing architecture via a Kamelet. Simply speaking, you can make the Camel K integration act as a Knative Event Source and send the Camel exchanges (OUT) through a Knative Event Sink. To start working with Kamelets you will need to add the kamelet source plugin to kn CLI.

As you probably already installed the kn CLI tooling, you can simply load the Kamelet source plugin binaries in order to add the commands for managing Kamelets as event sources.

Once you have the binary available on your machine you can hook this into your local kn tooling quite easily. The kn-client project provides a clever plugin architecture for adding commands. The respective plugin configuration is located in your home directory under ~/.config/kn/plugins.

Save the kn-source-kamelet binary into this configuration folder or add a symbolic link pointing to the plugin binary there. You can add the symbolic link as follows:

mkdir ~/.config/kn/plugins
cd ~/.config/kn/plugins
ln -s /the/path/to/my/kn-source-kamelet kn-source-kamelet

Add executable permission to the kn-source-kamelet binary

chmod +x ~/.config/kn/plugins/kn-source-kamelet

You can then verify the plugin setup by displaying the kn help page once more:

kn source -h
Manage event sources

Usage:
  kn source SOURCE|COMMAND [options]

Aliases:
  source, sources

Available Commands:
  apiserver   Manage Kubernetes api-server sources
  binding     Manage sink bindings
  container   Manage container sources
  list        List event sources
  list-types  List event source types
  ping        Manage ping sources

Plugins:
  kamelet      ~/.config/kn/plugins/kn-source-kamelet

Use "kn <command> --help for more information about a given command. Use kn options for a list of global command-line options (applies to all commands). You should see a new plugins section with the Kamelet source plugin listed. This means that you are now ready to use the plugin commands directly with the kn CLI.

To verify your installation, please run the following command:

kn plugin list

You should see an output similar to:

- kn-source-kamelet : /Users/rsoares/.config/kn/plugins/kn-source-kamelet

By default, the kn CLI tool has a set of different event sources and its respective commands to manage those sources. You can list all the available Kamelets with the following command:

kn source kamelet list -n knativetutorial

View CloudEvents Messages

In order for you to view the events drained from the Kamelet timed-greeter, you need to deploy a utility service called event-display. Run the following command to deploy the service:

cat <<EOF | kubectl create -n knativetutorial -f -
---
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: event-display
spec:
  template:
    spec:
      containers:
        - image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display
EOF

A successful event display should show the following pod in the knativetutorial:

watch kubectl get -n knativetutorial pods

List the Knative Service event-display:

  • kn

  • kubectl

kn service -n knativetutorial ls
NAME            URL                                                          LATEST                AGE   CONDITIONS   READY   REASON
event-display   http://event-display.knativetutorial.192.168.59.101.nip.io   event-display-00001   24s   3 OK / 3     True
kubectl -n knativetutorial get ksvc
NAME            URL                                                LATESTCREATED         LATESTREADY           READY   REASON
event-display   http://event-display.knativetutorial.example.com   event-display-7jvmm   event-display-7jvmm   True

Custom Kamelet as source for a Knative Eventing Sink

Knative Eventing semantics allows you to link the Event Source to Event Sink using the sink block of the Knative Eventing source specification.

As part of this exercise we will deploy the same timed-greeter integration that you deployed earlier but now as a Kamelet.

The following listing provides the details of Kamelet configuration:

timed-greeter Kamelet
apiVersion: camel.apache.org/v1alpha1 (1)
kind: Kamelet
metadata:
  name: timed-greeter
spec:
  definition:
    title: Timed Greeter Source
    description: Produces periodic events with a custom payload.
    required:
      - message
    type: object
    properties:
      period:
        title: Period
        description: The interval between two events in milliseconds
        type: integer
        default: 1000
      message:
        title: Message
        description: The message to generate
        type: string
        example: hello world
      contentType:
        title: Content Type
        description: The content type of the message being generated
        type: string
        default: text/plain
  dependencies:
    - "camel:core"(2)
    - "camel:timer"
    - "camel:kamelet"
  template:
    from: (3)
      uri: timer:tick
      parameters:
        period: 10000
      steps:
        - set-body:
            constant: "{{message}}"
        - set-header:
            name: "Content-Type"
            constant: "{{contentType}}"
        - transform:
            simple: "${body.toUpperCase()}"
        - to: "kamelet:sink"(4)
1 The Kamelet is provided by the API sources.knative.dev.
2 The Kamelet spec has three main sections: definition, dependencies and template. The dependencies block is used to configure the Camel K integration specific properties such as dependencies, traits, etc. In this example we add the required dependencies such as camel:core, it is the dependency that you earlier passed via kamel CLI.
3 The from attribute allows you define the Camel route.
4 The event sink for messages from the Camel event source. A Source Kamelet sends data to a kamelet:sink, that will be replaced at runtime by a different target.

To deploy the Kamelet run the following command:

kubectl apply -n knativetutorial -f get-started/timed-greeter-kamelet.yaml

A successful deployment will show the Kamelet timed-greeter in ready state along with its pods in the knativetutorial namespace.

kubectl get kamelet timed-greeter -n knativetutorial

When the Kamelet is successfully running you will see it in "READY" state True:

NAME            READY
timed-greeter   True

The event source is configured to drain the events to kamelet:sink. Now we just need to bind the Kamelet to the service event-display and we can do that by using a KameletBinding.

Use Kamelets when you want to connect two or more components (external applications or services). Each Kamelet is basically a route template with configuration properties. You need to know which component you want to get data from (a source) and which component you want to send data to (a sink). You connect the source and sink components by adding Kamelets in a Kamelet Binding as illustrated in Figure below:

kamelet binding simple
Figure 1. Kamelet Binding source to sink

The KamelBinding resource definition used to connect the timed-greeter source wuth the event-display service looks like:

timed-greeter KameletBinding
apiVersion: camel.apache.org/v1alpha1
kind: KameletBinding
metadata:
  name: timed-greeter-binding
spec:
  source:
    ref: (1)
      kind: Kamelet
      apiVersion: camel.apache.org/v1alpha1
      name: timed-greeter
    properties:
      period: 5000
      message: Welcome to Apache Camel K
  sink:
    uri: <INPUT_YOUR_EVENT_DISPLAY_URL>(2)
1 Kubernetes reference to the previously created Kamelet.
2 Sink the input to the URI of event-display.

To find out the URI of event-display please run the following command:

kn service describe event-display -o url -n knativetutorial

Copy the url that the previous command returned and run the following command. It will open an editor in which you can change the definition of the KameletBinding. Replace the sink uri with the value you just copied and save the file. Once you do that, Kubernetes will create an object based on the saved definition.

kubectl create -f get-started/timed-greeter-binding.yaml --edit -o yaml -n knativetutorial

You can validate the state of your KameletBinding using:

kn source kamelet binding list  -n knativetutorial

You should see an output stating it reached Ready state:

NAME                          PHASE   AGE    CONDITIONS   READY   REASON
timed-greeter-binding         Ready   45m    1 OK / 1     True

Once the timed-greeter and timed-greeter-binding are ready, you will notice Knative sink event-display scale up to receive the events from timed-greeter.

CamelSource timed-greeter pod and event-display pod
# watch kubectl -n knativetutorial get pods
NAME                                              READY   STATUS    AGE
camel-k-operator-84d7896b68-sgmpk                 1/1     Running   2m36s
event-display-dmq4s-deployment-775789b565-fnf2t   2/2     Running   17s
timed-greeter-m4chq-7cbf4ddc66-kxpqd              1/1     Running   86s

Open a new terminal and run the following command to start watching the events that are being drained into the sink event-display Knative service using the command:

stern -n knativetutorial event-display -c user-container

The stern command above should show the following output:

event-... user-container ☁️  cloudevents.Event
event-... user-container Validation: valid
event-... user-container Context Attributes,
event-... user-container   specversion: 1.0
event-... user-container   type: org.apache.camel.event
event-... user-container   source: source
event-... user-container   id: 3304E164DD1D7E1-0000000000000003
event-... user-container   time: 2022-01-31T17:40:01.752Z
event-... user-container   datacontenttype: text/plain
event-... user-container Data,
event-... user-container   WELCOME TO APACHE CAMEL K

Cleanup

$TUTORIAL_HOME/bin/clean-completed.sh
kubectl delete kameletbinding.camel.apache.org/timed-greeter-binding -n knativetutorial
kubectl delete kamelet.camel.apache.org/timed-greeter -n knativetutorial

After few seconds you will see the event-display Knative Service scaling down to zero since it no longer receives events via the event source.