Example #1
0
    def test_create_creates_dict_of_routes(self):
        function_name_1 = Mock()
        function_name_2 = Mock()
        api_gateway_route_1 = Route(methods=["GET"], function_name=function_name_1, path="/")
        api_gateway_route_2 = Route(methods=["POST"], function_name=function_name_2, path="/")

        list_of_routes = [api_gateway_route_1, api_gateway_route_2]

        lambda_runner = Mock()

        api = Api(routes=list_of_routes)
        service = LocalApigwService(api, lambda_runner)

        service.create()

        self.assertEqual(service._dict_of_routes, {"/:GET": api_gateway_route_1, "/:POST": api_gateway_route_2})
Example #2
0
 def test_resource_with_method_correct_routes(self):
     template = {
         "Resources": {
             "TestApi": {"Type": "AWS::ApiGateway::Resource", "Properties": {"StageName": "Prod"}},
             "BetaApiResource": {
                 "Type": "AWS::ApiGateway::Resource",
                 "Properties": {"PathPart": "beta", "ResourceId": "TestApi"},
             },
             "BetaAlphaApiMethod": {
                 "Type": "AWS::ApiGateway::Method",
                 "Properties": {"HttpMethod": "ANY", "RestApiId": "TestApi", "ResourceId": "BetaApiResource"},
             },
         }
     }
     provider = ApiProvider(template)
     assertCountEqual(
         self,
         provider.routes,
         [
             Route(
                 path="/beta",
                 methods=["POST", "GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "PUT"],
                 function_name=None,
             )
         ],
     )
Example #3
0
    def test_provider_parse_stage_name(self):
        template = {
            "Resources": {
                "Stage": {"Type": "AWS::ApiGateway::Stage", "Properties": {"StageName": "dev", "RestApiId": "TestApi"}},
                "TestApi": {
                    "Type": "AWS::ApiGateway::RestApi",
                    "Properties": {
                        "Body": {
                            "paths": {
                                "/path": {
                                    "get": {
                                        "x-amazon-apigateway-integration": {
                                            "httpMethod": "POST",
                                            "type": "aws_proxy",
                                            "uri": {
                                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31"
                                                "/functions/${NoApiEventFunction.Arn}/invocations"
                                            },
                                            "responses": {},
                                        }
                                    }
                                }
                            }
                        }
                    },
                },
            }
        }
        provider = ApiProvider(template)
        route1 = Route(path="/path", methods=["GET"], function_name="NoApiEventFunction")

        self.assertIn(route1, provider.routes)
        self.assertEqual(provider.api.stage_name, "dev")
        self.assertEqual(provider.api.stage_variables, None)
Example #4
0
    def _convert_event_route(lambda_logical_id, event_properties):
        """
        Converts a AWS::Serverless::Function's Event Property to an Route configuration usable by the provider.

        :param str lambda_logical_id: Logical Id of the AWS::Serverless::Function
        :param dict event_properties: Dictionary of the Event's Property
        :return tuple: tuple of route resource name and route
        """
        path = event_properties.get(SamApiProvider._EVENT_PATH)
        method = event_properties.get(SamApiProvider._EVENT_METHOD)

        # An API Event, can have RestApiId property which designates the resource that owns this API. If omitted,
        # the API is owned by Implicit API resource. This could either be a direct resource logical ID or a
        # "Ref" of the logicalID
        api_resource_id = event_properties.get(
            "RestApiId", SamApiProvider.IMPLICIT_API_RESOURCE_ID)
        if isinstance(api_resource_id, dict) and "Ref" in api_resource_id:
            api_resource_id = api_resource_id["Ref"]

        # This is still a dictionary. Something wrong with the template
        if isinstance(api_resource_id, dict):
            LOG.debug("Invalid RestApiId property of event %s",
                      event_properties)
            raise InvalidSamDocumentException(
                "RestApiId property of resource with logicalId '{}' is invalid. "
                "It should either be a LogicalId string or a Ref of a Logical Id string"
                .format(lambda_logical_id))

        return api_resource_id, Route(path=path,
                                      methods=[method],
                                      function_name=lambda_logical_id)
Example #5
0
    def dedupe_function_routes(routes: List[Route]) -> List[Route]:
        """
         Remove duplicate routes that have the same function_name and method

         route: list(Route)
             List of Routes

        Return
        -------
        A list of routes without duplicate routes with the same stack_path, function_name and method
        """
        grouped_routes: Dict[str, Route] = {}

        for route in routes:
            key = "{}-{}-{}".format(route.stack_path, route.function_name,
                                    route.path)
            config = grouped_routes.get(key, None)
            methods = route.methods
            if config:
                methods += config.methods
            sorted_methods = sorted(methods)
            grouped_routes[key] = Route(
                function_name=route.function_name,
                path=route.path,
                methods=sorted_methods,
                event_type=route.event_type,
                payload_format_version=route.payload_format_version,
                stack_path=route.stack_path,
            )
        return list(grouped_routes.values())
Example #6
0
    def test_with_one_path_method(self):
        function_name = "myfunction"
        swagger = {
            "paths": {
                "/path1": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "type": "aws_proxy",
                            "uri": "someuri"
                        }
                    }
                }
            }
        }

        parser = SwaggerParser(swagger)
        parser._get_integration_function_name = Mock()
        parser._get_integration_function_name.return_value = function_name

        expected = [
            Route(path="/path1", methods=["get"], function_name=function_name)
        ]
        result = parser.get_routes()

        self.assertEqual(expected, result)
        parser._get_integration_function_name.assert_called_with({
            "x-amazon-apigateway-integration": {
                "type": "aws_proxy",
                "uri": "someuri"
            }
        })
    def _extract_cfn_gateway_v2_route(self, stack_path: str, resources,
                                      logical_id, route_resource, collector):
        """
        Extract APIs from AWS::ApiGatewayV2::Route, and link it with the integration resource to get the lambda
        function.

        Parameters
        ----------
        stack_path : str
            Path of the stack the resource is located

        resources: dict
            All Resource definition, including its properties

        logical_id : str
            Logical ID of the resource

        route_resource : dict
            Resource definition, including its properties

        collector : ApiCollector
            Instance of the API collector that where we will save the API information
        """

        properties = route_resource.get("Properties", {})
        api_id = properties.get("ApiId")
        route_key = properties.get("RouteKey")
        integration_target = properties.get("Target")

        if integration_target:
            function_name, payload_format_version = self._get_route_function_name(
                resources, integration_target)
        else:
            LOG.debug(
                "Skipping The AWS::ApiGatewayV2::Route '%s', as it does not contain an integration for a Lambda "
                "Function",
                logical_id,
            )
            return

        method, path = self._parse_route_key(route_key)

        if not route_key or not method or not path:
            LOG.debug(
                "The AWS::ApiGatewayV2::Route '%s' does not have a correct route key '%s'",
                logical_id, route_key)
            raise InvalidSamTemplateException(
                "The AWS::ApiGatewayV2::Route {} does not have a correct route key {}"
                .format(logical_id, route_key))

        routes = Route(
            methods=[method],
            path=path,
            function_name=function_name,
            event_type=Route.HTTP,
            payload_format_version=payload_format_version,
            stack_path=stack_path,
        )
        collector.add_routes(api_id, [routes])
    def test_create_creates_dict_of_routes(self):
        function_name_1 = Mock()
        function_name_2 = Mock()
        api_gateway_route_1 = Route(['GET'], function_name_1, '/')
        api_gateway_route_2 = Route(['POST'], function_name_2, '/')

        list_of_routes = [api_gateway_route_1, api_gateway_route_2]

        lambda_runner = Mock()

        service = LocalApigwService(list_of_routes, lambda_runner)

        service.create()

        self.assertEquals(service._dict_of_routes, {'/:GET': api_gateway_route_1,
                                                    '/:POST': api_gateway_route_2
                                                    })
