aws_advanced_ruby_driver_wrapper 1.0.0 → 1.1.0

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -2
  3. data/README.md +115 -6
  4. data/THIRD-PARTY-LICENSES +70 -11
  5. data/aws_advanced_ruby_driver_wrapper.gemspec +9 -0
  6. data/lib/aws_advanced_ruby_driver_wrapper/active_record/aws_action_cable_postgresql_support.rb +40 -0
  7. data/lib/aws_advanced_ruby_driver_wrapper/active_record/aws_connection_handler.rb +47 -0
  8. data/lib/aws_advanced_ruby_driver_wrapper/active_record/aws_mysql2_adapter.rb +23 -9
  9. data/lib/aws_advanced_ruby_driver_wrapper/active_record/aws_postgresql_adapter.rb +65 -10
  10. data/lib/aws_advanced_ruby_driver_wrapper/active_record/aws_trilogy_adapter.rb +80 -0
  11. data/lib/aws_advanced_ruby_driver_wrapper/active_record/type_adapter_alias.rb +61 -0
  12. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/driver_dialect.rb +48 -0
  13. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/driver_dialect_manager.rb +11 -4
  14. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/mysql2_driver_dialect.rb +129 -0
  15. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/mysql_driver_dialect.rb +9 -81
  16. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/pg_driver_dialect.rb +28 -0
  17. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/trilogy_driver_dialect.rb +118 -0
  18. data/lib/aws_advanced_ruby_driver_wrapper/errors/error_handler.rb +16 -0
  19. data/lib/aws_advanced_ruby_driver_wrapper/errors/mysql_error_handler.rb +10 -5
  20. data/lib/aws_advanced_ruby_driver_wrapper/errors/trilogy_error_handler.rb +127 -0
  21. data/lib/aws_advanced_ruby_driver_wrapper/errors.rb +1 -0
  22. data/lib/aws_advanced_ruby_driver_wrapper/monitoring/cluster_topology_monitor.rb +11 -0
  23. data/lib/aws_advanced_ruby_driver_wrapper/monitoring/monitor.rb +14 -0
  24. data/lib/aws_advanced_ruby_driver_wrapper/monitoring/monitor_connection.rb +6 -0
  25. data/lib/aws_advanced_ruby_driver_wrapper/mysql.rb +27 -9
  26. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/blue_green_plugin.rb +125 -7
  27. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/drop_blue_connections_marker.rb +84 -0
  28. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/host_mapper.rb +3 -1
  29. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/base_routing.rb +7 -0
  30. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/substitute_connect_routing.rb +68 -41
  31. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/suspend_connect_routing.rb +4 -2
  32. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/suspend_execute_routing.rb +5 -3
  33. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/suspend_until_corresponding_host_found_connect_routing.rb +7 -1
  34. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_builder.rb +1 -1
  35. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_monitor.rb +10 -13
  36. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_provider.rb +95 -3
  37. data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/custom_endpoint_monitor.rb +11 -1
  38. data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/custom_endpoint_plugin.rb +4 -1
  39. data/lib/aws_advanced_ruby_driver_wrapper/plugins/default_plugin.rb +14 -3
  40. data/lib/aws_advanced_ruby_driver_wrapper/plugins/failover_plugin.rb +68 -3
  41. data/lib/aws_advanced_ruby_driver_wrapper/plugins/federated_auth/base_saml_auth_plugin.rb +266 -0
  42. data/lib/aws_advanced_ruby_driver_wrapper/plugins/federated_auth/federated_auth_plugin.rb +134 -0
  43. data/lib/aws_advanced_ruby_driver_wrapper/plugins/federated_auth/okta_auth_plugin.rb +113 -0
  44. data/lib/aws_advanced_ruby_driver_wrapper/plugins/gdb/gdb_failover_plugin.rb +30 -9
  45. data/lib/aws_advanced_ruby_driver_wrapper/plugins/iam_auth_plugin.rb +16 -2
  46. data/lib/aws_advanced_ruby_driver_wrapper/plugins/initial_connection_strategy_plugin.rb +4 -1
  47. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/key_management_utility.rb +6 -3
  48. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/key_manager.rb +13 -4
  49. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/kms_encryption_plugin.rb +29 -6
  50. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/sql/trigger_mysql.sql +108 -0
  51. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/sql/trigger_pg.sql +54 -0
  52. data/lib/aws_advanced_ruby_driver_wrapper/plugins/secrets_manager_plugin.rb +23 -1
  53. data/lib/aws_advanced_ruby_driver_wrapper/postgresql.rb +49 -23
  54. data/lib/aws_advanced_ruby_driver_wrapper/property_definition.rb +63 -1
  55. data/lib/aws_advanced_ruby_driver_wrapper/ruby_method.rb +3 -0
  56. data/lib/aws_advanced_ruby_driver_wrapper/services/dialect_service.rb +20 -7
  57. data/lib/aws_advanced_ruby_driver_wrapper/services/host_service.rb +34 -8
  58. data/lib/aws_advanced_ruby_driver_wrapper/services/monitor_service.rb +23 -4
  59. data/lib/aws_advanced_ruby_driver_wrapper/services/plugin_manager.rb +80 -29
  60. data/lib/aws_advanced_ruby_driver_wrapper/services/service_container.rb +10 -2
  61. data/lib/aws_advanced_ruby_driver_wrapper/services/service_utility.rb +4 -1
  62. data/lib/aws_advanced_ruby_driver_wrapper/trilogy.rb +167 -0
  63. data/lib/aws_advanced_ruby_driver_wrapper/utils/connection_config.rb +1 -1
  64. data/lib/aws_advanced_ruby_driver_wrapper/utils/connection_config_parser.rb +25 -15
  65. data/lib/aws_advanced_ruby_driver_wrapper/utils/events/batching_event_publisher.rb +18 -7
  66. data/lib/aws_advanced_ruby_driver_wrapper/utils/global_aurora_topology_utils.rb +2 -2
  67. data/lib/aws_advanced_ruby_driver_wrapper/utils/iam_auth_utils.rb +13 -4
  68. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/encryption_annotation_parser.rb +15 -31
  69. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/mysql_statement_analyzer.rb +55 -76
  70. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/mysql_text.rb +215 -0
  71. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/pg_statement_analyzer.rb +11 -20
  72. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/query_analysis.rb +2 -3
  73. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/sql_parser.rb +21 -14
  74. data/lib/aws_advanced_ruby_driver_wrapper/utils/retry_util.rb +2 -1
  75. data/lib/aws_advanced_ruby_driver_wrapper/utils/saml_utils.rb +133 -0
  76. data/lib/aws_advanced_ruby_driver_wrapper/utils/storage/storage_service.rb +29 -8
  77. data/lib/aws_advanced_ruby_driver_wrapper/utils/telemetry/null_telemetry.rb +89 -0
  78. data/lib/aws_advanced_ruby_driver_wrapper/utils/telemetry/open_telemetry_context.rb +124 -0
  79. data/lib/aws_advanced_ruby_driver_wrapper/utils/{ar_constants.rb → telemetry/open_telemetry_counter.rb} +19 -5
  80. data/lib/aws_advanced_ruby_driver_wrapper/utils/telemetry/open_telemetry_factory.rb +122 -0
  81. data/lib/aws_advanced_ruby_driver_wrapper/utils/telemetry/open_telemetry_gauge.rb +36 -0
  82. data/lib/aws_advanced_ruby_driver_wrapper/utils/telemetry/telemetry_const.rb +50 -0
  83. data/lib/aws_advanced_ruby_driver_wrapper/utils/telemetry/telemetry_factory.rb +143 -0
  84. data/lib/aws_advanced_ruby_driver_wrapper/utils/topology_utils.rb +9 -2
  85. data/lib/aws_advanced_ruby_driver_wrapper/version.rb +1 -1
  86. data/lib/aws_advanced_ruby_driver_wrapper.rb +47 -2
  87. metadata +57 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ab8433b9c38b4c70ea438830ccc3d870bdd56141e5be9ad28e309aad7852074
