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.
Files changed (672) hide show
  1. localstack/aws/api/apigateway/__init__.py +87 -110
  2. localstack/aws/api/cloudformation/__init__.py +18 -4
  3. localstack/aws/api/cloudwatch/__init__.py +41 -1
  4. localstack/aws/api/config/__init__.py +4 -0
  5. localstack/aws/api/core.py +8 -5
  6. localstack/aws/api/dynamodb/__init__.py +30 -0
  7. localstack/aws/api/ec2/__init__.py +1545 -66
  8. localstack/aws/api/events/__init__.py +12 -16
  9. localstack/aws/api/iam/__init__.py +7 -0
  10. localstack/aws/api/kinesis/__init__.py +19 -0
  11. localstack/aws/api/kms/__init__.py +6 -0
  12. localstack/aws/api/lambda_/__init__.py +36 -23
  13. localstack/aws/api/logs/__init__.py +20 -8
  14. localstack/aws/api/opensearch/__init__.py +16 -0
  15. localstack/aws/api/pipes/__init__.py +24 -32
  16. localstack/aws/api/redshift/__init__.py +9 -3
  17. localstack/aws/api/route53/__init__.py +5 -0
  18. localstack/aws/api/s3/__init__.py +12 -0
  19. localstack/aws/api/s3control/__init__.py +56 -0
  20. localstack/aws/api/scheduler/__init__.py +14 -16
  21. localstack/aws/api/ssm/__init__.py +2 -0
  22. localstack/aws/api/stepfunctions/__init__.py +88 -114
  23. localstack/aws/api/support/__init__.py +8 -9
  24. localstack/aws/api/transcribe/__init__.py +17 -0
  25. localstack/aws/chain.py +2 -2
  26. localstack/aws/client.py +14 -11
  27. localstack/aws/connect.py +42 -41
  28. localstack/aws/forwarder.py +57 -9
  29. localstack/aws/gateway.py +1 -3
  30. localstack/aws/handlers/analytics.py +2 -3
  31. localstack/aws/handlers/cors.py +4 -5
  32. localstack/aws/handlers/internal_requests.py +6 -1
  33. localstack/aws/handlers/logging.py +13 -4
  34. localstack/aws/handlers/metric_handler.py +44 -5
  35. localstack/aws/handlers/service.py +48 -28
  36. localstack/aws/mocking.py +18 -27
  37. localstack/aws/patches.py +2 -2
  38. localstack/aws/protocol/op_router.py +11 -10
  39. localstack/aws/protocol/parser.py +475 -49
  40. localstack/aws/protocol/serializer.py +723 -106
  41. localstack/aws/protocol/service_router.py +133 -33
  42. localstack/aws/protocol/validate.py +6 -6
  43. localstack/aws/scaffold.py +9 -10
  44. localstack/aws/serving/edge.py +5 -6
  45. localstack/aws/serving/hypercorn.py +2 -2
  46. localstack/aws/serving/twisted.py +1 -2
  47. localstack/aws/serving/werkzeug.py +2 -2
  48. localstack/aws/skeleton.py +12 -11
  49. localstack/aws/spec-patches.json +58 -0
  50. localstack/aws/spec.py +66 -46
  51. localstack/cli/exceptions.py +1 -1
  52. localstack/cli/localstack.py +11 -11
  53. localstack/cli/lpm.py +4 -5
  54. localstack/cli/plugins.py +1 -1
  55. localstack/cli/profiles.py +1 -2
  56. localstack/config.py +44 -30
  57. localstack/constants.py +4 -29
  58. localstack/deprecations.py +5 -5
  59. localstack/dev/kubernetes/__main__.py +130 -7
  60. localstack/dev/run/__main__.py +5 -5
  61. localstack/dev/run/configurators.py +1 -4
  62. localstack/dev/run/paths.py +6 -6
  63. localstack/dns/models.py +2 -1
  64. localstack/dns/plugins.py +5 -1
  65. localstack/dns/server.py +16 -6
  66. localstack/http/dispatcher.py +1 -2
  67. localstack/http/response.py +2 -2
  68. localstack/http/router.py +1 -1
  69. localstack/http/trace.py +2 -1
  70. localstack/logging/format.py +6 -6
  71. localstack/packages/api.py +13 -12
  72. localstack/packages/core.py +4 -4
  73. localstack/packages/debugpy.py +1 -3
  74. localstack/packages/ffmpeg.py +1 -2
  75. localstack/packages/java.py +38 -12
  76. localstack/packages/plugins.py +0 -8
  77. localstack/runtime/analytics.py +3 -0
  78. localstack/runtime/hooks.py +1 -1
  79. localstack/runtime/init.py +8 -9
  80. localstack/runtime/main.py +5 -5
  81. localstack/runtime/patches.py +2 -2
  82. localstack/runtime/shutdown.py +2 -1
  83. localstack/services/apigateway/exporter.py +1 -2
  84. localstack/services/apigateway/helpers.py +7 -10
  85. localstack/services/apigateway/legacy/context.py +21 -21
  86. localstack/services/apigateway/legacy/helpers.py +27 -28
  87. localstack/services/apigateway/legacy/integration.py +11 -10
  88. localstack/services/apigateway/legacy/invocations.py +6 -5
  89. localstack/services/apigateway/legacy/provider.py +148 -68
  90. localstack/services/apigateway/legacy/router_asf.py +2 -2
  91. localstack/services/apigateway/legacy/templates.py +6 -6
  92. localstack/services/apigateway/models.py +16 -16
  93. localstack/services/apigateway/next_gen/execute_api/api.py +2 -2
  94. localstack/services/apigateway/next_gen/execute_api/context.py +25 -25
  95. localstack/services/apigateway/next_gen/execute_api/handlers/api_key_validation.py +2 -5
  96. localstack/services/apigateway/next_gen/execute_api/handlers/method_request.py +7 -2
  97. localstack/services/apigateway/next_gen/execute_api/handlers/parse.py +1 -2
  98. localstack/services/apigateway/next_gen/execute_api/handlers/resource_router.py +2 -3
  99. localstack/services/apigateway/next_gen/execute_api/header_utils.py +1 -1
  100. localstack/services/apigateway/next_gen/execute_api/helpers.py +2 -2
  101. localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +9 -6
  102. localstack/services/apigateway/next_gen/execute_api/integrations/http.py +12 -12
  103. localstack/services/apigateway/next_gen/execute_api/router.py +31 -0
  104. localstack/services/apigateway/next_gen/execute_api/template_mapping.py +2 -2
  105. localstack/services/apigateway/next_gen/execute_api/test_invoke.py +114 -9
  106. localstack/services/apigateway/next_gen/execute_api/variables.py +63 -63
  107. localstack/services/apigateway/next_gen/provider.py +5 -0
  108. localstack/services/apigateway/resource_providers/aws_apigateway_account.py +3 -3
  109. localstack/services/apigateway/resource_providers/aws_apigateway_account_plugin.py +1 -3
  110. localstack/services/apigateway/resource_providers/aws_apigateway_apikey.py +14 -14
  111. localstack/services/apigateway/resource_providers/aws_apigateway_apikey_plugin.py +1 -3
  112. localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping.py +5 -5
  113. localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping_plugin.py +1 -3
  114. localstack/services/apigateway/resource_providers/aws_apigateway_deployment.py +46 -46
  115. localstack/services/apigateway/resource_providers/aws_apigateway_deployment_plugin.py +1 -3
  116. localstack/services/apigateway/resource_providers/aws_apigateway_domainname.py +18 -18
  117. localstack/services/apigateway/resource_providers/aws_apigateway_domainname_plugin.py +1 -3
  118. localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse.py +7 -7
  119. localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse_plugin.py +1 -3
  120. localstack/services/apigateway/resource_providers/aws_apigateway_method.py +36 -36
  121. localstack/services/apigateway/resource_providers/aws_apigateway_method_plugin.py +1 -3
  122. localstack/services/apigateway/resource_providers/aws_apigateway_model.py +6 -6
  123. localstack/services/apigateway/resource_providers/aws_apigateway_model_plugin.py +1 -3
  124. localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator.py +6 -6
  125. localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator_plugin.py +1 -3
  126. localstack/services/apigateway/resource_providers/aws_apigateway_resource.py +6 -6
  127. localstack/services/apigateway/resource_providers/aws_apigateway_resource_plugin.py +1 -3
  128. localstack/services/apigateway/resource_providers/aws_apigateway_restapi.py +26 -26
  129. localstack/services/apigateway/resource_providers/aws_apigateway_restapi_plugin.py +1 -3
  130. localstack/services/apigateway/resource_providers/aws_apigateway_stage.py +33 -33
  131. localstack/services/apigateway/resource_providers/aws_apigateway_stage_plugin.py +1 -3
  132. localstack/services/apigateway/resource_providers/aws_apigateway_usageplan.py +18 -18
  133. localstack/services/apigateway/resource_providers/aws_apigateway_usageplan_plugin.py +1 -3
  134. localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey.py +5 -5
  135. localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey_plugin.py +1 -3
  136. localstack/services/cdk/resource_providers/cdk_metadata.py +4 -3
  137. localstack/services/cdk/resource_providers/cdk_metadata_plugin.py +1 -3
  138. localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate.py +14 -14
  139. localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate_plugin.py +1 -3
  140. localstack/services/cloudformation/api_utils.py +4 -8
  141. localstack/services/cloudformation/cfn_utils.py +2 -2
  142. localstack/services/cloudformation/deployment_utils.py +14 -12
  143. localstack/services/cloudformation/engine/changes.py +3 -3
  144. localstack/services/cloudformation/engine/entities.py +27 -17
  145. localstack/services/cloudformation/engine/parameters.py +4 -4
  146. localstack/services/cloudformation/engine/template_deployer.py +15 -14
  147. localstack/services/cloudformation/engine/template_utils.py +34 -12
  148. localstack/services/cloudformation/engine/transformers.py +11 -8
  149. localstack/services/cloudformation/engine/types.py +5 -4
  150. localstack/services/cloudformation/engine/v2/change_set_model.py +336 -39
  151. localstack/services/cloudformation/engine/v2/change_set_model_describer.py +96 -17
  152. localstack/services/cloudformation/engine/v2/change_set_model_executor.py +289 -136
  153. localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +315 -146
  154. localstack/services/cloudformation/engine/v2/change_set_model_transform.py +380 -105
  155. localstack/services/cloudformation/engine/v2/change_set_model_validator.py +183 -0
  156. localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +6 -0
  157. localstack/services/cloudformation/engine/v2/resolving.py +102 -0
  158. localstack/services/cloudformation/engine/yaml_parser.py +9 -2
  159. localstack/services/cloudformation/provider.py +11 -6
  160. localstack/services/cloudformation/provider_utils.py +34 -4
  161. localstack/services/cloudformation/resource_provider.py +31 -21
  162. localstack/services/cloudformation/resource_providers/aws_cloudformation_macro.py +7 -7
  163. localstack/services/cloudformation/resource_providers/aws_cloudformation_macro_plugin.py +1 -3
  164. localstack/services/cloudformation/resource_providers/aws_cloudformation_stack.py +9 -9
  165. localstack/services/cloudformation/resource_providers/aws_cloudformation_stack_plugin.py +1 -3
  166. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition.py +6 -6
  167. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition_plugin.py +1 -3
  168. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle.py +2 -2
  169. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle_plugin.py +1 -3
  170. localstack/services/cloudformation/resources.py +24149 -0
  171. localstack/services/cloudformation/scaffolding/__main__.py +13 -12
  172. localstack/services/cloudformation/scaffolding/propgen.py +2 -2
  173. localstack/services/cloudformation/service_models.py +2 -2
  174. localstack/services/cloudformation/stores.py +33 -22
  175. localstack/services/cloudformation/v2/entities.py +103 -88
  176. localstack/services/cloudformation/v2/provider.py +872 -131
  177. localstack/services/cloudformation/v2/types.py +38 -0
  178. localstack/services/cloudformation/v2/utils.py +4 -1
  179. localstack/services/cloudwatch/alarm_scheduler.py +11 -8
  180. localstack/services/cloudwatch/cloudwatch_database_helper.py +4 -5
  181. localstack/services/cloudwatch/models.py +5 -7
  182. localstack/services/cloudwatch/provider.py +30 -25
  183. localstack/services/cloudwatch/provider_v2.py +27 -32
  184. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.py +40 -40
  185. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm_plugin.py +1 -3
  186. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm.py +12 -12
  187. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm_plugin.py +1 -3
  188. localstack/services/dynamodb/packages.py +3 -3
  189. localstack/services/dynamodb/provider.py +159 -18
  190. localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable.py +63 -63
  191. localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable_plugin.py +1 -3
  192. localstack/services/dynamodb/resource_providers/aws_dynamodb_table.py +57 -57
  193. localstack/services/dynamodb/resource_providers/aws_dynamodb_table_plugin.py +1 -3
  194. localstack/services/dynamodb/server.py +2 -2
  195. localstack/services/dynamodb/utils.py +13 -14
  196. localstack/services/dynamodb/v2/provider.py +157 -18
  197. localstack/services/dynamodbstreams/dynamodbstreams_api.py +2 -2
  198. localstack/services/dynamodbstreams/models.py +1 -3
  199. localstack/services/ec2/patches.py +26 -5
  200. localstack/services/ec2/provider.py +3 -3
  201. localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions.py +10 -10
  202. localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions_plugin.py +1 -3
  203. localstack/services/ec2/resource_providers/aws_ec2_instance.py +96 -96
  204. localstack/services/ec2/resource_providers/aws_ec2_instance_plugin.py +1 -3
  205. localstack/services/ec2/resource_providers/aws_ec2_internetgateway.py +5 -5
  206. localstack/services/ec2/resource_providers/aws_ec2_internetgateway_plugin.py +1 -3
  207. localstack/services/ec2/resource_providers/aws_ec2_keypair.py +10 -10
  208. localstack/services/ec2/resource_providers/aws_ec2_keypair_plugin.py +1 -3
  209. localstack/services/ec2/resource_providers/aws_ec2_natgateway.py +13 -13
  210. localstack/services/ec2/resource_providers/aws_ec2_natgateway_plugin.py +1 -3
  211. localstack/services/ec2/resource_providers/aws_ec2_networkacl.py +6 -6
  212. localstack/services/ec2/resource_providers/aws_ec2_networkacl_plugin.py +1 -3
  213. localstack/services/ec2/resource_providers/aws_ec2_prefixlist.py +14 -14
  214. localstack/services/ec2/resource_providers/aws_ec2_prefixlist_plugin.py +1 -3
  215. localstack/services/ec2/resource_providers/aws_ec2_route.py +15 -15
  216. localstack/services/ec2/resource_providers/aws_ec2_route_plugin.py +1 -3
  217. localstack/services/ec2/resource_providers/aws_ec2_routetable.py +6 -6
  218. localstack/services/ec2/resource_providers/aws_ec2_routetable_plugin.py +1 -3
  219. localstack/services/ec2/resource_providers/aws_ec2_securitygroup.py +29 -29
  220. localstack/services/ec2/resource_providers/aws_ec2_securitygroup_plugin.py +1 -3
  221. localstack/services/ec2/resource_providers/aws_ec2_subnet.py +19 -19
  222. localstack/services/ec2/resource_providers/aws_ec2_subnet_plugin.py +1 -3
  223. localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation.py +4 -4
  224. localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation_plugin.py +1 -3
  225. localstack/services/ec2/resource_providers/aws_ec2_transitgateway.py +16 -16
  226. localstack/services/ec2/resource_providers/aws_ec2_transitgateway_plugin.py +1 -3
  227. localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment.py +9 -9
  228. localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment_plugin.py +1 -3
  229. localstack/services/ec2/resource_providers/aws_ec2_vpc.py +15 -15
  230. localstack/services/ec2/resource_providers/aws_ec2_vpc_plugin.py +1 -3
  231. localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint.py +29 -22
  232. localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint_plugin.py +1 -3
  233. localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment.py +5 -5
  234. localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment_plugin.py +1 -3
  235. localstack/services/ecr/resource_providers/aws_ecr_repository.py +22 -19
  236. localstack/services/ecr/resource_providers/aws_ecr_repository_plugin.py +1 -3
  237. localstack/services/edge.py +6 -6
  238. localstack/services/es/provider.py +21 -21
  239. localstack/services/events/archive.py +2 -2
  240. localstack/services/events/connection.py +5 -5
  241. localstack/services/events/event_bus.py +9 -9
  242. localstack/services/events/event_rule_engine.py +31 -13
  243. localstack/services/events/models.py +29 -30
  244. localstack/services/events/provider.py +29 -26
  245. localstack/services/events/replay.py +3 -3
  246. localstack/services/events/resource_providers/aws_events_apidestination.py +8 -8
  247. localstack/services/events/resource_providers/aws_events_apidestination_plugin.py +1 -3
  248. localstack/services/events/resource_providers/aws_events_connection.py +27 -27
  249. localstack/services/events/resource_providers/aws_events_connection_plugin.py +1 -3
  250. localstack/services/events/resource_providers/aws_events_eventbus.py +9 -9
  251. localstack/services/events/resource_providers/aws_events_eventbus_plugin.py +1 -3
  252. localstack/services/events/resource_providers/aws_events_eventbuspolicy.py +11 -11
  253. localstack/services/events/resource_providers/aws_events_eventbuspolicy_plugin.py +1 -3
  254. localstack/services/events/resource_providers/aws_events_rule.py +82 -82
  255. localstack/services/events/resource_providers/aws_events_rule_plugin.py +1 -3
  256. localstack/services/events/rule.py +15 -15
  257. localstack/services/events/target.py +21 -13
  258. localstack/services/events/utils.py +7 -7
  259. localstack/services/events/v1/models.py +1 -3
  260. localstack/services/events/v1/provider.py +15 -15
  261. localstack/services/firehose/models.py +1 -3
  262. localstack/services/firehose/provider.py +25 -16
  263. localstack/services/iam/iam_patches.py +5 -6
  264. localstack/services/iam/provider.py +14 -119
  265. localstack/services/iam/resource_providers/aws_iam_accesskey.py +6 -6
  266. localstack/services/iam/resource_providers/aws_iam_accesskey_plugin.py +1 -3
  267. localstack/services/iam/resource_providers/aws_iam_group.py +9 -9
  268. localstack/services/iam/resource_providers/aws_iam_group_plugin.py +1 -3
  269. localstack/services/iam/resource_providers/aws_iam_instanceprofile.py +5 -5
  270. localstack/services/iam/resource_providers/aws_iam_instanceprofile_plugin.py +1 -3
  271. localstack/services/iam/resource_providers/aws_iam_managedpolicy.py +9 -9
  272. localstack/services/iam/resource_providers/aws_iam_managedpolicy_plugin.py +1 -3
  273. localstack/services/iam/resource_providers/aws_iam_policy.py +7 -7
  274. localstack/services/iam/resource_providers/aws_iam_policy_plugin.py +1 -3
  275. localstack/services/iam/resource_providers/aws_iam_role.py +16 -16
  276. localstack/services/iam/resource_providers/aws_iam_role_plugin.py +1 -3
  277. localstack/services/iam/resource_providers/aws_iam_servercertificate.py +10 -10
  278. localstack/services/iam/resource_providers/aws_iam_servercertificate_plugin.py +1 -3
  279. localstack/services/iam/resource_providers/aws_iam_servicelinkedrole.py +5 -5
  280. localstack/services/iam/resource_providers/aws_iam_servicelinkedrole_plugin.py +1 -3
  281. localstack/services/iam/resource_providers/aws_iam_user.py +17 -17
  282. localstack/services/iam/resource_providers/aws_iam_user_plugin.py +1 -3
  283. localstack/services/iam/resources/policy_simulator.py +133 -0
  284. localstack/services/kinesis/kinesis_mock_server.py +7 -8
  285. localstack/services/kinesis/models.py +17 -5
  286. localstack/services/kinesis/packages.py +3 -3
  287. localstack/services/kinesis/provider.py +86 -3
  288. localstack/services/kinesis/resource_providers/aws_kinesis_stream.py +13 -13
  289. localstack/services/kinesis/resource_providers/aws_kinesis_stream_plugin.py +1 -3
  290. localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer.py +7 -7
  291. localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer_plugin.py +1 -3
  292. localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream.py +191 -191
  293. localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream_plugin.py +1 -3
  294. localstack/services/kms/models.py +21 -18
  295. localstack/services/kms/provider.py +62 -26
  296. localstack/services/kms/resource_providers/aws_kms_alias.py +3 -3
  297. localstack/services/kms/resource_providers/aws_kms_alias_plugin.py +1 -3
  298. localstack/services/kms/resource_providers/aws_kms_key.py +14 -14
  299. localstack/services/kms/resource_providers/aws_kms_key_plugin.py +1 -3
  300. localstack/services/kms/utils.py +4 -3
  301. localstack/services/lambda_/api_utils.py +19 -16
  302. localstack/services/lambda_/custom_endpoints.py +2 -2
  303. localstack/services/lambda_/event_source_mapping/esm_worker_factory.py +4 -7
  304. localstack/services/lambda_/event_source_mapping/pipe_utils.py +2 -2
  305. localstack/services/lambda_/event_source_mapping/pollers/stream_poller.py +1 -1
  306. localstack/services/lambda_/event_source_mapping/senders/sender_utils.py +2 -1
  307. localstack/services/lambda_/hooks.py +6 -1
  308. localstack/services/lambda_/invocation/assignment.py +1 -2
  309. localstack/services/lambda_/invocation/docker_runtime_executor.py +7 -11
  310. localstack/services/lambda_/invocation/event_manager.py +1 -1
  311. localstack/services/lambda_/invocation/execution_environment.py +4 -4
  312. localstack/services/lambda_/invocation/executor_endpoint.py +8 -11
  313. localstack/services/lambda_/invocation/internal_sqs_queue.py +6 -10
  314. localstack/services/lambda_/invocation/lambda_models.py +33 -30
  315. localstack/services/lambda_/invocation/lambda_service.py +12 -5
  316. localstack/services/lambda_/invocation/logs.py +2 -3
  317. localstack/services/lambda_/invocation/runtime_executor.py +3 -3
  318. localstack/services/lambda_/invocation/version_manager.py +31 -8
  319. localstack/services/lambda_/ldm.py +14 -0
  320. localstack/services/lambda_/packages.py +3 -4
  321. localstack/services/lambda_/provider.py +9 -26
  322. localstack/services/lambda_/provider_utils.py +1 -1
  323. localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig.py +8 -8
  324. localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig_plugin.py +1 -3
  325. localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig.py +11 -11
  326. localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig_plugin.py +1 -3
  327. localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping.py +39 -39
  328. localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping_plugin.py +1 -3
  329. localstack/services/lambda_/resource_providers/aws_lambda_function.py +54 -54
  330. localstack/services/lambda_/resource_providers/aws_lambda_function_plugin.py +1 -3
  331. localstack/services/lambda_/resource_providers/aws_lambda_layerversion.py +11 -11
  332. localstack/services/lambda_/resource_providers/aws_lambda_layerversion_plugin.py +1 -3
  333. localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission.py +6 -6
  334. localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission_plugin.py +1 -3
  335. localstack/services/lambda_/resource_providers/aws_lambda_permission.py +10 -10
  336. localstack/services/lambda_/resource_providers/aws_lambda_permission_plugin.py +1 -3
  337. localstack/services/lambda_/resource_providers/aws_lambda_url.py +15 -15
  338. localstack/services/lambda_/resource_providers/aws_lambda_url_plugin.py +1 -3
  339. localstack/services/lambda_/resource_providers/aws_lambda_version.py +8 -8
  340. localstack/services/lambda_/resource_providers/aws_lambda_version_plugin.py +1 -3
  341. localstack/services/lambda_/resource_providers/lambda_alias.py +12 -12
  342. localstack/services/lambda_/resource_providers/lambda_alias_plugin.py +1 -3
  343. localstack/services/lambda_/runtimes.py +1 -3
  344. localstack/services/lambda_/urlrouter.py +14 -1
  345. localstack/services/logs/models.py +1 -3
  346. localstack/services/logs/provider.py +39 -22
  347. localstack/services/logs/resource_providers/aws_logs_loggroup.py +9 -9
  348. localstack/services/logs/resource_providers/aws_logs_loggroup_plugin.py +1 -3
  349. localstack/services/logs/resource_providers/aws_logs_logstream.py +4 -4
  350. localstack/services/logs/resource_providers/aws_logs_logstream_plugin.py +1 -3
  351. localstack/services/logs/resource_providers/aws_logs_subscriptionfilter.py +7 -7
  352. localstack/services/logs/resource_providers/aws_logs_subscriptionfilter_plugin.py +1 -3
  353. localstack/services/moto.py +5 -4
  354. localstack/services/opensearch/cluster.py +28 -20
  355. localstack/services/opensearch/cluster_manager.py +13 -14
  356. localstack/services/opensearch/models.py +1 -3
  357. localstack/services/opensearch/packages.py +27 -9
  358. localstack/services/opensearch/provider.py +15 -10
  359. localstack/services/opensearch/resource_providers/aws_elasticsearch_domain.py +61 -61
  360. localstack/services/opensearch/resource_providers/aws_elasticsearch_domain_plugin.py +1 -3
  361. localstack/services/opensearch/resource_providers/aws_opensearchservice_domain.py +89 -89
  362. localstack/services/opensearch/resource_providers/aws_opensearchservice_domain_plugin.py +1 -3
  363. localstack/services/opensearch/versions.py +57 -10
  364. localstack/services/plugins.py +37 -32
  365. localstack/services/providers.py +10 -2
  366. localstack/services/redshift/provider.py +0 -21
  367. localstack/services/redshift/resource_providers/aws_redshift_cluster.py +57 -57
  368. localstack/services/redshift/resource_providers/aws_redshift_cluster_plugin.py +1 -3
  369. localstack/services/resource_groups/resource_providers/aws_resourcegroups_group.py +21 -21
  370. localstack/services/resource_groups/resource_providers/aws_resourcegroups_group_plugin.py +1 -3
  371. localstack/services/route53/models.py +1 -3
  372. localstack/services/route53/provider.py +1 -2
  373. localstack/services/route53/resource_providers/aws_route53_healthcheck.py +6 -6
  374. localstack/services/route53/resource_providers/aws_route53_healthcheck_plugin.py +1 -3
  375. localstack/services/route53/resource_providers/aws_route53_recordset.py +27 -27
  376. localstack/services/route53/resource_providers/aws_route53_recordset_plugin.py +1 -3
  377. localstack/services/route53resolver/models.py +8 -10
  378. localstack/services/route53resolver/provider.py +12 -12
  379. localstack/services/s3/codec.py +2 -2
  380. localstack/services/s3/constants.py +5 -2
  381. localstack/services/s3/cors.py +8 -8
  382. localstack/services/s3/models.py +73 -73
  383. localstack/services/s3/notifications.py +74 -58
  384. localstack/services/s3/presigned_url.py +41 -59
  385. localstack/services/s3/provider.py +86 -29
  386. localstack/services/s3/resource_providers/aws_s3_bucket.py +180 -180
  387. localstack/services/s3/resource_providers/aws_s3_bucket_plugin.py +1 -3
  388. localstack/services/s3/resource_providers/aws_s3_bucketpolicy.py +4 -4
  389. localstack/services/s3/resource_providers/aws_s3_bucketpolicy_plugin.py +1 -3
  390. localstack/services/s3/storage/core.py +4 -3
  391. localstack/services/s3/storage/ephemeral.py +7 -6
  392. localstack/services/s3/utils.py +51 -31
  393. localstack/services/s3/validation.py +47 -33
  394. localstack/services/s3/website_hosting.py +9 -7
  395. localstack/services/scheduler/resource_providers/aws_scheduler_schedule.py +60 -60
  396. localstack/services/scheduler/resource_providers/aws_scheduler_schedule_plugin.py +1 -3
  397. localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup.py +9 -9
  398. localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup_plugin.py +1 -3
  399. localstack/services/secretsmanager/provider.py +10 -12
  400. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy.py +5 -5
  401. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy_plugin.py +1 -3
  402. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule.py +21 -21
  403. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule_plugin.py +1 -3
  404. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret.py +23 -23
  405. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret_plugin.py +1 -3
  406. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment.py +5 -5
  407. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment_plugin.py +1 -3
  408. localstack/services/ses/models.py +8 -1
  409. localstack/services/ses/provider.py +128 -55
  410. localstack/services/ses/resource_providers/aws_ses_emailidentity.py +21 -21
  411. localstack/services/ses/resource_providers/aws_ses_emailidentity_plugin.py +1 -3
  412. localstack/services/sns/constants.py +7 -1
  413. localstack/services/sns/executor.py +9 -2
  414. localstack/services/sns/models.py +25 -25
  415. localstack/services/sns/provider.py +9 -7
  416. localstack/services/sns/publisher.py +37 -23
  417. localstack/services/sns/resource_providers/aws_sns_subscription.py +13 -13
  418. localstack/services/sns/resource_providers/aws_sns_subscription_plugin.py +1 -3
  419. localstack/services/sns/resource_providers/aws_sns_topic.py +16 -16
  420. localstack/services/sns/resource_providers/aws_sns_topic_plugin.py +1 -3
  421. localstack/services/sns/resource_providers/aws_sns_topicpolicy.py +4 -4
  422. localstack/services/sns/resource_providers/aws_sns_topicpolicy_plugin.py +1 -3
  423. localstack/services/sns/v2/models.py +167 -0
  424. localstack/services/sns/v2/provider.py +867 -0
  425. localstack/services/sns/v2/utils.py +130 -0
  426. localstack/services/sqs/constants.py +2 -2
  427. localstack/services/sqs/developer_api.py +205 -0
  428. localstack/services/sqs/models.py +71 -36
  429. localstack/services/sqs/provider.py +56 -332
  430. localstack/services/sqs/query_api.py +8 -5
  431. localstack/services/sqs/resource_providers/aws_sqs_queue.py +21 -21
  432. localstack/services/sqs/resource_providers/aws_sqs_queue_plugin.py +1 -3
  433. localstack/services/sqs/resource_providers/aws_sqs_queuepolicy.py +7 -5
  434. localstack/services/sqs/resource_providers/aws_sqs_queuepolicy_plugin.py +1 -3
  435. localstack/services/sqs/utils.py +123 -4
  436. localstack/services/ssm/provider.py +3 -4
  437. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow.py +15 -15
  438. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow_plugin.py +1 -3
  439. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget.py +10 -10
  440. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget_plugin.py +1 -3
  441. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask.py +48 -48
  442. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask_plugin.py +1 -3
  443. localstack/services/ssm/resource_providers/aws_ssm_parameter.py +10 -10
  444. localstack/services/ssm/resource_providers/aws_ssm_parameter_plugin.py +1 -3
  445. localstack/services/ssm/resource_providers/aws_ssm_patchbaseline.py +29 -29
  446. localstack/services/ssm/resource_providers/aws_ssm_patchbaseline_plugin.py +1 -3
  447. localstack/services/stepfunctions/asl/antlt4utils/antlr4utils.py +3 -4
  448. localstack/services/stepfunctions/asl/component/common/assign/assign_decl.py +1 -1
  449. localstack/services/stepfunctions/asl/component/common/assign/assign_decl_binding.py +1 -1
  450. localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_array.py +1 -1
  451. localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_object.py +1 -1
  452. localstack/services/stepfunctions/asl/component/common/catch/catcher_decl.py +9 -9
  453. localstack/services/stepfunctions/asl/component/common/error_name/custom_error_name.py +2 -2
  454. localstack/services/stepfunctions/asl/component/common/error_name/error_name.py +4 -4
  455. localstack/services/stepfunctions/asl/component/common/error_name/failure_event.py +8 -8
  456. localstack/services/stepfunctions/asl/component/common/error_name/states_error_name_type.py +1 -1
  457. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_binding.py +2 -2
  458. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_array.py +1 -1
  459. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_object.py +1 -1
  460. localstack/services/stepfunctions/asl/component/common/path/input_path.py +4 -4
  461. localstack/services/stepfunctions/asl/component/common/path/output_path.py +4 -4
  462. localstack/services/stepfunctions/asl/component/common/path/result_path.py +3 -3
  463. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadarr/payload_arr.py +1 -1
  464. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding.py +3 -3
  465. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadtmpl/payload_tmpl.py +1 -1
  466. localstack/services/stepfunctions/asl/component/common/retry/retrier_decl.py +8 -8
  467. localstack/services/stepfunctions/asl/component/common/string/string_expression.py +3 -3
  468. localstack/services/stepfunctions/asl/component/common/timeouts/timeout.py +3 -3
  469. localstack/services/stepfunctions/asl/component/eval_component.py +2 -3
  470. localstack/services/stepfunctions/asl/component/intrinsic/argument/argument.py +4 -4
  471. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/array/array_partition.py +1 -1
  472. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/generic/string_format.py +1 -1
  473. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_array.py +1 -1
  474. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_format.py +1 -1
  475. localstack/services/stepfunctions/asl/component/intrinsic/jsonata.py +3 -3
  476. localstack/services/stepfunctions/asl/component/intrinsic/member.py +1 -1
  477. localstack/services/stepfunctions/asl/component/program/program.py +9 -9
  478. localstack/services/stepfunctions/asl/component/program/states.py +1 -1
  479. localstack/services/stepfunctions/asl/component/state/state.py +10 -11
  480. localstack/services/stepfunctions/asl/component/state/state_choice/choice_rule.py +11 -11
  481. localstack/services/stepfunctions/asl/component/state/state_choice/comparison/comparison.py +5 -11
  482. localstack/services/stepfunctions/asl/component/state/state_choice/comparison/operator/implementations/is_operator.py +2 -2
  483. localstack/services/stepfunctions/asl/component/state/state_choice/state_choice.py +3 -5
  484. localstack/services/stepfunctions/asl/component/state/state_execution/execute_state.py +9 -9
  485. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/item_reader_decl.py +7 -7
  486. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/reader_config/reader_config_decl.py +5 -5
  487. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_eval_s3.py +2 -1
  488. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_output_transformer/resource_output_transformer_csv.py +2 -2
  489. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/distributed_iteration_component.py +8 -8
  490. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/inline_iteration_component.py +7 -7
  491. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/distributed_item_processor_worker.py +4 -4
  492. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/inline_item_processor_worker.py +5 -5
  493. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/map_run_record.py +10 -10
  494. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_component.py +3 -3
  495. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_declaration.py +3 -3
  496. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_worker.py +2 -2
  497. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/distributed_iterator_worker.py +3 -5
  498. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator.py +1 -2
  499. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator_worker.py +5 -5
  500. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/job.py +9 -9
  501. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/result_writer/resource_eval/resource_eval_s3.py +2 -1
  502. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/state_map.py +12 -13
  503. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branch_worker.py +3 -3
  504. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branches_decl.py +7 -7
  505. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/state_parallel.py +2 -3
  506. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/lambda_eval_utils.py +7 -7
  507. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/resource.py +3 -3
  508. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service.py +10 -10
  509. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_api_gateway.py +18 -18
  510. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_aws_sdk.py +1 -1
  511. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_batch.py +8 -7
  512. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_callback.py +18 -17
  513. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_dynamodb.py +2 -2
  514. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_ecs.py +5 -4
  515. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_events.py +4 -4
  516. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_glue.py +7 -6
  517. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_lambda.py +4 -4
  518. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sfn.py +9 -8
  519. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sns.py +2 -2
  520. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sqs.py +4 -4
  521. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task.py +5 -5
  522. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task_lambda.py +2 -2
  523. localstack/services/stepfunctions/asl/component/state/state_fail/state_fail.py +3 -5
  524. localstack/services/stepfunctions/asl/component/state/state_pass/state_pass.py +5 -7
  525. localstack/services/stepfunctions/asl/component/state/state_succeed/state_succeed.py +1 -1
  526. localstack/services/stepfunctions/asl/component/state/state_wait/state_wait.py +1 -1
  527. localstack/services/stepfunctions/asl/component/state/state_wait/wait_function/timestamp.py +2 -2
  528. localstack/services/stepfunctions/asl/eval/callback/callback.py +18 -18
  529. localstack/services/stepfunctions/asl/eval/environment.py +22 -24
  530. localstack/services/stepfunctions/asl/eval/evaluation_details.py +3 -5
  531. localstack/services/stepfunctions/asl/eval/event/event_manager.py +10 -10
  532. localstack/services/stepfunctions/asl/eval/event/logging.py +3 -3
  533. localstack/services/stepfunctions/asl/eval/program_state.py +8 -8
  534. localstack/services/stepfunctions/asl/eval/states.py +12 -12
  535. localstack/services/stepfunctions/asl/eval/test_state/environment.py +3 -5
  536. localstack/services/stepfunctions/asl/eval/variable_store.py +6 -6
  537. localstack/services/stepfunctions/asl/jsonata/jsonata.py +7 -6
  538. localstack/services/stepfunctions/asl/parse/asl_parser.py +1 -1
  539. localstack/services/stepfunctions/asl/parse/intrinsic/preprocessor.py +2 -3
  540. localstack/services/stepfunctions/asl/parse/preprocessor.py +44 -44
  541. localstack/services/stepfunctions/asl/parse/typed_props.py +2 -2
  542. localstack/services/stepfunctions/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py +1 -1
  543. localstack/services/stepfunctions/asl/static_analyser/variable_references_static_analyser.py +2 -2
  544. localstack/services/stepfunctions/asl/utils/encoding.py +2 -2
  545. localstack/services/stepfunctions/asl/utils/json_path.py +2 -2
  546. localstack/services/stepfunctions/backend/activity.py +4 -4
  547. localstack/services/stepfunctions/backend/alias.py +8 -8
  548. localstack/services/stepfunctions/backend/execution.py +29 -30
  549. localstack/services/stepfunctions/backend/execution_worker.py +7 -7
  550. localstack/services/stepfunctions/backend/state_machine.py +28 -28
  551. localstack/services/stepfunctions/backend/test_state/execution.py +3 -4
  552. localstack/services/stepfunctions/backend/test_state/execution_worker.py +1 -3
  553. localstack/services/stepfunctions/mocking/mock_config.py +9 -9
  554. localstack/services/stepfunctions/mocking/mock_config_file.py +10 -10
  555. localstack/services/stepfunctions/packages.py +14 -5
  556. localstack/services/stepfunctions/provider.py +34 -44
  557. localstack/services/stepfunctions/quotas.py +2 -3
  558. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity.py +6 -6
  559. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity_plugin.py +1 -3
  560. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py +25 -25
  561. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine_plugin.py +1 -3
  562. localstack/services/stepfunctions/stepfunctions_utils.py +1 -2
  563. localstack/services/stores.py +8 -8
  564. localstack/services/transcribe/packages.py +1 -3
  565. localstack/services/transcribe/provider.py +8 -3
  566. localstack/state/codecs.py +61 -0
  567. localstack/state/core.py +11 -5
  568. localstack/state/inspect.py +4 -4
  569. localstack/state/pickle.py +36 -23
  570. localstack/testing/aws/asf_utils.py +3 -2
  571. localstack/testing/aws/cloudformation_utils.py +1 -1
  572. localstack/testing/aws/lambda_utils.py +15 -14
  573. localstack/testing/aws/util.py +3 -2
  574. localstack/testing/pytest/cloudformation/fixtures.py +68 -18
  575. localstack/testing/pytest/container.py +5 -5
  576. localstack/testing/pytest/filters.py +1 -3
  577. localstack/testing/pytest/fixtures.py +188 -49
  578. localstack/testing/pytest/in_memory_localstack.py +1 -3
  579. localstack/testing/pytest/marking.py +42 -15
  580. localstack/testing/pytest/path_filter.py +1 -1
  581. localstack/testing/pytest/stepfunctions/fixtures.py +4 -4
  582. localstack/testing/pytest/stepfunctions/utils.py +11 -10
  583. localstack/testing/pytest/util.py +1 -1
  584. localstack/testing/pytest/validation_tracking.py +3 -4
  585. localstack/testing/scenario/provisioning.py +11 -10
  586. localstack/testing/snapshots/transformer_utility.py +8 -3
  587. localstack/testing/testselection/matching.py +2 -2
  588. localstack/testing/testselection/opt_out.py +1 -1
  589. localstack/testing/testselection/scripts/filter_by_test_selection.py +1 -1
  590. localstack/testing/testselection/scripts/generate_test_selection.py +1 -1
  591. localstack/testing/testselection/testselection.py +2 -2
  592. localstack/utils/analytics/cli.py +2 -3
  593. localstack/utils/analytics/client.py +5 -5
  594. localstack/utils/analytics/events.py +2 -2
  595. localstack/utils/analytics/metadata.py +6 -4
  596. localstack/utils/analytics/metrics/counter.py +11 -18
  597. localstack/utils/analytics/metrics/registry.py +2 -2
  598. localstack/utils/analytics/publisher.py +4 -5
  599. localstack/utils/analytics/service_providers.py +19 -0
  600. localstack/utils/analytics/service_request_aggregator.py +4 -4
  601. localstack/utils/archives.py +12 -12
  602. localstack/utils/asyncio.py +2 -2
  603. localstack/utils/aws/arns.py +26 -31
  604. localstack/utils/aws/aws_responses.py +21 -28
  605. localstack/utils/aws/aws_stack.py +7 -12
  606. localstack/utils/aws/dead_letter_queue.py +4 -9
  607. localstack/utils/aws/message_forwarding.py +8 -11
  608. localstack/utils/aws/request_context.py +5 -6
  609. localstack/utils/aws/resources.py +1 -1
  610. localstack/utils/aws/templating.py +4 -4
  611. localstack/utils/batch_policy.py +4 -4
  612. localstack/utils/bootstrap.py +37 -30
  613. localstack/utils/catalog/catalog.py +139 -0
  614. localstack/utils/catalog/catalog_loader.py +119 -0
  615. localstack/utils/catalog/common.py +58 -0
  616. localstack/utils/catalog/plugins.py +28 -0
  617. localstack/utils/cloudwatch/cloudwatch_util.py +5 -5
  618. localstack/utils/collections.py +33 -27
  619. localstack/utils/config_listener.py +2 -2
  620. localstack/utils/container_networking.py +5 -6
  621. localstack/utils/container_utils/container_client.py +156 -160
  622. localstack/utils/container_utils/docker_cmd_client.py +97 -81
  623. localstack/utils/container_utils/docker_sdk_client.py +75 -72
  624. localstack/utils/crypto.py +12 -13
  625. localstack/utils/diagnose.py +11 -12
  626. localstack/utils/docker_utils.py +11 -7
  627. localstack/utils/files.py +34 -15
  628. localstack/utils/functions.py +5 -4
  629. localstack/utils/http.py +14 -14
  630. localstack/utils/iputils.py +2 -1
  631. localstack/utils/json.py +21 -7
  632. localstack/utils/kinesis/kinesis_connector.py +2 -1
  633. localstack/utils/net.py +25 -17
  634. localstack/utils/no_exit_argument_parser.py +2 -2
  635. localstack/utils/numbers.py +9 -2
  636. localstack/utils/objects.py +15 -14
  637. localstack/utils/patch.py +14 -7
  638. localstack/utils/platform.py +2 -2
  639. localstack/utils/run.py +15 -14
  640. localstack/utils/scheduler.py +13 -12
  641. localstack/utils/server/tcp_proxy.py +2 -2
  642. localstack/utils/serving.py +3 -4
  643. localstack/utils/strings.py +15 -16
  644. localstack/utils/sync.py +126 -1
  645. localstack/utils/tagging.py +10 -8
  646. localstack/utils/testutil.py +17 -17
  647. localstack/utils/threads.py +3 -3
  648. localstack/utils/time.py +12 -4
  649. localstack/utils/urls.py +1 -3
  650. localstack/utils/xml.py +1 -1
  651. localstack/utils/xray/traceid.py +1 -1
  652. localstack/version.py +16 -3
  653. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/METADATA +18 -13
  654. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/RECORD +663 -655
  655. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/entry_points.txt +8 -4
  656. localstack_core-4.10.1.dev12.dist-info/plux.json +1 -0
  657. localstack/packages/terraform.py +0 -47
  658. localstack/services/cloudformation/deploy.html +0 -144
  659. localstack/services/cloudformation/deploy_ui.py +0 -47
  660. localstack/services/cloudformation/plugins.py +0 -12
  661. localstack/services/lambda_/lambda_debug_mode/ldm.py +0 -375
  662. localstack/services/lambda_/lambda_debug_mode/ldm_config_file.py +0 -178
  663. localstack/services/lambda_/lambda_debug_mode/ldm_types.py +0 -11
  664. localstack/services/lambda_/lambda_debug_mode/ldm_utils.py +0 -43
  665. localstack_core-4.6.1.dev60.dist-info/plux.json +0 -1
  666. /localstack/{services/lambda_/lambda_debug_mode/__init__.py → testing/pytest/cloudformation/transformers.py} +0 -0
  667. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack +0 -0
  668. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack-supervisor +0 -0
  669. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack.bat +0 -0
  670. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/WHEEL +0 -0
  671. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/licenses/LICENSE.txt +0 -0
  672. {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 = 262144
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: Optional[int]
57
- receipt_handles: Set[str]
58
- last_received: Optional[float]
59
- first_received: Optional[float]
60
- visibility_deadline: Optional[float]
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) -> Optional[str]:
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) -> Optional[str]:
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) -> Optional[str]:
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 visibile or not.
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: Optional[float]
314
+ purge_timestamp: float | None
276
315
 
277
- delayed: Set[SqsMessage]
278
- inflight: Set[SqsMessage]
279
- receipts: Dict[str, SqsMessage]
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) -> Optional[dict]:
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) -> Optional[int]:
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: Dict[QueueAttributeName, str] = {}
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: Set[SqsMessage]
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(time.time(), message)
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: Dict[str, SqsMessage]
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(FifoQueue, self).update_delay_seconds(value)
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
- _, _, _, last_received = extract_receipt_handle_info(receipt_handle)
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
- if delay_seconds is not None:
1071
- fifo_message.delay_seconds = delay_seconds
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: Set[MessageGroup] = set()
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: Dict[str, SqsQueue] = LocalAttribute(default=dict)
1353
+ queues: dict[str, SqsQueue] = LocalAttribute(default=dict)
1319
1354
 
1320
- deleted: Dict[str, float] = LocalAttribute(default=dict)
1355
+ deleted: dict[str, float] = LocalAttribute(default=dict)
1321
1356
 
1322
- move_tasks: Dict[str, MessageMoveTask] = LocalAttribute(default=dict)
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):