203 lines
6.7 KiB
Swift
203 lines
6.7 KiB
Swift
// Copyright 2024 The NATS Authors
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
import Dispatch
|
|
import Foundation
|
|
import Logging
|
|
import NIO
|
|
import NIOFoundationCompat
|
|
|
|
public class NatsClientOptions {
|
|
private var urls: [URL] = []
|
|
private var pingInterval: TimeInterval = 60.0
|
|
private var reconnectWait: TimeInterval = 2.0
|
|
private var maxReconnects: Int?
|
|
private var initialReconnect = false
|
|
private var noRandomize = false
|
|
private var auth: Auth? = nil
|
|
private var withTls = false
|
|
private var tlsFirst = false
|
|
private var rootCertificate: URL? = nil
|
|
private var clientCertificate: URL? = nil
|
|
private var clientKey: URL? = nil
|
|
private var inboxPrefix: String = "_INBOX."
|
|
|
|
public init() {}
|
|
|
|
/// Sets the prefix for inbox subjects used for request/reply.
|
|
/// Defaults to "_INBOX."
|
|
public func inboxPrefix(_ prefix: String) -> NatsClientOptions {
|
|
if prefix.isEmpty {
|
|
self.inboxPrefix = "_INBOX."
|
|
return self
|
|
}
|
|
if prefix.last != "." {
|
|
self.inboxPrefix = prefix + "."
|
|
return self
|
|
}
|
|
self.inboxPrefix = prefix
|
|
return self
|
|
}
|
|
|
|
/// A list of server urls that a client can connect to.
|
|
public func urls(_ urls: [URL]) -> NatsClientOptions {
|
|
self.urls = urls
|
|
return self
|
|
}
|
|
|
|
/// A single url that the client can connect to.
|
|
public func url(_ url: URL) -> NatsClientOptions {
|
|
self.urls = [url]
|
|
return self
|
|
}
|
|
|
|
/// The interval with which the client will send pings to NATS server.
|
|
/// Defaults to 60s.
|
|
public func pingInterval(_ pingInterval: TimeInterval) -> NatsClientOptions {
|
|
self.pingInterval = pingInterval
|
|
return self
|
|
}
|
|
|
|
/// Wait time between reconnect attempts.
|
|
/// Defaults to 2s.
|
|
public func reconnectWait(_ reconnectWait: TimeInterval) -> NatsClientOptions {
|
|
self.reconnectWait = reconnectWait
|
|
return self
|
|
}
|
|
|
|
/// Maximum number of reconnect attempts after each disconnect.
|
|
/// Defaults to unlimited.
|
|
public func maxReconnects(_ maxReconnects: Int) -> NatsClientOptions {
|
|
self.maxReconnects = maxReconnects
|
|
return self
|
|
}
|
|
|
|
/// Username and password used to connect to the server.
|
|
public func usernameAndPassword(_ username: String, _ password: String) -> NatsClientOptions {
|
|
if self.auth == nil {
|
|
self.auth = Auth(user: username, password: password)
|
|
} else {
|
|
self.auth?.user = username
|
|
self.auth?.password = password
|
|
}
|
|
return self
|
|
}
|
|
|
|
/// Token used for token auth to NATS server.
|
|
public func token(_ token: String) -> NatsClientOptions {
|
|
if self.auth == nil {
|
|
self.auth = Auth(token: token)
|
|
} else {
|
|
self.auth?.token = token
|
|
}
|
|
return self
|
|
}
|
|
|
|
/// The location of a credentials file containing user JWT and Nkey seed.
|
|
public func credentialsFile(_ credentials: URL) -> NatsClientOptions {
|
|
if self.auth == nil {
|
|
self.auth = Auth.fromCredentials(credentials)
|
|
} else {
|
|
self.auth?.credentialsPath = credentials
|
|
}
|
|
return self
|
|
}
|
|
|
|
/// The location of a public nkey file.
|
|
/// This and ``NatsClientOptions/nkey(_:)`` are mutually exclusive.
|
|
public func nkeyFile(_ nkey: URL) -> NatsClientOptions {
|
|
if self.auth == nil {
|
|
self.auth = Auth.fromNkey(nkey)
|
|
} else {
|
|
self.auth?.nkeyPath = nkey
|
|
}
|
|
return self
|
|
}
|
|
|
|
/// Public nkey.
|
|
/// This and ``NatsClientOptions/nkeyFile(_:)`` are mutually exclusive.
|
|
public func nkey(_ nkey: String) -> NatsClientOptions {
|
|
if self.auth == nil {
|
|
self.auth = Auth.fromNkey(nkey)
|
|
} else {
|
|
self.auth?.nkey = nkey
|
|
}
|
|
return self
|
|
}
|
|
|
|
/// Indicates whether the client requires an SSL connection.
|
|
public func requireTls() -> NatsClientOptions {
|
|
self.withTls = true
|
|
return self
|
|
}
|
|
|
|
/// Indicates whether the client will attempt to perform a TLS handshake first, that is
|
|
/// before receiving the INFO protocol. This requires the server to also be
|
|
/// configured with such option, otherwise the connection will fail.
|
|
public func withTlsFirst() -> NatsClientOptions {
|
|
self.tlsFirst = true
|
|
return self
|
|
}
|
|
|
|
/// The location of a root CAs file.
|
|
public func rootCertificates(_ rootCertificate: URL) -> NatsClientOptions {
|
|
self.rootCertificate = rootCertificate
|
|
return self
|
|
}
|
|
|
|
/// The location of a client cert file.
|
|
public func clientCertificate(_ clientCertificate: URL, _ clientKey: URL) -> NatsClientOptions {
|
|
self.clientCertificate = clientCertificate
|
|
self.clientKey = clientKey
|
|
return self
|
|
}
|
|
|
|
/// Indicates whether the client will retain the order of URLs to connect to provided in ``NatsClientOptions/urls(_:)``
|
|
/// If not set, the client will randomize the server pool.
|
|
public func retainServersOrder() -> NatsClientOptions {
|
|
self.noRandomize = true
|
|
return self
|
|
}
|
|
|
|
/// By default, ``NatsClient/connect()`` will return an error if
|
|
/// the connection to the server cannot be established.
|
|
///
|
|
/// Setting `retryOnfailedConnect()` makes the client
|
|
/// establish the connection in the background even if the initial connect fails.
|
|
public func retryOnfailedConnect() -> NatsClientOptions {
|
|
self.initialReconnect = true
|
|
return self
|
|
}
|
|
|
|
public func build() -> NatsClient {
|
|
let client = NatsClient()
|
|
client.inboxPrefix = inboxPrefix
|
|
client.connectionHandler = ConnectionHandler(
|
|
inputBuffer: client.buffer,
|
|
urls: urls,
|
|
reconnectWait: reconnectWait,
|
|
maxReconnects: maxReconnects,
|
|
retainServersOrder: noRandomize,
|
|
pingInterval: pingInterval,
|
|
auth: auth,
|
|
requireTls: withTls,
|
|
tlsFirst: tlsFirst,
|
|
clientCertificate: clientCertificate,
|
|
clientKey: clientKey,
|
|
rootCertificate: rootCertificate,
|
|
retryOnFailedConnect: initialReconnect
|
|
)
|
|
return client
|
|
}
|
|
}
|