Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b7df1f7

Browse files
authoredNov 28, 2024··
Merge pull request #50 from xtremekforever/feature/connection-configuration-constructors
Add more options to AMQPConnectionConfiguration convenience inits
2 parents cb9c294 + e6c22b5 commit b7df1f7

File tree

2 files changed

+58
-17
lines changed

2 files changed

+58
-17
lines changed
 

‎Sources/AMQPClient/AMQPConnectionConfiguration.swift

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ public struct AMQPConnectionConfiguration: Sendable {
3232
public var vhost: String
3333
public var timeout: TimeAmount
3434
public var connectionName: String
35-
35+
3636
public init(host: String? = nil,
3737
port: Int? = nil,
3838
user: String? = nil,
3939
password: String? = nil,
4040
vhost: String? = nil,
4141
timeout: TimeAmount? = nil,
4242
connectionName: String? = nil) {
43-
43+
4444
self.host = host ?? Defaults.host
4545
self.port = port ?? Defaults.port
4646
self.user = user ?? Defaults.user
@@ -62,25 +62,43 @@ public extension AMQPConnectionConfiguration {
6262
enum UrlScheme: String {
6363
case amqp = "amqp"
6464
case amqps = "amqps"
65-
65+
6666
var defaultPort: Int {
6767
switch self {
6868
case .amqp: return Server.Defaults.port
6969
case .amqps: return Server.Defaults.tlsPort
7070
}
7171
}
7272
}
73-
74-
init(url: String, tls: TLSConfiguration? = nil) throws {
73+
74+
/// Convenience init to create connection configuration from a URL string + key options.
75+
///
76+
/// - Parameters:
77+
/// - url: A string that contains the URL to create configuration from.
78+
/// - tls: Optional TLS configuration. If `nil`, default will be used.
79+
/// - sniServerName: Server name to use for TLS connection. If `nil`, default will be used.
80+
/// - timeout: Optional connection timeout. If `nil`, default timeout will be used.
81+
/// - connectionName: Optional connection name. If `nil`, default connection name will be used.
82+
/// - Throws: `AMQPConnectionError.invalidUrl` if URL is invalid, or `AMQPConnectionError.invalidUrlScheme` if URL scheme is not supported.
83+
init(url: String, tls: TLSConfiguration? = nil, sniServerName: String? = nil, timeout: TimeAmount? = nil, connectionName: String? = nil) throws {
7584
guard let url = URL(string: url) else { throw AMQPConnectionError.invalidUrl }
76-
try self.init(url: url, tls: tls)
85+
try self.init(url: url, tls: tls, sniServerName: sniServerName, timeout: timeout, connectionName: connectionName)
7786
}
7887

79-
init(url: URL, tls: TLSConfiguration? = nil) throws {
88+
/// Convenience init to create connection configuration from a URL + key options.
89+
///
90+
/// - Parameters:
91+
/// - url: A URL to create the configuration from.
92+
/// - tls: Optional TLS configuration. If `nil`, default will be used.
93+
/// - sniServerName: Server name to use for TLS connection. If `nil`, default will be used.
94+
/// - timeout: Optional connection timeout. If `nil`, default timeout will be used.
95+
/// - connectionName: Optional connection name. If `nil`, default connection name will be used.
96+
/// - Throws: `AMQPConnectionError.invalidUrlScheme` if URL scheme is not supported.
97+
init(url: URL, tls: TLSConfiguration? = nil, sniServerName: String? = nil, timeout: TimeAmount? = nil, connectionName: String? = nil) throws {
8098
guard let scheme = UrlScheme(rawValue: url.scheme ?? "") else { throw AMQPConnectionError.invalidUrlScheme }
81-
99+
82100
// there is no such thing as a "" host
83-
let host = url.host?.isEmpty == true ? nil : url.host
101+
let host = url.host?.isEmpty == true ? nil : url.host?.removingPercentEncoding
84102
//special path magic for vhost interpretation (see https://www.rabbitmq.com/uri-spec.html)
85103
var vhost = url.path.isEmpty ? nil : String(url.path.removingPercentEncoding?.dropFirst() ?? "")
86104

@@ -89,11 +107,15 @@ public extension AMQPConnectionConfiguration {
89107
vhost = "/"
90108
}
91109

92-
let server = Server(host: host, port: url.port ?? scheme.defaultPort, user: url.user, password: url.password?.removingPercentEncoding, vhost: vhost)
93-
110+
let server = Server(
111+
host: host, port: url.port ?? scheme.defaultPort,
112+
user: url.user?.removingPercentEncoding,password: url.password?.removingPercentEncoding,
113+
vhost: vhost, timeout: timeout, connectionName: connectionName
114+
)
115+
94116
switch scheme {
95117
case .amqp: self = .init(connection: .plain, server: server)
96-
case .amqps: self = .init(connection: .tls(tls, sniServerName: nil), server: server)
118+
case .amqps: self = .init(connection: .tls(tls, sniServerName: sniServerName), server: server)
97119
}
98120
}
99121
}

‎Tests/AMQPClientTests/AMQPConnectionConfigurationTest.swift

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import XCTest
22
import AMQPClient
3+
import NIOSSL
4+
35
@testable import AMQPClient
46

57
@available(macOS 13.0, *)
@@ -14,7 +16,7 @@ final class AMQPClientConfigurationTest: XCTestCase {
1416
XCTAssertEqual(config.server.password, "myPass")
1517
XCTAssertEqual(config.server.vhost, "myVHost")
1618
}
17-
19+
1820
func testFromPlainURLWithDefaults() throws {
1921
let config = try AMQPConnectionConfiguration(url: "amqp://myHost")
2022
guard case .plain = config.connection else { return XCTFail("plain expected") }
@@ -25,7 +27,7 @@ final class AMQPClientConfigurationTest: XCTestCase {
2527
XCTAssertEqual(config.server.password, "guest")
2628
XCTAssertEqual(config.server.vhost, "/")
2729
}
28-
30+
2931
func testFromTlsURLWithOnlyUserAndPassword() throws {
3032
let config = try AMQPConnectionConfiguration(url: "amqps://top:secret@")
3133

@@ -37,7 +39,7 @@ final class AMQPClientConfigurationTest: XCTestCase {
3739
XCTAssertEqual(config.server.password, "secret")
3840
XCTAssertEqual(config.server.vhost, "/")
3941
}
40-
42+
4143
func testWithEmpties() throws {
4244
let c = try AMQPConnectionConfiguration(url: "amqp://@:/")
4345

@@ -47,7 +49,7 @@ final class AMQPClientConfigurationTest: XCTestCase {
4749
XCTAssertEqual(c.server.password, "")
4850
XCTAssertEqual(c.server.vhost, "")
4951
}
50-
52+
5153
func testWithUrlEncodedVHost() throws {
5254
let c = try AMQPConnectionConfiguration(url: "amqps://hello@host:1234/%2f")
5355

@@ -57,7 +59,7 @@ final class AMQPClientConfigurationTest: XCTestCase {
5759
XCTAssertEqual(c.server.password, "")
5860
XCTAssertEqual(c.server.vhost, "/")
5961
}
60-
62+
6163
func testWithUrlEncodedEverything() throws {
6264
let c = try AMQPConnectionConfiguration(url: "amqp://user%61:%61pass@ho%61st:10000/v%2fhost")
6365

@@ -67,4 +69,21 @@ final class AMQPClientConfigurationTest: XCTestCase {
6769
XCTAssertEqual(c.server.password, "apass")
6870
XCTAssertEqual(c.server.vhost, "v/host")
6971
}
72+
73+
func testWithTlsConfigurationPassed() throws {
74+
let tls = TLSConfiguration.makeClientConfiguration()
75+
let c = try AMQPConnectionConfiguration(url: "amqps://myHost", tls: tls, sniServerName: "wow")
76+
77+
if case let .tls(tls, sniServerName) = c.connection {
78+
XCTAssertNotNil(tls)
79+
XCTAssertEqual(sniServerName, "wow")
80+
}
81+
}
82+
83+
func testWithOtherConfigurationPassed() throws {
84+
let c = try AMQPConnectionConfiguration(url: "amqp://myHost", timeout: .seconds(10), connectionName: "MyConnection")
85+
86+
XCTAssertEqual(c.server.timeout, .seconds(10))
87+
XCTAssertEqual(c.server.connectionName, "MyConnection")
88+
}
7089
}

0 commit comments

Comments
 (0)
Please sign in to comment.