1// Code generated by smithy-go-codegen DO NOT EDIT.
2
3package codedeploy
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/codedeploy/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// Gets information about a deployment. The content property of the appSpecContent
20// object in the returned revision is always null. Use GetApplicationRevision and
21// the sha256 property of the returned appSpecContent object to get the content of
22// the deployment’s AppSpec file.
23func (c *Client) GetDeployment(ctx context.Context, params *GetDeploymentInput, optFns ...func(*Options)) (*GetDeploymentOutput, error) {
24	if params == nil {
25		params = &GetDeploymentInput{}
26	}
27
28	result, metadata, err := c.invokeOperation(ctx, "GetDeployment", params, optFns, addOperationGetDeploymentMiddlewares)
29	if err != nil {
30		return nil, err
31	}
32
33	out := result.(*GetDeploymentOutput)
34	out.ResultMetadata = metadata
35	return out, nil
36}
37
38// Represents the input of a GetDeployment operation.
39type GetDeploymentInput struct {
40
41	// The unique ID of a deployment associated with the IAM user or AWS account.
42	//
43	// This member is required.
44	DeploymentId *string
45}
46
47// Represents the output of a GetDeployment operation.
48type GetDeploymentOutput struct {
49
50	// Information about the deployment.
51	DeploymentInfo *types.DeploymentInfo
52
53	// Metadata pertaining to the operation's result.
54	ResultMetadata middleware.Metadata
55}
56
57func addOperationGetDeploymentMiddlewares(stack *middleware.Stack, options Options) (err error) {
58	err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetDeployment{}, middleware.After)
59	if err != nil {
60		return err
61	}
62	err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetDeployment{}, middleware.After)
63	if err != nil {
64		return err
65	}
66	if err = addSetLoggerMiddleware(stack, options); err != nil {
67		return err
68	}
69	if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
70		return err
71	}
72	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
73		return err
74	}
75	if err = addResolveEndpointMiddleware(stack, options); err != nil {
76		return err
77	}
78	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
79		return err
80	}
81	if err = addRetryMiddlewares(stack, options); err != nil {
82		return err
83	}
84	if err = addHTTPSignerV4Middleware(stack, options); err != nil {
85		return err
86	}
87	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
88		return err
89	}
90	if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
91		return err
92	}
93	if err = addClientUserAgent(stack); err != nil {
94		return err
95	}
96	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
97		return err
98	}
99	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
100		return err
101	}
102	if err = addOpGetDeploymentValidationMiddleware(stack); err != nil {
103		return err
104	}
105	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetDeployment(options.Region), middleware.Before); err != nil {
106		return err
107	}
108	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
109		return err
110	}
111	if err = addResponseErrorMiddleware(stack); err != nil {
112		return err
113	}
114	if err = addRequestResponseLogging(stack, options); err != nil {
115		return err
116	}
117	return nil
118}
119
120// GetDeploymentAPIClient is a client that implements the GetDeployment operation.
121type GetDeploymentAPIClient interface {
122	GetDeployment(context.Context, *GetDeploymentInput, ...func(*Options)) (*GetDeploymentOutput, error)
123}
124
125var _ GetDeploymentAPIClient = (*Client)(nil)
126
127// DeploymentSuccessfulWaiterOptions are waiter options for
128// DeploymentSuccessfulWaiter
129type DeploymentSuccessfulWaiterOptions struct {
130
131	// Set of options to modify how an operation is invoked. These apply to all
132	// operations invoked for this client. Use functional options on operation call to
133	// modify this list for per operation behavior.
134	APIOptions []func(*middleware.Stack) error
135
136	// MinDelay is the minimum amount of time to delay between retries. If unset,
137	// DeploymentSuccessfulWaiter will use default minimum delay of 15 seconds. Note
138	// that MinDelay must resolve to a value lesser than or equal to the MaxDelay.
139	MinDelay time.Duration
140
141	// MaxDelay is the maximum amount of time to delay between retries. If unset or set
142	// to zero, DeploymentSuccessfulWaiter will use default max delay of 120 seconds.
143	// Note that MaxDelay must resolve to value greater than or equal to the MinDelay.
144	MaxDelay time.Duration
145
146	// LogWaitAttempts is used to enable logging for waiter retry attempts
147	LogWaitAttempts bool
148
149	// Retryable is function that can be used to override the service defined
150	// waiter-behavior based on operation output, or returned error. This function is
151	// used by the waiter to decide if a state is retryable or a terminal state. By
152	// default service-modeled logic will populate this option. This option can thus be
153	// used to define a custom waiter state with fall-back to service-modeled waiter
154	// state mutators.The function returns an error in case of a failure state. In case
155	// of retry state, this function returns a bool value of true and nil error, while
156	// in case of success it returns a bool value of false and nil error.
157	Retryable func(context.Context, *GetDeploymentInput, *GetDeploymentOutput, error) (bool, error)
158}
159
160// DeploymentSuccessfulWaiter defines the waiters for DeploymentSuccessful
161type DeploymentSuccessfulWaiter struct {
162	client GetDeploymentAPIClient
163
164	options DeploymentSuccessfulWaiterOptions
165}
166
167// NewDeploymentSuccessfulWaiter constructs a DeploymentSuccessfulWaiter.
168func NewDeploymentSuccessfulWaiter(client GetDeploymentAPIClient, optFns ...func(*DeploymentSuccessfulWaiterOptions)) *DeploymentSuccessfulWaiter {
169	options := DeploymentSuccessfulWaiterOptions{}
170	options.MinDelay = 15 * time.Second
171	options.MaxDelay = 120 * time.Second
172	options.Retryable = deploymentSuccessfulStateRetryable
173
174	for _, fn := range optFns {
175		fn(&options)
176	}
177	return &DeploymentSuccessfulWaiter{
178		client:  client,
179		options: options,
180	}
181}
182
183// Wait calls the waiter function for DeploymentSuccessful waiter. The maxWaitDur
184// is the maximum wait duration the waiter will wait. The maxWaitDur is required
185// and must be greater than zero.
186func (w *DeploymentSuccessfulWaiter) Wait(ctx context.Context, params *GetDeploymentInput, maxWaitDur time.Duration, optFns ...func(*DeploymentSuccessfulWaiterOptions)) error {
187	if maxWaitDur <= 0 {
188		return fmt.Errorf("maximum wait time for waiter must be greater than zero")
189	}
190
191	options := w.options
192	for _, fn := range optFns {
193		fn(&options)
194	}
195
196	if options.MaxDelay <= 0 {
197		options.MaxDelay = 120 * time.Second
198	}
199
200	if options.MinDelay > options.MaxDelay {
201		return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
202	}
203
204	ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
205	defer cancelFn()
206
207	logger := smithywaiter.Logger{}
208	remainingTime := maxWaitDur
209
210	var attempt int64
211	for {
212
213		attempt++
214		apiOptions := options.APIOptions
215		start := time.Now()
216
217		if options.LogWaitAttempts {
218			logger.Attempt = attempt
219			apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
220			apiOptions = append(apiOptions, logger.AddLogger)
221		}
222
223		out, err := w.client.GetDeployment(ctx, params, func(o *Options) {
224			o.APIOptions = append(o.APIOptions, apiOptions...)
225		})
226
227		retryable, err := options.Retryable(ctx, params, out, err)
228		if err != nil {
229			return err
230		}
231		if !retryable {
232			return nil
233		}
234
235		remainingTime -= time.Since(start)
236		if remainingTime < options.MinDelay || remainingTime <= 0 {
237			break
238		}
239
240		// compute exponential backoff between waiter retries
241		delay, err := smithywaiter.ComputeDelay(
242			attempt, options.MinDelay, options.MaxDelay, remainingTime,
243		)
244		if err != nil {
245			return fmt.Errorf("error computing waiter delay, %w", err)
246		}
247
248		remainingTime -= delay
249		// sleep for the delay amount before invoking a request
250		if err := smithytime.SleepWithContext(ctx, delay); err != nil {
251			return fmt.Errorf("request cancelled while waiting, %w", err)
252		}
253	}
254	return fmt.Errorf("exceeded max wait time for DeploymentSuccessful waiter")
255}
256
257func deploymentSuccessfulStateRetryable(ctx context.Context, input *GetDeploymentInput, output *GetDeploymentOutput, err error) (bool, error) {
258
259	if err == nil {
260		pathValue, err := jmespath.Search("deploymentInfo.status", output)
261		if err != nil {
262			return false, fmt.Errorf("error evaluating waiter state: %w", err)
263		}
264
265		expectedValue := "Succeeded"
266		value, ok := pathValue.(types.DeploymentStatus)
267		if !ok {
268			return false, fmt.Errorf("waiter comparator expected types.DeploymentStatus value, got %T", pathValue)
269		}
270
271		if string(value) == expectedValue {
272			return false, nil
273		}
274	}
275
276	if err == nil {
277		pathValue, err := jmespath.Search("deploymentInfo.status", output)
278		if err != nil {
279			return false, fmt.Errorf("error evaluating waiter state: %w", err)
280		}
281
282		expectedValue := "Failed"
283		value, ok := pathValue.(types.DeploymentStatus)
284		if !ok {
285			return false, fmt.Errorf("waiter comparator expected types.DeploymentStatus value, got %T", pathValue)
286		}
287
288		if string(value) == expectedValue {
289			return false, fmt.Errorf("waiter state transitioned to Failure")
290		}
291	}
292
293	if err == nil {
294		pathValue, err := jmespath.Search("deploymentInfo.status", output)
295		if err != nil {
296			return false, fmt.Errorf("error evaluating waiter state: %w", err)
297		}
298
299		expectedValue := "Stopped"
300		value, ok := pathValue.(types.DeploymentStatus)
301		if !ok {
302			return false, fmt.Errorf("waiter comparator expected types.DeploymentStatus value, got %T", pathValue)
303		}
304
305		if string(value) == expectedValue {
306			return false, fmt.Errorf("waiter state transitioned to Failure")
307		}
308	}
309
310	return true, nil
311}
312
313func newServiceMetadataMiddleware_opGetDeployment(region string) *awsmiddleware.RegisterServiceMetadata {
314	return &awsmiddleware.RegisterServiceMetadata{
315		Region:        region,
316		ServiceID:     ServiceID,
317		SigningName:   "codedeploy",
318		OperationName: "GetDeployment",
319	}
320}
321