Skip to content

Commit 75774da

Browse files
committed
rewrite to use a global route
1 parent 6122a88 commit 75774da

27 files changed

+431
-307
lines changed

localstack-core/localstack/config.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,8 +1033,11 @@ def populate_edge_configuration(
10331033
LEGACY_SNS_GCM_PUBLISHING = is_env_true("LEGACY_SNS_GCM_PUBLISHING")
10341034

10351035
# Whether to enable the Next Gen APIGW invocation logic (handler chain)
1036-
# TODO: fix this, set `is_env_true` to disabled by default
1037-
ENABLE_APIGW_NEXT_GEN = is_env_not_false("ENABLE_APIGW_NEXT_GEN")
1036+
# TODO: remove this before merge!
1037+
if not os.environ.get("PROVIDER_OVERRIDE_APIGATEWAY"):
1038+
os.environ["PROVIDER_OVERRIDE_APIGATEWAY"] = "next_gen"
1039+
1040+
APIGW_NEXT_GEN_PROVIDER = os.environ.get("PROVIDER_OVERRIDE_APIGATEWAY", "") == "next_gen"
10381041

10391042
# TODO remove fallback to LAMBDA_DOCKER_NETWORK with next minor version
10401043
MAIN_DOCKER_NETWORK = os.environ.get("MAIN_DOCKER_NETWORK", "") or LAMBDA_DOCKER_NETWORK

localstack-core/localstack/services/apigateway/execute_api/api.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

localstack-core/localstack/services/apigateway/execute_api/gateway.py

Lines changed: 0 additions & 6 deletions
This file was deleted.

localstack-core/localstack/services/apigateway/execute_api/handlers/method_response.py

Lines changed: 0 additions & 20 deletions
This file was deleted.

localstack-core/localstack/services/apigateway/execute_api/handlers/parse.py

Lines changed: 0 additions & 22 deletions
This file was deleted.

localstack-core/localstack/services/apigateway/execute_api/router.py

Lines changed: 0 additions & 94 deletions
This file was deleted.

localstack-core/localstack/services/apigateway/helpers.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
from botocore.utils import InvalidArnException
1414
from jsonpatch import apply_patch
1515
from jsonpointer import JsonPointerException
16-
from moto.apigateway.models import Integration, Resource, RestAPI, apigateway_backends
16+
from moto.apigateway import models as apigw_models
17+
from moto.apigateway.models import Integration, Resource, apigateway_backends
18+
from moto.apigateway.models import RestAPI as MotoRestAPI
1719
from moto.apigateway.utils import create_id as create_resource_id
1820
from requests.models import Response
1921

@@ -26,6 +28,7 @@
2628
DocumentationPartLocation,
2729
IntegrationType,
2830
Model,
31+
NotFoundException,
2932
RequestValidator,
3033
)
3134
from localstack.aws.connect import connect_to
@@ -141,6 +144,25 @@ def get_apigateway_store_for_invocation(context: ApiInvocationContext) -> ApiGat
141144
return apigateway_stores[account_id][region_name]
142145

143146

