mirror of
https://github.com/status-im/consul.git
synced 2025-01-10 22:06:20 +00:00
326c0ecfbe
* Implement In-Process gRPC for use by controller caching/indexing This replaces the pipe base listener implementation we were previously using. The new style CAN avoid cloning resources which our controller caching/indexing is taking advantage of to not duplicate resource objects in memory. To maintain safety for controllers and for them to be able to modify data they get back from the cache and the resource service, the client they are presented in their runtime will be wrapped with an autogenerated client which clones request and response messages as they pass through the client. Another sizable change in this PR is to consolidate how server specific gRPC services get registered and managed. Before this was in a bunch of different methods and it was difficult to track down how gRPC services were registered. Now its all in one place. * Fix race in tests * Ensure the resource service is registered to the multiplexed handler for forwarding from client agents * Expose peer streaming on the internal handler
64 lines
2.2 KiB
Go
64 lines
2.2 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package controller
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/hashicorp/consul/internal/controller/cache"
|
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
|
"github.com/hashicorp/go-hclog"
|
|
)
|
|
|
|
// TestController is most useful when writing unit tests for a controller where
|
|
// individual Reconcile calls need to be made instead of having a Manager
|
|
// execute the controller in response to watch events.
|
|
//
|
|
// TODO(controller-testing) Ideally this would live within the controllertest
|
|
// package. However it makes light use of unexported fields on the Controller
|
|
// and therefore cannot live in another package without more refactorings
|
|
// to have the Controller include a config struct of sorts defined in an
|
|
// internal package with exported fields. For now this seems fine.
|
|
type TestController struct {
|
|
c *Controller
|
|
cache cache.Cache
|
|
client pbresource.ResourceServiceClient
|
|
logger hclog.Logger
|
|
}
|
|
|
|
// NewTestController will create a new TestController from the provided Controller
|
|
// and ResourceServiceClient. The test controller will build the controllers
|
|
// cache with the configured indexes and will maintain the cached state in response
|
|
// to Write, WriteStatus and Delete calls made on the wrapped ResourceServiceClient.
|
|
// Call the Runtime() method to get at the wrapped client.
|
|
func NewTestController(ctl *Controller, client pbresource.ResourceServiceClient) *TestController {
|
|
ctlCache := ctl.buildCache()
|
|
return &TestController{
|
|
c: ctl,
|
|
cache: ctlCache,
|
|
client: cache.NewCachedClient(ctlCache, client),
|
|
logger: ctl.buildLogger(hclog.NewNullLogger()),
|
|
}
|
|
}
|
|
|
|
// Reconcile invokes the controllers configured reconciler with the cache enabled Runtime
|
|
func (tc *TestController) Reconcile(ctx context.Context, req Request) error {
|
|
return tc.c.reconciler.Reconcile(ctx, tc.Runtime(), req)
|
|
}
|
|
|
|
// Reconciler returns the controllers configured reconciler
|
|
func (tc *TestController) Reconciler() Reconciler {
|
|
return tc.c.reconciler
|
|
}
|
|
|
|
// Runtime returns the Runtime that should be used for calls to reconcile or to perform
|
|
// operations that would also affect the managed cache.
|
|
func (tc *TestController) Runtime() Runtime {
|
|
return Runtime{
|
|
Client: tc.client,
|
|
Logger: tc.logger,
|
|
Cache: tc.cache,
|
|
}
|
|
}
|