...

Source file src/github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/clients/abe/client.go

Documentation: github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/clients/abe

     1  /*
     2   * A Bit of Everything
     3   *
     4   * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
     5   *
     6   * API version: 1.0
     7   * Contact: none@example.com
     8   * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
     9   */
    10  
    11  package abe
    12  
    13  import (
    14  	"bytes"
    15  	"context"
    16  	"encoding/json"
    17  	"encoding/xml"
    18  	"errors"
    19  	"fmt"
    20  	"io"
    21  	"mime/multipart"
    22  	"net/http"
    23  	"net/url"
    24  	"os"
    25  	"path/filepath"
    26  	"reflect"
    27  	"regexp"
    28  	"strconv"
    29  	"strings"
    30  	"time"
    31  	"unicode/utf8"
    32  
    33  	"golang.org/x/oauth2"
    34  )
    35  
    36  var (
    37  	jsonCheck = regexp.MustCompile("(?i:[application|text]/json)")
    38  	xmlCheck  = regexp.MustCompile("(?i:[application|text]/xml)")
    39  )
    40  
    41  // APIClient manages communication with the A Bit of Everything API v1.0
    42  // In most cases there should be only one, shared, APIClient.
    43  type APIClient struct {
    44  	cfg    *Configuration
    45  	common service // Reuse a single struct instead of allocating one for each service on the heap.
    46  
    47  	// API Services
    48  
    49  	ABitOfEverythingApi *ABitOfEverythingApiService
    50  
    51  	ABitOfEverythingServiceApi *ABitOfEverythingServiceApiService
    52  
    53  	CamelCaseServiceNameApi *CamelCaseServiceNameApiService
    54  
    55  	EchoRpcApi *EchoRpcApiService
    56  
    57  	SnakeEnumServiceApi *SnakeEnumServiceApiService
    58  }
    59  
    60  type service struct {
    61  	client *APIClient
    62  }
    63  
    64  // NewAPIClient creates a new API client. Requires a userAgent string describing your application.
    65  // optionally a custom http.Client to allow for advanced features such as caching.
    66  func NewAPIClient(cfg *Configuration) *APIClient {
    67  	if cfg.HTTPClient == nil {
    68  		cfg.HTTPClient = http.DefaultClient
    69  	}
    70  
    71  	c := &APIClient{}
    72  	c.cfg = cfg
    73  	c.common.client = c
    74  
    75  	// API Services
    76  	c.ABitOfEverythingApi = (*ABitOfEverythingApiService)(&c.common)
    77  	c.ABitOfEverythingServiceApi = (*ABitOfEverythingServiceApiService)(&c.common)
    78  	c.CamelCaseServiceNameApi = (*CamelCaseServiceNameApiService)(&c.common)
    79  	c.EchoRpcApi = (*EchoRpcApiService)(&c.common)
    80  	c.SnakeEnumServiceApi = (*SnakeEnumServiceApiService)(&c.common)
    81  
    82  	return c
    83  }
    84  
    85  func atoi(in string) (int, error) {
    86  	return strconv.Atoi(in)
    87  }
    88  
    89  // selectHeaderContentType select a content type from the available list.
    90  func selectHeaderContentType(contentTypes []string) string {
    91  	if len(contentTypes) == 0 {
    92  		return ""
    93  	}
    94  	if contains(contentTypes, "application/json") {
    95  		return "application/json"
    96  	}
    97  	return contentTypes[0] // use the first content type specified in 'consumes'
    98  }
    99  
   100  // selectHeaderAccept join all accept types and return
   101  func selectHeaderAccept(accepts []string) string {
   102  	if len(accepts) == 0 {
   103  		return ""
   104  	}
   105  
   106  	if contains(accepts, "application/json") {
   107  		return "application/json"
   108  	}
   109  
   110  	return strings.Join(accepts, ",")
   111  }
   112  
   113  // contains is a case insenstive match, finding needle in a haystack
   114  func contains(haystack []string, needle string) bool {
   115  	for _, a := range haystack {
   116  		if strings.ToLower(a) == strings.ToLower(needle) {
   117  			return true
   118  		}
   119  	}
   120  	return false
   121  }
   122  
   123  // Verify optional parameters are of the correct type.
   124  func typeCheckParameter(obj interface{}, expected string, name string) error {
   125  	// Make sure there is an object.
   126  	if obj == nil {
   127  		return nil
   128  	}
   129  
   130  	// Check the type is as expected.
   131  	if reflect.TypeOf(obj).String() != expected {
   132  		return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String())
   133  	}
   134  	return nil
   135  }
   136  
   137  // parameterToString convert interface{} parameters to string, using a delimiter if format is provided.
   138  func parameterToString(obj interface{}, collectionFormat string) string {
   139  	var delimiter string
   140  
   141  	switch collectionFormat {
   142  	case "pipes":
   143  		delimiter = "|"
   144  	case "ssv":
   145  		delimiter = " "
   146  	case "tsv":
   147  		delimiter = "\t"
   148  	case "csv":
   149  		delimiter = ","
   150  	}
   151  
   152  	if reflect.TypeOf(obj).Kind() == reflect.Slice {
   153  		return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]")
   154  	}
   155  
   156  	return fmt.Sprintf("%v", obj)
   157  }
   158  
   159  // callAPI do the request.
   160  func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
   161  	return c.cfg.HTTPClient.Do(request)
   162  }
   163  
   164  // Change base path to allow switching to mocks
   165  func (c *APIClient) ChangeBasePath(path string) {
   166  	c.cfg.BasePath = path
   167  }
   168  
   169  // prepareRequest build the request
   170  func (c *APIClient) prepareRequest(
   171  	ctx context.Context,
   172  	path string, method string,
   173  	postBody interface{},
   174  	headerParams map[string]string,
   175  	queryParams url.Values,
   176  	formParams url.Values,
   177  	fileName string,
   178  	fileBytes []byte) (localVarRequest *http.Request, err error) {
   179  
   180  	var body *bytes.Buffer
   181  
   182  	// Detect postBody type and post.
   183  	if postBody != nil {
   184  		contentType := headerParams["Content-Type"]
   185  		if contentType == "" {
   186  			contentType = detectContentType(postBody)
   187  			headerParams["Content-Type"] = contentType
   188  		}
   189  
   190  		body, err = setBody(postBody, contentType)
   191  		if err != nil {
   192  			return nil, err
   193  		}
   194  	}
   195  
   196  	// add form parameters and file if available.
   197  	if len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") {
   198  		if body != nil {
   199  			return nil, errors.New("Cannot specify postBody and multipart form at the same time.")
   200  		}
   201  		body = &bytes.Buffer{}
   202  		w := multipart.NewWriter(body)
   203  
   204  		for k, v := range formParams {
   205  			for _, iv := range v {
   206  				if strings.HasPrefix(k, "@") { // file
   207  					err = addFile(w, k[1:], iv)
   208  					if err != nil {
   209  						return nil, err
   210  					}
   211  				} else { // form value
   212  					w.WriteField(k, iv)
   213  				}
   214  			}
   215  		}
   216  		if len(fileBytes) > 0 && fileName != "" {
   217  			w.Boundary()
   218  			//_, fileNm := filepath.Split(fileName)
   219  			part, err := w.CreateFormFile("file", filepath.Base(fileName))
   220  			if err != nil {
   221  				return nil, err
   222  			}
   223  			_, err = part.Write(fileBytes)
   224  			if err != nil {
   225  				return nil, err
   226  			}
   227  			// Set the Boundary in the Content-Type
   228  			headerParams["Content-Type"] = w.FormDataContentType()
   229  		}
   230  
   231  		// Set Content-Length
   232  		headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
   233  		w.Close()
   234  	}
   235  
   236  	// Setup path and query parameters
   237  	url, err := url.Parse(path)
   238  	if err != nil {
   239  		return nil, err
   240  	}
   241  
   242  	// Adding Query Param
   243  	query := url.Query()
   244  	for k, v := range queryParams {
   245  		for _, iv := range v {
   246  			query.Add(k, iv)
   247  		}
   248  	}
   249  
   250  	// Encode the parameters.
   251  	url.RawQuery = query.Encode()
   252  
   253  	// Generate a new request
   254  	if body != nil {
   255  		localVarRequest, err = http.NewRequest(method, url.String(), body)
   256  	} else {
   257  		localVarRequest, err = http.NewRequest(method, url.String(), nil)
   258  	}
   259  	if err != nil {
   260  		return nil, err
   261  	}
   262  
   263  	// add header parameters, if any
   264  	if len(headerParams) > 0 {
   265  		headers := http.Header{}
   266  		for h, v := range headerParams {
   267  			headers.Set(h, v)
   268  		}
   269  		localVarRequest.Header = headers
   270  	}
   271  
   272  	// Override request host, if applicable
   273  	if c.cfg.Host != "" {
   274  		localVarRequest.Host = c.cfg.Host
   275  	}
   276  
   277  	// Add the user agent to the request.
   278  	localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
   279  
   280  	if ctx != nil {
   281  		// add context to the request
   282  		localVarRequest = localVarRequest.WithContext(ctx)
   283  
   284  		// Walk through any authentication.
   285  
   286  		// OAuth2 authentication
   287  		if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok {
   288  			// We were able to grab an oauth2 token from the context
   289  			var latestToken *oauth2.Token
   290  			if latestToken, err = tok.Token(); err != nil {
   291  				return nil, err
   292  			}
   293  
   294  			latestToken.SetAuthHeader(localVarRequest)
   295  		}
   296  
   297  		// Basic HTTP Authentication
   298  		if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok {
   299  			localVarRequest.SetBasicAuth(auth.UserName, auth.Password)
   300  		}
   301  
   302  		// AccessToken Authentication
   303  		if auth, ok := ctx.Value(ContextAccessToken).(string); ok {
   304  			localVarRequest.Header.Add("Authorization", "Bearer "+auth)
   305  		}
   306  	}
   307  
   308  	for header, value := range c.cfg.DefaultHeader {
   309  		localVarRequest.Header.Add(header, value)
   310  	}
   311  
   312  	return localVarRequest, nil
   313  }
   314  
   315  func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {
   316  		if strings.Contains(contentType, "application/xml") {
   317  			if err = xml.Unmarshal(b, v); err != nil {
   318  				return err
   319  			}
   320  			return nil
   321  		} else if strings.Contains(contentType, "application/json") {
   322  			if err = json.Unmarshal(b, v); err != nil {
   323  				return err
   324  			}
   325  			return nil
   326  		}
   327  	return errors.New("undefined response type")
   328  }
   329  
   330  // Add a file to the multipart request
   331  func addFile(w *multipart.Writer, fieldName, path string) error {
   332  	file, err := os.Open(path)
   333  	if err != nil {
   334  		return err
   335  	}
   336  	defer file.Close()
   337  
   338  	part, err := w.CreateFormFile(fieldName, filepath.Base(path))
   339  	if err != nil {
   340  		return err
   341  	}
   342  	_, err = io.Copy(part, file)
   343  
   344  	return err
   345  }
   346  
   347  // Prevent trying to import "fmt"
   348  func reportError(format string, a ...interface{}) error {
   349  	return fmt.Errorf(format, a...)
   350  }
   351  
   352  // Set request body from an interface{}
   353  func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {
   354  	if bodyBuf == nil {
   355  		bodyBuf = &bytes.Buffer{}
   356  	}
   357  
   358  	if reader, ok := body.(io.Reader); ok {
   359  		_, err = bodyBuf.ReadFrom(reader)
   360  	} else if b, ok := body.([]byte); ok {
   361  		_, err = bodyBuf.Write(b)
   362  	} else if s, ok := body.(string); ok {
   363  		_, err = bodyBuf.WriteString(s)
   364  	} else if s, ok := body.(*string); ok {
   365  		_, err = bodyBuf.WriteString(*s)
   366  	} else if jsonCheck.MatchString(contentType) {
   367  		err = json.NewEncoder(bodyBuf).Encode(body)
   368  	} else if xmlCheck.MatchString(contentType) {
   369  		xml.NewEncoder(bodyBuf).Encode(body)
   370  	}
   371  
   372  	if err != nil {
   373  		return nil, err
   374  	}
   375  
   376  	if bodyBuf.Len() == 0 {
   377  		err = fmt.Errorf("Invalid body type %s\n", contentType)
   378  		return nil, err
   379  	}
   380  	return bodyBuf, nil
   381  }
   382  
   383  // detectContentType method is used to figure out `Request.Body` content type for request header
   384  func detectContentType(body interface{}) string {
   385  	contentType := "text/plain; charset=utf-8"
   386  	kind := reflect.TypeOf(body).Kind()
   387  
   388  	switch kind {
   389  	case reflect.Struct, reflect.Map, reflect.Ptr:
   390  		contentType = "application/json; charset=utf-8"
   391  	case reflect.String:
   392  		contentType = "text/plain; charset=utf-8"
   393  	default:
   394  		if b, ok := body.([]byte); ok {
   395  			contentType = http.DetectContentType(b)
   396  		} else if kind == reflect.Slice {
   397  			contentType = "application/json; charset=utf-8"
   398  		}
   399  	}
   400  
   401  	return contentType
   402  }
   403  
   404  // Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
   405  type cacheControl map[string]string
   406  
   407  func parseCacheControl(headers http.Header) cacheControl {
   408  	cc := cacheControl{}
   409  	ccHeader := headers.Get("Cache-Control")
   410  	for _, part := range strings.Split(ccHeader, ",") {
   411  		part = strings.Trim(part, " ")
   412  		if part == "" {
   413  			continue
   414  		}
   415  		if strings.ContainsRune(part, '=') {
   416  			keyval := strings.Split(part, "=")
   417  			cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
   418  		} else {
   419  			cc[part] = ""
   420  		}
   421  	}
   422  	return cc
   423  }
   424  
   425  // CacheExpires helper function to determine remaining time before repeating a request.
   426  func CacheExpires(r *http.Response) time.Time {
   427  	// Figure out when the cache expires.
   428  	var expires time.Time
   429  	now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
   430  	if err != nil {
   431  		return time.Now()
   432  	}
   433  	respCacheControl := parseCacheControl(r.Header)
   434  
   435  	if maxAge, ok := respCacheControl["max-age"]; ok {
   436  		lifetime, err := time.ParseDuration(maxAge + "s")
   437  		if err != nil {
   438  			expires = now
   439  		}
   440  		expires = now.Add(lifetime)
   441  	} else {
   442  		expiresHeader := r.Header.Get("Expires")
   443  		if expiresHeader != "" {
   444  			expires, err = time.Parse(time.RFC1123, expiresHeader)
   445  			if err != nil {
   446  				expires = now
   447  			}
   448  		}
   449  	}
   450  	return expires
   451  }
   452  
   453  func strlen(s string) int {
   454  	return utf8.RuneCountInString(s)
   455  }
   456  
   457  // GenericSwaggerError Provides access to the body, error and model on returned errors.
   458  type GenericSwaggerError struct {
   459  	body  []byte
   460  	error string
   461  	model interface{}
   462  }
   463  
   464  // Error returns non-empty string if there was an error.
   465  func (e GenericSwaggerError) Error() string {
   466  	return e.error
   467  }
   468  
   469  // Body returns the raw bytes of the response
   470  func (e GenericSwaggerError) Body() []byte {
   471  	return e.body
   472  }
   473  
   474  // Model returns the unpacked model of the error
   475  func (e GenericSwaggerError) Model() interface{} {
   476  	return e.model
   477  }

View as plain text