序
本文主要研究一下dubbo-go-proxy的DiscoveryService
DiscoveryService
dubbo-go-proxy/pkg/service/discovery_service.go
// APIDiscoveryService api discovery service interface
type APIDiscoveryService interface {
AddAPI(router.API) error
GetAPI(string, config.HTTPVerb) (router.API, error)
}
// DiscoveryService is come from envoy, it can used for admin
// ListenerDiscoveryService
type ListenerDiscoveryService interface {
AddListeners(request DiscoveryRequest) (DiscoveryResponse, error)
GetListeners(request DiscoveryRequest) (DiscoveryResponse, error)
}
// RouteDiscoveryService
type RouteDiscoveryService interface {
AddRoutes(r DiscoveryRequest) (DiscoveryResponse, error)
GetRoutes(r DiscoveryRequest) (DiscoveryResponse, error)
}
// ClusterDiscoveryService
type ClusterDiscoveryService interface {
AddClusters(r DiscoveryRequest) (DiscoveryResponse, error)
GetClusters(r DiscoveryRequest) (DiscoveryResponse, error)
}
// EndpointDiscoveryService
type EndpointDiscoveryService interface {
AddEndpoints(r DiscoveryRequest) (DiscoveryResponse, error)
GetEndpoints(r DiscoveryRequest) (DiscoveryResponse, error)
}
discovery_service.go定义了四种DiscoveryService接口,分别是APIDiscoveryService、ListenerDiscoveryService、RouteDiscoveryService、ClusterDiscoveryService、EndpointDiscoveryService
DiscoveryRequest
dubbo-go-proxy/pkg/service/discovery_service.go
// DiscoveryRequest a request for discovery
type DiscoveryRequest struct {
Body []byte
}
// NewDiscoveryRequest return a DiscoveryRequest with body
func NewDiscoveryRequest(b []byte) *DiscoveryRequest {
return &DiscoveryRequest{
Body: b,
}
}
DiscoveryRequest定义了Body属性
DiscoveryResponse
dubbo-go-proxy/pkg/service/discovery_service.go
// DiscoveryResponse a response for discovery
type DiscoveryResponse struct {
Success bool
Data interface{}
}
// NewDiscoveryResponseWithSuccess return a DiscoveryResponse with success
func NewDiscoveryResponseWithSuccess(b bool) *DiscoveryResponse {
return &DiscoveryResponse{
Success: b,
}
}
// NewDiscoveryResponse return a DiscoveryResponse with Data and success true
func NewDiscoveryResponse(d interface{}) *DiscoveryResponse {
return &DiscoveryResponse{
Success: true,
Data: d,
}
}
var EmptyDiscoveryResponse = &DiscoveryResponse{}
DiscoveryResponse定义了Success及Data属性
LocalMemoryAPIDiscoveryService
dubbo-go-proxy/pkg/service/api/discovery_service.go
// Init set api discovery local_memory service.
func Init() {
extension.SetAPIDiscoveryService(constant.LocalMemoryApiDiscoveryService, NewLocalMemoryAPIDiscoveryService())
}
// LocalMemoryAPIDiscoveryService is the local cached API discovery service
type LocalMemoryAPIDiscoveryService struct {
router *router.Route
}
// NewLocalMemoryAPIDiscoveryService creates a new LocalMemoryApiDiscoveryService instance
func NewLocalMemoryAPIDiscoveryService() *LocalMemoryAPIDiscoveryService {
return &LocalMemoryAPIDiscoveryService{
router: router.NewRoute(),
}
}
// AddAPI adds a method to the router tree
func (ads *LocalMemoryAPIDiscoveryService) AddAPI(api fr.API) error {
return ads.router.PutAPI(api)
}
// GetAPI returns the method to the caller
func (ads *LocalMemoryAPIDiscoveryService) GetAPI(url string, httpVerb config.HTTPVerb) (fr.API, error) {
if api, ok := ads.router.FindAPI(url, httpVerb); ok {
return *api, nil
}
return fr.API{}, errors.New("not found")
}
LocalMemoryAPIDiscoveryService定义了router属性;它实现了APIDiscoveryService的AddAPI及GetAPI方法,均是代理给了router
InitAPIsFromConfig
dubbo-go-proxy/pkg/service/api/discovery_service.go
// InitAPIsFromConfig inits the router from API config and to local cache
func InitAPIsFromConfig(apiConfig config.APIConfig) error {
localAPIDiscSrv := extension.GetMustAPIDiscoveryService(constant.LocalMemoryApiDiscoveryService)
if len(apiConfig.Resources) == 0 {
return nil
}
// load pluginsGroup
plugins.InitPluginsGroup(apiConfig.PluginsGroup, apiConfig.PluginFilePath)
// init plugins from resource
plugins.InitAPIURLWithFilterChain(apiConfig.Resources)
return loadAPIFromResource("", apiConfig.Resources, nil, localAPIDiscSrv)
}
InitAPIsFromConfig根据config.APIConfig的配置来加载plugin对应的filter方法
loadAPIFromResource
dubbo-go-proxy/pkg/service/api/discovery_service.go
func loadAPIFromResource(parrentPath string, resources []config.Resource, parentHeaders map[string]string, localSrv service.APIDiscoveryService) error {
errStack := []string{}
if len(resources) == 0 {
return nil
}
groupPath := parrentPath
if parrentPath == constant.PathSlash {
groupPath = ""
}
fullHeaders := parentHeaders
if fullHeaders == nil {
fullHeaders = make(map[string]string, 9)
}
for _, resource := range resources {
fullPath := groupPath + resource.Path
if !strings.HasPrefix(resource.Path, constant.PathSlash) {
errStack = append(errStack, fmt.Sprintf("Path %s in %s doesn't start with /", resource.Path, parrentPath))
continue
}
for headerName, headerValue := range resource.Headers {
fullHeaders[headerName] = headerValue
}
if len(resource.Resources) > 0 {
if err := loadAPIFromResource(resource.Path, resource.Resources, fullHeaders, localSrv); err != nil {
errStack = append(errStack, err.Error())
}
}
if err := loadAPIFromMethods(fullPath, resource.Methods, fullHeaders, localSrv); err != nil {
errStack = append(errStack, err.Error())
}
}
if len(errStack) > 0 {
return errors.New(strings.Join(errStack, "; "))
}
return nil
}
loadAPIFromResource用于加载指定resources的api,它借用了loadAPIFromMethods
loadAPIFromMethods
dubbo-go-proxy/pkg/service/api/discovery_service.go
func loadAPIFromMethods(fullPath string, methods []config.Method, headers map[string]string, localSrv service.APIDiscoveryService) error {
errStack := []string{}
for _, method := range methods {
api := fr.API{
URLPattern: fullPath,
Method: method,
Headers: headers,
}
if err := localSrv.AddAPI(api); err != nil {
errStack = append(errStack, fmt.Sprintf("Path: %s, Method: %s, error: %s", fullPath, method.HTTPVerb, err.Error()))
}
}
if len(errStack) > 0 {
return errors.New(strings.Join(errStack, "\n"))
}
return nil
}
loadAPIFromMethods遍历methods创建fr.API,并执行localSrv.AddAPI(api)
小结
discovery_service.go定义了四种DiscoveryService接口,分别是APIDiscoveryService、ListenerDiscoveryService、RouteDiscoveryService、ClusterDiscoveryService、EndpointDiscoveryService;LocalMemoryAPIDiscoveryService定义了router属性;它实现了APIDiscoveryService的AddAPI及GetAPI方法,均是代理给了router。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。