github.com/polarismesh/polaris@v1.17.8/store/mysql/service.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 "fmt" 23 "strings" 24 "time" 25 26 "github.com/polarismesh/polaris/common/model" 27 "github.com/polarismesh/polaris/common/utils" 28 "github.com/polarismesh/polaris/store" 29 ) 30 31 // serviceStore 实现了ServiceStore 32 type serviceStore struct { 33 master *BaseDB 34 slave *BaseDB 35 } 36 37 // AddService 增加服务 38 func (ss *serviceStore) AddService(s *model.Service) error { 39 if s.ID == "" || s.Name == "" || s.Namespace == "" { 40 return store.NewStatusError(store.EmptyParamsErr, fmt.Sprintf( 41 "add service missing some params, id is %s, name is %s, namespace is %s", s.ID, s.Name, s.Namespace)) 42 } 43 44 err := RetryTransaction("addService", func() error { 45 return ss.addService(s) 46 }) 47 return store.Error(err) 48 } 49 50 // addService add service 51 func (ss *serviceStore) addService(s *model.Service) error { 52 tx, err := ss.master.Begin() 53 if err != nil { 54 return err 55 } 56 defer func() { 57 _ = tx.Rollback() 58 }() 59 60 // 先清理无效数据 61 if err := cleanService(tx, s.Name, s.Namespace); err != nil { 62 return err 63 } 64 65 // 填充main表 66 if err := addServiceMain(tx, s); err != nil { 67 log.Errorf("[Store][database] add service table err: %s", err.Error()) 68 return err 69 } 70 71 // 填充metadata表 72 if err := addServiceMeta(tx, s.ID, s.Meta); err != nil { 73 log.Errorf("[Store][database] add service meta table err: %s", err.Error()) 74 return err 75 } 76 77 // 填充owner_service_map表 78 if err := addOwnerServiceMap(tx, s.Name, s.Namespace, s.Owner); err != nil { 79 log.Errorf("[Store][database] add owner_service_map table err: %s", err.Error()) 80 return err 81 } 82 83 if err := tx.Commit(); err != nil { 84 log.Errorf("[Store][database] add service tx commit err: %s", err.Error()) 85 return err 86 } 87 88 return nil 89 } 90 91 // DeleteService 删除服务 92 func (ss *serviceStore) DeleteService(id, serviceName, namespaceName string) error { 93 err := RetryTransaction("deleteService", func() error { 94 return ss.deleteService(id, serviceName, namespaceName) 95 }) 96 return store.Error(err) 97 } 98 99 // deleteService 删除服务的内部函数 100 func (ss *serviceStore) deleteService(id, serviceName, namespaceName string) error { 101 tx, err := ss.master.Begin() 102 if err != nil { 103 return err 104 } 105 defer func() { 106 _ = tx.Rollback() 107 }() 108 109 // 删除服务 110 if err := deleteServiceByID(tx, id); err != nil { 111 log.Errorf("[Store][database] delete service(%s) err : %s", id, err.Error()) 112 return err 113 } 114 115 // 删除负责人、服务映射表对应记录 116 if err := deleteOwnerServiceMap(tx, serviceName, namespaceName); err != nil { 117 log.Errorf("[Store][database] delete owner_service_map(%s) err : %s", id, err.Error()) 118 return err 119 } 120 121 if err := tx.Commit(); err != nil { 122 log.Errorf("[Store][database] add service tx commit err: %s", err.Error()) 123 return err 124 } 125 126 return nil 127 } 128 129 // deleteServiceByID 删除服务或服务别名 130 func deleteServiceByID(tx *BaseTx, id string) error { 131 log.Infof("[Store][database] delete service id(%s)", id) 132 str := "update service set flag = 1, mtime = sysdate() where id = ?" 133 if _, err := tx.Exec(str, id); err != nil { 134 return err 135 } 136 137 return nil 138 } 139 140 // DeleteServiceAlias 删除服务别名 141 func (ss *serviceStore) DeleteServiceAlias(name string, namespace string) error { 142 return ss.master.processWithTransaction("deleteServiceAlias", func(tx *BaseTx) error { 143 str := "update service set flag = 1, mtime = sysdate() where name = ? and namespace = ?" 144 if _, err := tx.Exec(str, name, namespace); err != nil { 145 log.Errorf("[Store][database] delete service alias err: %s", err.Error()) 146 return store.Error(err) 147 } 148 149 if err := tx.Commit(); err != nil { 150 log.Errorf("[Store][database] batch delete service alias commit tx err: %s", err.Error()) 151 return err 152 } 153 return nil 154 }) 155 } 156 157 // UpdateServiceAlias 更新服务别名 158 func (ss *serviceStore) UpdateServiceAlias(alias *model.Service, needUpdateOwner bool) error { 159 if alias.ID == "" || 160 alias.Name == "" || 161 alias.Namespace == "" || 162 alias.Revision == "" || 163 alias.Reference == "" || 164 (needUpdateOwner && alias.Owner == "") { 165 return store.NewStatusError(store.EmptyParamsErr, "update Service Alias missing some params") 166 } 167 if err := ss.updateServiceAlias(alias, needUpdateOwner); err != nil { 168 log.Errorf("[Store][ServiceAlias] update service alias err: %s", err.Error()) 169 return store.Error(err) 170 } 171 172 return nil 173 } 174 175 // updateServiceAlias update service alias 176 func (ss *serviceStore) updateServiceAlias(alias *model.Service, needUpdateOwner bool) error { 177 tx, err := ss.master.Begin() 178 if err != nil { 179 log.Errorf("[Store][database] update service alias tx begin err: %s", err.Error()) 180 return err 181 } 182 defer func() { 183 _ = tx.Rollback() 184 }() 185 186 updateStmt := ` 187 update 188 service 189 set 190 name = ?, namespace = ?, reference = ?, comment = ?, token = ?, revision = ?, owner = ?, mtime = sysdate() 191 where 192 id = ? and (select flag from (select flag from service where id = ?) as alias) = 0` 193 194 result, err := tx.Exec(updateStmt, alias.Name, alias.Namespace, alias.Reference, alias.Comment, alias.Token, 195 alias.Revision, alias.Owner, alias.ID, alias.Reference) 196 if err != nil { 197 log.Errorf("[Store][ServiceAlias] update service alias exec err: %s", err.Error()) 198 return err 199 } 200 201 // 更新owner_service_map表 202 if needUpdateOwner { 203 if err := updateOwnerServiceMap(tx, alias.Name, alias.Namespace, alias.Owner); err != nil { 204 log.Errorf("[Store][database] update owner_service_map table err: %s", err.Error()) 205 return err 206 } 207 } 208 209 if err := tx.Commit(); err != nil { 210 log.Errorf("[Store][database] update service alias tx commit err: %s", err.Error()) 211 return err 212 } 213 214 if err := checkServiceAffectedRows(result, 1); err != nil { 215 if store.Code(err) == store.AffectedRowsNotMatch { 216 return store.NewStatusError(store.NotFoundService, "not found service") 217 } 218 } 219 return nil 220 } 221 222 // checkServiceAffectedRows 检查服务数据库处理返回的行数 223 func checkServiceAffectedRows(result sql.Result, count int64) error { 224 n, err := result.RowsAffected() 225 if err != nil { 226 log.Errorf("[Store][ServiceAlias] get rows affected err: %s", err.Error()) 227 return err 228 } 229 230 if n == count { 231 return nil 232 } 233 log.Errorf("[Store][ServiceAlias] get rows affected result(%d) is not match expect(%d)", n, count) 234 return store.NewStatusError(store.AffectedRowsNotMatch, "affected rows not match") 235 } 236 237 // UpdateService 更新完整的服务信息 238 func (ss *serviceStore) UpdateService(service *model.Service, needUpdateOwner bool) error { 239 if service.ID == "" || 240 service.Name == "" || 241 service.Namespace == "" || 242 service.Revision == "" { 243 return store.NewStatusError(store.EmptyParamsErr, "Update Service missing some params") 244 } 245 246 err := RetryTransaction("updateService", func() error { 247 return ss.updateService(service, needUpdateOwner) 248 }) 249 if err == nil { 250 return nil 251 } 252 253 serr := store.Error(err) 254 if store.Code(serr) == store.DuplicateEntryErr { 255 serr = store.NewStatusError(store.DataConflictErr, err.Error()) 256 } 257 return serr 258 } 259 260 // updateService update service 261 func (ss *serviceStore) updateService(service *model.Service, needUpdateOwner bool) error { 262 tx, err := ss.master.Begin() 263 if err != nil { 264 log.Errorf("[Store][database] update service tx begin err: %s", err.Error()) 265 return err 266 } 267 defer func() { 268 _ = tx.Rollback() 269 }() 270 271 // 更新main表 272 if err := updateServiceMain(tx, service); err != nil { 273 log.Errorf("[Store][database] update service main table err: %s", err.Error()) 274 return err 275 } 276 277 // 更新meta表 278 if err := updateServiceMeta(tx, service.ID, service.Meta); err != nil { 279 log.Errorf("[Store][database] update service meta table err: %s", err.Error()) 280 return err 281 } 282 283 // 更新owner_service_map表 284 if needUpdateOwner { 285 if err := updateOwnerServiceMap(tx, service.Name, service.Namespace, service.Owner); err != nil { 286 log.Errorf("[Store][database] update owner_service_map table err: %s", err.Error()) 287 return err 288 } 289 } 290 291 if err := tx.Commit(); err != nil { 292 log.Errorf("[Store][database] update service tx commit err: %s", err.Error()) 293 return err 294 } 295 return nil 296 } 297 298 // UpdateServiceToken 更新服务token 299 func (ss *serviceStore) UpdateServiceToken(id string, token string, revision string) error { 300 return ss.master.processWithTransaction("updateServiceToken", func(tx *BaseTx) error { 301 str := `update service set token = ?, revision = ?, mtime = sysdate() where id = ?` 302 _, err := tx.Exec(str, token, revision, id) 303 if err != nil { 304 log.Errorf("[Store][database] update service(%s) token err: %s", id, err.Error()) 305 return store.Error(err) 306 } 307 308 if err := tx.Commit(); err != nil { 309 log.Errorf("[Store][database] update service token tx commit err: %s", err.Error()) 310 return err 311 } 312 313 return nil 314 }) 315 } 316 317 // GetService 获取服务详情,只返回有效的数据 318 func (ss *serviceStore) GetService(name string, namespace string) (*model.Service, error) { 319 service, err := ss.getService(name, namespace) 320 if err != nil { 321 return nil, fmt.Errorf("getService err: %v", err) 322 } 323 324 if service != nil && !service.Valid { 325 return nil, nil 326 } 327 328 return service, nil 329 } 330 331 // GetSourceServiceToken 获取只获取服务token 332 // 返回服务ID,服务token 333 func (ss *serviceStore) GetSourceServiceToken(name string, namespace string) (*model.Service, error) { 334 str := `select id, token, IFNULL(platform_id, "") from service 335 where name = ? and namespace = ? and flag = 0 336 and (reference is null or reference = '')` 337 var out model.Service 338 err := ss.master.QueryRow(str, name, namespace).Scan(&out.ID, &out.Token, &out.PlatformID) 339 switch { 340 case err == sql.ErrNoRows: 341 return nil, nil 342 case err != nil: 343 return nil, err 344 default: 345 out.Name = name 346 out.Namespace = namespace 347 return &out, nil 348 } 349 } 350 351 // GetServiceByID 根据服务ID查询服务详情 352 func (ss *serviceStore) GetServiceByID(id string) (*model.Service, error) { 353 service, err := ss.getServiceByID(id) 354 if err != nil { 355 return nil, err 356 } 357 if service != nil && !service.Valid { 358 return nil, nil 359 } 360 361 return service, nil 362 } 363 364 // GetServices 根据相关条件查询对应服务及数目,不包括别名 365 func (ss *serviceStore) GetServices(serviceFilters, serviceMetas map[string]string, instanceFilters *store.InstanceArgs, 366 offset, limit uint32) (uint32, []*model.Service, error) { 367 // 只查询flag=0的服务列表 368 serviceFilters["service.flag"] = "0" 369 370 out, err := ss.getServices(serviceFilters, serviceMetas, instanceFilters, offset, limit) 371 if err != nil { 372 return 0, nil, err 373 } 374 375 num, err := ss.getServicesCount(serviceFilters, serviceMetas, instanceFilters) 376 if err != nil { 377 return 0, nil, err 378 } 379 return num, out, err 380 } 381 382 // GetServicesCount 获取所有服务总数 383 func (ss *serviceStore) GetServicesCount() (uint32, error) { 384 countStr := "select count(*) from service where flag = 0" 385 return queryEntryCount(ss.master, countStr, nil) 386 } 387 388 // GetMoreServices 根据modify_time获取增量数据 389 func (ss *serviceStore) GetMoreServices(mtime time.Time, firstUpdate, disableBusiness, needMeta bool) ( 390 map[string]*model.Service, error) { 391 if needMeta { 392 services, err := getMoreServiceWithMeta(ss.slave.Query, mtime, firstUpdate, disableBusiness) 393 if err != nil { 394 log.Errorf("[Store][database] get more service+meta err: %s", err.Error()) 395 return nil, err 396 } 397 return services, nil 398 } 399 services, err := getMoreServiceMain(ss.slave.Query, mtime, firstUpdate, disableBusiness) 400 if err != nil { 401 log.Errorf("[Store][database] get more service main err: %s", err.Error()) 402 return nil, err 403 } 404 return services, nil 405 } 406 407 // GetSystemServices 获取系统服务 408 func (ss *serviceStore) GetSystemServices() ([]*model.Service, error) { 409 str := genServiceSelectSQL() 410 str += " from service where flag = 0 and namespace = ?" 411 rows, err := ss.master.Query(str, SystemNamespace) 412 if err != nil { 413 log.Errorf("[Store][database] get system service query err: %s", err.Error()) 414 return nil, err 415 } 416 417 out, err := ss.fetchRowServices(rows) 418 if err != nil { 419 log.Errorf("[Store][database] get row services err: %s", err) 420 return nil, err 421 } 422 423 return out, nil 424 } 425 426 // GetServiceAliases 获取服务别名列表 427 func (ss *serviceStore) GetServiceAliases(filter map[string]string, offset uint32, limit uint32) (uint32, 428 []*model.ServiceAlias, error) { 429 430 whereFilter := serviceAliasFilter2Where(filter) 431 count, err := ss.getServiceAliasesCount(whereFilter) 432 if err != nil { 433 log.Errorf("[Store][database] get service aliases count err: %s", err.Error()) 434 return 0, nil, err 435 } 436 437 items, err := ss.getServiceAliasesInfo(whereFilter, offset, limit) 438 if err != nil { 439 log.Errorf("[Store][database] get service aliases info err: %s", err.Error()) 440 return 0, nil, err 441 } 442 443 return count, items, nil 444 } 445 446 // getServiceAliasesInfo 获取服务别名的详细信息 447 func (ss *serviceStore) getServiceAliasesInfo(filter map[string]string, offset uint32, 448 limit uint32) ([]*model.ServiceAlias, error) { 449 // limit为0,则直接返回 450 if limit == 0 { 451 return make([]*model.ServiceAlias, 0), nil 452 } 453 454 baseStr := ` 455 select 456 alias.id, alias.name, alias.namespace, UNIX_TIMESTAMP(alias.ctime), UNIX_TIMESTAMP(alias.mtime), 457 alias.comment, source.id as sourceID, source.name as sourceName, source.namespace, alias.owner 458 from 459 service as alias inner join service as source 460 on alias.reference = source.id and alias.flag != 1 ` 461 order := &Order{"alias.mtime", "desc"} 462 463 queryStmt, args := genServiceAliasWhereSQLAndArgs(baseStr, filter, order, offset, limit) 464 rows, err := ss.master.Query(queryStmt, args...) 465 if err != nil { 466 log.Errorf("[Store][database] get service aliases query(%s) err: %s", queryStmt, err.Error()) 467 return nil, err 468 } 469 defer func() { _ = rows.Close() }() 470 471 var out []*model.ServiceAlias 472 var ctime, mtime int64 473 for rows.Next() { 474 var entry model.ServiceAlias 475 err := rows.Scan( 476 &entry.ID, &entry.Alias, &entry.AliasNamespace, &ctime, &mtime, &entry.Comment, 477 &entry.ServiceID, &entry.Service, &entry.Namespace, &entry.Owner) 478 if err != nil { 479 log.Errorf("[Store][database] get service alias rows scan err: %s", err.Error()) 480 return nil, err 481 } 482 483 entry.CreateTime = time.Unix(ctime, 0) 484 entry.ModifyTime = time.Unix(mtime, 0) 485 out = append(out, &entry) 486 } 487 488 return out, nil 489 } 490 491 // getServiceAliasesCount 获取别名总数 492 func (ss *serviceStore) getServiceAliasesCount(filter map[string]string) (uint32, error) { 493 baseStr := ` 494 select 495 count(*) 496 from 497 service as alias inner join service as source 498 on alias.reference = source.id and alias.flag != 1 ` 499 str, args := genServiceAliasWhereSQLAndArgs(baseStr, filter, nil, 0, 1) 500 return queryEntryCount(ss.master, str, args) 501 } 502 503 // getServices 根据相关条件查询对应服务,不包括别名 504 func (ss *serviceStore) getServices(sFilters, sMetas map[string]string, iFilters *store.InstanceArgs, 505 offset, limit uint32) ([]*model.Service, error) { 506 // 不查询任意内容,直接返回空数组 507 if limit == 0 { 508 return make([]*model.Service, 0), nil 509 } 510 511 // 构造SQL语句 512 var args []interface{} 513 whereStr := " from service where (reference is null or reference = '') " 514 if len(sMetas) > 0 { 515 subStr, subArgs := filterMetadata(sMetas) 516 whereStr += " and service.id in " + subStr 517 args = append(args, subArgs...) 518 } 519 if iFilters != nil { 520 subStr, subArgs := filterInstance(iFilters) 521 whereStr += " and service.id in " + subStr 522 args = append(args, subArgs...) 523 } 524 str := genServiceSelectSQL() + whereStr 525 526 filterStr, filterArgs := genServiceFilterSQL(sFilters) 527 if filterStr != "" { 528 str += " and " + filterStr 529 args = append(args, filterArgs...) 530 } 531 532 order := &Order{"service.mtime", "desc"} 533 page := &Page{offset, limit} 534 opStr, opArgs := genOrderAndPage(order, page) 535 536 str += opStr 537 args = append(args, opArgs...) 538 rows, err := ss.master.Query(str, args...) 539 if err != nil { 540 log.Errorf("[Store][database] get services by filter query(%s) err: %s", str, err.Error()) 541 return nil, err 542 } 543 544 out, err := ss.fetchRowServices(rows) 545 if err != nil { 546 log.Errorf("[Store][database] get row services err: %s", err) 547 return nil, err 548 } 549 550 return out, nil 551 } 552 553 // getServicesCount 根据相关条件查询对应服务数目,不包括别名 554 func (ss *serviceStore) getServicesCount( 555 sFilters, sMetas map[string]string, iFilters *store.InstanceArgs) (uint32, error) { 556 str := `select count(*) from service where (reference is null or reference = '')` 557 var args []interface{} 558 if len(sMetas) > 0 { 559 subStr, subArgs := filterMetadata(sMetas) 560 str += " and service.id in " + subStr 561 args = append(args, subArgs...) 562 } 563 if iFilters != nil { 564 subStr, subArgs := filterInstance(iFilters) 565 str += " and service.id in " + subStr 566 args = append(args, subArgs...) 567 } 568 569 filterStr, filterArgs := genServiceFilterSQL(sFilters) 570 if filterStr != "" { 571 str += " and " + filterStr 572 args = append(args, filterArgs...) 573 } 574 return queryEntryCount(ss.master, str, args) 575 } 576 577 // fetchRowServices 根据rows,获取到services,并且批量获取对应的metadata 578 func (ss *serviceStore) fetchRowServices(rows *sql.Rows) ([]*model.Service, error) { 579 services, err := fetchServiceRows(rows) 580 if err != nil { 581 return nil, err 582 } 583 584 data := make([]interface{}, 0, len(services)) 585 for idx := range services { 586 // 只获取valid为true的metadata 587 if services[idx].Valid { 588 data = append(data, services[idx]) 589 } 590 } 591 592 err = BatchQuery("get-service-metadata", data, func(objects []interface{}) error { 593 rows, batchErr := batchQueryServiceMeta(ss.master.Query, objects) 594 if batchErr != nil { 595 return batchErr 596 } 597 metas := make(map[string]map[string]string) 598 batchErr = callFetchServiceMetaRows(rows, func(id, key, value string) (b bool, e error) { 599 if _, ok := metas[id]; !ok { 600 metas[id] = make(map[string]string) 601 } 602 metas[id][key] = value 603 return true, nil 604 }) 605 if batchErr != nil { 606 return batchErr 607 } 608 for id, meta := range metas { 609 for _, entry := range objects { 610 if entry.(*model.Service).ID == id { 611 entry.(*model.Service).Meta = meta 612 break 613 } 614 } 615 } 616 return nil 617 }) 618 if err != nil { 619 log.Errorf("[Store][database] get service metadata err: %s", err.Error()) 620 return nil, err 621 } 622 623 return services, nil 624 } 625 626 // getServiceMeta 获取metadata数据 627 func (ss *serviceStore) getServiceMeta(id string) (map[string]string, error) { 628 if id == "" { 629 return nil, nil 630 } 631 632 // 从metadata表中获取数据 633 metaStr := "select `mkey`, `mvalue` from service_metadata where id = ?" 634 rows, err := ss.master.Query(metaStr, id) 635 if err != nil { 636 log.Errorf("[Store][database] get service metadata query err: %s", err.Error()) 637 return nil, err 638 } 639 return fetchServiceMeta(rows) 640 } 641 642 // getService 获取service内部函数 643 func (ss *serviceStore) getService(name string, namespace string) (*model.Service, error) { 644 if name == "" || namespace == "" { 645 return nil, fmt.Errorf("missing params, name: %s, namespace: %s", name, namespace) 646 } 647 648 out, err := ss.getServiceMain(name, namespace) 649 if err != nil { 650 return nil, err 651 } 652 if out == nil { 653 return nil, nil 654 } 655 656 meta, err := ss.getServiceMeta(out.ID) 657 if err != nil { 658 return nil, err 659 } 660 661 out.Meta = meta 662 return out, nil 663 } 664 665 // getServiceMain 获取服务表的信息,不包括metadata 666 func (ss *serviceStore) getServiceMain(name string, namespace string) (*model.Service, error) { 667 str := genServiceSelectSQL() + " from service where name = ? and namespace = ?" 668 rows, err := ss.master.Query(str, name, namespace) 669 if err != nil { 670 log.Errorf("[Store][database] get service err: %s", err.Error()) 671 return nil, err 672 } 673 674 out, err := fetchServiceRows(rows) 675 if err != nil { 676 return nil, err 677 } 678 679 if len(out) == 0 { 680 return nil, nil 681 } 682 683 return out[0], nil 684 } 685 686 // getServiceByID 根据服务ID获取服务详情的内部函数 687 func (ss *serviceStore) getServiceByID(serviceID string) (*model.Service, error) { 688 str := genServiceSelectSQL() + " from service where service.id = ?" 689 rows, err := ss.master.Query(str, serviceID) 690 if err != nil { 691 log.Errorf("[Store][database] get service by id query err: %s", err.Error()) 692 return nil, err 693 } 694 695 out, err := fetchServiceRows(rows) 696 if err != nil { 697 return nil, err 698 } 699 700 if len(out) == 0 { 701 return nil, nil 702 } 703 704 meta, err := ss.getServiceMeta(out[0].ID) 705 if err != nil { 706 return nil, err 707 } 708 out[0].Meta = meta 709 710 return out[0], nil 711 } 712 713 // cleanService 清理无效数据,flag=1的数据,只需要删除service即可 714 func cleanService(tx *BaseTx, name string, namespace string) error { 715 log.Infof("[Store][database] clean service(%s, %s)", name, namespace) 716 str := "delete from service where name = ? and namespace = ? and flag = 1" 717 _, err := tx.Exec(str, name, namespace) 718 if err != nil { 719 log.Errorf("[Store][database] clean service(%s, %s) err: %s", name, namespace, err.Error()) 720 return err 721 } 722 723 return nil 724 } 725 726 // getMoreServiceWithMeta获取增量服务,包括元数据 727 func getMoreServiceWithMeta(queryHandler QueryHandler, mtime time.Time, firstUpdate, disableBusiness bool) ( 728 map[string]*model.Service, error) { 729 // 首次拉取 730 if firstUpdate { 731 // 获取全量服务 732 services, err := getMoreServiceMain(queryHandler, mtime, firstUpdate, disableBusiness) 733 if err != nil { 734 log.Errorf("[Store][database] get more service main err: %s", err.Error()) 735 return nil, err 736 } 737 // 获取全量服务元数据 738 str := "select id, mkey, mvalue from service_metadata" 739 rows, err := queryHandler(str) 740 if err != nil { 741 log.Errorf("[Store][database] acquire services meta query err: %s", err.Error()) 742 return nil, err 743 } 744 if err := fetchMoreServiceMeta(services, rows); err != nil { 745 return nil, err 746 } 747 return services, nil 748 } 749 750 // 非首次拉取 751 var args []interface{} 752 args = append(args, timeToTimestamp(mtime)) 753 str := genServiceSelectSQL() + `, IFNULL(service_metadata.id, ""), IFNULL(mkey, ""), IFNULL(mvalue, "") ` + 754 `from service left join service_metadata on service.id = service_metadata.id where service.mtime >= FROM_UNIXTIME(?)` 755 if disableBusiness { 756 str += " and service.namespace = ?" 757 args = append(args, SystemNamespace) 758 } 759 rows, err := queryHandler(str, args...) 760 if err != nil { 761 log.Errorf("[Store][database] get more services with meta query err: %s", err.Error()) 762 return nil, err 763 } 764 return fetchServiceWithMetaRows(rows) 765 } 766 767 // fetchServiceWithMetaRows 获取service+metadata rows里面的数据 768 func fetchServiceWithMetaRows(rows *sql.Rows) (map[string]*model.Service, error) { 769 if rows == nil { 770 return nil, nil 771 } 772 defer rows.Close() 773 774 out := make(map[string]*model.Service) 775 var id, mKey, mValue string 776 var flag int 777 progress := 0 778 for rows.Next() { 779 progress++ 780 if progress%100000 == 0 { 781 log.Infof("[Store][database] services+meta row next progress: %d", progress) 782 } 783 784 var item model.Service 785 if err := rows.Scan(&item.ID, &item.Name, &item.Namespace, &item.Business, &item.Comment, 786 &item.Token, &item.Revision, &item.Owner, &flag, &item.Ctime, &item.Mtime, &item.Ports, 787 &item.Department, &item.CmdbMod1, &item.CmdbMod2, &item.CmdbMod3, 788 &item.Reference, &item.ReferFilter, &item.PlatformID, &id, &mKey, &mValue); err != nil { 789 log.Errorf("[Store][database] fetch service+meta rows scan err: %s", err.Error()) 790 return nil, err 791 } 792 item.CreateTime = time.Unix(item.Ctime, 0) 793 item.ModifyTime = time.Unix(item.Mtime, 0) 794 item.Valid = true 795 if flag == 1 { 796 item.Valid = false 797 } 798 799 if _, ok := out[item.ID]; !ok { 800 out[item.ID] = &item 801 } 802 // 服务存在meta 803 if id != "" { 804 if out[item.ID].Meta == nil { 805 out[item.ID].Meta = make(map[string]string) 806 } 807 out[item.ID].Meta[mKey] = mValue 808 } 809 } 810 811 if err := rows.Err(); err != nil { 812 log.Errorf("[Store][database] fetch service+meta rows next err: %s", err.Error()) 813 return nil, err 814 } 815 return out, nil 816 } 817 818 // getMoreServiceMain get more service main 819 func getMoreServiceMain(queryHandler QueryHandler, mtime time.Time, 820 firstUpdate, disableBusiness bool) (map[string]*model.Service, error) { 821 var args []interface{} 822 args = append(args, timeToTimestamp(mtime)) 823 str := genServiceSelectSQL() + " from service where service.mtime >= FROM_UNIXTIME(?)" 824 if disableBusiness { 825 str += " and service.namespace = ?" 826 args = append(args, SystemNamespace) 827 } 828 if firstUpdate { 829 str += " and flag != 1" 830 } 831 rows, err := queryHandler(str, args...) 832 if err != nil { 833 log.Errorf("[Store][database] get more services query err: %s", err.Error()) 834 return nil, err 835 } 836 out := make(map[string]*model.Service) 837 err = callFetchServiceRows(rows, func(entry *model.Service) (b bool, e error) { 838 out[entry.ID] = entry 839 return true, nil 840 }) 841 if err != nil { 842 log.Errorf("[Store][database] call fetch service rows err: %s", err.Error()) 843 return nil, err 844 } 845 846 return out, nil 847 } 848 849 // batchQueryServiceMeta 批量查询service meta的封装 850 func batchQueryServiceMeta(handler QueryHandler, services []interface{}) (*sql.Rows, error) { 851 if len(services) == 0 { 852 return nil, nil 853 } 854 855 str := "select `id`, `mkey`, `mvalue` from service_metadata where id in(" 856 first := true 857 args := make([]interface{}, 0, len(services)) 858 for _, ele := range services { 859 if first { 860 str += "?" 861 first = false 862 } else { 863 str += ",?" 864 } 865 args = append(args, ele.(*model.Service).ID) 866 } 867 str += ")" 868 869 rows, err := handler(str, args...) 870 if err != nil { 871 log.Errorf("[Store][database] batch query service meta err: %s", err.Error()) 872 return nil, err 873 } 874 875 return rows, nil 876 } 877 878 // fetchMoreServiceMeta fetch more service meta 879 func fetchMoreServiceMeta(services map[string]*model.Service, rows *sql.Rows) error { 880 err := callFetchServiceMetaRows(rows, func(id, key, value string) (b bool, e error) { 881 service, ok := services[id] 882 if !ok { 883 return true, nil 884 } 885 if service.Meta == nil { 886 service.Meta = make(map[string]string) 887 } 888 service.Meta[key] = value 889 return true, nil 890 }) 891 if err != nil { 892 log.Errorf("[Store][database] call fetch service meta rows err: %s", err.Error()) 893 return err 894 } 895 896 return nil 897 } 898 899 // callFetchServiceMetaRows 获取metadata的回调 900 func callFetchServiceMetaRows(rows *sql.Rows, handler func(id, key, value string) (bool, error)) error { 901 if rows == nil { 902 return nil 903 } 904 defer rows.Close() 905 906 var id, key, value string 907 progress := 0 908 for rows.Next() { 909 progress++ 910 if progress%100000 == 0 { 911 log.Infof("[Store][database] fetch service meta rows progress: %d", progress) 912 } 913 if err := rows.Scan(&id, &key, &value); err != nil { 914 log.Errorf("[Store][database] multi get service metadata scan err: %s", err.Error()) 915 return err 916 } 917 ok, err := handler(id, key, value) 918 if err != nil { 919 return err 920 } 921 if !ok { 922 return nil 923 } 924 } 925 if err := rows.Err(); err != nil { 926 return err 927 } 928 return nil 929 } 930 931 // addServiceMain 增加service主表数据 932 func addServiceMain(tx *BaseTx, s *model.Service) error { 933 // 先把主表填充 934 insertStmt := ` 935 insert into service 936 (id, name, namespace, ports, business, department, cmdb_mod1, cmdb_mod2, 937 cmdb_mod3, comment, token, reference, platform_id, revision, owner, ctime, mtime) 938 values 939 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, sysdate(), sysdate())` 940 941 _, err := tx.Exec(insertStmt, s.ID, s.Name, s.Namespace, s.Ports, s.Business, s.Department, 942 s.CmdbMod1, s.CmdbMod2, s.CmdbMod3, s.Comment, s.Token, 943 s.Reference, s.PlatformID, s.Revision, s.Owner) 944 return err 945 } 946 947 // addServiceMeta 增加服务metadata 948 func addServiceMeta(tx *BaseTx, id string, meta map[string]string) error { 949 if len(meta) == 0 { 950 return nil 951 } 952 str := "insert into service_metadata(id, `mkey`, `mvalue`, `ctime`, `mtime`) values " 953 cnt := 0 954 args := make([]interface{}, 0, len(meta)*3) 955 for key, value := range meta { 956 cnt++ 957 if cnt == len(meta) { 958 str += "(?, ?, ?, sysdate(), sysdate())" 959 } else { 960 str += "(?, ?, ?, sysdate(), sysdate())," 961 } 962 963 args = append(args, id) 964 args = append(args, key) 965 args = append(args, value) 966 } 967 968 // log.Infof("str: %s, args: %+v", str, args) 969 _, err := tx.Exec(str, args...) 970 return err 971 } 972 973 // updateServiceMain 更新service主表 974 func updateServiceMain(tx *BaseTx, service *model.Service) error { 975 str := `update service set name = ?, namespace = ?, ports = ?, business = ?, 976 department = ?, cmdb_mod1 = ?, cmdb_mod2 = ?, cmdb_mod3 = ?, comment = ?, token = ?, platform_id = ?, 977 revision = ?, owner = ?, mtime = sysdate() where id = ?` 978 979 _, err := tx.Exec(str, service.Name, service.Namespace, service.Ports, service.Business, 980 service.Department, service.CmdbMod1, service.CmdbMod2, service.CmdbMod3, 981 service.Comment, service.Token, service.PlatformID, service.Revision, service.Owner, service.ID) 982 return err 983 } 984 985 // updateServiceMeta 更新service meta表 986 func updateServiceMeta(tx *BaseTx, id string, meta map[string]string) error { 987 // 只有metadata为nil的时候,则不用处理。 988 // 如果metadata不为nil,但是len(metadata) == 0,则代表删除metadata 989 if meta == nil { 990 return nil 991 } 992 993 str := "delete from service_metadata where id = ?" 994 if _, err := tx.Exec(str, id); err != nil { 995 return err 996 } 997 998 return addServiceMeta(tx, id, meta) 999 } 1000 1001 // fetchServiceMeta 从rows里面获取metadata数据 1002 func fetchServiceMeta(rows *sql.Rows) (map[string]string, error) { 1003 if rows == nil { 1004 return nil, nil 1005 } 1006 defer rows.Close() 1007 1008 out := make(map[string]string) 1009 var key, value string 1010 for rows.Next() { 1011 1012 if err := rows.Scan(&key, &value); err != nil { 1013 log.Errorf("[Store][database] fetch service meta err: %s", err.Error()) 1014 return nil, err 1015 } 1016 out[key] = value 1017 } 1018 if err := rows.Err(); err != nil { 1019 log.Errorf("[Store][database] service metadata rows err: %s", err.Error()) 1020 return nil, err 1021 } 1022 1023 return out, nil 1024 } 1025 1026 // genServiceSelectSQL 生成service查询语句 1027 func genServiceSelectSQL() string { 1028 return `select service.id, name, namespace, IFNULL(business, ""), IFNULL(comment, ""), 1029 token, service.revision, owner, service.flag, 1030 UNIX_TIMESTAMP(service.ctime), UNIX_TIMESTAMP(service.mtime), 1031 IFNULL(ports, ""), IFNULL(department, ""), IFNULL(cmdb_mod1, ""), IFNULL(cmdb_mod2, ""), 1032 IFNULL(cmdb_mod3, ""), IFNULL(reference, ""), IFNULL(refer_filter, ""), IFNULL(platform_id, "") ` 1033 } 1034 1035 // callFetchServiceRows call fetch service rows 1036 func callFetchServiceRows(rows *sql.Rows, callback func(entry *model.Service) (bool, error)) error { 1037 if rows == nil { 1038 return nil 1039 } 1040 defer rows.Close() 1041 1042 var ctime, mtime int64 1043 var flag int 1044 progress := 0 1045 for rows.Next() { 1046 progress++ 1047 if progress%100000 == 0 { 1048 log.Infof("[Store][database] services row next progress: %d", progress) 1049 } 1050 1051 var item model.Service 1052 err := rows.Scan( 1053 &item.ID, &item.Name, &item.Namespace, &item.Business, &item.Comment, 1054 &item.Token, &item.Revision, &item.Owner, &flag, &ctime, &mtime, &item.Ports, 1055 &item.Department, &item.CmdbMod1, &item.CmdbMod2, &item.CmdbMod3, 1056 &item.Reference, &item.ReferFilter, &item.PlatformID) 1057 1058 if err != nil { 1059 log.Errorf("[Store][database] fetch service rows scan err: %s", err.Error()) 1060 return err 1061 } 1062 1063 item.CreateTime = time.Unix(ctime, 0) 1064 item.ModifyTime = time.Unix(mtime, 0) 1065 item.Valid = true 1066 if flag == 1 { 1067 item.Valid = false 1068 } 1069 ok, err := callback(&item) 1070 if err != nil { 1071 return err 1072 } 1073 if !ok { 1074 return nil 1075 } 1076 } 1077 if err := rows.Err(); err != nil { 1078 log.Errorf("[Store][database] fetch service rows next err: %s", err.Error()) 1079 return err 1080 } 1081 return nil 1082 } 1083 1084 // fetchServiceRows 获取service rows里面的数据 1085 func fetchServiceRows(rows *sql.Rows) ([]*model.Service, error) { 1086 var out []*model.Service 1087 err := callFetchServiceRows(rows, func(entry *model.Service) (b bool, e error) { 1088 out = append(out, entry) 1089 return true, nil 1090 }) 1091 if err != nil { 1092 return nil, err 1093 } 1094 1095 return out, nil 1096 } 1097 1098 // filterInstance 查找service,根据instance属性过滤 1099 // 生成子查询语句 1100 func filterInstance(filters *store.InstanceArgs) (string, []interface{}) { 1101 var args []interface{} 1102 str := "(select service_id from instance where instance.flag != 1 and host in (" + 1103 PlaceholdersN(len(filters.Hosts)) + ")" 1104 if len(filters.Ports) > 0 { 1105 str += " and port in (" + PlaceholdersN(len(filters.Ports)) + ")" 1106 } 1107 str += " group by service_id)" 1108 for _, host := range filters.Hosts { 1109 args = append(args, host) 1110 } 1111 for _, port := range filters.Ports { 1112 args = append(args, port) 1113 } 1114 return str, args 1115 } 1116 1117 // filterMetadata 查找service,根据metadata属性过滤 1118 // 生成子查询语句 1119 // 多个metadata,取交集(and) 1120 func filterMetadata(metas map[string]string) (string, []interface{}) { 1121 str := "(select id from service_metadata where mkey = ? and mvalue = ?)" 1122 args := make([]interface{}, 0, 2) 1123 for key, value := range metas { 1124 args = append(args, key) 1125 args = append(args, value) 1126 } 1127 1128 return str, args 1129 } 1130 1131 // GetServicesBatch 查询多个服务的id 1132 func (ss *serviceStore) GetServicesBatch(services []*model.Service) ([]*model.Service, error) { 1133 if len(services) == 0 { 1134 return nil, nil 1135 } 1136 str := `select id, name, namespace,owner from service where flag = 0 and (name, namespace) in (` 1137 args := make([]interface{}, 0, len(services)*2) 1138 for key, value := range services { 1139 str += "(" + PlaceholdersN(2) + ")" 1140 if key != len(services)-1 { 1141 str += "," 1142 } 1143 args = append(args, value.Name) 1144 args = append(args, value.Namespace) 1145 } 1146 str += `)` 1147 1148 rows, err := ss.master.Query(str, args...) 1149 if err != nil { 1150 log.Errorf("[Store][database] query services batch err: %s", err.Error()) 1151 return nil, err 1152 } 1153 1154 res := make([]*model.Service, 0, len(services)) 1155 var namespace, name, id, owner string 1156 for rows.Next() { 1157 err := rows.Scan(&id, &name, &namespace, &owner) 1158 if err != nil { 1159 log.Errorf("[Store][database] fetch services batch scan err: %s", err.Error()) 1160 return nil, err 1161 } 1162 res = append(res, &model.Service{ 1163 ID: id, 1164 Name: name, 1165 Namespace: namespace, 1166 Owner: owner, 1167 }) 1168 } 1169 if err := rows.Err(); err != nil { 1170 log.Errorf("[Store][database] fetch services batch next err: %s", err.Error()) 1171 return nil, err 1172 } 1173 return res, nil 1174 } 1175 1176 // addOwnerServiceMap 填充owner_service_map表 1177 func addOwnerServiceMap(tx *BaseTx, service, namespace, owner string) error { 1178 addSql := "insert into owner_service_map(id,owner,service,namespace) values" 1179 1180 // 根据; ,进行分割 1181 owners := strings.FieldsFunc(owner, func(r rune) bool { 1182 return r == ';' || r == ',' 1183 }) 1184 args := make([]interface{}, 0) 1185 1186 if len(owners) >= 1 { 1187 for i := 0; i < len(owners); i++ { 1188 addSql += "(?,?,?,?)," 1189 args = append(args, utils.NewUUID(), owners[i], service, namespace) 1190 } 1191 if len(args) != 0 { 1192 addSql = strings.TrimSuffix(addSql, ",") 1193 if _, err := tx.Exec(addSql, args...); err != nil { 1194 return err 1195 } 1196 } 1197 } 1198 return nil 1199 } 1200 1201 // deleteOwnerServiceMap 删除owner_service_map表中对应记录 1202 func deleteOwnerServiceMap(tx *BaseTx, service, namespace string) error { 1203 log.Infof("[Store][database] delete service(%s) namespace(%s)", service, namespace) 1204 delSql := "delete from owner_service_map where service=? and namespace=?" 1205 if _, err := tx.Exec(delSql, service, namespace); err != nil { 1206 return err 1207 } 1208 1209 return nil 1210 } 1211 1212 // updateOwnerServiceMap owner_service_map表,先删除,后填充 1213 func updateOwnerServiceMap(tx *BaseTx, service, namespace, owner string) error { 1214 // 删除 1215 if err := deleteOwnerServiceMap(tx, service, namespace); err != nil { 1216 return err 1217 } 1218 // 填充 1219 if err := addOwnerServiceMap(tx, service, namespace, owner); err != nil { 1220 return err 1221 } 1222 1223 return nil 1224 }