1// Code generated by smithy-go-codegen DO NOT EDIT.
2
3package kendra
4
5import (
6	"context"
7	cryptorand "crypto/rand"
8	"github.com/aws/aws-sdk-go-v2/aws"
9	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
10	"github.com/aws/aws-sdk-go-v2/aws/retry"
11	"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
12	awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
13	smithy "github.com/aws/smithy-go"
14	"github.com/aws/smithy-go/logging"
15	"github.com/aws/smithy-go/middleware"
16	smithyrand "github.com/aws/smithy-go/rand"
17	smithyhttp "github.com/aws/smithy-go/transport/http"
18	"net/http"
19	"time"
20)
21
22const ServiceID = "kendra"
23const ServiceAPIVersion = "2019-02-03"
24
25// Client provides the API client to make operations call for
26// AWSKendraFrontendService.
27type Client struct {
28	options Options
29}
30
31// New returns an initialized Client based on the functional options. Provide
32// additional functional options to further configure the behavior of the client,
33// such as changing the client's endpoint or adding custom middleware behavior.
34func New(options Options, optFns ...func(*Options)) *Client {
35	options = options.Copy()
36
37	resolveDefaultLogger(&options)
38
39	resolveRetryer(&options)
40
41	resolveHTTPClient(&options)
42
43	resolveHTTPSignerV4(&options)
44
45	resolveDefaultEndpointConfiguration(&options)
46
47	resolveIdempotencyTokenProvider(&options)
48
49	for _, fn := range optFns {
50		fn(&options)
51	}
52
53	client := &Client{
54		options: options,
55	}
56
57	return client
58}
59
60type Options struct {
61	// Set of options to modify how an operation is invoked. These apply to all
62	// operations invoked for this client. Use functional options on operation call to
63	// modify this list for per operation behavior.
64	APIOptions []func(*middleware.Stack) error
65
66	// Configures the events that will be sent to the configured logger.
67	ClientLogMode aws.ClientLogMode
68
69	// The credentials object to use when signing requests.
70	Credentials aws.CredentialsProvider
71
72	// The endpoint options to be used when attempting to resolve an endpoint.
73	EndpointOptions EndpointResolverOptions
74
75	// The service endpoint resolver.
76	EndpointResolver EndpointResolver
77
78	// Signature Version 4 (SigV4) Signer
79	HTTPSignerV4 HTTPSignerV4
80
81	// Provides idempotency tokens values that will be automatically populated into
82	// idempotent API operations.
83	IdempotencyTokenProvider IdempotencyTokenProvider
84
85	// The logger writer interface to write logging messages to.
86	Logger logging.Logger
87
88	// The region to send requests to. (Required)
89	Region string
90
91	// Retryer guides how HTTP requests should be retried in case of recoverable
92	// failures. When nil the API client will use a default retryer.
93	Retryer aws.Retryer
94
95	// The HTTP client to invoke API calls with. Defaults to client's default HTTP
96	// implementation if nil.
97	HTTPClient HTTPClient
98}
99
100// WithAPIOptions returns a functional option for setting the Client's APIOptions
101// option.
102func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) {
103	return func(o *Options) {
104		o.APIOptions = append(o.APIOptions, optFns...)
105	}
106}
107
108// WithEndpointResolver returns a functional option for setting the Client's
109// EndpointResolver option.
110func WithEndpointResolver(v EndpointResolver) func(*Options) {
111	return func(o *Options) {
112		o.EndpointResolver = v
113	}
114}
115
116type HTTPClient interface {
117	Do(*http.Request) (*http.Response, error)
118}
119
120// Copy creates a clone where the APIOptions list is deep copied.
121func (o Options) Copy() Options {
122	to := o
123	to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions))
124	copy(to.APIOptions, o.APIOptions)
125	return to
126}
127func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) {
128	ctx = middleware.ClearStackValues(ctx)
129	stack := middleware.NewStack(opID, smithyhttp.NewStackRequest)
130	options := c.options.Copy()
131	for _, fn := range optFns {
132		fn(&options)
133	}
134
135	for _, fn := range stackFns {
136		if err := fn(stack, options); err != nil {
137			return nil, metadata, err
138		}
139	}
140
141	for _, fn := range options.APIOptions {
142		if err := fn(stack); err != nil {
143			return nil, metadata, err
144		}
145	}
146
147	handler := middleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack)
148	result, metadata, err = handler.Handle(ctx, params)
149	if err != nil {
150		err = &smithy.OperationError{
151			ServiceID:     ServiceID,
152			OperationName: opID,
153			Err:           err,
154		}
155	}
156	return result, metadata, err
157}
158
159func resolveDefaultLogger(o *Options) {
160	if o.Logger != nil {
161		return
162	}
163	o.Logger = logging.Nop{}
164}
165
166func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error {
167	return middleware.AddSetLoggerMiddleware(stack, o.Logger)
168}
169
170// NewFromConfig returns a new client from the provided config.
171func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client {
172	opts := Options{
173		Region:        cfg.Region,
174		HTTPClient:    cfg.HTTPClient,
175		Credentials:   cfg.Credentials,
176		APIOptions:    cfg.APIOptions,
177		Logger:        cfg.Logger,
178		ClientLogMode: cfg.ClientLogMode,
179	}
180	resolveAWSRetryerProvider(cfg, &opts)
181	resolveAWSEndpointResolver(cfg, &opts)
182	return New(opts, optFns...)
183}
184
185func resolveHTTPClient(o *Options) {
186	if o.HTTPClient != nil {
187		return
188	}
189	o.HTTPClient = awshttp.NewBuildableClient()
190}
191
192func resolveRetryer(o *Options) {
193	if o.Retryer != nil {
194		return
195	}
196	o.Retryer = retry.NewStandard()
197}
198
199func resolveAWSRetryerProvider(cfg aws.Config, o *Options) {
200	if cfg.Retryer == nil {
201		return
202	}
203	o.Retryer = cfg.Retryer()
204}
205
206func resolveAWSEndpointResolver(cfg aws.Config, o *Options) {
207	if cfg.EndpointResolver == nil {
208		return
209	}
210	o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, NewDefaultEndpointResolver())
211}
212
213func addClientUserAgent(stack *middleware.Stack) error {
214	return awsmiddleware.AddRequestUserAgentMiddleware(stack)
215}
216
217func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error {
218	mw := v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{
219		CredentialsProvider: o.Credentials,
220		Signer:              o.HTTPSignerV4,
221		LogSigning:          o.ClientLogMode.IsSigning(),
222	})
223	return stack.Finalize.Add(mw, middleware.After)
224}
225
226type HTTPSignerV4 interface {
227	SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error
228}
229
230func resolveHTTPSignerV4(o *Options) {
231	if o.HTTPSignerV4 != nil {
232		return
233	}
234	o.HTTPSignerV4 = newDefaultV4Signer(*o)
235}
236
237func newDefaultV4Signer(o Options) *v4.Signer {
238	return v4.NewSigner(func(so *v4.SignerOptions) {
239		so.Logger = o.Logger
240		so.LogSigning = o.ClientLogMode.IsSigning()
241	})
242}
243
244func resolveIdempotencyTokenProvider(o *Options) {
245	if o.IdempotencyTokenProvider != nil {
246		return
247	}
248	o.IdempotencyTokenProvider = smithyrand.NewUUIDIdempotencyToken(cryptorand.Reader)
249}
250
251func addRetryMiddlewares(stack *middleware.Stack, o Options) error {
252	mo := retry.AddRetryMiddlewaresOptions{
253		Retryer:          o.Retryer,
254		LogRetryAttempts: o.ClientLogMode.IsRetries(),
255	}
256	return retry.AddRetryMiddlewares(stack, mo)
257}
258
259// IdempotencyTokenProvider interface for providing idempotency token
260type IdempotencyTokenProvider interface {
261	GetIdempotencyToken() (string, error)
262}
263
264func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error {
265	return awsmiddleware.AddRequestIDRetrieverMiddleware(stack)
266}
267
268func addResponseErrorMiddleware(stack *middleware.Stack) error {
269	return awshttp.AddResponseErrorMiddleware(stack)
270}
271
272func addRequestResponseLogging(stack *middleware.Stack, o Options) error {
273	return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{
274		LogRequest:          o.ClientLogMode.IsRequest(),
275		LogRequestWithBody:  o.ClientLogMode.IsRequestWithBody(),
276		LogResponse:         o.ClientLogMode.IsResponse(),
277		LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(),
278	}, middleware.After)
279}
280