From 6718dce964db10f0e3e5bf62c8dc383db1f69ec9 Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Wed, 8 Jul 2020 17:37:11 +0300 Subject: [PATCH] Subscribable and subtypes v1alpha1<>v1 conversion --- .../v1alpha1/subscribable_types_conversion.go | 122 ++++++++++-- .../subscribable_types_conversion_test.go | 188 +++++++++++++++++- 2 files changed, 292 insertions(+), 18 deletions(-) diff --git a/pkg/apis/duck/v1alpha1/subscribable_types_conversion.go b/pkg/apis/duck/v1alpha1/subscribable_types_conversion.go index c174306d312..87ee03df5f9 100644 --- a/pkg/apis/duck/v1alpha1/subscribable_types_conversion.go +++ b/pkg/apis/duck/v1alpha1/subscribable_types_conversion.go @@ -23,14 +23,22 @@ import ( "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" - duckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" + eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1" + eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" ) // ConvertTo implements apis.Convertible -// Converts source (from v1alpha1.SubscribableType) into v1beta1.Subscribable func (source *SubscribableType) ConvertTo(ctx context.Context, obj apis.Convertible) error { switch sink := obj.(type) { - case *duckv1beta1.Subscribable: + case *eventingduckv1beta1.Subscribable: + sink.ObjectMeta = source.ObjectMeta + if err := source.Status.ConvertTo(ctx, &sink.Status); err != nil { + return err + } + if err := source.Spec.ConvertTo(ctx, &sink.Spec); err != nil { + return err + } + case *eventingduckv1.Subscribable: sink.ObjectMeta = source.ObjectMeta if err := source.Status.ConvertTo(ctx, &sink.Status); err != nil { return err @@ -47,9 +55,18 @@ func (source *SubscribableType) ConvertTo(ctx context.Context, obj apis.Converti // ConvertTo implements apis.Convertible func (source *SubscribableTypeSpec) ConvertTo(ctx context.Context, obj apis.Convertible) error { switch sink := obj.(type) { - case *duckv1beta1.SubscribableSpec: + case *eventingduckv1beta1.SubscribableSpec: if source.Subscribable != nil { - sink.Subscribers = make([]duckv1beta1.SubscriberSpec, len(source.Subscribable.Subscribers)) + sink.Subscribers = make([]eventingduckv1beta1.SubscriberSpec, len(source.Subscribable.Subscribers)) + for i, s := range source.Subscribable.Subscribers { + if err := s.ConvertTo(ctx, &sink.Subscribers[i]); err != nil { + return err + } + } + } + case *eventingduckv1.SubscribableSpec: + if source.Subscribable != nil && len(source.Subscribable.Subscribers) > 0 { + sink.Subscribers = make([]eventingduckv1.SubscriberSpec, len(source.Subscribable.Subscribers)) for i, s := range source.Subscribable.Subscribers { if err := s.ConvertTo(ctx, &sink.Subscribers[i]); err != nil { return err @@ -65,7 +82,7 @@ func (source *SubscribableTypeSpec) ConvertTo(ctx context.Context, obj apis.Conv // ConvertTo implements apis.Convertible func (source *SubscriberSpec) ConvertTo(ctx context.Context, obj apis.Convertible) error { switch sink := obj.(type) { - case *duckv1beta1.SubscriberSpec: + case *eventingduckv1beta1.SubscriberSpec: sink.UID = source.UID sink.Generation = source.Generation sink.SubscriberURI = source.SubscriberURI @@ -76,12 +93,31 @@ func (source *SubscriberSpec) ConvertTo(ctx context.Context, obj apis.Convertibl } else { // If however, there's a Deprecated DeadLetterSinkURI, convert that up // to DeliverySpec. - sink.Delivery = &duckv1beta1.DeliverySpec{ + sink.Delivery = &eventingduckv1beta1.DeliverySpec{ DeadLetterSink: &duckv1.Destination{ URI: source.DeadLetterSinkURI, }, } } + case *eventingduckv1.SubscriberSpec: + sink.UID = source.UID + sink.Generation = source.Generation + sink.SubscriberURI = source.SubscriberURI + if source.Delivery != nil { + sink.Delivery = &eventingduckv1.DeliverySpec{} + if err := source.Delivery.ConvertTo(ctx, sink.Delivery); err != nil { + return err + } + } else { + // If however, there's a Deprecated DeadLetterSinkURI, convert that up + // to DeliverySpec. + sink.Delivery = &eventingduckv1.DeliverySpec{ + DeadLetterSink: &duckv1.Destination{ + URI: source.DeadLetterSinkURI, + }, + } + } + sink.ReplyURI = source.ReplyURI default: return fmt.Errorf("unknown version, got: %T", sink) } @@ -91,12 +127,12 @@ func (source *SubscriberSpec) ConvertTo(ctx context.Context, obj apis.Convertibl // ConvertTo implements apis.Convertible func (source *SubscribableTypeStatus) ConvertTo(ctx context.Context, obj apis.Convertible) error { switch sink := obj.(type) { - case *duckv1beta1.SubscribableStatus: + case *eventingduckv1beta1.SubscribableStatus: if source.SubscribableStatus != nil && len(source.SubscribableStatus.Subscribers) > 0 { - sink.Subscribers = make([]duckv1beta1.SubscriberStatus, len(source.SubscribableStatus.Subscribers)) + sink.Subscribers = make([]eventingduckv1beta1.SubscriberStatus, len(source.SubscribableStatus.Subscribers)) for i, ss := range source.SubscribableStatus.Subscribers { - sink.Subscribers[i] = duckv1beta1.SubscriberStatus{ + sink.Subscribers[i] = eventingduckv1beta1.SubscriberStatus{ UID: ss.UID, ObservedGeneration: ss.ObservedGeneration, Ready: ss.Ready, @@ -104,6 +140,17 @@ func (source *SubscribableTypeStatus) ConvertTo(ctx context.Context, obj apis.Co } } } + case *eventingduckv1.SubscribableStatus: + if source.SubscribableStatus != nil && + len(source.SubscribableStatus.Subscribers) > 0 { + sink.Subscribers = make([]eventingduckv1.SubscriberStatus, len(source.SubscribableStatus.Subscribers)) + for i, ss := range source.SubscribableStatus.Subscribers { + sink.Subscribers[i] = eventingduckv1.SubscriberStatus{} + if err := ss.ConvertTo(ctx, &sink.Subscribers[i]); err != nil { + return err + } + } + } default: return fmt.Errorf("unknown version, got: %T", sink) } @@ -114,7 +161,15 @@ func (source *SubscribableTypeStatus) ConvertTo(ctx context.Context, obj apis.Co // Converts obj v1beta1.Subscribable into v1alpha1.SubscribableType func (sink *SubscribableType) ConvertFrom(ctx context.Context, obj apis.Convertible) error { switch source := obj.(type) { - case *duckv1beta1.Subscribable: + case *eventingduckv1beta1.Subscribable: + sink.ObjectMeta = source.ObjectMeta + if err := sink.Status.ConvertFrom(ctx, &source.Status); err != nil { + return err + } + if err := sink.Spec.ConvertFrom(ctx, &source.Spec); err != nil { + return err + } + case *eventingduckv1.Subscribable: sink.ObjectMeta = source.ObjectMeta if err := sink.Status.ConvertFrom(ctx, &source.Status); err != nil { return err @@ -131,7 +186,18 @@ func (sink *SubscribableType) ConvertFrom(ctx context.Context, obj apis.Converti // ConvertFrom implements apis.Convertible func (sink *SubscribableTypeSpec) ConvertFrom(ctx context.Context, obj apis.Convertible) error { switch source := obj.(type) { - case *duckv1beta1.SubscribableSpec: + case *eventingduckv1beta1.SubscribableSpec: + if len(source.Subscribers) > 0 { + sink.Subscribable = &Subscribable{ + Subscribers: make([]SubscriberSpec, len(source.Subscribers)), + } + for i, s := range source.Subscribers { + if err := sink.Subscribable.Subscribers[i].ConvertFrom(ctx, &s); err != nil { + return err + } + } + } + case *eventingduckv1.SubscribableSpec: if len(source.Subscribers) > 0 { sink.Subscribable = &Subscribable{ Subscribers: make([]SubscriberSpec, len(source.Subscribers)), @@ -151,7 +217,7 @@ func (sink *SubscribableTypeSpec) ConvertFrom(ctx context.Context, obj apis.Conv // ConvertFrom implements apis.Convertible func (sink *SubscriberSpec) ConvertFrom(ctx context.Context, obj apis.Convertible) error { switch source := obj.(type) { - case *duckv1beta1.SubscriberSpec: + case *eventingduckv1beta1.SubscriberSpec: var deadLetterSinkURI *apis.URL if source.Delivery != nil && source.Delivery.DeadLetterSink != nil { deadLetterSinkURI = source.Delivery.DeadLetterSink.URI @@ -162,6 +228,18 @@ func (sink *SubscriberSpec) ConvertFrom(ctx context.Context, obj apis.Convertibl sink.ReplyURI = source.ReplyURI sink.Delivery = source.Delivery sink.DeadLetterSinkURI = deadLetterSinkURI + case *eventingduckv1.SubscriberSpec: + sink.UID = source.UID + sink.Generation = source.Generation + sink.SubscriberURI = source.SubscriberURI + sink.ReplyURI = source.ReplyURI + if source.Delivery != nil { + sink.Delivery = &eventingduckv1beta1.DeliverySpec{} + if err := sink.Delivery.ConvertFrom(ctx, source.Delivery); err != nil { + return err + } + sink.DeadLetterSinkURI = source.Delivery.DeadLetterSink.URI + } default: return fmt.Errorf("unknown version, got: %T", sink) } @@ -171,13 +249,13 @@ func (sink *SubscriberSpec) ConvertFrom(ctx context.Context, obj apis.Convertibl // ConvertFrom implements apis.Convertible func (sink *SubscribableTypeStatus) ConvertFrom(ctx context.Context, obj apis.Convertible) error { switch source := obj.(type) { - case *duckv1beta1.SubscribableStatus: + case *eventingduckv1beta1.SubscribableStatus: if len(source.Subscribers) > 0 { sink.SubscribableStatus = &SubscribableStatus{ - Subscribers: make([]duckv1beta1.SubscriberStatus, len(source.Subscribers)), + Subscribers: make([]eventingduckv1beta1.SubscriberStatus, len(source.Subscribers)), } for i, ss := range source.Subscribers { - sink.SubscribableStatus.Subscribers[i] = duckv1beta1.SubscriberStatus{ + sink.SubscribableStatus.Subscribers[i] = eventingduckv1beta1.SubscriberStatus{ UID: ss.UID, ObservedGeneration: ss.ObservedGeneration, Ready: ss.Ready, @@ -185,6 +263,18 @@ func (sink *SubscribableTypeStatus) ConvertFrom(ctx context.Context, obj apis.Co } } } + case *eventingduckv1.SubscribableStatus: + if len(source.Subscribers) > 0 { + sink.SubscribableStatus = &SubscribableStatus{ + Subscribers: make([]eventingduckv1beta1.SubscriberStatus, len(source.Subscribers)), + } + for i, ss := range source.Subscribers { + sink.SubscribableStatus.Subscribers[i] = eventingduckv1beta1.SubscriberStatus{} + if err := sink.SubscribableStatus.Subscribers[i].ConvertFrom(ctx, &ss); err != nil { + return err + } + } + } default: return fmt.Errorf("unknown version, got: %T", sink) } diff --git a/pkg/apis/duck/v1alpha1/subscribable_types_conversion_test.go b/pkg/apis/duck/v1alpha1/subscribable_types_conversion_test.go index cdc4e4dbc7d..3c0aed99ab9 100644 --- a/pkg/apis/duck/v1alpha1/subscribable_types_conversion_test.go +++ b/pkg/apis/duck/v1alpha1/subscribable_types_conversion_test.go @@ -27,6 +27,7 @@ import ( "knative.dev/pkg/apis" pkgduckv1 "knative.dev/pkg/apis/duck/v1" + v1 "knative.dev/eventing/pkg/apis/duck/v1" "knative.dev/eventing/pkg/apis/duck/v1beta1" ) @@ -43,7 +44,7 @@ func TestSubscribableTypeConversionBadType(t *testing.T) { } // Test v1alpha1 -> v1beta1 -> v1alpha1 -func TestSubscribableTypeConversion(t *testing.T) { +func TestSubscribableTypeConversionV1alphaV1beta1(t *testing.T) { // Just one for now, just adding the for loop for ease of future changes. versions := []apis.Convertible{&v1beta1.Subscribable{}} @@ -141,8 +142,107 @@ func TestSubscribableTypeConversion(t *testing.T) { } } +// Test v1alpha1 -> v1 -> v1alpha1 +func TestSubscribableTypeConversionV1alphaV1(t *testing.T) { + // Just one for now, just adding the for loop for ease of future changes. + versions := []apis.Convertible{&v1.Subscribable{}} + + linear := v1beta1.BackoffPolicyLinear + + tests := []struct { + name string + in *SubscribableType + }{{ + name: "min configuration", + in: &SubscribableType{ + ObjectMeta: metav1.ObjectMeta{ + Name: "subscribable-name", + Namespace: "subscribable-ns", + Generation: 17, + }, + Spec: SubscribableTypeSpec{}, + Status: SubscribableTypeStatus{}, + }, + }, { + name: "full configuration", + in: &SubscribableType{ + ObjectMeta: metav1.ObjectMeta{ + Name: "subscribable-name", + Namespace: "subscribable-ns", + Generation: 17, + }, + Spec: SubscribableTypeSpec{ + Subscribable: &Subscribable{ + Subscribers: []SubscriberSpec{ + { + UID: "uid-1", + Generation: 7, + SubscriberURI: apis.HTTP("subscriber.example.com"), + ReplyURI: apis.HTTP("reply.example.com"), + DeadLetterSinkURI: apis.HTTP("subscriber.dls.example.com"), + Delivery: &v1beta1.DeliverySpec{ + DeadLetterSink: &pkgduckv1.Destination{ + Ref: &pkgduckv1.KReference{ + Kind: "dlKind", + Namespace: "dlNamespace", + Name: "dlName", + APIVersion: "dlAPIVersion", + }, + URI: apis.HTTP("subscriber.dls.example.com"), + }, + Retry: pointer.Int32Ptr(5), + BackoffPolicy: &linear, + BackoffDelay: pointer.StringPtr("5s"), + }, + }, + { + UID: "uid-2", + Generation: 8, + SubscriberURI: apis.HTTP("subscriber2.example.com"), + ReplyURI: apis.HTTP("reply2.example.com"), + DeadLetterSinkURI: apis.HTTP("subscriber2.dls.example.com"), + Delivery: nil, + }, + }, + }, + }, + Status: SubscribableTypeStatus{ + SubscribableStatus: &SubscribableStatus{ + Subscribers: []v1beta1.SubscriberStatus{ + { + UID: "status-uid-1", + ObservedGeneration: 99, + Ready: corev1.ConditionTrue, + Message: "msg", + }, + }, + }, + }, + }, + }} + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := test.in.ConvertTo(context.Background(), ver); err != nil { + t.Errorf("ConvertTo() = %v", err) + } + got := &SubscribableType{} + if err := got.ConvertFrom(context.Background(), ver); err != nil { + t.Errorf("ConvertFrom() = %v", err) + } + + fixed := fixSubscribableTypeDeprecated(test.in) + if diff := cmp.Diff(fixed, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} + // Test v1beta1 -> v1alpha1 -> v1beta1 -func TestSubscribableTypeConversionWithV1Beta1(t *testing.T) { +func TestSubscribableTypeConversionWithV1beta1V1alpha1(t *testing.T) { // Just one for now, just adding the for loop for ease of future changes. versions := []apis.Convertible{&SubscribableType{}} @@ -225,6 +325,90 @@ func TestSubscribableTypeConversionWithV1Beta1(t *testing.T) { } } +// Test v1 -> v1alpha1 -> v1 +func TestSubscribableTypeConversionWithV1V1alpha1(t *testing.T) { + // Just one for now, just adding the for loop for ease of future changes. + versions := []apis.Convertible{&SubscribableType{}} + + linear := v1.BackoffPolicyLinear + + tests := []struct { + name string + in *v1.Subscribable + }{{ + name: "min", + in: &v1.Subscribable{ + ObjectMeta: metav1.ObjectMeta{ + Name: "subscribable-name", + Namespace: "subscribable-ns", + Generation: 17, + }, + Spec: v1.SubscribableSpec{}, + Status: v1.SubscribableStatus{}, + }, + }, { + name: "full configuration", + in: &v1.Subscribable{ + ObjectMeta: metav1.ObjectMeta{ + Name: "subscribable-name", + Namespace: "subscribable-ns", + Generation: 17, + }, + Spec: v1.SubscribableSpec{ + Subscribers: []v1.SubscriberSpec{ + { + UID: "uid-1", + Generation: 7, + SubscriberURI: apis.HTTP("subscriber.example.com"), + ReplyURI: apis.HTTP("reply.example.com"), + Delivery: &v1.DeliverySpec{ + DeadLetterSink: &pkgduckv1.Destination{ + Ref: &pkgduckv1.KReference{ + Kind: "dlKind", + Namespace: "dlNamespace", + Name: "dlName", + APIVersion: "dlAPIVersion", + }, + URI: apis.HTTP("subscriber.dls.example.com"), + }, + Retry: pointer.Int32Ptr(5), + BackoffPolicy: &linear, + BackoffDelay: pointer.StringPtr("5s"), + }, + }, + }, + }, + Status: v1.SubscribableStatus{ + Subscribers: []v1.SubscriberStatus{ + { + UID: "status-uid-1", + ObservedGeneration: 99, + Ready: corev1.ConditionTrue, + Message: "msg", + }, + }, + }, + }, + }} + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := version.ConvertFrom(context.Background(), test.in); err != nil { + t.Errorf("ConvertTo() = %v", err) + } + got := &v1.Subscribable{} + if err := ver.ConvertTo(context.Background(), got); err != nil { + t.Errorf("ConvertFrom() = %v", err) + } + if diff := cmp.Diff(test.in, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} + func TestSubscribableTypeSpecConversionBadType(t *testing.T) { good, bad := &SubscribableTypeSpec{}, &SubscribableTypeSpec{}