@@ -108,15 +108,16 @@ func (a *AmqpConnOptions) isOAuth2() bool {
108108func (a * AmqpConnOptions ) Clone () * AmqpConnOptions {
109109
110110 cloned := & AmqpConnOptions {
111- ContainerID : a .ContainerID ,
112- IdleTimeout : a .IdleTimeout ,
113- MaxFrameSize : a .MaxFrameSize ,
114- MaxSessions : a .MaxSessions ,
115- Properties : a .Properties ,
116- SASLType : a .SASLType ,
117- TLSConfig : a .TLSConfig ,
118- WriteTimeout : a .WriteTimeout ,
119- Id : a .Id ,
111+ ContainerID : a .ContainerID ,
112+ IdleTimeout : a .IdleTimeout ,
113+ MaxFrameSize : a .MaxFrameSize ,
114+ MaxSessions : a .MaxSessions ,
115+ Properties : a .Properties ,
116+ SASLType : a .SASLType ,
117+ TLSConfig : a .TLSConfig ,
118+ WriteTimeout : a .WriteTimeout ,
119+ Id : a .Id ,
120+ TopologyRecoveryOptions : a .TopologyRecoveryOptions ,
120121 }
121122 if a .OAuth2Options != nil {
122123 cloned .OAuth2Options = a .OAuth2Options .Clone ()
@@ -126,7 +127,6 @@ func (a *AmqpConnOptions) Clone() *AmqpConnOptions {
126127 }
127128
128129 return cloned
129-
130130}
131131
132132type AmqpConnection struct {
@@ -517,8 +517,8 @@ func (a *AmqpConnection) maybeReconnect() {
517517 cancel ()
518518
519519 if err == nil {
520+ a .recoverTopology ()
520521 a .restartEntities ()
521- // TODO: integration point for topology recovery
522522 a .lifeCycle .SetState (& StateOpen {})
523523 return
524524 }
@@ -573,6 +573,39 @@ func (a *AmqpConnection) restartEntities() {
573573 "consumerFails" , consumerFails )
574574}
575575
576+ func (a * AmqpConnection ) recoverTopology () {
577+ Debug ("Recovering topology" )
578+ // Set the isRecovering flag to prevent duplicate recovery records.
579+ // Using atomic operations since this runs in the recovery goroutine
580+ // while public API methods can be called from user goroutines.
581+ a .management .isRecovering .Store (true )
582+ defer func () {
583+ a .management .isRecovering .Store (false )
584+ }()
585+
586+ for _ , exchange := range a .topologyRecoveryRecords .exchanges {
587+ Debug ("Recovering exchange" , "exchange" , exchange .exchangeName )
588+ _ , err := a .Management ().DeclareExchange (context .Background (), exchange .toIExchangeSpecification ())
589+ if err != nil {
590+ Error ("Failed to recover exchange" , "error" , err , "ID" , a .Id (), "exchange" , exchange .exchangeName )
591+ }
592+ }
593+ for _ , queue := range a .topologyRecoveryRecords .queues {
594+ Debug ("Recovering queue" , "queue" , queue .queueName )
595+ _ , err := a .Management ().DeclareQueue (context .Background (), queue .toIQueueSpecification ())
596+ if err != nil {
597+ Error ("Failed to recover queue" , "error" , err , "ID" , a .Id (), "queue" , queue .queueName )
598+ }
599+ }
600+ for _ , binding := range a .topologyRecoveryRecords .bindings {
601+ Debug ("Recovering binding" , "bind source" , binding .sourceExchange , "bind destination" , binding .destination )
602+ _ , err := a .Management ().Bind (context .Background (), binding .toIBindingSpecification ())
603+ if err != nil {
604+ Error ("Failed to recover binding" , "error" , err , "ID" , a .Id (), "bind source" , binding .sourceExchange , "bind destination" , binding .destination )
605+ }
606+ }
607+ }
608+
576609func (a * AmqpConnection ) close () {
577610 if a .refMap != nil {
578611 a .refMap .Delete (a .Id ())
0 commit comments