localstack-core 4.6.1.dev60__py3-none-any.whl → 4.10.1.dev12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- localstack/aws/api/apigateway/__init__.py +87 -110
- localstack/aws/api/cloudformation/__init__.py +18 -4
- localstack/aws/api/cloudwatch/__init__.py +41 -1
- localstack/aws/api/config/__init__.py +4 -0
- localstack/aws/api/core.py +8 -5
- localstack/aws/api/dynamodb/__init__.py +30 -0
- localstack/aws/api/ec2/__init__.py +1545 -66
- localstack/aws/api/events/__init__.py +12 -16
- localstack/aws/api/iam/__init__.py +7 -0
- localstack/aws/api/kinesis/__init__.py +19 -0
- localstack/aws/api/kms/__init__.py +6 -0
- localstack/aws/api/lambda_/__init__.py +36 -23
- localstack/aws/api/logs/__init__.py +20 -8
- localstack/aws/api/opensearch/__init__.py +16 -0
- localstack/aws/api/pipes/__init__.py +24 -32
- localstack/aws/api/redshift/__init__.py +9 -3
- localstack/aws/api/route53/__init__.py +5 -0
- localstack/aws/api/s3/__init__.py +12 -0
- localstack/aws/api/s3control/__init__.py +56 -0
- localstack/aws/api/scheduler/__init__.py +14 -16
- localstack/aws/api/ssm/__init__.py +2 -0
- localstack/aws/api/stepfunctions/__init__.py +88 -114
- localstack/aws/api/support/__init__.py +8 -9
- localstack/aws/api/transcribe/__init__.py +17 -0
- localstack/aws/chain.py +2 -2
- localstack/aws/client.py +14 -11
- localstack/aws/connect.py +42 -41
- localstack/aws/forwarder.py +57 -9
- localstack/aws/gateway.py +1 -3
- localstack/aws/handlers/analytics.py +2 -3
- localstack/aws/handlers/cors.py +4 -5
- localstack/aws/handlers/internal_requests.py +6 -1
- localstack/aws/handlers/logging.py +13 -4
- localstack/aws/handlers/metric_handler.py +44 -5
- localstack/aws/handlers/service.py +48 -28
- localstack/aws/mocking.py +18 -27
- localstack/aws/patches.py +2 -2
- localstack/aws/protocol/op_router.py +11 -10
- localstack/aws/protocol/parser.py +475 -49
- localstack/aws/protocol/serializer.py +723 -106
- localstack/aws/protocol/service_router.py +133 -33
- localstack/aws/protocol/validate.py +6 -6
- localstack/aws/scaffold.py +9 -10
- localstack/aws/serving/edge.py +5 -6
- localstack/aws/serving/hypercorn.py +2 -2
- localstack/aws/serving/twisted.py +1 -2
- localstack/aws/serving/werkzeug.py +2 -2
- localstack/aws/skeleton.py +12 -11
- localstack/aws/spec-patches.json +58 -0
- localstack/aws/spec.py +66 -46
- localstack/cli/exceptions.py +1 -1
- localstack/cli/localstack.py +11 -11
- localstack/cli/lpm.py +4 -5
- localstack/cli/plugins.py +1 -1
- localstack/cli/profiles.py +1 -2
- localstack/config.py +44 -30
- localstack/constants.py +4 -29
- localstack/deprecations.py +5 -5
- localstack/dev/kubernetes/__main__.py +130 -7
- localstack/dev/run/__main__.py +5 -5
- localstack/dev/run/configurators.py +1 -4
- localstack/dev/run/paths.py +6 -6
- localstack/dns/models.py +2 -1
- localstack/dns/plugins.py +5 -1
- localstack/dns/server.py +16 -6
- localstack/http/dispatcher.py +1 -2
- localstack/http/response.py +2 -2
- localstack/http/router.py +1 -1
- localstack/http/trace.py +2 -1
- localstack/logging/format.py +6 -6
- localstack/packages/api.py +13 -12
- localstack/packages/core.py +4 -4
- localstack/packages/debugpy.py +1 -3
- localstack/packages/ffmpeg.py +1 -2
- localstack/packages/java.py +38 -12
- localstack/packages/plugins.py +0 -8
- localstack/runtime/analytics.py +3 -0
- localstack/runtime/hooks.py +1 -1
- localstack/runtime/init.py +8 -9
- localstack/runtime/main.py +5 -5
- localstack/runtime/patches.py +2 -2
- localstack/runtime/shutdown.py +2 -1
- localstack/services/apigateway/exporter.py +1 -2
- localstack/services/apigateway/helpers.py +7 -10
- localstack/services/apigateway/legacy/context.py +21 -21
- localstack/services/apigateway/legacy/helpers.py +27 -28
- localstack/services/apigateway/legacy/integration.py +11 -10
- localstack/services/apigateway/legacy/invocations.py +6 -5
- localstack/services/apigateway/legacy/provider.py +148 -68
- localstack/services/apigateway/legacy/router_asf.py +2 -2
- localstack/services/apigateway/legacy/templates.py +6 -6
- localstack/services/apigateway/models.py +16 -16
- localstack/services/apigateway/next_gen/execute_api/api.py +2 -2
- localstack/services/apigateway/next_gen/execute_api/context.py +25 -25
- localstack/services/apigateway/next_gen/execute_api/handlers/api_key_validation.py +2 -5
- localstack/services/apigateway/next_gen/execute_api/handlers/method_request.py +7 -2
- localstack/services/apigateway/next_gen/execute_api/handlers/parse.py +1 -2
- localstack/services/apigateway/next_gen/execute_api/handlers/resource_router.py +2 -3
- localstack/services/apigateway/next_gen/execute_api/header_utils.py +1 -1
- localstack/services/apigateway/next_gen/execute_api/helpers.py +2 -2
- localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +9 -6
- localstack/services/apigateway/next_gen/execute_api/integrations/http.py +12 -12
- localstack/services/apigateway/next_gen/execute_api/router.py +31 -0
- localstack/services/apigateway/next_gen/execute_api/template_mapping.py +2 -2
- localstack/services/apigateway/next_gen/execute_api/test_invoke.py +114 -9
- localstack/services/apigateway/next_gen/execute_api/variables.py +63 -63
- localstack/services/apigateway/next_gen/provider.py +5 -0
- localstack/services/apigateway/resource_providers/aws_apigateway_account.py +3 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_account_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_apikey.py +14 -14
- localstack/services/apigateway/resource_providers/aws_apigateway_apikey_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping.py +5 -5
- localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_deployment.py +46 -46
- localstack/services/apigateway/resource_providers/aws_apigateway_deployment_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_domainname.py +18 -18
- localstack/services/apigateway/resource_providers/aws_apigateway_domainname_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse.py +7 -7
- localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_method.py +36 -36
- localstack/services/apigateway/resource_providers/aws_apigateway_method_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_model.py +6 -6
- localstack/services/apigateway/resource_providers/aws_apigateway_model_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator.py +6 -6
- localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_resource.py +6 -6
- localstack/services/apigateway/resource_providers/aws_apigateway_resource_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_restapi.py +26 -26
- localstack/services/apigateway/resource_providers/aws_apigateway_restapi_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_stage.py +33 -33
- localstack/services/apigateway/resource_providers/aws_apigateway_stage_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_usageplan.py +18 -18
- localstack/services/apigateway/resource_providers/aws_apigateway_usageplan_plugin.py +1 -3
- localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey.py +5 -5
- localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey_plugin.py +1 -3
- localstack/services/cdk/resource_providers/cdk_metadata.py +4 -3
- localstack/services/cdk/resource_providers/cdk_metadata_plugin.py +1 -3
- localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate.py +14 -14
- localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate_plugin.py +1 -3
- localstack/services/cloudformation/api_utils.py +4 -8
- localstack/services/cloudformation/cfn_utils.py +2 -2
- localstack/services/cloudformation/deployment_utils.py +14 -12
- localstack/services/cloudformation/engine/changes.py +3 -3
- localstack/services/cloudformation/engine/entities.py +27 -17
- localstack/services/cloudformation/engine/parameters.py +4 -4
- localstack/services/cloudformation/engine/template_deployer.py +15 -14
- localstack/services/cloudformation/engine/template_utils.py +34 -12
- localstack/services/cloudformation/engine/transformers.py +11 -8
- localstack/services/cloudformation/engine/types.py +5 -4
- localstack/services/cloudformation/engine/v2/change_set_model.py +336 -39
- localstack/services/cloudformation/engine/v2/change_set_model_describer.py +96 -17
- localstack/services/cloudformation/engine/v2/change_set_model_executor.py +289 -136
- localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +315 -146
- localstack/services/cloudformation/engine/v2/change_set_model_transform.py +380 -105
- localstack/services/cloudformation/engine/v2/change_set_model_validator.py +183 -0
- localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +6 -0
- localstack/services/cloudformation/engine/v2/resolving.py +102 -0
- localstack/services/cloudformation/engine/yaml_parser.py +9 -2
- localstack/services/cloudformation/provider.py +11 -6
- localstack/services/cloudformation/provider_utils.py +34 -4
- localstack/services/cloudformation/resource_provider.py +31 -21
- localstack/services/cloudformation/resource_providers/aws_cloudformation_macro.py +7 -7
- localstack/services/cloudformation/resource_providers/aws_cloudformation_macro_plugin.py +1 -3
- localstack/services/cloudformation/resource_providers/aws_cloudformation_stack.py +9 -9
- localstack/services/cloudformation/resource_providers/aws_cloudformation_stack_plugin.py +1 -3
- localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition.py +6 -6
- localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition_plugin.py +1 -3
- localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle.py +2 -2
- localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle_plugin.py +1 -3
- localstack/services/cloudformation/resources.py +24149 -0
- localstack/services/cloudformation/scaffolding/__main__.py +13 -12
- localstack/services/cloudformation/scaffolding/propgen.py +2 -2
- localstack/services/cloudformation/service_models.py +2 -2
- localstack/services/cloudformation/stores.py +33 -22
- localstack/services/cloudformation/v2/entities.py +103 -88
- localstack/services/cloudformation/v2/provider.py +872 -131
- localstack/services/cloudformation/v2/types.py +38 -0
- localstack/services/cloudformation/v2/utils.py +4 -1
- localstack/services/cloudwatch/alarm_scheduler.py +11 -8
- localstack/services/cloudwatch/cloudwatch_database_helper.py +4 -5
- localstack/services/cloudwatch/models.py +5 -7
- localstack/services/cloudwatch/provider.py +30 -25
- localstack/services/cloudwatch/provider_v2.py +27 -32
- localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.py +40 -40
- localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm_plugin.py +1 -3
- localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm.py +12 -12
- localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm_plugin.py +1 -3
- localstack/services/dynamodb/packages.py +3 -3
- localstack/services/dynamodb/provider.py +159 -18
- localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable.py +63 -63
- localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable_plugin.py +1 -3
- localstack/services/dynamodb/resource_providers/aws_dynamodb_table.py +57 -57
- localstack/services/dynamodb/resource_providers/aws_dynamodb_table_plugin.py +1 -3
- localstack/services/dynamodb/server.py +2 -2
- localstack/services/dynamodb/utils.py +13 -14
- localstack/services/dynamodb/v2/provider.py +157 -18
- localstack/services/dynamodbstreams/dynamodbstreams_api.py +2 -2
- localstack/services/dynamodbstreams/models.py +1 -3
- localstack/services/ec2/patches.py +26 -5
- localstack/services/ec2/provider.py +3 -3
- localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions.py +10 -10
- localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_instance.py +96 -96
- localstack/services/ec2/resource_providers/aws_ec2_instance_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_internetgateway.py +5 -5
- localstack/services/ec2/resource_providers/aws_ec2_internetgateway_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_keypair.py +10 -10
- localstack/services/ec2/resource_providers/aws_ec2_keypair_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_natgateway.py +13 -13
- localstack/services/ec2/resource_providers/aws_ec2_natgateway_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_networkacl.py +6 -6
- localstack/services/ec2/resource_providers/aws_ec2_networkacl_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_prefixlist.py +14 -14
- localstack/services/ec2/resource_providers/aws_ec2_prefixlist_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_route.py +15 -15
- localstack/services/ec2/resource_providers/aws_ec2_route_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_routetable.py +6 -6
- localstack/services/ec2/resource_providers/aws_ec2_routetable_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_securitygroup.py +29 -29
- localstack/services/ec2/resource_providers/aws_ec2_securitygroup_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_subnet.py +19 -19
- localstack/services/ec2/resource_providers/aws_ec2_subnet_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation.py +4 -4
- localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_transitgateway.py +16 -16
- localstack/services/ec2/resource_providers/aws_ec2_transitgateway_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment.py +9 -9
- localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_vpc.py +15 -15
- localstack/services/ec2/resource_providers/aws_ec2_vpc_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint.py +29 -22
- localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint_plugin.py +1 -3
- localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment.py +5 -5
- localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment_plugin.py +1 -3
- localstack/services/ecr/resource_providers/aws_ecr_repository.py +22 -19
- localstack/services/ecr/resource_providers/aws_ecr_repository_plugin.py +1 -3
- localstack/services/edge.py +6 -6
- localstack/services/es/provider.py +21 -21
- localstack/services/events/archive.py +2 -2
- localstack/services/events/connection.py +5 -5
- localstack/services/events/event_bus.py +9 -9
- localstack/services/events/event_rule_engine.py +31 -13
- localstack/services/events/models.py +29 -30
- localstack/services/events/provider.py +29 -26
- localstack/services/events/replay.py +3 -3
- localstack/services/events/resource_providers/aws_events_apidestination.py +8 -8
- localstack/services/events/resource_providers/aws_events_apidestination_plugin.py +1 -3
- localstack/services/events/resource_providers/aws_events_connection.py +27 -27
- localstack/services/events/resource_providers/aws_events_connection_plugin.py +1 -3
- localstack/services/events/resource_providers/aws_events_eventbus.py +9 -9
- localstack/services/events/resource_providers/aws_events_eventbus_plugin.py +1 -3
- localstack/services/events/resource_providers/aws_events_eventbuspolicy.py +11 -11
- localstack/services/events/resource_providers/aws_events_eventbuspolicy_plugin.py +1 -3
- localstack/services/events/resource_providers/aws_events_rule.py +82 -82
- localstack/services/events/resource_providers/aws_events_rule_plugin.py +1 -3
- localstack/services/events/rule.py +15 -15
- localstack/services/events/target.py +21 -13
- localstack/services/events/utils.py +7 -7
- localstack/services/events/v1/models.py +1 -3
- localstack/services/events/v1/provider.py +15 -15
- localstack/services/firehose/models.py +1 -3
- localstack/services/firehose/provider.py +25 -16
- localstack/services/iam/iam_patches.py +5 -6
- localstack/services/iam/provider.py +14 -119
- localstack/services/iam/resource_providers/aws_iam_accesskey.py +6 -6
- localstack/services/iam/resource_providers/aws_iam_accesskey_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_group.py +9 -9
- localstack/services/iam/resource_providers/aws_iam_group_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_instanceprofile.py +5 -5
- localstack/services/iam/resource_providers/aws_iam_instanceprofile_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_managedpolicy.py +9 -9
- localstack/services/iam/resource_providers/aws_iam_managedpolicy_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_policy.py +7 -7
- localstack/services/iam/resource_providers/aws_iam_policy_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_role.py +16 -16
- localstack/services/iam/resource_providers/aws_iam_role_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_servercertificate.py +10 -10
- localstack/services/iam/resource_providers/aws_iam_servercertificate_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_servicelinkedrole.py +5 -5
- localstack/services/iam/resource_providers/aws_iam_servicelinkedrole_plugin.py +1 -3
- localstack/services/iam/resource_providers/aws_iam_user.py +17 -17
- localstack/services/iam/resource_providers/aws_iam_user_plugin.py +1 -3
- localstack/services/iam/resources/policy_simulator.py +133 -0
- localstack/services/kinesis/kinesis_mock_server.py +7 -8
- localstack/services/kinesis/models.py +17 -5
- localstack/services/kinesis/packages.py +3 -3
- localstack/services/kinesis/provider.py +86 -3
- localstack/services/kinesis/resource_providers/aws_kinesis_stream.py +13 -13
- localstack/services/kinesis/resource_providers/aws_kinesis_stream_plugin.py +1 -3
- localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer.py +7 -7
- localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer_plugin.py +1 -3
- localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream.py +191 -191
- localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream_plugin.py +1 -3
- localstack/services/kms/models.py +21 -18
- localstack/services/kms/provider.py +62 -26
- localstack/services/kms/resource_providers/aws_kms_alias.py +3 -3
- localstack/services/kms/resource_providers/aws_kms_alias_plugin.py +1 -3
- localstack/services/kms/resource_providers/aws_kms_key.py +14 -14
- localstack/services/kms/resource_providers/aws_kms_key_plugin.py +1 -3
- localstack/services/kms/utils.py +4 -3
- localstack/services/lambda_/api_utils.py +19 -16
- localstack/services/lambda_/custom_endpoints.py +2 -2
- localstack/services/lambda_/event_source_mapping/esm_worker_factory.py +4 -7
- localstack/services/lambda_/event_source_mapping/pipe_utils.py +2 -2
- localstack/services/lambda_/event_source_mapping/pollers/stream_poller.py +1 -1
- localstack/services/lambda_/event_source_mapping/senders/sender_utils.py +2 -1
- localstack/services/lambda_/hooks.py +6 -1
- localstack/services/lambda_/invocation/assignment.py +1 -2
- localstack/services/lambda_/invocation/docker_runtime_executor.py +7 -11
- localstack/services/lambda_/invocation/event_manager.py +1 -1
- localstack/services/lambda_/invocation/execution_environment.py +4 -4
- localstack/services/lambda_/invocation/executor_endpoint.py +8 -11
- localstack/services/lambda_/invocation/internal_sqs_queue.py +6 -10
- localstack/services/lambda_/invocation/lambda_models.py +33 -30
- localstack/services/lambda_/invocation/lambda_service.py +12 -5
- localstack/services/lambda_/invocation/logs.py +2 -3
- localstack/services/lambda_/invocation/runtime_executor.py +3 -3
- localstack/services/lambda_/invocation/version_manager.py +31 -8
- localstack/services/lambda_/ldm.py +14 -0
- localstack/services/lambda_/packages.py +3 -4
- localstack/services/lambda_/provider.py +9 -26
- localstack/services/lambda_/provider_utils.py +1 -1
- localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig.py +8 -8
- localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig.py +11 -11
- localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping.py +39 -39
- localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_function.py +54 -54
- localstack/services/lambda_/resource_providers/aws_lambda_function_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_layerversion.py +11 -11
- localstack/services/lambda_/resource_providers/aws_lambda_layerversion_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission.py +6 -6
- localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_permission.py +10 -10
- localstack/services/lambda_/resource_providers/aws_lambda_permission_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_url.py +15 -15
- localstack/services/lambda_/resource_providers/aws_lambda_url_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/aws_lambda_version.py +8 -8
- localstack/services/lambda_/resource_providers/aws_lambda_version_plugin.py +1 -3
- localstack/services/lambda_/resource_providers/lambda_alias.py +12 -12
- localstack/services/lambda_/resource_providers/lambda_alias_plugin.py +1 -3
- localstack/services/lambda_/runtimes.py +1 -3
- localstack/services/lambda_/urlrouter.py +14 -1
- localstack/services/logs/models.py +1 -3
- localstack/services/logs/provider.py +39 -22
- localstack/services/logs/resource_providers/aws_logs_loggroup.py +9 -9
- localstack/services/logs/resource_providers/aws_logs_loggroup_plugin.py +1 -3
- localstack/services/logs/resource_providers/aws_logs_logstream.py +4 -4
- localstack/services/logs/resource_providers/aws_logs_logstream_plugin.py +1 -3
- localstack/services/logs/resource_providers/aws_logs_subscriptionfilter.py +7 -7
- localstack/services/logs/resource_providers/aws_logs_subscriptionfilter_plugin.py +1 -3
- localstack/services/moto.py +5 -4
- localstack/services/opensearch/cluster.py +28 -20
- localstack/services/opensearch/cluster_manager.py +13 -14
- localstack/services/opensearch/models.py +1 -3
- localstack/services/opensearch/packages.py +27 -9
- localstack/services/opensearch/provider.py +15 -10
- localstack/services/opensearch/resource_providers/aws_elasticsearch_domain.py +61 -61
- localstack/services/opensearch/resource_providers/aws_elasticsearch_domain_plugin.py +1 -3
- localstack/services/opensearch/resource_providers/aws_opensearchservice_domain.py +89 -89
- localstack/services/opensearch/resource_providers/aws_opensearchservice_domain_plugin.py +1 -3
- localstack/services/opensearch/versions.py +57 -10
- localstack/services/plugins.py +37 -32
- localstack/services/providers.py +10 -2
- localstack/services/redshift/provider.py +0 -21
- localstack/services/redshift/resource_providers/aws_redshift_cluster.py +57 -57
- localstack/services/redshift/resource_providers/aws_redshift_cluster_plugin.py +1 -3
- localstack/services/resource_groups/resource_providers/aws_resourcegroups_group.py +21 -21
- localstack/services/resource_groups/resource_providers/aws_resourcegroups_group_plugin.py +1 -3
- localstack/services/route53/models.py +1 -3
- localstack/services/route53/provider.py +1 -2
- localstack/services/route53/resource_providers/aws_route53_healthcheck.py +6 -6
- localstack/services/route53/resource_providers/aws_route53_healthcheck_plugin.py +1 -3
- localstack/services/route53/resource_providers/aws_route53_recordset.py +27 -27
- localstack/services/route53/resource_providers/aws_route53_recordset_plugin.py +1 -3
- localstack/services/route53resolver/models.py +8 -10
- localstack/services/route53resolver/provider.py +12 -12
- localstack/services/s3/codec.py +2 -2
- localstack/services/s3/constants.py +5 -2
- localstack/services/s3/cors.py +8 -8
- localstack/services/s3/models.py +73 -73
- localstack/services/s3/notifications.py +74 -58
- localstack/services/s3/presigned_url.py +41 -59
- localstack/services/s3/provider.py +86 -29
- localstack/services/s3/resource_providers/aws_s3_bucket.py +180 -180
- localstack/services/s3/resource_providers/aws_s3_bucket_plugin.py +1 -3
- localstack/services/s3/resource_providers/aws_s3_bucketpolicy.py +4 -4
- localstack/services/s3/resource_providers/aws_s3_bucketpolicy_plugin.py +1 -3
- localstack/services/s3/storage/core.py +4 -3
- localstack/services/s3/storage/ephemeral.py +7 -6
- localstack/services/s3/utils.py +51 -31
- localstack/services/s3/validation.py +47 -33
- localstack/services/s3/website_hosting.py +9 -7
- localstack/services/scheduler/resource_providers/aws_scheduler_schedule.py +60 -60
- localstack/services/scheduler/resource_providers/aws_scheduler_schedule_plugin.py +1 -3
- localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup.py +9 -9
- localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup_plugin.py +1 -3
- localstack/services/secretsmanager/provider.py +10 -12
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy.py +5 -5
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy_plugin.py +1 -3
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule.py +21 -21
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule_plugin.py +1 -3
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret.py +23 -23
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret_plugin.py +1 -3
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment.py +5 -5
- localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment_plugin.py +1 -3
- localstack/services/ses/models.py +8 -1
- localstack/services/ses/provider.py +128 -55
- localstack/services/ses/resource_providers/aws_ses_emailidentity.py +21 -21
- localstack/services/ses/resource_providers/aws_ses_emailidentity_plugin.py +1 -3
- localstack/services/sns/constants.py +7 -1
- localstack/services/sns/executor.py +9 -2
- localstack/services/sns/models.py +25 -25
- localstack/services/sns/provider.py +9 -7
- localstack/services/sns/publisher.py +37 -23
- localstack/services/sns/resource_providers/aws_sns_subscription.py +13 -13
- localstack/services/sns/resource_providers/aws_sns_subscription_plugin.py +1 -3
- localstack/services/sns/resource_providers/aws_sns_topic.py +16 -16
- localstack/services/sns/resource_providers/aws_sns_topic_plugin.py +1 -3
- localstack/services/sns/resource_providers/aws_sns_topicpolicy.py +4 -4
- localstack/services/sns/resource_providers/aws_sns_topicpolicy_plugin.py +1 -3
- localstack/services/sns/v2/models.py +167 -0
- localstack/services/sns/v2/provider.py +867 -0
- localstack/services/sns/v2/utils.py +130 -0
- localstack/services/sqs/constants.py +2 -2
- localstack/services/sqs/developer_api.py +205 -0
- localstack/services/sqs/models.py +71 -36
- localstack/services/sqs/provider.py +56 -332
- localstack/services/sqs/query_api.py +8 -5
- localstack/services/sqs/resource_providers/aws_sqs_queue.py +21 -21
- localstack/services/sqs/resource_providers/aws_sqs_queue_plugin.py +1 -3
- localstack/services/sqs/resource_providers/aws_sqs_queuepolicy.py +7 -5
- localstack/services/sqs/resource_providers/aws_sqs_queuepolicy_plugin.py +1 -3
- localstack/services/sqs/utils.py +123 -4
- localstack/services/ssm/provider.py +3 -4
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow.py +15 -15
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow_plugin.py +1 -3
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget.py +10 -10
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget_plugin.py +1 -3
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask.py +48 -48
- localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask_plugin.py +1 -3
- localstack/services/ssm/resource_providers/aws_ssm_parameter.py +10 -10
- localstack/services/ssm/resource_providers/aws_ssm_parameter_plugin.py +1 -3
- localstack/services/ssm/resource_providers/aws_ssm_patchbaseline.py +29 -29
- localstack/services/ssm/resource_providers/aws_ssm_patchbaseline_plugin.py +1 -3
- localstack/services/stepfunctions/asl/antlt4utils/antlr4utils.py +3 -4
- localstack/services/stepfunctions/asl/component/common/assign/assign_decl.py +1 -1
- localstack/services/stepfunctions/asl/component/common/assign/assign_decl_binding.py +1 -1
- localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_array.py +1 -1
- localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_object.py +1 -1
- localstack/services/stepfunctions/asl/component/common/catch/catcher_decl.py +9 -9
- localstack/services/stepfunctions/asl/component/common/error_name/custom_error_name.py +2 -2
- localstack/services/stepfunctions/asl/component/common/error_name/error_name.py +4 -4
- localstack/services/stepfunctions/asl/component/common/error_name/failure_event.py +8 -8
- localstack/services/stepfunctions/asl/component/common/error_name/states_error_name_type.py +1 -1
- localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_binding.py +2 -2
- localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_array.py +1 -1
- localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_object.py +1 -1
- localstack/services/stepfunctions/asl/component/common/path/input_path.py +4 -4
- localstack/services/stepfunctions/asl/component/common/path/output_path.py +4 -4
- localstack/services/stepfunctions/asl/component/common/path/result_path.py +3 -3
- localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadarr/payload_arr.py +1 -1
- localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding.py +3 -3
- localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadtmpl/payload_tmpl.py +1 -1
- localstack/services/stepfunctions/asl/component/common/retry/retrier_decl.py +8 -8
- localstack/services/stepfunctions/asl/component/common/string/string_expression.py +3 -3
- localstack/services/stepfunctions/asl/component/common/timeouts/timeout.py +3 -3
- localstack/services/stepfunctions/asl/component/eval_component.py +2 -3
- localstack/services/stepfunctions/asl/component/intrinsic/argument/argument.py +4 -4
- localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/array/array_partition.py +1 -1
- localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/generic/string_format.py +1 -1
- localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_array.py +1 -1
- localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_format.py +1 -1
- localstack/services/stepfunctions/asl/component/intrinsic/jsonata.py +3 -3
- localstack/services/stepfunctions/asl/component/intrinsic/member.py +1 -1
- localstack/services/stepfunctions/asl/component/program/program.py +9 -9
- localstack/services/stepfunctions/asl/component/program/states.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state.py +10 -11
- localstack/services/stepfunctions/asl/component/state/state_choice/choice_rule.py +11 -11
- localstack/services/stepfunctions/asl/component/state/state_choice/comparison/comparison.py +5 -11
- localstack/services/stepfunctions/asl/component/state/state_choice/comparison/operator/implementations/is_operator.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_choice/state_choice.py +3 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/execute_state.py +9 -9
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/item_reader_decl.py +7 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/reader_config/reader_config_decl.py +5 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_eval_s3.py +2 -1
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_output_transformer/resource_output_transformer_csv.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/distributed_iteration_component.py +8 -8
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/inline_iteration_component.py +7 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/distributed_item_processor_worker.py +4 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/inline_item_processor_worker.py +5 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/map_run_record.py +10 -10
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_component.py +3 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_declaration.py +3 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_worker.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/distributed_iterator_worker.py +3 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator.py +1 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator_worker.py +5 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/job.py +9 -9
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/result_writer/resource_eval/resource_eval_s3.py +2 -1
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/state_map.py +12 -13
- localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branch_worker.py +3 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branches_decl.py +7 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/state_parallel.py +2 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/lambda_eval_utils.py +7 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/resource.py +3 -3
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service.py +10 -10
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_api_gateway.py +18 -18
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_aws_sdk.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_batch.py +8 -7
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_callback.py +18 -17
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_dynamodb.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_ecs.py +5 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_events.py +4 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_glue.py +7 -6
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_lambda.py +4 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sfn.py +9 -8
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sns.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sqs.py +4 -4
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task.py +5 -5
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task_lambda.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_fail/state_fail.py +3 -5
- localstack/services/stepfunctions/asl/component/state/state_pass/state_pass.py +5 -7
- localstack/services/stepfunctions/asl/component/state/state_succeed/state_succeed.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_wait/state_wait.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_wait/wait_function/timestamp.py +2 -2
- localstack/services/stepfunctions/asl/eval/callback/callback.py +18 -18
- localstack/services/stepfunctions/asl/eval/environment.py +22 -24
- localstack/services/stepfunctions/asl/eval/evaluation_details.py +3 -5
- localstack/services/stepfunctions/asl/eval/event/event_manager.py +10 -10
- localstack/services/stepfunctions/asl/eval/event/logging.py +3 -3
- localstack/services/stepfunctions/asl/eval/program_state.py +8 -8
- localstack/services/stepfunctions/asl/eval/states.py +12 -12
- localstack/services/stepfunctions/asl/eval/test_state/environment.py +3 -5
- localstack/services/stepfunctions/asl/eval/variable_store.py +6 -6
- localstack/services/stepfunctions/asl/jsonata/jsonata.py +7 -6
- localstack/services/stepfunctions/asl/parse/asl_parser.py +1 -1
- localstack/services/stepfunctions/asl/parse/intrinsic/preprocessor.py +2 -3
- localstack/services/stepfunctions/asl/parse/preprocessor.py +44 -44
- localstack/services/stepfunctions/asl/parse/typed_props.py +2 -2
- localstack/services/stepfunctions/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py +1 -1
- localstack/services/stepfunctions/asl/static_analyser/variable_references_static_analyser.py +2 -2
- localstack/services/stepfunctions/asl/utils/encoding.py +2 -2
- localstack/services/stepfunctions/asl/utils/json_path.py +2 -2
- localstack/services/stepfunctions/backend/activity.py +4 -4
- localstack/services/stepfunctions/backend/alias.py +8 -8
- localstack/services/stepfunctions/backend/execution.py +29 -30
- localstack/services/stepfunctions/backend/execution_worker.py +7 -7
- localstack/services/stepfunctions/backend/state_machine.py +28 -28
- localstack/services/stepfunctions/backend/test_state/execution.py +3 -4
- localstack/services/stepfunctions/backend/test_state/execution_worker.py +1 -3
- localstack/services/stepfunctions/mocking/mock_config.py +9 -9
- localstack/services/stepfunctions/mocking/mock_config_file.py +10 -10
- localstack/services/stepfunctions/packages.py +14 -5
- localstack/services/stepfunctions/provider.py +34 -44
- localstack/services/stepfunctions/quotas.py +2 -3
- localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity.py +6 -6
- localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity_plugin.py +1 -3
- localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py +25 -25
- localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine_plugin.py +1 -3
- localstack/services/stepfunctions/stepfunctions_utils.py +1 -2
- localstack/services/stores.py +8 -8
- localstack/services/transcribe/packages.py +1 -3
- localstack/services/transcribe/provider.py +8 -3
- localstack/state/codecs.py +61 -0
- localstack/state/core.py +11 -5
- localstack/state/inspect.py +4 -4
- localstack/state/pickle.py +36 -23
- localstack/testing/aws/asf_utils.py +3 -2
- localstack/testing/aws/cloudformation_utils.py +1 -1
- localstack/testing/aws/lambda_utils.py +15 -14
- localstack/testing/aws/util.py +3 -2
- localstack/testing/pytest/cloudformation/fixtures.py +68 -18
- localstack/testing/pytest/container.py +5 -5
- localstack/testing/pytest/filters.py +1 -3
- localstack/testing/pytest/fixtures.py +188 -49
- localstack/testing/pytest/in_memory_localstack.py +1 -3
- localstack/testing/pytest/marking.py +42 -15
- localstack/testing/pytest/path_filter.py +1 -1
- localstack/testing/pytest/stepfunctions/fixtures.py +4 -4
- localstack/testing/pytest/stepfunctions/utils.py +11 -10
- localstack/testing/pytest/util.py +1 -1
- localstack/testing/pytest/validation_tracking.py +3 -4
- localstack/testing/scenario/provisioning.py +11 -10
- localstack/testing/snapshots/transformer_utility.py +8 -3
- localstack/testing/testselection/matching.py +2 -2
- localstack/testing/testselection/opt_out.py +1 -1
- localstack/testing/testselection/scripts/filter_by_test_selection.py +1 -1
- localstack/testing/testselection/scripts/generate_test_selection.py +1 -1
- localstack/testing/testselection/testselection.py +2 -2
- localstack/utils/analytics/cli.py +2 -3
- localstack/utils/analytics/client.py +5 -5
- localstack/utils/analytics/events.py +2 -2
- localstack/utils/analytics/metadata.py +6 -4
- localstack/utils/analytics/metrics/counter.py +11 -18
- localstack/utils/analytics/metrics/registry.py +2 -2
- localstack/utils/analytics/publisher.py +4 -5
- localstack/utils/analytics/service_providers.py +19 -0
- localstack/utils/analytics/service_request_aggregator.py +4 -4
- localstack/utils/archives.py +12 -12
- localstack/utils/asyncio.py +2 -2
- localstack/utils/aws/arns.py +26 -31
- localstack/utils/aws/aws_responses.py +21 -28
- localstack/utils/aws/aws_stack.py +7 -12
- localstack/utils/aws/dead_letter_queue.py +4 -9
- localstack/utils/aws/message_forwarding.py +8 -11
- localstack/utils/aws/request_context.py +5 -6
- localstack/utils/aws/resources.py +1 -1
- localstack/utils/aws/templating.py +4 -4
- localstack/utils/batch_policy.py +4 -4
- localstack/utils/bootstrap.py +37 -30
- localstack/utils/catalog/catalog.py +139 -0
- localstack/utils/catalog/catalog_loader.py +119 -0
- localstack/utils/catalog/common.py +58 -0
- localstack/utils/catalog/plugins.py +28 -0
- localstack/utils/cloudwatch/cloudwatch_util.py +5 -5
- localstack/utils/collections.py +33 -27
- localstack/utils/config_listener.py +2 -2
- localstack/utils/container_networking.py +5 -6
- localstack/utils/container_utils/container_client.py +156 -160
- localstack/utils/container_utils/docker_cmd_client.py +97 -81
- localstack/utils/container_utils/docker_sdk_client.py +75 -72
- localstack/utils/crypto.py +12 -13
- localstack/utils/diagnose.py +11 -12
- localstack/utils/docker_utils.py +11 -7
- localstack/utils/files.py +34 -15
- localstack/utils/functions.py +5 -4
- localstack/utils/http.py +14 -14
- localstack/utils/iputils.py +2 -1
- localstack/utils/json.py +21 -7
- localstack/utils/kinesis/kinesis_connector.py +2 -1
- localstack/utils/net.py +25 -17
- localstack/utils/no_exit_argument_parser.py +2 -2
- localstack/utils/numbers.py +9 -2
- localstack/utils/objects.py +15 -14
- localstack/utils/patch.py +14 -7
- localstack/utils/platform.py +2 -2
- localstack/utils/run.py +15 -14
- localstack/utils/scheduler.py +13 -12
- localstack/utils/server/tcp_proxy.py +2 -2
- localstack/utils/serving.py +3 -4
- localstack/utils/strings.py +15 -16
- localstack/utils/sync.py +126 -1
- localstack/utils/tagging.py +10 -8
- localstack/utils/testutil.py +17 -17
- localstack/utils/threads.py +3 -3
- localstack/utils/time.py +12 -4
- localstack/utils/urls.py +1 -3
- localstack/utils/xml.py +1 -1
- localstack/utils/xray/traceid.py +1 -1
- localstack/version.py +16 -3
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/METADATA +18 -13
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/RECORD +663 -655
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/entry_points.txt +8 -4
- localstack_core-4.10.1.dev12.dist-info/plux.json +1 -0
- localstack/packages/terraform.py +0 -47
- localstack/services/cloudformation/deploy.html +0 -144
- localstack/services/cloudformation/deploy_ui.py +0 -47
- localstack/services/cloudformation/plugins.py +0 -12
- localstack/services/lambda_/lambda_debug_mode/ldm.py +0 -375
- localstack/services/lambda_/lambda_debug_mode/ldm_config_file.py +0 -178
- localstack/services/lambda_/lambda_debug_mode/ldm_types.py +0 -11
- localstack/services/lambda_/lambda_debug_mode/ldm_utils.py +0 -43
- localstack_core-4.6.1.dev60.dist-info/plux.json +0 -1
- /localstack/{services/lambda_/lambda_debug_mode/__init__.py → testing/pytest/cloudformation/transformers.py} +0 -0
- {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack +0 -0
- {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack-supervisor +0 -0
- {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack.bat +0 -0
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/WHEEL +0 -0
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/licenses/LICENSE.txt +0 -0
- {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import json
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
from botocore.utils import InvalidArnException
|
|
6
|
+
|
|
7
|
+
from localstack.aws.api.sns import InvalidParameterException
|
|
8
|
+
from localstack.services.sns.constants import E164_REGEX, VALID_SUBSCRIPTION_ATTR_NAME
|
|
9
|
+
from localstack.utils.aws.arns import ArnData, parse_arn
|
|
10
|
+
from localstack.utils.strings import short_uid, to_bytes, to_str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def parse_and_validate_topic_arn(topic_arn: str | None) -> ArnData:
|
|
14
|
+
return _parse_and_validate_arn(topic_arn, "Topic")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def parse_and_validate_platform_application_arn(platform_application_arn: str | None) -> ArnData:
|
|
18
|
+
return _parse_and_validate_arn(platform_application_arn, "PlatformApplication")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _parse_and_validate_arn(arn: str | None, resource_type: str) -> ArnData:
|
|
22
|
+
arn = arn or ""
|
|
23
|
+
try:
|
|
24
|
+
return parse_arn(arn)
|
|
25
|
+
except InvalidArnException:
|
|
26
|
+
count = len(arn.split(":"))
|
|
27
|
+
raise InvalidParameterException(
|
|
28
|
+
f"Invalid parameter: {resource_type}Arn Reason: An ARN must have at least 6 elements, not {count}"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def is_valid_e164_number(number: str) -> bool:
|
|
33
|
+
return E164_REGEX.match(number) is not None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def validate_subscription_attribute(
|
|
37
|
+
attribute_name: str,
|
|
38
|
+
attribute_value: str,
|
|
39
|
+
topic_arn: str,
|
|
40
|
+
endpoint: str,
|
|
41
|
+
is_subscribe_call: bool = False,
|
|
42
|
+
) -> None:
|
|
43
|
+
"""
|
|
44
|
+
Validate the subscription attribute to be set. See:
|
|
45
|
+
https://docs.aws.amazon.com/sns/latest/api/API_SetSubscriptionAttributes.html
|
|
46
|
+
:param attribute_name: the subscription attribute name, must be in VALID_SUBSCRIPTION_ATTR_NAME
|
|
47
|
+
:param attribute_value: the subscription attribute value
|
|
48
|
+
:param topic_arn: the topic_arn of the subscription, needed to know if it is FIFO
|
|
49
|
+
:param endpoint: the subscription endpoint (like an SQS queue ARN)
|
|
50
|
+
:param is_subscribe_call: the error message is different if called from Subscribe or SetSubscriptionAttributes
|
|
51
|
+
:raises InvalidParameterException
|
|
52
|
+
:return:
|
|
53
|
+
"""
|
|
54
|
+
error_prefix = (
|
|
55
|
+
"Invalid parameter: Attributes Reason: " if is_subscribe_call else "Invalid parameter: "
|
|
56
|
+
)
|
|
57
|
+
if attribute_name not in VALID_SUBSCRIPTION_ATTR_NAME:
|
|
58
|
+
raise InvalidParameterException(f"{error_prefix}AttributeName")
|
|
59
|
+
|
|
60
|
+
if attribute_name == "FilterPolicy":
|
|
61
|
+
try:
|
|
62
|
+
json.loads(attribute_value or "{}")
|
|
63
|
+
except json.JSONDecodeError:
|
|
64
|
+
raise InvalidParameterException(f"{error_prefix}FilterPolicy: failed to parse JSON.")
|
|
65
|
+
elif attribute_name == "FilterPolicyScope":
|
|
66
|
+
if attribute_value not in ("MessageAttributes", "MessageBody"):
|
|
67
|
+
raise InvalidParameterException(
|
|
68
|
+
f"{error_prefix}FilterPolicyScope: Invalid value [{attribute_value}]. "
|
|
69
|
+
f"Please use either MessageBody or MessageAttributes"
|
|
70
|
+
)
|
|
71
|
+
elif attribute_name == "RawMessageDelivery":
|
|
72
|
+
# TODO: only for SQS and https(s) subs, + firehose
|
|
73
|
+
if attribute_value.lower() not in ("true", "false"):
|
|
74
|
+
raise InvalidParameterException(
|
|
75
|
+
f"{error_prefix}RawMessageDelivery: Invalid value [{attribute_value}]. "
|
|
76
|
+
f"Must be true or false."
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
elif attribute_name == "RedrivePolicy":
|
|
80
|
+
try:
|
|
81
|
+
dlq_target_arn = json.loads(attribute_value).get("deadLetterTargetArn", "")
|
|
82
|
+
except json.JSONDecodeError:
|
|
83
|
+
raise InvalidParameterException(f"{error_prefix}RedrivePolicy: failed to parse JSON.")
|
|
84
|
+
try:
|
|
85
|
+
parsed_arn = parse_arn(dlq_target_arn)
|
|
86
|
+
except InvalidArnException:
|
|
87
|
+
raise InvalidParameterException(
|
|
88
|
+
f"{error_prefix}RedrivePolicy: deadLetterTargetArn is an invalid arn"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if topic_arn.endswith(".fifo"):
|
|
92
|
+
if endpoint.endswith(".fifo") and (
|
|
93
|
+
not parsed_arn["resource"].endswith(".fifo") or "sqs" not in parsed_arn["service"]
|
|
94
|
+
):
|
|
95
|
+
raise InvalidParameterException(
|
|
96
|
+
f"{error_prefix}RedrivePolicy: must use a FIFO queue as DLQ for a FIFO Subscription to a FIFO Topic."
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def create_subscription_arn(topic_arn: str) -> str:
|
|
101
|
+
# This is the format of a Subscription ARN
|
|
102
|
+
# arn:aws:sns:us-west-2:123456789012:my-topic:8a21d249-4329-4871-acc6-7be709c6ea7f
|
|
103
|
+
return f"{topic_arn}:{uuid4()}"
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def encode_subscription_token_with_region(region: str) -> str:
|
|
107
|
+
"""
|
|
108
|
+
Create a 64 characters Subscription Token with the region encoded
|
|
109
|
+
:param region:
|
|
110
|
+
:return: a subscription token with the region encoded
|
|
111
|
+
"""
|
|
112
|
+
return ((region.encode() + b"/").hex() + short_uid() * 8)[:64]
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def get_next_page_token_from_arn(resource_arn: str) -> str:
|
|
116
|
+
return to_str(base64.b64encode(to_bytes(resource_arn)))
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def get_region_from_subscription_token(token: str) -> str:
|
|
120
|
+
"""
|
|
121
|
+
Try to decode and return the region from a subscription token
|
|
122
|
+
:param token:
|
|
123
|
+
:return: the region if able to decode it
|
|
124
|
+
:raises: InvalidParameterException if the token is invalid
|
|
125
|
+
"""
|
|
126
|
+
try:
|
|
127
|
+
region = token.split("2f", maxsplit=1)[0]
|
|
128
|
+
return bytes.fromhex(region).decode("utf-8")
|
|
129
|
+
except (IndexError, ValueError, TypeError, UnicodeDecodeError):
|
|
130
|
+
raise InvalidParameterException("Invalid parameter: Token")
|
|
@@ -9,7 +9,7 @@ MSG_CONTENT_REGEX = "^[\u0009\u000a\u000d\u0020-\ud7ff\ue000-\ufffd\U00010000-\U
|
|
|
9
9
|
ATTR_NAME_CHAR_REGEX = "^[\u00c0-\u017fa-zA-Z0-9_.-]*$"
|
|
10
10
|
ATTR_NAME_PREFIX_SUFFIX_REGEX = r"^(?!(aws\.|amazon\.|\.)).*(?<!\.)$"
|
|
11
11
|
ATTR_TYPE_REGEX = "^(String|Number|Binary).*$"
|
|
12
|
-
FIFO_MSG_REGEX = "^[0-9a-zA-z!\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~-]
|
|
12
|
+
FIFO_MSG_REGEX = "^[0-9a-zA-z!\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~-]{1,128}$"
|
|
13
13
|
|
|
14
14
|
DEDUPLICATION_INTERVAL_IN_SEC = 5 * 60
|
|
15
15
|
|
|
@@ -18,7 +18,7 @@ DEDUPLICATION_INTERVAL_IN_SEC = 5 * 60
|
|
|
18
18
|
RECENTLY_DELETED_TIMEOUT = 60
|
|
19
19
|
|
|
20
20
|
# the default maximum message size in SQS
|
|
21
|
-
DEFAULT_MAXIMUM_MESSAGE_SIZE =
|
|
21
|
+
DEFAULT_MAXIMUM_MESSAGE_SIZE = 1048576
|
|
22
22
|
INTERNAL_QUEUE_ATTRIBUTES = [
|
|
23
23
|
# these attributes cannot be changed by set_queue_attributes and should
|
|
24
24
|
# therefore be ignored when comparing queue attributes for create_queue
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from werkzeug import Request as WerkzeugRequest
|
|
5
|
+
|
|
6
|
+
from localstack.aws.api import CommonServiceException, ServiceException
|
|
7
|
+
from localstack.aws.api.sqs import (
|
|
8
|
+
Message,
|
|
9
|
+
QueueAttributeName,
|
|
10
|
+
QueueDoesNotExist,
|
|
11
|
+
ReceiveMessageResult,
|
|
12
|
+
)
|
|
13
|
+
from localstack.aws.protocol.parser import create_parser
|
|
14
|
+
from localstack.aws.protocol.serializer import aws_response_serializer
|
|
15
|
+
from localstack.aws.spec import load_service
|
|
16
|
+
from localstack.http import Request, route
|
|
17
|
+
from localstack.services.sqs.models import (
|
|
18
|
+
FifoQueue,
|
|
19
|
+
SqsMessage,
|
|
20
|
+
SqsQueue,
|
|
21
|
+
StandardQueue,
|
|
22
|
+
sqs_stores,
|
|
23
|
+
to_sqs_api_message,
|
|
24
|
+
)
|
|
25
|
+
from localstack.services.sqs.utils import (
|
|
26
|
+
parse_queue_url,
|
|
27
|
+
)
|
|
28
|
+
from localstack.utils.aws.request_context import extract_region_from_headers
|
|
29
|
+
|
|
30
|
+
LOG = logging.getLogger(__name__)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class InvalidAddress(ServiceException):
|
|
34
|
+
code = "InvalidAddress"
|
|
35
|
+
message = "The address https://queue.amazonaws.com/ is not valid for this endpoint."
|
|
36
|
+
sender_fault = True
|
|
37
|
+
status_code = 404
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_sqs_protocol(request: Request) -> Literal["query", "json"]:
|
|
41
|
+
content_type = request.headers.get("Content-Type")
|
|
42
|
+
return "json" if content_type == "application/x-amz-json-1.0" else "query"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def sqs_auto_protocol_aws_response_serializer(service_name: str, operation: str):
|
|
46
|
+
def _decorate(fn):
|
|
47
|
+
def _proxy(*args, **kwargs):
|
|
48
|
+
# extract request from function invocation (decorator can be used for methods as well as for functions).
|
|
49
|
+
if len(args) > 0 and isinstance(args[0], WerkzeugRequest):
|
|
50
|
+
# function
|
|
51
|
+
request = args[0]
|
|
52
|
+
elif len(args) > 1 and isinstance(args[1], WerkzeugRequest):
|
|
53
|
+
# method (arg[0] == self)
|
|
54
|
+
request = args[1]
|
|
55
|
+
elif "request" in kwargs:
|
|
56
|
+
request = kwargs["request"]
|
|
57
|
+
else:
|
|
58
|
+
raise ValueError(f"could not find Request in signature of function {fn}")
|
|
59
|
+
|
|
60
|
+
protocol = get_sqs_protocol(request)
|
|
61
|
+
return aws_response_serializer(service_name, operation, protocol)(fn)(*args, **kwargs)
|
|
62
|
+
|
|
63
|
+
return _proxy
|
|
64
|
+
|
|
65
|
+
return _decorate
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class SqsDeveloperApi:
|
|
69
|
+
"""
|
|
70
|
+
A set of SQS developer tool endpoints:
|
|
71
|
+
|
|
72
|
+
- ``/_aws/sqs/messages``: list SQS messages without side effects, compatible with ``ReceiveMessage``.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
def __init__(self, stores=None):
|
|
76
|
+
self.stores = stores or sqs_stores
|
|
77
|
+
|
|
78
|
+
@route("/_aws/sqs/messages", methods=["GET", "POST"])
|
|
79
|
+
@sqs_auto_protocol_aws_response_serializer("sqs", "ReceiveMessage")
|
|
80
|
+
def list_messages(self, request: Request) -> ReceiveMessageResult:
|
|
81
|
+
"""
|
|
82
|
+
This endpoint expects a ``QueueUrl`` request parameter (either as query arg or form parameter), similar to
|
|
83
|
+
the ``ReceiveMessage`` operation. It will parse the Queue URL generated by one of the SQS endpoint strategies.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
if "x-amz-" in request.mimetype or "x-www-form-urlencoded" in request.mimetype:
|
|
87
|
+
# only parse the request using a parser if it comes from an AWS client
|
|
88
|
+
protocol = get_sqs_protocol(request)
|
|
89
|
+
operation, service_request = create_parser(
|
|
90
|
+
load_service("sqs", protocol=protocol)
|
|
91
|
+
).parse(request)
|
|
92
|
+
if operation.name != "ReceiveMessage":
|
|
93
|
+
raise CommonServiceException(
|
|
94
|
+
"InvalidRequest", "This endpoint only accepts ReceiveMessage calls"
|
|
95
|
+
)
|
|
96
|
+
else:
|
|
97
|
+
service_request = dict(request.values)
|
|
98
|
+
|
|
99
|
+
if not service_request.get("QueueUrl"):
|
|
100
|
+
raise QueueDoesNotExist()
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
account_id, region, queue_name = parse_queue_url(service_request.get("QueueUrl"))
|
|
104
|
+
except ValueError:
|
|
105
|
+
LOG.error(
|
|
106
|
+
"Error while parsing Queue URL from request values: %s",
|
|
107
|
+
service_request.get,
|
|
108
|
+
exc_info=LOG.isEnabledFor(logging.DEBUG),
|
|
109
|
+
)
|
|
110
|
+
raise InvalidAddress()
|
|
111
|
+
|
|
112
|
+
if not region:
|
|
113
|
+
region = extract_region_from_headers(request.headers)
|
|
114
|
+
|
|
115
|
+
return self._get_and_serialize_messages(request, region, account_id, queue_name)
|
|
116
|
+
|
|
117
|
+
@route("/_aws/sqs/messages/<region>/<account_id>/<queue_name>")
|
|
118
|
+
@sqs_auto_protocol_aws_response_serializer("sqs", "ReceiveMessage")
|
|
119
|
+
def list_messages_for_queue_url(
|
|
120
|
+
self, request: Request, region: str, account_id: str, queue_name: str
|
|
121
|
+
) -> ReceiveMessageResult:
|
|
122
|
+
"""
|
|
123
|
+
This endpoint extracts the region, account_id, and queue_name directly from the URL rather than requiring the
|
|
124
|
+
QueueUrl as parameter.
|
|
125
|
+
"""
|
|
126
|
+
return self._get_and_serialize_messages(request, region, account_id, queue_name)
|
|
127
|
+
|
|
128
|
+
def _get_and_serialize_messages(
|
|
129
|
+
self,
|
|
130
|
+
request: Request,
|
|
131
|
+
region: str,
|
|
132
|
+
account_id: str,
|
|
133
|
+
queue_name: str,
|
|
134
|
+
) -> ReceiveMessageResult:
|
|
135
|
+
show_invisible = request.values.get("ShowInvisible", "").lower() in ["true", "1"]
|
|
136
|
+
show_delayed = request.values.get("ShowDelayed", "").lower() in ["true", "1"]
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
store = self.stores[account_id][region]
|
|
140
|
+
queue = store.queues[queue_name]
|
|
141
|
+
except KeyError:
|
|
142
|
+
LOG.info(
|
|
143
|
+
"no queue named %s in region %s and account %s", queue_name, region, account_id
|
|
144
|
+
)
|
|
145
|
+
raise QueueDoesNotExist()
|
|
146
|
+
|
|
147
|
+
messages = self._collect_messages(
|
|
148
|
+
queue, show_invisible=show_invisible, show_delayed=show_delayed
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
return ReceiveMessageResult(Messages=messages)
|
|
152
|
+
|
|
153
|
+
def _collect_messages(
|
|
154
|
+
self, queue: SqsQueue, show_invisible: bool = False, show_delayed: bool = False
|
|
155
|
+
) -> list[Message]:
|
|
156
|
+
"""
|
|
157
|
+
Retrieves from a given SqsQueue all visible messages without causing any side effects (not setting any
|
|
158
|
+
receive timestamps, receive counts, or visibility state).
|
|
159
|
+
|
|
160
|
+
:param queue: the queue
|
|
161
|
+
:param show_invisible: show invisible messages as well
|
|
162
|
+
:param show_delayed: show delayed messages as well
|
|
163
|
+
:return: a list of messages
|
|
164
|
+
"""
|
|
165
|
+
receipt_handle = "SQS/BACKDOOR/ACCESS" # dummy receipt handle
|
|
166
|
+
|
|
167
|
+
sqs_messages: list[SqsMessage] = []
|
|
168
|
+
|
|
169
|
+
if show_invisible:
|
|
170
|
+
sqs_messages.extend(queue.inflight)
|
|
171
|
+
|
|
172
|
+
if isinstance(queue, StandardQueue):
|
|
173
|
+
sqs_messages.extend(queue.visible.queue)
|
|
174
|
+
elif isinstance(queue, FifoQueue):
|
|
175
|
+
if show_invisible:
|
|
176
|
+
for inflight_group in queue.inflight_groups:
|
|
177
|
+
# messages that have been received are held in ``queue.inflight``, even for FIFO queues. however,
|
|
178
|
+
# for fifo queues, messages that are in the same message group as messages that have been
|
|
179
|
+
# received, are also considered invisible, and are held here in ``inflight_group.messages``.
|
|
180
|
+
for sqs_message in inflight_group.messages:
|
|
181
|
+
sqs_messages.append(sqs_message)
|
|
182
|
+
|
|
183
|
+
for message_group in queue.message_group_queue.queue:
|
|
184
|
+
# these are all messages of message groups that are visible
|
|
185
|
+
for sqs_message in message_group.messages:
|
|
186
|
+
sqs_messages.append(sqs_message)
|
|
187
|
+
else:
|
|
188
|
+
raise ValueError(f"unknown queue type {type(queue)}")
|
|
189
|
+
|
|
190
|
+
if show_delayed:
|
|
191
|
+
sqs_messages.extend(queue.delayed)
|
|
192
|
+
|
|
193
|
+
messages = []
|
|
194
|
+
|
|
195
|
+
for sqs_message in sqs_messages:
|
|
196
|
+
message: Message = to_sqs_api_message(sqs_message, [QueueAttributeName.All], ["All"])
|
|
197
|
+
# these are all non-standard fields so we squelch the linter
|
|
198
|
+
if show_invisible:
|
|
199
|
+
message["Attributes"]["IsVisible"] = str(sqs_message.is_visible).lower() # noqa
|
|
200
|
+
if show_delayed:
|
|
201
|
+
message["Attributes"]["IsDelayed"] = str(sqs_message.is_delayed).lower() # noqa
|
|
202
|
+
messages.append(message)
|
|
203
|
+
message["ReceiptHandle"] = receipt_handle
|
|
204
|
+
|
|
205
|
+
return messages
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import copy
|
|
1
2
|
import hashlib
|
|
2
3
|
import heapq
|
|
3
4
|
import inspect
|
|
@@ -8,7 +9,6 @@ import threading
|
|
|
8
9
|
import time
|
|
9
10
|
from datetime import datetime
|
|
10
11
|
from queue import Empty
|
|
11
|
-
from typing import Dict, Optional, Set
|
|
12
12
|
|
|
13
13
|
from localstack import config
|
|
14
14
|
from localstack.aws.api import RequestContext
|
|
@@ -16,6 +16,7 @@ from localstack.aws.api.sqs import (
|
|
|
16
16
|
AttributeNameList,
|
|
17
17
|
InvalidAttributeName,
|
|
18
18
|
Message,
|
|
19
|
+
MessageAttributeNameList,
|
|
19
20
|
MessageSystemAttributeName,
|
|
20
21
|
QueueAttributeMap,
|
|
21
22
|
QueueAttributeName,
|
|
@@ -30,12 +31,15 @@ from localstack.services.sqs.exceptions import (
|
|
|
30
31
|
)
|
|
31
32
|
from localstack.services.sqs.queue import InterruptiblePriorityQueue, InterruptibleQueue
|
|
32
33
|
from localstack.services.sqs.utils import (
|
|
34
|
+
create_message_attribute_hash,
|
|
33
35
|
encode_move_task_handle,
|
|
34
36
|
encode_receipt_handle,
|
|
35
37
|
extract_receipt_handle_info,
|
|
36
38
|
global_message_sequence,
|
|
37
39
|
guess_endpoint_strategy_and_host,
|
|
38
40
|
is_message_deduplication_id_required,
|
|
41
|
+
message_filter_attributes,
|
|
42
|
+
message_filter_message_attributes,
|
|
39
43
|
)
|
|
40
44
|
from localstack.services.stores import AccountRegionBundle, BaseStore, LocalAttribute
|
|
41
45
|
from localstack.utils.aws.arns import get_partition
|
|
@@ -53,11 +57,11 @@ class SqsMessage:
|
|
|
53
57
|
created: float
|
|
54
58
|
visibility_timeout: int
|
|
55
59
|
receive_count: int
|
|
56
|
-
delay_seconds:
|
|
57
|
-
receipt_handles:
|
|
58
|
-
last_received:
|
|
59
|
-
first_received:
|
|
60
|
-
visibility_deadline:
|
|
60
|
+
delay_seconds: int | None
|
|
61
|
+
receipt_handles: set[str]
|
|
62
|
+
last_received: float | None
|
|
63
|
+
first_received: float | None
|
|
64
|
+
visibility_deadline: float | None
|
|
61
65
|
deleted: bool
|
|
62
66
|
priority: float
|
|
63
67
|
message_deduplication_id: str
|
|
@@ -104,15 +108,15 @@ class SqsMessage:
|
|
|
104
108
|
)
|
|
105
109
|
|
|
106
110
|
@property
|
|
107
|
-
def message_group_id(self) ->
|
|
111
|
+
def message_group_id(self) -> str | None:
|
|
108
112
|
return self.message["Attributes"].get(MessageSystemAttributeName.MessageGroupId)
|
|
109
113
|
|
|
110
114
|
@property
|
|
111
|
-
def message_deduplication_id(self) ->
|
|
115
|
+
def message_deduplication_id(self) -> str | None:
|
|
112
116
|
return self.message["Attributes"].get(MessageSystemAttributeName.MessageDeduplicationId)
|
|
113
117
|
|
|
114
118
|
@property
|
|
115
|
-
def dead_letter_queue_source_arn(self) ->
|
|
119
|
+
def dead_letter_queue_source_arn(self) -> str | None:
|
|
116
120
|
return self.message["Attributes"].get(MessageSystemAttributeName.DeadLetterQueueSourceArn)
|
|
117
121
|
|
|
118
122
|
@property
|
|
@@ -154,7 +158,7 @@ class SqsMessage:
|
|
|
154
158
|
"""
|
|
155
159
|
Returns false if the message has a visibility deadline that is in the future.
|
|
156
160
|
|
|
157
|
-
:return: whether the message is
|
|
161
|
+
:return: whether the message is visible or not.
|
|
158
162
|
"""
|
|
159
163
|
if self.visibility_deadline is None:
|
|
160
164
|
return True
|
|
@@ -191,6 +195,41 @@ class SqsMessage:
|
|
|
191
195
|
return f"SqsMessage(id={self.message_id},group={self.message_group_id})"
|
|
192
196
|
|
|
193
197
|
|
|
198
|
+
def to_sqs_api_message(
|
|
199
|
+
standard_message: SqsMessage,
|
|
200
|
+
attribute_names: AttributeNameList = None,
|
|
201
|
+
message_attribute_names: MessageAttributeNameList = None,
|
|
202
|
+
) -> Message:
|
|
203
|
+
"""
|
|
204
|
+
Utility function to convert an SQS message from LocalStack's internal representation to the AWS API
|
|
205
|
+
concept 'Message', which is the format returned by the ``ReceiveMessage`` operation.
|
|
206
|
+
|
|
207
|
+
:param standard_message: A LocalStack SQS message
|
|
208
|
+
:param attribute_names: the attribute name list to filter
|
|
209
|
+
:param message_attribute_names: the message attribute names to filter
|
|
210
|
+
:return: a copy of the original Message with updated message attributes and MD5 attribute hash sums
|
|
211
|
+
"""
|
|
212
|
+
# prepare message for receiver
|
|
213
|
+
message = copy.deepcopy(standard_message.message)
|
|
214
|
+
|
|
215
|
+
# update system attributes of the message copy
|
|
216
|
+
message["Attributes"][MessageSystemAttributeName.ApproximateFirstReceiveTimestamp] = str(
|
|
217
|
+
int((standard_message.first_received or 0) * 1000)
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# filter attributes for receiver
|
|
221
|
+
message_filter_attributes(message, attribute_names)
|
|
222
|
+
message_filter_message_attributes(message, message_attribute_names)
|
|
223
|
+
if message.get("MessageAttributes"):
|
|
224
|
+
message["MD5OfMessageAttributes"] = create_message_attribute_hash(
|
|
225
|
+
message["MessageAttributes"]
|
|
226
|
+
)
|
|
227
|
+
else:
|
|
228
|
+
# delete the value that was computed when creating the message
|
|
229
|
+
message.pop("MD5OfMessageAttributes", None)
|
|
230
|
+
return message
|
|
231
|
+
|
|
232
|
+
|
|
194
233
|
class ReceiveMessageResult:
|
|
195
234
|
"""
|
|
196
235
|
Object to communicate the result of a "receive messages" operation between the SqsProvider and
|
|
@@ -272,11 +311,11 @@ class SqsQueue:
|
|
|
272
311
|
tags: TagMap
|
|
273
312
|
|
|
274
313
|
purge_in_progress: bool
|
|
275
|
-
purge_timestamp:
|
|
314
|
+
purge_timestamp: float | None
|
|
276
315
|
|
|
277
|
-
delayed:
|
|
278
|
-
inflight:
|
|
279
|
-
receipts:
|
|
316
|
+
delayed: set[SqsMessage]
|
|
317
|
+
inflight: set[SqsMessage]
|
|
318
|
+
receipts: dict[str, SqsMessage]
|
|
280
319
|
|
|
281
320
|
def __init__(self, name: str, region: str, account_id: str, attributes=None, tags=None) -> None:
|
|
282
321
|
self.name = name
|
|
@@ -393,13 +432,13 @@ class SqsQueue:
|
|
|
393
432
|
)
|
|
394
433
|
|
|
395
434
|
@property
|
|
396
|
-
def redrive_policy(self) ->
|
|
435
|
+
def redrive_policy(self) -> dict | None:
|
|
397
436
|
if policy_document := self.attributes.get(QueueAttributeName.RedrivePolicy):
|
|
398
437
|
return json.loads(policy_document)
|
|
399
438
|
return None
|
|
400
439
|
|
|
401
440
|
@property
|
|
402
|
-
def max_receive_count(self) ->
|
|
441
|
+
def max_receive_count(self) -> int | None:
|
|
403
442
|
"""
|
|
404
443
|
Returns the maxReceiveCount attribute of the redrive policy. If no redrive policy is set, then it
|
|
405
444
|
returns None.
|
|
@@ -678,7 +717,7 @@ class SqsQueue:
|
|
|
678
717
|
if QueueAttributeName.All in attribute_names:
|
|
679
718
|
attribute_names = self.attributes.keys()
|
|
680
719
|
|
|
681
|
-
result:
|
|
720
|
+
result: dict[QueueAttributeName, str] = {}
|
|
682
721
|
|
|
683
722
|
for attr in attribute_names:
|
|
684
723
|
try:
|
|
@@ -740,7 +779,7 @@ class SqsQueue:
|
|
|
740
779
|
|
|
741
780
|
class StandardQueue(SqsQueue):
|
|
742
781
|
visible: InterruptiblePriorityQueue[SqsMessage]
|
|
743
|
-
inflight:
|
|
782
|
+
inflight: set[SqsMessage]
|
|
744
783
|
|
|
745
784
|
def __init__(self, name: str, region: str, account_id: str, attributes=None, tags=None) -> None:
|
|
746
785
|
super().__init__(name, region, account_id, attributes, tags)
|
|
@@ -771,13 +810,12 @@ class StandardQueue(SqsQueue):
|
|
|
771
810
|
f"Value {message_deduplication_id} for parameter MessageDeduplicationId is invalid. Reason: The "
|
|
772
811
|
f"request includes a parameter that is not valid for this queue type."
|
|
773
812
|
)
|
|
774
|
-
if isinstance(message_group_id, str):
|
|
775
|
-
raise InvalidParameterValueException(
|
|
776
|
-
f"Value {message_group_id} for parameter MessageGroupId is invalid. Reason: The request include "
|
|
777
|
-
f"parameter that is not valid for this queue type."
|
|
778
|
-
)
|
|
779
813
|
|
|
780
|
-
standard_message = SqsMessage(
|
|
814
|
+
standard_message = SqsMessage(
|
|
815
|
+
time.time(),
|
|
816
|
+
message,
|
|
817
|
+
message_group_id=message_group_id,
|
|
818
|
+
)
|
|
781
819
|
|
|
782
820
|
if visibility_timeout is not None:
|
|
783
821
|
standard_message.visibility_timeout = visibility_timeout
|
|
@@ -960,7 +998,7 @@ class FifoQueue(SqsQueue):
|
|
|
960
998
|
TODO: raise exceptions when trying to remove a message with an expired receipt handle
|
|
961
999
|
"""
|
|
962
1000
|
|
|
963
|
-
deduplication:
|
|
1001
|
+
deduplication: dict[str, SqsMessage]
|
|
964
1002
|
message_groups: dict[str, MessageGroup]
|
|
965
1003
|
inflight_groups: set[MessageGroup]
|
|
966
1004
|
message_group_queue: InterruptibleQueue
|
|
@@ -1010,13 +1048,12 @@ class FifoQueue(SqsQueue):
|
|
|
1010
1048
|
}
|
|
1011
1049
|
|
|
1012
1050
|
def update_delay_seconds(self, value: int):
|
|
1013
|
-
super(
|
|
1051
|
+
super().update_delay_seconds(value)
|
|
1014
1052
|
for message in self.delayed:
|
|
1015
1053
|
message.delay_seconds = value
|
|
1016
1054
|
|
|
1017
1055
|
def _pre_delete_checks(self, message: SqsMessage, receipt_handle: str) -> None:
|
|
1018
|
-
|
|
1019
|
-
if time.time() - float(last_received) > message.visibility_timeout:
|
|
1056
|
+
if message.is_visible:
|
|
1020
1057
|
raise InvalidParameterValueException(
|
|
1021
1058
|
f"Value {receipt_handle} for parameter ReceiptHandle is invalid. Reason: The receipt handle has expired."
|
|
1022
1059
|
)
|
|
@@ -1067,10 +1104,8 @@ class FifoQueue(SqsQueue):
|
|
|
1067
1104
|
# use the attribute from the queue
|
|
1068
1105
|
fifo_message.visibility_timeout = self.visibility_timeout
|
|
1069
1106
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
else:
|
|
1073
|
-
fifo_message.delay_seconds = self.delay_seconds
|
|
1107
|
+
# FIFO queues always use the queue level setting for 'DelaySeconds'
|
|
1108
|
+
fifo_message.delay_seconds = self.delay_seconds
|
|
1074
1109
|
|
|
1075
1110
|
original_message = self.deduplication.get(dedup_id)
|
|
1076
1111
|
if (
|
|
@@ -1159,7 +1194,7 @@ class FifoQueue(SqsQueue):
|
|
|
1159
1194
|
timeout = wait_time_seconds or 0
|
|
1160
1195
|
start = time.time()
|
|
1161
1196
|
|
|
1162
|
-
received_groups:
|
|
1197
|
+
received_groups: set[MessageGroup] = set()
|
|
1163
1198
|
|
|
1164
1199
|
# collect messages over potentially multiple groups
|
|
1165
1200
|
while True:
|
|
@@ -1315,11 +1350,11 @@ class FifoQueue(SqsQueue):
|
|
|
1315
1350
|
|
|
1316
1351
|
|
|
1317
1352
|
class SqsStore(BaseStore):
|
|
1318
|
-
queues:
|
|
1353
|
+
queues: dict[str, SqsQueue] = LocalAttribute(default=dict)
|
|
1319
1354
|
|
|
1320
|
-
deleted:
|
|
1355
|
+
deleted: dict[str, float] = LocalAttribute(default=dict)
|
|
1321
1356
|
|
|
1322
|
-
move_tasks:
|
|
1357
|
+
move_tasks: dict[str, MessageMoveTask] = LocalAttribute(default=dict)
|
|
1323
1358
|
"""Maps task IDs to their ``MoveMessageTask`` object. Task IDs can be found by decoding a task handle."""
|
|
1324
1359
|
|
|
1325
1360
|
def expire_deleted(self):
|