4
- data.tar.gz: bfc31bb5bbd87b1a3bb2ee416cc0208b79bd15c9e92422266822cc5a0904b0f5
3
+ metadata.gz: b3f6f4cf5575f7126636ad09c23b81a3feec7544b36c7fd3a1d13cb159f0978d
4
+ data.tar.gz: e5053d0035262786e689706ecc48788fd031c06b4144f2cc3e15e0dba2d44589
5
5
  SHA512:
6
- metadata.gz: f321a9d2942e5cef6eada081baa62f5cedc42b906b8f991ab42bb9ee55bd6323381b0aa781090427e1f4d9b5a1c6ac9d2e32aadf0e2d4dfd476dc57ef34217d1
7
- data.tar.gz: d6125a87b85478e47d4f851ff7c9d7a0a6aa6a14806575e6b77df86bff38f458c516497bc3c458abd0ccc66937fb1de1f77164d64c324bed60ee1786f7e7035d
6
+ metadata.gz: 8c3bfe267a552d4542b4b89944c76f35442ffbe1a16fde107126660b8aa0e352f932353fba29e67029db860fda83aea0c3acace10c3997a4a50b7b0bc89d0652
7
+ data.tar.gz: fe7c1b9e226219d8740daa00f0f101004e3c869044cac2b7b950a8cf6447c6ebc9ac418c2fcc30ea3c86767d72cb9091ce18c587d19fbae4663d174fd20f98b5
data/CHANGELOG.md CHANGED
@@ -3,7 +3,51 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/#semantic-versioning-200).
5
5
 
