common/requester/apiserver.go (71 lines of code) (raw):
package requester
import (
"sync"
"github.com/aliyun/aliyun_assist_client/thirdparty/sirupsen/logrus"
)
var (
_apiServerProviders []APIServerProvider
_selectedAPIServerProvider APIServerProvider
_apiServerProviderLock sync.RWMutex
)
func SetAPIServerProviders(providers []APIServerProvider) {
_apiServerProviderLock.Lock()
defer _apiServerProviderLock.Unlock()
_apiServerProviders = providers
_selectedAPIServerProvider = nil
}
func GetServerDomain(logger logrus.FieldLogger) (string, error) {
domain, err := func () (string, error) {
_apiServerProviderLock.RLock()
defer _apiServerProviderLock.RUnlock()
if _selectedAPIServerProvider == nil {
return "", ErrNotProvided
}
domain, err := _selectedAPIServerProvider.ServerDomain(logger)
if err != nil {
logger.WithError(err).Warningf("Previously selected API server provider %s does not work for server domain", _selectedAPIServerProvider.Name())
return "", err
}
return domain, nil
}()
if err == nil {
return domain, nil
}
_apiServerProviderLock.Lock()
defer _apiServerProviderLock.Unlock()
if _selectedAPIServerProvider != nil {
domain, err := _selectedAPIServerProvider.ServerDomain(logger)
if err == nil {
return domain, nil
}
logger.WithError(err).Warningf("Newly selected API server provider %s does not work for server domain yet", _selectedAPIServerProvider.Name())
}
return unsafeSelectProviderForServerDomain(logger)
}
// GetExtraHTTPHeaders would provide effective extra HTTP headers only when API
// server is determined
func GetExtraHTTPHeaders(logger logrus.FieldLogger) (map[string]string, error) {
_apiServerProviderLock.RLock()
defer _apiServerProviderLock.RUnlock()
if _selectedAPIServerProvider == nil {
return nil, ErrNotProvided
}
extraHeaders, err := _selectedAPIServerProvider.ExtraHTTPHeaders(logger)
if err != nil {
logger.WithError(err).Warningf("Previously selected API server provider %s does not work for extra HTTP headers", _selectedAPIServerProvider.Name())
}
return extraHeaders, err
}
// unsafeSelectProviderForServerDomain MUST be called with protection under
// correct locking
func unsafeSelectProviderForServerDomain(logger logrus.FieldLogger) (string, error) {
logger.Infoln("Start selection procedure for API server provider")
for _, provider := range _apiServerProviders {
domain, err := provider.ServerDomain(logger)
if err != nil {
logger.WithError(err).Errorf("Failed to get API server domain from %s", provider.Name())
continue
}
logger.Infof("Selected %s for API server domain and extra HTTP headers needed", provider.Name())
_selectedAPIServerProvider = provider
return domain, nil
}
logger.Error("No API server provider is selected")
return "", ErrNotProvided
}