1// Code generated by smithy-go-codegen DO NOT EDIT.
2
3package medialive
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/medialive/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// Gets details about a channel
21func (c *Client) DescribeChannel(ctx context.Context, params *DescribeChannelInput, optFns ...func(*Options)) (*DescribeChannelOutput, error) {
22	if params == nil {
23		params = &DescribeChannelInput{}
24	}
25
26	result, metadata, err := c.invokeOperation(ctx, "DescribeChannel", params, optFns, addOperationDescribeChannelMiddlewares)
27	if err != nil {
28		return nil, err
29	}
30
31	out := result.(*DescribeChannelOutput)
32	out.ResultMetadata = metadata
33	return out, nil
34}
35
36// Placeholder documentation for DescribeChannelRequest
37type DescribeChannelInput struct {
38
39	// channel ID
40	//
41	// This member is required.
42	ChannelId *string
43}
44
45// Placeholder documentation for DescribeChannelResponse
46type DescribeChannelOutput struct {
47
48	// The unique arn of the channel.
49	Arn *string
50
51	// Specification of CDI inputs for this channel
52	CdiInputSpecification *types.CdiInputSpecification
53
54	// The class for this channel. STANDARD for a channel with two pipelines or
55	// SINGLE_PIPELINE for a channel with one pipeline.
56	ChannelClass types.ChannelClass
57
58	// A list of destinations of the channel. For UDP outputs, there is one destination
59	// per output. For other types (HLS, for example), there is one destination per
60	// packager.
61	Destinations []types.OutputDestination
62
63	// The endpoints where outgoing connections initiate from
64	EgressEndpoints []types.ChannelEgressEndpoint
65
66	// Encoder Settings
67	EncoderSettings *types.EncoderSettings
68
69	// The unique id of the channel.
70	Id *string
71
72	// List of input attachments for channel.
73	InputAttachments []types.InputAttachment
74
75	// Specification of network and file inputs for this channel
76	InputSpecification *types.InputSpecification
77
78	// The log level being written to CloudWatch Logs.
79	LogLevel types.LogLevel
80
81	// The name of the channel. (user-mutable)
82	Name *string
83
84	// Runtime details for the pipelines of a running channel.
85	PipelineDetails []types.PipelineDetail
86
87	// The number of currently healthy pipelines.
88	PipelinesRunningCount int32
89
90	// The Amazon Resource Name (ARN) of the role assumed when running the Channel.
91	RoleArn *string
92
93	// Placeholder documentation for ChannelState
94	State types.ChannelState
95
96	// A collection of key-value pairs.
97	Tags map[string]string
98
99	// Settings for VPC output
100	Vpc *types.VpcOutputSettingsDescription
101
102	// Metadata pertaining to the operation's result.
103	ResultMetadata middleware.Metadata
104}
105
106func addOperationDescribeChannelMiddlewares(stack *middleware.Stack, options Options) (err error) {
107	err = stack.Serialize.Add(&awsRestjson1_serializeOpDescribeChannel{}, middleware.After)
108	if err != nil {
109		return err
110	}
111	err = stack.Deserialize.Add(&awsRestjson1_deserializeOpDescribeChannel{}, middleware.After)
112	if err != nil {
113		return err
114	}
115	if err = addSetLoggerMiddleware(stack, options); err != nil {
116		return err
117	}
118	if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
119		return err
120	}
121	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
122		return err
123	}
124	if err = addResolveEndpointMiddleware(stack, options); err != nil {
125		return err
126	}
127	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
128		return err
129	}
130	if err = addRetryMiddlewares(stack, options); err != nil {
131		return err
132	}
133	if err = addHTTPSignerV4Middleware(stack, options); err != nil {
134		return err
135	}
136	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
137		return err
138	}
139	if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
140		return err
141	}
142	if err = addClientUserAgent(stack); err != nil {
143		return err
144	}
145	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
146		return err
147	}
148	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
149		return err
150	}
151	if err = addOpDescribeChannelValidationMiddleware(stack); err != nil {
152		return err
153	}
154	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeChannel(options.Region), middleware.Before); err != nil {
155		return err
156	}
157	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
158		return err
159	}
160	if err = addResponseErrorMiddleware(stack); err != nil {
161		return err
162	}
163	if err = addRequestResponseLogging(stack, options); err != nil {
164		return err
165	}
166	return nil
167}
168
169// DescribeChannelAPIClient is a client that implements the DescribeChannel
170// operation.
171type DescribeChannelAPIClient interface {
172	DescribeChannel(context.Context, *DescribeChannelInput, ...func(*Options)) (*DescribeChannelOutput, error)
173}
174
175var _ DescribeChannelAPIClient = (*Client)(nil)
176
177// ChannelCreatedWaiterOptions are waiter options for ChannelCreatedWaiter
178type ChannelCreatedWaiterOptions struct {
179
180	// Set of options to modify how an operation is invoked. These apply to all
181	// operations invoked for this client. Use functional options on operation call to
182	// modify this list for per operation behavior.
183	APIOptions []func(*middleware.Stack) error
184
185	// MinDelay is the minimum amount of time to delay between retries. If unset,
186	// ChannelCreatedWaiter will use default minimum delay of 3 seconds. Note that
187	// MinDelay must resolve to a value lesser than or equal to the MaxDelay.
188	MinDelay time.Duration
189
190	// MaxDelay is the maximum amount of time to delay between retries. If unset or set
191	// to zero, ChannelCreatedWaiter will use default max delay of 120 seconds. Note
192	// that MaxDelay must resolve to value greater than or equal to the MinDelay.
193	MaxDelay time.Duration
194
195	// LogWaitAttempts is used to enable logging for waiter retry attempts
196	LogWaitAttempts bool
197
198	// Retryable is function that can be used to override the service defined
199	// waiter-behavior based on operation output, or returned error. This function is
200	// used by the waiter to decide if a state is retryable or a terminal state. By
201	// default service-modeled logic will populate this option. This option can thus be
202	// used to define a custom waiter state with fall-back to service-modeled waiter
203	// state mutators.The function returns an error in case of a failure state. In case
204	// of retry state, this function returns a bool value of true and nil error, while
205	// in case of success it returns a bool value of false and nil error.
206	Retryable func(context.Context, *DescribeChannelInput, *DescribeChannelOutput, error) (bool, error)
207}
208
209// ChannelCreatedWaiter defines the waiters for ChannelCreated
210type ChannelCreatedWaiter struct {
211	client DescribeChannelAPIClient
212
213	options ChannelCreatedWaiterOptions
214}
215
216// NewChannelCreatedWaiter constructs a ChannelCreatedWaiter.
217func NewChannelCreatedWaiter(client DescribeChannelAPIClient, optFns ...func(*ChannelCreatedWaiterOptions)) *ChannelCreatedWaiter {
218	options := ChannelCreatedWaiterOptions{}
219	options.MinDelay = 3 * time.Second
220	options.MaxDelay = 120 * time.Second
221	options.Retryable = channelCreatedStateRetryable
222
223	for _, fn := range optFns {
224		fn(&options)
225	}
226	return &ChannelCreatedWaiter{
227		client:  client,
228		options: options,
229	}
230}
231
232// Wait calls the waiter function for ChannelCreated waiter. The maxWaitDur is the
233// maximum wait duration the waiter will wait. The maxWaitDur is required and must
234// be greater than zero.
235func (w *ChannelCreatedWaiter) Wait(ctx context.Context, params *DescribeChannelInput, maxWaitDur time.Duration, optFns ...func(*ChannelCreatedWaiterOptions)) error {
236	if maxWaitDur <= 0 {
237		return fmt.Errorf("maximum wait time for waiter must be greater than zero")
238	}
239
240	options := w.options
241	for _, fn := range optFns {
242		fn(&options)
243	}
244
245	if options.MaxDelay <= 0 {
246		options.MaxDelay = 120 * time.Second
247	}
248
249	if options.MinDelay > options.MaxDelay {
250		return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
251	}
252
253	ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
254	defer cancelFn()
255
256	logger := smithywaiter.Logger{}
257	remainingTime := maxWaitDur
258
259	var attempt int64
260	for {
261
262		attempt++
263		apiOptions := options.APIOptions
264		start := time.Now()
265
266		if options.LogWaitAttempts {
267			logger.Attempt = attempt
268			apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
269			apiOptions = append(apiOptions, logger.AddLogger)
270		}
271
272		out, err := w.client.DescribeChannel(ctx, params, func(o *Options) {
273			o.APIOptions = append(o.APIOptions, apiOptions...)
274		})
275
276		retryable, err := options.Retryable(ctx, params, out, err)
277		if err != nil {
278			return err
279		}
280		if !retryable {
281			return nil
282		}
283
284		remainingTime -= time.Since(start)
285		if remainingTime < options.MinDelay || remainingTime <= 0 {
286			break
287		}
288
289		// compute exponential backoff between waiter retries
290		delay, err := smithywaiter.ComputeDelay(
291			attempt, options.MinDelay, options.MaxDelay, remainingTime,
292		)
293		if err != nil {
294			return fmt.Errorf("error computing waiter delay, %w", err)
295		}
296
297		remainingTime -= delay
298		// sleep for the delay amount before invoking a request
299		if err := smithytime.SleepWithContext(ctx, delay); err != nil {
300			return fmt.Errorf("request cancelled while waiting, %w", err)
301		}
302	}
303	return fmt.Errorf("exceeded max wait time for ChannelCreated waiter")
304}
305
306func channelCreatedStateRetryable(ctx context.Context, input *DescribeChannelInput, output *DescribeChannelOutput, err error) (bool, error) {
307
308	if err == nil {
309		pathValue, err := jmespath.Search("State", output)
310		if err != nil {
311			return false, fmt.Errorf("error evaluating waiter state: %w", err)
312		}
313
314		expectedValue := "IDLE"
315		value, ok := pathValue.(types.ChannelState)
316		if !ok {
317			return false, fmt.Errorf("waiter comparator expected types.ChannelState value, got %T", pathValue)
318		}
319
320		if string(value) == expectedValue {
321			return false, nil
322		}
323	}
324
325	if err == nil {
326		pathValue, err := jmespath.Search("State", output)
327		if err != nil {
328			return false, fmt.Errorf("error evaluating waiter state: %w", err)
329		}
330
331		expectedValue := "CREATING"
332		value, ok := pathValue.(types.ChannelState)
333		if !ok {
334			return false, fmt.Errorf("waiter comparator expected types.ChannelState value, got %T", pathValue)
335		}
336
337		if string(value) == expectedValue {
338			return true, nil
339		}
340	}
341
342	if err != nil {
343		var errorType *types.InternalServerErrorException
344		if errors.As(err, &errorType) {
345			return true, nil
346		}
347	}
348
349	if err == nil {
350		pathValue, err := jmespath.Search("State", output)
351		if err != nil {
352			return false, fmt.Errorf("error evaluating waiter state: %w", err)
353		}
354
355		expectedValue := "CREATE_FAILED"
356		value, ok := pathValue.(types.ChannelState)
357		if !ok {
358			return false, fmt.Errorf("waiter comparator expected types.ChannelState value, got %T", pathValue)
359		}
360
361		if string(value) == expectedValue {
362			return false, fmt.Errorf("waiter state transitioned to Failure")
363		}
364	}
365
366	return true, nil
367}
368
369// ChannelDeletedWaiterOptions are waiter options for ChannelDeletedWaiter
370type ChannelDeletedWaiterOptions struct {
371
372	// Set of options to modify how an operation is invoked. These apply to all
373	// operations invoked for this client. Use functional options on operation call to
374	// modify this list for per operation behavior.
375	APIOptions []func(*middleware.Stack) error
376
377	// MinDelay is the minimum amount of time to delay between retries. If unset,
378	// ChannelDeletedWaiter will use default minimum delay of 5 seconds. Note that
379	// MinDelay must resolve to a value lesser than or equal to the MaxDelay.
380	MinDelay time.Duration
381
382	// MaxDelay is the maximum amount of time to delay between retries. If unset or set
383	// to zero, ChannelDeletedWaiter will use default max delay of 120 seconds. Note
384	// that MaxDelay must resolve to value greater than or equal to the MinDelay.
385	MaxDelay time.Duration
386
387	// LogWaitAttempts is used to enable logging for waiter retry attempts
388	LogWaitAttempts bool
389
390	// Retryable is function that can be used to override the service defined
391	// waiter-behavior based on operation output, or returned error. This function is
392	// used by the waiter to decide if a state is retryable or a terminal state. By
393	// default service-modeled logic will populate this option. This option can thus be
394	// used to define a custom waiter state with fall-back to service-modeled waiter
395	// state mutators.The function returns an error in case of a failure state. In case
396	// of retry state, this function returns a bool value of true and nil error, while
397	// in case of success it returns a bool value of false and nil error.
398	Retryable func(context.Context, *DescribeChannelInput, *DescribeChannelOutput, error) (bool, error)
399}
400
401// ChannelDeletedWaiter defines the waiters for ChannelDeleted
402type ChannelDeletedWaiter struct {
403	client DescribeChannelAPIClient
404
405	options ChannelDeletedWaiterOptions
406}
407
408// NewChannelDeletedWaiter constructs a ChannelDeletedWaiter.
409func NewChannelDeletedWaiter(client DescribeChannelAPIClient, optFns ...func(*ChannelDeletedWaiterOptions)) *ChannelDeletedWaiter {
410	options := ChannelDeletedWaiterOptions{}
411	options.MinDelay = 5 * time.Second
412	options.MaxDelay = 120 * time.Second
413	options.Retryable = channelDeletedStateRetryable
414
415	for _, fn := range optFns {
416		fn(&options)
417	}
418	return &ChannelDeletedWaiter{
419		client:  client,
420		options: options,
421	}
422}
423
424// Wait calls the waiter function for ChannelDeleted waiter. The maxWaitDur is the
425// maximum wait duration the waiter will wait. The maxWaitDur is required and must
426// be greater than zero.
427func (w *ChannelDeletedWaiter) Wait(ctx context.Context, params *DescribeChannelInput, maxWaitDur time.Duration, optFns ...func(*ChannelDeletedWaiterOptions)) error {
428	if maxWaitDur <= 0 {
429		return fmt.Errorf("maximum wait time for waiter must be greater than zero")
430	}
431
432	options := w.options
433	for _, fn := range optFns {
434		fn(&options)
435	}
436
437	if options.MaxDelay <= 0 {
438		options.MaxDelay = 120 * time.Second
439	}
440
441	if options.MinDelay > options.MaxDelay {
442		return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
443	}
444
445	ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
446	defer cancelFn()
447
448	logger := smithywaiter.Logger{}
449	remainingTime := maxWaitDur
450
451	var attempt int64
452	for {
453
454		attempt++
455		apiOptions := options.APIOptions
456		start := time.Now()
457
458		if options.LogWaitAttempts {
459			logger.Attempt = attempt
460			apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
461			apiOptions = append(apiOptions, logger.AddLogger)
462		}
463
464		out, err := w.client.DescribeChannel(ctx, params, func(o *Options) {
465			o.APIOptions = append(o.APIOptions, apiOptions...)
466		})
467
468		retryable, err := options.Retryable(ctx, params, out, err)
469		if err != nil {
470			return err
471		}
472		if !retryable {
473			return nil
474		}
475
476		remainingTime -= time.Since(start)
477		if remainingTime < options.MinDelay || remainingTime <= 0 {
478			break
479		}
480
481		// compute exponential backoff between waiter retries
482		delay, err := smithywaiter.ComputeDelay(
483			attempt, options.MinDelay, options.MaxDelay, remainingTime,
484		)
485		if err != nil {
486			return fmt.Errorf("error computing waiter delay, %w", err)
487		}
488
489		remainingTime -= delay
490		// sleep for the delay amount before invoking a request
491		if err := smithytime.SleepWithContext(ctx, delay); err != nil {
492			return fmt.Errorf("request cancelled while waiting, %w", err)
493		}
494	}
495	return fmt.Errorf("exceeded max wait time for ChannelDeleted waiter")
496}
497
498func channelDeletedStateRetryable(ctx context.Context, input *DescribeChannelInput, output *DescribeChannelOutput, err error) (bool, error) {
499
500	if err == nil {
501		pathValue, err := jmespath.Search("State", output)
502		if err != nil {
503			return false, fmt.Errorf("error evaluating waiter state: %w", err)
504		}
505
506		expectedValue := "DELETED"
507		value, ok := pathValue.(types.ChannelState)
508		if !ok {
509			return false, fmt.Errorf("waiter comparator expected types.ChannelState value, got %T", pathValue)
510		}
511
512		if string(value) == expectedValue {
513			return false, nil
514		}
515	}
516
517	if err == nil {
518		pathValue, err := jmespath.Search("State", output)
519		if err != nil {
520			return false, fmt.Errorf("error evaluating waiter state: %w", err)
521		}
522
523		expectedValue := "DELETING"
524		value, ok := pathValue.(types.ChannelState)
525		if !ok {
526			return false, fmt.Errorf("waiter comparator expected types.ChannelState value, got %T", pathValue)
527		}
528
529		if string(value) == expectedValue {
530			return true, nil
531		}
532	}
533
534	if err != nil {
535		var errorType *types.InternalServerErrorException
536		if errors.As(err, &errorType) {
537			return true, nil
538		}
539	}
540
541	return true, nil
542}
543
544// ChannelRunningWaiterOptions are waiter options for ChannelRunningWaiter
545type ChannelRunningWaiterOptions struct {
546
547	// Set of options to modify how an operation is invoked. These apply to all
548	// operations invoked for this client. Use functional options on operation call to
549	// modify this list for per operation behavior.
550	APIOptions []func(*middleware.Stack) error
551
552	// MinDelay is the minimum amount of time to delay between retries. If unset,
553	// ChannelRunningWaiter will use default minimum delay of 5 seconds. Note that
554	// MinDelay must resolve to a value lesser than or equal to the MaxDelay.
555	MinDelay time.Duration
556
557	// MaxDelay is the maximum amount of time to delay between retries. If unset or set
558	// to zero, ChannelRunningWaiter will use default max delay of 120 seconds. Note
559	// that MaxDelay must resolve to value greater than or equal to the MinDelay.
560	MaxDelay time.Duration
561
562	// LogWaitAttempts is used to enable logging for waiter retry attempts
563	LogWaitAttempts bool
564
565	// Retryable is function that can be used to override the service defined
566	// waiter-behavior based on operation output, or returned error. This function is
567	// used by the waiter to decide if a state is retryable or a terminal state. By
568	// default service-modeled logic will populate this option. This option can thus be
569	// used to define a custom waiter state with fall-back to service-modeled waiter
570	// state mutators.The function returns an error in case of a failure state. In case
571	// of retry state, this function returns a bool value of true and nil error, while
572	// in case of success it returns a bool value of false and nil error.
573	Retryable func(context.Context, *DescribeChannelInput, *DescribeChannelOutput, error) (bool, error)
574}
575
576// ChannelRunningWaiter defines the waiters for ChannelRunning
577type ChannelRunningWaiter struct {
578	client DescribeChannelAPIClient
579
580	options ChannelRunningWaiterOptions
581}
582
583// NewChannelRunningWaiter constructs a ChannelRunningWaiter.
584func NewChannelRunningWaiter(client DescribeChannelAPIClient, optFns ...func(*ChannelRunningWaiterOptions)) *ChannelRunningWaiter {
585	options := ChannelRunningWaiterOptions{}
586	options.MinDelay = 5 * time.Second
587	options.MaxDelay = 120 * time.Second
588	options.Retryable = channelRunningStateRetryable
589
590	for _, fn := range optFns {
591		fn(&options)
592	}
593	return &ChannelRunningWaiter{
594		client:  client,
595		options: options,
596	}
597}
598
599// Wait calls the waiter function for ChannelRunning waiter. The maxWaitDur is the
600// maximum wait duration the waiter will wait. The maxWaitDur is required and must
601// be greater than zero.
602func (w *ChannelRunningWaiter) Wait(ctx context.Context, params *DescribeChannelInput, maxWaitDur time.Duration, optFns ...func(*ChannelRunningWaiterOptions)) error {
603	if maxWaitDur <= 0 {
604		return fmt.Errorf("maximum wait time for waiter must be greater than zero")
605	}
606
607	options := w.options
608	for _, fn := range optFns {
609		fn(&options)
610	}
611
612	if options.MaxDelay <= 0 {
613		options.MaxDelay = 120 * time.Second
614	}
615
616	if options.MinDelay > options.MaxDelay {
617		return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
618	}
619
620	ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
621	defer cancelFn()
622
623	logger := smithywaiter.Logger{}
624	remainingTime := maxWaitDur
625
626	var attempt int64
627	for {
628
629		attempt++
630		apiOptions := options.APIOptions
631		start := time.Now()
632
633		if options.LogWaitAttempts {
634			logger.Attempt = attempt
635			apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
636			apiOptions = append(apiOptions, logger.AddLogger)
637		}
638
639		out, err := w.client.DescribeChannel(ctx, params, func(o *Options) {
640			o.APIOptions = append(o.APIOptions, apiOptions...)
641		})
642
643		retryable, err := options.Retryable(ctx, params, out, err)
644		if err != nil {
645			return err
646		}
647		if !retryable {
648			return nil
649		}
650
651		remainingTime -= time.Since(start)
652		if remainingTime < options.MinDelay || remainingTime <= 0 {
653			break
654		}
655
656		// compute exponential backoff between waiter retries
657		delay, err := smithywaiter.ComputeDelay(
658			attempt, options.MinDelay, options.MaxDelay, remainingTime,
659		)
660		if err != nil {
661			return fmt.Errorf("error computing waiter delay, %w", err)
662		}
663
664		remainingTime -= delay
665		// sleep for the delay amount before invoking a request
666		if err := smithytime.SleepWithContext(ctx, delay); err != nil {
667			return fmt.Errorf("request cancelled while waiting, %w", err)
668		}
669	}
670	return fmt.Errorf("exceeded max wait time for ChannelRunning waiter")
671}
672
673func channelRunningStateRetryable(ctx context.Context, input *DescribeChannelInput, output *DescribeChannelOutput, err error) (bool, error) {
674
675	if err == nil {
676		pathValue, err := jmespath.Search("State", output)
677		if err != nil {
678			return false, fmt.Errorf("error evaluating waiter state: %w", err)
679		}
680
681		expectedValue := "RUNNING"
682		value, ok := pathValue.(types.ChannelState)
683		if !ok {
684			return false, fmt.Errorf("waiter comparator expected types.ChannelState value, got %T", pathValue)
685		}
686
687		if string(value) == expectedValue {
688			return false, nil
689		}
690	}
691
692	if err == nil {
693		pathValue, err := jmespath.Search("State", output)
694		if err != nil {
695			return false, fmt.Errorf("error evaluating waiter state: %w", err)
696		}
697
698		expectedValue := "STARTING"
699		value, ok := pathValue.(types.ChannelState)
700		if !ok {
701			return false, fmt.Errorf("waiter comparator expected types.ChannelState value, got %T", pathValue)
702		}
703
704		if string(value) == expectedValue {
705			return true, nil
706		}
707	}
708
709	if err != nil {
710		var errorType *types.InternalServerErrorException
711		if errors.As(err, &errorType) {
712			return true, nil
713		}
714	}
715
716	return true, nil
717}
718
719// ChannelStoppedWaiterOptions are waiter options for ChannelStoppedWaiter
720type ChannelStoppedWaiterOptions struct {
721
722	// Set of options to modify how an operation is invoked. These apply to all
723	// operations invoked for this client. Use functional options on operation call to
724	// modify this list for per operation behavior.
725	APIOptions []func(*middleware.Stack) error
726
727	// MinDelay is the minimum amount of time to delay between retries. If unset,
728	// ChannelStoppedWaiter will use default minimum delay of 5 seconds. Note that
729	// MinDelay must resolve to a value lesser than or equal to the MaxDelay.
730	MinDelay time.Duration
731
732	// MaxDelay is the maximum amount of time to delay between retries. If unset or set
733	// to zero, ChannelStoppedWaiter will use default max delay of 120 seconds. Note
734	// that MaxDelay must resolve to value greater than or equal to the MinDelay.
735	MaxDelay time.Duration
736
737	// LogWaitAttempts is used to enable logging for waiter retry attempts
738	LogWaitAttempts bool
739
740	// Retryable is function that can be used to override the service defined
741	// waiter-behavior based on operation output, or returned error. This function is
742	// used by the waiter to decide if a state is retryable or a terminal state. By
743	// default service-modeled logic will populate this option. This option can thus be
744	// used to define a custom waiter state with fall-back to service-modeled waiter
745	// state mutators.The function returns an error in case of a failure state. In case
746	// of retry state, this function returns a bool value of true and nil error, while
747	// in case of success it returns a bool value of false and nil error.
748	Retryable func(context.Context, *DescribeChannelInput, *DescribeChannelOutput, error) (bool, error)
749}
750
751// ChannelStoppedWaiter defines the waiters for ChannelStopped
752type ChannelStoppedWaiter struct {
753	client DescribeChannelAPIClient
754
755	options ChannelStoppedWaiterOptions
756}
757
758// NewChannelStoppedWaiter constructs a ChannelStoppedWaiter.
759func NewChannelStoppedWaiter(client DescribeChannelAPIClient, optFns ...func(*ChannelStoppedWaiterOptions)) *ChannelStoppedWaiter {
760	options := ChannelStoppedWaiterOptions{}
761	options.MinDelay = 5 * time.Second
762	options.MaxDelay = 120 * time.Second
763	options.Retryable = channelStoppedStateRetryable
764
765	for _, fn := range optFns {
766		fn(&options)
767	}
768	return &ChannelStoppedWaiter{
769		client:  client,
770		options: options,
771	}
772}
773
774// Wait calls the waiter function for ChannelStopped waiter. The maxWaitDur is the
775// maximum wait duration the waiter will wait. The maxWaitDur is required and must
776// be greater than zero.
777func (w *ChannelStoppedWaiter) Wait(ctx context.Context, params *DescribeChannelInput, maxWaitDur time.Duration, optFns ...func(*ChannelStoppedWaiterOptions)) error {
778	if maxWaitDur <= 0 {
779		return fmt.Errorf("maximum wait time for waiter must be greater than zero")
780	}
781
782	options := w.options
783	for _, fn := range optFns {
784		fn(&options)
785	}
786
787	if options.MaxDelay <= 0 {
788		options.MaxDelay = 120 * time.Second
789	}
790
791	if options.MinDelay > options.MaxDelay {
792		return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
793	}
794
795	ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
796	defer cancelFn()
797
798	logger := smithywaiter.Logger{}
799	remainingTime := maxWaitDur
800
801	var attempt int64
802	for {
803
804		attempt++
805		apiOptions := options.APIOptions
806		start := time.Now()
807
808		if options.LogWaitAttempts {
809			logger.Attempt = attempt
810			apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
811			apiOptions = append(apiOptions, logger.AddLogger)
812		}
813
814		out, err := w.client.DescribeChannel(ctx, params, func(o *Options) {
815			o.APIOptions = append(o.APIOptions, apiOptions...)
816		})
817
818		retryable, err := options.Retryable(ctx, params, out, err)
819		if err != nil {
820			return err
821		}
822		if !retryable {
823			return nil
824		}
825
826		remainingTime -= time.Since(start)
827		if remainingTime < options.MinDelay || remainingTime <= 0 {
828			break
829		}
830
831		// compute exponential backoff between waiter retries
832		delay, err := smithywaiter.ComputeDelay(
833			attempt, options.MinDelay, options.MaxDelay, remainingTime,
834		)
835		if err != nil {
836			return fmt.Errorf("error computing waiter delay, %w", err)
837		}
838
839		remainingTime -= delay
840		// sleep for the delay amount before invoking a request
841		if err := smithytime.SleepWithContext(ctx, delay); err != nil {
842			return fmt.Errorf("request cancelled while waiting, %w", err)
843		}
844	}
845	return fmt.Errorf("exceeded max wait time for ChannelStopped waiter")
846}
847
848func channelStoppedStateRetryable(ctx context.Context, input *DescribeChannelInput, output *DescribeChannelOutput, err error) (bool, error) {
849
850	if err == nil {
851		pathValue, err := jmespath.Search("State", output)
852		if err != nil {
853			return false, fmt.Errorf("error evaluating waiter state: %w", err)
854		}
855
856		expectedValue := "IDLE"
857		value, ok := pathValue.(types.ChannelState)
858		if !ok {
859			return false, fmt.Errorf("waiter comparator expected types.ChannelState value, got %T", pathValue)
860		}
861
862		if string(value) == expectedValue {
863			return false, nil
864		}
865	}
866
867	if err == nil {
868		pathValue, err := jmespath.Search("State", output)
869		if err != nil {
870			return false, fmt.Errorf("error evaluating waiter state: %w", err)
871		}
872
873		expectedValue := "STOPPING"
874		value, ok := pathValue.(types.ChannelState)
875		if !ok {
876			return false, fmt.Errorf("waiter comparator expected types.ChannelState value, got %T", pathValue)
877		}
878
879		if string(value) == expectedValue {
880			return true, nil
881		}
882	}
883
884	if err != nil {
885		var errorType *types.InternalServerErrorException
886		if errors.As(err, &errorType) {
887			return true, nil
888		}
889	}
890
891	return true, nil
892}
893
894func newServiceMetadataMiddleware_opDescribeChannel(region string) *awsmiddleware.RegisterServiceMetadata {
895	return &awsmiddleware.RegisterServiceMetadata{
896		Region:        region,
897		ServiceID:     ServiceID,
898		SigningName:   "medialive",
899		OperationName: "DescribeChannel",
900	}
901}
902