github.com/polarismesh/polaris@v1.17.8/store/mysql/routing_config_v2.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package sqldb 19 20 import ( 21 "database/sql" 22 "errors" 23 "fmt" 24 "time" 25 26 "go.uber.org/zap" 27 28 "github.com/polarismesh/polaris/common/model" 29 "github.com/polarismesh/polaris/store" 30 ) 31 32 var _ store.RoutingConfigStoreV2 = (*routingConfigStoreV2)(nil) 33 34 // RoutingConfigStoreV2 impl 35 type routingConfigStoreV2 struct { 36 master *BaseDB 37 slave *BaseDB 38 } 39 40 // CreateRoutingConfigV2 Add a new routing configuration 41 func (r *routingConfigStoreV2) CreateRoutingConfigV2(conf *model.RouterConfig) error { 42 if conf.ID == "" || conf.Revision == "" { 43 log.Errorf("[Store][boltdb] create routing config v2 missing id or revision") 44 return store.NewStatusError(store.EmptyParamsErr, "missing id or revision") 45 } 46 if conf.Policy == "" || conf.Config == "" { 47 log.Errorf("[Store][boltdb] create routing config v2 missing params") 48 return store.NewStatusError(store.EmptyParamsErr, "missing some params") 49 } 50 51 err := RetryTransaction("CreateRoutingConfigV2", func() error { 52 tx, err := r.master.Begin() 53 if err != nil { 54 return err 55 } 56 57 defer func() { 58 _ = tx.Rollback() 59 }() 60 if err := r.createRoutingConfigV2Tx(tx, conf); err != nil { 61 return err 62 } 63 64 if err := tx.Commit(); err != nil { 65 log.Errorf("[Store][database] create routing config v2(%+v) commit: %s", conf, err.Error()) 66 return store.Error(err) 67 } 68 69 return nil 70 }) 71 72 return store.Error(err) 73 } 74 75 func (r *routingConfigStoreV2) CreateRoutingConfigV2Tx(tx store.Tx, conf *model.RouterConfig) error { 76 if tx == nil { 77 return errors.New("tx is nil") 78 } 79 80 dbTx := tx.GetDelegateTx().(*BaseTx) 81 return r.createRoutingConfigV2Tx(dbTx, conf) 82 } 83 84 func (r *routingConfigStoreV2) createRoutingConfigV2Tx(tx *BaseTx, conf *model.RouterConfig) error { 85 // 删除无效的数据 86 if _, err := tx.Exec("DELETE FROM routing_config_v2 WHERE id = ? AND flag = 1", conf.ID); err != nil { 87 log.Errorf("[Store][database] create routing v2(%+v) err: %s", conf, err.Error()) 88 return store.Error(err) 89 } 90 91 insertSQL := "INSERT INTO routing_config_v2(id, namespace, name, policy, config, enable, " + 92 " priority, revision, description, ctime, mtime, etime) VALUES (?,?,?,?,?,?,?,?,?,sysdate(),sysdate(),%s)" 93 94 var enable int 95 if conf.Enable { 96 enable = 1 97 insertSQL = fmt.Sprintf(insertSQL, "sysdate()") 98 } else { 99 enable = 0 100 insertSQL = fmt.Sprintf(insertSQL, emptyEnableTime) 101 } 102 103 log.Debug("[Store][database] create routing v2", zap.String("sql", insertSQL)) 104 105 if _, err := tx.Exec(insertSQL, conf.ID, conf.Namespace, conf.Name, conf.Policy, 106 conf.Config, enable, conf.Priority, conf.Revision, conf.Description); err != nil { 107 log.Errorf("[Store][database] create routing v2(%+v) err: %s", conf, err.Error()) 108 return store.Error(err) 109 } 110 return nil 111 } 112 113 // UpdateRoutingConfigV2 Update a routing configuration 114 func (r *routingConfigStoreV2) UpdateRoutingConfigV2(conf *model.RouterConfig) error { 115 116 tx, err := r.master.Begin() 117 if err != nil { 118 return err 119 } 120 121 defer func() { 122 _ = tx.Rollback() 123 }() 124 125 if err := r.updateRoutingConfigV2Tx(tx, conf); err != nil { 126 return err 127 } 128 129 if err := tx.Commit(); err != nil { 130 log.Errorf("[Store][database] update routing config v2(%+v) commit: %s", conf, err.Error()) 131 return store.Error(err) 132 } 133 134 return nil 135 } 136 137 func (r *routingConfigStoreV2) UpdateRoutingConfigV2Tx(tx store.Tx, conf *model.RouterConfig) error { 138 if tx == nil { 139 return errors.New("tx is nil") 140 } 141 142 dbTx := tx.GetDelegateTx().(*BaseTx) 143 return r.updateRoutingConfigV2Tx(dbTx, conf) 144 } 145 146 func (r *routingConfigStoreV2) updateRoutingConfigV2Tx(tx *BaseTx, conf *model.RouterConfig) error { 147 if conf.ID == "" || conf.Revision == "" { 148 log.Errorf("[Store][database] update routing config v2 missing id or revision") 149 return store.NewStatusError(store.EmptyParamsErr, "missing id or revision") 150 } 151 if conf.Policy == "" || conf.Config == "" { 152 log.Errorf("[Store][boltdb] create routing config v2 missing params") 153 return store.NewStatusError(store.EmptyParamsErr, "missing some params") 154 } 155 156 str := "update routing_config_v2 set name = ?, policy = ?, config = ?, revision = ?, priority = ?, " + 157 " description = ?, mtime = sysdate() where id = ?" 158 if _, err := tx.Exec(str, conf.Name, conf.Policy, conf.Config, conf.Revision, conf.Priority, conf.Description, 159 conf.ID); err != nil { 160 log.Errorf("[Store][database] update routing config v2(%+v) exec err: %s", conf, err.Error()) 161 return store.Error(err) 162 } 163 return nil 164 } 165 166 // EnableRateLimit Enable current limit rules 167 func (r *routingConfigStoreV2) EnableRouting(conf *model.RouterConfig) error { 168 if conf.ID == "" || conf.Revision == "" { 169 return errors.New("[Store][database] enable routing config v2 missing some params") 170 } 171 172 err := RetryTransaction("EnableRouting", func() error { 173 var ( 174 enable int 175 etimeStr string 176 ) 177 if conf.Enable { 178 enable = 1 179 etimeStr = "sysdate()" 180 } else { 181 enable = 0 182 etimeStr = emptyEnableTime 183 } 184 str := fmt.Sprintf( 185 `update routing_config_v2 set enable = ?, revision = ?, mtime = sysdate(), etime=%s where id = ?`, etimeStr) 186 if _, err := r.master.Exec(str, enable, conf.Revision, conf.ID); err != nil { 187 log.Errorf("[Store][database] update outing config v2(%+v), sql %s, err: %s", conf, str, err) 188 return err 189 } 190 191 return nil 192 }) 193 194 return store.Error(err) 195 } 196 197 // DeleteRoutingConfigV2 Delete a routing configuration 198 func (r *routingConfigStoreV2) DeleteRoutingConfigV2(ruleID string) error { 199 200 if ruleID == "" { 201 log.Errorf("[Store][database] delete routing config v2 missing service id") 202 return store.NewStatusError(store.EmptyParamsErr, "missing service id") 203 } 204 205 str := `update routing_config_v2 set flag = 1, mtime = sysdate() where id = ?` 206 if _, err := r.master.Exec(str, ruleID); err != nil { 207 log.Errorf("[Store][database] delete routing config v2(%s) err: %s", ruleID, err.Error()) 208 return store.Error(err) 209 } 210 211 return nil 212 } 213 214 // GetRoutingConfigsV2ForCache Pull the incremental routing configuration information through mtime 215 func (r *routingConfigStoreV2) GetRoutingConfigsV2ForCache( 216 mtime time.Time, firstUpdate bool) ([]*model.RouterConfig, error) { 217 str := `select id, name, policy, config, enable, revision, flag, priority, description, 218 unix_timestamp(ctime), unix_timestamp(mtime), unix_timestamp(etime) 219 from routing_config_v2 where mtime > FROM_UNIXTIME(?) ` 220 221 if firstUpdate { 222 str += " and flag != 1" 223 } 224 rows, err := r.slave.Query(str, timeToTimestamp(mtime)) 225 if err != nil { 226 log.Errorf("[Store][database] query routing configs v2 with mtime err: %s", err.Error()) 227 return nil, err 228 } 229 out, err := fetchRoutingConfigV2Rows(rows) 230 if err != nil { 231 return nil, err 232 } 233 234 return out, nil 235 } 236 237 // GetRoutingConfigV2WithID Pull the routing configuration according to the rules ID 238 func (r *routingConfigStoreV2) GetRoutingConfigV2WithID(ruleID string) (*model.RouterConfig, error) { 239 240 tx, err := r.master.Begin() 241 if err != nil { 242 return nil, err 243 } 244 245 defer func() { 246 _ = tx.Rollback() 247 }() 248 return r.getRoutingConfigV2WithIDTx(tx, ruleID) 249 } 250 251 // GetRoutingConfigV2WithIDTx Pull the routing configuration according to the rules ID 252 func (r *routingConfigStoreV2) GetRoutingConfigV2WithIDTx(tx store.Tx, ruleID string) (*model.RouterConfig, error) { 253 254 if tx == nil { 255 return nil, errors.New("transaction is nil") 256 } 257 258 dbTx := tx.GetDelegateTx().(*BaseTx) 259 return r.getRoutingConfigV2WithIDTx(dbTx, ruleID) 260 } 261 262 func (r *routingConfigStoreV2) getRoutingConfigV2WithIDTx(tx *BaseTx, ruleID string) (*model.RouterConfig, error) { 263 264 str := `select id, name, policy, config, enable, revision, flag, priority, description, 265 unix_timestamp(ctime), unix_timestamp(mtime), unix_timestamp(etime) 266 from routing_config_v2 267 where id = ? and flag = 0` 268 rows, err := tx.Query(str, ruleID) 269 if err != nil { 270 log.Errorf("[Store][database] query routing v2 with id(%s) err: %s", ruleID, err.Error()) 271 return nil, err 272 } 273 274 out, err := fetchRoutingConfigV2Rows(rows) 275 if err != nil { 276 return nil, err 277 } 278 279 if len(out) == 0 { 280 return nil, nil 281 } 282 283 return out[0], nil 284 } 285 286 // fetchRoutingConfigRows Read the data of the database and release ROWS 287 func fetchRoutingConfigV2Rows(rows *sql.Rows) ([]*model.RouterConfig, error) { 288 defer rows.Close() 289 var out []*model.RouterConfig 290 for rows.Next() { 291 var ( 292 entry model.RouterConfig 293 flag, enable int 294 ctime, mtime, etime int64 295 ) 296 297 err := rows.Scan(&entry.ID, &entry.Name, &entry.Policy, &entry.Config, &enable, &entry.Revision, 298 &flag, &entry.Priority, &entry.Description, &ctime, &mtime, &etime) 299 if err != nil { 300 log.Errorf("[database][store] fetch routing config v2 scan err: %s", err.Error()) 301 return nil, err 302 } 303 304 entry.CreateTime = time.Unix(ctime, 0) 305 entry.ModifyTime = time.Unix(mtime, 0) 306 entry.EnableTime = time.Unix(etime, 0) 307 entry.Valid = true 308 if flag == 1 { 309 entry.Valid = false 310 } 311 entry.Enable = enable == 1 312 313 out = append(out, &entry) 314 } 315 if err := rows.Err(); err != nil { 316 log.Errorf("[database][store] fetch routing config v2 next err: %s", err.Error()) 317 return nil, err 318 } 319 320 return out, nil 321 }