1// Code generated by smithy-go-codegen DO NOT EDIT.
2
3package schemas
4
5import (
6	"context"
7	"errors"
8	"fmt"
9	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
10	"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
11	"github.com/aws/aws-sdk-go-v2/service/schemas/types"
12	"github.com/aws/smithy-go/middleware"
13	smithytime "github.com/aws/smithy-go/time"
14	smithyhttp "github.com/aws/smithy-go/transport/http"
15	smithywaiter "github.com/aws/smithy-go/waiter"
16	"github.com/jmespath/go-jmespath"
17	"time"
18)
19
20// Describe the code binding URI.
21func (c *Client) DescribeCodeBinding(ctx context.Context, params *DescribeCodeBindingInput, optFns ...func(*Options)) (*DescribeCodeBindingOutput, error) {
22	if params == nil {
23		params = &DescribeCodeBindingInput{}
24	}
25
26	result, metadata, err := c.invokeOperation(ctx, "DescribeCodeBinding", params, optFns, addOperationDescribeCodeBindingMiddlewares)
27	if err != nil {
28		return nil, err
29	}
30
31	out := result.(*DescribeCodeBindingOutput)
32	out.ResultMetadata = metadata
33	return out, nil
34}
35
36type DescribeCodeBindingInput struct {
37
38	// The language of the code binding.
39	//
40	// This member is required.
41	Language *string
42
43	// The name of the registry.
44	//
45	// This member is required.
46	RegistryName *string
47
48	// The name of the schema.
49	//
50	// This member is required.
51	SchemaName *string
52
53	// Specifying this limits the results to only this schema version.
54	SchemaVersion *string
55}
56
57type DescribeCodeBindingOutput struct {
58
59	// The time and date that the code binding was created.
60	CreationDate *time.Time
61
62	// The date and time that code bindings were modified.
63	LastModified *time.Time
64
65	// The version number of the schema.
66	SchemaVersion *string
67
68	// The current status of code binding generation.
69	Status types.CodeGenerationStatus
70
71	// Metadata pertaining to the operation's result.
72	ResultMetadata middleware.Metadata
73}
74
75func addOperationDescribeCodeBindingMiddlewares(stack *middleware.Stack, options Options) (err error) {
76	err = stack.Serialize.Add(&awsRestjson1_serializeOpDescribeCodeBinding{}, middleware.After)
77	if err != nil {
78		return err
79	}
80	err = stack.Deserialize.Add(&awsRestjson1_deserializeOpDescribeCodeBinding{}, middleware.After)
81	if err != nil {
82		return err
83	}
84	if err = addSetLoggerMiddleware(stack, options); err != nil {
85		return err
86	}
87	if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
88		return err
89	}
90	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
91		return err
92	}
93	if err = addResolveEndpointMiddleware(stack, options); err != nil {
94		return err
95	}
96	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
97		return err
98	}
99	if err = addRetryMiddlewares(stack, options); err != nil {
100		return err
101	}
102	if err = addHTTPSignerV4Middleware(stack, options); err != nil {
103		return err
104	}
105	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
106		return err
107	}
108	if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
109		return err
110	}
111	if err = addClientUserAgent(stack); err != nil {
112		return err
113	}
114	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
115		return err
116	}
117	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
118		return err
119	}
120	if err = addOpDescribeCodeBindingValidationMiddleware(stack); err != nil {
121		return err
122	}
123	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeCodeBinding(options.Region), middleware.Before); err != nil {
124		return err
125	}
126	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
127		return err
128	}
129	if err = addResponseErrorMiddleware(stack); err != nil {
130		return err
131	}
132	if err = addRequestResponseLogging(stack, options); err != nil {
133		return err
134	}
135	return nil
136}
137
138// DescribeCodeBindingAPIClient is a client that implements the DescribeCodeBinding
139// operation.
140type DescribeCodeBindingAPIClient interface {
141	DescribeCodeBinding(context.Context, *DescribeCodeBindingInput, ...func(*Options)) (*DescribeCodeBindingOutput, error)
142}
143
144var _ DescribeCodeBindingAPIClient = (*Client)(nil)
145
146// CodeBindingExistsWaiterOptions are waiter options for CodeBindingExistsWaiter
147type CodeBindingExistsWaiterOptions struct {
148
149	// Set of options to modify how an operation is invoked. These apply to all
150	// operations invoked for this client. Use functional options on operation call to
151	// modify this list for per operation behavior.
152	APIOptions []func(*middleware.Stack) error
153
154	// MinDelay is the minimum amount of time to delay between retries. If unset,
155	// CodeBindingExistsWaiter will use default minimum delay of 2 seconds. Note that
156	// MinDelay must resolve to a value lesser than or equal to the MaxDelay.
157	MinDelay time.Duration
158
159	// MaxDelay is the maximum amount of time to delay between retries. If unset or set
160	// to zero, CodeBindingExistsWaiter will use default max delay of 120 seconds. Note
161	// that MaxDelay must resolve to value greater than or equal to the MinDelay.
162	MaxDelay time.Duration
163
164	// LogWaitAttempts is used to enable logging for waiter retry attempts
165	LogWaitAttempts bool
166
167	// Retryable is function that can be used to override the service defined
168	// waiter-behavior based on operation output, or returned error. This function is
169	// used by the waiter to decide if a state is retryable or a terminal state. By
170	// default service-modeled logic will populate this option. This option can thus be
171	// used to define a custom waiter state with fall-back to service-modeled waiter
172	// state mutators.The function returns an error in case of a failure state. In case
173	// of retry state, this function returns a bool value of true and nil error, while
174	// in case of success it returns a bool value of false and nil error.
175	Retryable func(context.Context, *DescribeCodeBindingInput, *DescribeCodeBindingOutput, error) (bool, error)
176}
177
178// CodeBindingExistsWaiter defines the waiters for CodeBindingExists
179type CodeBindingExistsWaiter struct {
180	client DescribeCodeBindingAPIClient
181
182	options CodeBindingExistsWaiterOptions
183}
184
185// NewCodeBindingExistsWaiter constructs a CodeBindingExistsWaiter.
186func NewCodeBindingExistsWaiter(client DescribeCodeBindingAPIClient, optFns ...func(*CodeBindingExistsWaiterOptions)) *CodeBindingExistsWaiter {
187	options := CodeBindingExistsWaiterOptions{}
188	options.MinDelay = 2 * time.Second
189	options.MaxDelay = 120 * time.Second
190	options.Retryable = codeBindingExistsStateRetryable
191
192	for _, fn := range optFns {
193		fn(&options)
194	}
195	return &CodeBindingExistsWaiter{
196		client:  client,
197		options: options,
198	}
199}
200
201// Wait calls the waiter function for CodeBindingExists waiter. The maxWaitDur is
202// the maximum wait duration the waiter will wait. The maxWaitDur is required and
203// must be greater than zero.
204func (w *CodeBindingExistsWaiter) Wait(ctx context.Context, params *DescribeCodeBindingInput, maxWaitDur time.Duration, optFns ...func(*CodeBindingExistsWaiterOptions)) error {
205	if maxWaitDur <= 0 {
206		return fmt.Errorf("maximum wait time for waiter must be greater than zero")
207	}
208
209	options := w.options
210	for _, fn := range optFns {
211		fn(&options)
212	}
213
214	if options.MaxDelay <= 0 {
215		options.MaxDelay = 120 * time.Second
216	}
217
218	if options.MinDelay > options.MaxDelay {
219		return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
220	}
221
222	ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
223	defer cancelFn()
224
225	logger := smithywaiter.Logger{}
226	remainingTime := maxWaitDur
227
228	var attempt int64
229	for {
230
231		attempt++
232		apiOptions := options.APIOptions
233		start := time.Now()
234
235		if options.LogWaitAttempts {
236			logger.Attempt = attempt
237			apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
238			apiOptions = append(apiOptions, logger.AddLogger)
239		}
240
241		out, err := w.client.DescribeCodeBinding(ctx, params, func(o *Options) {
242			o.APIOptions = append(o.APIOptions, apiOptions...)
243		})
244
245		retryable, err := options.Retryable(ctx, params, out, err)
246		if err != nil {
247			return err
248		}
249		if !retryable {
250			return nil
251		}
252
253		remainingTime -= time.Since(start)
254		if remainingTime < options.MinDelay || remainingTime <= 0 {
255			break
256		}
257
258		// compute exponential backoff between waiter retries
259		delay, err := smithywaiter.ComputeDelay(
260			attempt, options.MinDelay, options.MaxDelay, remainingTime,
261		)
262		if err != nil {
263			return fmt.Errorf("error computing waiter delay, %w", err)
264		}
265
266		remainingTime -= delay
267		// sleep for the delay amount before invoking a request
268		if err := smithytime.SleepWithContext(ctx, delay); err != nil {
269			return fmt.Errorf("request cancelled while waiting, %w", err)
270		}
271	}
272	return fmt.Errorf("exceeded max wait time for CodeBindingExists waiter")
273}
274
275func codeBindingExistsStateRetryable(ctx context.Context, input *DescribeCodeBindingInput, output *DescribeCodeBindingOutput, err error) (bool, error) {
276
277	if err == nil {
278		pathValue, err := jmespath.Search("Status", output)
279		if err != nil {
280			return false, fmt.Errorf("error evaluating waiter state: %w", err)
281		}
282
283		expectedValue := "CREATE_COMPLETE"
284		value, ok := pathValue.(types.CodeGenerationStatus)
285		if !ok {
286			return false, fmt.Errorf("waiter comparator expected types.CodeGenerationStatus value, got %T", pathValue)
287		}
288
289		if string(value) == expectedValue {
290			return false, nil
291		}
292	}
293
294	if err == nil {
295		pathValue, err := jmespath.Search("Status", output)
296		if err != nil {
297			return false, fmt.Errorf("error evaluating waiter state: %w", err)
298		}
299
300		expectedValue := "CREATE_IN_PROGRESS"
301		value, ok := pathValue.(types.CodeGenerationStatus)
302		if !ok {
303			return false, fmt.Errorf("waiter comparator expected types.CodeGenerationStatus value, got %T", pathValue)
304		}
305
306		if string(value) == expectedValue {
307			return true, nil
308		}
309	}
310
311	if err == nil {
312		pathValue, err := jmespath.Search("Status", output)
313		if err != nil {
314			return false, fmt.Errorf("error evaluating waiter state: %w", err)
315		}
316
317		expectedValue := "CREATE_FAILED"
318		value, ok := pathValue.(types.CodeGenerationStatus)
319		if !ok {
320			return false, fmt.Errorf("waiter comparator expected types.CodeGenerationStatus value, got %T", pathValue)
321		}
322
323		if string(value) == expectedValue {
324			return false, fmt.Errorf("waiter state transitioned to Failure")
325		}
326	}
327
328	if err != nil {
329		var errorType *types.NotFoundException
330		if errors.As(err, &errorType) {
331			return false, fmt.Errorf("waiter state transitioned to Failure")
332		}
333	}
334
335	return true, nil
336}
337
338func newServiceMetadataMiddleware_opDescribeCodeBinding(region string) *awsmiddleware.RegisterServiceMetadata {
339	return &awsmiddleware.RegisterServiceMetadata{
340		Region:        region,
341		ServiceID:     ServiceID,
342		SigningName:   "schemas",
343		OperationName: "DescribeCodeBinding",
344	}
345}
346