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
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ require (
go.uber.org/zap v1.14.1
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
google.golang.org/grpc v1.28.0
gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d // indirect
k8s.io/api v0.17.6
k8s.io/apiextensions-apiserver v0.17.6
k8s.io/apimachinery v0.17.6
k8s.io/apiserver v0.17.6
k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
k8s.io/utils v0.0.0-20200124190032-861946025e34
knative.dev/pkg v0.0.0-20200622135826-98f8a949a106
knative.dev/pkg v0.0.0-20200622150626-f0da4c9b6e79
knative.dev/test-infra v0.0.0-20200619200026-0b0587234302
sigs.k8s.io/yaml v1.2.0
)
Expand Down
30 changes: 28 additions & 2 deletions go.sum

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions hack/update-codegen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ ${GOPATH}/bin/deepcopy-gen \
# Only deepcopy the Duck types, as they are not real resources.
${CODEGEN_PKG}/generate-groups.sh "deepcopy" \
knative.dev/eventing/pkg/client knative.dev/eventing/pkg/apis \
"duck:v1alpha1 duck:v1beta1" \
"duck:v1alpha1 duck:v1beta1 duck:v1" \
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt

# Knative Injection
chmod +x ${KNATIVE_CODEGEN_PKG}/hack/generate-knative.sh
${KNATIVE_CODEGEN_PKG}/hack/generate-knative.sh "injection" \
knative.dev/eventing/pkg/client knative.dev/eventing/pkg/apis \
"eventing:v1beta1 messaging:v1beta1 flows:v1beta1 sources:v1alpha1 sources:v1alpha2 duck:v1alpha1 duck:v1beta1 configs:v1alpha1" \
"eventing:v1beta1 messaging:v1beta1 flows:v1beta1 sources:v1alpha1 sources:v1alpha2 duck:v1alpha1 duck:v1beta1 duck:v1 configs:v1alpha1" \
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt

# Make sure our dependencies are up-to-date
Expand Down
152 changes: 152 additions & 0 deletions pkg/apis/duck/v1/channelable_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
Copyright 2020 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"knative.dev/pkg/apis"
"knative.dev/pkg/apis/duck"
duckv1 "knative.dev/pkg/apis/duck/v1"
)

// +genduck
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Channelable is a skeleton type wrapping Subscribable and Addressable in the manner we expect resource writers
// defining compatible resources to embed it. We will typically use this type to deserialize
// Channelable ObjectReferences and access their subscription and address data. This is not a real resource.
type Channelable struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

// Spec is the part where the Channelable fulfills the Subscribable contract.
Spec ChannelableSpec `json:"spec,omitempty"`

Status ChannelableStatus `json:"status,omitempty"`
}

// ChannelableSpec contains Spec of the Channelable object
type ChannelableSpec struct {
SubscribableSpec `json:",inline"`

// DeliverySpec contains options controlling the event delivery
// +optional
Delivery *DeliverySpec `json:"delivery,omitempty"`
}

// ChannelableStatus contains the Status of a Channelable object.
type ChannelableStatus struct {
// inherits duck/v1 Status, which currently provides:
// * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller.
// * Conditions - the latest available observations of a resource's current state.
duckv1.Status `json:",inline"`
// AddressStatus is the part where the Channelable fulfills the Addressable contract.
duckv1.AddressStatus `json:",inline"`
// Subscribers is populated with the statuses of each of the Channelable's subscribers.
SubscribableStatus `json:",inline"`
// DeadLetterChannel is a KReference and is set by the channel when it supports native error handling via a channel
// Failed messages are delivered here.
// +optional
DeadLetterChannel *duckv1.KReference `json:"deadLetterChannel,omitempty"`
}

var (
// Verify Channelable resources meet duck contracts.
_ duck.Populatable = (*Channelable)(nil)
_ duck.Implementable = (*Channelable)(nil)
_ apis.Listable = (*Channelable)(nil)
)

// Populate implements duck.Populatable
func (c *Channelable) Populate() {
c.Spec.SubscribableSpec = SubscribableSpec{
// Populate ALL fields
Subscribers: []SubscriberSpec{{
UID: "2f9b5e8e-deb6-11e8-9f32-f2801f1b9fd1",
Generation: 1,
SubscriberURI: apis.HTTP("call1"),
ReplyURI: apis.HTTP("sink2"),
}, {
UID: "34c5aec8-deb6-11e8-9f32-f2801f1b9fd1",
Generation: 2,
SubscriberURI: apis.HTTP("call2"),
ReplyURI: apis.HTTP("sink2"),
}},
}
retry := int32(5)
linear := BackoffPolicyLinear
delay := "5s"
c.Spec.Delivery = &DeliverySpec{
DeadLetterSink: &duckv1.Destination{
Ref: &duckv1.KReference{
Name: "aname",
},
URI: &apis.URL{
Scheme: "http",
Host: "test-error-domain",
},
},
Retry: &retry,
BackoffPolicy: &linear,
BackoffDelay: &delay,
}
c.Status = ChannelableStatus{
AddressStatus: duckv1.AddressStatus{
Address: &duckv1.Addressable{
URL: &apis.URL{
Scheme: "http",
Host: "test-domain",
},
},
},
SubscribableStatus: SubscribableStatus{
Subscribers: []SubscriberStatus{{
UID: "2f9b5e8e-deb6-11e8-9f32-f2801f1b9fd1",
ObservedGeneration: 1,
Ready: corev1.ConditionTrue,
Message: "Some message",
}, {
UID: "34c5aec8-deb6-11e8-9f32-f2801f1b9fd1",
ObservedGeneration: 2,
Ready: corev1.ConditionFalse,
Message: "Some message",
}},
},
}
}

