Skip to content
This repository has been archived by the owner on Aug 8, 2018. It is now read-only.

“Invalid mapping expression specified” when specifying an integration response header #121

Open
aviflax opened this issue Dec 9, 2015 · 19 comments

Comments

@aviflax
Copy link

aviflax commented Dec 9, 2015

I’m using RAML. When I specify an integration response header in my config JSON file, like so:

"^401.*": {
    "statusCode": "401",
    "responseParameters": {
        "method.response.header.WWW-Authenticate": "'realm=\"Pegged Web API\"'"
    },
    "responseTemplates": { "application/json": "{\"message\": $input.json('$.errorMessage')}" }
}

I get this error when running the importer:

2015-12-09 18:19:22,638 INFO - Creating integration with type AWS
2015-12-09 18:19:22,923 ERROR - Error creating API, rolling back
com.amazonaws.services.apigateway.model.BadRequestException: Invalid mapping expression specified: Validation Result: warnings : [], errors : [No method response exists for method.] (Service: null; Status Code: 400; Error Code: null; Request ID: 48738c76-9ecb-11e5-a89f-69a422b3b5fa)
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1275)
    at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:873)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:576)
    at com.amazonaws.http.AmazonHttpClient.doExecute(AmazonHttpClient.java:362)
    at com.amazonaws.http.AmazonHttpClient.executeWithTimer(AmazonHttpClient.java:328)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:307)
    at com.amazonaws.hal.client.HalClient.invoke(HalClient.java:235)
    at com.amazonaws.hal.client.HalClient.putResource(HalClient.java:122)
    at com.amazonaws.hal.client.HalResourceInvocationHandler.invoke(HalResourceInvocationHandler.java:125)
    at com.sun.proxy.$Proxy32.putIntegrationResponse(Unknown Source)
    at com.amazonaws.service.apigateway.importer.impl.sdk.ApiGatewaySdkRamlApiImporter.createIntegrationResponses(ApiGatewaySdkRamlApiImporter.java:332)
    at com.amazonaws.service.apigateway.importer.impl.sdk.ApiGatewaySdkRamlApiImporter.createIntegration(ApiGatewaySdkRamlApiImporter.java:305)
    at com.amazonaws.service.apigateway.importer.impl.sdk.ApiGatewaySdkRamlApiImporter.createMethod(ApiGatewaySdkRamlApiImporter.java:256)
    at com.amazonaws.service.apigateway.importer.impl.sdk.ApiGatewaySdkRamlApiImporter.createMethods(ApiGatewaySdkRamlApiImporter.java:180)
    at com.amazonaws.service.apigateway.importer.impl.sdk.ApiGatewaySdkRamlApiImporter.createResources(ApiGatewaySdkRamlApiImporter.java:149)
    at com.amazonaws.service.apigateway.importer.impl.sdk.ApiGatewaySdkRamlApiImporter.createApi(ApiGatewaySdkRamlApiImporter.java:83)
    at com.amazonaws.service.apigateway.importer.impl.ApiGatewayRamlFileImporter.importApi(ApiGatewayRamlFileImporter.java:49)
    at com.amazonaws.service.apigateway.importer.ApiImporterMain.importRaml(ApiImporterMain.java:171)
    at com.amazonaws.service.apigateway.importer.ApiImporterMain.execute(ApiImporterMain.java:141)
    at com.amazonaws.service.apigateway.importer.ApiImporterMain.main(ApiImporterMain.java:83)

I’ve confirmed that if I remove responseParameters from the object above, the importer runs successfully with no errors.

I’m confused as to what’s going on here; whether I’m doing something wrong or what… because when I specify such a response header manually in the console, it succeeds just fine. And the result of doing so manually:

