2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2021-06-01 22:31:52 +00:00
|
|
|
package resolver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"google.golang.org/grpc/resolver"
|
|
|
|
)
|
|
|
|
|
|
|
|
// registry of ServerResolverBuilder. This type exists because grpc requires that
|
|
|
|
// resolvers are registered globally before any requests are made. This is
|
|
|
|
// incompatible with our resolver implementation and testing strategy, which
|
|
|
|
// requires a different Resolver for each test.
|
|
|
|
type registry struct {
|
|
|
|
lock sync.RWMutex
|
|
|
|
byAuthority map[string]*ServerResolverBuilder
|
|
|
|
}
|
|
|
|
|
2022-03-23 16:10:03 +00:00
|
|
|
func (r *registry) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
|
2021-06-01 22:31:52 +00:00
|
|
|
r.lock.RLock()
|
|
|
|
defer r.lock.RUnlock()
|
2022-11-07 16:34:30 +00:00
|
|
|
//nolint:staticcheck
|
2023-08-09 17:04:32 +00:00
|
|
|
res, ok := r.byAuthority[target.URL.Host]
|
2021-06-01 22:31:52 +00:00
|
|
|
if !ok {
|
2022-11-07 16:34:30 +00:00
|
|
|
//nolint:staticcheck
|
2023-08-09 17:04:32 +00:00
|
|
|
return nil, fmt.Errorf("no resolver registered for %v", target.URL.Host)
|
2021-06-01 22:31:52 +00:00
|
|
|
}
|
|
|
|
return res.Build(target, cc, opts)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *registry) Scheme() string {
|
|
|
|
return "consul"
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ resolver.Builder = (*registry)(nil)
|
|
|
|
|
|
|
|
var reg = ®istry{byAuthority: make(map[string]*ServerResolverBuilder)}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
resolver.Register(reg)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register a ServerResolverBuilder with the global registry.
|
|
|
|
func Register(res *ServerResolverBuilder) {
|
|
|
|
reg.lock.Lock()
|
|
|
|
defer reg.lock.Unlock()
|
|
|
|
reg.byAuthority[res.Authority()] = res
|
|
|
|
}
|
|
|
|
|
|
|
|
// Deregister the ServerResolverBuilder associated with the authority. Only used
|
|
|
|
// for testing.
|
|
|
|
func Deregister(authority string) {
|
|
|
|
reg.lock.Lock()
|
|
|
|
defer reg.lock.Unlock()
|
|
|
|
delete(reg.byAuthority, authority)
|
|
|
|
}
|