Example #9
0
    def test_swagger_with_any_method(self):
        routes = [Route(path="/path", methods=["any"], function_name="SamFunc1")]

        expected_routes = [
            Route(
                path="/path",
                methods=["GET", "DELETE", "PUT", "POST", "HEAD", "OPTIONS", "PATCH"],
                function_name="SamFunc1",
            )
        ]

        template = {
            "Resources": {"Api1": {"Type": "AWS::ApiGateway::RestApi", "Properties": {"Body": make_swagger(routes)}}}
        }

        provider = ApiProvider(template)
        self.assertCountEqual(expected_routes, provider.routes)
 def setUp(self):
     self.function_name = "name"
     self.stage_name = "Dev"
     self.stage_variables = {"test": "sample"}
     self.api_gateway = Route(['POST'],
                              self.function_name,
                              '/',
                              stage_name=self.stage_name,
                              stage_variables=self.stage_variables)
Example #11
0
    def test_with_combination_of_paths_methods(self):
        function_name = "myfunction"
        swagger = {
            "paths": {
                "/path1": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "type": "aws_proxy",
                            "uri": "someuri"
                        }
                    },
                    "delete": {
                        "x-amazon-apigateway-integration": {
                            "type": "aws_proxy",
                            "uri": "someuri"
                        }
                    }
                },
                "/path2": {
                    "post": {
                        "x-amazon-apigateway-integration": {
                            "type": "aws_proxy",
                            "uri": "someuri"
                        }
                    }
                }
            }
        }

        parser = SwaggerParser(swagger)
        parser._get_integration_function_name = Mock()
        parser._get_integration_function_name.return_value = function_name

        expected = {
            Route(path="/path1", methods=["get"], function_name=function_name),
            Route(path="/path1",
                  methods=["delete"],
                  function_name=function_name),
            Route(path="/path2", methods=["post"],
                  function_name=function_name),
        }
        result = parser.get_routes()

        self.assertEquals(expected, set(result))
