c_cloud.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package config
  2. import (
  3. "cicv-data-closedloop/common/config/c_log"
  4. "cicv-data-closedloop/common/util"
  5. "gopkg.in/yaml.v3"
  6. "os"
  7. "strings"
  8. "sync"
  9. "time"
  10. )
  11. type MonitorStruct struct {
  12. Url string `yaml:"url"`
  13. }
  14. type platform struct {
  15. UrlDeviceAuth string `yaml:"url-device-auth"`
  16. UrlTaskPoll string `yaml:"url-task-poll"`
  17. UrlTask string `yaml:"url-task"`
  18. }
  19. type rosbagStruct struct {
  20. Path string `yaml:"path"`
  21. Envs []string `yaml:"envs"`
  22. }
  23. type hostStruct struct {
  24. Name string `yaml:"name"`
  25. Ip string `yaml:"ip"`
  26. Topics []string `yaml:"topics"`
  27. Rosbag rosbagStruct `yaml:"rosbag"`
  28. }
  29. type ros struct {
  30. MasterAddress string `yaml:"master-address"`
  31. Nodes []string `yaml:"nodes"`
  32. }
  33. type disk struct {
  34. Name string `yaml:"name"`
  35. Used uint64 `yaml:"used"`
  36. }
  37. type trigger struct {
  38. Label string `yaml:"label"`
  39. Topics []string `yaml:"topics"`
  40. }
  41. type cloudConfig struct {
  42. FullCollect bool `yaml:"full-collect"`
  43. ConfigRefreshInterval int `yaml:"config-refresh-interval"` // 配置刷新时间间隔
  44. BagNumber int `yaml:"bag-number"`
  45. TimeWindowSendGap int `yaml:"time-window-send-gap"` // 主节点向从节点发送窗口的最小时间间隔
  46. MapBagPath string `yaml:"map-bag-path"`
  47. TfstaticBagPath string `yaml:"tfstatic-bag-path"`
  48. CostmapBagPath string `yaml:"costmap-bag-path"`
  49. BagDataDir string `yaml:"bag-data-dir"`
  50. BagCopyDir string `yaml:"bag-copy-dir"`
  51. TriggersDir string `yaml:"triggers-dir"`
  52. RpcPort string `yaml:"rpc-port"`
  53. Triggers []trigger `yaml:"triggers"`
  54. Hosts []hostStruct `yaml:"hosts"`
  55. Ros ros `yaml:"ros"`
  56. Platform platform `yaml:"platform"`
  57. Disk disk `yaml:"disk"`
  58. Monitor MonitorStruct `yaml:"monitor"`
  59. }
  60. var (
  61. CloudConfig cloudConfig
  62. CloudConfigMutex sync.RWMutex
  63. )
  64. // InitCloudConfig 初始化业务配置
  65. func InitCloudConfig() {
  66. // history20240401:朴津机器人额外加一个获取sn码
  67. var snCode string
  68. for {
  69. time.Sleep(time.Duration(2) * time.Second)
  70. var command []string
  71. command = append(command, "get")
  72. command = append(command, "sn")
  73. _, snOutput, err := util.ExecuteSync(LocalConfig.RosparamPath, command...)
  74. if err != nil {
  75. c_log.GlobalLogger.Error("执行获取sn码命令", command, "出错:", err)
  76. continue
  77. }
  78. c_log.GlobalLogger.Info("执行获取sn码命令", command, "成功,结果为:", snOutput)
  79. snCode = strings.Replace(strings.Replace(snOutput, " ", "", -1), "\n", "", -1)
  80. LocalConfig.SecretKey = snCode
  81. LocalConfig.EquipmentNo = "pjibot-" + snCode
  82. break
  83. }
  84. c_log.GlobalLogger.Info("本地机器人sn码为:", snCode)
  85. c_log.GlobalLogger.Info("初始化OSS配置文件 - 开始。")
  86. // 获取文件的目录
  87. _ = util.CreateParentDir(LocalConfig.CloudConfigLocalPath)
  88. // 3 ------- 获取 yaml 字符串 -------
  89. cloudConfigObjectKey := LocalConfig.OssBasePrefix + LocalConfig.EquipmentNo + "/" + LocalConfig.CloudConfigFilename
  90. // 判断文件是否存在。如果不存在则使用默认的
  91. isExist, err := OssBucket.IsObjectExist(cloudConfigObjectKey)
  92. if err != nil {
  93. c_log.GlobalLogger.Errorf("判断配置文件是否存在失败,错误信息为:%v", err)
  94. }
  95. if isExist {
  96. c_log.GlobalLogger.Info("使用机器人自定义配置文件:", cloudConfigObjectKey)
  97. } else {
  98. cloudConfigObjectKey = LocalConfig.OssBasePrefix + LocalConfig.CloudConfigFilename
  99. c_log.GlobalLogger.Info("使用机器人默认配置文件:", cloudConfigObjectKey)
  100. }
  101. for {
  102. time.Sleep(time.Duration(2) * time.Second)
  103. OssMutex.Lock()
  104. err := OssBucket.GetObjectToFile(cloudConfigObjectKey, LocalConfig.CloudConfigLocalPath)
  105. OssMutex.Unlock()
  106. if err != nil {
  107. c_log.GlobalLogger.Error("下载 OSS 上的配置文件 "+cloudConfigObjectKey+" 失败,请尽快在 OSS 上传配置文件。", err)
  108. continue
  109. }
  110. break
  111. }
  112. content, err := os.ReadFile(LocalConfig.CloudConfigLocalPath)
  113. if err != nil {
  114. c_log.GlobalLogger.Error("程序崩溃,配置文件 ", LocalConfig.CloudConfigLocalPath, " 读取失败:", err)
  115. os.Exit(-1)
  116. }
  117. // 4 ------- 解析YAML内容 -------
  118. var newCloudConfig cloudConfig
  119. err = yaml.Unmarshal(content, &newCloudConfig)
  120. if err != nil {
  121. c_log.GlobalLogger.Error("程序崩溃,配置文件 ", LocalConfig.CloudConfigLocalPath, " 解析失败:", err)
  122. os.Exit(-1)
  123. }
  124. // 5 ------- 校验 yaml -------
  125. if checkCloudConfig(newCloudConfig) {
  126. CloudConfigMutex.RLock()
  127. CloudConfig = newCloudConfig
  128. CloudConfigMutex.RUnlock()
  129. } else {
  130. c_log.GlobalLogger.Error("程序崩溃,配置文件格式错误:", newCloudConfig)
  131. os.Exit(-1)
  132. }
  133. c_log.GlobalLogger.Info("初始化OSS配置文件 - 成功。")
  134. util.CreateDir(CloudConfig.BagDataDir)
  135. util.CreateDir(CloudConfig.BagCopyDir)
  136. }
  137. // refreshCloudConfig 更新业务配置
  138. func refreshCloudConfig() {
  139. // 获取文件的目录
  140. _ = util.CreateParentDir(LocalConfig.CloudConfigLocalPath)
  141. // 3 ------- 获取 yaml 字符串 -------
  142. var content []byte
  143. cloudConfigObjectKey := LocalConfig.OssBasePrefix + LocalConfig.EquipmentNo + "/" + LocalConfig.CloudConfigFilename
  144. OssMutex.Lock()
  145. err := OssBucket.GetObjectToFile(cloudConfigObjectKey, LocalConfig.CloudConfigLocalPath)
  146. OssMutex.Unlock()
  147. if err != nil {
  148. c_log.GlobalLogger.Error("下载oss上的配置文件"+cloudConfigObjectKey+"失败。", err)
  149. //os.Exit(-1)
  150. }
  151. content, err = os.ReadFile(LocalConfig.CloudConfigLocalPath)
  152. if err != nil {
  153. c_log.GlobalLogger.Error("配置文件 ", LocalConfig.CloudConfigLocalPath, " 读取失败:", err)
  154. os.Exit(-1)
  155. }
  156. // 4 ------- 解析YAML内容 -------
  157. var newCloudConfig cloudConfig
  158. err = yaml.Unmarshal(content, &newCloudConfig)
  159. if err != nil {
  160. c_log.GlobalLogger.Error("配置文件 ", LocalConfig.CloudConfigLocalPath, " 解析失败:", err)
  161. os.Exit(-1)
  162. }
  163. // 5 ------- 校验 yaml -------
  164. if checkCloudConfig(newCloudConfig) {
  165. CloudConfigMutex.RLock()
  166. CloudConfig = newCloudConfig
  167. CloudConfigMutex.RUnlock()
  168. } else {
  169. c_log.GlobalLogger.Error("配置文件格式错误:", newCloudConfig)
  170. os.Exit(-1)
  171. }
  172. util.CreateDir(CloudConfig.BagDataDir)
  173. util.CreateDir(CloudConfig.BagCopyDir)
  174. }
  175. // RefreshCloudConfig 轮询oss上的配置文件更新到本地
  176. func RefreshCloudConfig() {
  177. for {
  178. time.Sleep(time.Duration(CloudConfig.ConfigRefreshInterval) * time.Second)
  179. refreshCloudConfig()
  180. }
  181. }
  182. // CheckConfig 校验 cfg.yaml 文件
  183. func checkCloudConfig(check cloudConfig) bool {
  184. if len(check.Hosts) != 1 {
  185. c_log.GlobalLogger.Error("cloud-config.yaml中配置的hosts必须为1。")
  186. os.Exit(-1)
  187. }
  188. return true
  189. }