|
1 | 1 | import json
|
2 | 2 | import re
|
| 3 | +import textwrap |
3 | 4 |
|
4 | 5 | import pytest
|
5 | 6 | import requests
|
@@ -350,3 +351,144 @@ def get_sqs_message():
|
350 | 351 | message = retry(get_sqs_message, sleep=2, retries=10)
|
351 | 352 | snapshot.match("sqs-message-body", message["Body"])
|
352 | 353 | snapshot.match("sqs-message-attributes", message["MessageAttributes"])
|
| 354 | + |
| 355 | + |
| 356 | +@markers.aws.validated |
| 357 | +@markers.snapshot.skip_snapshot_verify( |
| 358 | + paths=[ |
| 359 | + # FIXME: those are minor parity gap in how we handle printing out VTL Map when they are nested inside bigger maps |
| 360 | + "$..context.identity", |
| 361 | + "$..context.requestOverride", |
| 362 | + "$..context.responseOverride", |
| 363 | + "$..requestOverride.header", |
| 364 | + "$..requestOverride.path", |
| 365 | + "$..requestOverride.querystring", |
| 366 | + "$..responseOverride.header", |
| 367 | + "$..responseOverride.path", |
| 368 | + "$..responseOverride.status", |
| 369 | + ] |
| 370 | +) |
| 371 | +def test_sqs_amz_json_protocol( |
| 372 | + create_rest_apigw, |
| 373 | + sqs_create_queue, |
| 374 | + aws_client, |
| 375 | + create_role_with_policy, |
| 376 | + region_name, |
| 377 | + account_id, |
| 378 | + snapshot, |
| 379 | + sqs_collect_messages, |
| 380 | +): |
| 381 | + snapshot.add_transformer(snapshot.transform.sqs_api()) |
| 382 | + snapshot.add_transformers_list( |
| 383 | + [ |
| 384 | + snapshot.transform.key_value("MD5OfBody"), |
| 385 | + snapshot.transform.key_value("resourceId"), |
| 386 | + snapshot.transform.key_value("extendedRequestId"), |
| 387 | + snapshot.transform.key_value("requestTime"), |
| 388 | + snapshot.transform.key_value("requestTimeEpoch", reference_replacement=False), |
| 389 | + snapshot.transform.key_value("domainName"), |
| 390 | + snapshot.transform.key_value("deploymentId"), |
| 391 | + snapshot.transform.key_value("apiId"), |
| 392 | + snapshot.transform.key_value("sourceIp"), |
| 393 | + ] |
| 394 | + ) |
| 395 | + |
| 396 | + # create target SQS stream |
| 397 | + queue_name = f"queue-{short_uid()}" |
| 398 | + queue_url = sqs_create_queue(QueueName=queue_name) |
| 399 | + |
| 400 | + # create invocation role |
| 401 | + _, role_arn = create_role_with_policy( |
| 402 | + "Allow", "sqs:SendMessage", json.dumps(APIGATEWAY_ASSUME_ROLE_POLICY), "*" |
| 403 | + ) |
| 404 | + |
| 405 | + api_id, _, root = create_rest_apigw( |
| 406 | + name=f"test-api-{short_uid()}", |
| 407 | + description="Test Integration with SQS", |
| 408 | + ) |
| 409 | + |
| 410 | + resource_id = aws_client.apigateway.create_resource( |
| 411 | + restApiId=api_id, |
| 412 | + parentId=root, |
| 413 | + pathPart="sqs", |
| 414 | + )["id"] |
| 415 | + |
| 416 | + aws_client.apigateway.put_method( |
| 417 | + restApiId=api_id, |
| 418 | + resourceId=resource_id, |
| 419 | + httpMethod="POST", |
| 420 | + authorizationType="NONE", |
| 421 | + ) |
| 422 | + |
| 423 | + # we need to inline the JSON object because VTL does not handle newlines very well :/ |
| 424 | + context_template = textwrap.dedent(f""" |
| 425 | + {{ |
| 426 | + "QueueUrl": "{queue_url}", |
| 427 | + "MessageBody": "{{\\"context\\": {{#foreach( $key in $context.keySet() )\\"$key\\": \\"$context.get($key)\\"#if($foreach.hasNext),#end#end}},\\"identity\\": {{#foreach( $key in $context.identity.keySet() )\\"$key\\": \\"$context.identity.get($key)\\"#if($foreach.hasNext),#end#end}},\\"requestOverride\\": {{#foreach( $key in $context.requestOverride.keySet() )\\"$key\\": \\"$context.requestOverride.get($key)\\"#if($foreach.hasNext),#end#end}},\\"responseOverride\\": {{#foreach( $key in $context.responseOverride.keySet() )\\"$key\\": \\"$context.responseOverride.get($key)\\"#if($foreach.hasNext),#end#end}},\\"authorizer_keys\\": {{#foreach( $key in $context.authorizer.keySet() )\\"$key\\": \\"$util.escapeJavaScript($context.authorizer.get($key))\\"#if($foreach.hasNext),#end#end}}}}"}} |
| 428 | + """) |
| 429 | + |
| 430 | + aws_client.apigateway.put_integration( |
| 431 | + restApiId=api_id, |
| 432 | + resourceId=resource_id, |
| 433 | + httpMethod="POST", |
| 434 | + type="AWS", |
| 435 | + integrationHttpMethod="POST", |
| 436 | + uri=f"arn:aws:apigateway:{region_name}:sqs:path/{account_id}/{queue_name}", |
| 437 | + credentials=role_arn, |
| 438 | + requestParameters={ |
| 439 | + "integration.request.header.Content-Type": "'application/x-amz-json-1.0'", |
| 440 | + "integration.request.header.X-Amz-Target": "'AmazonSQS.SendMessage'", |
| 441 | + }, |
| 442 | + requestTemplates={"application/json": context_template}, |
| 443 | + passthroughBehavior="NEVER", |
| 444 | + ) |
| 445 | + |
| 446 | + aws_client.apigateway.put_method_response( |
| 447 | + restApiId=api_id, |
| 448 | + resourceId=resource_id, |
| 449 | + httpMethod="POST", |
| 450 | + statusCode="200", |
| 451 | + responseModels={"application/json": "Empty"}, |
| 452 | + ) |
| 453 | + aws_client.apigateway.put_method_response( |
| 454 | + restApiId=api_id, |
| 455 | + resourceId=resource_id, |
| 456 | + httpMethod="POST", |
| 457 | + statusCode="400", |
| 458 | + responseModels={"application/json": "Empty"}, |
| 459 | + ) |
| 460 | + |
| 461 | + aws_client.apigateway.put_integration_response( |
| 462 | + restApiId=api_id, |
| 463 | + resourceId=resource_id, |
| 464 | + httpMethod="POST", |
| 465 | + statusCode="200", |
| 466 | + responseTemplates={"application/json": '{"message": "great success!"}'}, |
| 467 | + ) |
| 468 | + |
| 469 | + aws_client.apigateway.put_integration_response( |
| 470 | + restApiId=api_id, |
| 471 | + resourceId=resource_id, |
| 472 | + httpMethod="POST", |
| 473 | + statusCode="400", |
| 474 | + responseTemplates={"application/json": '{"message": "failure :("}'}, |
| 475 | + selectionPattern="400", |
| 476 | + ) |
| 477 | + |
| 478 | + aws_client.apigateway.create_deployment(restApiId=api_id, stageName=TEST_STAGE_NAME) |
| 479 | + |
| 480 | + invocation_url = api_invoke_url(api_id=api_id, stage=TEST_STAGE_NAME, path="/sqs") |
| 481 | + |
| 482 | + def invoke_api(url): |
| 483 | + _response = requests.post(url, headers={"User-Agent": "python/requests/tests"}) |
| 484 | + assert _response.ok |
| 485 | + content = _response.json() |
| 486 | + assert content == {"message": "great success!"} |
| 487 | + return content |
| 488 | + |
| 489 | + retry(invoke_api, sleep=2, retries=10, url=invocation_url) |
| 490 | + |
| 491 | + messages = sqs_collect_messages( |
| 492 | + queue_url=queue_url, expected=1, timeout=10, wait_time_seconds=5 |
| 493 | + ) |
| 494 | + snapshot.match("sqs-messages", messages) |
0 commit comments