Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add to pingsource.md #3476

Closed
wants to merge 12 commits into from
229 changes: 145 additions & 84 deletions docs/eventing/sources/pingsource.md
Original file line number Diff line number Diff line change
@@ -1,196 +1,257 @@
---
title: "PingSource"
linkTitle: "PingSource"
weight: 31
weight: 10
type: "docs"
---

![version](https://img.shields.io/badge/API_Version-v1beta2-red?style=flat-square)

A PingSource produces events with a fixed payload on a specified cron schedule.
This topic explains event-driven architecture in terms of producers and consumers, and shows how to
configure PingSource as an event source targeting a Knative service.

## Installation
## Before you begin

The PingSource source type is enabled by default when you install Knative Eventing.
1. Set up [Knative Serving](../../../serving).
1. Set up [Knative Eventing](../../../eventing).

## Example
## About Producers and Consumers

This example shows how to send an event every minute to a Event Display Service.
### Producers

### Creating a namespace
Producers create events. Using GitHub as an example, the producer is the GitHub webhook that sends
information when a pull request is created.
Essentially, you ask the producer for events that they are capable of sending and you tell the
producer where to send those events.

Create a new namespace called `pingsource-example` by entering the following
command:
Producers send the event data per specifications that make it easy for consumers to handle it.
Knative uses the CloudEvents specifications by default.
For more information, see the [Cloud Events](https://cloudevents.io/) website.
Comment on lines +20 to +29
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really think this belongs here honestly, I think all of this info about event-driven etc should be in a main, generic section about event sources, not preceding a procedure on creating an example PingSource?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@omerbensaadon wants it here, AFAIK. We could (should?) re-title this as more of a Getting Started document than a reference topic for PingSource buried way down the subnav.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abrennan89, it's good content regardless. Where would you rather it be placed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://knative.dev/development/concepts/ maybe? Or the main eventing landing page, but both of those require cleanup first. FWIW there's a task for producers and consumers as part of #1923, so I'd do it as part of that rather than adding to pingsource.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't have a place for this text right now, would it unblock this PR to add a <!-- TODO(<issue link>): move this to conceptual documentation when that exists --> here?


```shell
kubectl create namespace pingsource-example
```
### Consumers

Consumers consume the data that producers create. Consumers are usually functions.

### Creating the Event Display Service
In the GitHub example above, a consumer might update a ticket in the ticketing system with the data
from the pull request.

In this step, you create one event consumer, `event-display` to verify that
`PingSource` is properly working.

To deploy the `event-display` consumer to your cluster, run the following
command:
## Create a consumer

To verify that the PingSource is working, create a simple Knative service that receives CloudEvents
and writes them to standard out.

{{< tabs name="create-service" default="YAML" >}}
{{% tab name="YAML" %}}
Create the service from standard input by running:

```shell
kubectl -n pingsource-example apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
cat <<EOF | kubectl create -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: event-display
spec:
replicas: 1
selector:
matchLabels: &labels
app: event-display
template:
metadata:
labels: *labels
spec:
containers:
- name: event-display
image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display
- image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event-display
EOF
```
{{< /tab >}}

---
{{% tab name="kn" %}}
Create a service using the `kn` CLI:

kind: Service
apiVersion: v1
metadata:
name: event-display
spec:
selector:
app: event-display
ports:
- protocol: TCP
port: 80
targetPort: 8080
EOF
```shell
kn service create event-display --image gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event-display
```
{{< /tab >}}
{{< /tabs >}}

## Create a producer

### Creating the PingSource
Create a producer that sends events to your consumer every two minutes.
The `sink` element in the metadata describes where to send events.
In this case, events are sent to a service with the name `event-display`.

You can now create the `PingSource` sending an event containing
`{"message": "Hello world!"}` every minute.
For each set of ping events that you want to request, create an event source in the same namespace
as the destination.

{{< tabs name="create-source" default="YAML" >}}
{{% tab name="YAML" %}}
Create the event source from standard in by running:

```shell
kubectl create -n pingsource-example -f - <<EOF
apiVersion: sources.knative.dev/v1beta2
cat <<EOF | kubectl create -f -
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

apiVersion: sources.knative.dev/v1alpha2
kind: PingSource
metadata:
name: test-ping-source
spec:
schedule: "*/1 * * * *"
schedule: "*/2 * * * *"
contentType: "application/json"
data: '{"message": "Hello world!"}'
sink:
ref:
apiVersion: v1
apiVersion: serving.knative.dev/v1
kind: Service
name: event-display
EOF
```

{{< /tab >}}

{{% tab name="kn" %}}
Notice that the namespace is specified in two places in the command in `--namespace` and the `--sink` hostname
Create a PingSource by using the `kn` CLI:

```shell
kn source ping create test-ping-source \
--namespace pingsource-example \
--schedule "*/1 * * * *" \
--data '{"message": "Hello world!"}' \
--sink http://event-display.pingsource-example.svc.cluster.local
--schedule "*/2 * * * *" --data \
'{ "message": "Hello world!" }' \
--sink ksvc:event-display
```

{{< /tab >}}
{{< /tabs >}}

## (Optional) Create a PingSource with binary data
{{% tab name="binary" %}}
You can send binary data, that cannot be directly serialized by using YAML, to downstream, by using
`dataBase64` as the payload. `dataBase64` carries data that is base64-encoded.

Sometimes you may want to send binary data, which cannot be directly serialized in yaml, to downstream. This can be achieved by using `dataBase64` as the payload. As the name suggests, `dataBase64` should carry data that is base64 encoded.
**Note:** `data` and `dataBase64` cannot co-exist.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
**Note:** `data` and `dataBase64` cannot co-exist.
**NOTE:** You can use either `data` or `dataBase64`, but not both.

Explain why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lionelvillard, why can't you use both?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both data and dataBase64 specify the CloudEvent payload, that's why those fields are mutually-exclusive.

Does that answer your question?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the following text, to clarify why:

**NOTE:** Because both `data` and `dataBase64` specify the event payload, only one field may be set.


Please note that `data` and `dataBase64` cannot co-exist.
Create the event source with binary data from standard in by running:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd leave out "from standard" entirely here.
As an example, I'd prefer
"To create an event source by using binary data, enter the command:"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, I might call this "stdin", "standard input" (weird, but what STDIN is abbreviated from) or "terminal input".


```shell
kubectl create -n pingsource-example -f - <<EOF
cat <<EOF | kubectl create -f -
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

apiVersion: sources.knative.dev/v1beta2
kind: PingSource
metadata:
name: test-ping-source-binary
spec:
schedule: "*/1 * * * *"
schedule: "*/2 * * * *"
contentType: "text/plain"
dataBase64: "ZGF0YQ=="
sink:
ref:
apiVersion: v1
apiVersion: serving.knative.dev/v1
kind: Service
name: event-display
EOF
```
{{< /tab >}}
{{< /tabs >}}


## Verify the message was sent

Verify that the message was sent to the Knative Eventing system by looking at message dumper logs.
Comment on lines +144 to +146
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use "Verify that the message was sent" both places?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to point out that Knative Services may scale down to zero and have their logs recycled, but it occurs to me that the PingSource might be firing just frequently enough to avoid this.

I suspect this will work whether or not the service is getting scaled down to zero because there will be at least one pod running with at least one request in the logs (because the pingsource keeps sending events), so this is mostly a note for other examples.


### Verify
{{< tabs name="event-display" default="kubectl" >}}
{{% tab name="kubectl" %}}

View the logs for the `event-display` event consumer by
entering the following command:
View the logs of the event-display service by running:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be consistent with names - event-display

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't forget the backticks, not sure why these were removed


```shell
kubectl -n pingsource-example logs -l app=event-display --tail=100
kubectl logs -l serving.knative.dev/service=event-display -c user-container --since=10m
```

This returns the `Attributes` and `Data` of the events that the PingSource sent to the `event-display` Service:
{{< /tab >}}
{{% tab name="kail" %}}

Use `kail` to tail the logs of the subscriber by running:

```shell
kail -l serving.knative.dev/service=event-display -c user-container --since=10m
```

For more information, see the [`kail`](https://github.com/boz/kail) repository in GitHub.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd call this out earlier as an optional prereq, e.g. "if you want to view logs, you need to install kail" and add the link there, so it's not being introduced mid procedure

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

You could also reference using log aggregation via https://knative.dev/docs/install/collecting-logs/ as another way to view the logs if desired, but I'm not super-happy with that yet so I don't want to add it to this PR.


{{< /tab >}}
{{< /tabs >}}


Log entries appear showing the request headers and body from the source:

```shell
☁️ cloudevents.Event
Validation: valid
Context Attributes,
specversion: 1.0
type: dev.knative.sources.ping
source: /apis/v1/namespaces/pingsource-example/pingsources/test-ping-source
id: 49f04fe2-7708-453d-ae0a-5fbaca9586a8
time: 2021-03-25T19:41:00.444508332Z
source: /apis/v1/namespaces/default/pingsources/test-ping-source
id: d8e761eb-30c7-49a3-a421-cd5895239f2d
time: 2019-12-04T14:24:00.000702251Z
datacontenttype: application/json
Data,
{
"message": "Hello world!"
}
```

If you created a PingSource with binary data, you should also see the following:
If you created a PingSource with binary data, the output will be similar to the following:

```shell
☁️ cloudevents.Event
Validation: valid
Context Attributes,
specversion: 1.0
type: dev.knative.sources.ping
source: /apis/v1/namespaces/pingsource-example/pingsources/test-ping-source-binary
id: ddd7bad2-9b6a-42a7-8f9b-b64494a6ce43
time: 2021-03-25T19:38:00.455013472Z
source: /apis/v1/namespaces/default/pingsources/test-ping-source-binary
id: a195be33-ff65-49af-9045-0e0711d05e94
time: 2020-11-17T19:48:00.48334181Z
datacontenttype: text/plain
Data,
data
ZGF0YQ==
```

## Clean up

Delete the PingSource instance:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove this because it's duplicated in the tabs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll delete the duplicate within the tabs.


{{< tabs name="delete-source" default="kubectl" >}}
{{% tab name="kubectl" %}}

Run:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"To delete the PingSource, enter the command:"

I'd also prefer we have one command per code block, it's not clear to me why both are here, does a user need both, or is the second only if they used the binary data?


```shell
kubectl delete pingsources.sources.knative.dev test-ping-source
kubectl delete pingsources.sources.knative.dev test-ping-source-binary
```

{{< /tab >}}

{{% tab name="kn" %}}

Run:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


```shell
kn source ping delete test-ping-source
kn source ping delete test-ping-source-binary
```

### Cleanup
{{< /tab >}}
{{< /tabs >}}


Delete the service instance:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, delete, repeated in tabs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise I'd make it a step, e.g.

  1. Delete the service instance:
    <tab>

but not include the same line in the tabs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting for numbered steps across two tabbed sections seems impossible (or very near it -- I've tried many times). I'll simply leave the full instruction outside the tabs as above.


Delete the `pingsource-example` namespace and all of its resources from your
cluster by entering the following command:
{{< tabs name="delete-service" default="kubectl" >}}
{{% tab name="kubectl" %}}

Run:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above, explain what the step is maybe


```shell
kubectl delete namespace pingsource-example
kubectl delete service.serving.knative.dev event-display
```

## Reference Documentation
{{< /tab >}}

{{% tab name="kn" %}}

See the [PingSource specification](../../reference/api/eventing/#sources.knative.dev/v1beta2.PingSource).
Run:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


## Contact
```shell
kn service delete event-display
```

For any inquiries about this source, please reach out on to the
[Knative users group](https://groups.google.com/forum/#!forum/knative-users).
{{< /tab >}}
{{< /tabs >}}