github.com/micro/go-micro/examples@v0.0.0-20210105173217-bf4ab679e18b/config/grpc/srv/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "crypto/md5" 6 "fmt" 7 "net" 8 "strings" 9 "sync" 10 "time" 11 12 "github.com/micro/go-micro/v2/config" 13 "github.com/micro/go-micro/v2/config/source/file" 14 "github.com/micro/go-micro/v2/util/log" 15 proto "github.com/micro/go-plugins/config/source/grpc/v2/proto" 16 grpc "google.golang.org/grpc" 17 ) 18 19 var ( 20 mux sync.RWMutex 21 configMaps = make(map[string]*proto.ChangeSet) 22 apps = []string{"micro", "extra"} 23 ) 24 25 type Service struct{} 26 27 func main() { 28 // load config files 29 err := loadConfigFile() 30 if err != nil { 31 log.Fatal(err) 32 } 33 34 // new service 35 service := grpc.NewServer() 36 proto.RegisterSourceServer(service, new(Service)) 37 ts, err := net.Listen("tcp", ":8600") 38 if err != nil { 39 log.Fatal(err) 40 } 41 42 log.Logf("configServer started") 43 err = service.Serve(ts) 44 if err != nil { 45 log.Fatal(err) 46 } 47 } 48 49 func (s Service) Read(ctx context.Context, req *proto.ReadRequest) (rsp *proto.ReadResponse, err error) { 50 appName := parsePath(req.Path) 51 switch appName { 52 case "micro", "extra": 53 rsp = &proto.ReadResponse{ 54 ChangeSet: getConfig(appName), 55 } 56 return 57 default: 58 err = fmt.Errorf("[Read] the first path is invalid") 59 return 60 } 61 62 return 63 } 64 65 func (s Service) Watch(req *proto.WatchRequest, server proto.Source_WatchServer) (err error) { 66 appName := parsePath(req.Path) 67 rsp := &proto.WatchResponse{ 68 ChangeSet: getConfig(appName), 69 } 70 if err = server.Send(rsp); err != nil { 71 log.Logf("[Watch] watch files error,%s", err) 72 return err 73 } 74 75 return 76 } 77 78 func loadConfigFile() (err error) { 79 for _, app := range apps { 80 if err := config.Load(file.NewSource( 81 file.WithPath("./conf/" + app + ".yml"), 82 )); err != nil { 83 log.Fatalf("[loadConfigFile] load files error,%s", err) 84 return err 85 } 86 } 87 88 // watch changes 89 watcher, err := config.Watch() 90 if err != nil { 91 log.Fatalf("[loadConfigFile] start watching files error,%s", err) 92 return err 93 } 94 95 go func() { 96 for { 97 v, err := watcher.Next() 98 if err != nil { 99 log.Fatalf("[loadConfigFile] watch files error,%s", err) 100 return 101 } 102 103 log.Logf("[loadConfigFile] file change, %s", string(v.Bytes())) 104 } 105 }() 106 107 return 108 } 109 110 func getConfig(appName string) *proto.ChangeSet { 111 bytes := config.Get(appName).Bytes() 112 113 log.Logf("[getConfig] appName,%s", string(bytes)) 114 return &proto.ChangeSet{ 115 Data: bytes, 116 Checksum: fmt.Sprintf("%x", md5.Sum(bytes)), 117 Format: "yml", 118 Source: "file", 119 Timestamp: time.Now().Unix()} 120 } 121 122 func parsePath(path string) (appName string) { 123 paths := strings.Split(path, "/") 124 125 if paths[0] == "" && len(paths) > 1 { 126 return paths[1] 127 } 128 129 return paths[0] 130 }