Sequence terminal

We are going to create the following logical configuration. We create a CronJobSource, feeding events to a Sequence. Sequence can then do either external work, or out of band create additional events.

Logical Configuration

The functions used in these examples live in https://github.com/knative/eventing-contrib/blob/master/cmd/appender/main.go.

Prerequisites

For this example, we’ll assume you have set up an InMemoryChannel as well as Knative Serving (for our functions). The examples use default namespace, again, if you want to deploy to another Namespace, you will need to modify the examples to reflect this.

If you want to use different type of Channel, you will have to modify the Sequence.Spec.ChannelTemplate to create the appropriate Channel resources.

Setup

Create the Knative Services

First create the 3 steps that will be referenced in the Steps.

  1. apiVersion: serving.knative.dev/v1
  2. kind: Service
  3. metadata:
  4. name: first
  5. spec:
  6. template:
  7. spec:
  8. containers:
  9. - image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/appender
  10. env:
  11. - name: MESSAGE
  12. value: " - Handled by 0"
  13. ---
  14. apiVersion: serving.knative.dev/v1
  15. kind: Service
  16. metadata:
  17. name: second
  18. spec:
  19. template:
  20. spec:
  21. containers:
  22. - image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/appender
  23. env:
  24. - name: MESSAGE
  25. value: " - Handled by 1"
  26. ---
  27. apiVersion: serving.knative.dev/v1
  28. kind: Service
  29. metadata:
  30. name: third
  31. spec:
  32. template:
  33. spec:
  34. containers:
  35. - image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/appender
  36. env:
  37. - name: MESSAGE
  38. value: " - Handled by 2"
  39. ---
  1. kubectl -n default create -f ./steps.yaml

Create the Sequence

The sequence.yaml file contains the specifications for creating the Sequence. If you are using a different type of Channel, you need to change the spec.channelTemplate to point to your desired Channel.

  1. apiVersion: flows.knative.dev/v1beta1
  2. kind: Sequence
  3. metadata:
  4. name: sequence
  5. spec:
  6. channelTemplate:
  7. apiVersion: messaging.knative.dev/v1
  8. kind: InMemoryChannel
  9. steps:
  10. - ref:
  11. apiVersion: serving.knative.dev/v1
  12. kind: Service
  13. name: first
  14. - ref:
  15. apiVersion: serving.knative.dev/v1
  16. kind: Service
  17. name: second
  18. - ref:
  19. apiVersion: serving.knative.dev/v1
  20. kind: Service
  21. name: third

Change default below to create the Sequence in the Namespace where you want the resources to be created.

  1. kubectl -n default create -f ./sequence.yaml

Create the PingSource targeting the Sequence

This will create a PingSource which will send a CloudEvent with {"message": "Hello world!"} as the data payload every 2 minutes.

  1. apiVersion: sources.knative.dev/v1alpha2
  2. kind: PingSource
  3. metadata:
  4. name: ping-source
  5. spec:
  6. schedule: "*/2 * * * *"
  7. jsonData: '{"message": "Hello world!"}'
  8. sink:
  9. ref:
  10. apiVersion: flows.knative.dev/v1beta1
  11. kind: Sequence
  12. name: sequence

Here, if you are using different type of Channel, you need to change the spec.channelTemplate to point to your desired Channel.

  1. kubectl -n default create -f ./ping-source.yaml

Inspecting the results

You can now see the final output by inspecting the logs of the event-display pods. Note that since we set the PingSource to emit every 2 minutes, it might take some time for the events to show up in the logs.

  1. kubectl -n default get pods

Let’s look at the logs for the first Step in the Sequence:

  1. kubectl -n default logs -l serving.knative.dev/service=first -c user-container --tail=-1
  2. 2020/03/02 21:28:00 listening on 8080, appending " - Handled by 0" to events
  3. 2020/03/02 21:28:01 Received a new event:
  4. 2020/03/02 21:28:01 [2020-03-02T21:28:00.0010247Z] /apis/v1/namespaces/default/pingsources/ping-source dev.knative.sources.ping: &{Sequence:0 Message:Hello world!}
  5. 2020/03/02 21:28:01 Transform the event to:
  6. 2020/03/02 21:28:01 [2020-03-02T21:28:00.0010247Z] /apis/v1/namespaces/default/pingsources/ping-source dev.knative.sources.ping: &{Sequence:0 Message:Hello world! - Handled by 0}

Then we can look at the output of the second Step in the Sequence:

  1. kubectl -n default logs -l serving.knative.dev/service=second -c user-container --tail=-1
  2. 2020/03/02 21:28:02 listening on 8080, appending " - Handled by 1" to events
  3. 2020/03/02 21:28:02 Received a new event:
  4. 2020/03/02 21:28:02 [2020-03-02T21:28:00.0010247Z] /apis/v1/namespaces/default/pingsources/ping-source dev.knative.sources.ping: &{Sequence:0 Message:Hello world! - Handled by 0}
  5. 2020/03/02 21:28:02 Transform the event to:
  6. 2020/03/02 21:28:02 [2020-03-02T21:28:00.0010247Z] /apis/v1/namespaces/default/pingsources/ping-source dev.knative.sources.ping: &{Sequence:0 Message:Hello world! - Handled by 0 - Handled by 1}

And you can see that the initial PingSource message ("Hello World!") has now been modified by the first step in the Sequence to include “ - Handled by 0”. Exciting :)

Then we can look at the output of the last Step in the Sequence:

  1. kubectl -n default logs -l serving.knative.dev/service=third -c user-container --tail=-1
  2. 2020/03/02 21:28:03 listening on 8080, appending " - Handled by 2" to events
  3. 2020/03/02 21:28:03 Received a new event:
  4. 2020/03/02 21:28:03 [2020-03-02T21:28:00.0010247Z] /apis/v1/namespaces/default/pingsources/ping-source dev.knative.sources.ping: &{Sequence:0 Message:Hello world! - Handled by 0 - Handled by 1}
  5. 2020/03/02 21:28:03 Transform the event to:
  6. 2020/03/02 21:28:03 [2020-03-02T21:28:00.0010247Z] /apis/v1/namespaces/default/pingsources/ping-source dev.knative.sources.ping: &{Sequence:0 Message:Hello world! - Handled by 0 - Handled by 1 - Handled by 2}

And as expected it’s now been handled by both the first and second Step as reflected by the Message being now: “Hello world! - Handled by 0 - Handled by 1”