github.com/wangyougui/gf/v2@v2.6.5/net/gsvc/gsvc_service.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/wangyougui/gf. 6 7 package gsvc 8 9 import ( 10 "context" 11 12 "github.com/wangyougui/gf/v2/encoding/gjson" 13 "github.com/wangyougui/gf/v2/errors/gcode" 14 "github.com/wangyougui/gf/v2/errors/gerror" 15 "github.com/wangyougui/gf/v2/internal/intlog" 16 "github.com/wangyougui/gf/v2/os/gcmd" 17 "github.com/wangyougui/gf/v2/text/gstr" 18 ) 19 20 // LocalService provides a default implements for interface Service. 21 type LocalService struct { 22 Head string // Service custom head string in service key. 23 Deployment string // Service deployment name, eg: dev, qa, staging, prod, etc. 24 Namespace string // Service Namespace, to indicate different services in the same environment with the same Name. 25 Name string // Name for the service. 26 Version string // Service version, eg: v1.0.0, v2.1.1, etc. 27 Endpoints Endpoints // Service Endpoints, pattern: IP:port, eg: 192.168.1.2:8000. 28 Metadata Metadata // Custom data for this service, which can be set using JSON by environment or command-line. 29 } 30 31 // NewServiceWithName creates and returns a default implements for interface Service by service name. 32 func NewServiceWithName(name string) Service { 33 s := &LocalService{ 34 Name: name, 35 Metadata: make(Metadata), 36 } 37 s.autoFillDefaultAttributes() 38 return s 39 } 40 41 // NewServiceWithKV creates and returns a default implements for interface Service by key-value pair string. 42 func NewServiceWithKV(key, value string) (Service, error) { 43 var ( 44 err error 45 array = gstr.Split(gstr.Trim(key, DefaultSeparator), DefaultSeparator) 46 ) 47 if len(array) < 6 { 48 err = gerror.NewCodef(gcode.CodeInvalidParameter, `invalid service key "%s"`, key) 49 return nil, err 50 } 51 s := &LocalService{ 52 Head: array[0], 53 Deployment: array[1], 54 Namespace: array[2], 55 Name: array[3], 56 Version: array[4], 57 Endpoints: NewEndpoints(array[5]), 58 Metadata: make(Metadata), 59 } 60 s.autoFillDefaultAttributes() 61 if len(value) > 0 { 62 if err = gjson.Unmarshal([]byte(value), &s.Metadata); err != nil { 63 err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `invalid service value "%s"`, value) 64 return nil, err 65 } 66 } 67 return s, nil 68 } 69 70 // GetName returns the name of the service. 71 // The name is necessary for a service, and should be unique among services. 72 func (s *LocalService) GetName() string { 73 return s.Name 74 } 75 76 // GetVersion returns the version of the service. 77 // It is suggested using GNU version naming like: v1.0.0, v2.0.1, v2.1.0-rc. 78 // A service can have multiple versions deployed at once. 79 // If no version set in service, the default version of service is "latest". 80 func (s *LocalService) GetVersion() string { 81 return s.Version 82 } 83 84 // GetKey formats and returns a unique key string for service. 85 // The result key is commonly used for key-value registrar server. 86 func (s *LocalService) GetKey() string { 87 serviceNameUnique := s.GetPrefix() 88 serviceNameUnique += DefaultSeparator + s.Endpoints.String() 89 return serviceNameUnique 90 } 91 92 // GetValue formats and returns the value of the service. 93 // The result value is commonly used for key-value registrar server. 94 func (s *LocalService) GetValue() string { 95 b, err := gjson.Marshal(s.Metadata) 96 if err != nil { 97 intlog.Errorf(context.TODO(), `%+v`, err) 98 } 99 return string(b) 100 } 101 102 // GetPrefix formats and returns the key prefix string. 103 // The result prefix string is commonly used in key-value registrar server 104 // for service searching. 105 // 106 // Take etcd server for example, the prefix string is used like: 107 // `etcdctl get /services/prod/hello.svc --prefix` 108 func (s *LocalService) GetPrefix() string { 109 s.autoFillDefaultAttributes() 110 return DefaultSeparator + gstr.Join( 111 []string{ 112 s.Head, 113 s.Deployment, 114 s.Namespace, 115 s.Name, 116 s.Version, 117 }, 118 DefaultSeparator, 119 ) 120 } 121 122 // GetMetadata returns the Metadata map of service. 123 // The Metadata is key-value pair map specifying extra attributes of a service. 124 func (s *LocalService) GetMetadata() Metadata { 125 return s.Metadata 126 } 127 128 // GetEndpoints returns the Endpoints of service. 129 // The Endpoints contain multiple host/port information of service. 130 func (s *LocalService) GetEndpoints() Endpoints { 131 return s.Endpoints 132 } 133 134 func (s *LocalService) autoFillDefaultAttributes() { 135 if s.Head == "" { 136 s.Head = gcmd.GetOptWithEnv(EnvPrefix, DefaultHead).String() 137 } 138 if s.Deployment == "" { 139 s.Deployment = gcmd.GetOptWithEnv(EnvDeployment, DefaultDeployment).String() 140 } 141 if s.Namespace == "" { 142 s.Namespace = gcmd.GetOptWithEnv(EnvNamespace, DefaultNamespace).String() 143 } 144 if s.Name == "" { 145 s.Name = gcmd.GetOptWithEnv(EnvName).String() 146 } 147 if s.Version == "" { 148 s.Version = gcmd.GetOptWithEnv(EnvVersion, DefaultVersion).String() 149 } 150 }