Example #12
0
    def _extract_cfn_gateway_v2_api(
        self,
        stack_path: str,
        logical_id: str,
        api_resource: Dict,
        collector: ApiCollector,
        cwd: Optional[str] = None,
    ) -> None:
        """
        Extract APIs from AWS::ApiGatewayV2::Api resource by reading and parsing Swagger documents. The result is
        added to the collector. If the Swagger documents is not available, it can add a catch-all route based on
        the target function.

        Parameters
        ----------
        stack_path : str
            Path of the stack the resource is located

        logical_id : str
            Logical ID of the resource
        api_resource : dict
            Resource definition, including its properties
        collector : ApiCollector
            Instance of the API collector that where we will save the API information
        cwd : Optional[str]
            An optional string to override the current working directory
        """
        properties = api_resource.get("Properties", {})
        body = properties.get("Body")
        body_s3_location = properties.get("BodyS3Location")
        cors = self.extract_cors_http(properties.get("CorsConfiguration"))
        target = properties.get("Target")
        route_key = properties.get("RouteKey")
        protocol_type = properties.get("ProtocolType")

        if not body and not body_s3_location:
            LOG.debug(
                "Swagger document not found in Body and BodyS3Location for resource '%s'.",
                logical_id)
            if cors:
                collector.cors = cors
            if target and protocol_type == CfnApiProvider.HTTP_API_PROTOCOL_TYPE:
                method, path = self._parse_route_key(route_key)
                routes = Route(
                    methods=[method],
                    path=path,
                    function_name=LambdaUri.get_function_name(target),
                    event_type=Route.HTTP,
                    stack_path=stack_path,
                )
                collector.add_routes(logical_id, [routes])
            return

        CfnBaseApiProvider.extract_swagger_route(stack_path, logical_id, body,
                                                 body_s3_location, None,
                                                 collector, cwd, Route.HTTP)
    def _extract_cloud_formation_method(self, stack_path: str, resources,
                                        logical_id, method_resource,
                                        collector):
        """
        Extract APIs from AWS::ApiGateway::Method and work backwards up the tree to resolve and find the true path.

        Parameters
        ----------
        stack_path : str
            Path of the stack the resource is located

        resources: dict
            All Resource definition, including its properties

        logical_id : str
            Logical ID of the resource

        method_resource : dict
            Resource definition, including its properties

        collector : ApiCollector
            Instance of the API collector that where we will save the API information
        """

        properties = method_resource.get("Properties", {})
        resource_id = properties.get("ResourceId")
        rest_api_id = properties.get("RestApiId")
        method = properties.get("HttpMethod")

        resource_path = "/"
        if isinstance(resource_id,
                      str):  # If the resource_id resolves to a string
            resource = resources.get(resource_id)

            if resource:
                resource_path = self.resolve_resource_path(
                    resources, resource, "")
            else:
                # This is the case that a raw ref resolves to a string { "Fn::GetAtt": ["MyRestApi", "RootResourceId"] }
                resource_path = resource_id

        integration = properties.get("Integration", {})
        content_type = integration.get("ContentType")

        content_handling = integration.get("ContentHandling")

        if content_handling == CfnApiProvider.METHOD_BINARY_TYPE and content_type:
            collector.add_binary_media_types(logical_id, [content_type])

        routes = Route(
            methods=[method],
            function_name=self._get_integration_function_name(integration),
            path=resource_path,
            stack_path=stack_path,
        )
        collector.add_routes(rest_api_id, [routes])
    def test_must_print_routes(self):
        host = "host"
        port = 123

        apis = [
            Route(path="/1", methods=["GET"], function_name="name1"),
            Route(path="/1", methods=["POST"], function_name="name1"),
            Route(path="/1", methods=["DELETE"], function_name="othername1"),
            Route(path="/2", methods=["GET2"], function_name="name2"),
            Route(path="/3", methods=["GET3"], function_name="name3"),
        ]
        apis = ApiCollector.dedupe_function_routes(apis)
        expected = {"Mounting name1 at http://host:123/1 [GET, POST]",
                    "Mounting othername1 at http://host:123/1 [DELETE]",
                    "Mounting name2 at http://host:123/2 [GET2]",
                    "Mounting name3 at http://host:123/3 [GET3]"}

        actual = LocalApiService._print_routes(apis, host, port)
        self.assertEquals(expected, set(actual))
