sequence
This paper focuses on DiscoveryService of dubo-go-proxy
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)
}
Copy the code
Go defines four DiscoveryService interfaces. They are APIDiscoveryService, ListenerDiscoveryService, RouteDiscoveryService, ClusterDiscoveryService, and 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, } }Copy the code
DiscoveryRequest defines the Body property
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{}
Copy the code
DiscoveryResponse defines the Success and Data attributes
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")
}
Copy the code
LocalMemoryAPIDiscoveryService defines the router attribute; It implements AddAPI and GetAPI methods of APIDiscoveryService, both of which are delegated to the 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)
}
Copy the code
InitAPIsFromConfig loads the plugin’s corresponding filter method according to config.APIConfig configuration
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 }Copy the code
LoadAPIFromResource is used to load the API for the specified resources, which borroves 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 }Copy the code
LoadAPIFromMethods Iterate over methods to create fr.API and execute localsrv.addAPI (API)
summary
Go defines four DiscoveryService interfaces. APIDiscoveryService, ListenerDiscoveryService, RouteDiscoveryService, ClusterDiscoveryService, and EndpointDiscoveryService respectively. LocalMemoryAPIDiscoveryService defines the router attribute; It implements AddAPI and GetAPI methods of APIDiscoveryService, both of which are delegated to the Router.
doc
- dubbo-go-proxy