1// Code generated by smithy-go-codegen DO NOT EDIT.
2
3package cloudfront
4
5import (
6	"context"
7	"fmt"
8	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
9	"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
10	"github.com/aws/aws-sdk-go-v2/service/cloudfront/types"
11	"github.com/aws/smithy-go/middleware"
12	smithytime "github.com/aws/smithy-go/time"
13	smithyhttp "github.com/aws/smithy-go/transport/http"
14	smithywaiter "github.com/aws/smithy-go/waiter"
15	"github.com/jmespath/go-jmespath"
16	"time"
17)
18
19// Get the information about an invalidation.
20func (c *Client) GetInvalidation(ctx context.Context, params *GetInvalidationInput, optFns ...func(*Options)) (*GetInvalidationOutput, error) {
21	if params == nil {
22		params = &GetInvalidationInput{}
23	}
24
25	result, metadata, err := c.invokeOperation(ctx, "GetInvalidation", params, optFns, c.addOperationGetInvalidationMiddlewares)
26	if err != nil {
27		return nil, err
28	}
29
30	out := result.(*GetInvalidationOutput)
31	out.ResultMetadata = metadata
32	return out, nil
33}
34
35// The request to get an invalidation's information.
36type GetInvalidationInput struct {
37
38	// The distribution's ID.
39	//
40	// This member is required.
41	DistributionId *string
42
43	// The identifier for the invalidation request, for example, IDFDVBD632BHDS5.
44	//
45	// This member is required.
46	Id *string
47
48	noSmithyDocumentSerde
49}
50
51// The returned result of the corresponding request.
52type GetInvalidationOutput struct {
53
54	// The invalidation's information. For more information, see Invalidation Complex
55	// Type
56	// (https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/InvalidationDatatype.html).
57	Invalidation *types.Invalidation
58
59	// Metadata pertaining to the operation's result.
60	ResultMetadata middleware.Metadata
61
62	noSmithyDocumentSerde
63}
64
65func (c *Client) addOperationGetInvalidationMiddlewares(stack *middleware.Stack, options Options) (err error) {
66	err = stack.Serialize.Add(&awsRestxml_serializeOpGetInvalidation{}, middleware.After)
67	if err != nil {
68		return err
69	}
70	err = stack.Deserialize.Add(&awsRestxml_deserializeOpGetInvalidation{}, middleware.After)
71	if err != nil {
72		return err
73	}
74	if err = addSetLoggerMiddleware(stack, options); err != nil {
75		return err
76	}
77	if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
78		return err
79	}
80	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
81		return err
82	}
83	if err = addResolveEndpointMiddleware(stack, options); err != nil {
84		return err
85	}
86	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
87		return err
88	}
89	if err = addRetryMiddlewares(stack, options); err != nil {
90		return err
91	}
92	if err = addHTTPSignerV4Middleware(stack, options); err != nil {
93		return err
94	}
95	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
96		return err
97	}
98	if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
99		return err
100	}
101	if err = addClientUserAgent(stack); err != nil {
102		return err
103	}
104	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
105		return err
106	}
107	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
108		return err
109	}
110	if err = addOpGetInvalidationValidationMiddleware(stack); err != nil {
111		return err
112	}
113	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetInvalidation(options.Region), middleware.Before); err != nil {
114		return err
115	}
116	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
117		return err
118	}
119	if err = addResponseErrorMiddleware(stack); err != nil {
120		return err
121	}
122	if err = addRequestResponseLogging(stack, options); err != nil {
123		return err
124	}
125	return nil
126}
127
128// GetInvalidationAPIClient is a client that implements the GetInvalidation
129// operation.
130type GetInvalidationAPIClient interface {
131	GetInvalidation(context.Context, *GetInvalidationInput, ...func(*Options)) (*GetInvalidationOutput, error)
132}
133
134var _ GetInvalidationAPIClient = (*Client)(nil)
135
136// InvalidationCompletedWaiterOptions are waiter options for
137// InvalidationCompletedWaiter
138type InvalidationCompletedWaiterOptions struct {
139
140	// Set of options to modify how an operation is invoked. These apply to all
141	// operations invoked for this client. Use functional options on operation call to
142	// modify this list for per operation behavior.
143	APIOptions []func(*middleware.Stack) error
144
145	// MinDelay is the minimum amount of time to delay between retries. If unset,
146	// InvalidationCompletedWaiter will use default minimum delay of 20 seconds. Note
147	// that MinDelay must resolve to a value lesser than or equal to the MaxDelay.
148	MinDelay time.Duration
149
150	// MaxDelay is the maximum amount of time to delay between retries. If unset or set
151	// to zero, InvalidationCompletedWaiter will use default max delay of 120 seconds.
152	// Note that MaxDelay must resolve to value greater than or equal to the MinDelay.
153	MaxDelay time.Duration
154
155	// LogWaitAttempts is used to enable logging for waiter retry attempts
156	LogWaitAttempts bool
157
158	// Retryable is function that can be used to override the service defined
159	// waiter-behavior based on operation output, or returned error. This function is
160	// used by the waiter to decide if a state is retryable or a terminal state. By
161	// default service-modeled logic will populate this option. This option can thus be
162	// used to define a custom waiter state with fall-back to service-modeled waiter
163	// state mutators.The function returns an error in case of a failure state. In case
164	// of retry state, this function returns a bool value of true and nil error, while
165	// in case of success it returns a bool value of false and nil error.
166	Retryable func(context.Context, *GetInvalidationInput, *GetInvalidationOutput, error) (bool, error)
167}
168
169// InvalidationCompletedWaiter defines the waiters for InvalidationCompleted
170type InvalidationCompletedWaiter struct {
171	client GetInvalidationAPIClient
172
173	options InvalidationCompletedWaiterOptions
174}
175
176// NewInvalidationCompletedWaiter constructs a InvalidationCompletedWaiter.
177func NewInvalidationCompletedWaiter(client GetInvalidationAPIClient, optFns ...func(*InvalidationCompletedWaiterOptions)) *InvalidationCompletedWaiter {
178	options := InvalidationCompletedWaiterOptions{}
179	options.MinDelay = 20 * time.Second
180	options.MaxDelay = 120 * time.Second
181	options.Retryable = invalidationCompletedStateRetryable
182
183	for _, fn := range optFns {
184		fn(&options)
185	}
186	return &InvalidationCompletedWaiter{
187		client:  client,
188		options: options,
189	}
190}
191
192// Wait calls the waiter function for InvalidationCompleted waiter. The maxWaitDur
193// is the maximum wait duration the waiter will wait. The maxWaitDur is required
194// and must be greater than zero.
195func (w *InvalidationCompletedWaiter) Wait(ctx context.Context, params *GetInvalidationInput, maxWaitDur time.Duration, optFns ...func(*InvalidationCompletedWaiterOptions)) error {
196	if maxWaitDur <= 0 {
197		return fmt.Errorf("maximum wait time for waiter must be greater than zero")
198	}
199
200	options := w.options
201	for _, fn := range optFns {
202		fn(&options)
203	}
204
205	if options.MaxDelay <= 0 {
206		options.MaxDelay = 120 * time.Second
207	}
208
209	if options.MinDelay > options.MaxDelay {
210		return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
211	}
212
213	ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
214	defer cancelFn()
215
216	logger := smithywaiter.Logger{}
217	remainingTime := maxWaitDur
218
219	var attempt int64
220	for {
221
222		attempt++
223		apiOptions := options.APIOptions
224		start := time.Now()
225
226		if options.LogWaitAttempts {
227			logger.Attempt = attempt
228			apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
229			apiOptions = append(apiOptions, logger.AddLogger)
230		}
231
232		out, err := w.client.GetInvalidation(ctx, params, func(o *Options) {
233			o.APIOptions = append(o.APIOptions, apiOptions...)
234		})
235
236		retryable, err := options.Retryable(ctx, params, out, err)
237		if err != nil {
238			return err
239		}
240		if !retryable {
241			return nil
242		}
243
244		remainingTime -= time.Since(start)
245		if remainingTime < options.MinDelay || remainingTime <= 0 {
246			break
247		}
248
249		// compute exponential backoff between waiter retries
250		delay, err := smithywaiter.ComputeDelay(
251			attempt, options.MinDelay, options.MaxDelay, remainingTime,
252		)
253		if err != nil {
254			return fmt.Errorf("error computing waiter delay, %w", err)
255		}
256
257		remainingTime -= delay
258		// sleep for the delay amount before invoking a request
259		if err := smithytime.SleepWithContext(ctx, delay); err != nil {
260			return fmt.Errorf("request cancelled while waiting, %w", err)
261		}
262	}
263	return fmt.Errorf("exceeded max wait time for InvalidationCompleted waiter")
264}
265
266func invalidationCompletedStateRetryable(ctx context.Context, input *GetInvalidationInput, output *GetInvalidationOutput, err error) (bool, error) {
267
268	if err == nil {
269		pathValue, err := jmespath.Search("Invalidation.Status", output)
270		if err != nil {
271			return false, fmt.Errorf("error evaluating waiter state: %w", err)
272		}
273
274		expectedValue := "Completed"
275		value, ok := pathValue.(*string)
276		if !ok {
277			return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue)
278		}
279
280		if string(*value) == expectedValue {
281			return false, nil
282		}
283	}
284
285	return true, nil
286}
287
288func newServiceMetadataMiddleware_opGetInvalidation(region string) *awsmiddleware.RegisterServiceMetadata {
289	return &awsmiddleware.RegisterServiceMetadata{
290		Region:        region,
291		ServiceID:     ServiceID,
292		SigningName:   "cloudfront",
293		OperationName: "GetInvalidation",
294	}
295}
296