Example #15
0
    def test_must_return_routing_list_from_apis(self):
        api_provider = Mock()
        apis = [
            Api(path="/1", method="GET1", function_name="name1", cors="CORS1"),
            Api(path="/2", method="GET2", function_name="name2", cors="CORS2"),
            Api(path="/3", method="GET3", function_name="name3", cors="CORS3"),
        ]
        expected = [
            Route(path="/1", methods=["GET1"], function_name="name1"),
            Route(path="/2", methods=["GET2"], function_name="name2"),
            Route(path="/3", methods=["GET3"], function_name="name3")
        ]

        api_provider.get_all.return_value = apis

        result = LocalApiService._make_routing_list(api_provider)
        self.assertEquals(len(result), len(expected))
        for index, r in enumerate(result):
            self.assertEquals(r.__dict__, expected[index].__dict__)
Example #16
0
    def test_payload_format_version(self):
        function_name = "myfunction"
        swagger = {
            "paths": {
                "/path1": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "type": "aws_proxy",
                            "uri": "someuri",
                            "payloadFormatVersion": "1.0",
                        }
                    }
                },
                "/path2": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "type": "aws_proxy",
                            "uri": "someuri",
                            "payloadFormatVersion": "2.0",
                        }
                    }
                },
            }
        }

        parser = SwaggerParser(swagger)
        parser._get_integration_function_name = Mock()
        parser._get_integration_function_name.return_value = function_name

        expected = [
            Route(path="/path1",
                  methods=["get"],
                  function_name=function_name,
                  payload_format_version="1.0"),
            Route(path="/path2",
                  methods=["get"],
                  function_name=function_name,
                  payload_format_version="2.0"),
        ]
        result = parser.get_routes()

        self.assertEqual(expected, result)
    def test_route_object_equals(self):
        route1 = Route(function_name="test",
                       path="/test",
                       methods=["POST", "GET"])
        route2 = type('obj', (object, ), {
            'function_name': 'test',
            "path": "/test",
            "methods": ["GET", "POST"]
        })

        self.assertNotEqual(route1, route2)
