Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions Sources/ConsulServiceDiscovery/Consul.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
case httpResponseError(HTTPResponseStatus, String?)
case failedToDecodeValue(String)
case error(String)
case emptyHost
case invalidPort(String)
case portOutOfRange(String)
}

protocol ConsulResponseHandler: Sendable {
Expand Down Expand Up @@ -357,7 +360,7 @@
let values = try buffer.withUnsafeReadableBytes {
try JSONDecoder().decode([Value].self, from: Data($0))
}
if values.count > 0 {

Check failure on line 363 in Sources/ConsulServiceDiscovery/Consul.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Empty Count Violation: Prefer checking `isEmpty` over comparing `count` to zero (empty_count)
let value = values[0]
if let valueValue = value.value {
if let data = Data(base64Encoded: valueValue), let str = String(data: data, encoding: .utf8) {
Expand Down Expand Up @@ -848,7 +851,7 @@
}
}

public init(host: String? = nil, port: Int? = nil, logLevel: Logger.Level = .info) {
public init(host: String, port: Int, logLevel: Logger.Level = .info) {
// We use EventLoopFuture<> as a result for most calls,
// the problem here is the 'future' is tied to particular event loop,
// and from SwiftNIO point of view it is an error if we fill the 'future'
Expand All @@ -858,8 +861,6 @@
// The only way to workaround that issue now is to use an event loop group
// with only one event loop.
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let host = host ?? Self.defaultHost
let port = port ?? Self.defaultPort
impl = Impl(host, port, logLevel, eventLoopGroup)
agent = AgentEndpoint(impl)
catalog = CatalogEndpoint(impl)
Expand All @@ -869,6 +870,44 @@
status = StatusEndpoint(impl)
}

convenience public init(host: String? = nil, port: Int? = nil, logLevel: Logger.Level = .info) {
self.init(
host: host ?? Self.defaultHost,
port: port ?? Self.defaultPort,
logLevel: logLevel
)
}

static func parseAddress(_ address: String?) throws -> (host: String, port: Int) {
if let address, !address.isEmpty {
guard let colon = address.lastIndex(of: ":") else {
return (address, Self.defaultPort)
}

let host = String(address[..<colon])
if host.isEmpty {
throw ConsulError.emptyHost
}

let str = address[address.index(after: colon)...]
guard let port = Int(str) else {
throw ConsulError.invalidPort(String(str))
}
guard (0...65535).contains(port) else {
throw ConsulError.portOutOfRange(String(str))
}

return (host, port)
} else {
return (Self.defaultHost, Self.defaultPort)
}
}
Comment thread
ser-0xff marked this conversation as resolved.

convenience public init(address: String?, logLevel: Logger.Level = .info) throws {
let (host, port) = try Self.parseAddress(address)
self.init(host: host, port: port, logLevel: logLevel)
}

public func syncShutdown() throws {
try impl.eventLoopGroup.syncShutdownGracefully()
}
Expand Down Expand Up @@ -993,4 +1032,4 @@
}
context.close(promise: nil)
}
}

Check failure on line 1035 in Sources/ConsulServiceDiscovery/Consul.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

File Length Violation: File should contain 1000 lines or less: currently contains 1035 (file_length)
55 changes: 53 additions & 2 deletions Tests/ConsulServiceDiscoveryTests/ConsulTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@testable import ConsulServiceDiscovery
import NIOPosix
import class NIOCore.EventLoopFuture

Check failure on line 3 in Tests/ConsulServiceDiscoveryTests/ConsulTests.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Sorted Imports Violation: Imports should be sorted (sorted_imports)
import XCTest

final class ConsulTests: XCTestCase {
Expand Down Expand Up @@ -145,7 +145,7 @@
let testKey = "test-key-does-not-exist"
let future = consul.kv.valueForKey(testKey)
let value = try future.wait()
XCTAssertEqual(value, nil)
XCTAssertNil(value)
try consul.syncShutdown()
}

Expand All @@ -153,12 +153,12 @@
let pid = ProcessInfo.processInfo.processIdentifier
let consul = Consul()

let session1 = Session(lockDelay: 1*1_000_000_000, ttl: "10s")

Check failure on line 156 in Tests/ConsulServiceDiscoveryTests/ConsulTests.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used (operator_usage_whitespace)
let session1Future = consul.session.create(session1)
let session1Id = try session1Future.wait()
// print("session1=\(session1Id)")

let session2 = Session(lockDelay: 1*1_000_000_000, ttl: "10s")

Check failure on line 161 in Tests/ConsulServiceDiscoveryTests/ConsulTests.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used (operator_usage_whitespace)
let session2Future = consul.session.create(session2)
let session2Id = try session2Future.wait()
// print("session2=\(session2Id)")
Expand All @@ -178,8 +178,59 @@

let renewFuture = consul.session.renew(session1Id)
let renewResult = try renewFuture.wait()
//print("\(renewResult)")
// print("\(renewResult)")
XCTAssertEqual(renewResult.lockDelay!.ns, 1_000_000_000)
XCTAssertEqual(renewResult.ttl, "10s")
}

func testParseAddress() throws {
var (host, port): (String, Int)

(host, port) = try Consul.parseAddress(nil)
XCTAssertEqual(host, Consul.defaultHost)
XCTAssertEqual(port, Consul.defaultPort)

(host, port) = try Consul.parseAddress("")
XCTAssertEqual(host, Consul.defaultHost)
XCTAssertEqual(port, Consul.defaultPort)

(host, port) = try Consul.parseAddress("localhost")
XCTAssertEqual(host, "localhost")
XCTAssertEqual(port, Consul.defaultPort)

(host, port) = try Consul.parseAddress("localhost:12345")
XCTAssertEqual(host, "localhost")
XCTAssertEqual(port, 12_345)
Comment thread
ser-0xff marked this conversation as resolved.

XCTAssertThrowsError(try Consul.parseAddress(":8500")) { error in
guard let error = error as? ConsulError, case .emptyHost = error else {
XCTFail("expected ConsulError.emptyHost, got \(error)")
return
}
}

XCTAssertThrowsError(try Consul.parseAddress("localhost:")) { error in
guard let error = error as? ConsulError, case let .invalidPort(value) = error else {
XCTFail("expected ConsulError.invalidPort, got \(error)")
return
}
XCTAssertEqual(value, "")
}

XCTAssertThrowsError(try Consul.parseAddress("localhost:abc")) { error in
guard let error = error as? ConsulError, case let .invalidPort(value) = error else {
XCTFail("expected ConsulError.invalidPort, got \(error)")
return
}
XCTAssertEqual(value, "abc")
}

XCTAssertThrowsError(try Consul.parseAddress("localhost:999999")) { error in
guard let error = error as? ConsulError, case let .portOutOfRange(value) = error else {
XCTFail("expected ConsulError.portOutOfRange, got \(error)")
return
}
XCTAssertEqual(value, "999999")
}
}
}
Loading