github.com/polarismesh/polaris@v1.17.8/store/boltdb/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 boltdb 19 20 import ( 21 "errors" 22 "time" 23 24 bolt "go.etcd.io/bbolt" 25 "go.uber.org/zap" 26 27 "github.com/polarismesh/polaris/common/model" 28 "github.com/polarismesh/polaris/store" 29 ) 30 31 var _ store.RoutingConfigStoreV2 = (*routingStoreV2)(nil) 32 33 var ( 34 // ErrMultipleRoutingV2Found 多个路由配置 35 ErrMultipleRoutingV2Found = errors.New("multiple routing v2 found") 36 ) 37 38 const ( 39 tblNameRoutingV2 = "routing_config_v2" 40 41 routingV2FieldID = "ID" 42 routingV2FieldName = "Name" 43 routingV2FieldNamespace = "Namespace" 44 routingV2FieldPolicy = "Policy" 45 routingV2FieldConfig = "Config" 46 routingV2FieldEnable = "Enable" 47 routingV2FieldRevision = "Revision" 48 routingV2FieldCreateTime = "CreateTime" 49 routingV2FieldModifyTime = "ModifyTime" 50 routingV2FieldEnableTime = "EnableTime" 51 routingV2FieldValid = "Valid" 52 routingV2FieldPriority = "Priority" 53 routingV2FieldDescription = "Description" 54 ) 55 56 type routingStoreV2 struct { 57 handler BoltHandler 58 } 59 60 // CreateRoutingConfigV2 新增一个路由配置 61 func (r *routingStoreV2) CreateRoutingConfigV2(conf *model.RouterConfig) error { 62 if conf.ID == "" || conf.Revision == "" { 63 log.Errorf("[Store][boltdb] create routing config v2 missing id or revision") 64 return store.NewStatusError(store.EmptyParamsErr, "missing id or revision") 65 } 66 if conf.Policy == "" || conf.Config == "" { 67 log.Errorf("[Store][boltdb] create routing config v2 missing params") 68 return store.NewStatusError(store.EmptyParamsErr, "missing some params") 69 } 70 71 return r.handler.Execute(true, func(tx *bolt.Tx) error { 72 return r.createRoutingConfigV2(tx, conf) 73 }) 74 } 75 76 // cleanRoutingConfig 从数据库彻底清理路由配置 77 func (r *routingStoreV2) cleanRoutingConfig(tx *bolt.Tx, ruleID string) error { 78 err := deleteValues(tx, tblNameRoutingV2, []string{ruleID}) 79 if err != nil { 80 log.Errorf("[Store][boltdb] delete invalid route config v2 error, %v", err) 81 return err 82 } 83 return nil 84 } 85 86 func (r *routingStoreV2) CreateRoutingConfigV2Tx(tx store.Tx, conf *model.RouterConfig) error { 87 if tx == nil { 88 return errors.New("transaction is nil") 89 } 90 91 dbTx := tx.GetDelegateTx().(*bolt.Tx) 92 return r.createRoutingConfigV2(dbTx, conf) 93 } 94 95 func (r *routingStoreV2) createRoutingConfigV2(tx *bolt.Tx, conf *model.RouterConfig) error { 96 if err := r.cleanRoutingConfig(tx, conf.ID); err != nil { 97 return err 98 } 99 100 currTime := time.Now() 101 conf.CreateTime = currTime 102 conf.ModifyTime = currTime 103 conf.EnableTime = time.Time{} 104 conf.Valid = true 105 106 if conf.Enable { 107 conf.EnableTime = time.Now() 108 } else { 109 conf.EnableTime = time.Time{} 110 } 111 112 err := saveValue(tx, tblNameRoutingV2, conf.ID, conf) 113 if err != nil { 114 log.Errorf("[Store][boltdb] add routing config v2 to kv error, %v", err) 115 return err 116 } 117 return nil 118 } 119 120 // UpdateRoutingConfigV2 更新一个路由配置 121 func (r *routingStoreV2) UpdateRoutingConfigV2(conf *model.RouterConfig) error { 122 if conf.ID == "" || conf.Revision == "" { 123 log.Errorf("[Store][boltdb] update routing config v2 missing id or revision") 124 return store.NewStatusError(store.EmptyParamsErr, "missing id or revision") 125 } 126 if conf.Policy == "" || conf.Config == "" { 127 log.Errorf("[Store][boltdb] create routing config v2 missing params") 128 return store.NewStatusError(store.EmptyParamsErr, "missing some params") 129 } 130 131 return r.handler.Execute(true, func(tx *bolt.Tx) error { 132 return r.updateRoutingConfigV2Tx(tx, conf) 133 }) 134 } 135 136 func (r *routingStoreV2) UpdateRoutingConfigV2Tx(tx store.Tx, conf *model.RouterConfig) error { 137 if tx == nil { 138 return errors.New("tx is nil") 139 } 140 141 dbTx := tx.GetDelegateTx().(*bolt.Tx) 142 return r.updateRoutingConfigV2Tx(dbTx, conf) 143 } 144 145 func (r *routingStoreV2) updateRoutingConfigV2Tx(tx *bolt.Tx, conf *model.RouterConfig) error { 146 properties := make(map[string]interface{}) 147 properties[routingV2FieldEnable] = conf.Enable 148 properties[routingV2FieldName] = conf.Name 149 properties[routingV2FieldPolicy] = conf.Policy 150 properties[routingV2FieldConfig] = conf.Config 151 properties[routingV2FieldPriority] = conf.Priority 152 properties[routingV2FieldRevision] = conf.Revision 153 properties[routingV2FieldDescription] = conf.Description 154 properties[routingV2FieldModifyTime] = time.Now() 155 156 err := updateValue(tx, tblNameRoutingV2, conf.ID, properties) 157 if err != nil { 158 log.Errorf("[Store][boltdb] update route config v2 to kv error, %v", err) 159 return err 160 } 161 return nil 162 } 163 164 // EnableRouting 165 func (r *routingStoreV2) EnableRouting(conf *model.RouterConfig) error { 166 if conf.ID == "" || conf.Revision == "" { 167 return errors.New("[Store][database] enable routing config v2 missing some params") 168 } 169 170 if conf.Enable { 171 conf.EnableTime = time.Now() 172 } else { 173 conf.EnableTime = time.Time{} 174 } 175 176 properties := make(map[string]interface{}) 177 properties[routingV2FieldEnable] = conf.Enable 178 properties[routingV2FieldEnableTime] = conf.EnableTime 179 properties[routingV2FieldRevision] = conf.Revision 180 properties[routingV2FieldModifyTime] = time.Now() 181 182 err := r.handler.UpdateValue(tblNameRoutingV2, conf.ID, properties) 183 if err != nil { 184 log.Errorf("[Store][boltdb] enable route config v2 to kv error, %v", err) 185 return err 186 } 187 return nil 188 } 189 190 // DeleteRoutingConfigV2 删除一个路由配置 191 func (r *routingStoreV2) DeleteRoutingConfigV2(ruleID string) error { 192 if ruleID == "" { 193 log.Errorf("[Store][boltdb] update routing config v2 missing id") 194 return store.NewStatusError(store.EmptyParamsErr, "missing id") 195 } 196 properties := make(map[string]interface{}) 197 properties[routingV2FieldValid] = false 198 properties[routingV2FieldModifyTime] = time.Now() 199 200 err := r.handler.UpdateValue(tblNameRoutingV2, ruleID, properties) 201 if err != nil { 202 log.Errorf("[Store][boltdb] update route config v2 to kv error, %v", err) 203 return err 204 } 205 return nil 206 } 207 208 // GetRoutingConfigsV2ForCache 通过mtime拉取增量的路由配置信息 209 // 此方法用于 cache 增量更新,需要注意 mtime 应为数据库时间戳 210 func (r *routingStoreV2) GetRoutingConfigsV2ForCache(mtime time.Time, firstUpdate bool) ([]*model.RouterConfig, error) { 211 if firstUpdate { 212 mtime = time.Time{} 213 } 214 215 fields := []string{routingV2FieldModifyTime} 216 217 routes, err := r.handler.LoadValuesByFilter(tblNameRoutingV2, fields, &model.RouterConfig{}, 218 func(m map[string]interface{}) bool { 219 rMtime, ok := m[routingV2FieldModifyTime] 220 if !ok { 221 return false 222 } 223 routeMtime := rMtime.(time.Time) 224 return !routeMtime.Before(mtime) 225 }) 226 if err != nil { 227 log.Errorf("[Store][boltdb] load route config v2 from kv error, %v", err) 228 return nil, err 229 } 230 231 return toRouteConfV2(routes), nil 232 } 233 234 func toRouteConfV2(m map[string]interface{}) []*model.RouterConfig { 235 var routeConf []*model.RouterConfig 236 for _, r := range m { 237 routeConf = append(routeConf, r.(*model.RouterConfig)) 238 } 239 240 return routeConf 241 } 242 243 // GetRoutingConfigV2WithID 根据服务ID拉取路由配置 244 func (r *routingStoreV2) GetRoutingConfigV2WithID(id string) (*model.RouterConfig, error) { 245 tx, err := r.handler.StartTx() 246 if err != nil { 247 return nil, err 248 } 249 250 boldTx := tx.GetDelegateTx().(*bolt.Tx) 251 defer func() { 252 _ = boldTx.Rollback() 253 }() 254 255 return r.getRoutingConfigV2WithIDTx(boldTx, id) 256 } 257 258 // GetRoutingConfigV2WithIDTx 根据服务ID拉取路由配置 259 func (r *routingStoreV2) GetRoutingConfigV2WithIDTx(tx store.Tx, id string) (*model.RouterConfig, error) { 260 261 if tx == nil { 262 return nil, errors.New("tx is nil") 263 } 264 265 boldTx := tx.GetDelegateTx().(*bolt.Tx) 266 return r.getRoutingConfigV2WithIDTx(boldTx, id) 267 } 268 269 func (r *routingStoreV2) getRoutingConfigV2WithIDTx(tx *bolt.Tx, id string) (*model.RouterConfig, error) { 270 ret := make(map[string]interface{}) 271 if err := loadValues(tx, tblNameRoutingV2, []string{id}, &model.RouterConfig{}, ret); err != nil { 272 log.Error("[Store][boltdb] load route config v2 from kv", zap.String("routing-id", id), zap.Error(err)) 273 return nil, err 274 } 275 276 if len(ret) == 0 { 277 return nil, nil 278 } 279 280 if len(ret) > 1 { 281 return nil, ErrMultipleRoutingV2Found 282 } 283 284 val := ret[id].(*model.RouterConfig) 285 if !val.Valid { 286 return nil, nil 287 } 288 289 return val, nil 290 }