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  }