Knative eventing workflow example
Tags: serverless, kubernetes, eventdriven, knative
Published: 2023-03-29 08:46:54

#### What we want to implement

![Inteded workflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5g91lxz8e13s0zom41e0.png)

#### What we have (pre-requisite)
1. A kubernetes cluster (kind cluster in my case => no external urls possible)
2. Knative serving installed ([installation script](https://github.com/ashok-an/knative-eventing-demoes/blob/main/install/serving.sh))
3. Knative eventing installed ([installation script](https://github.com/ashok-an/knative-eventing-demoes/blob/main/install/eventing.sh))
4. Kafka related broker, source, sink .. ([installation script](https://github.com/ashok-an/knative-eventing-demoes/blob/main/install/kafka-broker.sh))
5. A kafka cluster ([internal cluster installation script](https://github.com/ashok-an/knative-eventing-demoes/blob/main/install/kafka-cluster.sh)) - broker url will be `http://my-cluster.kafka-ns.cluster.local:9092`.
Note: I am using a cluster hosted on `173.39.62.80:9092` in my examples ([installation link](https://towardsdev.com/3-simple-steps-to-set-up-kafka-locally-using-docker-b07f71f0e2c9))
6. Microservices invoked via POST:
6a. Builder-MS - external (emits CE with "[BUILD] <bug id>")
6b. Tester-MS - internal (sequence: emits CE with "..Create TB..", "Run Tests", "..Clean TB..")
6c. Committer-MS - external (emits CE with "[COMMIT]")
6d. Alerter-MS - internal (records and displays the events - for demo; can be event-display service with `kn service create alert-ms --image=gcr.io/knative-releases/knative.dev/eventing/cmd/event_display`)

#### Intended workflow
1. `GitHubSource` - is registered with GitHub which pushes events (PR related) to `GitHubSource` ([installation](https://knative.github.io/docs/docs/eventing/samples/github-source/))
Note: Since I am working on localhost/kind, I will skip this part
1a. Every `EventSource` needs a `Sink`; in this case we use `http://Builder-MS-URL` as the `Sink`
Note: I will directly invoke this `http://Builder-MS-URL` via POST

2. Builder MS - Microservice that builds and posts a `build.done{}` with a `Ce-buildstatus=xyz` event to Kafka topic `build.done`

3. KafkaSource - Subscribes to topic `build.done` and passes it on-to `Sink=Broker:kb-build`
3a. Broker kb-build passes on the event to `trigger:kt-build`

4. Trigger(kt-build) - if `buildstatus=pass` pass the event to `Sink:sequence`, if `buildstatus=fail` pass it to `http://Alerter-MS-URL`

5. Sequence - calls 3 services `create-tb-ms`, `run-tests-ms`, `clean-tb-ms` and passes the results on-to `Sink=Broker:kb-test`

6. Broker(kb-test)/Trigger(kt-test) - if `teststatus=pass` pass the event to `Sink:KafkaSink`, if `teststatus=fail` pass it to `http://Alerter-MS-URL`

7. KafkaSink - posts `test.done{}` with `teststatus=pass` to kafka topic: `test.done`

8. KafkaSource - Subscribes to topic `test.done` and passes it on-to `Sink=http://Commit-MS-URL`

9. Commit MS - Does commit process and posts a Cloud-event

---
#### Notes
1. All the manifests are under [github directory](https://github.com/ashok-an/knative-eventing-demoes/tree/main/kafka)
2. The demo uses `InMemory Channel` for the brokers when created with [dummy.sh](https://github.com/ashok-an/knative-eventing-demoes/blob/main/kafka/brokers/dummy.sh), use [run.sh](https://github.com/ashok-an/knative-eventing-demoes/blob/main/kafka/brokers/run.sh) for Kafka based broker implementation
3. Steps #6, #7 and #8 can be avoided by directly calling Commit MS; I use it to add `teststatus` with `CeOverrides` which is only available through an `EventSource`
4. Use [`SinkBinding`](https://knative.github.io/docs/docs/eventing/sources/sinkbinding/) if you directly want to call an EventSink
5. Tester MS is always returning `teststatus=pass` in my case as it is a dummy sequence
6. Kafka brokers and triggers need to be in the same namespace to work properly

---
#### Test run
```sh
# post installation, these are the knative objects
❯ kn sources list -A
NAMESPACE   NAME            TYPE          RESOURCE                           SINK               READY
kafka-ns    ks-build-done   KafkaSource   kafkasources.sources.knative.dev   broker:kb-test     True
kafka-ns    ks-test-done    KafkaSource   kafkasources.sources.knative.dev   broker:kb-commit   True

❯ kn service list -A
NAMESPACE   NAME           URL                                             LATEST               AGE   CONDITIONS   READY   REASON
default     alert-ms       http://alert-ms.default.svc.cluster.local       alert-ms-00001       17h   3 OK / 3     True
default     clean-tb-ms    http://clean-tb-ms.default.svc.cluster.local    clean-tb-ms-00001    17h   3 OK / 3     True
default     create-tb-ms   http://create-tb-ms.default.svc.cluster.local   create-tb-ms-00001   17h   3 OK / 3     True
default     run-tests-ms   http://run-tests-ms.default.svc.cluster.local   run-tests-ms-00001   17h   3 OK / 3     True

❯ kubectl get sequences.flows.knative.dev
NAME      URL                                                                 AGE   READY   REASON
test-ms   http://test-ms-kn-sequence-0-kn-channel.default.svc.cluster.local   17h   True

❯ kn broker list -A
NAMESPACE   NAME        URL                                                                           AGE   CONDITIONS   READY   REASON
kafka-ns    kb-build    http://broker-ingress.knative-eventing.svc.cluster.local/kafka-ns/kb-build    17h   6 OK / 6     True
kafka-ns    kb-commit   http://broker-ingress.knative-eventing.svc.cluster.local/kafka-ns/kb-commit   17h   6 OK / 6     True
kafka-ns    kb-test     http://broker-ingress.knative-eventing.svc.cluster.local/kafka-ns/kb-test     17h   6 OK / 6     True

❯ kn trigger list -A
NAMESPACE   NAME              BROKER      SINK                                                        AGE   CONDITIONS   READY   REASON
kafka-ns    kt-build-start    kb-build    http://builer-ms-url                         17h   6 OK / 6     True
kafka-ns    kt-commit-start   kb-commit   http://commiter-ms-url                        17h   6 OK / 6     True
kafka-ns    kt-test-start     kb-test     sequence:test-ms                                            17h   6 OK / 6     True

# trigger the workflow by calling `builder-ms-url`
❯ http POST http://builer-ms-url ...
HTTP/1.0 200 OK
Content-Length: 263
Date: Wed, 29 Mar 2023 08:36:44 GMT
Server: Werkzeug/2.0.3 Python/3.6.3
content-type: application/cloudevents+json

{
    "buildstatus": "pass",
    "data": {
        "message": "[BUILD] BUGmn15840",
        "completed": true
    },
    "id": "6110dd6e-f670-4ede-a41b-3f671219ae0d",
    "source": "demo.build",
    "specversion": "1.0",
    "task": "build",
    "time": "2023-03-29T08:36:37.353013+00:00",
    "type": "build.pass"
}

## output events in the order of arrival
# 1. output from build
# ce-source: /apis/v1/namespaces/kafka-ns/kafkasources/ks-build-done#build.pass
# ce-buildstatus: pass
# ce-type: dev.knative.kafka.event
{
  "message": "[BUILD] BUGmn15840",
  "completed": true
}

#2. output from test
# ce-source: /apis/v1/namespaces/kafka-ns/kafkasources/ks-build-done#build.pass
# ce-buildstatus: pass
# ce-teststatus: pass
# ce-type: dev.knative.kafka.event
{
  "id": 1234,
  "message": "[BUILD] BUGmn15840...Create TB......Run tests......Clean TB..."
  "completed": true
}

#3. output from commit
# ce-source: demo.commit
# ce-buildstatus: pass
# ce-teststatus: pass
# ce-commitstatus: pass
# ce-type: commit.pass
{
  "message": "[BUILD] BUGmn15840...Create TB......Run tests......Clean TB... [COMMIT] ",
  "completed": true
}
```
---
#### Tracing
1. Install zipkin tracing with [installer](https://github.com/ashok-an/knative-eventing-demoes/blob/main/install/zipkin.sh)
2. Configure tracing endpoint with this [guide](https://knative.github.io/docs/docs/eventing/accessing-traces/#configuring-tracing)