Example #18
0
    def get_routes(self):
        """
        Parses a swagger document and returns a list of APIs configured in the document.

        Swagger documents have the following structure
        {
            "/path1": {    # path
                "get": {   # method
                    "x-amazon-apigateway-integration": {   # integration
                        "type": "aws_proxy",

                        # URI contains the Lambda function ARN that needs to be parsed to get Function Name
                        "uri": {
                            "Fn::Sub":
                                "arn:aws:apigateway:aws:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/..."
                        }
                    }
                },
                "post": {
                },
            },
            "/path2": {
                ...
            }
        }

        Returns
        -------
        list of list of samcli.commands.local.apigw.local_apigw_service.Route
            List of APIs that are configured in the Swagger document
        """

        result = []
        paths_dict = self.swagger.get("paths", {})

        for full_path, path_config in paths_dict.items():
            for method, method_config in path_config.items():

                function_name = self._get_integration_function_name(
                    method_config)
                if not function_name:
                    LOG.debug(
                        "Lambda function integration not found in Swagger document at path='%s' method='%s'",
                        full_path,
                        method,
                    )
                    continue

                if method.lower() == self._ANY_METHOD_EXTENSION_KEY:
                    # Convert to a more commonly used method notation
                    method = self._ANY_METHOD
                route = Route(function_name, full_path, methods=[method])
                result.append(route)
        return result
Example #19
0
    def test_with_binary_media_types(self):
        template = {
            "Resources": {
                "Api1": {
                    "Type": "AWS::ApiGateway::RestApi",
                    "Properties": {"Body": make_swagger(self.input_routes, binary_media_types=self.binary_types)},
                }
            }
        }

        expected_binary_types = sorted(self.binary_types)
        expected_apis = [
            Route(path="/path1", methods=["GET", "POST"], function_name="SamFunc1"),
            Route(path="/path2", methods=["PUT", "GET"], function_name="SamFunc1"),
            Route(path="/path3", methods=["DELETE"], function_name="SamFunc1"),
        ]

        provider = ApiProvider(template)
        self.assertCountEqual(expected_apis, provider.routes)
        self.assertCountEqual(provider.api.binary_media_types, expected_binary_types)
    def setUp(self):
        self.function_name = Mock()
        self.api_gateway_route = Route(methods=["GET"], function_name=self.function_name, path="/")
        self.list_of_routes = [self.api_gateway_route]

        self.lambda_runner = Mock()
        self.lambda_runner.is_debugging.return_value = False

        self.stderr = Mock()
        self.api = Api(routes=self.list_of_routes)
        self.service = LocalApigwService(self.api, self.lambda_runner, port=3000, host="127.0.0.1", stderr=self.stderr)