6
- ## [1.0.0] - 2026-10-02
6
+ ## [1.1.0] - 2026-11-05
7
+
8
+ ### :magic_wand: Added
9
+ - [Federated Authentication Plugin](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/federated-auth), which authenticates with Active Directory Federation Services (AD FS), exchanges the resulting SAML assertion for temporary AWS credentials via STS, and connects to the database with an RDS IAM authentication token. Enabled with the `federated_auth` plugin code ([PR #207](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/207)).
10
+ - [Okta Authentication Plugin](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/okta-auth), which uses the same SAML-to-STS flow as AD FS but against Okta, is also available via the `okta` plugin code ([PR #215](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/215)).
11
+ - [Telemetry](https://aws.github.io/aws-advanced-wrapper-docs/ruby/telemetry) through OpenTelemetry. With `enable_telemetry` set, the wrapper records traces of each wrapper call, the plugins it passes through, and the driver, plus failover, Blue/Green switchover, and authentication spans, and metrics such as failover and token fetch counts. Traces and metrics are sent wherever the application's OpenTelemetry SDK exports them. The OpenTelemetry gems are optional dependencies ([PR #220](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/220), [PR #225](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/225)).
12
+ - Support for the [`trilogy`](https://rubygems.org/gems/trilogy) MySQL driver, through the `WrapperTrilogyClient` connection class and the drop-in `aws_trilogy` ActiveRecord adapter. The KMS Encryption Plugin is not supported with `trilogy` ([PR #203](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/203)).
13
+ - The [Blue/Green Deployment plugin](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/blue-green) now invalidates connections that were opened to the old blue environment before a switchover, controlled by the new `bg_drop_blue_connections` property (default `true`). Once a switchover is confirmed, each such connection is closed the next time it is used, so with the failover plugin enabled it fails over through Blue/Green routing and raises `FailoverSuccessError` (or `TransactionStateUnknownError` inside a transaction), and without failover the driver raises its closed-connection error ([PR #223](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/223)).
14
+ - AI assistant skills for the wrapper, in the repository under [`skills/`](https://github.com/aws/aws-advanced-ruby-driver-wrapper/tree/main/skills): a [configuration assistant](https://github.com/aws/aws-advanced-ruby-driver-wrapper/tree/main/skills/ruby-wrapper-configuration-assistant) that builds a working configuration through an interview, reviews existing configurations, and answers parameter and plugin questions, and a [troubleshooting assistant](https://github.com/aws/aws-advanced-ruby-driver-wrapper/tree/main/skills/ruby-wrapper-troubleshooting-assistant) that diagnoses errors and unexpected behavior and classifies the cause as configuration, environment, wrapper bug, or not the wrapper. Both are self-contained and grounded in the wrapper source and the official Ruby docs ([PR #214](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/214), [PR #219](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/219), [PR #233](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/233), [PR #237](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/237), [PR #239](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/239)).
15
+
16
+ ### :crab: Changed
17
+ - Simplified the KMS Encryption Plugin's PostgreSQL trigger SQL to read the column's HMAC key from `key_storage` for every row. Re-run the trigger SQL from the [documentation](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/kms-encryption#postgresql-1) to update existing deployments ([PR #216](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/216)).
18
+ - The KMS Encryption Plugin's trigger SQL now ships with the gem and is stamped with its version, so deployed triggers can be checked against the version in use ([PR #218](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/218)).
19
+ - With `mysql2` (`WrapperMysql2Client` and the `aws_mysql2` ActiveRecord adapter), the failover plugin now fails over on a `read_timeout`, when MySQL 8.0.24+ disconnects a connection that exceeded `wait_timeout` (error 4031), and on a lost connection reported as error 2055 (`CR_SERVER_LOST_EXTENDED`), matching `trilogy`. Before, none of these triggered failover: a `read_timeout` raised `Mysql2::Error::TimeoutError` (`ActiveRecord::AdapterTimeout` under `aws_mysql2`), and errors 4031 and 2055 were raised as-is (`ActiveRecord::ConnectionFailed` under `aws_mysql2`, which ActiveRecord answered by reconnecting to the original endpoint and retrying queries it considers retryable). **Behavior change:** these errors now fail over and raise `FailoverSuccessError` (or `TransactionStateUnknownError` inside a transaction), which ActiveRecord does not retry. This includes:
20
+ - a query that runs longer than `read_timeout`. Set `read_timeout` higher than your slowest expected query.
21
+ - the first query on a pooled connection that sat idle longer than the server's `wait_timeout`. Raise `wait_timeout`, or have the pool reap idle connections sooner (for example with ActiveRecord's `idle_timeout`).
22
+
23
+ Lock wait timeouts (error 1205) still do not trigger failover ([PR #234](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/234)).
24
+ - Declared `bigdecimal` and `logger` as runtime dependencies, since Ruby no longer installs them by default from 3.4 (`bigdecimal`) and 4.0 (`logger`) on, and dropped the need for `base64` and the full `cgi` library. This keeps a bundle that does not otherwise include them, such as an app using the drivers without ActiveRecord, from failing to load the wrapper ([PR #224](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/224)).
25
+
26
+ ### :bug: Fixed
27
+ - Fixed the Custom Endpoint Plugin signing its RDS API calls with the default credential chain instead of the configured `aws_credentials_provider`, so a custom endpoint could not be resolved in an account reachable only through the configured credentials ([PR #205](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/205)).
28
+ - Fixed an unknown host selection strategy being accepted at configuration time and only failing later during connection use. An invalid strategy is now rejected when the connection is set up ([PR #206](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/206)).
29
+ - Fixed `iam_access_token_property_name`, `cluster_id`, and `bgd_id` not accepting YAML-typed (non-string) values from `database.yml`, such as a numeric `cluster_id` ([PR #209](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/209)).
30
+ - Fixed the block form of `pg`'s `exec`, `query`, `exec_params`, and `exec_prepared` not working through `WrapperPgConnection`. The wrapper now yields the result to the block, clears it when the block returns, and returns the block's value, matching `pg` ([PR #221](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/221)).
31
+ - Fixed the cluster topology and custom endpoint monitors stopping when their stored data was read, which could leave the wrapper with a stale topology so failover could not find the new writer ([PR #226](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/226)).
32
+ - Fixed the KMS Encryption Plugin matching MySQL placeholders to the wrong encrypted columns when the statement contained comments, so values could be encrypted against the wrong column ([PR #227](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/227)).
33
+ - Fixed several ActiveRecord error-handling gaps: a `nil` connection is now recognized as a connection error; a `pg` IAM authentication failure is classified as a connection error rather than `ActiveRecord::NoDatabaseError`; `trilogy` schema errors are identified correctly; and `ping` and `close` now match the underlying driver's behavior ([PR #228](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/228)).
34
+
35
+ ## [1.0.1] - 2026-10-07
36
+
37
+ ### :bug: Fixed
38
+ - Fixed the `aws_postgresql` ActiveRecord adapter passing ActiveRecord-only `database.yml` keys, such as the Rails 8.1 pool settings (`max_connections`, `min_connections`, `keepalive`, `max_age`) and multi-database settings (`replica`, `migrations_paths`, `database_tasks`), to `pg`, which rejected them with `PG::Error: invalid connection option` ([PR #191](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/191)).
39
+ - Fixed the `aws_mysql2` ActiveRecord adapter dropping the `flags`, `encoding`, `socket`, and `reconnect` client options, which removed ActiveRecord's `FOUND_ROWS` flag so that statements such as `update_all` reported changed rows instead of matched rows ([PR #193](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/193)).
40
+ - Fixed the `aws_postgresql` and `aws_mysql2` ActiveRecord adapters not translating connection errors the way the standard adapters do, so a missing database was not reported as `ActiveRecord::NoDatabaseError` and `db:prepare` (and `bin/setup`) failed instead of creating it ([PR #193](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/193)).
41
+ - Fixed the `aws_postgresql` and `aws_mysql2` ActiveRecord adapters keeping ActiveRecord's prepared statement cache after a successful failover, so every query prepared before the failover failed on that connection with `Method invoked against old connection` until the process restarted ([PR #194](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/194), [documentation](https://aws.github.io/aws-advanced-wrapper-docs/ruby/enhanced-failover)).
42
+ - Fixed `db:drop`, `db:reset`, and `db:test:prepare` failing on Aurora PostgreSQL with `database "<name>" is being accessed by other users`. The same error occurred when running `bin/rails test` after a schema change. The cause was the wrapper's topology and Blue/Green monitors, which kept their own connections open to the database being dropped. The wrapper now stops these monitors before dropping a database and when ActiveRecord clears all its connections ([PR #195](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/195)).
43
+ - Fixed forked processes, such as Puma workers with `preload_app!`, Unicorn workers, and Resque jobs, inheriting the parent's background monitors after their threads had stopped, so the cluster topology never refreshed in the child and failover there could not find the new writer. A forked child now starts its own monitors and leaves the parent's monitoring connections open. A forked child also no longer waits on a Secrets Manager fetch that was in progress in the parent when it forked ([PR #196](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/196)).
44
+ - Fixed the AWS Secrets Manager plugin not reporting a timed-out secret fetch as a timeout. A fetch that did not finish within 60 seconds failed with a generic `SecretsManagerAuthError` (`Failed to fetch database credentials from AWS Secrets Manager`) instead of `Timed out fetching secret after 60s` ([PR #196](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/196)).
45
+ - Fixed Action Cable's PostgreSQL subscription adapter (`adapter: postgresql` in `cable.yml`) refusing to run on the `aws_postgresql` ActiveRecord adapter with `The Active Record database must be PostgreSQL in order to use the PostgreSQL Action Cable storage adapter`, which also stopped Turbo Stream broadcasts ([PR #197](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/197)).
46
+ - Fixed the `aws_postgresql` and `aws_mysql2` ActiveRecord adapters raising `Unknown type` for adapter-specific attribute types and columns. ActiveRecord keys its type registry by the connection's adapter name, and the wrapped adapters registered none of their own, so types such as PostgreSQL `:interval`, `:point`, `:uuid`, array, and range, and MySQL `:unsigned_integer`, could not be resolved. The wrapped adapter names are now aliased to the underlying `postgresql` and `mysql2` adapters for type registration and lookup, so the wrapped adapters resolve the same types as the standard adapters ([PR #200](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/200)).
47
+ - **Side effect:** in an application that uses both a standard (`postgresql`/`mysql2`) connection and a wrapped (`aws_postgresql`/`aws_mysql2`) connection, a type registered for one is now shared with the other, because both resolve under the same underlying adapter key.
48
+ - Changed the `aws_postgresql` and `aws_mysql2` ActiveRecord adapters to report the underlying `adapter_name` (`"PostgreSQL"` and `"Mysql2"`) instead of `"AwsPostgreSQL"` and `"AwsMySQL2"`. ActiveRecord's migration compatibility layer gates PostgreSQL- and MySQL-specific behavior on `connection.adapter_name` string comparisons. Legacy versioned migrations (`ActiveRecord::Migration[5.0]` through `[7.0]`) now complete as expected ([PR #200](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/200)).
49
+
50
+ ## [1.0.0] - 2026-10-05
7
51
 
8
52
  The Amazon Web Services (AWS) Advanced Ruby Driver Wrapper allows an application to take advantage of the features of clustered Aurora databases.
9
53
 
@@ -20,4 +64,6 @@ The Amazon Web Services (AWS) Advanced Ruby Driver Wrapper allows an application
20
64
  - [Initial Connection Strategy Plugin](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/initial-connection-strategy).
21
65
  - [KMS Encryption Plugin](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/kms-encryption).
22
66
 
23
- [1.0.0]: https://github.com/aws/aws-advanced-ruby-driver-wrapper/releases/tag/1.0.0
67
+ [1.1.0]: https://github.com/aws/aws-advanced-ruby-driver-wrapper/releases/tag/v1.1.0
68
+ [1.0.1]: https://github.com/aws/aws-advanced-ruby-driver-wrapper/releases/tag/v1.0.1
69
+ [1.0.0]: https://github.com/aws/aws-advanced-ruby-driver-wrapper/releases/tag/v1.0.0
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  The **AWS Advanced Ruby Driver Wrapper** is complementary to an existing Ruby database driver and aims to extend the functionality of the driver to enable applications to take full advantage of the features of clustered databases such as Amazon Aurora. In other words, the AWS Advanced Ruby Driver Wrapper does not connect directly to any database, but enables support of AWS and Aurora functionalities on top of an underlying Ruby driver of the user's choice. This approach enables service-specific enhancements without requiring users to change their workflow with their existing Ruby drivers and tooling.
6
6
 
7
- The wrapper integrates with [ActiveRecord](https://guides.rubyonrails.org/active_record_basics.html) by providing drop-in `aws_mysql2` and `aws_postgresql` adapters that sit on top of the community [`mysql2`](https://rubygems.org/gems/mysql2) and [`pg`](https://rubygems.org/gems/pg) drivers.
7
+ The wrapper integrates with [ActiveRecord](https://guides.rubyonrails.org/active_record_basics.html) by providing drop-in `aws_mysql2`, `aws_trilogy` and `aws_postgresql` adapters that sit on top of the community [`mysql2`](https://rubygems.org/gems/mysql2), [`trilogy`](https://rubygems.org/gems/trilogy) and [`pg`](https://rubygems.org/gems/pg) drivers.
8
8
 
9
9
  ## About the Wrapper
10
10
 
@@ -54,10 +54,12 @@ Add this line to your application's Gemfile:
54
54
  gem 'aws_advanced_ruby_driver_wrapper'
55
55
  ```
56
56
 
57
- For MySQL users, also install the underlying driver:
57
+ For MySQL users, also install one of the underlying drivers:
58
58
 
59
59
  ```ruby
60
60
  gem 'mysql2'
61
+ # or
62
+ gem 'trilogy'
61
63
  ```
62
64
 
63
65
  For PostgreSQL users, also install the underlying driver:
@@ -74,14 +76,17 @@ bundle install
74
76
 
75
77
  ## Getting Started
76
78
 
77
- The wrapper registers two ActiveRecord adapters — `aws_mysql2` and `aws_postgresql` — that are drop-in replacements for the standard `mysql2` and `postgresql` adapters.
79
+ The wrapper registers three ActiveRecord adapters — `aws_mysql2`, `aws_trilogy` and `aws_postgresql` — that are drop-in replacements for the standard `mysql2`, `trilogy` and `postgresql` adapters.
78
80
 
79
81
  Require the appropriate entry point for your database:
80
82
 
81
83
  ```ruby
82
- # For MySQL
84
+ # For MySQL with mysql2
83
85
  require 'aws_advanced_ruby_driver_wrapper/mysql'
84
86
 
87
+ # For MySQL with trilogy
88
+ require 'aws_advanced_ruby_driver_wrapper/trilogy'
89
+
85
90
  # For PostgreSQL
86
91
  require 'aws_advanced_ruby_driver_wrapper/postgresql'
87
92
  ```
@@ -89,7 +94,7 @@ require 'aws_advanced_ruby_driver_wrapper/postgresql'
89
94
  Then set the adapter in your database configuration (for example, `config/database.yml` in a Rails application):
90
95
 
91
96
  ```yaml
92
- # MySQL
97
+ # MySQL (use aws_trilogy with the trilogy driver)
93
98
  production:
94
99
  adapter: aws_mysql2
95
100
  host: my-cluster.cluster-xxxx.us-east-1.rds.amazonaws.com
@@ -106,6 +111,105 @@ production:
106
111
  password: <password>
107
112
  ```
108
113
 
114
+ This is a minimal configuration. To add failover tuning, IAM or Secrets Manager authentication, TLS, and other plugins for your deployment, see the [documentation](#documentation), or [let an AI assistant build the configuration with you](#configuring-the-wrapper-with-ai-tools).
115
+
116
+ ### Configuring the Wrapper with AI Tools
117
+
118
+ If you use an AI assistant (Kiro, Cursor, Claude Code, GitHub Copilot, ChatGPT, Amazon Bedrock, etc.), you can give it the wrapper's configuration assistant skill to help build, review, or troubleshoot your wrapper configuration.
119
+
120
+ The skill is a single self-contained markdown file, [`skills/ruby-wrapper-configuration-assistant/SKILL.md`](./skills/ruby-wrapper-configuration-assistant/SKILL.md). It covers every plugin, parameter, default value, dialect, failover mode, and compatibility constraint, so the AI can answer configuration questions without access to the wrapper source. It follows the [Agent Skills](https://agentskills.io) format. It is about 65,000 tokens on Claude Opus 5.5 and Sonnet 5.5 (other models count tokens differently). How much of that you pay for depends on how you add it:
121
+
122
+ - **Tools that support Agent Skills** load only the skill's name and description (about 100 tokens) until a request needs the skill. They then load the full file, and it stays in context for the rest of that conversation.
123
+ - **A system prompt, or a file pasted into a chat,** sends the full file with every message.
124
+
125
+ Once the full file is in context, it is sent again with each message, so tools that cache prompts handle it most cheaply.
126
+
127
+ #### Quick start
128
+
129
+ 1. Download or copy [`SKILL.md`](https://github.com/aws/aws-advanced-ruby-driver-wrapper/blob/v1.1.0/skills/ruby-wrapper-configuration-assistant/SKILL.md) from the latest release, or the whole `skills/ruby-wrapper-configuration-assistant` folder. The copy on `main` can describe changes that aren't released yet; it marks them `[Unreleased]`, and the AI won't recommend them for a released gem version.
130
+ 2. Add it to your AI tool:
131
+ - **Tools that support Agent Skills** (Kiro, Cursor, Claude Code, GitHub Copilot in VS Code, and others): copy the `ruby-wrapper-configuration-assistant` folder (or create a folder with that name and save `SKILL.md` in it) into one of the tool's skills directories. The folder name must match the `name` field at the top of the file (`ruby-wrapper-configuration-assistant`), as the Agent Skills format requires; a tool may not load the skill if they differ.
132
+
133
+ | Tool | Project skills directory | User skills directory |
134
+ |---|---|---|
135
+ | Kiro | `.kiro/skills/` | `~/.kiro/skills/` |
136
+ | Cursor | `.cursor/skills/`, `.agents/skills/`, or `.claude/skills/` | `~/.cursor/skills/`, `~/.agents/skills/`, or `~/.claude/skills/` |
137
+ | Claude Code | `.claude/skills/` | `~/.claude/skills/` |
138
+ | GitHub Copilot in VS Code | `.github/skills/`, `.agents/skills/`, or `.claude/skills/` | `~/.copilot/skills/`, `~/.agents/skills/`, or `~/.claude/skills/` |
139
+
140
+ For example, to add the skill to a project for Claude Code:
141
+
142
+ ```bash
143
+ mkdir -p .claude/skills/ruby-wrapper-configuration-assistant
144
+ curl -fsSL -o .claude/skills/ruby-wrapper-configuration-assistant/SKILL.md \
145
+ https://raw.githubusercontent.com/aws/aws-advanced-ruby-driver-wrapper/v1.1.0/skills/ruby-wrapper-configuration-assistant/SKILL.md
146
+ ```
147
+
148
+ - **Claude Projects**: upload it as a project knowledge document. Claude reads project knowledge in full while it fits in the context window, but when a project's knowledge approaches that limit, Claude switches to searching it for passages that match each question, so the model may miss the instructions and cross-references the skill depends on. Keep the project's other knowledge small, or use a separate project.
149
+ - **ChatGPT custom GPT**: a custom GPT searches its knowledge files and passes the model only the passages that match each question, so the model may miss the instructions and cross-references the skill depends on. Paste the file into a plain chat instead (below).
150
+ - **Amazon Bedrock**: send the file as the system prompt of your `InvokeModel` or `Converse` request. Avoid attaching it to a Bedrock knowledge base: a knowledge base passes the model only the passages that match each question, so the model misses the instructions and cross-references the skill depends on.
151
+ - **Plain chat (ChatGPT, Claude, Gemini)**: paste it at the start of a new conversation, then ask your question. Start a new conversation for each new question: in a long conversation the pasted skill can be pushed out of the model's context, and ChatGPT drops the oldest messages first. In ChatGPT, the file is about 40,000 tokens, which is more than the Free plan's context window and leaves little room on the Go and Plus plans' Instant models, so choose a Thinking model in the model picker or use the Pro plan.
152
+ 3. Ask the AI for help. It will interview you when it needs more details, or give you a configuration straight away if you ask it to skip the interview.
153
+
154
+ #### Example prompts
155
+
156
+ The simplest way to start:
157
+
158
+ ```
159
+ Help me configure the AWS Advanced Ruby Driver Wrapper for my Rails app.
160
+ ```
161
+
162
+ Skip the interview when you already know what you want:
163
+
164
+ ```
165
+ Give me a default config/database.yml for Rails on Aurora PostgreSQL with failover and IAM authentication.
166
+ ```
167
+
168
+ Review an existing configuration:
169
+
170
+ ```
171
+ Review this database.yml entry and tell me what to change:
172
+
173
+ <paste your database.yml entry, or the Ruby code that opens the connection>
174
+ ```
175
+
176
+ Diagnose a configuration error:
177
+
178
+ ```
179
+ My Rails app on aws_postgresql fails at startup with "The failover plugin is not compatible with RDS Proxy endpoints".
180
+ What's wrong with my database.yml?
181
+ ```
182
+
183
+ The skill targets wrapper version 1.0.1 and later. If it doesn't know something, it says so and points you to the [Ruby wrapper documentation](https://aws.github.io/aws-advanced-wrapper-docs/ruby/overview).
184
+
185
+ ### Troubleshooting the Wrapper with AI Tools
186
+
187
+ A second skill, the troubleshooting assistant, helps an AI assistant find out why the wrapper isn't doing what you expect: installation and load errors, connection setup errors, IAM, Secrets Manager, AD FS and Okta authentication failures, failover that doesn't happen or fails, Active Record integration problems, the trilogy driver, Blue/Green, custom endpoints, Global Database, KMS encryption, telemetry, and performance. It works out whether the cause is your configuration, your environment (network, AWS permissions, TLS), a wrapper bug, or something outside the wrapper, helps you narrow it down and read the wrapper's logs, and drafts an issue report when the problem needs one.
188
+
189
+ The skill is [`skills/ruby-wrapper-troubleshooting-assistant/SKILL.md`](https://github.com/aws/aws-advanced-ruby-driver-wrapper/blob/v1.1.0/skills/ruby-wrapper-troubleshooting-assistant/SKILL.md) (link to the latest release), about 30,000 tokens on Claude Opus 5.5 and Sonnet 5.5 (about 20,000 in ChatGPT). The two skills are independent: install either one or both. Add it to your AI tool the same way as the configuration assistant (see [Quick start](#quick-start)), using the folder name `ruby-wrapper-troubleshooting-assistant`. For example, for Claude Code:
190
+
191
+ ```bash
192
+ mkdir -p .claude/skills/ruby-wrapper-troubleshooting-assistant
193
+ curl -fsSL -o .claude/skills/ruby-wrapper-troubleshooting-assistant/SKILL.md \
194
+ https://raw.githubusercontent.com/aws/aws-advanced-ruby-driver-wrapper/v1.1.0/skills/ruby-wrapper-troubleshooting-assistant/SKILL.md
195
+ ```
196
+
197
+ Then describe the problem, and include the error message and backtrace if you have one. Remove passwords and other secrets from anything you paste.
198
+
199
+ ```
200
+ My Rails app on Aurora PostgreSQL gets AwsAdvancedRubyDriverWrapper::Errors::FailoverSuccessError
201
+ a few times a day, but there's no failover in the RDS events. What's going on?
202
+ ```
203
+
204
+ ```
205
+ Failover fails with "The request to discover the new topology timed out or was unsuccessful".
206
+ Here are the wrapper's debug logs:
207
+
208
+ <paste the logs>
209
+ ```
210
+
211
+ The skill targets wrapper version 1.0.1 and later.
212
+
109
213
  ## Documentation
110
214
 
111
215
  Technical documentation regarding the functionality of the AWS Advanced Ruby Driver Wrapper is published at the [AWS Advanced Wrapper documentation site](https://aws.github.io/aws-advanced-wrapper-docs/ruby/overview). Since the wrapper requires an underlying Ruby driver, please refer to the individual driver's documentation for driver-specific information.
@@ -128,6 +232,11 @@ Technical documentation regarding the functionality of the AWS Advanced Ruby Dri
128
232
 
129
233
  ### Known Limitations
130
234
 
235
+ #### Trilogy MySQL Driver
236
+
237
+ - The KMS Encryption Plugin is not supported with `trilogy`, which has no prepared statements, so a bind parameter could only reach the server in plaintext. The plugin refuses to start on a `trilogy` connection.
238
+ - To authenticate with an IAM token, set `enable_cleartext_plugin: true` (and `ssl_mode`), since `trilogy` only sends the token with `mysql_clear_password` when that option is set.
239
+
131
240
  #### Amazon RDS Blue/Green Deployments
132
241
 
133
242
  Support for Blue/Green deployments using the wrapper requires specific metadata tables. Please refer to the plugin documentation for the supported database engine versions.
@@ -137,7 +246,7 @@ Support for Blue/Green deployments using the wrapper requires specific metadata
137
246
  If you encounter a bug with the AWS Advanced Ruby Driver Wrapper, we would like to hear about it.
138
247
  Please search the [existing issues](https://github.com/aws/aws-advanced-ruby-driver-wrapper/issues) to see if others are also experiencing the issue before reporting the problem in a new issue. GitHub issues are intended for bug reports and feature requests.
139
248
 
140
- When opening a new issue, please fill in all required fields in the issue template to help expedite the investigation process.
249
+ When opening a new issue, please fill in all required fields in the issue template to help expedite the investigation process. The [troubleshooting assistant skill](#troubleshooting-the-wrapper-with-ai-tools) can help you find the cause first, and draft the issue if it turns out to be a bug.
141
250
 
142
251
  For all other questions, please use [GitHub discussions](https://github.com/aws/aws-advanced-ruby-driver-wrapper/discussions).
143
252
 
data/THIRD-PARTY-LICENSES CHANGED
@@ -3,10 +3,10 @@ following third-party software. The applicable licenses and notices are
3
3
  reproduced below. Each dependency remains under its own license; nothing in
4
4
  this file modifies those terms.
5
5
 
6
- The underlying database drivers (pg, mysql2), ActiveRecord, pg_query, and the
7
- AWS SDK gems are optional dependencies that are installed by the user as needed;
8
- they are listed here because the wrapper is designed to load and run on top of
9
- them.
6
+ The underlying database drivers (pg, mysql2, trilogy), ActiveRecord, pg_query,
7
+ the OpenTelemetry gems, and the AWS SDK gems are optional dependencies that are
8
+ installed by the user as needed; they are listed here because the wrapper is
9
+ designed to load and run on top of them.
10
10
 
11
11
  ===============================================================================
12
12
 
@@ -40,6 +40,19 @@ SOFTWARE.
40
40
 
41
41
  -----------
42
42
 
43
+ The following Ruby gems are required runtime dependencies of this product.
44
+ Ruby no longer installs them by default from Ruby 3.4 (bigdecimal) and 4.0
45
+ (logger) on, so the wrapper declares them explicitly:
46
+
47
+ - bigdecimal@4.1.3
48
+ - logger@1.7.0
49
+
50
+ These packages are each distributed under the same Ruby license reproduced
51
+ below for the `pg` gem (the Ruby license or, at your option, the 2-clause
52
+ BSDL).
53
+
54
+ -----------
55
+
43
56
  The following Ruby gem may be used with this product (ActiveRecord adapters):
44
57
 
45
58
  - activerecord@8.1.4
@@ -131,9 +144,41 @@ SOFTWARE.
131
144
 
132
145
  -----------
133
146
 
147
+ The following Ruby gem may be used with this product (alternative MySQL driver;
148
+ the KMS Encryption plugin is not supported with trilogy):
149
+
150
+ - trilogy@2.13.2
151
+
152
+ This package contains the following license and notice below:
153
+
154
+ Copyright (c) 2012-2021 GitHub, Inc.
155
+
156
+ Permission is hereby granted, free of charge, to any person
157
+ obtaining a copy of this software and associated documentation
158
+ files (the "Software"), to deal in the Software without
159
+ restriction, including without limitation the rights to use,
160
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
161
+ copies of the Software, and to permit persons to whom the
162
+ Software is furnished to do so, subject to the following
163
+ conditions:
164
+
165
+ The above copyright notice and this permission notice shall be
166
+ included in all copies or substantial portions of the Software.
167
+
168
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
169
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
170
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
171
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
172
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
173
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
174
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
175
+ OTHER DEALINGS IN THE SOFTWARE.
176
+
177
+ -----------
178
+
134
179
  The following Ruby gem may be used with this product (PostgreSQL driver):
135
180
 
136
- - pg@1.6.3
181
+ - pg@1.7.0
137
182
 
138
183
  This package contains the following license and notice below:
139
184
 
@@ -224,7 +269,7 @@ SUCH DAMAGE.
224
269
  The following Ruby gem may be used with this product (SQL statement parsing
225
270
  for the KMS Encryption plugin):
226
271
 
227
- - pg_query@6.2.3
272
+ - pg_query@6.2.5
228
273
 
229
274
  This package contains the following license and notice below:
230
275
 
@@ -259,13 +304,27 @@ POSSIBILITY OF SUCH DAMAGE.
259
304
 
260
305
  -----------
261
306
 
307
+ The following OpenTelemetry for Ruby gems may be used with this product
308
+ (telemetry, when `enable_telemetry` is set). The wrapper loads these API gems;
309
+ the OpenTelemetry SDK and exporters that actually emit the traces and metrics
310
+ are supplied by the application:
311
+
312
+ - opentelemetry-api@1.11.1
313
+ - opentelemetry-metrics-api@0.10.0
314
+
315
+ These packages are each licensed under the Apache License, Version 2.0,
316
+ reproduced below (following the AWS SDK gems).
317
+
318
+ -----------
319
+
262
320
  The following AWS SDK for Ruby gems may be used with this product (AWS IAM
263
- Authentication, AWS Secrets Manager, Custom Endpoint, and KMS Encryption
264
- plugins):
321
+ Authentication, AWS Secrets Manager, Custom Endpoint, Federated Authentication,
322
+ Okta Authentication, and KMS Encryption plugins):
265
323
 
266
- - aws-sdk-kms@1.132.0
267
- - aws-sdk-rds@1.323.0
268
- - aws-sdk-secretsmanager@1.136.0
324
+ - aws-sdk-core@3.263.0
325
+ - aws-sdk-kms@1.138.0
326
+ - aws-sdk-rds@1.329.0
327
+ - aws-sdk-secretsmanager@1.141.0
269
328
 
270
329
  These packages are each licensed under the Apache License, Version 2.0,
271
330
  reproduced below:
@@ -53,7 +53,12 @@ Gem::Specification.new do |spec|
53
53
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
54
54
  spec.require_paths = ['lib']
55
55
 
56
+ # The wrapper requires bigdecimal and logger, and Ruby no longer installs them by default from 3.4
57
+ # (bigdecimal) and 4.0 (logger) on. Declaring them keeps a bundle that does not otherwise include
58
+ # them, such as an app using the drivers without Active Record, from failing to load the wrapper.
59
+ spec.add_dependency 'bigdecimal'
56
60
  spec.add_dependency 'concurrent-ruby', '~> 1.3', '>= 1.3.7'
61
+ spec.add_dependency 'logger'
57
62
 
58
63
  spec.post_install_message = <<~MSG
59
64
  ═══════════════════════════════════════════════════════════════
@@ -63,6 +68,10 @@ Gem::Specification.new do |spec|
63
68
  gem install mysql2
64
69
  require 'aws_advanced_ruby_driver_wrapper/mysql'
65
70
 
71
+ To use with MySQL through trilogy:
72
+ gem install trilogy
73
+ require 'aws_advanced_ruby_driver_wrapper/trilogy'
74
+
66
75
  To use with PostgreSQL:
67
76
  gem install pg
68
77
  require 'aws_advanced_ruby_driver_wrapper/postgresql'
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License").
6
+ # You may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative '../postgresql'
18
+
19
+ module ActiveRecord
20
+ module ConnectionAdapters
21
+ # Lets Action Cable's PostgreSQL subscription adapter (cable.yml `adapter: postgresql`) run on the
22
+ # aws_postgresql adapter. Action Cable refuses any raw connection that is not a PG::Connection, and
23
+ # aws_postgresql hands out a WrapperPgConnection, which forwards the calls Action Cable makes
24
+ # (exec, escape_identifier, escape_string, wait_for_notify) to the PG::Connection it wraps.
25
+ module AwsActionCablePostgreSQLSupport
26
+ private
27
+
28
+ def verify!(pg_conn)
29
+ super unless pg_conn.is_a?(AwsAdvancedRubyDriverWrapper::WrapperPgConnection)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # Action Cable runs this hook when its server loads, before it loads a subscription adapter, so the
36
+ # PostgreSQL one is loaded here to patch it. Applications without Action Cable never run the hook.
37
+ ActiveSupport.on_load(:action_cable) do
38
+ require 'action_cable/subscription_adapter/postgresql'
39
+ ActionCable::SubscriptionAdapter::PostgreSQL.prepend(ActiveRecord::ConnectionAdapters::AwsActionCablePostgreSQLSupport)
40
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License").
6
+ # You may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'active_record'
18
+ require_relative '../services/service_utility'
19
+ require_relative '../host/rds_host_list_provider'
20
+ require_relative '../plugins/blue_green/blue_green_plugin'
21
+
22
+ module ActiveRecord
23
+ module ConnectionAdapters
24
+ # Stops the wrapper's background monitors and Blue/Green status providers when ActiveRecord closes every
25
+ # connection pool, and forgets the state they cached, so that the next connection starts new ones straight away.
26
+ #
27
+ # The monitors keep their own connections to the database, outside ActiveRecord's pools. Closing
28
+ # everything is what ActiveRecord does before another process takes over the database, for example
29
+ # when bin/rails test runs db:test:prepare in a child process to drop and reload the test database,
30
+ # and PostgreSQL refuses to drop a database that a monitor is still connected to. The next
31
+ # connection that needs a monitor starts a new one.
32
+ module AwsConnectionHandler
33
+ def clear_all_connections!(...)
34
+ super
35
+ core = AwsAdvancedRubyDriverWrapper::Services::CoreServices
36
+ core.monitor_service.stop_and_remove_all
37
+ AwsAdvancedRubyDriverWrapper::Plugins::BlueGreen::BlueGreenPlugin.clean_up_providers
38
+ # Without this, connections would keep reading cached state that nothing refreshes any more.
39
+ cached = [AwsAdvancedRubyDriverWrapper::Host::RdsHostListProvider::TOPOLOGY_CACHE_NAME,
40
+ AwsAdvancedRubyDriverWrapper::Plugins::BlueGreen::BlueGreenPlugin::BLUE_GREEN_NAME]
41
+ cached.each { |name| core.storage_service.clear(name) if core.storage_service.registered?(name) }
42
+ end
43
+ end
44
+
45
+ ConnectionHandler.prepend(AwsConnectionHandler)
46
+ end
47
+ end
@@ -17,20 +17,31 @@
17
17
  require 'active_record/connection_adapters/mysql2_adapter'
18
18
  require_relative '../mysql'
19
19
  require_relative '../errors'
20
- require_relative '../utils/ar_constants'
20
+ require_relative 'type_adapter_alias'
21
+ require_relative 'aws_connection_handler'
21
22
 
22
23
  module ActiveRecord
23
24
  module ConnectionAdapters
24
25
  class AwsMysql2Adapter < Mysql2Adapter
25
- ADAPTER_NAME = 'AwsMySQL2'
26
-
27
- # ActiveRecord-only keys that should not be passed to the wrapper or native driver.
28
- AR_ONLY_KEYS = AwsAdvancedRubyDriverWrapper::Utils::AR_COMMON_KEYS
29
-
30
- def adapter_name = ADAPTER_NAME
31
-
26
+ # Passes the whole config on, as the parent adapter does: the wrapper takes its own properties out,
27
+ # and mysql2 reads the client options it knows (including the FOUND_ROWS flag the parent adds) and
28
+ # ignores the ActiveRecord-only keys.
29
+ #
30
+ # Translates connection errors the same way the parent adapter does, so ActiveRecord can tell a
31
+ # missing database (which db:prepare creates) or rejected credentials from other failures.
32
32
  def self.new_client(config)
33
- AwsAdvancedRubyDriverWrapper::WrapperMysql2Client.new(**config.except(*AR_ONLY_KEYS))
33
+ AwsAdvancedRubyDriverWrapper::WrapperMysql2Client.new(**config)
34
+ rescue ::Mysql2::Error => e
35
+ case e.error_number
36
+ when ER_BAD_DB_ERROR
37
+ raise ActiveRecord::NoDatabaseError.db_error(config[:database])
38
+ when ER_DBACCESS_DENIED_ERROR, ER_ACCESS_DENIED_ERROR
39
+ raise ActiveRecord::DatabaseConnectionError.username_error(config[:username])
40
+ when ER_CONN_HOST_ERROR, ER_UNKNOWN_HOST_ERROR
41
+ raise ActiveRecord::DatabaseConnectionError.hostname_error(config[:host])
42
+ else
43
+ raise ActiveRecord::ConnectionNotEstablished, e.message
44
+ end
34
45
  end
35
46
 
36
47
  def connect
@@ -53,6 +64,9 @@ module ActiveRecord
53
64
  return super unless exception.is_a?(AwsAdvancedRubyDriverWrapper::Errors::AwsError)
54
65
 
55
66
  if exception.needs_reconfiguration
67
+ # The wrapper has reconnected this connection object to a new physical connection, where the
68
+ # statements prepared on the old one do not exist. Forget them so they are prepared again.
69
+ clear_cache!(new_connection: true)
56
70
  configure_connection
57
71
  exception
58
72
  elsif exception.is_a?(AwsAdvancedRubyDriverWrapper::Errors::FailoverFailedError)