diff --git a/Sources/ConfidenceProvider/Apply/FlagApplierWithRetries.swift b/Sources/ConfidenceProvider/Apply/FlagApplierWithRetries.swift index 1dc6d0df..e37c7fe9 100644 --- a/Sources/ConfidenceProvider/Apply/FlagApplierWithRetries.swift +++ b/Sources/ConfidenceProvider/Apply/FlagApplierWithRetries.swift @@ -10,17 +10,20 @@ final class FlagApplierWithRetries: FlagApplier { private let httpClient: HttpClient private let options: ConfidenceClientOptions private let cacheDataInteractor: CacheDataActor + private let metadata: ConfidenceMetadata init( httpClient: HttpClient, storage: Storage, options: ConfidenceClientOptions, + metadata: ConfidenceMetadata, cacheDataInteractor: CacheDataActor? = nil, triggerBatch: Bool = true ) { self.storage = storage self.httpClient = httpClient self.options = options + self.metadata = metadata let storedData = try? storage.load(defaultValue: CacheData.empty()) self.cacheDataInteractor = cacheDataInteractor ?? CacheDataInteractor(cacheData: storedData ?? .empty()) @@ -119,7 +122,8 @@ final class FlagApplierWithRetries: FlagApplier { flags: applyFlagRequestItems, sendTime: Date.backport.nowISOString, clientSecret: options.credentials.getSecret(), - resolveToken: resolveToken + resolveToken: resolveToken, + sdk: Sdk(id: metadata.name, version: metadata.version) ) performRequest(request: request) { result in diff --git a/Sources/ConfidenceProvider/ConfidenceClient/RemoteConfidenceClient.swift b/Sources/ConfidenceProvider/ConfidenceClient/RemoteConfidenceClient.swift index a9db2d2e..35bdd4f0 100644 --- a/Sources/ConfidenceProvider/ConfidenceClient/RemoteConfidenceClient.swift +++ b/Sources/ConfidenceProvider/ConfidenceClient/RemoteConfidenceClient.swift @@ -5,6 +5,7 @@ public class RemoteConfidenceClient: ConfidenceClient { private let targetingKey = "targeting_key" private let flagApplier: FlagApplier private var options: ConfidenceClientOptions + private let metadata: ConfidenceMetadata private var httpClient: HttpClient private var applyOnResolve: Bool @@ -13,12 +14,14 @@ public class RemoteConfidenceClient: ConfidenceClient { options: ConfidenceClientOptions, session: URLSession? = nil, applyOnResolve: Bool, - flagApplier: FlagApplier + flagApplier: FlagApplier, + metadata: ConfidenceMetadata ) { self.options = options self.httpClient = NetworkClient(session: session, region: options.region) self.flagApplier = flagApplier self.applyOnResolve = applyOnResolve + self.metadata = metadata } // MARK: Resolver @@ -28,7 +31,9 @@ public class RemoteConfidenceClient: ConfidenceClient { flags: flags.map { "flags/\($0)" }, evaluationContext: try getEvaluationContextStruct(ctx: ctx), clientSecret: options.credentials.getSecret(), - apply: applyOnResolve) + apply: applyOnResolve, + sdk: Sdk(id: metadata.name, version: metadata.version) + ) do { let result: HttpClientResponse = @@ -108,6 +113,7 @@ struct ResolveFlagsRequest: Codable { var evaluationContext: Struct var clientSecret: String var apply: Bool + var sdk: Sdk } struct ResolveFlagsResponse: Codable { @@ -149,6 +155,7 @@ struct ApplyFlagsRequest: Codable { var sendTime: String var clientSecret: String var resolveToken: String + var sdk: Sdk } struct ApplyFlagsResponse: Codable { @@ -184,6 +191,16 @@ public enum ConfidenceRegion: String { case usa = "us" } +struct Sdk: Codable { + init(id: String?, version: String?) { + self.id = id ?? "SDK_ID_SWIFT_PROVIDER" + self.version = version ?? "unknown" + } + + var id: String + var version: String +} + private func displayName(resolvedFlag: ResolvedFlag) throws -> String { let flagNameComponents = resolvedFlag.flag.components(separatedBy: "/") if flagNameComponents.count <= 1 || flagNameComponents[0] != "flags" { diff --git a/Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift b/Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift index 43c3f313..5ac21cd0 100644 --- a/Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift +++ b/Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift @@ -9,8 +9,8 @@ import os // swiftlint:disable type_body_length // swiftlint:disable file_length public class ConfidenceFeatureProvider: FeatureProvider { + public var metadata: ProviderMetadata public var hooks: [any Hook] = [] - public let metadata: ProviderMetadata = ConfidenceMetadata() private let lock = UnfairLock() private var resolver: Resolver private let client: ConfidenceClient @@ -22,6 +22,7 @@ public class ConfidenceFeatureProvider: FeatureProvider { /// Should not be called externally, use `ConfidenceFeatureProvider.Builder` instead. init( + metadata: ProviderMetadata, client: RemoteConfidenceClient, cache: ProviderCache, storage: Storage, @@ -31,6 +32,7 @@ public class ConfidenceFeatureProvider: FeatureProvider { initializationStrategy: InitializationStrategy ) { self.client = client + self.metadata = metadata self.cache = cache self.overrides = overrides self.flagApplier = flagApplier @@ -393,6 +395,7 @@ extension ConfidenceFeatureProvider { extension ConfidenceFeatureProvider { public struct Builder { var options: ConfidenceClientOptions + let metadata = ConfidenceMetadata(version: "0.1.1") // x-release-please-version var session: URLSession? var localOverrides: [String: LocalOverride] = [:] var storage: Storage = DefaultStorage.resolverFlagsCache() @@ -574,7 +577,8 @@ extension ConfidenceFeatureProvider { ?? FlagApplierWithRetries( httpClient: NetworkClient(region: options.region), storage: DefaultStorage.applierFlagsCache(), - options: options + options: options, + metadata: metadata ) let cache = cache ?? InMemoryProviderCache.from(storage: storage) @@ -583,10 +587,12 @@ extension ConfidenceFeatureProvider { options: options, session: self.session, applyOnResolve: false, - flagApplier: flagApplier + flagApplier: flagApplier, + metadata: metadata ) return ConfidenceFeatureProvider( + metadata: metadata, client: client, cache: cache, storage: storage, diff --git a/Sources/ConfidenceProvider/InitializationStrategy.swift b/Sources/ConfidenceProvider/InitializationStrategy.swift index d3220e77..0669c528 100644 --- a/Sources/ConfidenceProvider/InitializationStrategy.swift +++ b/Sources/ConfidenceProvider/InitializationStrategy.swift @@ -3,4 +3,3 @@ import Foundation public enum InitializationStrategy { case fetchAndActivate, activateAndFetchAsync } - diff --git a/Sources/ConfidenceProvider/Utils/ConfidenceMetadata.swift b/Sources/ConfidenceProvider/Utils/ConfidenceMetadata.swift index 3a6ee67b..6fb6a6cc 100644 --- a/Sources/ConfidenceProvider/Utils/ConfidenceMetadata.swift +++ b/Sources/ConfidenceProvider/Utils/ConfidenceMetadata.swift @@ -1,5 +1,6 @@ import OpenFeature public struct ConfidenceMetadata: ProviderMetadata { - public var name: String? = "Confidence" + public var name: String? = "SDK_ID_SWIFT_PROVIDER" + public var version: String? } diff --git a/Tests/ConfidenceProviderTests/FlagApplierWithRetriesTest.swift b/Tests/ConfidenceProviderTests/FlagApplierWithRetriesTest.swift index afe97f3f..820da2da 100644 --- a/Tests/ConfidenceProviderTests/FlagApplierWithRetriesTest.swift +++ b/Tests/ConfidenceProviderTests/FlagApplierWithRetriesTest.swift @@ -11,6 +11,7 @@ class FlagApplierWithRetriesTest: XCTestCase { private let options = ConfidenceClientOptions(credentials: .clientSecret(secret: "test")) private var storage = StorageMock() private var httpClient = HttpClientMock() + private let metadata = ConfidenceMetadata(name: "test-provider-name", version: "0.0.0.") override func setUp() { storage = StorageMock() @@ -22,7 +23,7 @@ class FlagApplierWithRetriesTest: XCTestCase { func testApply_differentTokens() async { // Given flag applier let applier = FlagApplierWithRetries( - httpClient: httpClient, storage: storage, options: options, triggerBatch: false + httpClient: httpClient, storage: storage, options: options, metadata: metadata, triggerBatch: false ) // When 3 apply calls are issued with different tokens @@ -37,7 +38,7 @@ class FlagApplierWithRetriesTest: XCTestCase { func testApply_duplicateEventsAreNotSent() async { // Given flag applier let applier = FlagApplierWithRetries( - httpClient: httpClient, storage: storage, options: options, triggerBatch: false + httpClient: httpClient, storage: storage, options: options, metadata: metadata, triggerBatch: false ) // When 3 identical apply calls are issued @@ -56,6 +57,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: httpClient, storage: storage, options: options, + metadata: metadata, cacheDataInteractor: cacheDataInteractor, triggerBatch: false ) @@ -80,6 +82,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: httpClient, storage: storage, options: options, + metadata: metadata, cacheDataInteractor: cacheDataInteractor, triggerBatch: false ) @@ -114,6 +117,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: httpClient, storage: storage, options: options, + metadata: metadata, triggerBatch: false ) } @@ -141,7 +145,8 @@ class FlagApplierWithRetriesTest: XCTestCase { _ = FlagApplierWithRetries( httpClient: httpClient, storage: prefilledStorage, - options: options + options: options, + metadata: metadata ) await waitForExpectations(timeout: 5.0) @@ -171,7 +176,8 @@ class FlagApplierWithRetriesTest: XCTestCase { _ = FlagApplierWithRetries( httpClient: partiallyFailingHttpClient, storage: prefilledStorage, - options: options + options: options, + metadata: metadata ) await waitForExpectations(timeout: 5.0) @@ -200,6 +206,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: httpClient, storage: storage, options: options, + metadata: metadata, triggerBatch: false ) @@ -243,6 +250,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: offlineClient, storage: storage, options: options, + metadata: metadata, cacheDataInteractor: cacheDataInteractor, triggerBatch: false ) @@ -285,7 +293,8 @@ class FlagApplierWithRetriesTest: XCTestCase { _ = FlagApplierWithRetries( httpClient: httpClient, storage: prefilledStorage, - options: options + options: options, + metadata: metadata ) await waitForExpectations(timeout: 1.0) @@ -310,6 +319,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: httpClient, storage: prefilledStorage, options: options, + metadata: metadata, triggerBatch: false ) @@ -337,6 +347,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: offlineClient, storage: prefilledStorage, options: options, + metadata: metadata, triggerBatch: false ) @@ -350,7 +361,7 @@ class FlagApplierWithRetriesTest: XCTestCase { // Given offline http client and flag applier let offlineClient = HttpClientMock(testMode: .error) let applier = FlagApplierWithRetries( - httpClient: offlineClient, storage: storage, options: options, triggerBatch: false + httpClient: offlineClient, storage: storage, options: options, metadata: metadata, triggerBatch: false ) // When 3 apply calls are issued with different flag names @@ -379,7 +390,7 @@ class FlagApplierWithRetriesTest: XCTestCase { // Given offline http client and flag applier let offlineClient = HttpClientMock(testMode: .error) let applier = FlagApplierWithRetries( - httpClient: offlineClient, storage: storage, options: options, triggerBatch: false + httpClient: offlineClient, storage: storage, options: options, metadata: metadata, triggerBatch: false ) // When 3 apply calls are issued with different tokens @@ -417,6 +428,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: offlineClient, storage: prefilledStorage, options: options, + metadata: metadata, triggerBatch: false ) @@ -449,6 +461,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: offlineClient, storage: prefilledStorage, options: options, + metadata: metadata, triggerBatch: false ) @@ -480,6 +493,7 @@ class FlagApplierWithRetriesTest: XCTestCase { httpClient: offlineClient, storage: prefilledStorage, options: options, + metadata: metadata, triggerBatch: false ) diff --git a/Tests/ConfidenceProviderTests/RemoteConfidenceClientTest.swift b/Tests/ConfidenceProviderTests/RemoteConfidenceClientTest.swift index f9176fd3..6f9616e9 100644 --- a/Tests/ConfidenceProviderTests/RemoteConfidenceClientTest.swift +++ b/Tests/ConfidenceProviderTests/RemoteConfidenceClientTest.swift @@ -30,7 +30,8 @@ class RemoteConfidenceClientTest: XCTestCase { options: .init(credentials: .clientSecret(secret: "test")), session: session, applyOnResolve: true, - flagApplier: flagApplier + flagApplier: flagApplier, + metadata: ConfidenceMetadata() ) let result = try await client.resolve(ctx: MutableContext(targetingKey: "user1")) diff --git a/release-please-config.json b/release-please-config.json index c0c56414..5950a06a 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -7,7 +7,10 @@ "bump-patch-for-minor-pre-major": true, "versioning": "default", "include-v-in-tag": false, - "extra-files": ["README.md"] + "extra-files": [ + "README.md", + "Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift" + ] } }, "changelog-sections": [