dubbo.apache.org/dubbo-go/v3@v3.1.1/config/service_config.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package config 19 20 import ( 21 "container/list" 22 "fmt" 23 "net/url" 24 "os" 25 "strconv" 26 "strings" 27 "sync" 28 "time" 29 ) 30 31 import ( 32 "github.com/creasty/defaults" 33 34 "github.com/dubbogo/gost/log/logger" 35 gxnet "github.com/dubbogo/gost/net" 36 37 perrors "github.com/pkg/errors" 38 39 "go.uber.org/atomic" 40 ) 41 42 import ( 43 "dubbo.apache.org/dubbo-go/v3/common" 44 "dubbo.apache.org/dubbo-go/v3/common/constant" 45 "dubbo.apache.org/dubbo-go/v3/common/extension" 46 "dubbo.apache.org/dubbo-go/v3/protocol" 47 "dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper" 48 ) 49 50 // ServiceConfig is the configuration of the service provider 51 type ServiceConfig struct { 52 id string 53 Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` 54 ProtocolIDs []string `yaml:"protocol-ids" json:"protocol-ids,omitempty" property:"protocol-ids"` // multi protocolIDs support, split by ',' 55 Interface string `yaml:"interface" json:"interface,omitempty" property:"interface"` 56 RegistryIDs []string `yaml:"registry-ids" json:"registry-ids,omitempty" property:"registry-ids"` 57 Cluster string `default:"failover" yaml:"cluster" json:"cluster,omitempty" property:"cluster"` 58 Loadbalance string `default:"random" yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` 59 Group string `yaml:"group" json:"group,omitempty" property:"group"` 60 Version string `yaml:"version" json:"version,omitempty" property:"version" ` 61 Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` 62 Warmup string `yaml:"warmup" json:"warmup,omitempty" property:"warmup"` 63 Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"` 64 Serialization string `yaml:"serialization" json:"serialization" property:"serialization"` 65 Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` 66 Token string `yaml:"token" json:"token,omitempty" property:"token"` 67 AccessLog string `yaml:"accesslog" json:"accesslog,omitempty" property:"accesslog"` 68 TpsLimiter string `yaml:"tps.limiter" json:"tps.limiter,omitempty" property:"tps.limiter"` 69 TpsLimitInterval string `yaml:"tps.limit.interval" json:"tps.limit.interval,omitempty" property:"tps.limit.interval"` 70 TpsLimitRate string `yaml:"tps.limit.rate" json:"tps.limit.rate,omitempty" property:"tps.limit.rate"` 71 TpsLimitStrategy string `yaml:"tps.limit.strategy" json:"tps.limit.strategy,omitempty" property:"tps.limit.strategy"` 72 TpsLimitRejectedHandler string `yaml:"tps.limit.rejected.handler" json:"tps.limit.rejected.handler,omitempty" property:"tps.limit.rejected.handler"` 73 ExecuteLimit string `yaml:"execute.limit" json:"execute.limit,omitempty" property:"execute.limit"` 74 ExecuteLimitRejectedHandler string `yaml:"execute.limit.rejected.handler" json:"execute.limit.rejected.handler,omitempty" property:"execute.limit.rejected.handler"` 75 Auth string `yaml:"auth" json:"auth,omitempty" property:"auth"` 76 NotRegister bool `yaml:"not_register" json:"not_register,omitempty" property:"not_register"` 77 ParamSign string `yaml:"param.sign" json:"param.sign,omitempty" property:"param.sign"` 78 Tag string `yaml:"tag" json:"tag,omitempty" property:"tag"` 79 TracingKey string `yaml:"tracing-key" json:"tracing-key,omitempty" propertiy:"tracing-key"` 80 81 RCProtocolsMap map[string]*ProtocolConfig 82 RCRegistriesMap map[string]*RegistryConfig 83 ProxyFactoryKey string 84 adaptiveService bool 85 metricsEnable bool // whether append metrics filter to filter chain 86 unexported *atomic.Bool 87 exported *atomic.Bool 88 export bool // a flag to control whether the current service should export or not 89 rpcService common.RPCService 90 cacheMutex sync.Mutex 91 cacheProtocol protocol.Protocol 92 exportersLock sync.Mutex 93 exporters []protocol.Exporter 94 95 metadataType string 96 } 97 98 // Prefix returns dubbo.service.${InterfaceName}. 99 func (s *ServiceConfig) Prefix() string { 100 return strings.Join([]string{constant.ServiceConfigPrefix, s.id}, ".") 101 } 102 103 func (s *ServiceConfig) Init(rc *RootConfig) error { 104 if err := initProviderMethodConfig(s); err != nil { 105 return err 106 } 107 if err := defaults.Set(s); err != nil { 108 return err 109 } 110 s.exported = atomic.NewBool(false) 111 s.metadataType = rc.Application.MetadataType 112 if s.Filter == "" { 113 s.Filter = rc.Provider.Filter 114 } 115 if s.Version == "" { 116 s.Version = rc.Application.Version 117 } 118 if s.Group == "" { 119 s.Group = rc.Application.Group 120 } 121 s.unexported = atomic.NewBool(false) 122 if len(s.RCRegistriesMap) == 0 { 123 s.RCRegistriesMap = rc.Registries 124 } 125 if len(s.RCProtocolsMap) == 0 { 126 s.RCProtocolsMap = rc.Protocols 127 } 128 if rc.Provider != nil { 129 s.ProxyFactoryKey = rc.Provider.ProxyFactory 130 } 131 s.RegistryIDs = translateIds(s.RegistryIDs) 132 if len(s.RegistryIDs) <= 0 { 133 s.RegistryIDs = rc.Provider.RegistryIDs 134 } 135 136 s.ProtocolIDs = translateIds(s.ProtocolIDs) 137 if len(s.ProtocolIDs) <= 0 { 138 s.ProtocolIDs = rc.Provider.ProtocolIDs 139 } 140 if len(s.ProtocolIDs) <= 0 { 141 for k := range rc.Protocols { 142 s.ProtocolIDs = append(s.ProtocolIDs, k) 143 } 144 } 145 if s.TracingKey == "" { 146 s.TracingKey = rc.Provider.TracingKey 147 } 148 if rc.Metric.Enable != nil { 149 s.metricsEnable = *rc.Metric.Enable 150 } 151 err := s.check() 152 if err != nil { 153 panic(err) 154 } 155 s.export = true 156 return verify(s) 157 } 158 159 func (s *ServiceConfig) check() error { 160 // check if the limiter has been imported 161 if s.TpsLimiter != "" { 162 _, err := extension.GetTpsLimiter(s.TpsLimiter) 163 if err != nil { 164 panic(err) 165 } 166 } 167 if s.TpsLimitStrategy != "" { 168 _, err := extension.GetTpsLimitStrategyCreator(s.TpsLimitStrategy) 169 if err != nil { 170 panic(err) 171 } 172 } 173 if s.TpsLimitRejectedHandler != "" { 174 _, err := extension.GetRejectedExecutionHandler(s.TpsLimitRejectedHandler) 175 if err != nil { 176 panic(err) 177 } 178 } 179 180 if s.TpsLimitInterval != "" { 181 tpsLimitInterval, err := strconv.ParseInt(s.TpsLimitInterval, 0, 0) 182 if err != nil { 183 return fmt.Errorf("[ServiceConfig] Cannot parse the configuration tps.limit.interval for service %s, please check your configuration", s.Interface) 184 } 185 if tpsLimitInterval < 0 { 186 return fmt.Errorf("[ServiceConfig] The configuration tps.limit.interval for service %s must be positive, please check your configuration", s.Interface) 187 } 188 } 189 190 if s.TpsLimitRate != "" { 191 tpsLimitRate, err := strconv.ParseInt(s.TpsLimitRate, 0, 0) 192 if err != nil { 193 return fmt.Errorf("[ServiceConfig] Cannot parse the configuration tps.limit.rate for service %s, please check your configuration", s.Interface) 194 } 195 if tpsLimitRate < 0 { 196 return fmt.Errorf("[ServiceConfig] The configuration tps.limit.rate for service %s must be positive, please check your configuration", s.Interface) 197 } 198 } 199 return nil 200 } 201 202 // InitExported will set exported as false atom bool 203 func (s *ServiceConfig) InitExported() { 204 s.exported = atomic.NewBool(false) 205 } 206 207 // IsExport will return whether the service config is exported or not 208 func (s *ServiceConfig) IsExport() bool { 209 return s.exported.Load() 210 } 211 212 // Get Random Port 213 func getRandomPort(protocolConfigs []*ProtocolConfig) *list.List { 214 ports := list.New() 215 for _, proto := range protocolConfigs { 216 if port, err := strconv.Atoi(proto.Port); err != nil { 217 logger.Infof( 218 "%s will be assgined to a random port, since the port is an invalid number", 219 proto.Name, 220 ) 221 } else if port > 0 { 222 continue 223 } 224 225 tcp, err := gxnet.ListenOnTCPRandomPort(proto.Ip) 226 if err != nil { 227 panic(perrors.New(fmt.Sprintf("Get tcp port error, err is {%v}", err))) 228 } 229 defer tcp.Close() 230 ports.PushBack(strings.Split(tcp.Addr().String(), ":")[1]) 231 } 232 return ports 233 } 234 235 // Export exports the service 236 func (s *ServiceConfig) Export() error { 237 // TODO: delay export 238 if s.unexported != nil && s.unexported.Load() { 239 err := perrors.Errorf("The service %v has already unexported!", s.Interface) 240 logger.Errorf(err.Error()) 241 return err 242 } 243 if s.exported != nil && s.exported.Load() { 244 logger.Warnf("The service %v has already exported!", s.Interface) 245 return nil 246 } 247 248 regUrls := make([]*common.URL, 0) 249 if !s.NotRegister { 250 regUrls = loadRegistries(s.RegistryIDs, s.RCRegistriesMap, common.PROVIDER) 251 } 252 253 urlMap := s.getUrlMap() 254 protocolConfigs := loadProtocol(s.ProtocolIDs, s.RCProtocolsMap) 255 if len(protocolConfigs) == 0 { 256 logger.Warnf("The service %v's '%v' protocols don't has right protocolConfigs, Please check your configuration center and transfer protocol ", s.Interface, s.ProtocolIDs) 257 return nil 258 } 259 260 ports := getRandomPort(protocolConfigs) 261 nextPort := ports.Front() 262 proxyFactory := extension.GetProxyFactory(s.ProxyFactoryKey) 263 for _, proto := range protocolConfigs { 264 // registry the service reflect 265 methods, err := common.ServiceMap.Register(s.Interface, proto.Name, s.Group, s.Version, s.rpcService) 266 if err != nil { 267 formatErr := perrors.Errorf("The service %v export the protocol %v error! Error message is %v.", 268 s.Interface, proto.Name, err.Error()) 269 logger.Errorf(formatErr.Error()) 270 return formatErr 271 } 272 273 port := proto.Port 274 if num, err := strconv.Atoi(proto.Port); err != nil || num <= 0 { 275 port = nextPort.Value.(string) 276 nextPort = nextPort.Next() 277 } 278 ivkURL := common.NewURLWithOptions( 279 common.WithPath(s.Interface), 280 common.WithProtocol(proto.Name), 281 common.WithIp(proto.Ip), 282 common.WithPort(port), 283 common.WithParams(urlMap), 284 common.WithParamsValue(constant.BeanNameKey, s.id), 285 //common.WithParamsValue(constant.SslEnabledKey, strconv.FormatBool(config.GetSslEnabled())), 286 common.WithMethods(strings.Split(methods, ",")), 287 common.WithToken(s.Token), 288 common.WithParamsValue(constant.MetadataTypeKey, s.metadataType), 289 // fix https://github.com/apache/dubbo-go/issues/2176 290 common.WithParamsValue(constant.MaxServerSendMsgSize, proto.MaxServerSendMsgSize), 291 common.WithParamsValue(constant.MaxServerRecvMsgSize, proto.MaxServerRecvMsgSize), 292 ) 293 if len(s.Tag) > 0 { 294 ivkURL.AddParam(constant.Tagkey, s.Tag) 295 } 296 297 // post process the URL to be exported 298 s.postProcessConfig(ivkURL) 299 // config post processor may set "export" to false 300 if !ivkURL.GetParamBool(constant.ExportKey, true) { 301 return nil 302 } 303 304 if len(regUrls) > 0 { 305 s.cacheMutex.Lock() 306 if s.cacheProtocol == nil { 307 logger.Debugf(fmt.Sprintf("First load the registry protocol, url is {%v}!", ivkURL)) 308 s.cacheProtocol = extension.GetProtocol(constant.RegistryProtocol) 309 } 310 s.cacheMutex.Unlock() 311 312 for _, regUrl := range regUrls { 313 setRegistrySubURL(ivkURL, regUrl) 314 invoker := proxyFactory.GetInvoker(regUrl) 315 exporter := s.cacheProtocol.Export(invoker) 316 if exporter == nil { 317 return perrors.New(fmt.Sprintf("Registry protocol new exporter error, registry is {%v}, url is {%v}", regUrl, ivkURL)) 318 } 319 s.exporters = append(s.exporters, exporter) 320 } 321 } else { 322 if ivkURL.GetParam(constant.InterfaceKey, "") == constant.MetadataServiceName { 323 ms, err := extension.GetLocalMetadataService("") 324 if err != nil { 325 logger.Warnf("export org.apache.dubbo.metadata.MetadataService failed beacause of %s ! pls check if you import _ \"dubbo.apache.org/dubbo-go/v3/metadata/service/local\"", err) 326 return nil 327 } 328 if err := ms.SetMetadataServiceURL(ivkURL); err != nil { 329 logger.Warnf("SetMetadataServiceURL error = %s", err) 330 } 331 } 332 invoker := proxyFactory.GetInvoker(ivkURL) 333 exporter := extension.GetProtocol(protocolwrapper.FILTER).Export(invoker) 334 if exporter == nil { 335 return perrors.New(fmt.Sprintf("Filter protocol without registry new exporter error, url is {%v}", ivkURL)) 336 } 337 s.exporters = append(s.exporters, exporter) 338 } 339 publishServiceDefinition(ivkURL) 340 } 341 s.exported.Store(true) 342 return nil 343 } 344 345 // setRegistrySubURL set registry sub url is ivkURl 346 func setRegistrySubURL(ivkURL *common.URL, regUrl *common.URL) { 347 ivkURL.AddParam(constant.RegistryKey, regUrl.GetParam(constant.RegistryKey, "")) 348 regUrl.SubURL = ivkURL 349 } 350 351 // loadProtocol filter protocols by ids 352 func loadProtocol(protocolIds []string, protocols map[string]*ProtocolConfig) []*ProtocolConfig { 353 returnProtocols := make([]*ProtocolConfig, 0, len(protocols)) 354 for _, v := range protocolIds { 355 for k, config := range protocols { 356 if v == k { 357 returnProtocols = append(returnProtocols, config) 358 } 359 } 360 } 361 return returnProtocols 362 } 363 364 // Unexport will call unexport of all exporters service config exported 365 func (s *ServiceConfig) Unexport() { 366 if !s.exported.Load() { 367 return 368 } 369 if s.unexported.Load() { 370 return 371 } 372 373 func() { 374 s.exportersLock.Lock() 375 defer s.exportersLock.Unlock() 376 for _, exporter := range s.exporters { 377 exporter.UnExport() 378 } 379 s.exporters = nil 380 }() 381 382 s.exported.Store(false) 383 s.unexported.Store(true) 384 } 385 386 // Implement only store the @s and return 387 func (s *ServiceConfig) Implement(rpcService common.RPCService) { 388 s.rpcService = rpcService 389 } 390 391 func (s *ServiceConfig) getUrlMap() url.Values { 392 urlMap := url.Values{} 393 // first set user params 394 for k, v := range s.Params { 395 urlMap.Set(k, v) 396 } 397 urlMap.Set(constant.InterfaceKey, s.Interface) 398 urlMap.Set(constant.TimestampKey, strconv.FormatInt(time.Now().Unix(), 10)) 399 urlMap.Set(constant.ClusterKey, s.Cluster) 400 urlMap.Set(constant.LoadbalanceKey, s.Loadbalance) 401 urlMap.Set(constant.WarmupKey, s.Warmup) 402 urlMap.Set(constant.RetriesKey, s.Retries) 403 if s.Group != "" { 404 urlMap.Set(constant.GroupKey, s.Group) 405 } 406 if s.Version != "" { 407 urlMap.Set(constant.VersionKey, s.Version) 408 } 409 urlMap.Set(constant.RegistryRoleKey, strconv.Itoa(common.PROVIDER)) 410 urlMap.Set(constant.ReleaseKey, "dubbo-golang-"+constant.Version) 411 urlMap.Set(constant.SideKey, (common.RoleType(common.PROVIDER)).Role()) 412 // todo: move 413 urlMap.Set(constant.SerializationKey, s.Serialization) 414 // application config info 415 ac := GetApplicationConfig() 416 urlMap.Set(constant.ApplicationKey, ac.Name) 417 urlMap.Set(constant.OrganizationKey, ac.Organization) 418 urlMap.Set(constant.NameKey, ac.Name) 419 urlMap.Set(constant.ModuleKey, ac.Module) 420 urlMap.Set(constant.AppVersionKey, ac.Version) 421 urlMap.Set(constant.OwnerKey, ac.Owner) 422 urlMap.Set(constant.EnvironmentKey, ac.Environment) 423 424 // filter 425 var filters string 426 if s.Filter == "" { 427 filters = constant.DefaultServiceFilters 428 } else { 429 filters = s.Filter 430 } 431 if s.adaptiveService { 432 filters += fmt.Sprintf(",%s", constant.AdaptiveServiceProviderFilterKey) 433 } 434 if s.metricsEnable { 435 filters += fmt.Sprintf(",%s", constant.MetricsFilterKey) 436 } 437 urlMap.Set(constant.ServiceFilterKey, filters) 438 439 // filter special config 440 urlMap.Set(constant.AccessLogFilterKey, s.AccessLog) 441 // tps limiter 442 urlMap.Set(constant.TPSLimitStrategyKey, s.TpsLimitStrategy) 443 urlMap.Set(constant.TPSLimitIntervalKey, s.TpsLimitInterval) 444 urlMap.Set(constant.TPSLimitRateKey, s.TpsLimitRate) 445 urlMap.Set(constant.TPSLimiterKey, s.TpsLimiter) 446 urlMap.Set(constant.TPSRejectedExecutionHandlerKey, s.TpsLimitRejectedHandler) 447 urlMap.Set(constant.TracingConfigKey, s.TracingKey) 448 449 // execute limit filter 450 urlMap.Set(constant.ExecuteLimitKey, s.ExecuteLimit) 451 urlMap.Set(constant.ExecuteRejectedExecutionHandlerKey, s.ExecuteLimitRejectedHandler) 452 453 // auth filter 454 urlMap.Set(constant.ServiceAuthKey, s.Auth) 455 urlMap.Set(constant.ParameterSignatureEnableKey, s.ParamSign) 456 457 // whether to export or not 458 urlMap.Set(constant.ExportKey, strconv.FormatBool(s.export)) 459 urlMap.Set(constant.PIDKey, fmt.Sprintf("%d", os.Getpid())) 460 461 for _, v := range s.Methods { 462 prefix := "methods." + v.Name + "." 463 urlMap.Set(prefix+constant.LoadbalanceKey, v.LoadBalance) 464 urlMap.Set(prefix+constant.RetriesKey, v.Retries) 465 urlMap.Set(prefix+constant.WeightKey, strconv.FormatInt(v.Weight, 10)) 466 467 urlMap.Set(prefix+constant.TPSLimitStrategyKey, v.TpsLimitStrategy) 468 urlMap.Set(prefix+constant.TPSLimitIntervalKey, v.TpsLimitInterval) 469 urlMap.Set(prefix+constant.TPSLimitRateKey, v.TpsLimitRate) 470 471 urlMap.Set(constant.ExecuteLimitKey, v.ExecuteLimit) 472 urlMap.Set(constant.ExecuteRejectedExecutionHandlerKey, v.ExecuteLimitRejectedHandler) 473 } 474 475 return urlMap 476 } 477 478 // GetExportedUrls will return the url in service config's exporter 479 func (s *ServiceConfig) GetExportedUrls() []*common.URL { 480 if s.exported.Load() { 481 var urls []*common.URL 482 for _, exporter := range s.exporters { 483 urls = append(urls, exporter.GetInvoker().GetURL()) 484 } 485 return urls 486 } 487 return nil 488 } 489 490 // postProcessConfig asks registered ConfigPostProcessor to post-process the current ServiceConfig. 491 func (s *ServiceConfig) postProcessConfig(url *common.URL) { 492 for _, p := range extension.GetConfigPostProcessors() { 493 p.PostProcessServiceConfig(url) 494 } 495 } 496 497 // newEmptyServiceConfig returns default ServiceConfig 498 func newEmptyServiceConfig() *ServiceConfig { 499 newServiceConfig := &ServiceConfig{ 500 unexported: atomic.NewBool(false), 501 exported: atomic.NewBool(false), 502 export: true, 503 RCProtocolsMap: make(map[string]*ProtocolConfig), 504 RCRegistriesMap: make(map[string]*RegistryConfig), 505 } 506 newServiceConfig.Params = make(map[string]string) 507 newServiceConfig.Methods = make([]*MethodConfig, 0, 8) 508 return newServiceConfig 509 } 510 511 type ServiceConfigBuilder struct { 512 serviceConfig *ServiceConfig 513 } 514 515 func NewServiceConfigBuilder() *ServiceConfigBuilder { 516 return &ServiceConfigBuilder{serviceConfig: newEmptyServiceConfig()} 517 } 518 519 func (pcb *ServiceConfigBuilder) SetRegistryIDs(registryIDs ...string) *ServiceConfigBuilder { 520 pcb.serviceConfig.RegistryIDs = registryIDs 521 return pcb 522 } 523 524 func (pcb *ServiceConfigBuilder) SetProtocolIDs(protocolIDs ...string) *ServiceConfigBuilder { 525 pcb.serviceConfig.ProtocolIDs = protocolIDs 526 return pcb 527 } 528 529 func (pcb *ServiceConfigBuilder) SetInterface(interfaceName string) *ServiceConfigBuilder { 530 pcb.serviceConfig.Interface = interfaceName 531 return pcb 532 } 533 534 func (pcb *ServiceConfigBuilder) SetMetadataType(setMetadataType string) *ServiceConfigBuilder { 535 pcb.serviceConfig.metadataType = setMetadataType 536 return pcb 537 } 538 539 func (pcb *ServiceConfigBuilder) SetLoadBalancce(lb string) *ServiceConfigBuilder { 540 pcb.serviceConfig.Loadbalance = lb 541 return pcb 542 } 543 544 func (pcb *ServiceConfigBuilder) SetWarmUpTie(warmUp string) *ServiceConfigBuilder { 545 pcb.serviceConfig.Warmup = warmUp 546 return pcb 547 } 548 549 func (pcb *ServiceConfigBuilder) SetCluster(cluster string) *ServiceConfigBuilder { 550 pcb.serviceConfig.Cluster = cluster 551 return pcb 552 } 553 554 func (pcb *ServiceConfigBuilder) AddRCProtocol(protocolName string, protocolConfig *ProtocolConfig) *ServiceConfigBuilder { 555 pcb.serviceConfig.RCProtocolsMap[protocolName] = protocolConfig 556 return pcb 557 } 558 559 func (pcb *ServiceConfigBuilder) AddRCRegistry(registryName string, registryConfig *RegistryConfig) *ServiceConfigBuilder { 560 pcb.serviceConfig.RCRegistriesMap[registryName] = registryConfig 561 return pcb 562 } 563 564 func (pcb *ServiceConfigBuilder) SetGroup(group string) *ServiceConfigBuilder { 565 pcb.serviceConfig.Group = group 566 return pcb 567 } 568 func (pcb *ServiceConfigBuilder) SetVersion(version string) *ServiceConfigBuilder { 569 pcb.serviceConfig.Version = version 570 return pcb 571 } 572 573 func (pcb *ServiceConfigBuilder) SetProxyFactoryKey(proxyFactoryKey string) *ServiceConfigBuilder { 574 pcb.serviceConfig.ProxyFactoryKey = proxyFactoryKey 575 return pcb 576 } 577 578 func (pcb *ServiceConfigBuilder) SetRPCService(service common.RPCService) *ServiceConfigBuilder { 579 pcb.serviceConfig.rpcService = service 580 return pcb 581 } 582 583 func (pcb *ServiceConfigBuilder) SetSerialization(serialization string) *ServiceConfigBuilder { 584 pcb.serviceConfig.Serialization = serialization 585 return pcb 586 } 587 588 func (pcb *ServiceConfigBuilder) SetServiceID(id string) *ServiceConfigBuilder { 589 pcb.serviceConfig.id = id 590 return pcb 591 } 592 593 func (pcb *ServiceConfigBuilder) SetNotRegister(notRegister bool) *ServiceConfigBuilder { 594 pcb.serviceConfig.NotRegister = notRegister 595 return pcb 596 } 597 598 func (pcb *ServiceConfigBuilder) Build() *ServiceConfig { 599 return pcb.serviceConfig 600 }