/vendor/github.com/ServiceComb/go-chassis/config-center/config_center.go

https://bitbucket.org/simpleelegant/godi · Go · 227 lines · 176 code · 41 blank · 10 comment · 43 complexity · 309ca7ddda393c89d30a995bdb6bdd36 MD5 · raw file

  1. package configcenter
  2. import (
  3. "crypto/tls"
  4. "errors"
  5. "fmt"
  6. "net/url"
  7. "regexp"
  8. "strings"
  9. "github.com/ServiceComb/go-archaius"
  10. // go-archaius package is imported for to initialize the config-center configurations
  11. _ "github.com/ServiceComb/go-archaius"
  12. "github.com/ServiceComb/go-archaius/core"
  13. "github.com/ServiceComb/go-archaius/sources/configcenter-source"
  14. "github.com/ServiceComb/go-cc-client"
  15. "github.com/ServiceComb/go-cc-client/member-discovery"
  16. "github.com/ServiceComb/go-chassis/core/common"
  17. "github.com/ServiceComb/go-chassis/core/config"
  18. "github.com/ServiceComb/go-chassis/core/lager"
  19. chassisTLS "github.com/ServiceComb/go-chassis/core/tls"
  20. "github.com/ServiceComb/go-chassis/core/archaius"
  21. )
  22. const (
  23. //Name is a variable of type string
  24. Name = "configcenter"
  25. maxValue = 256
  26. emptyDimeInfo = "Issue with regular expression or exceeded the max length"
  27. )
  28. // InitConfigCenter initialize config center
  29. func InitConfigCenter() error {
  30. if !isConfigCenter() {
  31. return nil
  32. }
  33. var enableSSL bool
  34. tlsConfig, tlsError := getTLSForClient()
  35. if tlsError != nil {
  36. lager.Logger.Errorf(tlsError, "Get %s.%s TLS config failed, err:", Name, common.Consumer)
  37. return tlsError
  38. }
  39. /*This condition added because member discovery can have multiple ip's with IsHTTPS
  40. having both true and false value.*/
  41. if tlsConfig != nil {
  42. enableSSL = true
  43. }
  44. dimensionInfo := getUniqueIDForDimInfo()
  45. if dimensionInfo == "" {
  46. err := errors.New("empty dimension info: " + emptyDimeInfo)
  47. lager.Logger.Error("empty dimension info", err)
  48. return err
  49. }
  50. if config.GlobalDefinition.Cse.Config.Client.TenantName == "" {
  51. config.GlobalDefinition.Cse.Config.Client.TenantName = common.DefaultTenant
  52. }
  53. if config.GlobalDefinition.Cse.Config.Client.RefreshInterval == 0 {
  54. config.GlobalDefinition.Cse.Config.Client.RefreshInterval = 30
  55. }
  56. err := initConfigCenter(config.GlobalDefinition.Cse.Config.Client.ServerURI,
  57. dimensionInfo, config.GlobalDefinition.Cse.Config.Client.TenantName,
  58. enableSSL, tlsConfig)
  59. if err != nil {
  60. lager.Logger.Error("failed to init config center", err)
  61. return err
  62. }
  63. lager.Logger.Warnf(nil, "config center init success")
  64. return nil
  65. }
  66. func isConfigCenter() bool {
  67. if config.GlobalDefinition.Cse.Config.Client.ServerURI == "" {
  68. lager.Logger.Warnf(nil, "empty config center endpoint, please provide the config center endpoint")
  69. return false
  70. }
  71. return true
  72. }
  73. func getTLSForClient() (*tls.Config, error) {
  74. base := config.GlobalDefinition.Cse.Config.Client.ServerURI
  75. if !strings.Contains(base, "://") {
  76. return nil, nil
  77. }
  78. ccURL, err := url.Parse(base)
  79. if err != nil {
  80. lager.Logger.Error("Error occurred while parsing config center Server Uri", err)
  81. return nil, err
  82. }
  83. if ccURL.Scheme == "http" {
  84. return nil, nil
  85. }
  86. sslTag := Name + "." + common.Consumer
  87. tlsConfig, sslConfig, err := chassisTLS.GetTLSConfigByService(Name, "", common.Consumer)
  88. if err != nil {
  89. if chassisTLS.IsSSLConfigNotExist(err) {
  90. return nil, fmt.Errorf("%s TLS mode, but no ssl config", sslTag)
  91. }
  92. return nil, err
  93. }
  94. lager.Logger.Warnf(nil, "%s TLS mode, verify peer: %t, cipher plugin: %s.",
  95. sslTag, sslConfig.VerifyPeer, sslConfig.CipherPlugin)
  96. return tlsConfig, nil
  97. }
  98. func getUniqueIDForDimInfo() string {
  99. serviceName := config.MicroserviceDefinition.ServiceDescription.Name
  100. version := config.MicroserviceDefinition.ServiceDescription.Version
  101. appName := config.MicroserviceDefinition.AppID
  102. if appName == "" {
  103. appName = config.GlobalDefinition.AppID
  104. }
  105. if appName != "" {
  106. serviceName = serviceName + "@" + appName
  107. }
  108. if version != "" {
  109. serviceName = serviceName + "#" + version
  110. }
  111. if len(serviceName) > maxValue {
  112. lager.Logger.Errorf(nil, "exceeded max value %d for dimensionInfo %s with length %d", maxValue, serviceName,
  113. len(serviceName))
  114. return ""
  115. }
  116. dimeExp := `\A([^\$\%\&\+\(/)\[\]\" "\"])*\z`
  117. dimRegexVar, err := regexp.Compile(dimeExp)
  118. if err != nil {
  119. lager.Logger.Error("not a valid regular expression", err)
  120. return ""
  121. }
  122. if !dimRegexVar.Match([]byte(serviceName)) {
  123. lager.Logger.Errorf(nil, "invalid value for dimension info, doesnot setisfy the regular expression for dimInfo:%s",
  124. serviceName)
  125. return ""
  126. }
  127. return serviceName
  128. }
  129. func initConfigCenter(ccEndpoint, dimensionInfo, tenantName string, enableSSL bool, tlsConfig *tls.Config) error {
  130. var err error
  131. if (config.GlobalDefinition.Cse.Config.Client.RefreshMode != 0) &&
  132. (config.GlobalDefinition.Cse.Config.Client.RefreshMode != 1) {
  133. err := errors.New(client.RefreshModeError)
  134. lager.Logger.Error(client.RefreshModeError, err)
  135. return err
  136. }
  137. memDiscovery := memberdiscovery.NewConfiCenterInit(tlsConfig, tenantName, enableSSL)
  138. configCenters := strings.Split(ccEndpoint, ",")
  139. cCenters := make([]string, 0)
  140. for _, value := range configCenters {
  141. value = strings.Replace(value, " ", "", -1)
  142. cCenters = append(cCenters, value)
  143. }
  144. memDiscovery.ConfigurationInit(cCenters)
  145. if enbledAutoDiscovery() {
  146. refreshError := memDiscovery.RefreshMembers()
  147. if refreshError != nil {
  148. lager.Logger.Error(client.ConfigServerMemRefreshError, refreshError)
  149. return errors.New(client.ConfigServerMemRefreshError)
  150. }
  151. }
  152. configCenterSource := configcentersource.NewConfigCenterSource(memDiscovery,
  153. dimensionInfo, tlsConfig, tenantName, config.GlobalDefinition.Cse.Config.Client.RefreshMode,
  154. config.GlobalDefinition.Cse.Config.Client.RefreshInterval, enableSSL)
  155. err = archaius.DefaultConf.ConfigFactory.AddSource(configCenterSource)
  156. if err != nil {
  157. lager.Logger.Error("failed to do add source operation!!", err)
  158. return err
  159. }
  160. // Get the whole configuration
  161. //config := factory.GetConfigurations()
  162. //logger.Info("init config center %+v", config)
  163. eventHandler := EventListener{
  164. Name: "EventHandler",
  165. Factory: archaius.DefaultConf.ConfigFactory,
  166. }
  167. memberdiscovery.MemberDiscoveryService = memDiscovery
  168. archaius.DefaultConf.ConfigFactory.RegisterListener(eventHandler, "a*")
  169. return nil
  170. }
  171. //EventListener is a struct
  172. type EventListener struct {
  173. Name string
  174. Factory goarchaius.ConfigurationFactory
  175. }
  176. //Event is a method
  177. func (e EventListener) Event(event *core.Event) {
  178. value := e.Factory.GetConfigurationByKey(event.Key)
  179. lager.Logger.Infof("config value %s | %s", event.Key, value)
  180. }
  181. func enbledAutoDiscovery() bool {
  182. if config.GlobalDefinition.Cse.Config.Client.Autodiscovery {
  183. return true
  184. }
  185. return false
  186. }