mirror of https://github.com/knative/pkg.git
				
				
				
			Implement getter machinery to generically fetch all injected clients (#2054)
This commit is contained in:
		
							parent
							
								
									85bc723bac
								
							
						
					
					
						commit
						bbe0bb3eb1
					
				|  | @ -29,6 +29,9 @@ import ( | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	injection.Default.RegisterClient(withClient) | 	injection.Default.RegisterClient(withClient) | ||||||
|  | 	injection.Default.RegisterClientFetcher(func(ctx context.Context) interface{} { | ||||||
|  | 		return Get(ctx) | ||||||
|  | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Key is used as the key for associating information with a context.Context.
 | // Key is used as the key for associating information with a context.Context.
 | ||||||
|  |  | ||||||
|  | @ -31,6 +31,9 @@ import ( | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	injection.Fake.RegisterClient(withClient) | 	injection.Fake.RegisterClient(withClient) | ||||||
|  | 	injection.Fake.RegisterClientFetcher(func(ctx context.Context) interface{} { | ||||||
|  | 		return Get(ctx) | ||||||
|  | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func withClient(ctx context.Context, cfg *rest.Config) context.Context { | func withClient(ctx context.Context, cfg *rest.Config) context.Context { | ||||||
|  |  | ||||||
|  | @ -29,6 +29,9 @@ import ( | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	injection.Default.RegisterClient(withClient) | 	injection.Default.RegisterClient(withClient) | ||||||
|  | 	injection.Default.RegisterClientFetcher(func(ctx context.Context) interface{} { | ||||||
|  | 		return Get(ctx) | ||||||
|  | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Key is used as the key for associating information with a context.Context.
 | // Key is used as the key for associating information with a context.Context.
 | ||||||
|  |  | ||||||
|  | @ -31,6 +31,9 @@ import ( | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	injection.Fake.RegisterClient(withClient) | 	injection.Fake.RegisterClient(withClient) | ||||||
|  | 	injection.Fake.RegisterClientFetcher(func(ctx context.Context) interface{} { | ||||||
|  | 		return Get(ctx) | ||||||
|  | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func withClient(ctx context.Context, cfg *rest.Config) context.Context { | func withClient(ctx context.Context, cfg *rest.Config) context.Context { | ||||||
|  |  | ||||||
|  | @ -66,7 +66,11 @@ func (g *clientGenerator) GenerateType(c *generator.Context, t *types.Type, w io | ||||||
| 		"clientSetNewForConfigOrDie": c.Universe.Function(types.Name{Package: g.clientSetPackage, Name: "NewForConfigOrDie"}), | 		"clientSetNewForConfigOrDie": c.Universe.Function(types.Name{Package: g.clientSetPackage, Name: "NewForConfigOrDie"}), | ||||||
| 		"clientSetInterface":         c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), | 		"clientSetInterface":         c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), | ||||||
| 		"injectionRegisterClient":    c.Universe.Function(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterClient"}), | 		"injectionRegisterClient":    c.Universe.Function(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterClient"}), | ||||||
| 		"restConfig":                 c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Config"}), | 		"injectionRegisterClientFetcher": c.Universe.Function(types.Name{ | ||||||
|  | 			Package: "knative.dev/pkg/injection", | ||||||
|  | 			Name:    "Default.RegisterClientFetcher", | ||||||
|  | 		}), | ||||||
|  | 		"restConfig": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Config"}), | ||||||
| 		"loggingFromContext": c.Universe.Function(types.Name{ | 		"loggingFromContext": c.Universe.Function(types.Name{ | ||||||
| 			Package: "knative.dev/pkg/logging", | 			Package: "knative.dev/pkg/logging", | ||||||
| 			Name:    "FromContext", | 			Name:    "FromContext", | ||||||
|  | @ -85,6 +89,9 @@ func (g *clientGenerator) GenerateType(c *generator.Context, t *types.Type, w io | ||||||
| var injectionClient = ` | var injectionClient = ` | ||||||
| func init() { | func init() { | ||||||
| 	{{.injectionRegisterClient|raw}}(withClient) | 	{{.injectionRegisterClient|raw}}(withClient) | ||||||
|  | 	{{.injectionRegisterClientFetcher|raw}}(func(ctx context.Context) interface{} { | ||||||
|  | 		return Get(ctx) | ||||||
|  | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Key is used as the key for associating information with a context.Context.
 | // Key is used as the key for associating information with a context.Context.
 | ||||||
|  |  | ||||||
|  | @ -71,6 +71,10 @@ func (g *fakeClientGenerator) GenerateType(c *generator.Context, t *types.Type, | ||||||
| 			Package: "knative.dev/pkg/injection", | 			Package: "knative.dev/pkg/injection", | ||||||
| 			Name:    "Fake.RegisterClient", | 			Name:    "Fake.RegisterClient", | ||||||
| 		}), | 		}), | ||||||
|  | 		"injectionRegisterClientFetcher": c.Universe.Function(types.Name{ | ||||||
|  | 			Package: "knative.dev/pkg/injection", | ||||||
|  | 			Name:    "Fake.RegisterClientFetcher", | ||||||
|  | 		}), | ||||||
| 		"loggingFromContext": c.Universe.Function(types.Name{ | 		"loggingFromContext": c.Universe.Function(types.Name{ | ||||||
| 			Package: "knative.dev/pkg/logging", | 			Package: "knative.dev/pkg/logging", | ||||||
| 			Name:    "FromContext", | 			Name:    "FromContext", | ||||||
|  | @ -91,6 +95,9 @@ func (g *fakeClientGenerator) GenerateType(c *generator.Context, t *types.Type, | ||||||
| var injectionFakeClient = ` | var injectionFakeClient = ` | ||||||
| func init() { | func init() { | ||||||
| 	{{.injectionRegisterClient|raw}}(withClient) | 	{{.injectionRegisterClient|raw}}(withClient) | ||||||
|  | 	{{.injectionRegisterClientFetcher|raw}}(func(ctx context.Context) interface{} { | ||||||
|  | 		return Get(ctx) | ||||||
|  | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func withClient(ctx {{.contextContext|raw}}, cfg *{{.restConfig|raw}}) {{.contextContext|raw}} { | func withClient(ctx {{.contextContext|raw}}, cfg *{{.restConfig|raw}}) {{.contextContext|raw}} { | ||||||
|  |  | ||||||
|  | @ -26,6 +26,10 @@ import ( | ||||||
| // client type to a context.
 | // client type to a context.
 | ||||||
| type ClientInjector func(context.Context, *rest.Config) context.Context | type ClientInjector func(context.Context, *rest.Config) context.Context | ||||||
| 
 | 
 | ||||||
|  | // ClientFetcher holds the type of a callback that returns a particular client type
 | ||||||
|  | // from a context.
 | ||||||
|  | type ClientFetcher func(context.Context) interface{} | ||||||
|  | 
 | ||||||
| func (i *impl) RegisterClient(ci ClientInjector) { | func (i *impl) RegisterClient(ci ClientInjector) { | ||||||
| 	i.m.Lock() | 	i.m.Lock() | ||||||
| 	defer i.m.Unlock() | 	defer i.m.Unlock() | ||||||
|  | @ -40,3 +44,21 @@ func (i *impl) GetClients() []ClientInjector { | ||||||
| 	// Copy the slice before returning.
 | 	// Copy the slice before returning.
 | ||||||
| 	return append(i.clients[:0:0], i.clients...) | 	return append(i.clients[:0:0], i.clients...) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (i *impl) RegisterClientFetcher(f ClientFetcher) { | ||||||
|  | 	i.m.Lock() | ||||||
|  | 	defer i.m.Unlock() | ||||||
|  | 
 | ||||||
|  | 	i.clientFetchers = append(i.clientFetchers, f) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (i *impl) FetchAllClients(ctx context.Context) []interface{} { | ||||||
|  | 	i.m.RLock() | ||||||
|  | 	defer i.m.RUnlock() | ||||||
|  | 
 | ||||||
|  | 	clients := make([]interface{}, 0, len(i.clientFetchers)) | ||||||
|  | 	for _, f := range i.clientFetchers { | ||||||
|  | 		clients = append(clients, f(ctx)) | ||||||
|  | 	} | ||||||
|  | 	return clients | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/google/go-cmp/cmp" | ||||||
| 	"k8s.io/client-go/rest" | 	"k8s.io/client-go/rest" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -50,3 +51,35 @@ func TestRegisterClient(t *testing.T) { | ||||||
| 		t.Errorf("GetClients() = %d, wanted %d", want, got) | 		t.Errorf("GetClients() = %d, wanted %d", want, got) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | type fakeClient struct { | ||||||
|  | 	Name string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestRegisterClientFetcher(t *testing.T) { | ||||||
|  | 	i := &impl{} | ||||||
|  | 
 | ||||||
|  | 	fakeA := fakeClient{Name: "a"} | ||||||
|  | 	fetchA := func(ctx context.Context) interface{} { | ||||||
|  | 		return fakeA | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fakeB := fakeClient{Name: "b"} | ||||||
|  | 	fetchB := func(ctx context.Context) interface{} { | ||||||
|  | 		return fakeB | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ctx := context.Background() | ||||||
|  | 	if want, got := 0, len(i.FetchAllClients(ctx)); got != want { | ||||||
|  | 		t.Errorf("FetchAllClients() = %d, wanted %d", got, want) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	i.RegisterClientFetcher(fetchA) | ||||||
|  | 	i.RegisterClientFetcher(fetchB) | ||||||
|  | 
 | ||||||
|  | 	got := i.FetchAllClients(ctx) | ||||||
|  | 	want := []interface{}{fakeA, fakeB} | ||||||
|  | 	if !cmp.Equal(got, want) { | ||||||
|  | 		t.Errorf("FetchAllClients() = %v, wanted %v", got, want) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -36,6 +36,13 @@ type Interface interface { | ||||||
| 	// GetClients fetches all of the registered client injectors.
 | 	// GetClients fetches all of the registered client injectors.
 | ||||||
| 	GetClients() []ClientInjector | 	GetClients() []ClientInjector | ||||||
| 
 | 
 | ||||||
|  | 	// RegisterClientFetcher registers a new callback that fetches a client from
 | ||||||
|  | 	// a given context.
 | ||||||
|  | 	RegisterClientFetcher(ClientFetcher) | ||||||
|  | 
 | ||||||
|  | 	// FetchAllClients returns all known clients from the given context.
 | ||||||
|  | 	FetchAllClients(context.Context) []interface{} | ||||||
|  | 
 | ||||||
| 	// RegisterInformerFactory registers a new injector callback for associating
 | 	// RegisterInformerFactory registers a new injector callback for associating
 | ||||||
| 	// a new informer factory with a context.
 | 	// a new informer factory with a context.
 | ||||||
| 	RegisterInformerFactory(InformerFactoryInjector) | 	RegisterInformerFactory(InformerFactoryInjector) | ||||||
|  | @ -92,6 +99,7 @@ type impl struct { | ||||||
| 	m sync.RWMutex | 	m sync.RWMutex | ||||||
| 
 | 
 | ||||||
| 	clients           []ClientInjector | 	clients           []ClientInjector | ||||||
|  | 	clientFetchers    []ClientFetcher | ||||||
| 	factories         []InformerFactoryInjector | 	factories         []InformerFactoryInjector | ||||||
| 	informers         []InformerInjector | 	informers         []InformerInjector | ||||||
| 	filteredInformers []FilteredInformersInjector | 	filteredInformers []FilteredInformersInjector | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue