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  }