@@ -17,38 +17,50 @@ import (
17
17
18
18
type AmqpConnection struct {
19
19
Connection * amqp.Conn
20
- management IManagement
20
+ management * AmqpManagement
21
21
lifeCycle * LifeCycle
22
22
session * amqp.Session
23
23
}
24
24
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 ))
27
31
if err != nil {
28
32
return nil , err
29
33
}
30
34
return newPublisher (sender ), nil
31
35
}
32
36
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 ) {
43
42
conn := & AmqpConnection {
44
43
management : NewAmqpManagement (),
45
44
lifeCycle : NewLifeCycle (),
46
45
}
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
50
62
}
51
- return conn , nil
63
+ return nil , fmt . Errorf ( "no address to connect to" )
52
64
}
53
65
54
66
// 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
84
96
if err != nil {
85
97
return err
86
98
}
87
- err = a .Management () .Open (ctx , a )
99
+ err = a .management .Open (ctx , a )
88
100
if err != nil {
89
101
// TODO close connection?
90
102
return err
91
103
}
92
104
93
- a .lifeCycle .SetStatus ( Open )
105
+ a .lifeCycle .SetState ( & StateOpen {} )
94
106
return nil
95
107
}
96
108
97
109
func (a * AmqpConnection ) Close (ctx context.Context ) error {
98
- err := a .Management () .Close (ctx )
110
+ err := a .management .Close (ctx )
99
111
if err != nil {
100
112
return err
101
113
}
102
114
err = a .Connection .Close ()
103
- a .lifeCycle .SetStatus ( Closed )
115
+ a .lifeCycle .SetState ( & StateClosed {} )
104
116
return err
105
117
}
106
118
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 ) {
108
122
a .lifeCycle .chStatusChanged = channel
109
123
}
110
124
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
113
135
}
136
+
137
+ //*** end management section ***
0 commit comments