feat(functions): add apiv2beta REST client (#6291)
diff --git a/functions/apiv2beta/doc.go b/functions/apiv2beta/doc.go
index 9ae9a3d..58028c9 100644
--- a/functions/apiv2beta/doc.go
+++ b/functions/apiv2beta/doc.go
@@ -72,6 +72,8 @@
import (
"context"
+ "fmt"
+ "net/http"
"os"
"runtime"
"strconv"
@@ -160,3 +162,22 @@
}
return "UNKNOWN"
}
+
+// maybeUnknownEnum wraps the given proto-JSON parsing error if it is the result
+// of receiving an unknown enum value.
+func maybeUnknownEnum(err error) error {
+ if strings.Contains(err.Error(), "invalid value for enum type") {
+ err = fmt.Errorf("received an unknown enum value; a later version of the library may support it: %w", err)
+ }
+ return err
+}
+
+// buildHeaders extracts metadata from the outgoing context, joins it with any other
+// given metadata, and converts them into a http.Header.
+func buildHeaders(ctx context.Context, mds ...metadata.MD) http.Header {
+ if cmd, ok := metadata.FromOutgoingContext(ctx); ok {
+ mds = append(mds, cmd)
+ }
+ md := metadata.Join(mds...)
+ return http.Header(md)
+}
diff --git a/functions/apiv2beta/function_client.go b/functions/apiv2beta/function_client.go
index a695704..7bfe590 100644
--- a/functions/apiv2beta/function_client.go
+++ b/functions/apiv2beta/function_client.go
@@ -17,25 +17,31 @@
package functions
import (
+ "bytes"
"context"
"fmt"
+ "io/ioutil"
"math"
+ "net/http"
"net/url"
"time"
"cloud.google.com/go/longrunning"
lroauto "cloud.google.com/go/longrunning/autogen"
gax "github.com/googleapis/gax-go/v2"
+ "google.golang.org/api/googleapi"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/api/option/internaloption"
gtransport "google.golang.org/api/transport/grpc"
+ httptransport "google.golang.org/api/transport/http"
functionspb "google.golang.org/genproto/googleapis/cloud/functions/v2beta"
locationpb "google.golang.org/genproto/googleapis/cloud/location"
iampb "google.golang.org/genproto/googleapis/iam/v1"
longrunningpb "google.golang.org/genproto/googleapis/longrunning"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
+ "google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
)
@@ -90,6 +96,25 @@
}
}
+func defaultFunctionRESTCallOptions() *FunctionCallOptions {
+ return &FunctionCallOptions{
+ GetFunction: []gax.CallOption{},
+ ListFunctions: []gax.CallOption{},
+ CreateFunction: []gax.CallOption{},
+ UpdateFunction: []gax.CallOption{},
+ DeleteFunction: []gax.CallOption{},
+ GenerateUploadUrl: []gax.CallOption{},
+ GenerateDownloadUrl: []gax.CallOption{},
+ ListRuntimes: []gax.CallOption{},
+ ListLocations: []gax.CallOption{},
+ GetIamPolicy: []gax.CallOption{},
+ SetIamPolicy: []gax.CallOption{},
+ TestIamPermissions: []gax.CallOption{},
+ GetOperation: []gax.CallOption{},
+ ListOperations: []gax.CallOption{},
+ }
+}
+
// internalFunctionClient is an interface that defines the methods available from Cloud Functions API.
type internalFunctionClient interface {
Close() error
@@ -398,6 +423,94 @@
return c.connPool.Close()
}
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type functionRESTClient struct {
+ // The http endpoint to connect to.
+ endpoint string
+
+ // The http client.
+ httpClient *http.Client
+
+ // LROClient is used internally to handle long-running operations.
+ // It is exposed so that its CallOptions can be modified if required.
+ // Users should not Close this client.
+ LROClient **lroauto.OperationsClient
+
+ // The x-goog-* metadata to be sent with each request.
+ xGoogMetadata metadata.MD
+
+ // Points back to the CallOptions field of the containing FunctionClient
+ CallOptions **FunctionCallOptions
+}
+
+// NewFunctionRESTClient creates a new function service rest client.
+//
+// Google Cloud Functions is used to deploy functions that are executed by
+// Google in response to various events. Data connected with that event is
+// passed to a function as the input data.
+//
+// A function is a resource which describes a function that should be
+// executed and how it is triggered.
+func NewFunctionRESTClient(ctx context.Context, opts ...option.ClientOption) (*FunctionClient, error) {
+ clientOpts := append(defaultFunctionRESTClientOptions(), opts...)
+ httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+ if err != nil {
+ return nil, err
+ }
+
+ callOpts := defaultFunctionRESTCallOptions()
+ c := &functionRESTClient{
+ endpoint: endpoint,
+ httpClient: httpClient,
+ CallOptions: &callOpts,
+ }
+ c.setGoogleClientInfo()
+
+ lroOpts := []option.ClientOption{
+ option.WithHTTPClient(httpClient),
+ option.WithEndpoint(endpoint),
+ }
+ opClient, err := lroauto.NewOperationsRESTClient(ctx, lroOpts...)
+ if err != nil {
+ return nil, err
+ }
+ c.LROClient = &opClient
+
+ return &FunctionClient{internalClient: c, CallOptions: callOpts}, nil
+}
+
+func defaultFunctionRESTClientOptions() []option.ClientOption {
+ return []option.ClientOption{
+ internaloption.WithDefaultEndpoint("https://cloudfunctions.googleapis.com"),
+ internaloption.WithDefaultMTLSEndpoint("https://cloudfunctions.mtls.googleapis.com"),
+ internaloption.WithDefaultAudience("https://cloudfunctions.googleapis.com/"),
+ internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+ }
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *functionRESTClient) setGoogleClientInfo(keyval ...string) {
+ kv := append([]string{"gl-go", versionGo()}, keyval...)
+ kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "rest", "UNKNOWN")
+ c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *functionRESTClient) Close() error {
+ // Replace httpClient with nil to force cleanup.
+ c.httpClient = nil
+ return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *functionRESTClient) Connection() *grpc.ClientConn {
+ return nil
+}
func (c *functionGRPCClient) GetFunction(ctx context.Context, req *functionspb.GetFunctionRequest, opts ...gax.CallOption) (*functionspb.Function, error) {
md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
@@ -726,9 +839,986 @@
return it
}
+// GetFunction returns a function with the given name from the requested project.
+func (c *functionRESTClient) GetFunction(ctx context.Context, req *functionspb.GetFunctionRequest, opts ...gax.CallOption) (*functionspb.Function, error) {
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v", req.GetName())
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ opts = append((*c.CallOptions).GetFunction[0:len((*c.CallOptions).GetFunction):len((*c.CallOptions).GetFunction)], opts...)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &functionspb.Function{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+ return resp, nil
+}
+
+// ListFunctions returns a list of functions that belong to the requested project.
+func (c *functionRESTClient) ListFunctions(ctx context.Context, req *functionspb.ListFunctionsRequest, opts ...gax.CallOption) *FunctionIterator {
+ it := &FunctionIterator{}
+ req = proto.Clone(req).(*functionspb.ListFunctionsRequest)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ it.InternalFetch = func(pageSize int, pageToken string) ([]*functionspb.Function, string, error) {
+ resp := &functionspb.ListFunctionsResponse{}
+ if pageToken != "" {
+ req.PageToken = pageToken
+ }
+ if pageSize > math.MaxInt32 {
+ req.PageSize = math.MaxInt32
+ } else if pageSize != 0 {
+ req.PageSize = int32(pageSize)
+ }
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, "", err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v/functions", req.GetParent())
+
+ params := url.Values{}
+ if req.GetFilter() != "" {
+ params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+ }
+ if req.GetOrderBy() != "" {
+ params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+ }
+ if req.GetPageSize() != 0 {
+ params.Add("pageSize", fmt.Sprintf("%v", req.GetPageSize()))
+ }
+ if req.GetPageToken() != "" {
+ params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+ }
+
+ baseUrl.RawQuery = params.Encode()
+
+ // Build HTTP headers from client and context metadata.
+ headers := buildHeaders(ctx, c.xGoogMetadata, metadata.Pairs("Content-Type", "application/json"))
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+ if err != nil {
+ return err
+ }
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, "", e
+ }
+ it.Response = resp
+ return resp.GetFunctions(), resp.GetNextPageToken(), nil
+ }
+
+ fetch := func(pageSize int, pageToken string) (string, error) {
+ items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
+ if err != nil {
+ return "", err
+ }
+ it.items = append(it.items, items...)
+ return nextPageToken, nil
+ }
+
+ it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
+ it.pageInfo.MaxSize = int(req.GetPageSize())
+ it.pageInfo.Token = req.GetPageToken()
+
+ return it
+}
+
+// CreateFunction creates a new function. If a function with the given name already exists in
+// the specified project, the long running operation will return
+// ALREADY_EXISTS error.
+func (c *functionRESTClient) CreateFunction(ctx context.Context, req *functionspb.CreateFunctionRequest, opts ...gax.CallOption) (*CreateFunctionOperation, error) {
+ m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true}
+ body := req.GetFunction()
+ jsonReq, err := m.Marshal(body)
+ if err != nil {
+ return nil, err
+ }
+
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v/functions", req.GetParent())
+
+ params := url.Values{}
+ if req.GetFunctionId() != "" {
+ params.Add("functionId", fmt.Sprintf("%v", req.GetFunctionId()))
+ }
+
+ baseUrl.RawQuery = params.Encode()
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &longrunningpb.Operation{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+
+ override := fmt.Sprintf("/v2beta/%s", resp.GetName())
+ return &CreateFunctionOperation{
+ lro: longrunning.InternalNewOperation(*c.LROClient, resp),
+ pollPath: override,
+ }, nil
+}
+
+// UpdateFunction updates existing function.
+func (c *functionRESTClient) UpdateFunction(ctx context.Context, req *functionspb.UpdateFunctionRequest, opts ...gax.CallOption) (*UpdateFunctionOperation, error) {
+ m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true}
+ body := req.GetFunction()
+ jsonReq, err := m.Marshal(body)
+ if err != nil {
+ return nil, err
+ }
+
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v", req.GetFunction().GetName())
+
+ params := url.Values{}
+ if req.GetUpdateMask().GetPaths() != nil {
+ params.Add("updateMask.paths", fmt.Sprintf("%v", req.GetUpdateMask().GetPaths()))
+ }
+
+ baseUrl.RawQuery = params.Encode()
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "function.name", url.QueryEscape(req.GetFunction().GetName())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &longrunningpb.Operation{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+
+ override := fmt.Sprintf("/v2beta/%s", resp.GetName())
+ return &UpdateFunctionOperation{
+ lro: longrunning.InternalNewOperation(*c.LROClient, resp),
+ pollPath: override,
+ }, nil
+}
+
+// DeleteFunction deletes a function with the given name from the specified project. If the
+// given function is used by some trigger, the trigger will be updated to
+// remove this function.
+func (c *functionRESTClient) DeleteFunction(ctx context.Context, req *functionspb.DeleteFunctionRequest, opts ...gax.CallOption) (*DeleteFunctionOperation, error) {
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v", req.GetName())
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &longrunningpb.Operation{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("DELETE", baseUrl.String(), nil)
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+
+ override := fmt.Sprintf("/v2beta/%s", resp.GetName())
+ return &DeleteFunctionOperation{
+ lro: longrunning.InternalNewOperation(*c.LROClient, resp),
+ pollPath: override,
+ }, nil
+}
+
+// GenerateUploadUrl returns a signed URL for uploading a function source code.
+// For more information about the signed URL usage see:
+// https://cloud.google.com/storage/docs/access-control/signed-urls (at https://cloud.google.com/storage/docs/access-control/signed-urls).
+// Once the function source code upload is complete, the used signed
+// URL should be provided in CreateFunction or UpdateFunction request
+// as a reference to the function source code.
+//
+// When uploading source code to the generated signed URL, please follow
+// these restrictions:
+//
+// Source file type should be a zip file.
+//
+// No credentials should be attached - the signed URLs provide access to the
+// target bucket using internal service identity; if credentials were
+// attached, the identity from the credentials would be used, but that
+// identity does not have permissions to upload files to the URL.
+//
+// When making a HTTP PUT request, these two headers need to be specified:
+//
+// content-type: application/zip
+//
+// And this header SHOULD NOT be specified:
+//
+// Authorization: Bearer YOUR_TOKEN
+func (c *functionRESTClient) GenerateUploadUrl(ctx context.Context, req *functionspb.GenerateUploadUrlRequest, opts ...gax.CallOption) (*functionspb.GenerateUploadUrlResponse, error) {
+ m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true}
+ jsonReq, err := m.Marshal(req)
+ if err != nil {
+ return nil, err
+ }
+
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v/functions:generateUploadUrl", req.GetParent())
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ opts = append((*c.CallOptions).GenerateUploadUrl[0:len((*c.CallOptions).GenerateUploadUrl):len((*c.CallOptions).GenerateUploadUrl)], opts...)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &functionspb.GenerateUploadUrlResponse{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+ return resp, nil
+}
+
+// GenerateDownloadUrl returns a signed URL for downloading deployed function source code.
+// The URL is only valid for a limited period and should be used within
+// 30 minutes of generation.
+// For more information about the signed URL usage see:
+// https://cloud.google.com/storage/docs/access-control/signed-urls (at https://cloud.google.com/storage/docs/access-control/signed-urls)
+func (c *functionRESTClient) GenerateDownloadUrl(ctx context.Context, req *functionspb.GenerateDownloadUrlRequest, opts ...gax.CallOption) (*functionspb.GenerateDownloadUrlResponse, error) {
+ m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true}
+ jsonReq, err := m.Marshal(req)
+ if err != nil {
+ return nil, err
+ }
+
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v:generateDownloadUrl", req.GetName())
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ opts = append((*c.CallOptions).GenerateDownloadUrl[0:len((*c.CallOptions).GenerateDownloadUrl):len((*c.CallOptions).GenerateDownloadUrl)], opts...)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &functionspb.GenerateDownloadUrlResponse{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+ return resp, nil
+}
+
+// ListRuntimes returns a list of runtimes that are supported for the requested project.
+func (c *functionRESTClient) ListRuntimes(ctx context.Context, req *functionspb.ListRuntimesRequest, opts ...gax.CallOption) (*functionspb.ListRuntimesResponse, error) {
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v/runtimes", req.GetParent())
+
+ params := url.Values{}
+ if req.GetFilter() != "" {
+ params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+ }
+
+ baseUrl.RawQuery = params.Encode()
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ opts = append((*c.CallOptions).ListRuntimes[0:len((*c.CallOptions).ListRuntimes):len((*c.CallOptions).ListRuntimes)], opts...)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &functionspb.ListRuntimesResponse{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+ return resp, nil
+}
+
+// ListLocations lists information about the supported locations for this service.
+func (c *functionRESTClient) ListLocations(ctx context.Context, req *locationpb.ListLocationsRequest, opts ...gax.CallOption) *LocationIterator {
+ it := &LocationIterator{}
+ req = proto.Clone(req).(*locationpb.ListLocationsRequest)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ it.InternalFetch = func(pageSize int, pageToken string) ([]*locationpb.Location, string, error) {
+ resp := &locationpb.ListLocationsResponse{}
+ if pageToken != "" {
+ req.PageToken = pageToken
+ }
+ if pageSize > math.MaxInt32 {
+ req.PageSize = math.MaxInt32
+ } else if pageSize != 0 {
+ req.PageSize = int32(pageSize)
+ }
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, "", err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v/locations", req.GetName())
+
+ params := url.Values{}
+ if req.GetFilter() != "" {
+ params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+ }
+ if req.GetPageSize() != 0 {
+ params.Add("pageSize", fmt.Sprintf("%v", req.GetPageSize()))
+ }
+ if req.GetPageToken() != "" {
+ params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+ }
+
+ baseUrl.RawQuery = params.Encode()
+
+ // Build HTTP headers from client and context metadata.
+ headers := buildHeaders(ctx, c.xGoogMetadata, metadata.Pairs("Content-Type", "application/json"))
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+ if err != nil {
+ return err
+ }
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, "", e
+ }
+ it.Response = resp
+ return resp.GetLocations(), resp.GetNextPageToken(), nil
+ }
+
+ fetch := func(pageSize int, pageToken string) (string, error) {
+ items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
+ if err != nil {
+ return "", err
+ }
+ it.items = append(it.items, items...)
+ return nextPageToken, nil
+ }
+
+ it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
+ it.pageInfo.MaxSize = int(req.GetPageSize())
+ it.pageInfo.Token = req.GetPageToken()
+
+ return it
+}
+
+// GetIamPolicy gets the access control policy for a resource. Returns an empty policy
+// if the resource exists and does not have a policy set.
+func (c *functionRESTClient) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) {
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v:getIamPolicy", req.GetResource())
+
+ params := url.Values{}
+ if req.GetOptions().GetRequestedPolicyVersion() != 0 {
+ params.Add("options.requestedPolicyVersion", fmt.Sprintf("%v", req.GetOptions().GetRequestedPolicyVersion()))
+ }
+
+ baseUrl.RawQuery = params.Encode()
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ opts = append((*c.CallOptions).GetIamPolicy[0:len((*c.CallOptions).GetIamPolicy):len((*c.CallOptions).GetIamPolicy)], opts...)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &iampb.Policy{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+ return resp, nil
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces
+// any existing policy.
+//
+// Can return NOT_FOUND, INVALID_ARGUMENT, and PERMISSION_DENIED
+// errors.
+func (c *functionRESTClient) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) {
+ m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true}
+ jsonReq, err := m.Marshal(req)
+ if err != nil {
+ return nil, err
+ }
+
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v:setIamPolicy", req.GetResource())
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ opts = append((*c.CallOptions).SetIamPolicy[0:len((*c.CallOptions).SetIamPolicy):len((*c.CallOptions).SetIamPolicy)], opts...)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &iampb.Policy{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+ return resp, nil
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource. If the
+// resource does not exist, this will return an empty set of
+// permissions, not a NOT_FOUND error.
+//
+// Note: This operation is designed to be used for building
+// permission-aware UIs and command-line tools, not for authorization
+// checking. This operation may “fail open” without warning.
+func (c *functionRESTClient) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) {
+ m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true}
+ jsonReq, err := m.Marshal(req)
+ if err != nil {
+ return nil, err
+ }
+
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v:testIamPermissions", req.GetResource())
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ opts = append((*c.CallOptions).TestIamPermissions[0:len((*c.CallOptions).TestIamPermissions):len((*c.CallOptions).TestIamPermissions)], opts...)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &iampb.TestIamPermissionsResponse{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+ return resp, nil
+}
+
+// GetOperation is a utility method from google.longrunning.Operations.
+func (c *functionRESTClient) GetOperation(ctx context.Context, req *longrunningpb.GetOperationRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) {
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v", req.GetName())
+
+ // Build HTTP headers from client and context metadata.
+ md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+
+ headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json"))
+ opts = append((*c.CallOptions).GetOperation[0:len((*c.CallOptions).GetOperation):len((*c.CallOptions).GetOperation)], opts...)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ resp := &longrunningpb.Operation{}
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+ if err != nil {
+ return err
+ }
+ httpReq = httpReq.WithContext(ctx)
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, e
+ }
+ return resp, nil
+}
+
+// ListOperations is a utility method from google.longrunning.Operations.
+func (c *functionRESTClient) ListOperations(ctx context.Context, req *longrunningpb.ListOperationsRequest, opts ...gax.CallOption) *OperationIterator {
+ it := &OperationIterator{}
+ req = proto.Clone(req).(*longrunningpb.ListOperationsRequest)
+ unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+ it.InternalFetch = func(pageSize int, pageToken string) ([]*longrunningpb.Operation, string, error) {
+ resp := &longrunningpb.ListOperationsResponse{}
+ if pageToken != "" {
+ req.PageToken = pageToken
+ }
+ if pageSize > math.MaxInt32 {
+ req.PageSize = math.MaxInt32
+ } else if pageSize != 0 {
+ req.PageSize = int32(pageSize)
+ }
+ baseUrl, err := url.Parse(c.endpoint)
+ if err != nil {
+ return nil, "", err
+ }
+ baseUrl.Path += fmt.Sprintf("/v2beta/%v/operations", req.GetName())
+
+ params := url.Values{}
+ if req.GetFilter() != "" {
+ params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+ }
+ if req.GetPageSize() != 0 {
+ params.Add("pageSize", fmt.Sprintf("%v", req.GetPageSize()))
+ }
+ if req.GetPageToken() != "" {
+ params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+ }
+
+ baseUrl.RawQuery = params.Encode()
+
+ // Build HTTP headers from client and context metadata.
+ headers := buildHeaders(ctx, c.xGoogMetadata, metadata.Pairs("Content-Type", "application/json"))
+ e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+ if settings.Path != "" {
+ baseUrl.Path = settings.Path
+ }
+ httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+ if err != nil {
+ return err
+ }
+ httpReq.Header = headers
+
+ httpRsp, err := c.httpClient.Do(httpReq)
+ if err != nil {
+ return err
+ }
+ defer httpRsp.Body.Close()
+
+ if err = googleapi.CheckResponse(httpRsp); err != nil {
+ return err
+ }
+
+ buf, err := ioutil.ReadAll(httpRsp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := unm.Unmarshal(buf, resp); err != nil {
+ return maybeUnknownEnum(err)
+ }
+
+ return nil
+ }, opts...)
+ if e != nil {
+ return nil, "", e
+ }
+ it.Response = resp
+ return resp.GetOperations(), resp.GetNextPageToken(), nil
+ }
+
+ fetch := func(pageSize int, pageToken string) (string, error) {
+ items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
+ if err != nil {
+ return "", err
+ }
+ it.items = append(it.items, items...)
+ return nextPageToken, nil
+ }
+
+ it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
+ it.pageInfo.MaxSize = int(req.GetPageSize())
+ it.pageInfo.Token = req.GetPageToken()
+
+ return it
+}
+
// CreateFunctionOperation manages a long-running operation from CreateFunction.
type CreateFunctionOperation struct {
- lro *longrunning.Operation
+ lro *longrunning.Operation
+ pollPath string
}
// CreateFunctionOperation returns a new CreateFunctionOperation from a given name.
@@ -739,10 +1829,21 @@
}
}
+// CreateFunctionOperation returns a new CreateFunctionOperation from a given name.
+// The name must be that of a previously created CreateFunctionOperation, possibly from a different process.
+func (c *functionRESTClient) CreateFunctionOperation(name string) *CreateFunctionOperation {
+ override := fmt.Sprintf("/v2beta/%s", name)
+ return &CreateFunctionOperation{
+ lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}),
+ pollPath: override,
+ }
+}
+
// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *CreateFunctionOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*functionspb.Function, error) {
+ opts = append([]gax.CallOption{gax.WithPath(op.pollPath)}, opts...)
var resp functionspb.Function
if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
return nil, err
@@ -760,6 +1861,7 @@
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *CreateFunctionOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*functionspb.Function, error) {
+ opts = append([]gax.CallOption{gax.WithPath(op.pollPath)}, opts...)
var resp functionspb.Function
if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
return nil, err
@@ -797,7 +1899,8 @@
// DeleteFunctionOperation manages a long-running operation from DeleteFunction.
type DeleteFunctionOperation struct {
- lro *longrunning.Operation
+ lro *longrunning.Operation
+ pollPath string
}
// DeleteFunctionOperation returns a new DeleteFunctionOperation from a given name.
@@ -808,10 +1911,21 @@
}
}
+// DeleteFunctionOperation returns a new DeleteFunctionOperation from a given name.
+// The name must be that of a previously created DeleteFunctionOperation, possibly from a different process.
+func (c *functionRESTClient) DeleteFunctionOperation(name string) *DeleteFunctionOperation {
+ override := fmt.Sprintf("/v2beta/%s", name)
+ return &DeleteFunctionOperation{
+ lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}),
+ pollPath: override,
+ }
+}
+
// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *DeleteFunctionOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
+ opts = append([]gax.CallOption{gax.WithPath(op.pollPath)}, opts...)
return op.lro.WaitWithInterval(ctx, nil, time.Minute, opts...)
}
@@ -825,6 +1939,7 @@
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *DeleteFunctionOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
+ opts = append([]gax.CallOption{gax.WithPath(op.pollPath)}, opts...)
return op.lro.Poll(ctx, nil, opts...)
}
@@ -855,7 +1970,8 @@
// UpdateFunctionOperation manages a long-running operation from UpdateFunction.
type UpdateFunctionOperation struct {
- lro *longrunning.Operation
+ lro *longrunning.Operation
+ pollPath string
}
// UpdateFunctionOperation returns a new UpdateFunctionOperation from a given name.
@@ -866,10 +1982,21 @@
}
}
+// UpdateFunctionOperation returns a new UpdateFunctionOperation from a given name.
+// The name must be that of a previously created UpdateFunctionOperation, possibly from a different process.
+func (c *functionRESTClient) UpdateFunctionOperation(name string) *UpdateFunctionOperation {
+ override := fmt.Sprintf("/v2beta/%s", name)
+ return &UpdateFunctionOperation{
+ lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}),
+ pollPath: override,
+ }
+}
+
// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *UpdateFunctionOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*functionspb.Function, error) {
+ opts = append([]gax.CallOption{gax.WithPath(op.pollPath)}, opts...)
var resp functionspb.Function
if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
return nil, err
@@ -887,6 +2014,7 @@
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *UpdateFunctionOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*functionspb.Function, error) {
+ opts = append([]gax.CallOption{gax.WithPath(op.pollPath)}, opts...)
var resp functionspb.Function
if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
return nil, err
diff --git a/functions/apiv2beta/function_client_example_test.go b/functions/apiv2beta/function_client_example_test.go
index 51c1865..3f30c75 100644
--- a/functions/apiv2beta/function_client_example_test.go
+++ b/functions/apiv2beta/function_client_example_test.go
@@ -39,6 +39,18 @@
_ = c
}
+func ExampleNewFunctionRESTClient() {
+ ctx := context.Background()
+ c, err := functions.NewFunctionRESTClient(ctx)
+ if err != nil {
+ // TODO: Handle error.
+ }
+ defer c.Close()
+
+ // TODO: Use client.
+ _ = c
+}
+
func ExampleFunctionClient_GetFunction() {
ctx := context.Background()
c, err := functions.NewFunctionClient(ctx)
diff --git a/functions/apiv2beta/gapic_metadata.json b/functions/apiv2beta/gapic_metadata.json
index da22a59..0896e21 100644
--- a/functions/apiv2beta/gapic_metadata.json
+++ b/functions/apiv2beta/gapic_metadata.json
@@ -81,6 +81,81 @@
]
}
}
+ },
+ "rest": {
+ "libraryClient": "FunctionClient",
+ "rpcs": {
+ "CreateFunction": {
+ "methods": [
+ "CreateFunction"
+ ]
+ },
+ "DeleteFunction": {
+ "methods": [
+ "DeleteFunction"
+ ]
+ },
+ "GenerateDownloadUrl": {
+ "methods": [
+ "GenerateDownloadUrl"
+ ]
+ },
+ "GenerateUploadUrl": {
+ "methods": [
+ "GenerateUploadUrl"
+ ]
+ },
+ "GetFunction": {
+ "methods": [
+ "GetFunction"
+ ]
+ },
+ "GetIamPolicy": {
+ "methods": [
+ "GetIamPolicy"
+ ]
+ },
+ "GetOperation": {
+ "methods": [
+ "GetOperation"
+ ]
+ },
+ "ListFunctions": {
+ "methods": [
+ "ListFunctions"
+ ]
+ },
+ "ListLocations": {
+ "methods": [
+ "ListLocations"
+ ]
+ },
+ "ListOperations": {
+ "methods": [
+ "ListOperations"
+ ]
+ },
+ "ListRuntimes": {
+ "methods": [
+ "ListRuntimes"
+ ]
+ },
+ "SetIamPolicy": {
+ "methods": [
+ "SetIamPolicy"
+ ]
+ },
+ "TestIamPermissions": {
+ "methods": [
+ "TestIamPermissions"
+ ]
+ },
+ "UpdateFunction": {
+ "methods": [
+ "UpdateFunction"
+ ]
+ }
+ }
}
}
}
diff --git a/internal/gapicgen/generator/config.go b/internal/gapicgen/generator/config.go
index c32759b..8691217 100644
--- a/internal/gapicgen/generator/config.go
+++ b/internal/gapicgen/generator/config.go
@@ -1558,6 +1558,7 @@
ImportPath: "cloud.google.com/go/functions/apiv2beta",
GRPCServiceConfigPath: "functions_grpc_service_config.json",
ApiServiceConfigPath: "cloudfunctions_v2beta.yaml",
+ Transports: []string{"grpc", "rest"},
ReleaseLevel: "beta",
},