$ aws apigateway get-integration --rest-api-id 59r3v8xeoh --resource-id yvazbs --http-method GET
{
    "integrationResponses": {
        "200": {
            "responseTemplates": {
                "application/json": "$input.json('$.body')\n"
            }, 
            "selectionPattern": "^$", 
            "statusCode": "200"
        }, 
        "401": {
            "responseParameters": {
                "method.response.header.WWW-Authenticate": "'realm=\"Pegged Web API\"'"
            }, 
            "selectionPattern": "^401.*", 
            "responseTemplates": {
                "application/json": "{\"message\": $input.json('$.errorMessage')}"
            }, 
            "statusCode": "401"
        }
    },
...

as you can see, the responseParameters property is identical… so I’m just confused!

Any help would be greatly appreciated!

Thanks,
Avi

@spencerfdavis
Copy link

👍 - Getting the same issue.

@rpgreen
Copy link
Contributor

rpgreen commented Dec 10, 2015

The error message "No method response exists for method" usually means that you don't have a method response defined matching the status code (in this case 401).

Here's an example: https://github.com/awslabs/aws-apigateway-importer/blob/master/tst/resources/raml/apigateway.raml#L205

If you're still having issues send along your raml file and I'll take a look

@aviflax
Copy link
Author

aviflax commented Dec 10, 2015

The error message "No method response exists for method" usually means that you don't have a method response defined matching the status code (in this case 401).

Yup, I get that, but I don’t think that’s what’s going on here. When I remove the responseParameters property from the 401 integration response in the JSON file, the 401 integration response is successfully created. So it seems I have properly specified the 401 response in my RAML. There seems to be something specifically about my responseParameters values that the importer doesn’t like, or is mishandling. I’m not sure what, because I can successfully set the same values via the console.

@rpgreen
Copy link
Contributor

rpgreen commented Dec 10, 2015

Can you send a sample swagger file so that we can reproduce the issue?

@aviflax
Copy link
Author

aviflax commented Dec 14, 2015

I can send it by email… if would that be acceptable, please shoot me a short note at [email protected] and I’ll supply it. Thanks!

@jackrk
Copy link
Contributor

jackrk commented Dec 15, 2015

Hi,

You do need to have headers defined in your method response before they are defined in the integration response. Could that be the case here?

Was the CLI command you ran was on the same resource/method or a different one that you created?

I'm wondering if the error message is wrong since you're saying that removing the responseParameters field fixes the issue.

Jack

@aviflax
Copy link
Author

aviflax commented Dec 29, 2015

You do need to have headers defined in your method response before they are defined in the integration response. Could that be the case here?

No, they’re defined properly in my RAML file.

Was the CLI command you ran was on the same resource/method or a different one that you created?

I guess you’re referring to the case wherein I was able to successfully add this response parameter mapping manually — but in this case I used the console, not the CLI.

I'm wondering if the error message is wrong since you're saying that removing the responseParameters field fixes the issue.

Seems plausible, I don’t know.

@kahouieong
Copy link

@aviflax
I apologize that you still have this issue. We found a bug in the RAML Importer which highlighted in code (https://github.com/awslabs/aws-apigateway-importer/blob/master/src/com/amazonaws/service/apigateway/importer/impl/sdk/ApiGatewaySdkRamlApiImporter.java#L256). It should create method response before creating the integration responses which is associated to the method response. We will prioritize to fix this issue.

We appreciate that you are reporting this bug.

@aviflax
Copy link
Author

aviflax commented Dec 30, 2015

@kaieongataws ah, I’m glad you figured it out! Thank you!

@rpgreen
Copy link
Contributor

rpgreen commented Dec 31, 2015

@blakeembrey can you have a look? @kaieongataws is correct in that the method responses should be created before the integration response. I'm not sure if this is a new regression.

Also I noticed that API key support is not implemented for RAML

@blakeembrey
Copy link
Contributor

can you have a look?

Seems correct to me, it's likely I wrote this out of order and didn't know that limitation - is it as easy as switching the order or is it more involved than I suspect?

Also I noticed that API key support is not implemented for RAML

There isn't a way in RAML 0.8 to specify API key support, it only describes custom scheme types using x- (https://github.com/raml-org/raml-spec/blob/master/raml-0.8.md#type-1). Since x-{other} could technically describe anything, I omitted it - if it's needed I could co-opt a specific name and use the first describedBy header parameter for API key support. I believe RAML 1.0 can work around this with the "Pass Through" type, which provides a runtime guarantee that the property is actually passed through as described (such as "API key"). Maybe that's overcomplicated, so let me know if I confused anyone else.

@doapp-ryanp
Copy link

I am getting the same issue, using swagger.json file. Full file below. I even get the error if I use exact responses object in the README.md, so there must be a regression bug someplace.

FWIW I'm using APIG-importer because its such a PITA to set response headers in the UI, so this is a blocker for me.

{
  "swagger": "2.0",
  "info": {
    "title": "MY Customer API",
    "description": "Allow clients to access a subset of our APIs",
    "version": "1.0.0"
  },
  "host": "ws.myhost.com",
  "schemes": [
    "https"
  ],
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "security": [
    {
      "api_key": []
    }
  ],
  "securityDefinitions": {
    "api_key": {
      "type": "apiKey",
      "name": "x-api-key",
      "in": "header"
    }
  },
  "paths": {
    "/apps/1/get-apps": {
      "get": {
        "summary": "Get a list of your company’s apps",
        "description": "Get a list of your company’s apps",
        "tags": [
          "my-apps"
        ],
        "responses": {
          "400": {
            "description": "Error",
            "schema": {
              "$ref": "#/definitions/Error"
            }
          },
          "500": {
            "description": "Execution Error",
            "schema": {
              "$ref": "#/definitions/Error"
            }
          }
        },
        "security": [
          {
            "api_key": []
          }
        ],
        "x-amazon-apigateway-auth": {
          "type": "none"
        },
        "x-amazon-apigateway-integration": {
          "type": "http",
          "uri": "https://${stageVariables.WsDomain}/apps/1/test",
          "httpMethod": "GET",
          "requestParameters": {
            "integration.request.header.ex-1": "stageVariables.ex1",
            "integration.request.header.ex2": "stageVariables.ex2"
          },
          "responses": {
            "2\\d{2}": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Cache-Control": "integration.response.header.Cache-Control"
              }
            },
            "default": {
              "statusCode": "400"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "Error": {
      "properties": {
        "error": {
          "type": "string"
        },
        "code": {
          "type": "integer",
          "format": "int32"
        },
        "server": {
          "type": "string"
        }
      }
    }
  }
}

@rpgreen
Copy link
Contributor

rpgreen commented Feb 8, 2016

@doapp-ryanp Same error message but different root cause.

You're missing the referenced 200 response and the definition for the Cache-Control response header.

You'll want to add something like this to the operation responses:

                    "200" : {
                        "headers" : {
                            "Cache-Control" : {
                                "type" : "string"
                            }
                        }
                    }

@doapp-ryanp
Copy link

@rpgreen thanks for the quick response. That did indeed fix my issue.

@clonq
Copy link

clonq commented Mar 27, 2016

any updates on this, was it fixed by any chance?

@rpgreen
Copy link
Contributor

rpgreen commented Apr 6, 2016

Swagger/OpenAPI import is now generally available in the API Gateway REST API, the AWS CLI and all AWS SDKs. You can also import and export Swagger definitions using the API Gateway console. This release addresses many of the open issues and feedback in this repository.

I would encourage you to migrate your workflow to the standard AWS tools. aws-apigateway-importer will receive minimal support from the API Gateway team going forward.

Any feedback or issues with the new importer should be directed to the official API Gateway forums.

Thanks,
Ryan

@rpgreen rpgreen closed this as completed Apr 6, 2016
@clonq
Copy link

clonq commented Apr 11, 2016

Thanks Ryan - this was about RAML though...

@aviflax
Copy link
Author

aviflax commented Apr 12, 2016

Now that Swagger has been officially “blessed” by and fully integrated into API Gateway, it would seem clear that RAML is just not a high priority for the team. Next time I work on an API Gateway project I’ll probably just use Swagger, even though I prefer RAML’s semantics.

@rpgreen rpgreen reopened this Apr 12, 2016
@rpgreen
Copy link
Contributor

rpgreen commented Apr 12, 2016

Apologies - I've reopened this issue. To be clear, we still want to support RAML, it just hasn't made it into the service yet. If there is enough demand for RAML support we will certainly prioritize.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants