1// Copyright 2020 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
16
17package workflows
18
19import (
20	"context"
21	"fmt"
22	"math"
23	"net/url"
24	"time"
25
26	"cloud.google.com/go/longrunning"
27	lroauto "cloud.google.com/go/longrunning/autogen"
28	"github.com/golang/protobuf/proto"
29	gax "github.com/googleapis/gax-go/v2"
30	"google.golang.org/api/iterator"
31	"google.golang.org/api/option"
32	gtransport "google.golang.org/api/transport/grpc"
33	workflowspb "google.golang.org/genproto/googleapis/cloud/workflows/v1beta"
34	longrunningpb "google.golang.org/genproto/googleapis/longrunning"
35	"google.golang.org/grpc"
36	"google.golang.org/grpc/metadata"
37)
38
39var newClientHook clientHook
40
41// CallOptions contains the retry settings for each method of Client.
42type CallOptions struct {
43	ListWorkflows  []gax.CallOption
44	GetWorkflow    []gax.CallOption
45	CreateWorkflow []gax.CallOption
46	DeleteWorkflow []gax.CallOption
47	UpdateWorkflow []gax.CallOption
48}
49
50func defaultClientOptions() []option.ClientOption {
51	return []option.ClientOption{
52		option.WithEndpoint("workflows.googleapis.com:443"),
53		option.WithGRPCDialOption(grpc.WithDisableServiceConfig()),
54		option.WithScopes(DefaultAuthScopes()...),
55		option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
56			grpc.MaxCallRecvMsgSize(math.MaxInt32))),
57	}
58}
59
60func defaultCallOptions() *CallOptions {
61	return &CallOptions{
62		ListWorkflows:  []gax.CallOption{},
63		GetWorkflow:    []gax.CallOption{},
64		CreateWorkflow: []gax.CallOption{},
65		DeleteWorkflow: []gax.CallOption{},
66		UpdateWorkflow: []gax.CallOption{},
67	}
68}
69
70// Client is a client for interacting with .
71//
72// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
73type Client struct {
74	// Connection pool of gRPC connections to the service.
75	connPool gtransport.ConnPool
76
77	// flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE
78	disableDeadlines bool
79
80	// The gRPC API client.
81	client workflowspb.WorkflowsClient
82
83	// LROClient is used internally to handle longrunning operations.
84	// It is exposed so that its CallOptions can be modified if required.
85	// Users should not Close this client.
86	LROClient *lroauto.OperationsClient
87
88	// The call options for this service.
89	CallOptions *CallOptions
90
91	// The x-goog-* metadata to be sent with each request.
92	xGoogMetadata metadata.MD
93}
94
95// NewClient creates a new workflows client.
96//
97// Workflows is used to deploy and execute workflow programs.
98// Workflows makes sure the program executes reliably, despite hardware and
99// networking interruptions.
100func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
101	clientOpts := defaultClientOptions()
102
103	if newClientHook != nil {
104		hookOpts, err := newClientHook(ctx, clientHookParams{})
105		if err != nil {
106			return nil, err
107		}
108		clientOpts = append(clientOpts, hookOpts...)
109	}
110
111	disableDeadlines, err := checkDisableDeadlines()
112	if err != nil {
113		return nil, err
114	}
115
116	connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...)
117	if err != nil {
118		return nil, err
119	}
120	c := &Client{
121		connPool:         connPool,
122		disableDeadlines: disableDeadlines,
123		CallOptions:      defaultCallOptions(),
124
125		client: workflowspb.NewWorkflowsClient(connPool),
126	}
127	c.setGoogleClientInfo()
128
129	c.LROClient, err = lroauto.NewOperationsClient(ctx, gtransport.WithConnPool(connPool))
130	if err != nil {
131		// This error "should not happen", since we are just reusing old connection pool
132		// and never actually need to dial.
133		// If this does happen, we could leak connp. However, we cannot close conn:
134		// If the user invoked the constructor with option.WithGRPCConn,
135		// we would close a connection that's still in use.
136		// TODO: investigate error conditions.
137		return nil, err
138	}
139	return c, nil
140}
141
142// Connection returns a connection to the API service.
143//
144// Deprecated.
145func (c *Client) Connection() *grpc.ClientConn {
146	return c.connPool.Conn()
147}
148
149// Close closes the connection to the API service. The user should invoke this when
150// the client is no longer required.
151func (c *Client) Close() error {
152	return c.connPool.Close()
153}
154
155// setGoogleClientInfo sets the name and version of the application in
156// the `x-goog-api-client` header passed on each request. Intended for
157// use by Google-written clients.
158func (c *Client) setGoogleClientInfo(keyval ...string) {
159	kv := append([]string{"gl-go", versionGo()}, keyval...)
160	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version)
161	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
162}
163
164// ListWorkflows lists Workflows in a given project and location.
165// The default order is not specified.
166func (c *Client) ListWorkflows(ctx context.Context, req *workflowspb.ListWorkflowsRequest, opts ...gax.CallOption) *WorkflowIterator {
167	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
168	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
169	opts = append(c.CallOptions.ListWorkflows[0:len(c.CallOptions.ListWorkflows):len(c.CallOptions.ListWorkflows)], opts...)
170	it := &WorkflowIterator{}
171	req = proto.Clone(req).(*workflowspb.ListWorkflowsRequest)
172	it.InternalFetch = func(pageSize int, pageToken string) ([]*workflowspb.Workflow, string, error) {
173		var resp *workflowspb.ListWorkflowsResponse
174		req.PageToken = pageToken
175		if pageSize > math.MaxInt32 {
176			req.PageSize = math.MaxInt32
177		} else {
178			req.PageSize = int32(pageSize)
179		}
180		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
181			var err error
182			resp, err = c.client.ListWorkflows(ctx, req, settings.GRPC...)
183			return err
184		}, opts...)
185		if err != nil {
186			return nil, "", err
187		}
188
189		it.Response = resp
190		return resp.GetWorkflows(), resp.GetNextPageToken(), nil
191	}
192	fetch := func(pageSize int, pageToken string) (string, error) {
193		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
194		if err != nil {
195			return "", err
196		}
197		it.items = append(it.items, items...)
198		return nextPageToken, nil
199	}
200	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
201	it.pageInfo.MaxSize = int(req.GetPageSize())
202	it.pageInfo.Token = req.GetPageToken()
203	return it
204}
205
206// GetWorkflow gets details of a single Workflow.
207func (c *Client) GetWorkflow(ctx context.Context, req *workflowspb.GetWorkflowRequest, opts ...gax.CallOption) (*workflowspb.Workflow, error) {
208	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
209	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
210	opts = append(c.CallOptions.GetWorkflow[0:len(c.CallOptions.GetWorkflow):len(c.CallOptions.GetWorkflow)], opts...)
211	var resp *workflowspb.Workflow
212	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
213		var err error
214		resp, err = c.client.GetWorkflow(ctx, req, settings.GRPC...)
215		return err
216	}, opts...)
217	if err != nil {
218		return nil, err
219	}
220	return resp, nil
221}
222
223// CreateWorkflow creates a new workflow. If a workflow with the specified name already
224// exists in the specified project and location, the long running operation
225// will return ALREADY_EXISTS error.
226func (c *Client) CreateWorkflow(ctx context.Context, req *workflowspb.CreateWorkflowRequest, opts ...gax.CallOption) (*CreateWorkflowOperation, error) {
227	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
228	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
229	opts = append(c.CallOptions.CreateWorkflow[0:len(c.CallOptions.CreateWorkflow):len(c.CallOptions.CreateWorkflow)], opts...)
230	var resp *longrunningpb.Operation
231	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
232		var err error
233		resp, err = c.client.CreateWorkflow(ctx, req, settings.GRPC...)
234		return err
235	}, opts...)
236	if err != nil {
237		return nil, err
238	}
239	return &CreateWorkflowOperation{
240		lro: longrunning.InternalNewOperation(c.LROClient, resp),
241	}, nil
242}
243
244// DeleteWorkflow deletes a workflow with the specified name.
245// This method also cancels and deletes all running executions of the
246// workflow.
247func (c *Client) DeleteWorkflow(ctx context.Context, req *workflowspb.DeleteWorkflowRequest, opts ...gax.CallOption) (*DeleteWorkflowOperation, error) {
248	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
249	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
250	opts = append(c.CallOptions.DeleteWorkflow[0:len(c.CallOptions.DeleteWorkflow):len(c.CallOptions.DeleteWorkflow)], opts...)
251	var resp *longrunningpb.Operation
252	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
253		var err error
254		resp, err = c.client.DeleteWorkflow(ctx, req, settings.GRPC...)
255		return err
256	}, opts...)
257	if err != nil {
258		return nil, err
259	}
260	return &DeleteWorkflowOperation{
261		lro: longrunning.InternalNewOperation(c.LROClient, resp),
262	}, nil
263}
264
265// UpdateWorkflow updates an existing workflow.
266// Running this method has no impact on already running executions of the
267// workflow. A new revision of the workflow may be created as a result of a
268// successful update operation. In that case, such revision will be used
269// in new workflow executions.
270func (c *Client) UpdateWorkflow(ctx context.Context, req *workflowspb.UpdateWorkflowRequest, opts ...gax.CallOption) (*UpdateWorkflowOperation, error) {
271	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "workflow.name", url.QueryEscape(req.GetWorkflow().GetName())))
272	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
273	opts = append(c.CallOptions.UpdateWorkflow[0:len(c.CallOptions.UpdateWorkflow):len(c.CallOptions.UpdateWorkflow)], opts...)
274	var resp *longrunningpb.Operation
275	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
276		var err error
277		resp, err = c.client.UpdateWorkflow(ctx, req, settings.GRPC...)
278		return err
279	}, opts...)
280	if err != nil {
281		return nil, err
282	}
283	return &UpdateWorkflowOperation{
284		lro: longrunning.InternalNewOperation(c.LROClient, resp),
285	}, nil
286}
287
288// CreateWorkflowOperation manages a long-running operation from CreateWorkflow.
289type CreateWorkflowOperation struct {
290	lro *longrunning.Operation
291}
292
293// CreateWorkflowOperation returns a new CreateWorkflowOperation from a given name.
294// The name must be that of a previously created CreateWorkflowOperation, possibly from a different process.
295func (c *Client) CreateWorkflowOperation(name string) *CreateWorkflowOperation {
296	return &CreateWorkflowOperation{
297		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
298	}
299}
300
301// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
302//
303// See documentation of Poll for error-handling information.
304func (op *CreateWorkflowOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*workflowspb.Workflow, error) {
305	var resp workflowspb.Workflow
306	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
307		return nil, err
308	}
309	return &resp, nil
310}
311
312// Poll fetches the latest state of the long-running operation.
313//
314// Poll also fetches the latest metadata, which can be retrieved by Metadata.
315//
316// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
317// the operation has completed with failure, the error is returned and op.Done will return true.
318// If Poll succeeds and the operation has completed successfully,
319// op.Done will return true, and the response of the operation is returned.
320// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
321func (op *CreateWorkflowOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*workflowspb.Workflow, error) {
322	var resp workflowspb.Workflow
323	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
324		return nil, err
325	}
326	if !op.Done() {
327		return nil, nil
328	}
329	return &resp, nil
330}
331
332// Metadata returns metadata associated with the long-running operation.
333// Metadata itself does not contact the server, but Poll does.
334// To get the latest metadata, call this method after a successful call to Poll.
335// If the metadata is not available, the returned metadata and error are both nil.
336func (op *CreateWorkflowOperation) Metadata() (*workflowspb.OperationMetadata, error) {
337	var meta workflowspb.OperationMetadata
338	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
339		return nil, nil
340	} else if err != nil {
341		return nil, err
342	}
343	return &meta, nil
344}
345
346// Done reports whether the long-running operation has completed.
347func (op *CreateWorkflowOperation) Done() bool {
348	return op.lro.Done()
349}
350
351// Name returns the name of the long-running operation.
352// The name is assigned by the server and is unique within the service from which the operation is created.
353func (op *CreateWorkflowOperation) Name() string {
354	return op.lro.Name()
355}
356
357// DeleteWorkflowOperation manages a long-running operation from DeleteWorkflow.
358type DeleteWorkflowOperation struct {
359	lro *longrunning.Operation
360}
361
362// DeleteWorkflowOperation returns a new DeleteWorkflowOperation from a given name.
363// The name must be that of a previously created DeleteWorkflowOperation, possibly from a different process.
364func (c *Client) DeleteWorkflowOperation(name string) *DeleteWorkflowOperation {
365	return &DeleteWorkflowOperation{
366		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
367	}
368}
369
370// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
371//
372// See documentation of Poll for error-handling information.
373func (op *DeleteWorkflowOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
374	return op.lro.WaitWithInterval(ctx, nil, time.Minute, opts...)
375}
376
377// Poll fetches the latest state of the long-running operation.
378//
379// Poll also fetches the latest metadata, which can be retrieved by Metadata.
380//
381// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
382// the operation has completed with failure, the error is returned and op.Done will return true.
383// If Poll succeeds and the operation has completed successfully,
384// op.Done will return true, and the response of the operation is returned.
385// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
386func (op *DeleteWorkflowOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
387	return op.lro.Poll(ctx, nil, opts...)
388}
389
390// Metadata returns metadata associated with the long-running operation.
391// Metadata itself does not contact the server, but Poll does.
392// To get the latest metadata, call this method after a successful call to Poll.
393// If the metadata is not available, the returned metadata and error are both nil.
394func (op *DeleteWorkflowOperation) Metadata() (*workflowspb.OperationMetadata, error) {
395	var meta workflowspb.OperationMetadata
396	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
397		return nil, nil
398	} else if err != nil {
399		return nil, err
400	}
401	return &meta, nil
402}
403
404// Done reports whether the long-running operation has completed.
405func (op *DeleteWorkflowOperation) Done() bool {
406	return op.lro.Done()
407}
408
409// Name returns the name of the long-running operation.
410// The name is assigned by the server and is unique within the service from which the operation is created.
411func (op *DeleteWorkflowOperation) Name() string {
412	return op.lro.Name()
413}
414
415// UpdateWorkflowOperation manages a long-running operation from UpdateWorkflow.
416type UpdateWorkflowOperation struct {
417	lro *longrunning.Operation
418}
419
420// UpdateWorkflowOperation returns a new UpdateWorkflowOperation from a given name.
421// The name must be that of a previously created UpdateWorkflowOperation, possibly from a different process.
422func (c *Client) UpdateWorkflowOperation(name string) *UpdateWorkflowOperation {
423	return &UpdateWorkflowOperation{
424		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
425	}
426}
427
428// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
429//
430// See documentation of Poll for error-handling information.
431func (op *UpdateWorkflowOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*workflowspb.Workflow, error) {
432	var resp workflowspb.Workflow
433	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
434		return nil, err
435	}
436	return &resp, nil
437}
438
439// Poll fetches the latest state of the long-running operation.
440//
441// Poll also fetches the latest metadata, which can be retrieved by Metadata.
442//
443// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
444// the operation has completed with failure, the error is returned and op.Done will return true.
445// If Poll succeeds and the operation has completed successfully,
446// op.Done will return true, and the response of the operation is returned.
447// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
448func (op *UpdateWorkflowOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*workflowspb.Workflow, error) {
449	var resp workflowspb.Workflow
450	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
451		return nil, err
452	}
453	if !op.Done() {
454		return nil, nil
455	}
456	return &resp, nil
457}
458
459// Metadata returns metadata associated with the long-running operation.
460// Metadata itself does not contact the server, but Poll does.
461// To get the latest metadata, call this method after a successful call to Poll.
462// If the metadata is not available, the returned metadata and error are both nil.
463func (op *UpdateWorkflowOperation) Metadata() (*workflowspb.OperationMetadata, error) {
464	var meta workflowspb.OperationMetadata
465	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
466		return nil, nil
467	} else if err != nil {
468		return nil, err
469	}
470	return &meta, nil
471}
472
473// Done reports whether the long-running operation has completed.
474func (op *UpdateWorkflowOperation) Done() bool {
475	return op.lro.Done()
476}
477
478// Name returns the name of the long-running operation.
479// The name is assigned by the server and is unique within the service from which the operation is created.
480func (op *UpdateWorkflowOperation) Name() string {
481	return op.lro.Name()
482}
483
484// WorkflowIterator manages a stream of *workflowspb.Workflow.
485type WorkflowIterator struct {
486	items    []*workflowspb.Workflow
487	pageInfo *iterator.PageInfo
488	nextFunc func() error
489
490	// Response is the raw response for the current page.
491	// It must be cast to the RPC response type.
492	// Calling Next() or InternalFetch() updates this value.
493	Response interface{}
494
495	// InternalFetch is for use by the Google Cloud Libraries only.
496	// It is not part of the stable interface of this package.
497	//
498	// InternalFetch returns results from a single call to the underlying RPC.
499	// The number of results is no greater than pageSize.
500	// If there are no more results, nextPageToken is empty and err is nil.
501	InternalFetch func(pageSize int, pageToken string) (results []*workflowspb.Workflow, nextPageToken string, err error)
502}
503
504// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
505func (it *WorkflowIterator) PageInfo() *iterator.PageInfo {
506	return it.pageInfo
507}
508
509// Next returns the next result. Its second return value is iterator.Done if there are no more
510// results. Once Next returns Done, all subsequent calls will return Done.
511func (it *WorkflowIterator) Next() (*workflowspb.Workflow, error) {
512	var item *workflowspb.Workflow
513	if err := it.nextFunc(); err != nil {
514		return item, err
515	}
516	item = it.items[0]
517	it.items = it.items[1:]
518	return item, nil
519}
520
521func (it *WorkflowIterator) bufLen() int {
522	return len(it.items)
523}
524
525func (it *WorkflowIterator) takeBuf() interface{} {
526	b := it.items
527	it.items = nil
528	return b
529}
530