From e379ac1cecad5617759db8830116ed071bf5c396 Mon Sep 17 00:00:00 2001 From: cm-iwata <38879253+cm-iwata@users.noreply.github.com> Date: Sat, 6 Nov 2021 19:52:27 +0900 Subject: [PATCH] Implement APIGateway get_base_path_mapping (#4531) --- moto/apigateway/exceptions.py | 9 ++++ moto/apigateway/models.py | 11 ++++ moto/apigateway/responses.py | 21 ++++++++ moto/apigateway/urls.py | 1 + tests/test_apigateway/test_apigateway.py | 68 ++++++++++++++++++++++++ 5 files changed, 110 insertions(+) diff --git a/moto/apigateway/exceptions.py b/moto/apigateway/exceptions.py index c153e2e78..3d22eab98 100644 --- a/moto/apigateway/exceptions.py +++ b/moto/apigateway/exceptions.py @@ -265,3 +265,12 @@ class BasePathConflictException(ConflictException): super(BasePathConflictException, self).__init__( "ConflictException", "Base path already exists for this domain name" ) + + +class BasePathNotFoundException(NotFoundException): + code = 404 + + def __init__(self): + super(BasePathNotFoundException, self).__init__( + "NotFoundException", "Invalid base path mapping identifier specified" + ) diff --git a/moto/apigateway/models.py b/moto/apigateway/models.py index c90e270c5..fc2352e29 100644 --- a/moto/apigateway/models.py +++ b/moto/apigateway/models.py @@ -47,6 +47,7 @@ from .exceptions import ( InvalidRestApiIdForBasePathMappingException, InvalidStageException, BasePathConflictException, + BasePathNotFoundException, ) from ..core.models import responses_mock from moto.apigateway.exceptions import MethodNotFoundException @@ -1769,6 +1770,16 @@ class APIGatewayBackend(BaseBackend): return list(self.base_path_mappings[domain_name].values()) + def get_base_path_mapping(self, domain_name, base_path): + + if domain_name not in self.domain_names: + raise DomainNameNotFound() + + if base_path not in self.base_path_mappings[domain_name]: + raise BasePathNotFoundException() + + return self.base_path_mappings[domain_name][base_path] + apigateway_backends = {} for region_name in Session().get_available_regions("apigateway"): diff --git a/moto/apigateway/responses.py b/moto/apigateway/responses.py index d7cfb271e..ee890416f 100644 --- a/moto/apigateway/responses.py +++ b/moto/apigateway/responses.py @@ -1,4 +1,5 @@ import json +from urllib.parse import unquote from moto.utilities.utils import merge_multiple_dicts from moto.core.responses import BaseResponse @@ -876,3 +877,23 @@ class APIGatewayResponse(BaseResponse): return self.error("NotFoundException", e.message, 404) except ConflictException as e: return self.error("ConflictException", e.message, 409) + + def base_path_mapping_individual(self, request, full_url, headers): + + self.setup_class(request, full_url, headers) + + url_path_parts = self.path.split("/") + domain_name = url_path_parts[2] + base_path = unquote(url_path_parts[4]) + + try: + if self.method == "GET": + base_path_mapping = self.backend.get_base_path_mapping( + domain_name, base_path + ) + return 200, {}, json.dumps(base_path_mapping) + elif self.method == "DELETE": + # TODO Implements + pass + except NotFoundException as e: + return self.error("NotFoundException", e.message, 404) diff --git a/moto/apigateway/urls.py b/moto/apigateway/urls.py index 2e602d5b1..4ab409038 100644 --- a/moto/apigateway/urls.py +++ b/moto/apigateway/urls.py @@ -28,6 +28,7 @@ url_paths = { "{0}/restapis/(?P[^/]+)/models/(?P[^/]+)/?$": response.model_induvidual, "{0}/domainnames/(?P[^/]+)/?$": response.domain_name_induvidual, "{0}/domainnames/(?P[^/]+)/basepathmappings$": response.base_path_mappings, + "{0}/domainnames/(?P[^/]+)/basepathmappings/(?P[^/]+)$": response.base_path_mapping_individual, "{0}/usageplans/(?P[^/]+)/?$": response.usage_plan_individual, "{0}/usageplans/(?P[^/]+)/keys$": response.usage_plan_keys, "{0}/usageplans/(?P[^/]+)/keys/(?P[^/]+)/?$": response.usage_plan_key_individual, diff --git a/tests/test_apigateway/test_apigateway.py b/tests/test_apigateway/test_apigateway.py index bc8319e37..9cdff407b 100644 --- a/tests/test_apigateway/test_apigateway.py +++ b/tests/test_apigateway/test_apigateway.py @@ -2559,3 +2559,71 @@ def test_get_base_path_mappings_with_unknown_domain(): ) ex.value.response["Error"]["Code"].should.equal("NotFoundException") ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(404) + + +@mock_apigateway +def test_get_base_path_mapping(): + client = boto3.client("apigateway", region_name="us-west-2") + domain_name = "testDomain" + test_certificate_name = "test.certificate" + client.create_domain_name( + domainName=domain_name, certificateName=test_certificate_name + ) + + response = client.create_rest_api(name="my_api", description="this is my api") + api_id = response["id"] + + stage_name = "dev" + create_method_integration(client, api_id) + client.create_deployment( + restApiId=api_id, stageName=stage_name, description="1.0.1" + ) + + client.create_base_path_mapping( + domainName=domain_name, restApiId=api_id, stage=stage_name + ) + + response = client.get_base_path_mapping(domainName=domain_name, basePath="(none)") + response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200) + response["basePath"].should.equal("(none)") + response["restApiId"].should.equal(api_id) + response["stage"].should.equal(stage_name) + + +@mock_apigateway +def test_get_base_path_mapping_with_unknown_domain(): + client = boto3.client("apigateway", region_name="us-west-2") + + with pytest.raises(ClientError) as ex: + client.get_base_path_mapping(domainName="unknown-domain", basePath="v1") + + ex.value.response["Error"]["Message"].should.equal( + "Invalid domain name identifier specified" + ) + ex.value.response["Error"]["Code"].should.equal("NotFoundException") + ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(404) + + +@mock_apigateway +def test_get_base_path_mapping_with_unknown_base_path(): + client = boto3.client("apigateway", region_name="us-west-2") + domain_name = "testDomain" + test_certificate_name = "test.certificate" + client.create_domain_name( + domainName=domain_name, certificateName=test_certificate_name + ) + + response = client.create_rest_api(name="my_api", description="this is my api") + api_id = response["id"] + client.create_base_path_mapping( + domainName=domain_name, restApiId=api_id, basePath="v1" + ) + + with pytest.raises(ClientError) as ex: + client.get_base_path_mapping(domainName=domain_name, basePath="unknown") + + ex.value.response["Error"]["Message"].should.equal( + "Invalid base path mapping identifier specified" + ) + ex.value.response["Error"]["Code"].should.equal("NotFoundException") + ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(404)