@@ -15,6 +15,7 @@ import (
1515 "github.com/openimsdk/tools/apiresp"
1616 "github.com/openimsdk/tools/errs"
1717 "github.com/openimsdk/tools/log"
18+ "github.com/openimsdk/tools/utils/datautil"
1819 "github.com/openimsdk/tools/utils/runtimeenv"
1920 clientv3 "go.etcd.io/etcd/client/v3"
2021)
@@ -109,6 +110,84 @@ func (cm *ConfigManager) SetConfig(c *gin.Context) {
109110 apiresp .GinSuccess (c , nil )
110111}
111112
113+ func (cm * ConfigManager ) SetConfigs (c * gin.Context ) {
114+ if cm .config .Discovery .Enable != kdisc .ETCDCONST {
115+ apiresp .GinError (c , errs .New ("only etcd support set config" ).Wrap ())
116+ return
117+ }
118+ var req apistruct.SetConfigsReq
119+ if err := c .BindJSON (& req ); err != nil {
120+ apiresp .GinError (c , errs .ErrArgs .WithDetail (err .Error ()).Wrap ())
121+ return
122+ }
123+ var (
124+ err error
125+ ops []* clientv3.Op
126+ )
127+
128+ for _ , cf := range req .Configs {
129+ var op * clientv3.Op
130+ switch cf .ConfigName {
131+ case config .DiscoveryConfigFileName :
132+ op , err = compareAndOp [config.Discovery ](c , cm .config .Name2Config (cf .ConfigName ), & cf , cm .client )
133+ case config .LogConfigFileName :
134+ op , err = compareAndOp [config.Log ](c , cm .config .Name2Config (cf .ConfigName ), & cf , cm .client )
135+ case config .MongodbConfigFileName :
136+ op , err = compareAndOp [config.Mongo ](c , cm .config .Name2Config (cf .ConfigName ), & cf , cm .client )
137+ case config .ChatAPIAdminCfgFileName :
138+ op , err = compareAndOp [config.API ](c , cm .config .Name2Config (cf .ConfigName ), & cf , cm .client )
139+ case config .ChatAPIChatCfgFileName :
140+ op , err = compareAndOp [config.API ](c , cm .config .Name2Config (cf .ConfigName ), & cf , cm .client )
141+ case config .ChatRPCAdminCfgFileName :
142+ op , err = compareAndOp [config.Admin ](c , cm .config .Name2Config (cf .ConfigName ), & cf , cm .client )
143+ case config .ChatRPCChatCfgFileName :
144+ op , err = compareAndOp [config.Chat ](c , cm .config .Name2Config (cf .ConfigName ), & cf , cm .client )
145+ case config .ShareFileName :
146+ op , err = compareAndOp [config.Share ](c , cm .config .Name2Config (cf .ConfigName ), & cf , cm .client )
147+ case config .RedisConfigFileName :
148+ op , err = compareAndOp [config.Redis ](c , cm .config .Name2Config (cf .ConfigName ), & cf , cm .client )
149+ default :
150+ apiresp .GinError (c , errs .ErrArgs .Wrap ())
151+ return
152+ }
153+ if err != nil {
154+ apiresp .GinError (c , errs .ErrArgs .WithDetail (err .Error ()).Wrap ())
155+ return
156+ }
157+ if op != nil {
158+ ops = append (ops , op )
159+ }
160+ }
161+ if len (ops ) > 0 {
162+ tx := cm .client .Txn (c )
163+ if _ , err = tx .Then (datautil .Batch (func (op * clientv3.Op ) clientv3.Op { return * op }, ops )... ).Commit (); err != nil {
164+ apiresp .GinError (c , errs .WrapMsg (err , "save to etcd failed" ))
165+ return
166+ }
167+
168+ }
169+
170+ apiresp .GinSuccess (c , nil )
171+ }
172+
173+ func compareAndOp [T any ](c * gin.Context , old any , req * apistruct.SetConfigReq , client * clientv3.Client ) (* clientv3.Op , error ) {
174+ conf := new (T )
175+ err := json .Unmarshal ([]byte (req .Data ), & conf )
176+ if err != nil {
177+ return nil , errs .ErrArgs .WithDetail (err .Error ()).Wrap ()
178+ }
179+ eq := reflect .DeepEqual (old , conf )
180+ if eq {
181+ return nil , nil
182+ }
183+ data , err := json .Marshal (conf )
184+ if err != nil {
185+ return nil , errs .ErrArgs .WithDetail (err .Error ()).Wrap ()
186+ }
187+ op := clientv3 .OpPut (etcd .BuildKey (req .ConfigName ), string (data ))
188+ return & op , nil
189+ }
190+
112191func compareAndSave [T any ](c * gin.Context , old any , req * apistruct.SetConfigReq , client * clientv3.Client ) error {
113192 conf := new (T )
114193 err := json .Unmarshal ([]byte (req .Data ), & conf )
0 commit comments