github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/courier/client/client.go (about)

     1  package client
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/johnnyeven/libtools/conf"
    10  	"github.com/johnnyeven/libtools/courier"
    11  	"github.com/johnnyeven/libtools/courier/httpx"
    12  	"github.com/johnnyeven/libtools/courier/transport_grpc"
    13  	"github.com/johnnyeven/libtools/courier/transport_http"
    14  	"github.com/johnnyeven/libtools/env"
    15  	"github.com/johnnyeven/libtools/log/context"
    16  	"github.com/johnnyeven/libtools/servicex"
    17  )
    18  
    19  const depToolStackName = "dep-tools"
    20  
    21  type Client struct {
    22  	Name string
    23  	// used in service
    24  	Service       string
    25  	Group         string
    26  	Version       string
    27  	Host          string `conf:"env,upstream" validate:"@hostname"`
    28  	Mode          string
    29  	Port          int
    30  	Timeout       time.Duration
    31  	WrapTransport transport_http.TransportWrapper
    32  }
    33  
    34  func (c Client) DockerDefaults() conf.DockerDefaults {
    35  	if c.Name == "rancher" {
    36  		return conf.DockerDefaults{
    37  			// todo make switch in docker or expose
    38  			"Host": conf.RancherInternal(depToolStackName, c.Name),
    39  			"Port": 38080,
    40  		}
    41  	}
    42  	return conf.DockerDefaults{
    43  		// todo make switch in docker or expose
    44  		"Host": conf.RancherInternal(c.Group, "service-"+c.Name),
    45  		"Port": 80,
    46  	}
    47  }
    48  
    49  func (Client) MarshalDefaults(v interface{}) {
    50  	if client, ok := v.(*Client); ok {
    51  		if client.Service == "" {
    52  			client.Service = os.Getenv("PROJECT_NAME")
    53  		}
    54  		if client.Group == "" {
    55  			client.Group = os.Getenv(servicex.EnvVarKeyProjectGroup)
    56  		}
    57  		if client.Version == "" {
    58  			client.Version = os.Getenv("PROJECT_REF")
    59  		}
    60  		if client.Mode == "" {
    61  			client.Mode = "http"
    62  		}
    63  		if client.Host == "" {
    64  			client.Host = fmt.Sprintf("service-%s.staging.g7pay.net", client.Name)
    65  		}
    66  		if client.Port == 0 {
    67  			client.Port = 80
    68  		}
    69  		if client.Timeout == 0 {
    70  			client.Timeout = 5 * time.Second
    71  		}
    72  	}
    73  }
    74  
    75  func (c Client) GetBaseURL(protocol string) (url string) {
    76  	url = c.Host
    77  	if protocol != "" {
    78  		url = fmt.Sprintf("%s://%s", protocol, c.Host)
    79  	}
    80  	if c.Port > 0 {
    81  		url = fmt.Sprintf("%s:%d", url, c.Port)
    82  	}
    83  	return
    84  }
    85  
    86  func (c *Client) Request(id, httpMethod, uri string, req interface{}, metas ...courier.Metadata) IRequest {
    87  	requestID := context.GetLogID()
    88  	metadata := courier.MetadataMerge(metas...)
    89  
    90  	if !env.IsOnline() {
    91  		if requestIDInMeta := metadata.Get(httpx.HeaderRequestID); requestIDInMeta != "" {
    92  			requestID = requestIDInMeta
    93  		}
    94  		mocker, err := ParseMockID(c.Service, requestID)
    95  		if err == nil {
    96  			if m, exists := mocker.Mocks[id]; exists {
    97  				return &MockRequest{
    98  					MockData: m,
    99  				}
   100  			}
   101  		}
   102  	}
   103  
   104  	if metadata.Has(courier.VersionSwitchKey) {
   105  		requestID = courier.ModifyRequestIDWithVersionSwitch(requestID, metadata.Get(courier.VersionSwitchKey))
   106  	} else {
   107  		if _, v, exists := courier.ParseVersionSwitch(requestID); exists {
   108  			metadata.Set(courier.VersionSwitchKey, v)
   109  		}
   110  	}
   111  
   112  	metadata.Add(httpx.HeaderRequestID, requestID)
   113  	metadata.Add(httpx.HeaderUserAgent, c.Service+" "+c.Version)
   114  
   115  	switch strings.ToLower(c.Mode) {
   116  	case "grpc":
   117  		serverName, method := parseID(id)
   118  		return &transport_grpc.GRPCRequest{
   119  			BaseURL:    c.GetBaseURL(""),
   120  			ServerName: serverName,
   121  			Method:     method,
   122  			Timeout:    c.Timeout,
   123  			RequestID:  requestID,
   124  			Req:        req,
   125  			Metadata:   metadata,
   126  		}
   127  	default:
   128  		return &transport_http.HttpRequest{
   129  			BaseURL:       c.GetBaseURL(c.Mode),
   130  			Method:        httpMethod,
   131  			URI:           uri,
   132  			ID:            id,
   133  			Timeout:       c.Timeout,
   134  			WrapTransport: c.WrapTransport,
   135  			Req:           req,
   136  			Metadata:      metadata,
   137  		}
   138  	}
   139  }
   140  
   141  func parseID(id string) (serverName string, method string) {
   142  	values := strings.Split(id, ".")
   143  	if len(values) == 2 {
   144  		serverName = strings.ToLower(strings.Replace(values[0], "Client", "", -1))
   145  		method = values[1]
   146  	}
   147  	return
   148  }