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

feat: add api gateway emulator skeleton #1902

Merged

Conversation

philasmar
Copy link
Contributor

Issue #, if available:
DOTNET-7837

Description of changes:

  • Added an API Gateway Emulator process
  • Added new command line arguments for the emulator
  • Added a service to process Lambda configuration through environment variables
  • Added the ability to match incoming HTTP requests with existing Lambda configurations
  • Added a catch-all HTTP endpoint
  • Updated base Spectre Command to support Cancellation tokens in order to facilitate unit tests

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@philasmar philasmar added the Release Not Needed Add this label if a PR does not need to be released. label Dec 10, 2024
@gcbeattyAWS
Copy link

can you double check the line file endings. i was getting warnings in my ide that they were not set as CRLF

@philasmar
Copy link
Contributor Author

can you double check the line file endings. i was getting warnings in my ide that they were not set as CRLF

Since we are working on different platforms we're bound to run into some line ending issues. I think what we did with the deploy tool was update our git config to retrieve files as LF. (something like that)

@philasmar philasmar requested a review from normj December 11, 2024 21:57
foreach (var routeConfig in _routeConfigs)
{
_logger.LogDebug("Checking if '{Path}' matches '{Template}'.", path, routeConfig.Path);
var template = TemplateParser.Parse(routeConfig.Path);
Copy link
Member

Choose a reason for hiding this comment

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

I don't see any tests for handling API Gateway's style of using {proxy+} to indicate wild card character. I really want to know if Microsoft's TemplateParser is handling that or if we need to roll our own solution. Have you done any side by side comparisons with API Gateway and this library to see if they resolve the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TemplateParser supports a catch-all variable similar to the greedy variable in API gateway. I have updated the implementation to account for it as well as add sorting based on the route priority logic from API Gateway. I have added comments to explain everything in the code.

return null;
}

private RouteValueDictionary GetDefaults(RouteTemplate parsedTemplate)
Copy link
Member

Choose a reason for hiding this comment

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

Are defaults even a think in API Gateway routing? I thought with API Gateway routing you can just have the name of the variable. I could be wrong but be sure we are not just implementing a feature of the Microsoft library and not API Gateway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right. The function was not doing anything for our use case. I removed it.


namespace Amazon.Lambda.TestTool.UnitTests.Services;

public class ApiGatewayRouteConfigServiceTests
Copy link
Member

Choose a reason for hiding this comment

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

You need tests with {proxy+} especially when there are other routes. And you need tests with some overlap in the routes. For example a test with routeA -> /foo/{value} and routeB -> /foo/bar and you test with requests to /foo, /foo/bar and /foo/fred. Similar idea with {proxy+} and make sure we mimic API Gateway's behavior when choosing to use the proxy endpoint versus a more direct path. Another example routeA /{proxy+} and routeB /phil. Requests going to /norm and /phil and /phil/dotnet. Don't expect the Microsoft template library to match API Gateway's behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have updated the implementation to account for it as well as add sorting based on the route priority logic from API Gateway. I have added comments to explain everything in the code.
I also added 1 big test that lists a bunch of different routes with overlap and tests which function was matched. This should cover everything.

@philasmar philasmar requested a review from normj December 12, 2024 17:42
}

[Fact]
public void ProperlySortRouteConfigs()
Copy link
Member

Choose a reason for hiding this comment

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

Do you verify with an API Gateway deployed with routes like this that returns behaves the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes the values I have in the test have been verified in API Gateway

}
}

// If there are leftover route segments
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain what would be an example route and request path that would go into this section. It would be good to add examples in the comment block to help readers. I'm struggling to read this and understand in what scenario would the route ever be a matched if there are more route segments then were in the request path.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I simplified this code paths as it was redundant. This was a leftover from my tweaking when I was working on it. I also added comments and examples explaining the code paths as much as possible.

}

// If request has leftover segments that aren't matched
if (matched && requestPathIndex < requestSegments.Length)
Copy link
Member

Choose a reason for hiding this comment

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

If the variableCount doesn't match the variables found in the request path should that be an false match.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we enter these code paths, then matched will be false and variableCount won't matter.

@philasmar philasmar requested a review from normj December 16, 2024 16:43
Copy link
Member

@normj normj left a comment

Choose a reason for hiding this comment

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

I ask that you change some LogDebug to LogError because they represent invalid user data. Other then that I'm good. I don't need to rereview for the LogError change.

@philasmar philasmar merged commit 86cf81f into feature/lambdatesttool-v2 Dec 16, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Release Not Needed Add this label if a PR does not need to be released.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants