aws_advanced_ruby_driver_wrapper 1.0.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 (150) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +23 -0
  3. data/LICENSE +175 -0
  4. data/NOTICE +1 -0
  5. data/README.md +168 -0
  6. data/THIRD-PARTY-LICENSES +473 -0
  7. data/aws_advanced_ruby_driver_wrapper.gemspec +73 -0
  8. data/lib/aws_advanced_ruby_driver_wrapper/active_record/aws_mysql2_adapter.rb +73 -0
  9. data/lib/aws_advanced_ruby_driver_wrapper/active_record/aws_postgresql_adapter.rb +95 -0
  10. data/lib/aws_advanced_ruby_driver_wrapper/custom_configuration.rb +58 -0
  11. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/aurora_mysql_dialect.rb +103 -0
  12. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/aurora_pg_dialect.rb +124 -0
  13. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/dialect_codes.rb +38 -0
  14. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/global_mysql_dialect.rb +91 -0
  15. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/global_pg_dialect.rb +92 -0
  16. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/multi_az_cluster_mysql_dialect.rb +95 -0
  17. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/multi_az_cluster_pg_dialect.rb +86 -0
  18. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/mysql_dialect.rb +98 -0
  19. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/pg_dialect.rb +95 -0
  20. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/rds_mysql_dialect.rb +88 -0
  21. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/rds_pg_dialect.rb +86 -0
  22. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/unknown_dialect.rb +72 -0
  23. data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/utils/dialect_utils.rb +71 -0
  24. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/driver_dialect.rb +154 -0
  25. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/driver_dialect_manager.rb +55 -0
  26. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/mysql_driver_dialect.rb +165 -0
  27. data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/pg_driver_dialect.rb +201 -0
  28. data/lib/aws_advanced_ruby_driver_wrapper/errors/error_handler.rb +62 -0
  29. data/lib/aws_advanced_ruby_driver_wrapper/errors/mysql_error_handler.rb +80 -0
  30. data/lib/aws_advanced_ruby_driver_wrapper/errors/pg_error_handler.rb +126 -0
  31. data/lib/aws_advanced_ruby_driver_wrapper/errors.rb +59 -0
  32. data/lib/aws_advanced_ruby_driver_wrapper/host/connection_string_host_list_provider.rb +95 -0
  33. data/lib/aws_advanced_ruby_driver_wrapper/host/global_aurora_host_list_provider.rb +65 -0
  34. data/lib/aws_advanced_ruby_driver_wrapper/host/host_availability.rb +24 -0
  35. data/lib/aws_advanced_ruby_driver_wrapper/host/host_availability_strategy.rb +27 -0
  36. data/lib/aws_advanced_ruby_driver_wrapper/host/host_info.rb +137 -0
  37. data/lib/aws_advanced_ruby_driver_wrapper/host/host_role.rb +25 -0
  38. data/lib/aws_advanced_ruby_driver_wrapper/host/random_host_selector.rb +40 -0
  39. data/lib/aws_advanced_ruby_driver_wrapper/host/rds_host_list_provider.rb +206 -0
  40. data/lib/aws_advanced_ruby_driver_wrapper/logging.rb +110 -0
  41. data/lib/aws_advanced_ruby_driver_wrapper/monitoring/cluster_topology_monitor.rb +709 -0
  42. data/lib/aws_advanced_ruby_driver_wrapper/monitoring/global_cluster_topology_monitor.rb +72 -0
  43. data/lib/aws_advanced_ruby_driver_wrapper/monitoring/monitor.rb +99 -0
  44. data/lib/aws_advanced_ruby_driver_wrapper/monitoring/monitor_connection.rb +57 -0
  45. data/lib/aws_advanced_ruby_driver_wrapper/monitoring/monitor_state.rb +25 -0
  46. data/lib/aws_advanced_ruby_driver_wrapper/mysql.rb +429 -0
  47. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/blue_green_plugin.rb +205 -0
  48. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/host_mapper.rb +132 -0
  49. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/iam_host_tracker.rb +84 -0
  50. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/interim_status.rb +92 -0
  51. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/interval_rate.rb +27 -0
  52. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/phase.rb +69 -0
  53. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/phase_event_log.rb +85 -0
  54. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/phase_time_info.rb +25 -0
  55. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/role.rb +38 -0
  56. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/base_routing.rb +83 -0
  57. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/reject_connect_routing.rb +40 -0
  58. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/substitute_connect_routing.rb +136 -0
  59. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/suspend_connect_routing.rb +53 -0
  60. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/suspend_execute_routing.rb +52 -0
  61. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/suspend_until_corresponding_host_found_connect_routing.rb +83 -0
  62. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status.rb +68 -0
  63. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_builder.rb +244 -0
  64. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_info.rb +30 -0
  65. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_monitor.rb +564 -0
  66. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_provider.rb +414 -0
  67. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/switchover_state.rb +98 -0
  68. data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/switchover_timer.rb +46 -0
  69. data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/custom_endpoint_monitor.rb +266 -0
  70. data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/custom_endpoint_plugin.rb +158 -0
  71. data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/info.rb +111 -0
  72. data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/member_list_type.rb +31 -0
  73. data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/role.rb +45 -0
  74. data/lib/aws_advanced_ruby_driver_wrapper/plugins/default_plugin.rb +108 -0
  75. data/lib/aws_advanced_ruby_driver_wrapper/plugins/failover_mode.rb +43 -0
  76. data/lib/aws_advanced_ruby_driver_wrapper/plugins/failover_plugin.rb +467 -0
  77. data/lib/aws_advanced_ruby_driver_wrapper/plugins/gdb/gdb_failover_mode.rb +68 -0
  78. data/lib/aws_advanced_ruby_driver_wrapper/plugins/gdb/gdb_failover_plugin.rb +403 -0
  79. data/lib/aws_advanced_ruby_driver_wrapper/plugins/iam_auth_plugin.rb +159 -0
  80. data/lib/aws_advanced_ruby_driver_wrapper/plugins/initial_connection_strategy_plugin.rb +485 -0
  81. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/audit_logger.rb +157 -0
  82. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/column_cipher.rb +159 -0
  83. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/column_encryption_config.rb +61 -0
  84. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/connection_source.rb +91 -0
  85. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/data_key_cache.rb +220 -0
  86. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/encryption_algorithm.rb +75 -0
  87. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/encryption_config.rb +146 -0
  88. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/encryption_service.rb +391 -0
  89. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/error_context.rb +198 -0
  90. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/errors.rb +259 -0
  91. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/key_management_utility.rb +435 -0
  92. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/key_manager.rb +378 -0
  93. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/key_metadata.rb +86 -0
  94. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/kms_encryption_plugin.rb +890 -0
  95. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/kms_encryption_utility.rb +281 -0
  96. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/metadata_manager.rb +332 -0
  97. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/sanitizer.rb +147 -0
  98. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/schema_name.rb +70 -0
  99. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/schema_validator.rb +211 -0
  100. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/sql_runner.rb +147 -0
  101. data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/type_marker.rb +109 -0
  102. data/lib/aws_advanced_ruby_driver_wrapper/plugins/secrets_manager_plugin.rb +358 -0
  103. data/lib/aws_advanced_ruby_driver_wrapper/postgresql.rb +659 -0
  104. data/lib/aws_advanced_ruby_driver_wrapper/property_definition.rb +409 -0
  105. data/lib/aws_advanced_ruby_driver_wrapper/ruby_method.rb +122 -0
  106. data/lib/aws_advanced_ruby_driver_wrapper/services/connection_service.rb +143 -0
  107. data/lib/aws_advanced_ruby_driver_wrapper/services/dialect_service.rb +267 -0
  108. data/lib/aws_advanced_ruby_driver_wrapper/services/host_service.rb +199 -0
  109. data/lib/aws_advanced_ruby_driver_wrapper/services/monitor_service.rb +186 -0
  110. data/lib/aws_advanced_ruby_driver_wrapper/services/plugin_call_context.rb +63 -0
  111. data/lib/aws_advanced_ruby_driver_wrapper/services/plugin_manager.rb +273 -0
  112. data/lib/aws_advanced_ruby_driver_wrapper/services/service_container.rb +30 -0
  113. data/lib/aws_advanced_ruby_driver_wrapper/services/service_utility.rb +78 -0
  114. data/lib/aws_advanced_ruby_driver_wrapper/services/session_state_service.rb +56 -0
  115. data/lib/aws_advanced_ruby_driver_wrapper/utils/accessible_regions.rb +52 -0
  116. data/lib/aws_advanced_ruby_driver_wrapper/utils/ar_constants.rb +25 -0
  117. data/lib/aws_advanced_ruby_driver_wrapper/utils/aurora_topology_utils.rb +99 -0
  118. data/lib/aws_advanced_ruby_driver_wrapper/utils/aws_credentials_utils.rb +62 -0
  119. data/lib/aws_advanced_ruby_driver_wrapper/utils/connection_config.rb +91 -0
  120. data/lib/aws_advanced_ruby_driver_wrapper/utils/connection_config_parser.rb +368 -0
  121. data/lib/aws_advanced_ruby_driver_wrapper/utils/conversion_utils.rb +51 -0
  122. data/lib/aws_advanced_ruby_driver_wrapper/utils/events/batching_event_publisher.rb +119 -0
  123. data/lib/aws_advanced_ruby_driver_wrapper/utils/events/data_access_event.rb +26 -0
  124. data/lib/aws_advanced_ruby_driver_wrapper/utils/events/monitor_reset_event.rb +26 -0
  125. data/lib/aws_advanced_ruby_driver_wrapper/utils/global_aurora_topology_utils.rb +185 -0
  126. data/lib/aws_advanced_ruby_driver_wrapper/utils/host_list_utils.rb +27 -0
  127. data/lib/aws_advanced_ruby_driver_wrapper/utils/iam_auth_utils.rb +112 -0
  128. data/lib/aws_advanced_ruby_driver_wrapper/utils/multi_az_topology_utils.rb +117 -0
  129. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/encryption_annotation_parser.rb +99 -0
  130. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/mysql_statement_analyzer.rb +641 -0
  131. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/pg_statement_analyzer.rb +502 -0
  132. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/query_analysis.rb +63 -0
  133. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/query_type.rb +35 -0
  134. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/routing_hint.rb +27 -0
  135. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/routing_hint_parser.rb +50 -0
  136. data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/sql_parser.rb +139 -0
  137. data/lib/aws_advanced_ruby_driver_wrapper/utils/rds_url_type.rb +71 -0
  138. data/lib/aws_advanced_ruby_driver_wrapper/utils/rds_utils.rb +575 -0
  139. data/lib/aws_advanced_ruby_driver_wrapper/utils/retry_util.rb +153 -0
  140. data/lib/aws_advanced_ruby_driver_wrapper/utils/sql_encoding.rb +56 -0
  141. data/lib/aws_advanced_ruby_driver_wrapper/utils/sql_method_analyzer.rb +195 -0
  142. data/lib/aws_advanced_ruby_driver_wrapper/utils/storage/cache_entry.rb +56 -0
  143. data/lib/aws_advanced_ruby_driver_wrapper/utils/storage/expiration_cache.rb +108 -0
  144. data/lib/aws_advanced_ruby_driver_wrapper/utils/storage/sliding_expiration_cache.rb +137 -0
  145. data/lib/aws_advanced_ruby_driver_wrapper/utils/storage/storage_service.rb +172 -0
  146. data/lib/aws_advanced_ruby_driver_wrapper/utils/topology_utils.rb +127 -0
  147. data/lib/aws_advanced_ruby_driver_wrapper/version.rb +19 -0
  148. data/lib/aws_advanced_ruby_driver_wrapper/wrapper_property.rb +64 -0
  149. data/lib/aws_advanced_ruby_driver_wrapper.rb +116 -0
  150. metadata +227 -0
