Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7.x.x: Remove EventLoop from Credential Provider context #557

Merged
merged 1 commit into from
Jul 5, 2023
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
1 change: 0 additions & 1 deletion Sources/SotoCore/AWSClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ public final class AWSClient: Sendable {

self.credentialProvider = credentialProviderFactory.createProvider(context: .init(
httpClient: httpClient,
eventLoop: httpClient.eventLoopGroup.next(),
logger: clientLogger,
options: options
))
Expand Down
6 changes: 3 additions & 3 deletions Sources/SotoCore/Credential/ConfigFileLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,16 @@ enum ConfigFileLoader {
let fileIO = NonBlockingFileIO(threadPool: threadPool)

// Load credentials file
return self.loadFile(path: credentialsFilePath, on: context.eventLoop, using: fileIO)
return self.loadFile(path: credentialsFilePath, on: context.httpClient.eventLoopGroup.any(), using: fileIO)
.flatMap { credentialsByteBuffer in
// Load profile config file
return loadFile(path: configFilePath, on: context.eventLoop, using: fileIO)
return loadFile(path: configFilePath, on: context.httpClient.eventLoopGroup.any(), using: fileIO)
.map {
(credentialsByteBuffer, $0)
}
.flatMapError { _ in
// Recover from error if profile config file does not exist
context.eventLoop.makeSucceededFuture((credentialsByteBuffer, nil))
context.httpClient.eventLoopGroup.any().makeSucceededFuture((credentialsByteBuffer, nil))
}
}
.flatMapErrorThrowing { _ in
Expand Down
6 changes: 1 addition & 5 deletions Sources/SotoCore/Credential/CredentialProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@ import SotoSignerV4
public protocol CredentialProvider: Sendable, CustomStringConvertible {
/// Return credential
/// - Parameters:
/// - eventLoop: EventLoop to run on
/// - logger: Logger to use
func getCredential(logger: Logger) async throws -> Credential

/// Shutdown credential provider
/// - Parameter eventLoop: EventLoop to use when shutiting down
func shutdown() async throws
}

Expand All @@ -40,14 +38,12 @@ extension CredentialProvider {
/// Provides factory functions for `CredentialProvider`s.
///
/// The factory functions are only called once the `AWSClient` has been setup. This means we can supply
/// things like a `Logger`, `EventLoop` and `HTTPClient` to the credential provider when we construct it.
/// things like a `Logger` and `HTTPClient` to the credential provider when we construct it.
public struct CredentialProviderFactory {
/// The initialization context for a `ContextProvider`
public struct Context {
/// The `AWSClient`s internal `HTTPClient`
public let httpClient: HTTPClient
/// The `EventLoop` that the `CredentialProvider` should use for credential refreshs
public let eventLoop: EventLoop
/// The `Logger` attached to the AWSClient
public let logger: Logger
/// AWSClient options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,14 @@ import XCTest
class ConfigFileCredentialProviderTests: XCTestCase {
// MARK: - Credential Provider

func makeContext() -> (CredentialProviderFactory.Context, MultiThreadedEventLoopGroup, HTTPClient) {
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let eventLoop = eventLoopGroup.next()
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(eventLoop))
return (.init(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init()), eventLoopGroup, httpClient)
func makeContext() -> (CredentialProviderFactory.Context, HTTPClient) {
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
return (.init(httpClient: httpClient, logger: TestEnvironment.logger, options: .init()), httpClient)
}

func testCredentialProviderStatic() async throws {
let credentials = ConfigFileLoader.SharedCredentials.staticCredential(credential: StaticCredential(accessKeyId: "foo", secretAccessKey: "bar"))
let (context, eventLoopGroup, httpClient) = self.makeContext()
let (context, httpClient) = self.makeContext()

let provider = try ConfigFileCredentialProvider.credentialProvider(
from: credentials,
Expand All @@ -45,7 +43,6 @@ class ConfigFileCredentialProviderTests: XCTestCase {

try await provider.shutdown()
try await httpClient.shutdown()
XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully())
}

func testCredentialProviderSTSAssumeRole() async throws {
Expand All @@ -55,7 +52,7 @@ class ConfigFileCredentialProviderTests: XCTestCase {
region: nil,
sourceCredentialProvider: .static(accessKeyId: "foo", secretAccessKey: "bar")
)
let (context, eventLoopGroup, httpClient) = self.makeContext()
let (context, httpClient) = self.makeContext()

let provider = try ConfigFileCredentialProvider.credentialProvider(
from: credentials,
Expand All @@ -67,7 +64,6 @@ class ConfigFileCredentialProviderTests: XCTestCase {

try await provider.shutdown()
try await httpClient.shutdown()
XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully())
}

// MARK: - Config File Credentials Provider
Expand All @@ -90,7 +86,7 @@ class ConfigFileCredentialProviderTests: XCTestCase {
defer { XCTAssertNoThrow(try httpClient.syncShutdown()) }
let factory = CredentialProviderFactory.configFile(credentialsFilePath: filenameURL.path)

let provider = factory.createProvider(context: .init(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init()))
let provider = factory.createProvider(context: .init(httpClient: httpClient, logger: TestEnvironment.logger, options: .init()))

let credential: Credential = try await provider.getCredential(logger: TestEnvironment.logger)
XCTAssertEqual(credential.accessKeyId, "AWSACCESSKEYID")
Expand Down Expand Up @@ -118,7 +114,7 @@ class ConfigFileCredentialProviderTests: XCTestCase {
defer { XCTAssertNoThrow(try httpClient.syncShutdown()) }
let factory = CredentialProviderFactory.configFile(credentialsFilePath: filenameURL.path)

let provider = factory.createProvider(context: .init(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init()))
let provider = factory.createProvider(context: .init(httpClient: httpClient, logger: TestEnvironment.logger, options: .init()))

let credential: Credential = try await provider.getCredential(logger: TestEnvironment.logger)
XCTAssertEqual(credential.accessKeyId, "TESTPROFILE-AWSACCESSKEYID")
Expand All @@ -136,7 +132,7 @@ class ConfigFileCredentialProviderTests: XCTestCase {
defer { XCTAssertNoThrow(try httpClient.syncShutdown()) }
let factory = CredentialProviderFactory.configFile(credentialsFilePath: filenameURL.path)

let provider = factory.createProvider(context: .init(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init()))
let provider = factory.createProvider(context: .init(httpClient: httpClient, logger: TestEnvironment.logger, options: .init()))

do {
_ = try await provider.getCredential(logger: TestEnvironment.logger)
Expand Down Expand Up @@ -166,12 +162,11 @@ class ConfigFileCredentialProviderTests: XCTestCase {
let filename = #function
let filenameURL = URL(fileURLWithPath: filename)
XCTAssertNoThrow(try Data(credentialsFile.utf8).write(to: filenameURL))
let (context, eventLoopGroup, httpClient) = makeContext()
let (context, httpClient) = makeContext()

defer {
XCTAssertNoThrow(try FileManager.default.removeItem(at: filenameURL))
XCTAssertNoThrow(try httpClient.syncShutdown())
XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully())
}

let sharedCredentials = try await ConfigFileLoader.loadSharedCredentials(
Expand Down
32 changes: 11 additions & 21 deletions Tests/SotoCoreTests/Credential/ConfigFileLoaderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ import XCTest
class ConfigFileLoadersTests: XCTestCase {
// MARK: - File Loading

func makeContext() throws -> (CredentialProviderFactory.Context, MultiThreadedEventLoopGroup, HTTPClient) {
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let eventLoop = eventLoopGroup.next()
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(eventLoop))
return (.init(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init()), eventLoopGroup, httpClient)
func makeContext() throws -> (CredentialProviderFactory.Context, HTTPClient) {
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
return (.init(httpClient: httpClient, logger: TestEnvironment.logger, options: .init()), httpClient)
}

func save(content: String, prefix: String) throws -> String {
Expand All @@ -48,12 +46,11 @@ class ConfigFileLoadersTests: XCTestCase {
"""

let credentialsPath = try save(content: credentialsFile, prefix: #function)
let (context, eventLoopGroup, httpClient) = try makeContext()
let (context, httpClient) = try makeContext()

defer {
try? FileManager.default.removeItem(atPath: credentialsPath)
try? httpClient.syncShutdown()
try? eventLoopGroup.syncShutdownGracefully()
}

let sharedCredentials = try await ConfigFileLoader.loadSharedCredentials(
Expand Down Expand Up @@ -95,13 +92,12 @@ class ConfigFileLoadersTests: XCTestCase {

let credentialsPath = try save(content: credentialsFile, prefix: #function)
let configPath = try save(content: configFile, prefix: "config")
let (context, eventLoopGroup, httpClient) = try makeContext()
let (context, httpClient) = try makeContext()

defer {
try? FileManager.default.removeItem(atPath: credentialsPath)
try? FileManager.default.removeItem(atPath: configPath)
try? httpClient.syncShutdown()
try? eventLoopGroup.syncShutdownGracefully()
}

let sharedCredentials = try await ConfigFileLoader.loadSharedCredentials(
Expand Down Expand Up @@ -134,12 +130,11 @@ class ConfigFileLoadersTests: XCTestCase {
"""

let credentialsPath = try save(content: credentialsFile, prefix: #function)
let (context, eventLoopGroup, httpClient) = try makeContext()
let (context, httpClient) = try makeContext()

defer {
try? FileManager.default.removeItem(atPath: credentialsPath)
try? httpClient.syncShutdown()
try? eventLoopGroup.syncShutdownGracefully()
}

let sharedCredentials = try await ConfigFileLoader.loadSharedCredentials(
Expand Down Expand Up @@ -170,12 +165,11 @@ class ConfigFileLoadersTests: XCTestCase {
"""

let credentialsPath = try save(content: credentialsFile, prefix: #function)
let (context, eventLoopGroup, httpClient) = try makeContext()
let (context, httpClient) = try makeContext()

defer {
try? FileManager.default.removeItem(atPath: credentialsPath)
try? httpClient.syncShutdown()
try? eventLoopGroup.syncShutdownGracefully()
}

do {
Expand All @@ -201,12 +195,11 @@ class ConfigFileLoadersTests: XCTestCase {
"""

let credentialsPath = try save(content: credentialsFile, prefix: #function)
let (context, eventLoopGroup, httpClient) = try makeContext()
let (context, httpClient) = try makeContext()

defer {
try? FileManager.default.removeItem(atPath: credentialsPath)
try? httpClient.syncShutdown()
try? eventLoopGroup.syncShutdownGracefully()
}

do {
Expand Down Expand Up @@ -237,12 +230,11 @@ class ConfigFileLoadersTests: XCTestCase {
"""

let credentialsPath = try save(content: credentialsFile, prefix: #function)
let (context, eventLoopGroup, httpClient) = try makeContext()
let (context, httpClient) = try makeContext()

defer {
try? FileManager.default.removeItem(atPath: credentialsPath)
try? httpClient.syncShutdown()
try? eventLoopGroup.syncShutdownGracefully()
}

do {
Expand Down Expand Up @@ -273,12 +265,11 @@ class ConfigFileLoadersTests: XCTestCase {
"""

let credentialsPath = try save(content: credentialsFile, prefix: #function)
let (context, eventLoopGroup, httpClient) = try makeContext()
let (context, httpClient) = try makeContext()

defer {
try? FileManager.default.removeItem(atPath: credentialsPath)
try? httpClient.syncShutdown()
try? eventLoopGroup.syncShutdownGracefully()
}

do {
Expand All @@ -304,12 +295,11 @@ class ConfigFileLoadersTests: XCTestCase {
"""

let credentialsPath = try save(content: credentialsFile, prefix: #function)
let (context, eventLoopGroup, httpClient) = try makeContext()
let (context, httpClient) = try makeContext()

defer {
try? FileManager.default.removeItem(atPath: credentialsPath)
try? httpClient.syncShutdown()
try? eventLoopGroup.syncShutdownGracefully()
}

do {
Expand Down
14 changes: 6 additions & 8 deletions Tests/SotoCoreTests/Credential/CredentialProviderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ final class CredentialProviderTests: XCTestCase {
defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) }
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(eventLoopGroup))
defer { XCTAssertNoThrow(try httpClient.syncShutdown()) }
let eventLoop = eventLoopGroup.next()
let context = CredentialProviderFactory.Context(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init())
let context = CredentialProviderFactory.Context(httpClient: httpClient, logger: TestEnvironment.logger, options: .init())
let myCredentialProvider = MyCredentialProvider()
let deferredProvider = DeferredCredentialProvider(context: context, provider: myCredentialProvider)
_ = try await deferredProvider.getCredential(logger: TestEnvironment.logger)
Expand All @@ -70,8 +69,8 @@ final class CredentialProviderTests: XCTestCase {
defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) }
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(eventLoopGroup))
defer { XCTAssertNoThrow(try httpClient.syncShutdown()) }
let eventLoop = eventLoopGroup.next()
let context = CredentialProviderFactory.Context(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init())

let context = CredentialProviderFactory.Context(httpClient: httpClient, logger: TestEnvironment.logger, options: .init())
let myCredentialProvider = MyCredentialProvider()
let deferredProvider = DeferredCredentialProvider(context: context, provider: myCredentialProvider)
try await deferredProvider.shutdown()
Expand All @@ -95,7 +94,7 @@ final class CredentialProviderTests: XCTestCase {
defer { XCTAssertNoThrow(try httpClient.syncShutdown()) }
let factory = CredentialProviderFactory.configFile(credentialsFilePath: filenameURL.path)

let provider = factory.createProvider(context: .init(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init()))
let provider = factory.createProvider(context: .init(httpClient: httpClient, logger: TestEnvironment.logger, options: .init()))

let credential = try await provider.getCredential(logger: TestEnvironment.logger)
XCTAssertEqual(credential.accessKeyId, "AWSACCESSKEYID")
Expand All @@ -113,7 +112,7 @@ final class CredentialProviderTests: XCTestCase {
defer { XCTAssertNoThrow(try httpClient.syncShutdown()) }
let factory = CredentialProviderFactory.configFile(credentialsFilePath: filenameURL.path)

let provider = factory.createProvider(context: .init(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init()))
let provider = factory.createProvider(context: .init(httpClient: httpClient, logger: TestEnvironment.logger, options: .init()))

do {
_ = try await provider.getCredential(logger: TestEnvironment.logger)
Expand All @@ -140,8 +139,7 @@ final class CredentialProviderTests: XCTestCase {
defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) }
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(eventLoopGroup))
defer { XCTAssertNoThrow(try httpClient.syncShutdown()) }
let eventLoop = eventLoopGroup.next()
let context = CredentialProviderFactory.Context(httpClient: httpClient, eventLoop: eventLoop, logger: TestEnvironment.logger, options: .init())
let context = CredentialProviderFactory.Context(httpClient: httpClient, logger: TestEnvironment.logger, options: .init())
let testCredentialProvider = TestCredentialProvider()

let deferredProvider = DeferredCredentialProvider(context: context, provider: testCredentialProvider)
Expand Down
Loading