Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ required = [
[[override]]
name = "github.com/knative/pkg"
# HEAD as of 2018-11-02
revision = "04b40fd38ac1cf17e0426b79860c792fd593ce71"
revision = "a8160c7d728d26da67e596c5b1975877082a26e6"

[[constraint]]
name = "github.com/knative/serving"
Expand Down
79 changes: 42 additions & 37 deletions docs/spec/interfaces.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,65 @@
# Interface Contracts

## Targetable
## Addressable

A **Targetable** resource represents an endpoint that receives events and
optionally returns events to forward downstream. One example of a _Targetable_
is a function.
An **Addressable** resource receives events over a network transport
(currently only HTTP is supported). The _Addressable_ returns success when it
has successfully handled the event (for example, by committing it to stable
storage). When used as an _Addressable_, only the acknowledgement or return
code is used to determine whether the event was handled successfully. One
example of an _Addressable_ is a _Channel_.

### Control Plane

A **Targetable** resource MUST expose a `status.targetable.domainInternal`
field. The _domainInternal_ value is an internal domain name that is capable of
receiving event deliveries. _Targetable_ resources may be referenced in the
`subscriber` section of a _Subscription_.
An **Addressable** resource MUST expose a `status.address.hostname` field.
The _hostname_ value is a cluster-resolvable DNS name which is capable of
receiving event deliveries. _Addressable_ resources may be referenced in the
`reply` section of a _Subscription_, and also by other custom resources acting
as an event Source.

### 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.
An **Addressable** resource will only respond to requests with success or
failure. Any payload (including a valid CloudEvent) returned to the sender
will be ignored. An _Addressable_ may receive the same event multiple times
even if it previously indicated success.

---

## Sinkable
## Callable

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
_Subscription_'s `reply` field.
A **Callable** resource represents an _Addressable_ endpoint which receives
events and optionally returns events to forward downstream. One example of a
_Callable_ is a function. Note that all _Callable_ resources are _Addressable_
(they accept an event and return a status code when completed), but not all
_Addressable_ resources are _Callable_.

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

That Channel implements Sinkable.
That Subscription expects a Sinkable in its spec.reply.
I think it would be clearer to separate the two (and possibly cover the second
item only in the object specs).
-->
A **Callable** resource MUST expose a `status.address.hostname` field (like
_Addressable_). The _hostname_ value is a cluster-resolvable DNS name which is
capable of receiving event deliveries and returning a resulting event in the
reply.. _Callable_ resources may be referenced in the `subscriber` section of
a _Subscription_.

### Control Plane
<!-- TODO(evankanderson):

What other properties separate a callable from an Addressable. We have talked
about using an annotation like `eventing.knative.dev/returnType = any` to
represent the return type of the _Callable_.

A **Sinkable** resource MUST expose a `status.sinkable.domainInternal` field.
The _domainInternal_ value is an internal domain name that is capable of
receiving event deliveries. _Sinkable_ resources may be referenced in the
`reply` 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.
The **Callable** 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 _Callable_ should return a successful response if the event was
processed successfully.

The _Callable_ 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.

---

Expand Down
24 changes: 12 additions & 12 deletions docs/spec/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
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).
[ClusterChannelProvisioners](spec.md#kind-clusterchannelprovisioner) which
may be fulfilled by multiple backing implementations (much like the
Kubernetes Ingress resource).

With extensibility and composability as a goal of Knative Eventing, the
eventing API defines several resources that can be reduced down to well
understood contracts. These eventing resource interfaces may be fulfilled by
other Kubernetes objects and then composed in the same way as the concrete
objects. The interfaces are ([Sinkable](interfaces.md#sinkable),
objects. The interfaces are ([Addressable](interfaces.md#addressable),
[Subscribable](interfaces.md#Subscribable),
[Targetable](interfaces.md#targetable)). For more details, see
[Callable](interfaces.md#callable)). For more details, see
[Interface Contracts](interfaces.md).

- A **Subscription** describes the transformation of an event and optional
Expand Down Expand Up @@ -43,22 +43,22 @@ Sources](https://github.com/knative/eventing-sources).
**Subscriptions** describe a flow of events from one _Channel_ to the next
Channel\* through transformations (such as a Knative Service which processes
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
to specify both a transformation and a storage destination, but at least one
must be provided.
transformations (`subscriber`) and destination storage (`result`) through the
_Callable_ and _Addressable_ interface contracts, and writes the resolved
addresses to the _Channel_ in the `channel` reference. _Subscriptions_ do not
need to specify both a transformation and a storage destination, but at least
one must be provided.

All event delivery linkage from a **Subscription** is 1:1 – only a single
`from`, `call`, and `result` may be provided.
`channel`, `subscriber`, and `result` may be provided.

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

## Channel

**Channel** provides an event delivery mechanism which can fan out received
events to multiple destinations via _Subscriptions_. A _Channel_ has a single
inbound _Sinkable_ interface which may accept events delivered directly or
inbound _Addressable_ interface which may accept events delivered directly or
forwarded from multiple _Subscriptions_. Different _Channels_ may implement
different degrees of persistence. Event delivery order is dependent on the
backing implementation of the _Channel_ provided by the
Expand Down
18 changes: 9 additions & 9 deletions docs/spec/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ its subscribers._

#### Status

| Field | Type | Description | Constraints |
| ---------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- | ----------- |
| sinkable | Sinkable | Address to the endpoint as top-level domain that will distribute traffic over the provided targets from inside the cluster. | |
| conditions | Conditions | Channel conditions. | |
| Field | Type | Description | Constraints |
| ---------- | ----------- | -------------------------------------------------------------------------------------------- | ----------- |
| address | Addressable | Address of the endpoint which meets the [_Addressable_ contract](interfaces.md#addressable). | |
| conditions | Conditions | Channel conditions. | |

##### Conditions

Expand All @@ -70,7 +70,7 @@ its subscribers._

### group: eventing.knative.dev/v1alpha1

_Describes a linkage between a Channel and a Targetable and/or Sinkable._
_Describes a linkage between a Channel and a Callable and/or Addressable channel._

### Object Schema

Expand Down Expand Up @@ -152,10 +152,10 @@ or a Channel system that receives and delivers events._

### SubscriberSpec

| Field | Type | Description | Constraints |
| ------------------- | --------------- | ----------- | -------------------------- |
| ref<sup>1</sup> | ObjectReference | | Must adhere to Targetable. |
| dnsName<sup>1</sup> | String | | |
| Field | Type | Description | Constraints |
| ------------------- | --------------- | ----------- | ------------------------ |
| ref<sup>1</sup> | ObjectReference | | Must adhere to Callable. |
| dnsName<sup>1</sup> | String | | |

1: One of (ref, dnsName), Required.

Expand Down
44 changes: 23 additions & 21 deletions pkg/apis/eventing/v1alpha1/channel_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Channel is an abstract resource that implements the Sinkable contract.
// Channel is an abstract resource that implements the Addressable contract.
// The Provisioner provisions infrastructure to accepts events and
// deliver to Subscriptions.
type Channel struct {
Expand Down Expand Up @@ -67,16 +67,16 @@ type ChannelSpec struct {
// Provisioner defines the name of the Provisioner backing this channel.
Provisioner *corev1.ObjectReference `json:"provisioner,omitempty"`

// Arguments defines the arguments to pass to the Provisioner which provisions
// this Channel.
// Arguments defines the arguments to pass to the Provisioner which
// provisions this Channel.
// +optional
Arguments *runtime.RawExtension `json:"arguments,omitempty"`

// Channel conforms to Duck type Subscribable.
Subscribable *eventingduck.Subscribable `json:"subscribable,omitempty"`
}

var chanCondSet = duckv1alpha1.NewLivingConditionSet(ChannelConditionProvisioned, ChannelConditionSinkable)
var chanCondSet = duckv1alpha1.NewLivingConditionSet(ChannelConditionProvisioned, ChannelConditionAddressable)

// ChannelStatus represents the current state of a Channel.
type ChannelStatus struct {
Expand All @@ -88,10 +88,12 @@ type ChannelStatus struct {
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// Channel is Sinkable. It currently exposes the endpoint as top-level domain
// that will distribute traffic over the provided targets from inside the cluster.
// Channel is Addressable. It currently exposes the endpoint as a
// fully-qualified DNS name which will distribute traffic over the
// provided targets from inside the cluster.
//
// It generally has the form {channel}.{namespace}.svc.cluster.local
Sinkable duckv1alpha1.Sinkable `json:"sinkable,omitempty"`
Address duckv1alpha1.Addressable `json:"address,omitempty"`

// Represents the latest available observations of a channel's current state.
// +optional
Expand All @@ -101,17 +103,17 @@ type ChannelStatus struct {
}

const (
// ChannelConditionReady has status True when the Channel is ready to accept
// traffic.
// ChannelConditionReady has status True when the Channel is ready to
// accept traffic.
ChannelConditionReady = duckv1alpha1.ConditionReady

// ChannelConditionProvisioned has status True when the Channel's backing
// resources have been provisioned.
// ChannelConditionProvisioned has status True when the Channel's
// backing resources have been provisioned.
ChannelConditionProvisioned duckv1alpha1.ConditionType = "Provisioned"

// ChannelConditionSinkable has status true when this Channel meets the Sinkable contract and
// has a non-empty domainInternal.
ChannelConditionSinkable duckv1alpha1.ConditionType = "Sinkable"
// ChannelConditionAddressable has status true when this Channel meets
// the Addressable contract and has a non-empty hostname.
ChannelConditionAddressable duckv1alpha1.ConditionType = "Addressable"
)

// GetCondition returns the condition currently associated with the given type, or nil.
Expand All @@ -134,14 +136,14 @@ func (cs *ChannelStatus) MarkProvisioned() {
chanCondSet.Manage(cs).MarkTrue(ChannelConditionProvisioned)
}

// SetSinkable makes this Channel sinkable by setting the domainInternal. It also sets the
// ChannelConditionSinkable to true.
func (cs *ChannelStatus) SetSinkable(domainInternal string) {
cs.Sinkable.DomainInternal = domainInternal
if domainInternal != "" {
chanCondSet.Manage(cs).MarkTrue(ChannelConditionSinkable)
// SetAddress makes this Channel addressable by setting the hostname. It also
// sets the ChannelConditionAddressable to true.
func (cs *ChannelStatus) SetAddress(hostname string) {
cs.Address.Hostname = hostname
if hostname != "" {
chanCondSet.Manage(cs).MarkTrue(ChannelConditionAddressable)
} else {
chanCondSet.Manage(cs).MarkFalse(ChannelConditionSinkable, "emptyDomainInternal", "domainInternal is the empty string")
chanCondSet.Manage(cs).MarkFalse(ChannelConditionAddressable, "emptyHostname", "hostname is the empty string")
}
}

Expand Down
Loading