// GetFullType implements duck.Implementable
func (s *Channelable) GetFullType() duck.Populatable {
return &Channelable{}
}

// GetListType implements apis.Listable
func (c *Channelable) GetListType() runtime.Object {
return &ChannelableList{}
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ChannelableList is a list of Channelable resources.
type ChannelableList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`

Items []Channelable `json:"items"`
}
107 changes: 107 additions & 0 deletions pkg/apis/duck/v1/channelable_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
Copyright 2020 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1

import (
"testing"

corev1 "k8s.io/api/core/v1"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"

"github.com/google/go-cmp/cmp"
)

func TestChannelableGetListType(t *testing.T) {
c := &Channelable{}
switch c.GetListType().(type) {
case *ChannelableList:
// expected
default:
t.Errorf("expected GetListType to return *ChannelableList, got %T", c.GetListType())
}
}

func TestChannelablePopulate(t *testing.T) {
got := &Channelable{}

retry := int32(5)
linear := BackoffPolicyLinear
delay := "5s"
want := &Channelable{
Spec: ChannelableSpec{
SubscribableSpec: SubscribableSpec{
Subscribers: []SubscriberSpec{{
UID: "2f9b5e8e-deb6-11e8-9f32-f2801f1b9fd1",
Generation: 1,
SubscriberURI: apis.HTTP("call1"),
ReplyURI: apis.HTTP("sink2"),
}, {
UID: "34c5aec8-deb6-11e8-9f32-f2801f1b9fd1",
Generation: 2,
SubscriberURI: apis.HTTP("call2"),
ReplyURI: apis.HTTP("sink2"),
}},
},
Delivery: &DeliverySpec{
DeadLetterSink: &duckv1.Destination{
Ref: &duckv1.KReference{
Name: "aname",
},
URI: &apis.URL{
Scheme: "http",
Host: "test-error-domain",
},
},
Retry: &retry,
BackoffPolicy: &linear,
BackoffDelay: &delay,
},
},

Status: ChannelableStatus{
AddressStatus: duckv1.AddressStatus{
Address: &duckv1.Addressable{
URL: &apis.URL{
Scheme: "http",
Host: "test-domain",
},
},
},
SubscribableStatus: SubscribableStatus{
Subscribers: []SubscriberStatus{{
UID: "2f9b5e8e-deb6-11e8-9f32-f2801f1b9fd1",
ObservedGeneration: 1,
Ready: corev1.ConditionTrue,
Message: "Some message",
}, {
UID: "34c5aec8-deb6-11e8-9f32-f2801f1b9fd1",
ObservedGeneration: 2,
Ready: corev1.ConditionFalse,
Message: "Some message",
}},
},
},
}

got.Populate()

if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Unexpected difference (-want, +got): %v", diff)
}

}
44 changes: 44 additions & 0 deletions pkg/apis/duck/v1/delivery_conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
Copyright 2020 The Knative Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1

import (
"context"
"fmt"

"knative.dev/pkg/apis"
)

// ConvertTo implements apis.Convertible
func (source *DeliverySpec) ConvertTo(ctx context.Context, sink apis.Convertible) error {
return fmt.Errorf("v1 is the highest known version, got: %T", sink)
}

// ConvertFrom implements apis.Convertible
func (sink *DeliverySpec) ConvertFrom(ctx context.Context, source apis.Convertible) error {
return fmt.Errorf("v1 is the highest known version, got: %T", source)
}

// ConvertTo implements apis.Convertible
func (source *DeliveryStatus) ConvertTo(ctx context.Context, sink apis.Convertible) error {
return fmt.Errorf("v1 is the highest known version, got: %T", sink)
}

// ConvertFrom implements apis.Convertible
func (sink *DeliveryStatus) ConvertFrom(ctx context.Context, source apis.Convertible) error {
return fmt.Errorf("v1 is the highest known version, got: %T", source)
}
46 changes: 46 additions & 0 deletions pkg/apis/duck/v1/delivery_conversion_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright 2020 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1

import (
"context"
"testing"
)

func TestDeliverySpecConversionBadType(t *testing.T) {
good, bad := &DeliverySpec{}, &DeliverySpec{}

if err := good.ConvertTo(context.Background(), bad); err == nil {
t.Errorf("ConvertTo() = %#v, wanted error", bad)
}

if err := good.ConvertFrom(context.Background(), bad); err == nil {
t.Errorf("ConvertFrom() = %#v, wanted error", good)
}
}

func TestDeliveryStatusConversionBadType(t *testing.T) {
good, bad := &DeliveryStatus{}, &DeliveryStatus{}

if err := good.ConvertTo(context.Background(), bad); err == nil {
t.Errorf("ConvertTo() = %#v, wanted error", bad)
}

if err := good.ConvertFrom(context.Background(), bad); err == nil {
t.Errorf("ConvertFrom() = %#v, wanted error", good)
}
}
Loading