@@ -17,38 +17,50 @@ import (
1717
1818type AmqpConnection struct {
1919 Connection * amqp.Conn
20- management IManagement
20+ management * AmqpManagement
2121 lifeCycle * LifeCycle
2222 session * amqp.Session
2323}
2424
25- func (a * AmqpConnection ) Publisher (ctx context.Context , destinationAdd string , linkName string ) (IPublisher , error ) {
26- sender , err := a .session .NewSender (ctx , destinationAdd , createSenderLinkOptions (destinationAdd , linkName ))
25+ func (a * AmqpConnection ) Publisher (ctx context.Context , destinationAdd string , linkName string ) (* Publisher , error ) {
26+ if ! validateAddress (destinationAdd ) {
27+ return nil , fmt .Errorf ("invalid destination address, the address should start with /%s/ or/%s/ " , exchanges , queues )
28+ }
29+
30+ sender , err := a .session .NewSender (ctx , destinationAdd , createSenderLinkOptions (destinationAdd , linkName , AtLeastOnce ))
2731 if err != nil {
2832 return nil , err
2933 }
3034 return newPublisher (sender ), nil
3135}
3236
33- // Management returns the management interface for the connection.
34- // See IManagement interface.
35- func (a * AmqpConnection ) Management () IManagement {
36- return a .management
37- }
38-
39- // Dial creates a new AmqpConnection
40- // with a new AmqpManagement and a new LifeCycle.
41- // Returns a pointer to the new AmqpConnection
42- func Dial (ctx context.Context , addr string , connOptions * amqp.ConnOptions ) (IConnection , error ) {
37+ // Dial connect to the AMQP 1.0 server using the provided connectionSettings
38+ // Returns a pointer to the new AmqpConnection if successful else an error.
39+ // addresses is a list of addresses to connect to. It picks one randomly.
40+ // It is enough that one of the addresses is reachable.
41+ func Dial (ctx context.Context , addresses []string , connOptions * amqp.ConnOptions ) (* AmqpConnection , error ) {
4342 conn := & AmqpConnection {
4443 management : NewAmqpManagement (),
4544 lifeCycle : NewLifeCycle (),
4645 }
47- err := conn .open (ctx , addr , connOptions )
48- if err != nil {
49- return nil , err
46+ tmp := make ([]string , len (addresses ))
47+ copy (tmp , addresses )
48+
49+ // random pick and extract one address to use for connection
50+ for len (tmp ) > 0 {
51+ idx := random (len (tmp ))
52+ addr := tmp [idx ]
53+ // remove the index from the tmp list
54+ tmp = append (tmp [:idx ], tmp [idx + 1 :]... )
55+ err := conn .open (ctx , addr , connOptions )
56+ if err != nil {
57+ Error ("Failed to open connection" , ExtractWithoutPassword (addr ), err )
58+ continue
59+ }
60+ Debug ("Connected to" , ExtractWithoutPassword (addr ))
61+ return conn , nil
5062 }
51- return conn , nil
63+ return nil , fmt . Errorf ( "no address to connect to" )
5264}
5365
5466// Open opens a connection to the AMQP 1.0 server.
@@ -84,30 +96,42 @@ func (a *AmqpConnection) open(ctx context.Context, addr string, connOptions *amq
8496 if err != nil {
8597 return err
8698 }
87- err = a .Management () .Open (ctx , a )
99+ err = a .management .Open (ctx , a )
88100 if err != nil {
89101 // TODO close connection?
90102 return err
91103 }
92104
93- a .lifeCycle .SetStatus ( Open )
105+ a .lifeCycle .SetState ( & StateOpen {} )
94106 return nil
95107}
96108
97109func (a * AmqpConnection ) Close (ctx context.Context ) error {
98- err := a .Management () .Close (ctx )
110+ err := a .management .Close (ctx )
99111 if err != nil {
100112 return err
101113 }
102114 err = a .Connection .Close ()
103- a .lifeCycle .SetStatus ( Closed )
115+ a .lifeCycle .SetState ( & StateClosed {} )
104116 return err
105117}
106118
107- func (a * AmqpConnection ) NotifyStatusChange (channel chan * StatusChanged ) {
119+ // NotifyStatusChange registers a channel to receive getState change notifications
120+ // from the connection.
121+ func (a * AmqpConnection ) NotifyStatusChange (channel chan * StateChanged ) {
108122 a .lifeCycle .chStatusChanged = channel
109123}
110124
111- func (a * AmqpConnection ) Status () int {
112- return a .lifeCycle .Status ()
125+ func (a * AmqpConnection ) State () LifeCycleState {
126+ return a .lifeCycle .State ()
127+ }
128+
129+ // *** management section ***
130+
131+ // Management returns the management interface for the connection.
132+ // The management interface is used to declare and delete exchanges, queues, and bindings.
133+ func (a * AmqpConnection ) Management () * AmqpManagement {
134+ return a .management
113135}
136+
137+ //*** end management section ***
0 commit comments