Example #21
0
    def _convert_event_route(stack_path: str, lambda_logical_id,
                             event_properties, event_type):
        """
        Converts a AWS::Serverless::Function's Event Property to an Route configuration usable by the provider.

        :param str stack_path: Path of the stack the resource is located
        :param str lambda_logical_id: Logical Id of the AWS::Serverless::Function
        :param dict event_properties: Dictionary of the Event's Property
        :param event_type: The event type, 'Api' or 'HttpApi', see samcli/local/apigw/local_apigw_service.py:35
        :return tuple: tuple of route resource name and route
        """
        path = event_properties.get(SamApiProvider._EVENT_PATH)
        method = event_properties.get(SamApiProvider._EVENT_METHOD)

        # An RESTAPI (HTTPAPI) Event, can have RestApiId (ApiId) property which designates the resource that owns this
        # API. If omitted, the API is owned by Implicit API resource. This could either be a direct resource logical ID
        # or a "Ref" of the logicalID

        api_resource_id = None
        payload_format_version = None

        if event_type == SamApiProvider._EVENT_TYPE_API:
            api_resource_id = event_properties.get(
                "RestApiId", SamApiProvider.IMPLICIT_API_RESOURCE_ID)
        else:
            api_resource_id = event_properties.get(
                "ApiId", SamApiProvider.IMPLICIT_HTTP_API_RESOURCE_ID)
            payload_format_version = event_properties.get(
                "PayloadFormatVersion")

        if isinstance(api_resource_id, dict) and "Ref" in api_resource_id:
            api_resource_id = api_resource_id["Ref"]

        # This is still a dictionary. Something wrong with the template
        if isinstance(api_resource_id, dict):
            LOG.debug("Invalid RestApiId property of event %s",
                      event_properties)
            raise InvalidSamDocumentException(
                "RestApiId property of resource with logicalId '{}' is invalid. "
                "It should either be a LogicalId string or a Ref of a Logical Id string"
                .format(lambda_logical_id))

        return (
            api_resource_id,
            Route(
                path=path,
                methods=[method],
                function_name=lambda_logical_id,
                event_type=event_type,
                payload_format_version=payload_format_version,
                stack_path=stack_path,
            ),
        )
Example #22
0
    def test_resolve_correct_multi_parent_resource_path(self):
        template = {
            "Resources": {
                "TestApi": {"Type": "AWS::ApiGateway::Resource", "Properties": {"StageName": "Prod"}},
                "RootApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "root", "ResourceId": "TestApi"},
                },
                "V1ApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "v1", "ResourceId": "TestApi", "ParentId": "RootApiResource"},
                },
                "AlphaApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "alpha", "ResourceId": "TestApi", "ParentId": "V1ApiResource"},
                },
                "BetaApiResource": {
                    "Type": "AWS::ApiGateway::Resource",
                    "Properties": {"PathPart": "beta", "ResourceId": "TestApi", "ParentId": "V1ApiResource"},
                },
                "AlphaApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {"HttpMethod": "GET", "RestApiId": "TestApi", "ResourceId": "AlphaApiResource"},
                },
                "BetaAlphaApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {"HttpMethod": "POST", "RestApiId": "TestApi", "ResourceId": "BetaApiResource"},
                },
            }
        }

        provider = ApiProvider(template)
        assertCountEqual(
            self,
            provider.routes,
            [
                Route(path="/root/v1/beta", methods=["POST"], function_name=None),
                Route(path="/root/v1/alpha", methods=["GET"], function_name=None),
            ],
        )
