Skip to content

Commit 35d4bdc

Browse files
authored
feat(Storage): Add async resolvePrefix (#1539)
* feat(Storage): Add async resolvePrefix * Add default conformance for sync resolvePrefix
1 parent 535c8ef commit 35d4bdc

14 files changed

+227
-128
lines changed

AmplifyPlugins/Storage/AWSS3StoragePlugin/Configuration/AWSS3PluginPrefixResolver.swift

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,40 @@ import AWSPluginsCore
1111

1212
/// Resolves the final prefix prepended to the S3 key for a given request.
1313
public protocol AWSS3PluginPrefixResolver {
14+
@available(*, deprecated, message: "Implement resolvePrefix with `completion` instead.")
1415
func resolvePrefix(for accessLevel: StorageAccessLevel, targetIdentityId: String?) -> Result<String, StorageError>
16+
17+
func resolvePrefix(for accessLevel: StorageAccessLevel,
18+
targetIdentityId: String?,
19+
completion: @escaping (Result<String, StorageError>) -> Void)
20+
}
21+
22+
/// Provide default conformance to `AWSS3PluginPrefixResolver`
23+
extension AWSS3PluginPrefixResolver {
24+
25+
/// The default conformance to this method will fail with falal error to indicate that developers, if providing
26+
/// their own prefix resolver, should conform to the asynchronous version of `resolvePrefix` with completion
27+
/// closure. The synchronous version existed originally without the async vserion and now has the below default
28+
/// implementation to allow new conforming classes without the requirement to conform to the synchronous version,
29+
/// and can conform to just the asynchronous method.
30+
public func resolvePrefix(for accessLevel: StorageAccessLevel,
31+
targetIdentityId: String?) -> Result<String, StorageError> {
32+
fatalError("Protocol conformance should implement `resolvePrefix(for:targetIdentityId:completion)`.")
33+
}
34+
35+
/// The default conformance of the asynchronous method calls the synchronous `resolvePrefix` for backwards
36+
/// compatibility for developers that originally implemented the synchronous version (which now has the deprecated
37+
/// flag).
38+
public func resolvePrefix(for accessLevel: StorageAccessLevel,
39+
targetIdentityId: String?,
40+
completion: @escaping (Result<String, StorageError>) -> Void) {
41+
completion(resolvePrefix(for: accessLevel, targetIdentityId: targetIdentityId))
42+
}
1543
}
1644

1745
/// Convenience resolver. Resolves the provided key as-is, with no manipulation
1846
public struct PassThroughPrefixResolver: AWSS3PluginPrefixResolver {
47+
1948
public func resolvePrefix(for accessLevel: StorageAccessLevel,
2049
targetIdentityId: String?) -> Result<String, StorageError> {
2150
return .success("")
@@ -30,17 +59,18 @@ struct StorageAccessLevelAwarePrefixResolver: AWSS3PluginPrefixResolver {
3059
self.authService = authService
3160
}
3261

33-
public func resolvePrefix(for accessLevel: StorageAccessLevel,
34-
targetIdentityId: String?) -> Result<String, StorageError> {
62+
func resolvePrefix(for accessLevel: StorageAccessLevel,
63+
targetIdentityId: String?,
64+
completion: @escaping (Result<String, StorageError>) -> Void) {
3565
let identityIdResult = authService.getIdentityId()
3666
switch identityIdResult {
3767
case .success(let identityId):
3868
let prefix = StorageRequestUtils.getAccessLevelPrefix(accessLevel: accessLevel,
3969
identityId: identityId,
4070
targetIdentityId: targetIdentityId)
41-
return .success(prefix)
71+
completion(.success(prefix))
4272
case .failure(let error):
43-
return .failure(StorageError.authError(error.errorDescription, error.recoverySuggestion))
73+
completion(.failure(StorageError.authError(error.errorDescription, error.recoverySuggestion)))
4474
}
4575
}
4676
}

AmplifyPlugins/Storage/AWSS3StoragePlugin/Operation/AWSS3StorageDownloadDataOperation.swift

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,19 @@ public class AWSS3StorageDownloadDataOperation: AmplifyInProcessReportingOperati
8686
}
8787

8888
let prefixResolver = storageConfiguration.prefixResolver ??
89-
StorageAccessLevelAwarePrefixResolver(authService: authService)
90-
let prefixResolution = prefixResolver.resolvePrefix(for: request.options.accessLevel,
91-
targetIdentityId: request.options.targetIdentityId)
92-
switch prefixResolution {
93-
case .success(let prefix):
94-
let serviceKey = prefix + request.key
95-
storageService.download(serviceKey: serviceKey, fileURL: nil) { [weak self] event in
96-
self?.onServiceEvent(event: event)
89+
StorageAccessLevelAwarePrefixResolver(authService: authService)
90+
prefixResolver.resolvePrefix(for: request.options.accessLevel,
91+
targetIdentityId: request.options.targetIdentityId) { prefixResolution in
92+
switch prefixResolution {
93+
case .success(let prefix):
94+
let serviceKey = prefix + self.request.key
95+
self.storageService.download(serviceKey: serviceKey, fileURL: nil) { [weak self] event in
96+
self?.onServiceEvent(event: event)
97+
}
98+
case .failure(let error):
99+
self.dispatch(error)
100+
self.finish()
97101
}
98-
case .failure(let error):
99-
dispatch(error)
100-
finish()
101102
}
102103
}
103104

AmplifyPlugins/Storage/AWSS3StoragePlugin/Operation/AWSS3StorageDownloadFileOperation.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,18 @@ public class AWSS3StorageDownloadFileOperation: AmplifyInProcessReportingOperati
9090

9191
let prefixResolver = storageConfiguration.prefixResolver ??
9292
StorageAccessLevelAwarePrefixResolver(authService: authService)
93-
let prefixResolution = prefixResolver.resolvePrefix(for: request.options.accessLevel,
94-
targetIdentityId: request.options.targetIdentityId)
95-
switch prefixResolution {
96-
case .success(let prefix):
97-
let serviceKey = prefix + request.key
98-
storageService.download(serviceKey: serviceKey, fileURL: request.local) { [weak self] event in
99-
self?.onServiceEvent(event: event)
93+
prefixResolver.resolvePrefix(for: request.options.accessLevel,
94+
targetIdentityId: request.options.targetIdentityId) { prefixResolution in
95+
switch prefixResolution {
96+
case .success(let prefix):
97+
let serviceKey = prefix + self.request.key
98+
self.storageService.download(serviceKey: serviceKey, fileURL: self.request.local) { [weak self] event in
99+
self?.onServiceEvent(event: event)
100+
}
101+
case .failure(let error):
102+
self.dispatch(error)
103+
self.finish()
100104
}
101-
case .failure(let error):
102-
dispatch(error)
103-
finish()
104105
}
105106
}
106107

AmplifyPlugins/Storage/AWSS3StoragePlugin/Operation/AWSS3StorageGetURLOperation.swift

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,21 @@ public class AWSS3StorageGetURLOperation: AmplifyOperation<
6060

6161
let prefixResolver = storageConfiguration.prefixResolver ??
6262
StorageAccessLevelAwarePrefixResolver(authService: authService)
63-
let prefixResolution = prefixResolver.resolvePrefix(for: request.options.accessLevel,
64-
targetIdentityId: request.options.targetIdentityId)
65-
switch prefixResolution {
66-
case .success(let prefix):
67-
let serviceKey = prefix + request.key
68-
storageService.getPreSignedURL(serviceKey: serviceKey,
69-
expires: request.options.expires) { [weak self] event in
70-
self?.onServiceEvent(event: event)
63+
prefixResolver.resolvePrefix(for: request.options.accessLevel,
64+
targetIdentityId: request.options.targetIdentityId) { prefixResolution in
65+
switch prefixResolution {
66+
case .success(let prefix):
67+
let serviceKey = prefix + self.request.key
68+
self.storageService.getPreSignedURL(serviceKey: serviceKey,
69+
expires: self.request.options.expires) { [weak self] event in
70+
self?.onServiceEvent(event: event)
71+
}
72+
case .failure(let error):
73+
self.dispatch(error)
74+
self.finish()
7175
}
72-
case .failure(let error):
73-
dispatch(error)
74-
finish()
7576
}
77+
7678
}
7779

7880
private func onServiceEvent(event: StorageEvent<Void, Void, URL, StorageError>) {

AmplifyPlugins/Storage/AWSS3StoragePlugin/Operation/AWSS3StorageListOperation.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,17 @@ public class AWSS3StorageListOperation: AmplifyOperation<
6060

6161
let prefixResolver = storageConfiguration.prefixResolver ??
6262
StorageAccessLevelAwarePrefixResolver(authService: authService)
63-
let prefixResolution = prefixResolver.resolvePrefix(for: request.options.accessLevel,
64-
targetIdentityId: request.options.targetIdentityId)
65-
switch prefixResolution {
66-
case .success(let prefix):
67-
storageService.list(prefix: prefix, path: request.options.path) { [weak self] event in
68-
self?.onServiceEvent(event: event)
63+
prefixResolver.resolvePrefix(for: request.options.accessLevel,
64+
targetIdentityId: request.options.targetIdentityId) { prefixResolution in
65+
switch prefixResolution {
66+
case .success(let prefix):
67+
self.storageService.list(prefix: prefix, path: self.request.options.path) { [weak self] event in
68+
self?.onServiceEvent(event: event)
69+
}
70+
case .failure(let error):
71+
self.dispatch(error)
72+
self.finish()
6973
}
70-
case .failure(let error):
71-
dispatch(error)
72-
finish()
7374
}
7475
}
7576

AmplifyPlugins/Storage/AWSS3StoragePlugin/Operation/AWSS3StorageRemoveOperation.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,18 @@ public class AWSS3StorageRemoveOperation: AmplifyOperation<
6060

6161
let prefixResolver = storageConfiguration.prefixResolver ??
6262
StorageAccessLevelAwarePrefixResolver(authService: authService)
63-
let prefixResolution = prefixResolver.resolvePrefix(for: request.options.accessLevel,
64-
targetIdentityId: nil)
65-
switch prefixResolution {
66-
case .success(let prefix):
67-
let serviceKey = prefix + request.key
68-
storageService.delete(serviceKey: serviceKey) { [weak self] event in
69-
self?.onServiceEvent(event: event)
63+
prefixResolver.resolvePrefix(for: request.options.accessLevel,
64+
targetIdentityId: nil) { prefixResolution in
65+
switch prefixResolution {
66+
case .success(let prefix):
67+
let serviceKey = prefix + self.request.key
68+
self.storageService.delete(serviceKey: serviceKey) { [weak self] event in
69+
self?.onServiceEvent(event: event)
70+
}
71+
case .failure(let error):
72+
self.dispatch(error)
73+
self.finish()
7074
}
71-
case .failure(let error):
72-
dispatch(error)
73-
finish()
7475
}
7576
}
7677

AmplifyPlugins/Storage/AWSS3StoragePlugin/Operation/AWSS3StorageUploadDataOperation.swift

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -86,31 +86,32 @@ public class AWSS3StorageUploadDataOperation: AmplifyInProcessReportingOperation
8686
}
8787

8888
let prefixResolver = storageConfiguration.prefixResolver ??
89-
StorageAccessLevelAwarePrefixResolver(authService: authService)
90-
let prefixResolution = prefixResolver.resolvePrefix(for: request.options.accessLevel,
91-
targetIdentityId: request.options.targetIdentityId)
92-
switch prefixResolution {
93-
case .success(let prefix):
94-
let serviceKey = prefix + request.key
95-
let serviceMetadata = StorageRequestUtils.getServiceMetadata(request.options.metadata)
96-
if request.data.count > StorageUploadDataRequest.Options.multiPartUploadSizeThreshold {
97-
storageService.multiPartUpload(serviceKey: serviceKey,
98-
uploadSource: .data(request.data),
99-
contentType: request.options.contentType,
89+
StorageAccessLevelAwarePrefixResolver(authService: authService)
90+
prefixResolver.resolvePrefix(for: request.options.accessLevel,
91+
targetIdentityId: request.options.targetIdentityId) { prefixResolution in
92+
switch prefixResolution {
93+
case .success(let prefix):
94+
let serviceKey = prefix + self.request.key
95+
let serviceMetadata = StorageRequestUtils.getServiceMetadata(self.request.options.metadata)
96+
if self.request.data.count > StorageUploadDataRequest.Options.multiPartUploadSizeThreshold {
97+
self.storageService.multiPartUpload(serviceKey: serviceKey,
98+
uploadSource: .data(self.request.data),
99+
contentType: self.request.options.contentType,
100+
metadata: serviceMetadata) { [weak self] event in
101+
self?.onServiceEvent(event: event)
102+
}
103+
} else {
104+
self.storageService.upload(serviceKey: serviceKey,
105+
uploadSource: .data(self.request.data),
106+
contentType: self.request.options.contentType,
100107
metadata: serviceMetadata) { [weak self] event in
101-
self?.onServiceEvent(event: event)
102-
}
103-
} else {
104-
storageService.upload(serviceKey: serviceKey,
105-
uploadSource: .data(request.data),
106-
contentType: request.options.contentType,
107-
metadata: serviceMetadata) { [weak self] event in
108-
self?.onServiceEvent(event: event)
109-
}
108+
self?.onServiceEvent(event: event)
109+
}
110+
}
111+
case .failure(let error):
112+
self.dispatch(error)
113+
self.finish()
110114
}
111-
case .failure(let error):
112-
dispatch(error)
113-
finish()
114115
}
115116
}
116117

AmplifyPlugins/Storage/AWSS3StoragePlugin/Operation/AWSS3StorageUploadFileOperation.swift

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -99,31 +99,32 @@ public class AWSS3StorageUploadFileOperation: AmplifyInProcessReportingOperation
9999
}
100100

101101
let prefixResolver = storageConfiguration.prefixResolver ??
102-
StorageAccessLevelAwarePrefixResolver(authService: authService)
103-
let prefixResolution = prefixResolver.resolvePrefix(for: request.options.accessLevel,
104-
targetIdentityId: request.options.targetIdentityId)
105-
switch prefixResolution {
106-
case .success(let prefix):
107-
let serviceKey = prefix + request.key
108-
let serviceMetadata = StorageRequestUtils.getServiceMetadata(request.options.metadata)
109-
if uploadSize > StorageUploadFileRequest.Options.multiPartUploadSizeThreshold {
110-
storageService.multiPartUpload(serviceKey: serviceKey,
111-
uploadSource: .local(request.local),
112-
contentType: request.options.contentType,
102+
StorageAccessLevelAwarePrefixResolver(authService: authService)
103+
prefixResolver.resolvePrefix(for: request.options.accessLevel,
104+
targetIdentityId: request.options.targetIdentityId) { prefixResolution in
105+
switch prefixResolution {
106+
case .success(let prefix):
107+
let serviceKey = prefix + self.request.key
108+
let serviceMetadata = StorageRequestUtils.getServiceMetadata(self.request.options.metadata)
109+
if uploadSize > StorageUploadFileRequest.Options.multiPartUploadSizeThreshold {
110+
self.storageService.multiPartUpload(serviceKey: serviceKey,
111+
uploadSource: .local(self.request.local),
112+
contentType: self.request.options.contentType,
113+
metadata: serviceMetadata) { [weak self] event in
114+
self?.onServiceEvent(event: event)
115+
}
116+
} else {
117+
self.storageService.upload(serviceKey: serviceKey,
118+
uploadSource: .local(self.request.local),
119+
contentType: self.request.options.contentType,
113120
metadata: serviceMetadata) { [weak self] event in
114-
self?.onServiceEvent(event: event)
115-
}
116-
} else {
117-
storageService.upload(serviceKey: serviceKey,
118-
uploadSource: .local(request.local),
119-
contentType: request.options.contentType,
120-
metadata: serviceMetadata) { [weak self] event in
121-
self?.onServiceEvent(event: event)
122-
}
121+
self?.onServiceEvent(event: event)
122+
}
123+
}
124+
case .failure(let error):
125+
self.dispatch(error)
126+
self.finish()
123127
}
124-
case .failure(let error):
125-
dispatch(error)
126-
finish()
127128
}
128129
}
129130

0 commit comments

Comments
 (0)