Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

AWSNetworkTransport modifications to enable the ability to mock server #40

Merged
merged 3 commits into from
Jun 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions AWSAppSyncClient.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
17E009DA1FCAB234005031DB /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17E009B81FCAB233005031DB /* Result.swift */; };
17E009DB1FCAB234005031DB /* NormalizedCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17E009B91FCAB234005031DB /* NormalizedCache.swift */; };
17E009DC1FCAB234005031DB /* ApolloClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17E009BA1FCAB234005031DB /* ApolloClient.swift */; };
DF9468DB20E1CA4A00E40482 /* AWSNetworkTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF9468DA20E1CA4A00E40482 /* AWSNetworkTransport.swift */; };
E4EA2880833EDE9A29FEBC15 /* Pods_AWSAppSync.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 621AB86198B779E235D8B962 /* Pods_AWSAppSync.framework */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -142,6 +143,7 @@
621AB86198B779E235D8B962 /* Pods_AWSAppSync.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AWSAppSync.framework; sourceTree = BUILT_PRODUCTS_DIR; };
AD111EB21748A599F5796B74 /* Pods-AWSAppSync.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AWSAppSync.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AWSAppSync/Pods-AWSAppSync.debug.xcconfig"; sourceTree = "<group>"; };
C830ED8003E746C4C6799F8E /* Pods-AWSAppSync.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AWSAppSync.release.xcconfig"; path = "Pods/Target Support Files/Pods-AWSAppSync/Pods-AWSAppSync.release.xcconfig"; sourceTree = "<group>"; };
DF9468DA20E1CA4A00E40482 /* AWSNetworkTransport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AWSNetworkTransport.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -232,6 +234,7 @@
17DECF611F59F5FF004B0512 /* AWSAppSync.h */,
17DECF621F59F5FF004B0512 /* Info.plist */,
17A66BA31F59FF69008DDA11 /* AWSAppSyncClient.swift */,
DF9468DA20E1CA4A00E40482 /* AWSNetworkTransport.swift */,
17915B041F5F106600C4B73C /* AWSAppSyncHTTPNetworkTransport.swift */,
17A2673C1F66465B009E50B7 /* AWSSQLLiteNormalizedCache.swift */,
17D2C2061F6F44A3006C6818 /* AWSOfflineMutationStore.swift */,
Expand Down Expand Up @@ -422,6 +425,7 @@
1729A0BF1F9DAB2400F88594 /* AWSSRWebSocket.m in Sources */,
17E009BC1FCAB234005031DB /* AWSGraphQLSubscriptionResponse.swift in Sources */,
1729A0B11F9DAB2400F88594 /* MQTTClient.m in Sources */,
DF9468DB20E1CA4A00E40482 /* AWSNetworkTransport.swift in Sources */,
17E009C91FCAB234005031DB /* Record.swift in Sources */,
17E009D41FCAB234005031DB /* GraphQLResultNormalizer.swift in Sources */,
17E009C01FCAB234005031DB /* InMemoryNormalizedCache.swift in Sources */,
Expand Down
84 changes: 52 additions & 32 deletions AWSAppSyncClient/AWSAppSyncClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,8 @@ public class AWSAppSyncClientConfiguration {
fileprivate var url: URL
fileprivate var region: AWSRegionType
fileprivate var store: ApolloStore
fileprivate var urlSessionConfiguration: URLSessionConfiguration

fileprivate var credentialsProvider: AWSCredentialsProvider? = nil
fileprivate var networkTransport: AWSNetworkTransport
fileprivate var databaseURL: URL?
fileprivate var apiKeyAuthProvider: AWSAPIKeyAuthProvider? = nil
fileprivate var userPoolsAuthProvider: AWSCognitoUserPoolsAuthProvider? = nil
fileprivate var oidcAuthProvider: AWSOIDCAuthProvider? = nil
fileprivate var snapshotController: SnapshotProcessController? = nil
fileprivate var s3ObjectManager: AWSS3ObjectManager? = nil
Expand Down Expand Up @@ -122,10 +118,13 @@ public class AWSAppSyncClientConfiguration {
presignedURLClient: AWSS3ObjectPresignedURLGenerator? = nil) throws {
self.url = url
self.region = serviceRegion
self.credentialsProvider = credentialsProvider
self.urlSessionConfiguration = urlSessionConfiguration
self.databaseURL = databaseURL
self.store = ApolloStore(cache: InMemoryNormalizedCache())
self.networkTransport = AWSAppSyncHTTPNetworkTransport(url: url,
configuration: urlSessionConfiguration,
region: region,
credentialsProvider: credentialsProvider)

self.connectionStateChangeHandler = connectionStateChangeHandler
if let databaseURL = databaseURL {
do {
Expand Down Expand Up @@ -160,10 +159,11 @@ public class AWSAppSyncClientConfiguration {
presignedURLClient: AWSS3ObjectPresignedURLGenerator? = nil) throws {
self.url = url
self.region = serviceRegion
self.apiKeyAuthProvider = apiKeyAuthProvider
self.urlSessionConfiguration = urlSessionConfiguration
self.databaseURL = databaseURL
self.store = ApolloStore(cache: InMemoryNormalizedCache())
self.networkTransport = AWSAppSyncHTTPNetworkTransport(url: url,
apiKeyAuthProvider: apiKeyAuthProvider,
configuration: urlSessionConfiguration)
if let databaseURL = databaseURL {
do {
self.store = try ApolloStore(cache: AWSSQLLiteNormalizedCache(fileURL: databaseURL))
Expand Down Expand Up @@ -197,10 +197,11 @@ public class AWSAppSyncClientConfiguration {
presignedURLClient: AWSS3ObjectPresignedURLGenerator? = nil) throws {
self.url = url
self.region = serviceRegion
self.userPoolsAuthProvider = userPoolsAuthProvider
self.urlSessionConfiguration = urlSessionConfiguration
self.databaseURL = databaseURL
self.store = ApolloStore(cache: InMemoryNormalizedCache())
self.networkTransport = AWSAppSyncHTTPNetworkTransport(url: url,
userPoolsAuthProvider: userPoolsAuthProvider,
configuration: urlSessionConfiguration)
if let databaseURL = databaseURL {
do {
self.store = try ApolloStore(cache: AWSSQLLiteNormalizedCache(fileURL: databaseURL))
Expand Down Expand Up @@ -234,10 +235,45 @@ public class AWSAppSyncClientConfiguration {
presignedURLClient: AWSS3ObjectPresignedURLGenerator? = nil) throws {
self.url = url
self.region = serviceRegion
self.oidcAuthProvider = oidcAuthProvider
self.urlSessionConfiguration = urlSessionConfiguration
self.databaseURL = databaseURL
self.store = ApolloStore(cache: InMemoryNormalizedCache())
self.networkTransport = AWSAppSyncHTTPNetworkTransport(url: url,
oidcAuthProvider: oidcAuthProvider,
configuration: urlSessionConfiguration)
if let databaseURL = databaseURL {
do {
self.store = try ApolloStore(cache: AWSSQLLiteNormalizedCache(fileURL: databaseURL))
} catch {
// Use in memory cache incase database init fails
}
}
self.s3ObjectManager = s3ObjectManager
self.presignedURLClient = presignedURLClient
self.connectionStateChangeHandler = connectionStateChangeHandler
}

/// Creates a configuration object for the `AWSAppSyncClient`.
///
/// - Parameters:
/// - url: The endpoint url for Appsync endpoint.
/// - serviceRegion: The service region for Appsync.
/// - networkTransport: The Network Transport used to communicate with the server.
/// - databaseURL: The path to local sqlite database for persistent storage, if nil, an in-memory database is used.
/// - connectionStateChangeHandler: The delegate object to be notified when client network state changes.
/// - s3ObjectManager: The client used for uploading / downloading `S3Objects`.
/// - presignedURLClient: The `AWSAppSyncClientConfiguration` object.
public init(url: URL,
serviceRegion: AWSRegionType,
networkTransport: AWSNetworkTransport,
databaseURL: URL? = nil,
connectionStateChangeHandler: ConnectionStateChangeHandler? = nil,
s3ObjectManager: AWSS3ObjectManager? = nil,
presignedURLClient: AWSS3ObjectPresignedURLGenerator? = nil) throws {
self.url = url
self.region = serviceRegion
self.databaseURL = databaseURL
self.store = ApolloStore(cache: InMemoryNormalizedCache())
self.networkTransport = networkTransport
if let databaseURL = databaseURL {
do {
self.store = try ApolloStore(cache: AWSSQLLiteNormalizedCache(fileURL: databaseURL))
Expand Down Expand Up @@ -306,7 +342,7 @@ public class AWSAppSyncClient: NetworkConnectionNotification {

private var networkStatusWatchers: [NetworkConnectionNotification] = []
private var appSyncConfiguration: AWSAppSyncClientConfiguration
internal var httpTransport: AWSAppSyncHTTPNetworkTransport?
internal var httpTransport: AWSNetworkTransport?
private var offlineMuationCacheClient : AWSAppSyncOfflineMutationCache?
private var offlineMutationExecutor: MutationExecutor?
private var autoSubmitOfflineMutations: Bool = false
Expand All @@ -328,26 +364,10 @@ public class AWSAppSyncClient: NetworkConnectionNotification {
self.appSyncMQTTClient.allowCellularAccess = self.appSyncConfiguration.allowsCellularAccess
self.presignedURLClient = appSyncConfig.presignedURLClient
self.s3ObjectManager = appSyncConfig.s3ObjectManager

self.httpTransport = appSyncConfig.networkTransport
self.connectionStateChangeHandler = appSyncConfiguration.connectionStateChangeHandler

if let apiKeyAuthProvider = appSyncConfig.apiKeyAuthProvider {
self.httpTransport = AWSAppSyncHTTPNetworkTransport(url: self.appSyncConfiguration.url,
apiKeyAuthProvider: apiKeyAuthProvider,
configuration: self.appSyncConfiguration.urlSessionConfiguration)
} else if let userPoolsAuthProvider = appSyncConfig.userPoolsAuthProvider {
self.httpTransport = AWSAppSyncHTTPNetworkTransport(url: self.appSyncConfiguration.url,
userPoolsAuthProvider: userPoolsAuthProvider,
configuration: self.appSyncConfiguration.urlSessionConfiguration)
} else if let oidcAuthProvider = appSyncConfig.oidcAuthProvider {
self.httpTransport = AWSAppSyncHTTPNetworkTransport(url: self.appSyncConfiguration.url,
oidcAuthProvider: oidcAuthProvider,
configuration: self.appSyncConfiguration.urlSessionConfiguration)
} else {
self.httpTransport = AWSAppSyncHTTPNetworkTransport(url: self.appSyncConfiguration.url,
configuration: self.appSyncConfiguration.urlSessionConfiguration,
region: self.appSyncConfiguration.region,
credentialsProvider: self.appSyncConfiguration.credentialsProvider!)
}
self.apolloClient = ApolloClient(networkTransport: self.httpTransport!, store: self.appSyncConfiguration.store)

try self.offlineMuationCacheClient = AWSAppSyncOfflineMutationCache()
Expand Down
2 changes: 1 addition & 1 deletion AWSAppSyncClient/AWSAppSyncHTTPNetworkTransport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ enum AuthType {
case oidcToken
}

public class AWSAppSyncHTTPNetworkTransport: NetworkTransport {
public class AWSAppSyncHTTPNetworkTransport: AWSNetworkTransport {
let url: URL
let session: URLSession
var region: AWSRegionType? = nil
Expand Down
4 changes: 2 additions & 2 deletions AWSAppSyncClient/AWSAppSyncSubscriptionWatcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ class SubscriptionsOrderHelper {
public final class AWSAppSyncSubscriptionWatcher<Subscription: GraphQLSubscription>: MQTTSubscritionWatcher, Cancellable {

weak var client: AppSyncMQTTClient?
weak var httpClient: AWSAppSyncHTTPNetworkTransport?
weak var httpClient: AWSNetworkTransport?
let subscription: Subscription?
let handlerQueue: DispatchQueue
let resultHandler: SubscriptionResultHandler<Subscription>
internal var subscriptionTopic: [String]?
let store: ApolloStore
public let uniqueIdentifier = SubscriptionsOrderHelper.sharedInstance.getLatestCount()

init(client: AppSyncMQTTClient, httpClient: AWSAppSyncHTTPNetworkTransport, store: ApolloStore, subscription: Subscription, handlerQueue: DispatchQueue, resultHandler: @escaping SubscriptionResultHandler<Subscription>) {
init(client: AppSyncMQTTClient, httpClient: AWSNetworkTransport, store: ApolloStore, subscription: Subscription, handlerQueue: DispatchQueue, resultHandler: @escaping SubscriptionResultHandler<Subscription>) {
self.client = client
self.httpClient = httpClient
self.store = store
Expand Down
11 changes: 11 additions & 0 deletions AWSAppSyncClient/AWSNetworkTransport.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// AWSNetworkTransport.swift
// AWSAppSyncClient
//

import Foundation

public protocol AWSNetworkTransport: AnyObject, NetworkTransport {
func send(data: Data, completionHandler: ((JSONObject?, Error?) -> Void)?)
func sendSubscriptionRequest<Operation: GraphQLOperation>(operation: Operation, completionHandler: @escaping (JSONObject?, Error?) -> Void) throws -> Cancellable
}
4 changes: 2 additions & 2 deletions AWSAppSyncClient/AWSOfflineMutationStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class MutationExecutor: NetworkConnectionNotification {

let isExecutingDispatchGroup = DispatchGroup()
var currentMutation: AWSAppSyncMutationRecord?
var networkClient: AWSAppSyncHTTPNetworkTransport
var networkClient: AWSNetworkTransport
var appSyncClient: AWSAppSyncClient
var handlerQueue = DispatchQueue.main
var store: ApolloStore?
Expand All @@ -147,7 +147,7 @@ class MutationExecutor: NetworkConnectionNotification {
private var persistentCache: AWSMutationCache?
var snapshotProcessController: SnapshotProcessController

init(networkClient: AWSAppSyncHTTPNetworkTransport,
init(networkClient: AWSNetworkTransport,
appSyncClient: AWSAppSyncClient,
snapshotProcessController: SnapshotProcessController,
fileURL: URL? = nil) {
Expand Down