Skip to content

Commit

Permalink
Subscriptions: Declarative Go Generic Loader (dapr#7582)
Browse files Browse the repository at this point in the history
* Subscriptions: Declarative Go Generic Loader

Following Components and HTTPEndpoints, creates a generic disk &
kubernetes loader for Subscriptions. Removes the adhok loaders from
existing runtime pubsub packages. This is required for adding
Subscriptions to the hot reloader reconciler and making a more
consistent & testable manifest loader package.

The disk loader loads both `v1alpha1` and `v2alpha1` Subscriptions,
converting `v1alpha1` to `v2alpha1` on successful load. Since the
operator returns only `v2alpha1` Subscriptions (Kubernetes API converts
`v1alpha1` to `v2alpha1`), the Kubernetes loader only loads `v2alpha1`.

`APIVersion() string` func has been added to the generic `meta.Resource`
interface type to allow for the generic loader to determine between
resource versions, supporting differentiating `v1alpha1` and `v2alpha1`
Subscription resource versions.

To ensure backwards compatibility of the previous disk Subscription
loader, the generic disk loader now tracks the order in which manifests
are loaded. This ensures that, even though `v1alpha1` and `v2alpha1`
Subscriptions use separate loaders, their file position order is
preserved once `v1alpha1` Subscriptions are converted to `v2alpha1`.
Subscription backwards compatibility of parsing & ingestion priority is
covered by existing extensive integration tests.

Notice that _ZERO_ of the comprehensive subscription integration tests
have been modified, proving no behaviour change has occurred for loading
and actuating Subscriptions.

Explanation of integration test changes:
- daprd/hotreload/selfhosted/crypto: loader now mandates `apiVersion` on
  disk manifests which is more correct. Previous behaviour ignoring this
  field should be considered a bug. Since we use Kubernetes resource
  API schema, `apiVersion` is (and has been) _always_ required.
- framework/process/grpc/operator/server.go: returning non-nil gRPC
  object for mocked operator Subscription RPC call prevents underlying
  gRPC library unmarshal nil errors- more correct than previous
  implementation.

Part of [Subscription hot-reloading](dapr#7139).

Signed-off-by: joshvanl <[email protected]>

* Update errS to patherrs to avoid confusion

Signed-off-by: joshvanl <[email protected]>

* Updates sub import to use bare version string

Signed-off-by: joshvanl <[email protected]>

* Remove unneeded code comment

Signed-off-by: joshvanl <[email protected]>

* Change test manifests to have unique names

Signed-off-by: joshvanl <[email protected]>

---------

Signed-off-by: joshvanl <[email protected]>
Co-authored-by: Dapr Bot <[email protected]>
  • Loading branch information
JoshVanL and dapr-bot authored Apr 11, 2024
1 parent 2dc5c87 commit 8bd7e07
Show file tree
Hide file tree
Showing 29 changed files with 762 additions and 874 deletions.
4 changes: 4 additions & 0 deletions pkg/apis/components/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ func (Component) Kind() string {
return "Component"
}

func (Component) APIVersion() string {
return components.GroupName + "/" + Version
}

// GetName returns the component name.
func (c Component) GetName() string {
return c.Name
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/httpEndpoint/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ func (HTTPEndpoint) Kind() string {
return kind
}

func (HTTPEndpoint) APIVersion() string {
return httpendpoint.GroupName + "/" + Version
}

// GetName returns the component name.
func (h HTTPEndpoint) GetName() string {
return h.Name
Expand Down
4 changes: 2 additions & 2 deletions pkg/apis/subscriptions/v1alpha1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
// SchemeGroupVersion is group version used to register these objects.
var SchemeGroupVersion = schema.GroupVersion{Group: subscriptions.GroupName, Version: "v1alpha1"}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind.
func Kind(kind string) schema.GroupKind {
// GroupKindFromKind takes an unqualified kind and returns back a Group qualified GroupKind.
func GroupKindFromKind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

Expand Down
48 changes: 48 additions & 0 deletions pkg/apis/subscriptions/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/dapr/dapr/pkg/apis/common"
"github.com/dapr/dapr/pkg/apis/subscriptions"
)

const (
Kind = "Subscription"
Version = "v1alpha1"
)

// +genclient
Expand Down Expand Up @@ -59,3 +67,43 @@ type SubscriptionList struct {

Items []Subscription `json:"items"`
}

func (Subscription) Kind() string {
return Kind
}

func (Subscription) APIVersion() string {
return subscriptions.GroupName + "/" + Version
}

// EmptyMetaDeepCopy returns a new instance of the subscription type with the
// TypeMeta's Kind and APIVersion fields set.
func (s Subscription) EmptyMetaDeepCopy() metav1.Object {
n := s.DeepCopy()
n.TypeMeta = metav1.TypeMeta{
Kind: Kind,
APIVersion: subscriptions.GroupName + "/" + Version,
}
n.ObjectMeta = metav1.ObjectMeta{Name: s.Name}
return n
}

func (s Subscription) GetName() string {
return s.Name
}

func (s Subscription) GetNamespace() string {
return s.Namespace
}

func (s Subscription) GetSecretStore() string {
return ""
}

func (s Subscription) LogName() string {
return s.GetName()
}

func (s Subscription) NameValuePairs() []common.NameValuePair {
return nil
}
4 changes: 2 additions & 2 deletions pkg/apis/subscriptions/v2alpha1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
// SchemeGroupVersion is group version used to register these objects.
var SchemeGroupVersion = schema.GroupVersion{Group: subscriptions.GroupName, Version: "v2alpha1"}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind.
func Kind(kind string) schema.GroupKind {
// GroupKindFromKind takes an unqualified kind and returns back a Group qualified GroupKind.
func GroupKindFromKind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

Expand Down
48 changes: 48 additions & 0 deletions pkg/apis/subscriptions/v2alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ package v2alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/dapr/dapr/pkg/apis/common"
"github.com/dapr/dapr/pkg/apis/subscriptions"
)

const (
Kind = "Subscription"
Version = "v2alpha1"
)

// +genclient
Expand Down Expand Up @@ -90,3 +98,43 @@ type SubscriptionList struct {

Items []Subscription `json:"items"`
}

func (Subscription) Kind() string {
return Kind
}

func (Subscription) APIVersion() string {
return subscriptions.GroupName + "/" + Version
}

// EmptyMetaDeepCopy returns a new instance of the subscription type with the
// TypeMeta's Kind and APIVersion fields set.
func (s Subscription) EmptyMetaDeepCopy() metav1.Object {
n := s.DeepCopy()
n.TypeMeta = metav1.TypeMeta{
Kind: Kind,
APIVersion: subscriptions.GroupName + "/" + Version,
}
n.ObjectMeta = metav1.ObjectMeta{Name: s.Name}
return n
}

func (s Subscription) GetName() string {
return s.Name
}

func (s Subscription) GetNamespace() string {
return s.Namespace
}

func (s Subscription) GetSecretStore() string {
return ""
}

func (s Subscription) LogName() string {
return s.GetName()
}

func (s Subscription) NameValuePairs() []common.NameValuePair {
return nil
}
15 changes: 10 additions & 5 deletions pkg/internal/apis/namevaluepair.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ import (
)

type GenericNameValueResource struct {
Name string
Namespace string
SecretStore string
ResourceKind string
Pairs []common.NameValuePair
Name string
Namespace string
SecretStore string
ResourceKind string
ResourceAPIVersion string
Pairs []common.NameValuePair
}

func (g GenericNameValueResource) Kind() string {
Expand All @@ -37,6 +38,10 @@ func (g GenericNameValueResource) GetName() string {
return g.Name
}

func (g GenericNameValueResource) APIVersion() string {
return g.ResourceAPIVersion
}

func (g GenericNameValueResource) GetNamespace() string {
return g.Namespace
}
Expand Down
23 changes: 23 additions & 0 deletions pkg/internal/loader/disk/components.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Copyright 2024 The Dapr 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 disk

import (
compapi "github.com/dapr/dapr/pkg/apis/components/v1alpha1"
"github.com/dapr/dapr/pkg/internal/loader"
)

func NewComponents(paths ...string) loader.Loader[compapi.Component] {
return new[compapi.Component](paths...)
}
Loading

0 comments on commit 8bd7e07

Please sign in to comment.