@@ -21,15 +21,18 @@ import { HostInfo } from "../host_info";
2121import { isDialectTopologyAware } from "../utils/utils" ;
2222import { Messages } from "../utils/messages" ;
2323import { AwsWrapperError } from "../utils/errors" ;
24+ import { HostInfoBuilder } from "../host_info_builder" ;
25+ import { logger } from "../../logutils" ;
2426
2527export class GlobalTopologyUtils extends TopologyUtils {
26- async queryForTopology (
28+ override async queryForTopology (
2729 targetClient : ClientWrapper ,
2830 dialect : DatabaseDialect ,
2931 initialHost : HostInfo ,
3032 clusterInstanceTemplate : HostInfo
3133 ) : Promise < HostInfo [ ] > {
32- throw new AwsWrapperError ( "Not implemented" ) ;
34+ // This method should not be called on this class.
35+ throw new AwsWrapperError ( "GlobalTopologyUtils.queryForTopology should not be called directly. Use queryForTopologyWithRegion instead." ) ;
3336 }
3437
3538 async queryForTopologyWithRegion (
@@ -39,14 +42,61 @@ export class GlobalTopologyUtils extends TopologyUtils {
3942 instanceTemplateByRegion : Map < string , HostInfo >
4043 ) : Promise < HostInfo [ ] > {
4144 if ( ! isDialectTopologyAware ( dialect ) ) {
42- throw new TypeError ( Messages . get ( "RdsHostListProvider.incorrectDialect" ) ) ;
45+ throw new AwsWrapperError ( Messages . get ( "RdsHostListProvider.incorrectDialect" ) ) ;
4346 }
4447
4548 return await dialect
4649 . queryForTopology ( targetClient )
4750 . then ( ( res : TopologyQueryResult [ ] ) => this . verifyWriter ( this . createHostsWithTemplateMap ( res , initialHost , instanceTemplateByRegion ) ) ) ;
4851 }
4952
53+ async getRegion ( instanceId : string , targetClient : ClientWrapper , dialect : DatabaseDialect ) : Promise < string | null > {
54+ if ( ! isDialectTopologyAware ( dialect ) ) {
55+ throw new AwsWrapperError ( Messages . get ( "RdsHostListProvider.incorrectDialect" ) ) ;
56+ }
57+
58+ const results = await dialect . queryForTopology ( targetClient ) ;
59+ const match = results . find ( ( row ) => row . id === instanceId ) ;
60+ return match ?. awsRegion ?? null ;
61+ }
62+
63+ parseInstanceTemplates (
64+ instanceTemplatesString : string | null ,
65+ hostValidator : ( hostPattern : string ) => void ,
66+ hostInfoBuilderFunc : ( ) => HostInfoBuilder
67+ ) : Map < string , HostInfo > {
68+ if ( ! instanceTemplatesString ) {
69+ throw new AwsWrapperError ( Messages . get ( "GlobalTopologyUtils.globalClusterInstanceHostPatternsRequired" ) ) ;
70+ }
71+
72+ const instanceTemplates = new Map < string , HostInfo > ( ) ;
73+ const patterns = instanceTemplatesString . split ( "," ) ;
74+
75+ for ( const pattern of patterns ) {
76+ const trimmedPattern = pattern . trim ( ) ;
77+ const colonIndex = trimmedPattern . indexOf ( ":" ) ;
78+ if ( colonIndex === - 1 ) {
79+ throw new AwsWrapperError ( Messages . get ( "GlobalTopologyUtils.invalidPatternFormat" , trimmedPattern ) ) ;
80+ }
81+
82+ const region = trimmedPattern . substring ( 0 , colonIndex ) . trim ( ) ;
83+ const hostPattern = trimmedPattern . substring ( colonIndex + 1 ) . trim ( ) ;
84+
85+ if ( ! region || ! hostPattern ) {
86+ throw new AwsWrapperError ( Messages . get ( "GlobalTopologyUtils.invalidPatternFormat" , trimmedPattern ) ) ;
87+ }
88+
89+ hostValidator ( hostPattern ) ;
90+
91+ const hostInfo = hostInfoBuilderFunc ( ) . withHost ( hostPattern ) . build ( ) ;
92+ instanceTemplates . set ( region , hostInfo ) ;
93+ }
94+
95+ logger . debug ( `Detected Global Database patterns: ${ JSON . stringify ( Array . from ( instanceTemplates . entries ( ) ) ) } ` ) ;
96+
97+ return instanceTemplates ;
98+ }
99+
50100 private createHostsWithTemplateMap (
51101 topologyQueryResults : TopologyQueryResult [ ] ,
52102 initialHost : HostInfo ,
0 commit comments