Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
d89a84e
First port of spec doc to markdown.
Oct 1, 2018
f0930b9
trim unused objects.
Oct 1, 2018
1e1607a
start using mrkdown tables.
Oct 1, 2018
0558eab
more meta for tables.
Oct 1, 2018
f0fdc69
passed at making tables md style.
Oct 1, 2018
e5d8eaa
Adding formatting to the markdown tables.
Oct 1, 2018
ffaea55
minor formatting.
Oct 1, 2018
69eb6de
Make required clear.
Oct 1, 2018
9b977cf
Adding links.
Oct 1, 2018
469ea51
add spacing because markdown.
Oct 1, 2018
eb401b9
Explode out the spec into components.
Oct 1, 2018
bf16902
Added images.
Oct 1, 2018
6adb9f0
Adding a link back to the original image to allow for editing later.
Oct 1, 2018
edf5caf
adding nav links to the bottom.
Oct 1, 2018
7ca20b8
next should not have this page.
Oct 1, 2018
9c825b8
Fix interface image.
Oct 1, 2018
806e9a1
scrub flow.
Oct 1, 2018
743b164
fix image and update some bolds.
Oct 1, 2018
f7689d0
Trying to make the documents read better.
Oct 1, 2018
3fe9f29
Update based on feedback.
Oct 1, 2018
5850ace
Feedback.
Oct 1, 2018
e12f1c5
adding event type for prosperity
Oct 1, 2018
e4a6a3b
checkpoint on feedback.
Oct 8, 2018
fa7d764
Finished review.
Oct 8, 2018
2765183
ran prettier on spec.
Oct 8, 2018
9de5e7e
more feedback updates.
Oct 9, 2018
e811c5f
Remove ProvisionerReference label selector
scothis Oct 11, 2018
b720910
Remove EventType resource
scothis Oct 11, 2018
ae345a9
Document ResultStrategy as implemented
scothis Oct 11, 2018
8746992
Clarify that only a Channel is subscribeable
scothis Oct 11, 2018
a5b313e
Merge pull request #3 from scothis/subscription-resultstrategy
n3wscott Oct 11, 2018
de9e4f8
Define Provisoner parameters
scothis Oct 12, 2018
bda77a0
remove reference that Source has subscriptions
matzew Oct 15, 2018
e4922e6
Merge pull request #1 from matzew/rm-subscribeable
scothis Oct 15, 2018
befda6f
Adding some clarification 1:1 Source/Channel, and adding fanout examp…
matzew Oct 15, 2018
f502206
Merge pull request #2 from matzew/one_channel_per_source_clarification
scothis Oct 15, 2018
e692af7
It should not just be HTTP
matzew Oct 16, 2018
bbe1988
Merge pull request #1 from scothis/rm-eventtype
n3wscott Oct 18, 2018
1dc6880
Merge pull request #2 from scothis/rm-provisionerreference-selector
n3wscott Oct 18, 2018
cbcb17e
Merge remote-tracking branch 'scothis/rm-subscribeable' into push_raw…
Oct 18, 2018
1c971a6
Merge pull request #10 from matzew/not_just_http
n3wscott Oct 18, 2018
5c64853
Merge pull request #7 from scothis/provisionable-args
n3wscott Oct 18, 2018
60425d4
fixed up overview, need to update the pictures.
Oct 18, 2018
f992391
First pass scrub to remove source.
Oct 18, 2018
27fb0aa
Formatting.
Oct 18, 2018
d1f392f
updated the images.
Oct 18, 2018
f82eb47
Provisioner -> ClusterProvisioner.
Oct 18, 2018
300723a
Set the width.
Oct 18, 2018
fe158af
width, try two.
Oct 18, 2018
7136a18
width, first try.
Oct 18, 2018
dcbb8a7
Width was too big at 300
Oct 18, 2018
7c74ca8
Update docs/spec/interfaces.md
evankanderson Oct 22, 2018
abd4456
Update docs/spec/interfaces.md
evankanderson Oct 22, 2018
6b7c28b
Update docs/spec/interfaces.md
evankanderson Oct 22, 2018
c1b677a
Update docs/spec/interfaces.md
evankanderson Oct 22, 2018
cba6a67
Update docs/spec/spec.md
evankanderson Oct 22, 2018
ce3fceb
Update docs/spec/spec.md
evankanderson Oct 22, 2018
63c5ff5
Update docs/spec/spec.md
evankanderson Oct 22, 2018
07e654b
applying sugestions
Oct 22, 2018
5b73ffc
syncing remote.
Oct 22, 2018
fbb8b6f
add a todo.
Oct 22, 2018
ae76ce0
sync.
Oct 22, 2018
a849d50
updates.
Oct 22, 2018
60e5cfc
remove type from new bus.
Oct 22, 2018
6f27fc0
domain to uri.
Oct 22, 2018
b08b089
Update docs/spec/spec.md
scothis Oct 22, 2018
79536d7
typos.
Oct 22, 2018
0891310
typos.
Oct 22, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 12 additions & 19 deletions docs/spec/README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
# Knative Eventing API spec

