Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[extension/awsmiddleware] Add AWS middleware extension interface #116

Merged
merged 4 commits into from
Oct 16, 2023

Conversation

jefchien
Copy link

Description: We want to have the option to customize the way AWS client requests/responses are handled for OTEL components. Both AWS SDK versions enable this, but in different ways:

To make configuring this easier and more streamlined, we're introducing an AWS middleware extension interface with functions available to configure both SDK versions. AWS components will be updated in another PR to use this configuration.

Link to tracking Issue: N/A

Testing: Added unit tests with mocks for both AWS SDK v1/v2.

Documentation: N/A

{
"Name": "metric3",
"Unit": "Seconds",
{
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasn't previously formatted, which was breaking the linting validation.

@jefchien jefchien requested a review from bryce-carey October 13, 2023 16:44
}
}
for _, handler := range mw.ResponseHandlers() {
if err := addHandlerToList(&handlers.Unmarshal, namedResponseHandler(handler), handler.Position()); err != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the unmarshal/deserialize steps apply to the response only? That would make sense. The diagram from the AWS middleware documentation is confusing because it shows both the input and output go through this step, but the description says

Deserialize | Deserialize responses from the protocol format into a structured type or error.

which implies that it applies to the response only.

This does seem like it will address the problem of extracting operational data since the extension will be able to save state across the request and response handlers.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the unit testing, it only applies to the response.

output, err := s3Client.ListBuckets(&s3v1.ListBucketsInput{})
require.NoError(t, err)
assert.NotNil(t, output)
assert.GreaterOrEqual(t, recorder.Latency(), testLatency)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this potentially be flaky? Are we checking more than just that the latency is strictly positive?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's checking that the end time (when the handler got the response) occurred at least after the expected latency. I don't think it can be flaky because the test server always sleeps for that amount of time, which will prevent the response from happening before then.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. I missed the sleep.

// RequestHandler allows for custom processing of requests.
type RequestHandler interface {
metadata
HandleRequest(r *http.Request)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a high level, do you see the usage of *http.Request and *http.Response as appropriate? This was on my mind as something that might become more clear during the implementation.

These objects are general enough that they can be applied to more than just AWS, but they're also not accounting for the other possibilities with middleware like changing default request behavior in this example: https://aws.github.io/aws-sdk-go-v2/docs/middleware/#writing-a-custom-middleware.

Some alternatives are to apply middleware to any or maybe some high level AWS request/response object. Then the extension implementing this interface could have type checks to apply the specific behavior it intends. What are your thoughts after spending time on this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for our usecase the http.Request/Response are enough. I want to avoid any as much as possible. It makes it hard for others to implement the interfaces and know what to expect.

The example you linked is at the initialize step. At the build and deserialize steps, it no longer has any of the parameters or inputs that would be useful. If we're not providing access to the other steps, then I don't think there's value in making it more generic.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, so we still have ways of extending this in the future, if doing that would even be valuable. So we're not entering a 1-way door decision.

SaxyPandaBear
SaxyPandaBear previously approved these changes Oct 13, 2023
Copy link

@SaxyPandaBear SaxyPandaBear left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nothing jumps out to me. looks good

extension/awsmiddleware/middleware.go Outdated Show resolved Hide resolved
}

// addHandlerToList adds the handler to the list based on the position.
func addHandlerToList(handlerList *request.HandlerList, handler request.NamedHandler, position HandlerPosition) error {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super duper mild nit - I personally dislike the [verb] to [thing] naming convention, but that is purely personal preference. It would be nice if we could just use append but that's already reserved for slices :/ oh well

bryce-carey
bryce-carey previously approved these changes Oct 13, 2023
adam-mateen
adam-mateen previously approved these changes Oct 13, 2023
@jefchien jefchien merged commit 1f23619 into amazon-contributing:aws-cwa-dev Oct 16, 2023
65 of 78 checks passed
@jefchien jefchien deleted the middleware-ext branch October 16, 2023 21:46
lisguo pushed a commit to lisguo/opentelemetry-collector-contrib that referenced this pull request Oct 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants