github.com/polarismesh/polaris@v1.17.8/store/boltdb/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 boltdb 19 20 import ( 21 "database/sql" 22 "errors" 23 "sort" 24 "strconv" 25 "strings" 26 "time" 27 28 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 29 "go.uber.org/zap" 30 31 "github.com/polarismesh/polaris/common/model" 32 "github.com/polarismesh/polaris/common/utils" 33 "github.com/polarismesh/polaris/store" 34 ) 35 36 type serviceStore struct { 37 handler BoltHandler 38 } 39 40 var ( 41 ErrMultipleSvcFound = errors.New("multiple service find") 42 ) 43 44 const ( 45 tblNameService string = "service" 46 SvcFieldID string = "ID" 47 SvcFieldName string = "Name" 48 SvcFieldNamespace string = "Namespace" 49 SvcFieldBusiness string = "Business" 50 SvcFieldPorts string = "Ports" 51 SvcFieldMeta string = "Meta" 52 SvcFieldComment string = "Comment" 53 SvcFieldDepartment string = "Department" 54 SvcFieldModifyTime string = "ModifyTime" 55 SvcFieldToken string = "Token" 56 SvcFieldOwner string = "Owner" 57 SvcFieldRevision string = "Revision" 58 SvcFieldReference string = "Reference" 59 SvcFieldValid string = "Valid" 60 SvcFieldCmdbMod1 string = "CmdbMod1" 61 SvcFieldCmdbMod2 string = "CmdbMod2" 62 SvcFieldCmdbMod3 string = "CmdbMod3" 63 ) 64 65 // AddService save a service 66 func (ss *serviceStore) AddService(s *model.Service) error { 67 68 // 删除之前同名的服务 69 if err := ss.cleanInValidService(s.Name, s.Namespace); err != nil { 70 return err 71 } 72 73 initService(s) 74 75 if s.ID == "" || s.Name == "" || s.Namespace == "" { 76 return store.NewStatusError(store.EmptyParamsErr, "add Service missing some params") 77 } 78 79 err := ss.handler.SaveValue(tblNameService, s.ID, s) 80 81 return store.Error(err) 82 } 83 84 // DeleteService delete a service 85 func (ss *serviceStore) DeleteService(id, serviceName, namespaceName string) error { 86 if id == "" { 87 return store.NewStatusError(store.EmptyParamsErr, "delete Service missing some params") 88 } 89 90 properties := make(map[string]interface{}) 91 properties[SvcFieldValid] = false 92 properties[SvcFieldModifyTime] = time.Now() 93 94 err := ss.handler.UpdateValue(tblNameService, id, properties) 95 return store.Error(err) 96 } 97 98 // DeleteServiceAlias delete a service alias 99 func (ss *serviceStore) DeleteServiceAlias(name string, namespace string) error { 100 if name == "" || namespace == "" { 101 return store.NewStatusError(store.EmptyParamsErr, "delete Service alias missing some params") 102 } 103 104 svc, err := ss.getServiceByNameAndNs(name, namespace) 105 if err != nil { 106 log.Error("[Store][boltdb] get service alias error", zap.Error(err)) 107 return err 108 } 109 if svc == nil { 110 return nil 111 } 112 113 properties := make(map[string]interface{}) 114 properties[SvcFieldValid] = false 115 properties[SvcFieldModifyTime] = time.Now() 116 117 if err = ss.handler.UpdateValue(tblNameService, svc.ID, properties); err != nil { 118 log.Errorf("[Store][boltdb] delete service alias error, %v", err) 119 } 120 121 return store.Error(err) 122 } 123 124 // UpdateServiceAlias update service alias 125 func (ss *serviceStore) UpdateServiceAlias(alias *model.Service, needUpdateOwner bool) error { 126 if alias.ID == "" || alias.Name == "" || alias.Namespace == "" || 127 alias.Revision == "" || alias.Reference == "" || (needUpdateOwner && alias.Owner == "") { 128 return store.NewStatusError(store.EmptyParamsErr, "update Service Alias missing some params") 129 } 130 131 properties := make(map[string]interface{}) 132 properties[SvcFieldName] = alias.Name 133 properties[SvcFieldNamespace] = alias.Namespace 134 properties[SvcFieldComment] = alias.Comment 135 properties[SvcFieldRevision] = alias.Revision 136 properties[SvcFieldToken] = alias.Token 137 properties[SvcFieldOwner] = alias.Owner 138 properties[SvcFieldReference] = alias.Reference 139 properties[SvcFieldModifyTime] = time.Now() 140 141 err := ss.handler.UpdateValue(tblNameService, alias.ID, properties) 142 143 return store.Error(err) 144 } 145 146 // UpdateService update service 147 func (ss *serviceStore) UpdateService(service *model.Service, needUpdateOwner bool) error { 148 if service.ID == "" || service.Name == "" || service.Namespace == "" || 149 service.Token == "" || service.Owner == "" || service.Revision == "" { 150 return store.NewStatusError(store.EmptyParamsErr, "Update Service missing some params") 151 } 152 153 properties := make(map[string]interface{}) 154 155 properties[SvcFieldName] = service.Name 156 properties[SvcFieldNamespace] = service.Namespace 157 properties[SvcFieldDepartment] = service.Department 158 properties[SvcFieldBusiness] = service.Business 159 properties[SvcFieldMeta] = service.Meta 160 properties[SvcFieldComment] = service.Comment 161 properties[SvcFieldRevision] = service.Revision 162 properties[SvcFieldToken] = service.Token 163 properties[SvcFieldOwner] = service.Owner 164 properties[SvcFieldPorts] = service.Ports 165 properties[SvcFieldReference] = service.Reference 166 properties[SvcFieldCmdbMod1] = service.CmdbMod1 167 properties[SvcFieldCmdbMod2] = service.CmdbMod2 168 properties[SvcFieldCmdbMod3] = service.CmdbMod3 169 properties[SvcFieldModifyTime] = time.Now() 170 171 err := ss.handler.UpdateValue(tblNameService, service.ID, properties) 172 173 serr := store.Error(err) 174 if store.Code(serr) == store.DuplicateEntryErr { 175 serr = store.NewStatusError(store.DataConflictErr, err.Error()) 176 } 177 return serr 178 } 179 180 // UpdateServiceToken update service token 181 func (ss *serviceStore) UpdateServiceToken(serviceID string, token string, revision string) error { 182 183 properties := make(map[string]interface{}) 184 properties[SvcFieldToken] = token 185 properties[SvcFieldRevision] = revision 186 properties[SvcFieldModifyTime] = time.Now() 187 188 err := ss.handler.UpdateValue(tblNameService, serviceID, properties) 189 190 return store.Error(err) 191 } 192 193 // GetSourceServiceToken get source service token 194 func (ss *serviceStore) GetSourceServiceToken(name string, namespace string) (*model.Service, error) { 195 var out model.Service 196 s, err := ss.getServiceByNameAndNs(name, namespace) 197 switch { 198 case err == sql.ErrNoRows: 199 return nil, nil 200 case err != nil: 201 return nil, err 202 case s == nil: 203 return nil, nil 204 default: 205 out.ID = s.ID 206 out.Token = s.Token 207 out.PlatformID = s.PlatformID 208 out.Name = name 209 out.Namespace = namespace 210 return &out, nil 211 } 212 } 213 214 // GetService get service details based on service name and namespace 215 func (ss *serviceStore) GetService(name string, namespace string) (*model.Service, error) { 216 s, err := ss.getServiceByNameAndNs(name, namespace) 217 if err != nil { 218 return nil, err 219 } 220 221 if s == nil { 222 return nil, nil 223 } 224 225 return s, nil 226 } 227 228 // GetServiceByID get service detail by service id 229 func (ss *serviceStore) GetServiceByID(id string) (*model.Service, error) { 230 service, err := ss.getServiceByID(id) 231 if err != nil { 232 return nil, err 233 } 234 235 return service, nil 236 } 237 238 // GetServices query corresponding services and numbers according to relevant conditions 239 func (ss *serviceStore) GetServices(serviceFilters, serviceMetas map[string]string, 240 instanceFilters *store.InstanceArgs, offset, limit uint32) (uint32, []*model.Service, error) { 241 242 totalCount, services, err := ss.getServices(serviceFilters, serviceMetas, instanceFilters, offset, limit) 243 if err != nil { 244 return 0, nil, err 245 } 246 247 return totalCount, services, nil 248 } 249 250 // GetServicesCount get the total number of all services 251 func (ss *serviceStore) GetServicesCount() (uint32, error) { 252 253 count, err := ss.handler.CountValues(tblNameService) 254 if err != nil { 255 log.Errorf("[Store][boltdb] load service from kv error %v", err) 256 return 0, err 257 } 258 259 return uint32(count), nil 260 } 261 262 // GetMoreServices get incremental services 263 func (ss *serviceStore) GetMoreServices( 264 mtime time.Time, firstUpdate, disableBusiness, needMeta bool) (map[string]*model.Service, error) { 265 266 fields := []string{SvcFieldModifyTime, SvcFieldValid} 267 if disableBusiness { 268 fields = append(fields, SvcFieldNamespace) 269 } 270 271 services, err := ss.handler.LoadValuesByFilter(tblNameService, fields, &model.Service{}, 272 func(m map[string]interface{}) bool { 273 if disableBusiness { 274 serviceNs, ok := m[SvcFieldNamespace] 275 if !ok { 276 return false 277 } 278 if serviceNs.(string) != SystemNamespace { 279 return false 280 } 281 } 282 283 svcMTime, ok := m[SvcFieldModifyTime] 284 if !ok { 285 return false 286 } 287 288 serviceMtime := svcMTime.(time.Time) 289 290 return !serviceMtime.Before(mtime) 291 }) 292 293 if err != nil { 294 log.Errorf("[Store][boltdb] load service from kv error, %v", err) 295 return nil, err 296 } 297 298 res := make(map[string]*model.Service) 299 for k, v := range services { 300 res[k] = v.(*model.Service) 301 } 302 303 return res, nil 304 } 305 306 // GetServiceAliases get list of service aliases 307 func (ss *serviceStore) GetServiceAliases( 308 filter map[string]string, offset uint32, limit uint32) (uint32, []*model.ServiceAlias, error) { 309 310 // find all alias service with filters 311 fields := []string{SvcFieldReference, SvcFieldValid, SvcFieldName, SvcFieldNamespace, 312 SvcFieldMeta, SvcFieldDepartment, SvcFieldBusiness} 313 for k := range filter { 314 fields = append(fields, k) 315 } 316 317 referenceService, services, err := ss.getServiceAliases(filter, fields) 318 if err != nil { 319 return 0, nil, err 320 } 321 322 // find source service for every alias 323 fields = []string{SvcFieldID, SvcFieldName, SvcFieldNamespace, SvcFieldValid} 324 325 svcName, hasSvcName := filter["service"] 326 svcNs, hasSvcNs := filter["namespace"] 327 328 refServices, err := ss.handler.LoadValuesByFilter(tblNameService, fields, &model.Service{}, 329 func(m map[string]interface{}) bool { 330 if valid, _ := m[SvcFieldValid].(bool); !valid { 331 return false 332 } 333 334 if hasSvcName && m[SvcFieldName].(string) != svcName { 335 return false 336 } 337 338 if hasSvcNs && m[SvcFieldNamespace].(string) != svcNs { 339 return false 340 } 341 342 _, ok := referenceService[m[SvcFieldID].(string)] 343 return ok 344 }) 345 346 var serviceAlias []*model.ServiceAlias 347 for _, service := range services { 348 349 if _, ok := refServices[service.Reference]; !ok { 350 continue 351 } 352 353 alias := model.ServiceAlias{} 354 alias.ID = service.ID 355 alias.Alias = service.Name 356 alias.AliasNamespace = service.Namespace 357 alias.ServiceID = service.Reference 358 alias.Service = refServices[service.Reference].(*model.Service).Name 359 alias.ModifyTime = service.ModifyTime 360 alias.CreateTime = service.CreateTime 361 alias.Comment = service.Comment 362 alias.Namespace = refServices[service.Reference].(*model.Service).Namespace 363 alias.Owner = service.Owner 364 365 serviceAlias = append(serviceAlias, &alias) 366 } 367 368 return uint32(len(serviceAlias)), doPageAliasServices(serviceAlias, offset, limit), nil 369 } 370 371 func (ss *serviceStore) getServiceAliases( 372 filter map[string]string, fields []string) (map[string]bool, map[string]*model.Service, error) { 373 aliasName, isAliasName := filter["alias"] 374 aliasNamespace, isAliasNamespace := filter["alias_namespace"] 375 keys, isKeys := filter["keys"] 376 values, isValues := filter["values"] 377 department, isDepartment := filter["department"] 378 business, isBusiness := filter["business"] 379 380 referenceService := make(map[string]bool) 381 services, err := ss.handler.LoadValuesByFilter(tblNameService, fields, &model.Service{}, 382 func(m map[string]interface{}) bool { 383 if valid, _ := m[SvcFieldValid].(bool); !valid { 384 return false 385 } 386 387 // judge whether it is alias by whether there is a reference 388 if reference, _ := m[SvcFieldReference].(string); reference == "" { 389 return false 390 } 391 392 // filter by other 393 if isAliasName { 394 svcName, _ := m[SvcFieldName].(string) 395 aliasName, isWild := utils.ParseWildName(aliasName) 396 if isWild && !strings.Contains(svcName, aliasName) { 397 return false 398 } 399 if svcName != aliasName { 400 return false 401 } 402 } 403 if isAliasNamespace { 404 svcNamespace, _ := m[SvcFieldNamespace].(string) 405 aliasNamespace, isWild := utils.ParseWildName(aliasNamespace) 406 if isWild && !strings.Contains(svcNamespace, aliasNamespace) { 407 return false 408 } 409 if svcNamespace != aliasNamespace { 410 return false 411 } 412 } 413 414 if isKeys { 415 svcMeta, ok := m[SvcFieldMeta] 416 if !ok { 417 return false 418 } 419 metaValue, ok := svcMeta.(map[string]string)[keys] 420 if !ok { 421 return false 422 } 423 if isValues && values != metaValue { 424 return false 425 } 426 } 427 428 if isDepartment { 429 svcDepartment, ok := m[SvcFieldDepartment] 430 if !ok { 431 return false 432 } 433 if department != svcDepartment.(string) { 434 return false 435 } 436 } 437 if isBusiness && business != m[SvcFieldBusiness].(string) { 438 svcBusiness, ok := m[SvcFieldBusiness] 439 if !ok { 440 return false 441 } 442 if business != svcBusiness.(string) { 443 return false 444 } 445 } 446 referenceService[m[SvcFieldReference].(string)] = true 447 return true 448 }) 449 if err != nil { 450 log.Errorf("[Store][boltdb] load service from kv error, %v", err) 451 return nil, nil, err 452 } 453 if len(services) == 0 { 454 return referenceService, map[string]*model.Service{}, nil 455 } 456 457 ret := make(map[string]*model.Service, len(services)) 458 for k := range services { 459 ret[k] = services[k].(*model.Service) 460 } 461 462 return referenceService, ret, nil 463 } 464 465 // GetSystemServices get system services 466 func (ss *serviceStore) GetSystemServices() ([]*model.Service, error) { 467 468 fields := []string{SvcFieldNamespace} 469 470 services, err := ss.handler.LoadValuesByFilter(tblNameService, fields, &model.Service{}, 471 func(m map[string]interface{}) bool { 472 svcNamespace, ok := m[SvcFieldNamespace] 473 if !ok { 474 return false 475 } 476 if svcNamespace.(string) == SystemNamespace { 477 return true 478 } 479 return false 480 }) 481 if err != nil { 482 log.Errorf("[Store][boltdb] load service from kv error, %v", err) 483 return nil, err 484 } 485 486 ret := make(map[string]*model.Service, len(services)) 487 for k := range services { 488 ret[k] = services[k].(*model.Service) 489 } 490 491 return getRealServicesList(ret, 0, uint32(len(services))), nil 492 } 493 494 // GetServicesBatch get service id and other information in batch 495 func (ss *serviceStore) GetServicesBatch(services []*model.Service) ([]*model.Service, error) { 496 497 if len(services) == 0 { 498 return nil, nil 499 } 500 501 fields := []string{SvcFieldName, SvcFieldNamespace} 502 503 serviceInfo := make(map[string]string) 504 505 for _, service := range services { 506 serviceInfo[service.Name] = service.Namespace 507 } 508 509 svcs, err := ss.handler.LoadValuesByFilter(tblNameService, fields, &model.Service{}, 510 func(m map[string]interface{}) bool { 511 512 svcName, ok := m[SvcFieldName] 513 if !ok { 514 return false 515 } 516 svcNs, ok := m[SvcFieldNamespace] 517 if !ok { 518 return false 519 } 520 521 name := svcName.(string) 522 namespace := svcNs.(string) 523 ns, ok := serviceInfo[name] 524 if !ok { 525 return false 526 } 527 if ns != namespace { 528 return false 529 } 530 return true 531 }) 532 if err != nil { 533 log.Errorf("[Store][boltdb] load service from kv error, %v", err) 534 return nil, err 535 } 536 537 ret := make(map[string]*model.Service, len(svcs)) 538 for k := range svcs { 539 ret[k] = svcs[k].(*model.Service) 540 } 541 542 return getRealServicesList(ret, 0, uint32(len(services))), nil 543 } 544 545 func (ss *serviceStore) getServiceByNameAndNs(name string, namespace string) (*model.Service, error) { 546 547 out, err := ss.getServiceByNameAndNsCommon(name, namespace, true) 548 if err != nil { 549 return nil, err 550 } 551 552 if out == nil || len(out) == 0 { 553 return nil, nil 554 } 555 556 return out[0], err 557 } 558 559 // getServiceByNameAndNsCommon 根据服务名和命名空间查询服务,支持模糊查询 560 func (ss *serviceStore) getServiceByNameAndNsCommon(name string, namespace string, forceValid bool) ( 561 []*model.Service, error) { 562 563 var out []*model.Service 564 fields := []string{svcFieldName, SvcFieldNamespace, SvcFieldValid} 565 566 isNameWild := utils.IsWildName(name) 567 isNamespaceWild := utils.IsWildName(namespace) 568 569 svcSlice, err := ss.handler.LoadValuesByFilter(tblNameService, fields, &model.Service{}, 570 func(m map[string]interface{}) bool { 571 // valid field filter 572 if forceValid { 573 valid, ok := m[SvcFieldValid] 574 if ok && !valid.(bool) { 575 return false 576 } 577 } 578 579 // service name field filter 580 svcName, ok := m[SvcFieldName] 581 if !ok { 582 return false 583 } 584 if len(name) > 0 { 585 if isNameWild { 586 if !utils.IsWildMatch(svcName.(string), name) { 587 return false 588 } 589 } else if svcName.(string) != name { 590 return false 591 } 592 } 593 594 // namespace field filter 595 svcNs, ok := m[SvcFieldNamespace] 596 if !ok { 597 return false 598 } 599 if len(namespace) > 0 { 600 if isNamespaceWild { 601 if !utils.IsWildMatch(svcNs.(string), namespace) { 602 return false 603 } 604 } else if svcNs.(string) != namespace { 605 return false 606 } 607 } 608 return true 609 }) 610 if err != nil { 611 return nil, err 612 } 613 614 if len(svcSlice) == 0 { 615 return nil, nil 616 } 617 618 out = make([]*model.Service, 0, len(svcSlice)) 619 for _, v := range svcSlice { 620 svc := v.(*model.Service) 621 if !svc.Valid { 622 continue 623 } 624 out = append(out, v.(*model.Service)) 625 } 626 if len(out) == 0 { 627 return nil, nil 628 } 629 return out, err 630 } 631 632 func (ss *serviceStore) getServiceByNameAndNsIgnoreValid(name string, namespace string) (*model.Service, error) { 633 var out *model.Service 634 635 fields := []string{SvcFieldName, SvcFieldNamespace, SvcFieldValid} 636 637 svc, err := ss.handler.LoadValuesByFilter(tblNameService, fields, &model.Service{}, 638 func(m map[string]interface{}) bool { 639 svcName, ok := m[SvcFieldName] 640 if !ok { 641 return false 642 } 643 svcNs, ok := m[SvcFieldNamespace] 644 if !ok { 645 return false 646 } 647 648 if svcName.(string) == name && svcNs.(string) == namespace { 649 return true 650 } 651 return false 652 }) 653 if err != nil { 654 return nil, err 655 } 656 657 if len(svc) > 1 { 658 log.Errorf("[Store][boltdb] multiple services found %v", svc) 659 return nil, ErrMultipleSvcFound 660 } 661 662 if len(svc) == 0 { 663 return nil, nil 664 } 665 666 // should only find one service 667 for _, v := range svc { 668 out = v.(*model.Service) 669 } 670 671 return out, err 672 } 673 674 func (ss *serviceStore) getServiceByID(id string) (*model.Service, error) { 675 676 fields := []string{SvcFieldID} 677 678 svc, err := ss.handler.LoadValuesByFilter(tblNameService, fields, &model.Service{}, 679 func(m map[string]interface{}) bool { 680 svcId, ok := m[SvcFieldID] 681 if !ok { 682 return false 683 } 684 if svcId.(string) != id { 685 return false 686 } 687 return true 688 }) 689 if err != nil { 690 return nil, err 691 } 692 693 if len(svc) > 1 { 694 log.Errorf("[Store][boltdb] multiple services found %v", svc) 695 return nil, ErrMultipleSvcFound 696 } 697 698 svcRet := svc[id].(*model.Service) 699 if svcRet.Valid { 700 return svcRet, nil 701 } 702 703 return nil, err 704 } 705 706 func (ss *serviceStore) getServices(serviceFilters, serviceMetas map[string]string, 707 instanceFilters *store.InstanceArgs, offset, limit uint32) (uint32, []*model.Service, error) { 708 709 insFiltersIds := make(map[string]bool) 710 // int array to string array 711 if instanceFilters != nil && (len(instanceFilters.Ports) > 0 || len(instanceFilters.Hosts) > 0) { 712 713 portArray := make([]string, len(instanceFilters.Ports)) 714 for i, port := range instanceFilters.Ports { 715 portArray[i] = strconv.Itoa(int(port)) 716 } 717 718 // get the filtered list of serviceIDs from instanceFilters 719 filter := []string{insFieldProto, insFieldValid} 720 721 inss, err := ss.handler.LoadValuesByFilter(tblNameInstance, filter, &model.Instance{}, 722 func(m map[string]interface{}) bool { 723 valid, ok := m[SvcFieldValid] 724 if ok && !valid.(bool) { 725 return false 726 } 727 insPorto, ok := m[insFieldProto] 728 if !ok { 729 return false 730 } 731 ins := insPorto.(*apiservice.Instance) 732 insHost := ins.GetHost().GetValue() 733 insPort := ins.GetPort().GetValue() 734 735 if len(instanceFilters.Hosts) > 0 { 736 ifFound := false 737 for _, h := range instanceFilters.Hosts { 738 if h == insHost { 739 ifFound = true 740 break 741 } 742 } 743 if !ifFound { 744 return false 745 } 746 } 747 if len(instanceFilters.Ports) > 0 { 748 ifFound := false 749 for _, p := range instanceFilters.Ports { 750 if p == insPort { 751 ifFound = true 752 break 753 } 754 } 755 if !ifFound { 756 return false 757 } 758 } 759 return true 760 }) 761 if err != nil { 762 log.Errorf("[Store][boltdb] load instance from kv error %v", err) 763 return 0, nil, err 764 } 765 for _, i := range inss { 766 insFiltersIds[i.(*model.Instance).ServiceID] = true 767 } 768 } 769 770 fields := []string{SvcFieldValid, SvcFieldNamespace, SvcFieldName, SvcFieldMeta, SvcFieldDepartment, 771 SvcFieldBusiness, SvcFieldReference} 772 if len(insFiltersIds) > 0 { 773 fields = append(fields, SvcFieldID) 774 } 775 776 isKeys := true 777 isValues := true 778 var keys string 779 var values string 780 781 if len(serviceMetas) == 0 { 782 isKeys = false 783 isValues = false 784 } else { 785 for k, v := range serviceMetas { 786 keys = k 787 values = v 788 if values == "" { 789 isValues = false 790 } 791 break 792 } 793 } 794 795 name, isName := serviceFilters["name"] 796 department, isDepartment := serviceFilters["department"] 797 business, isBusiness := serviceFilters["business"] 798 namespace, isNamespace := serviceFilters["namespace"] 799 800 svcs, err := ss.handler.LoadValuesByFilter(tblNameService, fields, &model.Service{}, 801 func(m map[string]interface{}) bool { 802 valid, ok := m[SvcFieldValid] 803 if ok && !valid.(bool) { 804 return false 805 } 806 // filter by id 807 if len(insFiltersIds) > 0 { 808 svcId, ok := m[SvcFieldID] 809 if !ok { 810 return false 811 } 812 _, ok = insFiltersIds[svcId.(string)] 813 if !ok { 814 return false 815 } 816 } 817 818 if isNamespace && namespace != "" { 819 svcNs, ok := m[SvcFieldNamespace] 820 if !ok { 821 return false 822 } 823 if utils.IsPrefixWildName(namespace) { 824 return strings.Contains(svcNs.(string), namespace[0:len(namespace)-1]) 825 } 826 if svcNs.(string) != namespace { 827 return false 828 } 829 } 830 831 // filter by other 832 if isName && name != "" { 833 svcName, ok := m[SvcFieldName] 834 if !ok { 835 return false 836 } 837 if utils.IsPrefixWildName(name) { 838 return strings.Contains(svcName.(string), name[0:len(name)-1]) 839 } 840 if svcName.(string) != name { 841 return false 842 } 843 } 844 845 if isKeys { 846 svcMeta, ok := m[SvcFieldMeta] 847 if !ok { 848 return false 849 } 850 metaValue, ok := svcMeta.(map[string]string)[keys] 851 if !ok { 852 return false 853 } 854 if isValues && values != metaValue { 855 return false 856 } 857 } 858 859 if isDepartment && department != "" { 860 svcDepartment, ok := m[SvcFieldDepartment] 861 if !ok { 862 return false 863 } 864 if utils.IsPrefixWildName(department) { 865 return strings.Contains(svcDepartment.(string), department[0:len(department)-1]) 866 } 867 if svcDepartment.(string) != department { 868 return false 869 } 870 } 871 872 if isBusiness && business != "" { 873 svcBusiness, ok := m[SvcFieldBusiness] 874 if !ok { 875 return false 876 } 877 if utils.IsPrefixWildName(business) { 878 return strings.Contains(svcBusiness.(string), business[0:len(business)-1]) 879 } 880 if svcBusiness.(string) != business { 881 return false 882 } 883 } 884 885 return true 886 }) 887 if err != nil { 888 log.Errorf("[Store][boltdb] load service from kv error %v", err) 889 return 0, nil, err 890 } 891 totalCount := len(svcs) 892 893 ret := make(map[string]*model.Service, len(svcs)) 894 for k := range svcs { 895 ret[k] = svcs[k].(*model.Service) 896 } 897 898 return uint32(totalCount), getRealServicesList(ret, offset, limit), nil 899 } 900 901 func (ss *serviceStore) cleanInValidService(name, namespace string) error { 902 old, err := ss.getServiceByNameAndNsIgnoreValid(name, namespace) 903 904 if err != nil { 905 return err 906 } 907 908 if old == nil { 909 return nil 910 } 911 912 if err := ss.handler.DeleteValues(tblNameService, []string{old.ID}); err != nil { 913 log.Errorf("[Store][boltdb] delete invalid service error, %+v", err) 914 return err 915 } 916 917 return nil 918 } 919 920 func (ss *serviceStore) GetServiceByNameAndNamespace(name string, namespace string) ([]*model.Service, error) { 921 return ss.getServiceByNameAndNsCommon(name, namespace, true) 922 } 923 924 func getRealServicesList(originServices map[string]*model.Service, offset, limit uint32) []*model.Service { 925 services := make([]*model.Service, 0) 926 beginIndex := offset 927 endIndex := beginIndex + limit 928 totalCount := uint32(len(originServices)) 929 // handle special offset, limit 930 if totalCount == 0 { 931 return services 932 } 933 if beginIndex >= endIndex { 934 return services 935 } 936 if beginIndex >= totalCount { 937 return services 938 } 939 if endIndex > totalCount { 940 endIndex = totalCount 941 } 942 943 for _, s := range originServices { 944 services = append(services, s) 945 } 946 947 sort.Slice(services, func(i, j int) bool { 948 // sort by modifyTime 949 if services[i].ModifyTime.After(services[j].ModifyTime) { 950 return true 951 } else if services[i].ModifyTime.Before(services[j].ModifyTime) { 952 return false 953 } else { 954 // compare id if modifyTime is the same 955 return services[i].ID < services[j].ID 956 } 957 }) 958 959 return services[beginIndex:endIndex] 960 } 961 962 func doPageAliasServices(originServices []*model.ServiceAlias, offset, limit uint32) []*model.ServiceAlias { 963 services := make([]*model.ServiceAlias, 0) 964 beginIndex := offset 965 endIndex := beginIndex + limit 966 totalCount := uint32(len(originServices)) 967 // handle special offset, limit 968 if totalCount == 0 { 969 return services 970 } 971 if beginIndex >= endIndex { 972 return services 973 } 974 if beginIndex >= totalCount { 975 return services 976 } 977 if endIndex > totalCount { 978 endIndex = totalCount 979 } 980 981 services = append(services, originServices...) 982 sort.Slice(services, func(i, j int) bool { 983 // sort by modifyTime 984 if services[i].ModifyTime.After(services[j].ModifyTime) { 985 return true 986 } else if services[i].ModifyTime.Before(services[j].ModifyTime) { 987 return false 988 } else { 989 // compare id if modifyTime is the same 990 return services[i].ID < services[j].ID 991 } 992 }) 993 994 return services[beginIndex:endIndex] 995 } 996 997 func initService(s *model.Service) { 998 current := time.Now() 999 if s != nil { 1000 s.CreateTime = current 1001 s.ModifyTime = current 1002 s.Valid = true 1003 } 1004 }