This directory contains the specification of the Knative Eventing API, which is
implemented in [`channels.knative.dev`](/pkg/apis/channels/v1alpha1),
[`feeds.knative.dev`](/pkg/apis/feeds/v1alpha1) and
[`flows.knative.dev`](/pkg/apis/flows/v1alpha1) and verified via [the e2e
test](/test/e2e).
implemented in [`eventing.knative.dev`](/pkg/apis/eventing/v1alpha1) and
verified via [the e2e test](/test/e2e).

**Updates to this spec should include a corresponding change to the API
implementation for [channels](/pkg/apis/channels/v1alpha1),
[feeds](/pkg/apis/feeds/v1alpha1) or [flows](/pkg/apis/feeds/v1alpha1) and [the
e2e test](/test/e2e).**
implementation for [eventing](/pkg/apis/eventing/v1alpha1) and [the e2e
test](/test/e2e).**

Docs in this directory:

* [Motivation and goals](motivation.md)
* [Resource type overview](overview.md)
<!-- TODO(n3wscott): * [Knative Eventing API spec](spec.md) -->
- [Motivation and goals](motivation.md)
- [Resource type overview](overview.md)
- [Interface contracts](interfaces.md)
- [Object model specification](spec.md)

<!-- TODO(n3wscott): * [Error conditions and reporting](errors.md) -->
<!-- TODO(n3wscott): * [Sample API usage](normative_examples.md) -->

<!-- TODO(evankanderson):
`This may be the right place, but it seems like it would be useful to include a
section on either "Known issues" with the API and/or patterns that we've agreed
upon. In particular, the use of containers/images for extension of Buses and
Sources is probably worth highlighting somewhere.`