@@ -0,0 +1,244 @@
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 '../../host/host_info'
18
+ require_relative '../../utils/rds_utils'
19
+ require_relative 'phase'
20
+ require_relative 'role'
21
+ require_relative 'routing/base_routing'
22
+ require_relative 'routing/substitute_connect_routing'
23
+ require_relative 'routing/reject_connect_routing'
24
+ require_relative 'routing/suspend_connect_routing'
25
+ require_relative 'routing/suspend_execute_routing'
26
+ require_relative 'routing/suspend_until_corresponding_host_found_connect_routing'
27
+
28
+ module AwsAdvancedRubyDriverWrapper
29
+ module Plugins
30
+ module BlueGreen
31
+ # Constructs the appropriate Status object for each Blue/Green phase.
32
+ # Each method encodes the routing rules that apply during that phase:
33
+ # created — no routing; normal connect/execute behaviour.
34
+ # preparation — blue connects routed to their IP addresses to avoid stale DNS.
35
+ # in_progress — all blue/green connects and executes suspended.
36
+ # post — blue connects redirected to corresponding green hosts; green connects rerouted to IPs.
37
+ # completed — no routing; normal behaviour resumes.
38
+ # If the switchover timer has expired, falls back to created (rollback) or completed.
39
+ class StatusBuilder
40
+ def initialize(bgd_id, host_mapper, timer, interim_statuses, iam_tracker, switchover_state)
41
+ @bgd_id = bgd_id
42
+ @host_mapper = host_mapper
43
+ @timer = timer
44
+ @interim_statuses = interim_statuses
45
+ @iam_tracker = iam_tracker
46
+ @switchover_state = switchover_state
47
+ end
48
+
49
+ def created
50
+ Status.new(@bgd_id, Phase::CREATED,
51
+ connect_routing: [],
52
+ execute_routing: [],
53
+ role_by_host: @host_mapper.role_by_host,
54
+ corresponding_hosts: @host_mapper.corresponding_hosts)
55
+ end
56
+
57
+ # BGD reports COMPLETED. If DNS hasn't fully propagated yet, delegates to post.
58
+ # Clears corresponding_hosts once DNS is confirmed settled.
59
+ def completed(rollback)
60
+ if @timer.expired?
61
+ return created if rollback
62
+
63
+ return Status.new(@bgd_id, Phase::COMPLETED,
64
+ connect_routing: [],
65
+ execute_routing: [],
66
+ role_by_host: @host_mapper.role_by_host,
67
+ corresponding_hosts: @host_mapper.corresponding_hosts)
68
+ end
69
+
70
+ return post(rollback) unless @switchover_state.blue_dns_update_completed && @switchover_state.green_dns_removed
71
+
72
+ Status.new(@bgd_id, Phase::COMPLETED,
73
+ connect_routing: [],
74
+ execute_routing: [],
75
+ role_by_host: @host_mapper.role_by_host,
76
+ corresponding_hosts: {})
77
+ end
78
+
79
+ # POST phase: blue connects are redirected to green hosts (or suspended until a green host is found).
80
+ # Green connects are rerouted to IPs (topology not yet updated) or rejected (DNS removed).
81
+ def post(rollback)
82
+ return (rollback ? created : completed(rollback)) if @timer.expired?
83
+
84
+ Status.new(@bgd_id, Phase::POST,
85
+ connect_routing: post_connect_routing,
86
+ execute_routing: [],
87
+ role_by_host: @host_mapper.role_by_host,
88
+ corresponding_hosts: @host_mapper.corresponding_hosts)
89
+ end
90
+
91
+ # IN_PROGRESS: all blue/green connects and executes are suspended.
92
+ # IP-addressed connections to known blue/green IPs are also suspended.
93
+ def in_progress(rollback)
94
+ return (rollback ? created : completed(rollback)) if @timer.expired?
95
+
96
+ connect_routing = [
97
+ Routing::SuspendConnectRouting.new(nil, nil, Role::SOURCE, @bgd_id),
98
+ Routing::SuspendConnectRouting.new(nil, nil, Role::TARGET, @bgd_id)
99
+ ]
100
+ execute_routing = [
101
+ Routing::SuspendExecuteRouting.new(nil, nil, Role::SOURCE, @bgd_id),
102
+ Routing::SuspendExecuteRouting.new(nil, nil, Role::TARGET, @bgd_id)
103
+ ]
104
+
105
+ ip_connect, ip_execute = @host_mapper.host_ip_addresses.values.compact.uniq
106
+ .each_with_object([[], []]) do |ip, (ic, ie)|
107
+ matched = [Role::SOURCE, Role::TARGET].find do |r|
108
+ interim = @interim_statuses[r]
109
+ interim && interim.start_ip_addresses_by_host.values.compact.include?(ip)
110
+ end
111
+
112
+ if matched
113
+ interim = @interim_statuses[matched]
114
+ port = interim.port.positive? ? interim.port : nil
115
+ ic << Routing::SuspendConnectRouting.new(ip, nil, nil, @bgd_id)
116
+ ic << Routing::SuspendConnectRouting.new(ip, port, nil, @bgd_id)
117
+ ie << Routing::SuspendExecuteRouting.new(ip, nil, nil, @bgd_id)
118
+ ie << Routing::SuspendExecuteRouting.new(ip, port, nil, @bgd_id)
119
+ else
120
+ ie << Routing::SuspendExecuteRouting.new(ip, nil, nil, @bgd_id)
121
+ end
122
+ end
123
+
124
+ Status.new(@bgd_id, Phase::IN_PROGRESS,
125
+ connect_routing: connect_routing + ip_connect,
126
+ execute_routing: execute_routing + ip_execute,
127
+ role_by_host: @host_mapper.role_by_host,
128
+ corresponding_hosts: @host_mapper.corresponding_hosts)
129
+ end
130
+
131
+ # PREPARATION: blue connects are routed to their current IP addresses to avoid
132
+ # stale DNS resolving to the wrong host during the upcoming switchover.
133
+ def preparation(rollback)
134
+ return (rollback ? created : completed(rollback)) if @timer.expired?
135
+
136
+ Status.new(@bgd_id, Phase::PREPARATION,
137
+ connect_routing: substitute_blue_with_ip_routing,
138
+ execute_routing: [],
139
+ role_by_host: @host_mapper.role_by_host,
140
+ corresponding_hosts: @host_mapper.corresponding_hosts)
141
+ end
142
+
143
+ private
144
+
145
+ def post_connect_routing
146
+ routing = []
147
+ append_source_post_routing(routing)
148
+ append_target_post_routing(routing)
149
+ routing
150
+ end
151
+
152
+ # Builds source-side POST routing: redirects blue connects to corresponding green hosts.
153
+ # If the green host isn't found yet, suspends until it appears.
154
+ # Skipped once blue DNS has fully updated and all green hosts have changed their IAM name.
155
+ def append_source_post_routing(routing)
156
+ return if @switchover_state.blue_dns_update_completed || @iam_tracker.all_changed?
157
+
158
+ @host_mapper.role_by_host.each do |blue_host, role|
159
+ next if role != Role::SOURCE
160
+ next unless @host_mapper.corresponding_hosts.key?(blue_host)
161
+
162
+ host_pair = @host_mapper.corresponding_hosts[blue_host]
163
+ green_host_spec = host_pair&.[](1)
164
+ interim_status = @interim_statuses[role]
165
+ port = interim_status&.port&.positive? ? interim_status.port : nil
166
+ is_instance = Utils::RdsUtils.rds_instance?(blue_host)
167
+
168
+ if green_host_spec.nil?
169
+ routing << Routing::SuspendUntilCorrespondingHostFoundConnectRouting.new(blue_host, nil, role, @bgd_id)
170
+ routing << Routing::SuspendUntilCorrespondingHostFoundConnectRouting.new(blue_host, port, role, @bgd_id) if port
171
+ else
172
+ green_host = green_host_spec.host
173
+ green_ip = @host_mapper.host_ip_addresses[green_host]
174
+ green_with_ip = green_ip ? Host::HostInfo.new(host: green_ip, port: green_host_spec.port,
175
+ role: green_host_spec.role) : green_host_spec
176
+ iam_blue_host = Host::HostInfo.new(host: Utils::RdsUtils.remove_green_instance_prefix(green_host),
177
+ port: green_host_spec.port, role: green_host_spec.role)
178
+ iam_hosts = @iam_tracker.connected?(green_host, iam_blue_host.host) ? [iam_blue_host] : [green_host_spec, iam_blue_host]
179
+ notify = is_instance ? ->(h) { @iam_tracker.register(green_host, h) } : nil
180
+
181
+ routing << Routing::SubstituteConnectRouting.new(blue_host, nil, role, green_with_ip, iam_hosts, notify)
182
+ routing << Routing::SubstituteConnectRouting.new(blue_host, port, role, green_with_ip, iam_hosts, notify) if port
183
+ end
184
+ end
185
+ end
186
+
187
+ # Builds target-side POST routing:
188
+ # - If green topology hasn't changed yet, reroutes green connects to their IP addresses.
189
+ # - If green topology changed but DNS isn't removed yet, rejects new green connects.
190
+ def append_target_post_routing(routing)
191
+ if !@switchover_state.green_topology_changed
192
+ @host_mapper.role_by_host.each do |green_host, role|
193
+ next if role != Role::TARGET
194
+
195
+ blue_host = Utils::RdsUtils.remove_green_instance_prefix(green_host)
196
+ interim_status = @interim_statuses[role]
197
+ port = interim_status&.port&.positive? ? interim_status.port : nil
198
+ is_instance = Utils::RdsUtils.rds_instance?(green_host)
199
+
200
+ blue_host_spec = Host::HostInfo.new(host: blue_host, **({ port: port } if port).to_h)
201
+ green_host_spec = Host::HostInfo.new(host: green_host, **({ port: port } if port).to_h)
202
+ green_ip = @host_mapper.host_ip_addresses[green_host]
203
+ green_with_ip = green_ip ? Host::HostInfo.new(host: green_ip,
204
+ **({ port: port } if port).to_h) : Host::HostInfo.new(host: green_host)
205
+ iam_hosts = @iam_tracker.connected?(green_host, blue_host) ? [blue_host_spec] : [green_host_spec, blue_host_spec]
206
+ notify = is_instance ? ->(h) { @iam_tracker.register(green_host, h) } : nil
207
+
208
+ routing << Routing::SubstituteConnectRouting.new(green_host, nil, role, green_with_ip, iam_hosts, notify)
209
+ routing << Routing::SubstituteConnectRouting.new(green_host, port, role, green_with_ip, iam_hosts, notify) if port
210
+ end
211
+ elsif !@switchover_state.green_dns_removed
212
+ routing << Routing::RejectConnectRouting.new(nil, nil, Role::TARGET)
213
+ end
214
+ end
215
+
216
+ # Builds PREPARATION routing: substitutes blue hostname connects with their resolved IP
217
+ # addresses so connections bypass DNS during the switchover window.
218
+ def substitute_blue_with_ip_routing
219
+ @host_mapper.role_by_host.flat_map do |host, role|
220
+ next [] if role != Role::SOURCE
221
+
222
+ host_pair = @host_mapper.corresponding_hosts[host]
223
+ next [] if host_pair.nil?
224
+
225
+ blue_host_spec = host_pair[0]
226
+ blue_ip_entry = @host_mapper.host_ip_addresses[blue_host_spec.host]
227
+ blue_ip_host_spec = blue_ip_entry ? Host::HostInfo.new(host: blue_ip_entry, port: blue_host_spec.port,
228
+ role: blue_host_spec.role) : blue_host_spec
229
+
230
+ entries = [Routing::SubstituteConnectRouting.new(host, nil, role, blue_ip_host_spec, [blue_host_spec], nil)]
231
+
232
+ interim_status = @interim_statuses[role]
233
+ if interim_status
234
+ port = interim_status.port.positive? ? interim_status.port : nil
235
+ entries << Routing::SubstituteConnectRouting.new(host, port, role, blue_ip_host_spec, [blue_host_spec], nil) if port
236
+ end
237
+
238
+ entries
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,30 @@
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 'phase'
18
+ require_relative 'role'
19
+
20
+ module AwsAdvancedRubyDriverWrapper
21
+ module Plugins
22
+ module BlueGreen
23
+ StatusInfo = Struct.new(:version, :endpoint, :port, :phase, :role) do
24
+ def to_s
25
+ "StatusInfo [version: #{version}, endpoint: #{endpoint}, port: #{port}, phase: #{phase}, role: #{role}]"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end