From 2364ee2f196618cccbc3d8d678340738d1f3ac5c Mon Sep 17 00:00:00 2001 From: Di Wu Date: Fri, 22 Mar 2024 14:36:52 -0700 Subject: [PATCH 1/8] chore: amplify network package --- .../xcschemes/Amplify-Package.xcscheme | 19 +++++ .../APIKeyAuthInterceptor.swift | 7 +- .../AuthTokenInterceptor.swift | 2 +- .../IAMAuthInterceptor.swift | 5 +- .../AWSGraphQLSubscriptionTaskRunner.swift | 40 +++++++++-- .../AppSyncRealTimeClientFactory.swift | 11 +-- .../AmplifyAWSServiceConfiguration.swift | 2 +- ...reLargeNumberModelsSubscriptionTests.swift | 1 + .../AppSyncRealTimeClient+HandleRequest.swift | 1 + .../AppSyncRealTimeClient.swift | 69 +++++++------------ .../AppSyncRealTimeRequest.swift | 16 +++-- .../AppSyncRealTimeRequestAuth.swift | 25 ++++++- .../AppSyncRealTimeResponse.swift | 1 + .../AppSyncRealTimeSubscription.swift | 10 +-- .../AppSyncRequestInterceptor.swift | 3 +- .../AppSyncSubscriptionEvent.swift | 3 +- .../AppSyncWebSocketClientProtocol.swift | 4 +- .../Network}/AppSyncRealTimeClient/README.md | 0 .../WebSocket/AmplifyNetworkMonitor.swift | 0 .../Sources/Network}/WebSocket/README.md | 0 .../Network}/WebSocket/RetryWithJitter.swift | 0 .../Network}/WebSocket/WebSocketClient.swift | 0 .../Network}/WebSocket/WebSocketEvent.swift | 0 .../WebSocket/WebSocketInterceptor.swift | 0 .../WebSocketNetworkMonitorProtocol.swift | 0 .../WebSocket/LocalWebSocketServer.swift | 0 .../WebSocket/RetryWithJitterTests.swift | 0 .../WebSocket/WebSocketClientTests.swift | 0 Package.swift | 21 +++++- 29 files changed, 158 insertions(+), 82 deletions(-) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift (99%) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/AppSyncRealTimeClient.swift (89%) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift (91%) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift (80%) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift (97%) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift (95%) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift (79%) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift (86%) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift (85%) rename AmplifyPlugins/{API/Sources/AWSAPIPlugin => Internal/Sources/Network}/AppSyncRealTimeClient/README.md (100%) rename AmplifyPlugins/{Core/AWSPluginsCore => Internal/Sources/Network}/WebSocket/AmplifyNetworkMonitor.swift (100%) rename AmplifyPlugins/{Core/AWSPluginsCore => Internal/Sources/Network}/WebSocket/README.md (100%) rename AmplifyPlugins/{Core/AWSPluginsCore => Internal/Sources/Network}/WebSocket/RetryWithJitter.swift (100%) rename AmplifyPlugins/{Core/AWSPluginsCore => Internal/Sources/Network}/WebSocket/WebSocketClient.swift (100%) rename AmplifyPlugins/{Core/AWSPluginsCore => Internal/Sources/Network}/WebSocket/WebSocketEvent.swift (100%) rename AmplifyPlugins/{Core/AWSPluginsCore => Internal/Sources/Network}/WebSocket/WebSocketInterceptor.swift (100%) rename AmplifyPlugins/{Core/AWSPluginsCore => Internal/Sources/Network}/WebSocket/WebSocketNetworkMonitorProtocol.swift (100%) rename AmplifyPlugins/{Core/AWSPluginsCoreTests => Internal/Tests/NetworkTests}/WebSocket/LocalWebSocketServer.swift (100%) rename AmplifyPlugins/{Core/AWSPluginsCoreTests => Internal/Tests/NetworkTests}/WebSocket/RetryWithJitterTests.swift (100%) rename AmplifyPlugins/{Core/AWSPluginsCoreTests => Internal/Tests/NetworkTests}/WebSocket/WebSocketClientTests.swift (100%) diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Amplify-Package.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Amplify-Package.xcscheme index 6970be959c..08c2c9efc2 100644 --- a/.swiftpm/xcode/xcshareddata/xcschemes/Amplify-Package.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/Amplify-Package.xcscheme @@ -741,6 +741,16 @@ ReferencedContainer = "container:"> + + + + + + + + diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift index f52ded490e..671e0627c7 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift @@ -8,7 +8,7 @@ import Foundation import Amplify -@_spi(WebSocket) import AWSPluginsCore +@_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork class APIKeyAuthInterceptor { private let apiKey: String @@ -31,7 +31,10 @@ extension APIKeyAuthInterceptor: WebSocketInterceptor { extension APIKeyAuthInterceptor: AppSyncRequestInterceptor { func interceptRequest(event: AppSyncRealTimeRequest, url: URL) async -> AppSyncRealTimeRequest { - let host = AppSyncRealTimeClientFactory.appSyncApiEndpoint(url).host! + guard let host = AppSyncRealTimeClientFactory.appSyncApiEndpoint(url).host else { + return event + } + guard case .start(let request) = event else { return event } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift index b0f19ffd78..99db676356 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift @@ -7,7 +7,7 @@ import Foundation import Amplify -@_spi(WebSocket) import AWSPluginsCore +@_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork /// General purpose authenticatication subscriptions interceptor for providers whose only /// requirement is to provide an authentication token via the "Authorization" header diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift index c3d33320c2..e8ff9cc7c2 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift @@ -6,10 +6,11 @@ // import Foundation -@_spi(WebSocket) import AWSPluginsCore import Amplify import AWSClientRuntime import ClientRuntime +import AWSPluginsCore +@_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork class IAMAuthInterceptor { @@ -114,7 +115,7 @@ extension IAMAuthInterceptor: AppSyncRequestInterceptor { return .start(.init( id: request.id, data: request.data, - auth: authHeader.map { .iam($0) } + auth: authHeader.map { AppSyncRealTimeRequestAuth.iam($0) } )) } } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift index 3e70654298..8c78cb10ca 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift @@ -9,6 +9,7 @@ import Amplify import Foundation import AWSPluginsCore import Combine +@_spi(AppSyncRTC) import AmplifyNetwork public class AWSGraphQLSubscriptionTaskRunner: InternalTaskRunner, InternalTaskAsyncThrowingSequence, InternalTaskThrowingChannel { public typealias Request = GraphQLOperationRequest @@ -140,8 +141,8 @@ public class AWSGraphQLSubscriptionTaskRunner: InternalTaskRunner, case .unsubscribed: send(GraphQLSubscriptionEvent.connection(.disconnected)) finish() - case .error(let errors): - fail(toAPIError(errors, type: R.self)) + case .error(let payload): + fail(toAPIError(decodeAppSyncRealTimeResponseError(payload), type: R.self)) } } @@ -320,8 +321,8 @@ final public class AWSGraphQLSubscriptionOperation: GraphQLSubscri dispatchInProcess(data: GraphQLSubscriptionEvent.connection(.disconnected)) dispatch(result: .successfulVoid) finish() - case .error(let errors): - dispatch(result: .failure(toAPIError(errors, type: R.self))) + case .error(let payload): + dispatch(result: .failure(toAPIError(decodeAppSyncRealTimeResponseError(payload), type: R.self))) finish() } } @@ -402,5 +403,36 @@ fileprivate func toAPIError(_ errors: [Error], type: R.Type) -> AP errors.first ) } +} + +fileprivate func decodeAppSyncRealTimeResponseError(_ data: JSONValue?) -> [Error] { + let knownAppSyncRealTimeRequestErorrs = + decodeAppSyncRealTimeRequestError(data) + .filter { !$0.isUnknown } + if knownAppSyncRealTimeRequestErorrs.isEmpty { + let graphQLErrors = decodeGraphQLErrors(data) + return graphQLErrors.isEmpty + ? [APIError.operationError("Failed to decode AppSync error response", "", nil)] + : graphQLErrors + } else { + return knownAppSyncRealTimeRequestErorrs + } +} + +fileprivate func decodeGraphQLErrors(_ data: JSONValue?) -> [GraphQLError] { + do { + return try GraphQLErrorDecoder.decodeAppSyncErrors(data) + } catch { + print("Failed to decode errors: \(error)") + return [] + } +} +fileprivate func decodeAppSyncRealTimeRequestError(_ data: JSONValue?) -> [AppSyncRealTimeRequest.Error] { + guard let errorsJson = data?.errors else { + print("No 'errors' field found in response json") + return [] + } + let errors = errorsJson.asArray ?? [errorsJson] + return errors.compactMap(AppSyncRealTimeRequest.parseResponseError(error:)) } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift index 1666312feb..b0a1bbf325 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift @@ -9,7 +9,9 @@ import Foundation import Amplify import Combine -@_spi(WebSocket) import AWSPluginsCore +import AWSPluginsCore +@_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork + protocol AppSyncRealTimeClientFactoryProtocol { func getAppSyncRealTimeClient( @@ -21,13 +23,6 @@ protocol AppSyncRealTimeClientFactoryProtocol { ) async throws -> AppSyncRealTimeClientProtocol } -protocol AppSyncRealTimeClientProtocol { - func connect() async throws - func disconnectWhenIdel() async - func disconnect() async - func subscribe(id: String, query: String) async throws -> AnyPublisher - func unsubscribe(id: String) async throws -} actor AppSyncRealTimeClientFactory: AppSyncRealTimeClientFactoryProtocol { struct MapperCacheKey: Hashable { diff --git a/AmplifyPlugins/Core/AWSPluginsCore/ServiceConfiguration/AmplifyAWSServiceConfiguration.swift b/AmplifyPlugins/Core/AWSPluginsCore/ServiceConfiguration/AmplifyAWSServiceConfiguration.swift index ac6db525d2..ca8f6cdbf9 100644 --- a/AmplifyPlugins/Core/AWSPluginsCore/ServiceConfiguration/AmplifyAWSServiceConfiguration.swift +++ b/AmplifyPlugins/Core/AWSPluginsCore/ServiceConfiguration/AmplifyAWSServiceConfiguration.swift @@ -15,7 +15,7 @@ import Amplify public class AmplifyAWSServiceConfiguration { /// - Tag: AmplifyAWSServiceConfiguration.amplifyVersion - public static let amplifyVersion = "2.28.0" + public static let amplifyVersion = "2.27.3" /// - Tag: AmplifyAWSServiceConfiguration.platformName public static let platformName = "amplify-swift" diff --git a/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift b/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift index cc09f0f40d..cc0fc9fbe6 100644 --- a/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift +++ b/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift @@ -10,6 +10,7 @@ import XCTest import Combine import Amplify @testable import AWSAPIPlugin +@_spi(AppSyncRTC) import AmplifyNetwork class DataStoreLargeNumberModelsSubscriptionTests: SyncEngineIntegrationTestBase { diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift similarity index 99% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift index d3eee7a753..4e8808c7ea 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift +++ b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift @@ -10,6 +10,7 @@ import Foundation import Combine import Amplify +@_spi(AppSyncRTC) extension AppSyncRealTimeClient { /** Submit an AppSync request to real-time server. diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient.swift similarity index 89% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient.swift index c8bf7efcab..205a038d44 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift +++ b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient.swift @@ -7,15 +7,24 @@ import Foundation -import Amplify import Combine -@_spi(WebSocket) import AWSPluginsCore +import Amplify + +@_spi(AppSyncRTC) +public protocol AppSyncRealTimeClientProtocol { + func connect() async throws + func disconnectWhenIdel() async + func disconnect() async + func subscribe(id: String, query: String) async throws -> AnyPublisher + func unsubscribe(id: String) async throws +} /** The AppSyncRealTimeClient conforms to the AppSync real-time WebSocket protocol. ref: https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html */ -actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { +@_spi(AppSyncRTC) +public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { static let jsonEncoder = JSONEncoder() static let jsonDecoder = JSONDecoder() @@ -50,7 +59,7 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { /// Writable data stream convert WebSocketEvent to AppSyncRealTimeResponse internal let subject = PassthroughSubject() - var isConnected: Bool { + public var isConnected: Bool { self.state.value == .connected } @@ -61,7 +70,7 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { - requestInterceptor: Interceptor for decocating AppSyncRealTimeRequest - webSocketClient: WebSocketClient for reading/writing to connection */ - init( + public init( endpoint: URL, requestInterceptor: AppSyncRequestInterceptor, webSocketClient: AppSyncWebSocketClientProtocol @@ -84,7 +93,7 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { /** Connecting to remote AppSync real-time server. */ - func connect() async throws { + public func connect() async throws { switch self.state.value { case .connecting, .connected: log.debug("[AppSyncRealTimeClient] client is already connecting or connected") @@ -116,7 +125,7 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { /** Disconnect only when there are no subscriptions exist. */ - func disconnectWhenIdel() async { + public func disconnectWhenIdel() async { if self.subscriptions.isEmpty { log.debug("[AppSyncRealTimeClient] no subscription exist, client is trying to disconnect") await disconnect() @@ -128,7 +137,7 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { /** Disconnect from AppSync real-time server. */ - func disconnect() async { + public func disconnect() async { guard self.state.value != .disconnecting else { log.debug("[AppSyncRealTimeClient] client already disconnecting") return @@ -152,7 +161,7 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { - Returns: A never fail data stream for AppSyncSubscriptionEvent. */ - func subscribe(id: String, query: String) async throws -> AnyPublisher { + public func subscribe(id: String, query: String) async throws -> AnyPublisher { log.debug("[AppSyncRealTimeClient] Received subscription request id: \(id), query: \(query)") let subscription = AppSyncRealTimeSubscription(id: id, query: query, appSyncRealTimeClient: self) subscriptions[id] = subscription @@ -201,7 +210,7 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { - Parameters: - id: unique identifier of the subscription. */ - func unsubscribe(id: String) async throws { + public func unsubscribe(id: String) async throws { defer { log.debug("[AppSyncRealTimeClient] deleted subscription with id: \(id)") subscriptions.removeValue(forKey: id) @@ -283,7 +292,7 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { .map { response -> AppSyncSubscriptionEvent? in switch response.type { case .connectionError, .error: - return .error(Self.decodeAppSyncRealTimeResponseError(response.payload)) + return response.payload.map { .error($0) } case .data: return response.payload.map { .data($0) } default: @@ -294,38 +303,6 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { .eraseToAnyPublisher() } - private static func decodeAppSyncRealTimeResponseError(_ data: JSONValue?) -> [Error] { - let knownAppSyncRealTimeRequestErorrs = - Self.decodeAppSyncRealTimeRequestError(data) - .filter { !$0.isUnknown } - if knownAppSyncRealTimeRequestErorrs.isEmpty { - let graphQLErrors = Self.decodeGraphQLErrors(data) - return graphQLErrors.isEmpty - ? [APIError.operationError("Failed to decode AppSync error response", "", nil)] - : graphQLErrors - } else { - return knownAppSyncRealTimeRequestErorrs - } - } - - private static func decodeGraphQLErrors(_ data: JSONValue?) -> [GraphQLError] { - do { - return try GraphQLErrorDecoder.decodeAppSyncErrors(data) - } catch { - log.debug("[AppSyncRealTimeClient] Failed to decode errors: \(error)") - return [] - } - } - - private static func decodeAppSyncRealTimeRequestError(_ data: JSONValue?) -> [AppSyncRealTimeRequest.Error] { - guard let errorsJson = data?.errors else { - log.error("[AppSyncRealTimeClient] No 'errors' field found in response json") - return [] - } - let errors = errorsJson.asArray ?? [errorsJson] - return errors.compactMap(AppSyncRealTimeRequest.parseResponseError(error:)) - } - private func bindCancellableToConnection(_ cancellable: AnyCancellable) { cancellable.store(in: &cancellablesBindToConnection) } @@ -434,15 +411,15 @@ extension Publisher where Output == AppSyncRealTimeSubscription.State, Failure = } extension AppSyncRealTimeClient: DefaultLogger { - static var log: Logger { + public static var log: Logger { Amplify.Logging.logger(forCategory: CategoryType.api.displayName, forNamespace: String(describing: self)) } - nonisolated var log: Logger { Self.log } + public nonisolated var log: Logger { Self.log } } extension AppSyncRealTimeClient: Resettable { - func reset() async { + public func reset() async { subject.send(completion: .finished) cancellables = Set() cancellablesBindToConnection = Set() diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift similarity index 91% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift index 19599820b4..a08855d6ee 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift +++ b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift @@ -7,18 +7,24 @@ import Foundation -import Combine import Amplify +@_spi(AppSyncRTC) public enum AppSyncRealTimeRequest { case connectionInit case start(StartRequest) case stop(String) public struct StartRequest { - let id: String - let data: String - let auth: AppSyncRealTimeRequestAuth? + public let id: String + public let data: String + public let auth: AppSyncRealTimeRequestAuth? + + public init(id: String, data: String, auth: AppSyncRealTimeRequestAuth?) { + self.id = id + self.data = data + self.auth = auth + } } var id: String? { @@ -78,7 +84,7 @@ extension AppSyncRealTimeRequest { case unauthorized case unknown(message: String? = nil, causedBy: Swift.Error? = nil, payload: [String: Any]?) - var isUnknown: Bool { + public var isUnknown: Bool { if case .unknown = self { return true } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift similarity index 80% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift index 87e01b1842..68db7f9de3 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift +++ b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift @@ -8,6 +8,7 @@ import Foundation +@_spi(AppSyncRTC) public enum AppSyncRealTimeRequestAuth { case authToken(AuthToken) case apiKey(ApiKey) @@ -16,12 +17,23 @@ public enum AppSyncRealTimeRequestAuth { public struct AuthToken { let host: String let authToken: String + + public init(host: String, authToken: String) { + self.host = host + self.authToken = authToken + } } public struct ApiKey { let host: String let apiKey: String let amzDate: String + + public init(host: String, apiKey: String, amzDate: String) { + self.host = host + self.apiKey = apiKey + self.amzDate = amzDate + } } public struct IAM { @@ -29,18 +41,25 @@ public enum AppSyncRealTimeRequestAuth { let authToken: String let securityToken: String let amzDate: String + + public init(host: String, authToken: String, securityToken: String, amzDate: String) { + self.host = host + self.authToken = authToken + self.securityToken = securityToken + self.amzDate = amzDate + } } public struct URLQuery { let header: AppSyncRealTimeRequestAuth let payload: String - init(header: AppSyncRealTimeRequestAuth, payload: String = "{}") { + public init(header: AppSyncRealTimeRequestAuth, payload: String = "{}") { self.header = header self.payload = payload } - func withBaseURL(_ url: URL, encoder: JSONEncoder? = nil) -> URL { + public func withBaseURL(_ url: URL, encoder: JSONEncoder? = nil) -> URL { let jsonEncoder: JSONEncoder = encoder ?? JSONEncoder() guard let headerJsonData = try? jsonEncoder.encode(header) else { return url @@ -53,7 +72,7 @@ public enum AppSyncRealTimeRequestAuth { urlComponents.queryItems = [ URLQueryItem(name: "header", value: headerJsonData.base64EncodedString()), - URLQueryItem(name: "payload", value: try? payload.base64EncodedString()) + URLQueryItem(name: "payload", value: payload.data(using: .utf8)?.base64EncodedString()) ] return urlComponents.url ?? url diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift similarity index 97% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift index dfec371035..c6a0616047 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift +++ b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift @@ -8,6 +8,7 @@ import Foundation import Amplify +@_spi(AppSyncRTC) public struct AppSyncRealTimeResponse { public let id: String? diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift similarity index 95% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift index d7e4c6ef42..5517057306 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift +++ b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift @@ -9,15 +9,15 @@ import Foundation import Combine import Amplify -@_spi(WebSocket) import AWSPluginsCore /** AppSyncRealTimeSubscription reprensents one realtime subscription to AppSync realtime server. */ -actor AppSyncRealTimeSubscription { +@_spi(AppSyncRTC) +public actor AppSyncRealTimeSubscription { static let jsonEncoder = JSONEncoder() - enum State { + public enum State { case none case subscribing case subscribed @@ -121,9 +121,9 @@ actor AppSyncRealTimeSubscription { } extension AppSyncRealTimeSubscription: DefaultLogger { - static var log: Logger { + public static var log: Logger { Amplify.Logging.logger(forCategory: CategoryType.api.displayName, forNamespace: String(describing: self)) } - nonisolated var log: Logger { Self.log } + nonisolated public var log: Logger { Self.log } } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift similarity index 79% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift index 92414ea28c..b94c16ae70 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift +++ b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift @@ -8,6 +8,7 @@ import Foundation -protocol AppSyncRequestInterceptor { +@_spi(AppSyncRTC) +public protocol AppSyncRequestInterceptor { func interceptRequest(event: AppSyncRealTimeRequest, url: URL) async -> AppSyncRealTimeRequest } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift similarity index 86% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift index ec86c53e6a..00404601ab 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift +++ b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift @@ -9,10 +9,11 @@ import Foundation import Amplify +@_spi(AppSyncRTC) public enum AppSyncSubscriptionEvent { case subscribing case subscribed case data(JSONValue) case unsubscribed - case error([Error]) + case error(JSONValue) } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift similarity index 85% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift index d7d9cadc29..570ca71689 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift +++ b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift @@ -8,9 +8,9 @@ import Foundation import Combine -@_spi(WebSocket) import AWSPluginsCore -protocol AppSyncWebSocketClientProtocol: AnyObject { +@_spi(AppSyncRTC) +public protocol AppSyncWebSocketClientProtocol: AnyObject { var isConnected: Bool { get async } var publisher: AnyPublisher { get async } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/README.md b/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/README.md similarity index 100% rename from AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/README.md rename to AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/README.md diff --git a/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/AmplifyNetworkMonitor.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCore/WebSocket/AmplifyNetworkMonitor.swift rename to AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift diff --git a/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/README.md b/AmplifyPlugins/Internal/Sources/Network/WebSocket/README.md similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCore/WebSocket/README.md rename to AmplifyPlugins/Internal/Sources/Network/WebSocket/README.md diff --git a/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/RetryWithJitter.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCore/WebSocket/RetryWithJitter.swift rename to AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift diff --git a/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/WebSocketClient.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCore/WebSocket/WebSocketClient.swift rename to AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift diff --git a/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/WebSocketEvent.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCore/WebSocket/WebSocketEvent.swift rename to AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift diff --git a/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/WebSocketInterceptor.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCore/WebSocket/WebSocketInterceptor.swift rename to AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift diff --git a/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/WebSocketNetworkMonitorProtocol.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCore/WebSocket/WebSocketNetworkMonitorProtocol.swift rename to AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift diff --git a/AmplifyPlugins/Core/AWSPluginsCoreTests/WebSocket/LocalWebSocketServer.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/LocalWebSocketServer.swift similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCoreTests/WebSocket/LocalWebSocketServer.swift rename to AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/LocalWebSocketServer.swift diff --git a/AmplifyPlugins/Core/AWSPluginsCoreTests/WebSocket/RetryWithJitterTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCoreTests/WebSocket/RetryWithJitterTests.swift rename to AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift diff --git a/AmplifyPlugins/Core/AWSPluginsCoreTests/WebSocket/WebSocketClientTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift similarity index 100% rename from AmplifyPlugins/Core/AWSPluginsCoreTests/WebSocket/WebSocketClientTests.swift rename to AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift diff --git a/Package.swift b/Package.swift index 77f5211f2a..da9b806838 100644 --- a/Package.swift +++ b/Package.swift @@ -115,7 +115,8 @@ let apiTargets: [Target] = [ name: "AWSAPIPlugin", dependencies: [ .target(name: "Amplify"), - .target(name: "AWSPluginsCore") + .target(name: "AWSPluginsCore"), + .target(name: "AmplifyNetwork") ], path: "AmplifyPlugins/API/Sources/AWSAPIPlugin", exclude: [ @@ -315,6 +316,23 @@ let internalPinpointTargets: [Target] = [ ) ] +let internalNetworkingTargets: [Target] = [ + .target( + name: "AmplifyNetwork", + dependencies: [ + .target(name: "Amplify") + ], + path: "AmplifyPlugins/Internal/Sources/Network" + ), + .testTarget( + name: "AmplifyNetworkUnitTests", + dependencies: [ + "AmplifyNetwork" + ], + path: "AmplifyPlugins/Internal/Tests/NetworkTests" + ) +] + let analyticsTargets: [Target] = [ .target( name: "AWSPinpointAnalyticsPlugin", @@ -443,6 +461,7 @@ let targets: [Target] = amplifyTargets + analyticsTargets + pushNotificationsTargets + internalPinpointTargets + + internalNetworkingTargets + predictionsTargets + loggingTargets From f616f3b8983eda45e6b59b9f526b3122eeabf772 Mon Sep 17 00:00:00 2001 From: Di Wu Date: Fri, 22 Mar 2024 15:55:22 -0700 Subject: [PATCH 2/8] fix build errors in API plugin unit tests --- .../APIKeyAuthInterceptorTests.swift | 1 + .../CognitoAuthInterceptorTests.swift | 3 +- .../Mocks/MockSubscription.swift | 3 +- .../GraphQLSubscribeCombineTests.swift | 1 + .../Operation/GraphQLSubscribeTaskTests.swift | 30 ++++++++++++++----- .../Operation/GraphQLSubscribeTests.swift | 1 + .../AppSyncRealTimeClientTests.swift | 1 - .../AppSyncRealTimeRequestAuthTests.swift | 0 8 files changed, 30 insertions(+), 10 deletions(-) rename AmplifyPlugins/{API/Tests/AWSAPIPluginTests => Internal/Tests/NetworkTests}/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift (99%) rename AmplifyPlugins/{API/Tests/AWSAPIPluginTests => Internal/Tests/NetworkTests}/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift (100%) diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift index 8c89c0a53a..db1de6de82 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift @@ -9,6 +9,7 @@ import XCTest import Amplify @testable import AWSAPIPlugin +@testable @_spi(AppSyncRTC) import AmplifyNetwork class APIKeyAuthInterceptorTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift index 4127f018fd..2e57e27579 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift @@ -9,7 +9,8 @@ import XCTest import Amplify @testable import AWSAPIPlugin -@testable @_spi(WebSocket) import AWSPluginsCore +@testable import AWSPluginsCore +@testable @_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork class CognitoAuthInterceptorTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift index 2ba9f97779..e02b61a939 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift @@ -10,7 +10,8 @@ import Foundation import Amplify import Combine @testable import AWSAPIPlugin -@_spi(WebSocket) import AWSPluginsCore +@testable import AWSPluginsCore +@testable @_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork struct MockSubscriptionConnectionFactory: AppSyncRealTimeClientFactoryProtocol { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift index cbe8ad220c..d8e9073096 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift @@ -11,6 +11,7 @@ import XCTest import Amplify @testable import AmplifyTestCommon @testable import AWSAPIPlugin +@testable @_spi(AppSyncRTC) import AmplifyNetwork @_implementationOnly import AmplifyAsyncTesting class GraphQLSubscribeCombineTests: OperationTestBase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift index d632e131c7..6c0e7b0421 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift @@ -11,6 +11,7 @@ import XCTest import Amplify @testable import AmplifyTestCommon @testable import AWSAPIPlugin +@testable @_spi(AppSyncRTC) import AmplifyNetwork @_implementationOnly import AmplifyAsyncTesting class GraphQLSubscribeTasksTests: OperationTestBase { @@ -130,7 +131,11 @@ class GraphQLSubscribeTasksTests: OperationTestBase { await fulfillment(of: [onSubscribeInvoked], timeout: 0.05) try await MockAppSyncRealTimeClient.waitForSubscirbing() - mockAppSyncRealTimeClient?.triggerEvent(.error([AppSyncRealTimeRequest.Error.limitExceeded])) + mockAppSyncRealTimeClient?.triggerEvent(.error([ + "errors": [ + "errorType": "LimitExceededError" + ] + ])) expectedCompletionFailureError = APIError.operationError("", "", AppSyncRealTimeRequest.Error.limitExceeded) await waitForSubscriptionExpectations() } @@ -145,18 +150,21 @@ class GraphQLSubscribeTasksTests: OperationTestBase { try await subscribe() await fulfillment(of: [onSubscribeInvoked], timeout: 0.05) - let unauthorizedError = GraphQLError(message: "", extensions: ["errorType": "Unauthorized"]) try await MockAppSyncRealTimeClient.waitForSubscirbing() - mockAppSyncRealTimeClient?.triggerEvent(.error([unauthorizedError])) + mockAppSyncRealTimeClient?.triggerEvent(.error([ + "errors": [ + "errorType": "Unauthorized" + ] + ])) expectedCompletionFailureError = APIError.operationError( "Subscription item event failed with error: Unauthorized", "", - GraphQLResponseError.error([unauthorizedError]) + AppSyncRealTimeRequest.Error.unauthorized ) await waitForSubscriptionExpectations() } - func testConnectionErrorWithAppSyncConnectionError() async throws { + func testConnectionErrorWithOtherAppSyncConnectionError() async throws { receivedCompletionSuccess.isInverted = true receivedStateValueConnected.isInverted = true receivedStateValueDisconnected.isInverted = true @@ -167,8 +175,16 @@ class GraphQLSubscribeTasksTests: OperationTestBase { await fulfillment(of: [onSubscribeInvoked], timeout: 0.05) try await MockAppSyncRealTimeClient.waitForSubscirbing() - mockAppSyncRealTimeClient?.triggerEvent(.error([URLError(URLError.Code(rawValue: 400))])) - expectedCompletionFailureError = APIError.operationError("", "", URLError(URLError.Code(rawValue: 400))) + mockAppSyncRealTimeClient?.triggerEvent(.error([ + "errors": [ + "message": "other error" + ] + ])) + expectedCompletionFailureError = APIError.operationError( + "Subscription item event failed with error", + "", + GraphQLResponseError.error([GraphQLError(message: "other error")]) + ) await waitForSubscriptionExpectations() } diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift index 4b28c62cc2..98806c17e0 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift @@ -9,6 +9,7 @@ import XCTest @testable import Amplify @testable import AmplifyTestCommon @testable import AWSAPIPlugin +@testable @_spi(AppSyncRTC) import AmplifyNetwork class GraphQLSubscribeTests: OperationTestBase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift similarity index 99% rename from AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift rename to AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift index 279ca304d3..aac4155d67 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift @@ -9,7 +9,6 @@ import XCTest import Combine import Amplify -@_spi(WebSocket) import AWSPluginsCore @testable import AWSAPIPlugin class AppSyncRealTimeClientTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift similarity index 100% rename from AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift rename to AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift From 6c99824e889ae9f61803aea0f7f92cf14f5c6dbd Mon Sep 17 00:00:00 2001 From: Di Wu Date: Thu, 28 Mar 2024 14:40:11 -0700 Subject: [PATCH 3/8] move AppSyncRTC back to API category package --- .../AppSyncRealTimeClient+HandleRequest.swift | 1 - .../AppSyncRealTimeClient.swift | 19 ++++++++--------- .../AppSyncRealTimeRequest.swift | 13 ++++++------ .../AppSyncRealTimeRequestAuth.swift | 21 +++++++++---------- .../AppSyncRealTimeResponse.swift | 11 +++++----- .../AppSyncRealTimeSubscription.swift | 10 ++++----- .../AppSyncRequestInterceptor.swift | 3 +-- .../AppSyncSubscriptionEvent.swift | 3 +-- .../AppSyncWebSocketClientProtocol.swift | 4 ++-- .../AppSyncRealTimeClient/README.md | 0 .../AppSyncRealTimeClientTests.swift | 13 +++++++----- .../AppSyncRealTimeClientTests.swift | 1 + .../AppSyncRealTimeRequestAuthTests.swift | 0 13 files changed, 48 insertions(+), 51 deletions(-) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift (99%) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/AppSyncRealTimeClient.swift (97%) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift (92%) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift (87%) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift (70%) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift (96%) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift (79%) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift (82%) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift (85%) rename AmplifyPlugins/{Internal/Sources/Network => API/Sources/AWSAPIPlugin}/AppSyncRealTimeClient/README.md (100%) rename AmplifyPlugins/{Internal/Tests/NetworkTests => API/Tests/AWSAPIPluginTests}/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift (99%) rename AmplifyPlugins/{Internal/Tests/NetworkTests => API/Tests/AWSAPIPluginTests}/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift (100%) diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift similarity index 99% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift index 4e8808c7ea..d3eee7a753 100644 --- a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient+HandleRequest.swift @@ -10,7 +10,6 @@ import Foundation import Combine import Amplify -@_spi(AppSyncRTC) extension AppSyncRealTimeClient { /** Submit an AppSync request to real-time server. diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift similarity index 97% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient.swift rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift index 205a038d44..1a411dd589 100644 --- a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeClient.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift @@ -9,9 +9,9 @@ import Foundation import Combine import Amplify +@_spi(WebSocket) import AmplifyNetwork -@_spi(AppSyncRTC) -public protocol AppSyncRealTimeClientProtocol { +protocol AppSyncRealTimeClientProtocol { func connect() async throws func disconnectWhenIdel() async func disconnect() async @@ -23,8 +23,7 @@ public protocol AppSyncRealTimeClientProtocol { The AppSyncRealTimeClient conforms to the AppSync real-time WebSocket protocol. ref: https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html */ -@_spi(AppSyncRTC) -public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { +actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { static let jsonEncoder = JSONEncoder() static let jsonDecoder = JSONDecoder() @@ -59,7 +58,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { /// Writable data stream convert WebSocketEvent to AppSyncRealTimeResponse internal let subject = PassthroughSubject() - public var isConnected: Bool { + var isConnected: Bool { self.state.value == .connected } @@ -70,7 +69,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { - requestInterceptor: Interceptor for decocating AppSyncRealTimeRequest - webSocketClient: WebSocketClient for reading/writing to connection */ - public init( + init( endpoint: URL, requestInterceptor: AppSyncRequestInterceptor, webSocketClient: AppSyncWebSocketClientProtocol @@ -93,7 +92,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { /** Connecting to remote AppSync real-time server. */ - public func connect() async throws { + func connect() async throws { switch self.state.value { case .connecting, .connected: log.debug("[AppSyncRealTimeClient] client is already connecting or connected") @@ -125,7 +124,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { /** Disconnect only when there are no subscriptions exist. */ - public func disconnectWhenIdel() async { + func disconnectWhenIdel() async { if self.subscriptions.isEmpty { log.debug("[AppSyncRealTimeClient] no subscription exist, client is trying to disconnect") await disconnect() @@ -137,7 +136,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { /** Disconnect from AppSync real-time server. */ - public func disconnect() async { + func disconnect() async { guard self.state.value != .disconnecting else { log.debug("[AppSyncRealTimeClient] client already disconnecting") return @@ -161,7 +160,7 @@ public actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { - Returns: A never fail data stream for AppSyncSubscriptionEvent. */ - public func subscribe(id: String, query: String) async throws -> AnyPublisher { + func subscribe(id: String, query: String) async throws -> AnyPublisher { log.debug("[AppSyncRealTimeClient] Received subscription request id: \(id), query: \(query)") let subscription = AppSyncRealTimeSubscription(id: id, query: query, appSyncRealTimeClient: self) subscriptions[id] = subscription diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift similarity index 92% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift index a08855d6ee..10fb87013a 100644 --- a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequest.swift @@ -9,18 +9,17 @@ import Foundation import Amplify -@_spi(AppSyncRTC) -public enum AppSyncRealTimeRequest { +enum AppSyncRealTimeRequest { case connectionInit case start(StartRequest) case stop(String) - public struct StartRequest { - public let id: String - public let data: String - public let auth: AppSyncRealTimeRequestAuth? + struct StartRequest { + let id: String + let data: String + let auth: AppSyncRealTimeRequestAuth? - public init(id: String, data: String, auth: AppSyncRealTimeRequestAuth?) { + init(id: String, data: String, auth: AppSyncRealTimeRequestAuth?) { self.id = id self.data = data self.auth = auth diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift similarity index 87% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift index 68db7f9de3..fffaf97faf 100644 --- a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeRequestAuth.swift @@ -8,41 +8,40 @@ import Foundation -@_spi(AppSyncRTC) -public enum AppSyncRealTimeRequestAuth { +enum AppSyncRealTimeRequestAuth { case authToken(AuthToken) case apiKey(ApiKey) case iam(IAM) - public struct AuthToken { + struct AuthToken { let host: String let authToken: String - public init(host: String, authToken: String) { + init(host: String, authToken: String) { self.host = host self.authToken = authToken } } - public struct ApiKey { + struct ApiKey { let host: String let apiKey: String let amzDate: String - public init(host: String, apiKey: String, amzDate: String) { + init(host: String, apiKey: String, amzDate: String) { self.host = host self.apiKey = apiKey self.amzDate = amzDate } } - public struct IAM { + struct IAM { let host: String let authToken: String let securityToken: String let amzDate: String - public init(host: String, authToken: String, securityToken: String, amzDate: String) { + init(host: String, authToken: String, securityToken: String, amzDate: String) { self.host = host self.authToken = authToken self.securityToken = securityToken @@ -50,16 +49,16 @@ public enum AppSyncRealTimeRequestAuth { } } - public struct URLQuery { + struct URLQuery { let header: AppSyncRealTimeRequestAuth let payload: String - public init(header: AppSyncRealTimeRequestAuth, payload: String = "{}") { + init(header: AppSyncRealTimeRequestAuth, payload: String = "{}") { self.header = header self.payload = payload } - public func withBaseURL(_ url: URL, encoder: JSONEncoder? = nil) -> URL { + func withBaseURL(_ url: URL, encoder: JSONEncoder? = nil) -> URL { let jsonEncoder: JSONEncoder = encoder ?? JSONEncoder() guard let headerJsonData = try? jsonEncoder.encode(header) else { return url diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift similarity index 70% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift index c6a0616047..36813b4bbb 100644 --- a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeResponse.swift @@ -8,14 +8,13 @@ import Foundation import Amplify -@_spi(AppSyncRTC) -public struct AppSyncRealTimeResponse { +struct AppSyncRealTimeResponse { - public let id: String? - public let payload: JSONValue? - public let type: EventType + let id: String? + let payload: JSONValue? + let type: EventType - public enum EventType: String, Codable { + enum EventType: String, Codable { case connectionAck = "connection_ack" case startAck = "start_ack" case stopAck = "complete" diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift similarity index 96% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift index 5517057306..88d891cb97 100644 --- a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift @@ -9,15 +9,15 @@ import Foundation import Combine import Amplify +@_spi(WebSocket) import AmplifyNetwork /** AppSyncRealTimeSubscription reprensents one realtime subscription to AppSync realtime server. */ -@_spi(AppSyncRTC) -public actor AppSyncRealTimeSubscription { +actor AppSyncRealTimeSubscription { static let jsonEncoder = JSONEncoder() - public enum State { + enum State { case none case subscribing case subscribed @@ -36,8 +36,8 @@ public actor AppSyncRealTimeSubscription { private weak var appSyncRealTimeClient: AppSyncRealTimeClient? - public let id: String - public let query: String + let id: String + let query: String init(id: String, query: String, appSyncRealTimeClient: AppSyncRealTimeClient) { diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift similarity index 79% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift index b94c16ae70..92414ea28c 100644 --- a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRequestInterceptor.swift @@ -8,7 +8,6 @@ import Foundation -@_spi(AppSyncRTC) -public protocol AppSyncRequestInterceptor { +protocol AppSyncRequestInterceptor { func interceptRequest(event: AppSyncRealTimeRequest, url: URL) async -> AppSyncRealTimeRequest } diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift similarity index 82% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift index 00404601ab..fbc0d27671 100644 --- a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncSubscriptionEvent.swift @@ -9,8 +9,7 @@ import Foundation import Amplify -@_spi(AppSyncRTC) -public enum AppSyncSubscriptionEvent { +enum AppSyncSubscriptionEvent { case subscribing case subscribed case data(JSONValue) diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift similarity index 85% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift index 570ca71689..2f43414296 100644 --- a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift @@ -8,9 +8,9 @@ import Foundation import Combine +@_spi(WebSocket) import AmplifyNetwork -@_spi(AppSyncRTC) -public protocol AppSyncWebSocketClientProtocol: AnyObject { +protocol AppSyncWebSocketClientProtocol: AnyObject { var isConnected: Bool { get async } var publisher: AnyPublisher { get async } diff --git a/AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/README.md b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/README.md similarity index 100% rename from AmplifyPlugins/Internal/Sources/Network/AppSyncRealTimeClient/README.md rename to AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/README.md diff --git a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift index 5e1ed6b31c..b82da6f2d9 100644 --- a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift @@ -10,7 +10,8 @@ import XCTest import Combine @testable import Amplify @testable import AWSAPIPlugin -@testable @_spi(WebSocket) import AWSPluginsCore +@testable import AWSPluginsCore +@testable @_spi(WebSocket) import AmplifyNetwork class AppSyncRealTimeClientTests: XCTestCase { let subscriptionRequest = """ @@ -154,10 +155,12 @@ class AppSyncRealTimeClientTests: XCTestCase { maxSubscriptionReachedError.assertForOverFulfill = false let retryTriggerredAndSucceed = expectation(description: "Retry on max subscription reached error and succeed") cancellables.append(try await makeOneSubscription { event in - if case .error(let errors) = event { - XCTAssertTrue(errors.count == 1) - XCTAssertTrue(errors[0] is AppSyncRealTimeRequest.Error) - if case .maxSubscriptionsReached = errors[0] as! AppSyncRealTimeRequest.Error { + if case .error(let payload) = event, + let error = payload.errors { + let errors = error.asArray ?? [error] + let requestErrors = errors.compactMap(AppSyncRealTimeRequest.parseResponseError(error:)) + XCTAssertTrue(requestErrors.count == 1) + if case .maxSubscriptionsReached = requestErrors[0] { maxSubscriptionReachedError.fulfill() cancellables.dropLast(10).forEach { $0?.cancel() } } diff --git a/AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift similarity index 99% rename from AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift rename to AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift index aac4155d67..3232fb3281 100644 --- a/AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift @@ -10,6 +10,7 @@ import XCTest import Combine import Amplify @testable import AWSAPIPlugin +@_spi(WebSocket) import AmplifyNetwork class AppSyncRealTimeClientTests: XCTestCase { diff --git a/AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift similarity index 100% rename from AmplifyPlugins/Internal/Tests/NetworkTests/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift rename to AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeRequestAuthTests.swift From 559147e988f7e097929e4fff176ed2eaf7229036 Mon Sep 17 00:00:00 2001 From: Di Wu Date: Thu, 28 Mar 2024 15:06:05 -0700 Subject: [PATCH 4/8] change _spi to _implementationOnly --- .../AppSyncRealTimeClient/AppSyncRealTimeClient.swift | 2 +- .../AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift | 2 +- .../AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift | 2 +- .../SubscriptionInterceptor/APIKeyAuthInterceptor.swift | 2 +- .../SubscriptionInterceptor/AuthTokenInterceptor.swift | 2 +- .../SubscriptionInterceptor/IAMAuthInterceptor.swift | 2 +- .../Operation/AWSGraphQLSubscriptionTaskRunner.swift | 2 +- .../SubscriptionFactory/AppSyncRealTimeClientFactory.swift | 2 +- .../AppSyncRealTimeClientTests.swift | 2 +- .../AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift | 2 +- .../SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift | 2 +- .../SubscriptionInterceptor/CognitoAuthInterceptorTests.swift | 2 +- .../API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift | 2 +- .../Operation/AWSGraphQLSubscriptionOperationCancelTests.swift | 2 +- .../Operation/GraphQLSubscribeCombineTests.swift | 2 +- .../AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift | 2 +- .../AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift | 2 +- .../DataStoreLargeNumberModelsSubscriptionTests.swift | 2 +- .../Sources/Network/WebSocket/AmplifyNetworkMonitor.swift | 1 - .../Internal/Sources/Network/WebSocket/RetryWithJitter.swift | 1 - .../Internal/Sources/Network/WebSocket/WebSocketClient.swift | 1 - .../Internal/Sources/Network/WebSocket/WebSocketEvent.swift | 1 - .../Sources/Network/WebSocket/WebSocketInterceptor.swift | 1 - .../Network/WebSocket/WebSocketNetworkMonitorProtocol.swift | 1 - .../Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift | 2 +- .../Tests/NetworkTests/WebSocket/WebSocketClientTests.swift | 2 +- 26 files changed, 20 insertions(+), 26 deletions(-) diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift index 1a411dd589..bbd7b71913 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift @@ -9,7 +9,7 @@ import Foundation import Combine import Amplify -@_spi(WebSocket) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork protocol AppSyncRealTimeClientProtocol { func connect() async throws diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift index 88d891cb97..204d9eefe6 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift @@ -9,7 +9,7 @@ import Foundation import Combine import Amplify -@_spi(WebSocket) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork /** AppSyncRealTimeSubscription reprensents one realtime subscription to AppSync realtime server. diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift index 2f43414296..deff4b205a 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift @@ -8,7 +8,7 @@ import Foundation import Combine -@_spi(WebSocket) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork protocol AppSyncWebSocketClientProtocol: AnyObject { var isConnected: Bool { get async } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift index 671e0627c7..a7edaa3747 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift @@ -8,7 +8,7 @@ import Foundation import Amplify -@_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork class APIKeyAuthInterceptor { private let apiKey: String diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift index 99db676356..8588b00ea3 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift @@ -7,7 +7,7 @@ import Foundation import Amplify -@_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork /// General purpose authenticatication subscriptions interceptor for providers whose only /// requirement is to provide an authentication token via the "Authorization" header diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift index e8ff9cc7c2..0b010156cb 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift @@ -10,7 +10,7 @@ import Amplify import AWSClientRuntime import ClientRuntime import AWSPluginsCore -@_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork class IAMAuthInterceptor { diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift index 8c78cb10ca..796838f693 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift @@ -9,7 +9,7 @@ import Amplify import Foundation import AWSPluginsCore import Combine -@_spi(AppSyncRTC) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork public class AWSGraphQLSubscriptionTaskRunner: InternalTaskRunner, InternalTaskAsyncThrowingSequence, InternalTaskThrowingChannel { public typealias Request = GraphQLOperationRequest diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift index b0a1bbf325..7243b1f00b 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift @@ -10,7 +10,7 @@ import Foundation import Amplify import Combine import AWSPluginsCore -@_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork protocol AppSyncRealTimeClientFactoryProtocol { diff --git a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift index b82da6f2d9..10844f834c 100644 --- a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift @@ -11,7 +11,7 @@ import Combine @testable import Amplify @testable import AWSAPIPlugin @testable import AWSPluginsCore -@testable @_spi(WebSocket) import AmplifyNetwork +@testable @_implementationOnly import AmplifyNetwork class AppSyncRealTimeClientTests: XCTestCase { let subscriptionRequest = """ diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift index 3232fb3281..69957c5879 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift @@ -10,7 +10,7 @@ import XCTest import Combine import Amplify @testable import AWSAPIPlugin -@_spi(WebSocket) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork class AppSyncRealTimeClientTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift index db1de6de82..a61dc9cd99 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift @@ -9,7 +9,7 @@ import XCTest import Amplify @testable import AWSAPIPlugin -@testable @_spi(AppSyncRTC) import AmplifyNetwork +@testable @_implementationOnly import AmplifyNetwork class APIKeyAuthInterceptorTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift index 2e57e27579..508d867496 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift @@ -10,7 +10,7 @@ import XCTest import Amplify @testable import AWSAPIPlugin @testable import AWSPluginsCore -@testable @_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork +@testable @_implementationOnly import AmplifyNetwork class CognitoAuthInterceptorTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift index e02b61a939..277daa37d0 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift @@ -11,7 +11,7 @@ import Amplify import Combine @testable import AWSAPIPlugin @testable import AWSPluginsCore -@testable @_spi(WebSocket) @_spi(AppSyncRTC) import AmplifyNetwork +@testable @_implementationOnly import AmplifyNetwork struct MockSubscriptionConnectionFactory: AppSyncRealTimeClientFactoryProtocol { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionOperationCancelTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionOperationCancelTests.swift index 95fc5b8e63..f0b9dcf390 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionOperationCancelTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionOperationCancelTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import Amplify @testable import AWSAPIPlugin @testable import AmplifyTestCommon -@testable @_spi(WebSocket) import AWSPluginsCore +@testable import AWSPluginsCore @testable import AWSPluginsTestCommon // swiftlint:disable:next type_name diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift index d8e9073096..3fe53f7099 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift @@ -11,7 +11,7 @@ import XCTest import Amplify @testable import AmplifyTestCommon @testable import AWSAPIPlugin -@testable @_spi(AppSyncRTC) import AmplifyNetwork +@testable @_implementationOnly import AmplifyNetwork @_implementationOnly import AmplifyAsyncTesting class GraphQLSubscribeCombineTests: OperationTestBase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift index 6c0e7b0421..446e159bd8 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift @@ -11,7 +11,7 @@ import XCTest import Amplify @testable import AmplifyTestCommon @testable import AWSAPIPlugin -@testable @_spi(AppSyncRTC) import AmplifyNetwork +@testable @_implementationOnly import AmplifyNetwork @_implementationOnly import AmplifyAsyncTesting class GraphQLSubscribeTasksTests: OperationTestBase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift index 98806c17e0..dee60cde4b 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import Amplify @testable import AmplifyTestCommon @testable import AWSAPIPlugin -@testable @_spi(AppSyncRTC) import AmplifyNetwork +@testable @_implementationOnly import AmplifyNetwork class GraphQLSubscribeTests: OperationTestBase { diff --git a/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift b/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift index cc0fc9fbe6..d0769d45ca 100644 --- a/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift +++ b/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift @@ -10,7 +10,7 @@ import XCTest import Combine import Amplify @testable import AWSAPIPlugin -@_spi(AppSyncRTC) import AmplifyNetwork +@_implementationOnly import AmplifyNetwork class DataStoreLargeNumberModelsSubscriptionTests: SyncEngineIntegrationTestBase { diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift index 23eb1ec4e2..50bc2180d5 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift @@ -9,7 +9,6 @@ import Network import Combine -@_spi(WebSocket) public final class AmplifyNetworkMonitor { public enum State { diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift index 9da51cb03f..ff97fab87d 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift @@ -8,7 +8,6 @@ import Foundation -@_spi(WebSocket) public actor RetryWithJitter { public enum Error: Swift.Error { case maxRetryExceeded([Swift.Error]) diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift index bc677744f8..513f121621 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift @@ -14,7 +14,6 @@ import Combine WebSocketClient wraps URLSessionWebSocketTask and offers an abstraction of the data stream in the form of WebSocketEvent. */ -@_spi(WebSocket) public final actor WebSocketClient: NSObject { public enum Error: Swift.Error { case connectionLost diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift index 35c101dd6e..4035e20a3a 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift @@ -8,7 +8,6 @@ import Foundation -@_spi(WebSocket) public enum WebSocketEvent { case connected case disconnected(URLSessionWebSocketTask.CloseCode, String?) diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift index a53ec3b950..6bed62cde5 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift @@ -8,7 +8,6 @@ import Foundation -@_spi(WebSocket) public protocol WebSocketInterceptor { func interceptConnection(url: URL) async -> URL } diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift index 3966e7ab9d..1958228a38 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift @@ -9,7 +9,6 @@ import Foundation import Combine -@_spi(WebSocket) public protocol WebSocketNetworkMonitorProtocol { var publisher: AnyPublisher<(AmplifyNetworkMonitor.State, AmplifyNetworkMonitor.State), Never> { get } func updateState(_ nextState: AmplifyNetworkMonitor.State) async diff --git a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift index 9ada954056..15a6aed34e 100644 --- a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift +++ b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift @@ -7,7 +7,7 @@ import XCTest -@testable @_spi(WebSocket) import AWSPluginsCore +@testable import AWSPluginsCore class RetryWithJitterTests: XCTestCase { struct TestError: Error { diff --git a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift index f3e53669c1..a9dc80a155 100644 --- a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift +++ b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift @@ -8,7 +8,7 @@ import XCTest import Combine -@testable @_spi(WebSocket) import AWSPluginsCore +@testable import AWSPluginsCore fileprivate let timeout: TimeInterval = 5 From 00a310a11167ce753ba4bf3fe62a7d887fb1518e Mon Sep 17 00:00:00 2001 From: Di Wu Date: Thu, 4 Apr 2024 12:45:22 -0700 Subject: [PATCH 5/8] change to _spi annotations --- .../AppSyncRealTimeClient/AppSyncRealTimeClient.swift | 2 +- .../AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift | 2 +- .../AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift | 2 +- .../SubscriptionInterceptor/APIKeyAuthInterceptor.swift | 2 +- .../SubscriptionInterceptor/AuthTokenInterceptor.swift | 2 +- .../SubscriptionInterceptor/IAMAuthInterceptor.swift | 2 +- .../Operation/AWSGraphQLSubscriptionTaskRunner.swift | 1 - .../SubscriptionFactory/AppSyncRealTimeClientFactory.swift | 2 +- .../AppSyncRealTimeClientTests.swift | 1 - .../AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift | 2 +- .../SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift | 1 - .../SubscriptionInterceptor/CognitoAuthInterceptorTests.swift | 1 - .../API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift | 2 +- .../Operation/GraphQLSubscribeCombineTests.swift | 1 - .../AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift | 1 - .../AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift | 1 - .../DataStoreLargeNumberModelsSubscriptionTests.swift | 1 - .../Sources/Network/WebSocket/AmplifyNetworkMonitor.swift | 1 + .../Internal/Sources/Network/WebSocket/RetryWithJitter.swift | 1 + .../Internal/Sources/Network/WebSocket/WebSocketClient.swift | 1 + .../Internal/Sources/Network/WebSocket/WebSocketEvent.swift | 1 + .../Sources/Network/WebSocket/WebSocketInterceptor.swift | 1 + .../Network/WebSocket/WebSocketNetworkMonitorProtocol.swift | 1 + 23 files changed, 15 insertions(+), 17 deletions(-) diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift index bbd7b71913..245117cf06 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift @@ -9,7 +9,7 @@ import Foundation import Combine import Amplify -@_implementationOnly import AmplifyNetwork +@_spi(WebSocket) @_spi(RetryWithJitter) import AmplifyNetwork protocol AppSyncRealTimeClientProtocol { func connect() async throws diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift index 204d9eefe6..a9c01c58bf 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift @@ -9,7 +9,7 @@ import Foundation import Combine import Amplify -@_implementationOnly import AmplifyNetwork +@_spi(RetryWithJitter) import AmplifyNetwork /** AppSyncRealTimeSubscription reprensents one realtime subscription to AppSync realtime server. diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift index deff4b205a..2f43414296 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift @@ -8,7 +8,7 @@ import Foundation import Combine -@_implementationOnly import AmplifyNetwork +@_spi(WebSocket) import AmplifyNetwork protocol AppSyncWebSocketClientProtocol: AnyObject { var isConnected: Bool { get async } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift index a7edaa3747..a2d122d50b 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift @@ -8,7 +8,7 @@ import Foundation import Amplify -@_implementationOnly import AmplifyNetwork +@_spi(WebSocket) import AmplifyNetwork class APIKeyAuthInterceptor { private let apiKey: String diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift index 8588b00ea3..b72c3310c4 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift @@ -7,7 +7,7 @@ import Foundation import Amplify -@_implementationOnly import AmplifyNetwork +@_spi(WebSocket) import AmplifyNetwork /// General purpose authenticatication subscriptions interceptor for providers whose only /// requirement is to provide an authentication token via the "Authorization" header diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift index 0b010156cb..cad6e5d4ec 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift @@ -10,7 +10,7 @@ import Amplify import AWSClientRuntime import ClientRuntime import AWSPluginsCore -@_implementationOnly import AmplifyNetwork +@_spi(WebSocket) import AmplifyNetwork class IAMAuthInterceptor { diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift index 796838f693..0c85051e4f 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift @@ -9,7 +9,6 @@ import Amplify import Foundation import AWSPluginsCore import Combine -@_implementationOnly import AmplifyNetwork public class AWSGraphQLSubscriptionTaskRunner: InternalTaskRunner, InternalTaskAsyncThrowingSequence, InternalTaskThrowingChannel { public typealias Request = GraphQLOperationRequest diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift index 7243b1f00b..24ebb1d03f 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift @@ -10,7 +10,7 @@ import Foundation import Amplify import Combine import AWSPluginsCore -@_implementationOnly import AmplifyNetwork +@_spi(WebSocket) import AmplifyNetwork protocol AppSyncRealTimeClientFactoryProtocol { diff --git a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift index 10844f834c..ef53c8ddaf 100644 --- a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift @@ -11,7 +11,6 @@ import Combine @testable import Amplify @testable import AWSAPIPlugin @testable import AWSPluginsCore -@testable @_implementationOnly import AmplifyNetwork class AppSyncRealTimeClientTests: XCTestCase { let subscriptionRequest = """ diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift index 69957c5879..3232fb3281 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift @@ -10,7 +10,7 @@ import XCTest import Combine import Amplify @testable import AWSAPIPlugin -@_implementationOnly import AmplifyNetwork +@_spi(WebSocket) import AmplifyNetwork class AppSyncRealTimeClientTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift index a61dc9cd99..8c89c0a53a 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptorTests.swift @@ -9,7 +9,6 @@ import XCTest import Amplify @testable import AWSAPIPlugin -@testable @_implementationOnly import AmplifyNetwork class APIKeyAuthInterceptorTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift index 508d867496..827ed88dac 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Interceptor/SubscriptionInterceptor/CognitoAuthInterceptorTests.swift @@ -10,7 +10,6 @@ import XCTest import Amplify @testable import AWSAPIPlugin @testable import AWSPluginsCore -@testable @_implementationOnly import AmplifyNetwork class CognitoAuthInterceptorTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift index 277daa37d0..ce698cd3ff 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift @@ -11,7 +11,7 @@ import Amplify import Combine @testable import AWSAPIPlugin @testable import AWSPluginsCore -@testable @_implementationOnly import AmplifyNetwork +@_spi(WebSocket) import AmplifyNetwork struct MockSubscriptionConnectionFactory: AppSyncRealTimeClientFactoryProtocol { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift index 3fe53f7099..cbe8ad220c 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeCombineTests.swift @@ -11,7 +11,6 @@ import XCTest import Amplify @testable import AmplifyTestCommon @testable import AWSAPIPlugin -@testable @_implementationOnly import AmplifyNetwork @_implementationOnly import AmplifyAsyncTesting class GraphQLSubscribeCombineTests: OperationTestBase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift index 446e159bd8..9d0257d6c7 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTaskTests.swift @@ -11,7 +11,6 @@ import XCTest import Amplify @testable import AmplifyTestCommon @testable import AWSAPIPlugin -@testable @_implementationOnly import AmplifyNetwork @_implementationOnly import AmplifyAsyncTesting class GraphQLSubscribeTasksTests: OperationTestBase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift index dee60cde4b..4b28c62cc2 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/GraphQLSubscribeTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import Amplify @testable import AmplifyTestCommon @testable import AWSAPIPlugin -@testable @_implementationOnly import AmplifyNetwork class GraphQLSubscribeTests: OperationTestBase { diff --git a/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift b/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift index d0769d45ca..cc09f0f40d 100644 --- a/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift +++ b/AmplifyPlugins/DataStore/Tests/DataStoreHostApp/AWSDataStorePluginIntegrationTests/DataStoreLargeNumberModelsSubscriptionTests.swift @@ -10,7 +10,6 @@ import XCTest import Combine import Amplify @testable import AWSAPIPlugin -@_implementationOnly import AmplifyNetwork class DataStoreLargeNumberModelsSubscriptionTests: SyncEngineIntegrationTestBase { diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift index 50bc2180d5..e1ac3c9c5c 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/AmplifyNetworkMonitor.swift @@ -9,6 +9,7 @@ import Network import Combine +@_spi(NetworkReachability) public final class AmplifyNetworkMonitor { public enum State { diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift index ff97fab87d..29436f916f 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/RetryWithJitter.swift @@ -8,6 +8,7 @@ import Foundation +@_spi(RetryWithJitter) public actor RetryWithJitter { public enum Error: Swift.Error { case maxRetryExceeded([Swift.Error]) diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift index 513f121621..bc677744f8 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketClient.swift @@ -14,6 +14,7 @@ import Combine WebSocketClient wraps URLSessionWebSocketTask and offers an abstraction of the data stream in the form of WebSocketEvent. */ +@_spi(WebSocket) public final actor WebSocketClient: NSObject { public enum Error: Swift.Error { case connectionLost diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift index 4035e20a3a..35c101dd6e 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketEvent.swift @@ -8,6 +8,7 @@ import Foundation +@_spi(WebSocket) public enum WebSocketEvent { case connected case disconnected(URLSessionWebSocketTask.CloseCode, String?) diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift index 6bed62cde5..a53ec3b950 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketInterceptor.swift @@ -8,6 +8,7 @@ import Foundation +@_spi(WebSocket) public protocol WebSocketInterceptor { func interceptConnection(url: URL) async -> URL } diff --git a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift index 1958228a38..3966e7ab9d 100644 --- a/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift +++ b/AmplifyPlugins/Internal/Sources/Network/WebSocket/WebSocketNetworkMonitorProtocol.swift @@ -9,6 +9,7 @@ import Foundation import Combine +@_spi(WebSocket) public protocol WebSocketNetworkMonitorProtocol { var publisher: AnyPublisher<(AmplifyNetworkMonitor.State, AmplifyNetworkMonitor.State), Never> { get } func updateState(_ nextState: AmplifyNetworkMonitor.State) async From 705338f348e5a0d5372b82a0803223374c617a54 Mon Sep 17 00:00:00 2001 From: Di Wu Date: Thu, 4 Apr 2024 13:49:35 -0700 Subject: [PATCH 6/8] fix intg test build error --- .../AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift index ef53c8ddaf..3687fe969a 100644 --- a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift @@ -11,6 +11,7 @@ import Combine @testable import Amplify @testable import AWSAPIPlugin @testable import AWSPluginsCore +@_spi(WebSocket) import AmplifyNetwork class AppSyncRealTimeClientTests: XCTestCase { let subscriptionRequest = """ From 633a8f0cce3966cead113e7672bbd0d21a344014 Mon Sep 17 00:00:00 2001 From: Di Wu Date: Thu, 16 May 2024 16:30:08 -0700 Subject: [PATCH 7/8] add unit test cases for appsync response error parsing --- .../AWSGraphQLSubscriptionTaskRunner.swift | 1 - ...SGraphQLSubscriptionTaskRunnerTests.swift} | 100 +++++++++++++++++- .../WebSocket/LocalWebSocketServer.swift | 8 +- .../WebSocket/RetryWithJitterTests.swift | 1 + .../WebSocket/WebSocketClientTests.swift | 1 + Package.swift | 1 + 6 files changed, 108 insertions(+), 4 deletions(-) rename AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/{AWSGraphQLSubscriptionTaskRunnerCancelTests.swift => AWSGraphQLSubscriptionTaskRunnerTests.swift} (66%) diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift index 382baa0775..09dfa9d3c7 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift @@ -178,7 +178,6 @@ public class AWSGraphQLSubscriptionTaskRunner: InternalTaskRunner, } } - internal static func decodeAppSyncRealTimeResponseError(_ data: JSONValue?) -> [Error] { let knownAppSyncRealTimeRequestErorrs = decodeAppSyncRealTimeRequestError(data) diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionTaskRunnerCancelTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionTaskRunnerTests.swift similarity index 66% rename from AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionTaskRunnerCancelTests.swift rename to AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionTaskRunnerTests.swift index a06001515f..f96b8fe5bd 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionTaskRunnerCancelTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Operation/AWSGraphQLSubscriptionTaskRunnerTests.swift @@ -14,7 +14,7 @@ import XCTest @testable import AWSPluginsTestCommon // swiftlint:disable:next type_name -class AWSGraphQLSubscriptionTaskRunnerCancelTests: XCTestCase { +class AWSGraphQLSubscriptionTaskRunnerTests: XCTestCase { var apiPlugin: AWSAPIPlugin! var authService: MockAWSAuthService! var pluginConfig: AWSAPICategoryPluginConfiguration! @@ -183,4 +183,102 @@ class AWSGraphQLSubscriptionTaskRunnerCancelTests: XCTestCase { subscriptionEvents.cancel() await fulfillment(of: [receivedFailure, receivedCompletion], timeout: 5) } + + func testDecodeAppSyncRealTimeResponseError_withEmptyJsonValue_failedToDecode() { + let errors = AWSGraphQLSubscriptionTaskRunner.decodeAppSyncRealTimeResponseError(nil) + XCTAssertEqual(errors.count, 1) + if case .some(.operationError(let description, _, _)) = errors.first as? APIError { + XCTAssertTrue(description.contains("Failed to decode AppSync error response")) + } else { + XCTFail("Should be failed with APIError") + } + } + + func testDecodeAppSYncRealTimeResponseError_withKnownAppSyncRealTimeRequestError_returnKnownErrors() { + let errorJson: JSONValue = [ + "errors": [[ + "message": "test1", + "errorType": "MaxSubscriptionsReachedError" + ]] + ] + + let errors = AWSGraphQLSubscriptionTaskRunner.decodeAppSyncRealTimeResponseError(errorJson) + XCTAssertEqual(errors.count, 1) + guard case .maxSubscriptionsReached = errors.first as? AppSyncRealTimeRequest.Error else { + XCTFail("Should be AppSyncRealTimeRequestError") + return + } + } + + func testDecodeAppSYncRealTimeResponseError_withUnknownError_returnParsedGraphQLError() { + let errorJson: JSONValue = [ + "errors": [[ + "message": "test1", + "errorType": "Unknown" + ]] + ] + + let errors = AWSGraphQLSubscriptionTaskRunner.decodeAppSyncRealTimeResponseError(errorJson) + XCTAssertEqual(errors.count, 1) + XCTAssertTrue(errors.first is GraphQLError) + } + + func testDecodeAppSyncRealTimeRequestError_withoutErrorsField_returnEmptyErrors() { + let errorJson: JSONValue = [ + "noErrors": [[ + "message": "test1", + "errorType": "Unknown" + ]] + ] + + let errors = AWSGraphQLSubscriptionTaskRunner.decodeAppSyncRealTimeRequestError(errorJson) + XCTAssertEqual(errors.count, 0) + } + + func testDecodeAppSyncRealTimeRequestError_withWellFormatErrors_parseErrors() { + let errorJson: JSONValue = [ + "errors": [[ + "message": "test1", + "errorType": "MaxSubscriptionsReachedError" + ], [ + "message": "test2", + "errorType": "LimitExceededError" + ], [ + "message": "test3", + "errorType": "Unauthorized" + ]] + ] + + let errors = AWSGraphQLSubscriptionTaskRunner.decodeAppSyncRealTimeRequestError(errorJson) + XCTAssertEqual(errors.count, 3) + } + + func testDecodeAppSyncRealTimeRequestError_withSomeWellFormatErrors_parseErrors() { + let errorJson: JSONValue = [ + "errors": [[ + "message": "test1", + "errorType": "MaxSubscriptionsReachedError" + ], [ + "message": "test2", + "errorType": "LimitExceededError" + ], [ + "random": "123" + ]] + ] + + let errors = AWSGraphQLSubscriptionTaskRunner.decodeAppSyncRealTimeRequestError(errorJson) + XCTAssertEqual(errors.count, 2) + } + + func testDecodeAppSyncRealTimeRequestError_withSingletonErrors_parseErrors() { + let errorJson: JSONValue = [ + "errors": [ + "message": "test1", + "errorType": "MaxSubscriptionsReachedError" + ] + ] + + let errors = AWSGraphQLSubscriptionTaskRunner.decodeAppSyncRealTimeRequestError(errorJson) + XCTAssertEqual(errors.count, 1) + } } diff --git a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/LocalWebSocketServer.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/LocalWebSocketServer.swift index 1dc0fbd948..0b8c47f16a 100644 --- a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/LocalWebSocketServer.swift +++ b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/LocalWebSocketServer.swift @@ -37,7 +37,7 @@ class LocalWebSocketServer { stack.applicationProtocols.insert(ws, at: 0) let port = NWEndpoint.Port(rawValue: portNumber)! guard let listener = try? NWListener(using: params, on: port) else { - throw "unable to start the listener at: localhost:\(port)" + throw LocalWebSocketServerError.error("unable to start the listener at: localhost:\(port)") } listener.newConnectionHandler = { [weak self] conn in @@ -93,7 +93,7 @@ class LocalWebSocketServer { func sendTransientFailureToConnections() { self.connections.forEach { - var metadata = NWProtocolWebSocket.Metadata(opcode: .close) + let metadata = NWProtocolWebSocket.Metadata(opcode: .close) metadata.closeCode = .protocolCode(NWProtocolWebSocket.CloseCode.Defined.internalServerError) $0.send( content: nil, @@ -103,3 +103,7 @@ class LocalWebSocketServer { } } } + +enum LocalWebSocketServerError: Error { + case error(String) +} diff --git a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift index 15a6aed34e..b7a023be44 100644 --- a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift +++ b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift @@ -8,6 +8,7 @@ import XCTest @testable import AWSPluginsCore +@testable @_spi(RetryWithJitter) import AmplifyNetwork class RetryWithJitterTests: XCTestCase { struct TestError: Error { diff --git a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift index a9dc80a155..be05e55443 100644 --- a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift +++ b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift @@ -9,6 +9,7 @@ import XCTest import Combine @testable import AWSPluginsCore +@testable @_spi(WebSocket) @_spi(NetworkReachability) import AmplifyNetwork fileprivate let timeout: TimeInterval = 5 diff --git a/Package.swift b/Package.swift index 1b9240c19a..38de745653 100644 --- a/Package.swift +++ b/Package.swift @@ -327,6 +327,7 @@ let internalNetworkingTargets: [Target] = [ .testTarget( name: "AmplifyNetworkUnitTests", dependencies: [ + "AmplifyTestCommon", "AmplifyNetwork" ], path: "AmplifyPlugins/Internal/Tests/NetworkTests" From a2cf85a91a311ddebb31a0241598253c07fd9a2c Mon Sep 17 00:00:00 2001 From: Di Wu Date: Fri, 17 May 2024 10:49:11 -0700 Subject: [PATCH 8/8] rename package name to InternalAmplifyNetwork --- .../xcschemes/Amplify-Package.xcscheme | 19 ++++++++++--------- .../AppSyncRealTimeClient.swift | 2 +- .../AppSyncRealTimeSubscription.swift | 2 +- .../AppSyncWebSocketClientProtocol.swift | 2 +- .../APIKeyAuthInterceptor.swift | 2 +- .../AuthTokenInterceptor.swift | 2 +- .../IAMAuthInterceptor.swift | 2 +- .../AppSyncRealTimeClientFactory.swift | 2 +- .../AppSyncRealTimeClientTests.swift | 2 +- .../AppSyncRealTimeClientTests.swift | 2 +- .../Mocks/MockSubscription.swift | 2 +- .../WebSocket/RetryWithJitterTests.swift | 2 +- .../WebSocket/WebSocketClientTests.swift | 2 +- Package.swift | 8 ++++---- 14 files changed, 26 insertions(+), 25 deletions(-) diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Amplify-Package.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Amplify-Package.xcscheme index 08c2c9efc2..c13ed00ec0 100644 --- a/.swiftpm/xcode/xcshareddata/xcschemes/Amplify-Package.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/Amplify-Package.xcscheme @@ -751,6 +751,16 @@ ReferencedContainer = "container:"> + + + + - - - - diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift index d791c3920a..dcab347d96 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift @@ -9,7 +9,7 @@ import Foundation import Combine import Amplify -@_spi(WebSocket) @_spi(RetryWithJitter) import AmplifyNetwork +@_spi(WebSocket) @_spi(RetryWithJitter) import InternalAmplifyNetwork protocol AppSyncRealTimeClientProtocol { func connect() async throws diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift index a9c01c58bf..2997311b7b 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeSubscription.swift @@ -9,7 +9,7 @@ import Foundation import Combine import Amplify -@_spi(RetryWithJitter) import AmplifyNetwork +@_spi(RetryWithJitter) import InternalAmplifyNetwork /** AppSyncRealTimeSubscription reprensents one realtime subscription to AppSync realtime server. diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift index 2f43414296..8969aaa1e3 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncWebSocketClientProtocol.swift @@ -8,7 +8,7 @@ import Foundation import Combine -@_spi(WebSocket) import AmplifyNetwork +@_spi(WebSocket) import InternalAmplifyNetwork protocol AppSyncWebSocketClientProtocol: AnyObject { var isConnected: Bool { get async } diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift index a2d122d50b..7174bfd414 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/APIKeyAuthInterceptor.swift @@ -8,7 +8,7 @@ import Foundation import Amplify -@_spi(WebSocket) import AmplifyNetwork +@_spi(WebSocket) import InternalAmplifyNetwork class APIKeyAuthInterceptor { private let apiKey: String diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift index b72c3310c4..c5ed1b50e7 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/AuthTokenInterceptor.swift @@ -7,7 +7,7 @@ import Foundation import Amplify -@_spi(WebSocket) import AmplifyNetwork +@_spi(WebSocket) import InternalAmplifyNetwork /// General purpose authenticatication subscriptions interceptor for providers whose only /// requirement is to provide an authentication token via the "Authorization" header diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift index cad6e5d4ec..41d4aa26b6 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/Interceptor/SubscriptionInterceptor/IAMAuthInterceptor.swift @@ -10,7 +10,7 @@ import Amplify import AWSClientRuntime import ClientRuntime import AWSPluginsCore -@_spi(WebSocket) import AmplifyNetwork +@_spi(WebSocket) import InternalAmplifyNetwork class IAMAuthInterceptor { diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift index 24ebb1d03f..3f8a7a5d5e 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift @@ -10,7 +10,7 @@ import Foundation import Amplify import Combine import AWSPluginsCore -@_spi(WebSocket) import AmplifyNetwork +@_spi(WebSocket) import InternalAmplifyNetwork protocol AppSyncRealTimeClientFactoryProtocol { diff --git a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift index 3687fe969a..3966917b5e 100644 --- a/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift @@ -11,7 +11,7 @@ import Combine @testable import Amplify @testable import AWSAPIPlugin @testable import AWSPluginsCore -@_spi(WebSocket) import AmplifyNetwork +@_spi(WebSocket) import InternalAmplifyNetwork class AppSyncRealTimeClientTests: XCTestCase { let subscriptionRequest = """ diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift index 3232fb3281..dc68e851cc 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift @@ -10,7 +10,7 @@ import XCTest import Combine import Amplify @testable import AWSAPIPlugin -@_spi(WebSocket) import AmplifyNetwork +@_spi(WebSocket) import InternalAmplifyNetwork class AppSyncRealTimeClientTests: XCTestCase { diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift index ce698cd3ff..9840a28170 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/Mocks/MockSubscription.swift @@ -11,7 +11,7 @@ import Amplify import Combine @testable import AWSAPIPlugin @testable import AWSPluginsCore -@_spi(WebSocket) import AmplifyNetwork +@_spi(WebSocket) import InternalAmplifyNetwork struct MockSubscriptionConnectionFactory: AppSyncRealTimeClientFactoryProtocol { diff --git a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift index b7a023be44..d1bbe4a22c 100644 --- a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift +++ b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/RetryWithJitterTests.swift @@ -8,7 +8,7 @@ import XCTest @testable import AWSPluginsCore -@testable @_spi(RetryWithJitter) import AmplifyNetwork +@testable @_spi(RetryWithJitter) import InternalAmplifyNetwork class RetryWithJitterTests: XCTestCase { struct TestError: Error { diff --git a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift index be05e55443..51b7a2e8f9 100644 --- a/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift +++ b/AmplifyPlugins/Internal/Tests/NetworkTests/WebSocket/WebSocketClientTests.swift @@ -9,7 +9,7 @@ import XCTest import Combine @testable import AWSPluginsCore -@testable @_spi(WebSocket) @_spi(NetworkReachability) import AmplifyNetwork +@testable @_spi(WebSocket) @_spi(NetworkReachability) import InternalAmplifyNetwork fileprivate let timeout: TimeInterval = 5 diff --git a/Package.swift b/Package.swift index 38de745653..bc4ce0b4a5 100644 --- a/Package.swift +++ b/Package.swift @@ -116,7 +116,7 @@ let apiTargets: [Target] = [ dependencies: [ .target(name: "Amplify"), .target(name: "AWSPluginsCore"), - .target(name: "AmplifyNetwork") + .target(name: "InternalAmplifyNetwork") ], path: "AmplifyPlugins/API/Sources/AWSAPIPlugin", exclude: [ @@ -318,17 +318,17 @@ let internalPinpointTargets: [Target] = [ let internalNetworkingTargets: [Target] = [ .target( - name: "AmplifyNetwork", + name: "InternalAmplifyNetwork", dependencies: [ .target(name: "Amplify") ], path: "AmplifyPlugins/Internal/Sources/Network" ), .testTarget( - name: "AmplifyNetworkUnitTests", + name: "InternalAmplifyNetworkUnitTests", dependencies: [ "AmplifyTestCommon", - "AmplifyNetwork" + "InternalAmplifyNetwork" ], path: "AmplifyPlugins/Internal/Tests/NetworkTests" )