147+
def get_moto_rest_api(context: RequestContext, rest_api_id: str) -> MotoRestAPI:
148+
moto_backend = apigw_models.apigateway_backends[context.account_id][context.region]
149+
if rest_api := moto_backend.apis.get(rest_api_id):
150+
return rest_api
151+
else:
152+
raise NotFoundException(
153+
f"Invalid API identifier specified {context.account_id}:{rest_api_id}"
154+
)
155+
156+
157+
def get_rest_api_container(context: RequestContext, rest_api_id: str) -> RestApiContainer:
158+
store = get_apigateway_store(context=context)
159+
if not (rest_api_container := store.rest_apis.get(rest_api_id)):
160+
raise NotFoundException(
161+
f"Invalid API identifier specified {context.account_id}:{rest_api_id}"
162+
)
163+
return rest_api_container
164+
165+
144166
class ApiGatewayIntegrationError(Exception):
145167
"""
146168
Base class for all ApiGateway Integration errors.
@@ -918,8 +940,8 @@ def add_documentation_parts(rest_api_container, documentation):
918940

919941

920942
def import_api_from_openapi_spec(
921-
rest_api: RestAPI, body: dict, context: RequestContext
922-
) -> Optional[RestAPI]:
943+
rest_api: MotoRestAPI, body: dict, context: RequestContext
944+
) -> Optional[MotoRestAPI]:
923945
"""Import an API from an OpenAPI spec document"""
924946

925947
query_params: dict = context.request.values.to_dict()

localstack-core/localstack/services/apigateway/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from localstack.services.stores import (
1919
AccountRegionBundle,
2020
BaseStore,
21+
CrossAccountAttribute,
2122
CrossRegionAttribute,
2223
LocalAttribute,
2324
)
@@ -88,6 +89,10 @@ class ApiGatewayStore(BaseStore):
8889
# internal deployments, represents a frozen REST API for a deployment
8990
internal_deployments: dict[str, RestApiDeployment] = LocalAttribute(default=dict)
9091

92+
# active deployments, mapping API ID + Stage to deployment ID
93+
# TODO: make sure API ID are unique across all accounts
94+
active_deployments: dict[(str, str), str] = CrossAccountAttribute(dict)
95+
9196
def __init__(self):
9297
super().__init__()
9398

localstack-core/localstack/services/apigateway/next_gen/execute_api/__init__.py

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from typing import Callable, Type
2+
3+
from rolo import Response
4+
from rolo.gateway.chain import HandlerChain as RoloHandlerChain
5+
6+
from .context import RestApiInvocationContext
7+
8+
RestApiGatewayHandler = Callable[
9+
[RoloHandlerChain[RestApiInvocationContext], RestApiInvocationContext, Response], None
10+
]
11+
12+
RestApiGatewayHandlerChain: Type[RoloHandlerChain[RestApiInvocationContext]] = RoloHandlerChain

localstack-core/localstack/services/apigateway/execute_api/context.py renamed to localstack-core/localstack/services/apigateway/next_gen/execute_api/context.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
from rolo import Request
44
from rolo.gateway import RequestContext
55

6-
from ..models import RestApiDeployment
6+
from localstack.services.apigateway.models import RestApiDeployment
77

88

9-
class InvocationContext(RequestContext):
9+
class RestApiInvocationContext(RequestContext):
1010
"""
1111
This context is going to be used to pass relevant information across an API Gateway invocation.
1212
"""
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from rolo import Response
2+
from rolo.gateway import Gateway
3+
4+
from . import handlers
5+
from .context import RestApiInvocationContext
6+
7+
8+
class RestApiGateway(Gateway):
9+
# TODO: not sure we need to extend it, might remove if not needed
10+
def __init__(self):
11+
super().__init__(context_class=RestApiInvocationContext)
12+
self.request_handlers.extend(
13+
[
14+
handlers.preprocess_request,
15+
handlers.method_request_handler,
16+
handlers.integration_request_handler,
17+
handlers.integration_handler,
18+
# temporary handler which executes everything for now
19+
handlers.global_temporary_handler,
20+
]
21+
)
22+
self.response_handlers.extend(
23+
[
24+
handlers.integration_response_handler,
25+
handlers.method_response_handler,
26+
# add composite response handlers?
27+
]
28+
)
29+
# TODO: we need the exception handler instead of serializing them
30+
self.exception_handlers.extend([])
31+
32+
def process_with_context(self, context: RestApiInvocationContext, response: Response):
33+
chain = self.new_chain()
34+
chain.handle(context, response)

localstack-core/localstack/services/apigateway/execute_api/handlers/integration.py renamed to localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/integration.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22

33
from localstack.http import Response
44

5-
from ..api import ApiGatewayHandler, ApiGatewayHandlerChain
6-
from ..context import InvocationContext
5+
from ..api import RestApiGatewayHandler, RestApiGatewayHandlerChain
6+
from ..context import RestApiInvocationContext
77

88
LOG = logging.getLogger(__name__)
99

1010

1111
# TODO: this will need to use ApiGatewayIntegration class, using Plugin for discoverability and a PluginManager,
1212
# in order to automatically have access to defined Integrations that we can extend
1313
# this might be a bit closer to our AWS Skeleton in a way
14-
class IntegrationHandler(ApiGatewayHandler):
14+
class IntegrationHandler(RestApiGatewayHandler):
1515
def __call__(
16-
self, chain: ApiGatewayHandlerChain, context: InvocationContext, response: Response
16+
self,
17+
chain: RestApiGatewayHandlerChain,
18+
context: RestApiInvocationContext,
19+
response: Response,
1720
):
1821
return

localstack-core/localstack/services/apigateway/execute_api/handlers/integration_request.py renamed to localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/integration_request.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@
22

33
from localstack.http import Response
44

5-
from ..api import ApiGatewayHandler, ApiGatewayHandlerChain
6-
from ..context import InvocationContext
5+
from ..api import RestApiGatewayHandler, RestApiGatewayHandlerChain
6+
from ..context import RestApiInvocationContext
77

88
LOG = logging.getLogger(__name__)
99

1010

11-
class IntegrationRequestHandler(ApiGatewayHandler):
11+
class IntegrationRequestHandler(RestApiGatewayHandler):
1212
"""
1313
This class will take care of the Integration Request part, which is mostly linked to template mapping
1414
See https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-integration-settings-integration-request.html
1515
"""
1616

1717
def __call__(
18-
self, chain: ApiGatewayHandlerChain, context: InvocationContext, response: Response
18+
self,
19+
chain: RestApiGatewayHandlerChain,
20+
context: RestApiInvocationContext,
21+
response: Response,
1922
):
2023
return

localstack-core/localstack/services/apigateway/execute_api/handlers/integration_response.py renamed to localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/integration_response.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@
22

33
from localstack.http import Response
44

5-
from ..api import ApiGatewayHandler, ApiGatewayHandlerChain
6-
from ..context import InvocationContext
5+
from ..api import RestApiGatewayHandler, RestApiGatewayHandlerChain
6+
from ..context import RestApiInvocationContext
77

88
LOG = logging.getLogger(__name__)
99

1010

11-
class IntegrationResponseHandler(ApiGatewayHandler):
11+
class IntegrationResponseHandler(RestApiGatewayHandler):
1212
"""
1313
This class will take care of the Integration Response part, which is mostly linked to template mapping
1414
See https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-integration-settings-integration-response.html
1515
"""
1616

1717
def __call__(
18-
self, chain: ApiGatewayHandlerChain, context: InvocationContext, response: Response
18+
self,
19+
chain: RestApiGatewayHandlerChain,
20+
context: RestApiInvocationContext,
21+
response: Response,
1922
):
2023
# TODO: if the integration type is AWS_PROXY, return
2124
return

0 commit comments

Comments
 (0)