The Parameters/ParametersFrom pattern for passing args to the images is
probably also worth documenting.
-->
See the [Knative Eventing Docs
Architecture](https://github.com/knative/docs/blob/master/eventing/README.md#architecture)
Comment thread
n3wscott marked this conversation as resolved.
for more high level details. <!-- TODO(#498): Update the docs/Architecture page. -->
33 changes: 0 additions & 33 deletions docs/spec/images/overview-reference.dot

This file was deleted.

Binary file removed docs/spec/images/overview-reference.png
Binary file not shown.
1 change: 1 addition & 0 deletions docs/spec/images/resource-types-overview.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/spec/images/resource-types-provisioner.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
91 changes: 91 additions & 0 deletions docs/spec/interfaces.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Interface Contracts

## Subscribable
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think Subscribable needs to be a public interface now that the only valid target of a Subscription is a Channel.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

for now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should document the interface but indicate that the only acceptable target is a Channel at the moment. (Since we agreed to revisit this with real-world experience in 3-6 months.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is already in the spec where subscribable is used, the limitation is channel only.


A **Subscribable** resource contains a list of subscribers and is responsible
for delivering events to each of them. Subscriptions only allow Channels to be
Subscribable (via `spec.from` on the Subscription) at the moment, but this may
be revisited with future experience. _Channel_ as the target of a
_Subscription_'s `from` field.


### Control Plane

The **Subscribable** resource stores a list of resolved _Subscriptions_ in the
resource's `spec.subscribers` field. The Subscription Controller is responsible
for resolving any ObjectReferences (such as _call_ and _result_) in the
_Subscription_ to network addresses.

### Data Plane

**Subscribable** resources will attempt delivery to each of the _subscribers_
at least once, and retry if the subscriber returns errors.
Comment thread
n3wscott marked this conversation as resolved.

<!--TODO(https://github.com/knative/eventing/issues/502) Expand the data plane definitions. -->

---

## Targetable

A **Targetable** resource represents an endpoint that receives events and
optionally returns events to forward downstream. One example of a _Targetable_
is a function.

### Control Plane

A **Targetable** resource MUST expose a _status.targetable.domainInternal_
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
A **Targetable** resource MUST expose a _status.targetable.domainInternal_
A **Targetable** resource MUST expose a _status.domainInternal_

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We want one level of indirection there for couple of reasons, one being that there will be less of a chance to have name collisions and is the standard for the other duck types.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fix this in a followup.

field. The _domainInternal_ value is an internal domain name that is capable of
receiving event deliveries. _Targetable_ resources may be referenced in the
_call_ section of a _Subscription_.

### Data Plane

The **Targetable** resource receives one event and returns zero or more events
in response. The returned events are not required to be related to the received
event. The _Targetable_ should return a successful response if the event was
processed successfully.

The _Targetable_ is not responsible for ensuring successful delivery of any
received or returned event. It may receive the same event multiple times even
if it previously indicated success.
Comment thread
n3wscott marked this conversation as resolved.

---

## Sinkable

A **Sinkable** resource receives events and takes responsibility for further
delivery. Unlike _Targetable_, a _Sinkable_ cannot return events in its
response. One example of a _Sinkable_ is a _Channel_ as the target of a
Comment thread
n3wscott marked this conversation as resolved.
_Subscription_'s _result_ field.

<!-- TODO(evankanderson):
I don't like this example, as it conflates two different things:

That Channel implements Sinkable.
That Subscription expects a Sinkable in its spec.from.
I think it would be clearer to separate the two (and possibly cover the second
item only in the object specs).
-->

### Control Plane

A **Sinkable** resource MUST expose a _status.sinkable.domainInternal_ field.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
A **Sinkable** resource MUST expose a _status.sinkable.domainInternal_ field.
A **Sinkable** resource MUST expose a _status.domainInternal_ field.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ditto.

The _domainInternal_ value is an internal domain name that is capable of
receiving event deliveries. _Sinkable_ resources may be referenced in the
_result_ section of a _Subscription_, and also by other custom resources acting as an event Source.

### Data Plane

A **Sinkable** resource will only respond to requests with success of failure.
Any payload (including a valid CloudEvent) returned to the sender will be
ignored. It may receive the same event multiple times even if it previously
indicated success.

---
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think there is also a "performs Delivery" interface that we wanted Sources to have so that there was a consistent way to see what object a source was sending to?

@vaikas-google proposed this in the meeting yesterday.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@vaikas-google @n3wscott (since you've thought the most about sources as CRDs and have some implementation experience)

Should we mandate that objects which want to act as sources need to implement both "performs Delivery" and be part of a specific named category?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah, added a todo knative/eventing-contrib#12


_Navigation_:

- [Motivation and goals](motivation.md)
- [Resource type overview](overview.md)
- **Interface contracts**
- [Object model specification](spec.md)
25 changes: 20 additions & 5 deletions docs/spec/motivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,26 @@ decoupled way.

Kubernetes has no primitives related to event processing, yet this is an
essential component in serverless workloads. Eventing introduces high-level
primitives for event production and delivery with a focus on push over HTTP. If
a new event source or type is required of your application, the effort required
to plumb them into the existing eventing framework will be minimal and will
integrate with CloudEvents middleware and message consumers.
primitives for event production and delivery with an initial focus on push over
HTTP. If a new event source or type is required of your application, the effort
required to plumb them into the existing eventing framework will be minimal and
will integrate with CloudEvents middleware and message consumers.

The Knative Eventing API is intended to operate independently, and interop
Knative eventing implements common components of an event delivery ecosystem:
enumeration and discovery of event sources, configuration and management of
event transport, and declarative binding of events (generated either by storage
services or earlier computation) to further event processing and persistence.

The Knative Eventing API is intended to operate independently, and interoperate
well with the [Serving API](https://github.com/knative/serving) and [Build
API](https://github.com/knative/build).


---

_Navigation_:

- **Motivation and goals**
- [Resource type overview](overview.md)
- [Interface contracts](interfaces.md)
- [Object model specification](spec.md)
111 changes: 67 additions & 44 deletions docs/spec/overview.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,93 @@
# Resource Groups

Knative Eventing API is grouped into _Channels_, _Feeds_ and _Flows_:
# Resource Types

* _Channels_ define an abstraction between the eventing infrastructure and the
consumption and production of the events.
The API defines and provides a complete implementation for
[Subscription](spec.md#kind-subscription), and abstract resource definitions
for [Channels](spec.md#kind-channel) and
[ClusterChannelProvisioners](spec.md#kind-clusterchannelprovisioner) which may
be fulfilled by multiple backing implementations (much like the Kubernetes
Ingress resource).

* _Feeds_ bridge the event source into the eventing framework.
With extendibility and compostability as a goal of Knative Eventing, the
eventing API defines several resources that can be reduced down to a well
understood contracts. These eventing resource interfaces may be fulfilled by
other Kubernetes objects and then composed in the same way as the concreate
objects. The interfaces are ([Sinkable](interfaces.md#sinkable),
[Subscribable](interfaces.md#Subscribable),
[Targetable](interfaces.md#targetable)). For more details, see
[Interface Contracts](interfaces.md).

* _Flows_ abstract the path of an event from a source takes to reach an event
consumer.
- A **Subscription** describes the transformation of an event and optional
forwarding of a returned event.

Typically, _Feeds_ perform out-of-cluster provisioning, while _Channels_ are
within-cluster management of event delivery. _Flows_ is a higher order wrapper
used to connect event producers directly with event consumers leveraging
_Feeds_ and _Channels_.
- A **Channel** provides event persistance and fanout of events from a
Comment thread
n3wscott marked this conversation as resolved.
well-known input address to multiple outputs described by _Subscriptions_.

# Resource Types
<!-- This image is sourced from https://drive.google.com/open?id=10mmXzDb8S_4_ZG_hcBr7s4HPISyBqcqeJLTXLwkilRc -->

The primary resources in the Knative Eventing _Feeds_ API are EventSource,
EventType and Feed:
![Resource Types Overview](images/resource-types-overview.svg)

* **EventSource**, an archetype of an event producer.
- **ClusterChannelProvisioners** implement strategies for realizing backing resources
for different implementations of _Channels_ currently active in the eventing
system.

* **EventType**, the schema for an event.
<!-- This image is sourced from https://drive.google.com/open?id=1o_0Xh5VjwpQ7Px08h_Q4qnaOdMjt4yCEPixRFwJQjh8 -->

* **Feed**, the association between the output of an event producer to the
input of an event consumer.
<img alt="Resource Types ClusterChannelProvisioners" src="images/resource-types-provisioner.svg" width="200">

An example _Feeds_ setup: GitHub would be the _EventSource_, a Pull Request
notification would be the _EventType_ and the _Feed_ describes the _org/repo_,
credentials, the specific _EventType_ and the consumer of the _Feed_ events.
Sources are defined by independent CRDs that can be installed into a cluster.
For more information see [Knative Eventing
Sources](https://github.com/knative/eventing-sources).

## Subscription

The primary resources in the Knative Eventing _Channels_ API are Channel,
Subscription and Bus:
**Subscriptions** describe a flow of events from one _Channel_) to the next
Comment thread
evankanderson marked this conversation as resolved.
Channel\* through transformations (such as a Knative Service which processes
Comment thread
n3wscott marked this conversation as resolved.
CloudEvents over HTTP). A _Subscription_ controller resolves the addresses of
transformations (`call`) and destination storage (`result`) through the
_Targetable_ and _Sinkable_ interface contracts, and writes the resolved
addresses to the _Channel_ in the `from` reference. _Subscriptions_ do not need
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
addresses to the _Channel_ in the `from` reference. _Subscriptions_ do not need
addresses to the Channel in the `from` reference. Subscriptions do not need

to specify both a transformation and a storage destination, but at least one
must be provided.

* **Channel**, a named endpoint which accepts and forwards events.
All event delivery linkage from a **Subscription** is 1:1 – only a single
`from`, `call`, and `result` may be provided.

* **Bus**, an implementation of an event delivery mechanism.
For more details, see [Kind: Subscription](spec.md#kind-subscription).
Comment thread
n3wscott marked this conversation as resolved.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does this imply that only a linear pipeline of function calls can be supported (regardless of the level of abstraction of deployment units)? Even if I manually deploy a set of Subscription, I could not introduce any conditional logic or branching?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That seems so to my eyes. I think the most important "building block" is missing in the spec: the spec is missing a "standard contract for a service to publish events on a bus channel, regardless of the bus implementation".

"Callable" services are not necessarily functions and moreover they are not necessarily pure functions without side effects. I think a Service should be able to publish one, two or several events within the context of a invocation, provided that it has been given the permissions (e.g. via static resource configuration) to do so.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I agree, that I would expect a Service to be able to publish a number of events. This would also be convenient for error handling and enabling a different component to respond to errors within a Service.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This has come up a couple times now. I think the correct answer is another spec that outlines the runtime contract spec for how subscribables, targetables and sinkables communicate at a protocol level and then how that maps to transports we support.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for calling out this ambiguity. The intent is that Sinkable would be the interface for delivering an event (including to a function) which takes ownership of the event from a "chain of responsibility" pattern.

I think there is a second document we need that describes the data plane transport contracts. For now, our baseline is HTTP POST of CloudEvents, but a protocol-negotiation scheme would be very interesting once we've shipped sufficient primitives.

Copy link
Copy Markdown
Contributor

@sjwoodman sjwoodman Oct 10, 2018

Choose a reason for hiding this comment

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

Thanks @n3wscott @evankanderson based on other comments I now understand how some of this could be achieved - a Service could produce CloudEvents with different EventType that would be sent along a common channel. Some other Services downstream could filter them. However, is it possible, in the current proposal, for a Service to produce multiple messages (for instance of the same type)? I'm thinking of flatMap() type functionality.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@sjwoodman Thanks for your patience!

At the moment, CloudEvents does not define how to deliver or return multiple messages in a single HTTP transaction. I think it would be feasible to extend the CloudEvents spec to support bundling multiple messages via multipart MIME using Structured Content Mode.

Alternatively, your service might be able to also act as an independent source of events, by taking the address of a Channel and performing HTTP delivery directly to the destination.


* **Subscription**, an expressed interest in events from a _Channel_ to be
delivered to an HTTP endpoint.
## Channel

An example _Channels_ setup: A _Channel_ has declared it is implemented by a
PubSubBusImpl. The PubSubBusImpl _Bus_ accepts input from an event producer
that is pushing events to the _Channel_. The _Bus_ also watches for
_Subscription_(s) on the _Channel_ and delivers the events accepted to the
consumer.
**Channel** provides an at least once event delivery mechanism which can fan
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We shouldn't be providing any delivery guarantees. That will be dependent on how the logical Channel is backed via its Provisioner. For example, an in-memory Channel implementation that fails between receiving and delivering an event would not conform to an "at least once" guarantee.

out received events to multiple destinations via _Subscriptions_. A _Channel_
has a single inbound _Sinkable_ interface which may accept events from multiple
_Subscriptions_ or even direct delivery from external systems. Different
_Channels_ may implement different degrees of persistence. Event delivery order
is dependent on the backing implementation of the _Channel_ provided by the
_ClusterChannelProvisioner_.

Event selection on a _Channel_ is 1:N – a single _Channel_ may fan out to
multiple _Subscriptions_.

The _Flows_ API implements a single resource, Flow:
See [Kind: Channel](spec.md#kind-channel).

* **Flow**, is an abstraction of the connection between an event producer to
the event consumer leveraging _Feed_s and _Channels_.
## ClusterChannelProvisioner

**ClusterChannelProvisioner** catalogs available implementations of _Channels_.
_ClusterChannelProvisioners_ hold a JSON Schema that is used to validate the
_Channel_ input arguments. _ClusterChannelProvisioners_ make it possible to
provide cluster wide defaults for the _Channels_ they provision.

An example _Flows_ setup: The _Flow_ describes the same properties as the _Feed_
except the target could be a _Service.serving.knative.dev_ and the _Flow_ will
create the _Channel_, _Feed_, and _Subscription_ for the event to flow from
event producer (GitHub) to event consumer (MyService).
_ClusterChannelProvisioners_ do not directly handle events. They are 1:N with
_Channels_.

For more details, see [Kind:
ClusterChannelProvisioner](spec.md#kind-clusterchannelprovisioner).

![Object Model](images/overview-reference.png)

See the [Knative Eventing Docs
Architecture](https://github.com/knative/docs/blob/master/eventing/README.md#architecture)
for more details.
---

_Navigation_:

- [Motivation and goals](motivation.md)
- **Resource type overview**
- [Interface contracts](interfaces.md)
- [Object model specification](spec.md)
Loading