Tries to resolve an Integration URI which contains Fn::Sub intrinsic function. This method tries to resolve
        and produce a string output.

        Example:
        {
          "Fn::Sub":
            "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
        }

        Fn::Sub Processing:
        ~~~~~~~~~~~~~~~~~~

        If this is a Fn::Sub, resolve as following:
            1. Get the ARN String:
                - If Sub is using the array syntax, then use element which is a string.
                - If Sub is using string syntax, then just use the string.
            2. If there is a ${XXX.Arn} then replace it with a dummy ARN
            3. Otherwise skip it

        .. code:
            Input:
            {
              "Fn::Sub":
                "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
            }

            Output: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:LambdaFunction/invocations"  # NOQA

        Note
        ~~~~
        This method supports only a very restricted subset of intrinsic functions with Swagger document. This is the
        best we can do without implementing a full blown intrinsic function resolution module.

        Parameters
        ----------
        uri_data : string or dict
            Value of Integration URI. It can either be a string or an intrinsic function that resolves to a string

        Returns
        -------
        string
            Integration URI as a string, if we were able to resolve the Sub intrinsic
        dict
            Input data is returned unmodified if we are unable to resolve the intrinsic

def _resolve_fn_sub(uri_data):
        """
        Tries to resolve an Integration URI which contains Fn::Sub intrinsic function. This method tries to resolve
        and produce a string output.

        Example:
        {
          "Fn::Sub":
            "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
        }

        Fn::Sub Processing:
        ~~~~~~~~~~~~~~~~~~

        If this is a Fn::Sub, resolve as following:
            1. Get the ARN String:
                - If Sub is using the array syntax, then use element which is a string.
                - If Sub is using string syntax, then just use the string.
            2. If there is a ${XXX.Arn} then replace it with a dummy ARN
            3. Otherwise skip it

        .. code:
            Input:
            {
              "Fn::Sub":
                "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
            }

            Output: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:LambdaFunction/invocations"  # NOQA

        Note
        ~~~~
        This method supports only a very restricted subset of intrinsic functions with Swagger document. This is the
        best we can do without implementing a full blown intrinsic function resolution module.

        Parameters
        ----------
        uri_data : string or dict
            Value of Integration URI. It can either be a string or an intrinsic function that resolves to a string

        Returns
        -------
        string
            Integration URI as a string, if we were able to resolve the Sub intrinsic
        dict
            Input data is returned unmodified if we are unable to resolve the intrinsic
        """

        # Try the short form of Fn::Sub syntax where the value is the ARN
        arn = uri_data[LambdaUri._FN_SUB]

        if isinstance(arn, list):
            # This is the long form of Fn::Sub syntax
            #
            # {
            #   "Fn::Sub":[ "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyARn}/invocations",
            #               {"MyARn": {"Ref": MyFunction"}
            #             ]
            # }
            #
            # Get the ARN out of the list
            arn = arn[0]

        if not isinstance(arn, string_types):
            # Even after all the processing, ARN is still not a string. Probably customer provided wrong syntax
            # for Fn::Sub. Let's skip this altogether
            LOG.debug("Unable to resolve Fn::Sub value for integration URI: %s", uri_data)
            return uri_data

        # Now finally we got the ARN string. Let us try to resolve it.
        # We only support value of type ${XXX.Arn} or ${YYY.Alias}. The `.Alias` syntax is a SAM specific intrinsic
        # to get ARN of Lambda Alias when using DeploymentPreference
        lambda_function_arn_template = r'arn:aws:lambda:${AWS::Region}:123456789012:function:\1'

        return re.sub(LambdaUri._REGEX_SUB_FUNCTION_ARN,  # Find all ${blah} patterns
                      # Replace with Lambda Function ARN, where function name is from pattern
                      lambda_function_arn_template,
                      arn)