Example #23
0
    def test_with_binary_media_types_in_swagger_and_on_resource(self):
        input_routes = [Route(path="/path", methods=["OPTIONS"], function_name="SamFunc1")]
        extra_binary_types = ["text/html"]

        template = {
            "Resources": {
                "Api1": {
                    "Type": "AWS::ApiGateway::RestApi",
                    "Properties": {
                        "BinaryMediaTypes": extra_binary_types,
                        "Body": make_swagger(input_routes, binary_media_types=self.binary_types),
                    },
                }
            }
        }

        expected_binary_types = sorted(self.binary_types + extra_binary_types)
        expected_routes = [Route(path="/path", methods=["OPTIONS"], function_name="SamFunc1")]

        provider = ApiProvider(template)
        self.assertCountEqual(expected_routes, provider.routes)
        self.assertCountEqual(provider.api.binary_media_types, expected_binary_types)
 def test_route_different_path_hash(self):
     route1 = Route(function_name="test",
                    path="/test1",
                    methods=["GET", "POST"])
     route2 = Route(function_name="test",
                    path="/test2",
                    methods=["GET", "POST"])
     self.assertNotEqual(route1.__hash__(), route2.__hash__())
 def test_route_method_order_hash(self):
     route1 = Route(function_name="test",
                    path="/test",
                    methods=["POST", "GET"])
     route2 = Route(function_name="test",
                    path="/test",
                    methods=["GET", "POST"])
     self.assertEquals(route1.__hash__(), route2.__hash__())
Example #26
0
    def setUp(self):
        self.function_name = Mock()
        self.api_gateway_route = Route(['GET'], self.function_name, '/')
        self.list_of_routes = [self.api_gateway_route]

        self.lambda_runner = Mock()
        self.lambda_runner.is_debugging.return_value = False

        self.stderr = Mock()
        self.service = LocalApigwService(self.list_of_routes,
                                         self.lambda_runner,
                                         port=3000,
                                         host='127.0.0.1',
                                         stderr=self.stderr)
Example #27
0
    def test_basic_rest_api_resource_method(self):
        template = {
            "Resources": {
                "TestApi": {"Type": "AWS::ApiGateway::RestApi", "Properties": {"StageName": "Prod"}},
                "ApiResource": {"Properties": {"PathPart": "{proxy+}", "RestApiId": "TestApi"}},
                "ApiMethod": {
                    "Type": "AWS::ApiGateway::Method",
                    "Properties": {"HttpMethod": "POST", "RestApiId": "TestApi", "ResourceId": "ApiResource"},
                },
            }
        }

        provider = ApiProvider(template)

        self.assertEqual(provider.routes, [Route(function_name=None, path="/{proxy+}", methods=["POST"])])
Example #28
0
    def test_with_any_method(self):
        function_name = "myfunction"
        swagger = {
            "paths": {
                "/path1": {
                    "x-amazon-apigateway-any-method": {
                        "x-amazon-apigateway-integration": {"type": "aws_proxy", "uri": "someuri"}
                    }
                }
            }
        }

        parser = SwaggerParser(self.stack_path, swagger)
        parser._get_integration_function_name = Mock()
        parser._get_integration_function_name.return_value = function_name

        expected = [Route(methods=["ANY"], path="/path1", function_name=function_name, stack_path=self.stack_path)]
        result = parser.get_routes()

        self.assertEqual(expected, result)
Example #29
0
    def _make_routing_list(api_provider):
        """
        Returns a list of routes to configure the Local API Service based on the APIs configured in the template.

        Parameters
        ----------
        api_provider : samcli.commands.local.lib.sam_api_provider.SamApiProvider

        Returns
        -------
        list(samcli.local.apigw.service.Route)
            List of Routes to pass to the service
        """

        routes = []
        for api in api_provider.get_all():
            route = Route(methods=[api.method], function_name=api.function_name, path=api.path,
                          binary_types=api.binary_media_types)
            routes.append(route)

        return routes
    def dedupe_function_routes(routes):
        """
        Remove duplicate routes that have the same function_name and method

        route: list(Route)
            List of Routes

       Return
       -------
       A list of routes without duplicate routes with the same function_name and method
        """
        grouped_routes = {}

        for route in routes:
            key = "{}-{}".format(route.function_name, route.path)
            config = grouped_routes.get(key, None)
            methods = route.methods
            if config:
                methods += config.methods
            sorted_methods = sorted(methods)
            grouped_routes[key] = Route(function_name=route.function_name,
                                        path=route.path,
                                        methods=sorted_methods)
        return list(grouped_routes.values())