AWS SDK for C++

AWS SDK for C++ Version 1.11.440

Loading...
Searching...
No Matches
TransferHandle.h
1
6#pragma once
7
8#include <aws/transfer/Transfer_EXPORTS.h>
9#include <aws/core/utils/memory/stl/AWSString.h>
10#include <aws/core/utils/memory/stl/AWSSet.h>
11#include <aws/core/utils/memory/stl/AWSMap.h>
12#include <aws/core/utils/UUID.h>
13#include <aws/core/client/AWSError.h>
14#include <aws/core/client/AsyncCallerContext.h>
15#include <aws/s3/S3Errors.h>
16#include <iostream>
17#include <atomic>
18#include <mutex>
19#include <condition_variable>
20
21namespace Aws
22{
23 namespace Utils
24 {
25 template < typename T > class Array;
26 }
27
28 namespace Transfer
29 {
30 class TransferHandle;
31
32 typedef std::function<Aws::IOStream*(void)> CreateDownloadStreamCallback;
33
34 static const char CLASS_TAG[] = "TransferManager";
35
37 {
39 versionId("")
40 {}
41
43
44 // TBI: controls for in-memory parts vs. resumable file-based parts with state serialization to/from file
45 };
46
47 class AWS_TRANSFER_API PartState
48 {
49 public:
51 PartState(int partId, uint64_t bestProgressInBytes, uint64_t sizeInBytes, bool lastPart = false);
52
53 int GetPartId() const { return m_partId; }
54
55 uint64_t GetBestProgressInBytes() const { return m_bestProgressInBytes; }
56 void SetBestProgressInBytes(uint64_t progressInBytes) { m_bestProgressInBytes = progressInBytes; }
57
58 uint64_t GetSizeInBytes() const { return m_sizeInBytes; }
59 void SetSizeInBytes(uint64_t sizeInBytes) { m_sizeInBytes = sizeInBytes; }
60
61 void Reset();
62
63 void OnDataTransferred(uint64_t amount, const std::shared_ptr<TransferHandle> &transferHandle);
64
65 void SetETag(const Aws::String& eTag) { m_eTag = eTag; }
66 const Aws::String& GetETag() const { return m_eTag; }
67
68 Aws::IOStream *GetDownloadPartStream() const { return m_downloadPartStream; }
69 void SetDownloadPartStream(Aws::IOStream *downloadPartStream) { m_downloadPartStream = downloadPartStream; }
70
71 unsigned char* GetDownloadBuffer() const { return m_downloadBuffer; }
72 void SetDownloadBuffer(unsigned char* downloadBuffer) { m_downloadBuffer = downloadBuffer; }
73
74 void SetRangeBegin(uint64_t rangeBegin) { m_rangeBegin = rangeBegin; }
75 uint64_t GetRangeBegin() const { return m_rangeBegin; }
76
77 bool IsLastPart() { return m_lastPart; }
78 void SetLastPart() { m_lastPart = true; }
79
80 Aws::String GetChecksum() const { return m_checksum; };
81 void SetChecksum(const Aws::String& checksum) { m_checksum = checksum; }
82 private:
83
84 int m_partId = 0;
85
86 Aws::String m_eTag;
87 uint64_t m_currentProgressInBytes = 0;
88 uint64_t m_bestProgressInBytes = 0;
89 uint64_t m_sizeInBytes = 0;
90 uint64_t m_rangeBegin = 0;
91
92 std::atomic<Aws::IOStream *> m_downloadPartStream;
93 std::atomic<unsigned char*> m_downloadBuffer;
94 bool m_lastPart = false;
95 Aws::String m_checksum;
96 };
97
98 using PartPointer = std::shared_ptr< PartState >;
100
101 enum class TransferStatus
102 {
103 //this value is only used for directory synchronization
105 //Operation is still queued and has not begun processing
107 //Operation is now running
109 //Operation was canceled. A Canceled operation can still be retried
110 CANCELED,
111 //Operation failed, A failed operation can still be retried.
112 FAILED,
113 //Operation was successful
114 COMPLETED,
115 //Operation either failed or was canceled and a user deleted the multipart upload from S3.
116 ABORTED
117 };
118
120 {
121 UPLOAD,
123 };
124
132 class AWS_TRANSFER_API TransferHandle
133 {
134 public:
138 TransferHandle(const Aws::String& bucketName, const Aws::String& keyName, uint64_t totalSize, const Aws::String& targetFilePath = "");
139
143 TransferHandle(const Aws::String& bucketName, const Aws::String& keyName, const Aws::String& targetFilePath = "");
144
148 TransferHandle(const Aws::String& bucketName, const Aws::String& keyName, CreateDownloadStreamCallback createDownloadStreamFn, const Aws::String& targetFilePath = "");
149
153 TransferHandle(const Aws::String& bucketName, const Aws::String& keyName,
154 const uint64_t fileOffset, const uint64_t downloadBytes,
155 CreateDownloadStreamCallback createDownloadStreamFn, const Aws::String& targetFilePath = "");
156
157
159
163 inline bool IsMultipart() const { return m_isMultipart.load(); }
167 inline void SetIsMultipart(bool value) { m_isMultipart.store(value); }
171 inline const Aws::String GetMultiPartId() const { std::lock_guard<std::mutex> locker(m_getterSetterLock); return m_multipartId; }
175 inline void SetMultipartId(const Aws::String& value) { std::lock_guard<std::mutex> locker(m_getterSetterLock); m_multipartId = value; }
183 void ChangePartToCompleted(const PartPointer& partState, const Aws::String &eTag);
191 bool HasPendingParts() const;
195 void AddPendingPart(const PartPointer& partState);
203 bool HasQueuedParts() const;
207 void AddQueuedPart(const PartPointer& partState);
215 bool HasFailedParts() const;
219 void ChangePartToFailed(const PartPointer& partState);
223 void GetAllPartsTransactional(PartStateMap& queuedParts, PartStateMap& pendingParts,
224 PartStateMap& failedParts, PartStateMap& completedParts);
228 bool HasParts() const;
232 bool ShouldContinue() const;
237 void Cancel();
238
242 void Restart();
252 inline uint64_t GetBytesTransferred() const { return m_bytesTransferred.load(); }
256 void UpdateBytesTransferred(uint64_t amount) { m_bytesTransferred.fetch_add(amount); }
257
261 inline uint64_t GetBytesOffset() const { return m_offset; }
265 inline uint64_t GetBytesTotalSize() const { return m_bytesTotalSize.load(); }
269 inline void SetBytesTotalSize(uint64_t value) { m_bytesTotalSize.store(value); }
270
277 inline uint64_t GetBytesAvailableFromStart() const { return m_bytesAvailableFromStart.load(std::memory_order_relaxed); }
278
282 inline const Aws::String& GetBucketName() const { return m_bucket; }
286 inline const Aws::String& GetKey() const { return m_key; }
291 inline const Aws::String& GetTargetFilePath() const { return m_fileName; }
292
296 const Aws::String GetVersionId() const { std::lock_guard<std::mutex> locker(m_getterSetterLock); return m_versionId; }
297 void SetVersionId(const Aws::String& versionId) { std::lock_guard<std::mutex> locker(m_getterSetterLock); m_versionId = versionId; }
298
302 inline TransferDirection GetTransferDirection() const { return m_direction; }
306 inline const Aws::String GetContentType() const { std::lock_guard<std::mutex> locker(m_getterSetterLock); return m_contentType; }
310 inline void SetContentType(const Aws::String& value) { std::lock_guard<std::mutex> locker(m_getterSetterLock); m_contentType = value; }
315 inline const Aws::Map<Aws::String, Aws::String> GetMetadata() const { std::lock_guard<std::mutex> locker(m_getterSetterLock); return m_metadata; }
320 inline void SetMetadata(const Aws::Map<Aws::String, Aws::String>& value) { std::lock_guard<std::mutex> locker(m_getterSetterLock); m_metadata = value; }
321
325 inline void AddMetadataEntry(const Aws::String& key, const Aws::String& value) { std::lock_guard<std::mutex> locker(m_getterSetterLock); m_metadata[key] = value; }
326
330 inline void SetContext(const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context) { std::lock_guard<std::mutex> locker(m_getterSetterLock); m_context = context; }
331
335 inline std::shared_ptr<const Aws::Client::AsyncCallerContext> GetContext() const { std::lock_guard<std::mutex> locker(m_getterSetterLock); return m_context; }
336
345
350 inline const Aws::Client::AWSError<Aws::S3::S3Errors> GetLastError() const { std::lock_guard<std::mutex> locker(m_getterSetterLock); return m_lastError; }
355 inline void SetError(const Aws::Client::AWSError<Aws::S3::S3Errors>& error) { std::lock_guard<std::mutex> locker(m_getterSetterLock); m_lastError = error; }
359 void WaitUntilFinished() const;
360
361 const CreateDownloadStreamCallback& GetCreateDownloadStreamFunction() const { return m_createDownloadStreamFn; }
362
367 Aws::String WritePartToDownloadStream(Aws::IOStream* partStream, uint64_t writeOffset);
368
370
372 {
373 bool expected = false;
374 return m_lastPart.compare_exchange_strong(expected, true/*desired*/);
375 }
376
377 /*
378 * Returns a unique identifier tied to this particular transfer handle.
379 */
381
382 private:
383
384 void CleanupDownloadStream();
385
386 std::atomic<bool> m_isMultipart;
387 Aws::String m_multipartId;
388 TransferDirection m_direction;
389 PartStateMap m_completedParts;
390 PartStateMap m_pendingParts;
391 PartStateMap m_queuedParts;
392 PartStateMap m_failedParts;
393 std::atomic<uint64_t> m_bytesTransferred;
394 std::atomic<bool> m_lastPart;
395 std::atomic<uint64_t> m_bytesTotalSize;
396 std::atomic<uint64_t> m_bytesAvailableFromStart;
397 /* The next part number to watch, that is able to grow m_bytesAvailableFromStart. */
398 uint32_t m_nextPartToWatch;
399 uint64_t m_offset;
400 Aws::String m_bucket;
401 Aws::String m_key;
402 Aws::String m_fileName;
403 Aws::String m_contentType;
404 Aws::String m_versionId;
406 TransferStatus m_status;
408 std::atomic<bool> m_cancel;
409 std::shared_ptr<const Aws::Client::AsyncCallerContext> m_context;
410 const Utils::UUID m_handleId;
411
412 CreateDownloadStreamCallback m_createDownloadStreamFn;
413 Aws::IOStream* m_downloadStream;
414 /* in case customer stream is not based off 0 */
415 uint64_t m_downloadStreamBaseOffset;
416
417 mutable std::mutex m_downloadStreamLock;
418 mutable std::mutex m_partsLock;
419 mutable std::mutex m_statusLock;
420 mutable std::condition_variable m_waitUntilFinishedSignal;
421 mutable std::mutex m_getterSetterLock;
422 };
423
425 }
426}
const Aws::String & GetETag() const
void OnDataTransferred(uint64_t amount, const std::shared_ptr< TransferHandle > &transferHandle)
uint64_t GetBestProgressInBytes() const
void SetDownloadPartStream(Aws::IOStream *downloadPartStream)
unsigned char * GetDownloadBuffer() const
void SetDownloadBuffer(unsigned char *downloadBuffer)
PartState(int partId, uint64_t bestProgressInBytes, uint64_t sizeInBytes, bool lastPart=false)
void SetETag(const Aws::String &eTag)
uint64_t GetRangeBegin() const
void SetRangeBegin(uint64_t rangeBegin)
Aws::String GetChecksum() const
uint64_t GetSizeInBytes() const
void SetSizeInBytes(uint64_t sizeInBytes)
void SetBestProgressInBytes(uint64_t progressInBytes)
void SetChecksum(const Aws::String &checksum)
Aws::IOStream * GetDownloadPartStream() const
const Aws::String & GetKey() const
const Aws::String GetVersionId() const
uint64_t GetBytesAvailableFromStart() const
std::shared_ptr< const Aws::Client::AsyncCallerContext > GetContext() const
void UpdateStatus(TransferStatus value)
PartStateMap GetPendingParts() const
const Aws::String GetContentType() const
TransferStatus GetStatus() const
PartStateMap GetFailedParts() const
void AddQueuedPart(const PartPointer &partState)
PartStateMap GetCompletedParts() const
const CreateDownloadStreamCallback & GetCreateDownloadStreamFunction() const
TransferHandle(const Aws::String &bucketName, const Aws::String &keyName, const uint64_t fileOffset, const uint64_t downloadBytes, CreateDownloadStreamCallback createDownloadStreamFn, const Aws::String &targetFilePath="")
TransferHandle(const Aws::String &bucketName, const Aws::String &keyName, const Aws::String &targetFilePath="")
void UpdateBytesTransferred(uint64_t amount)
void ChangePartToCompleted(const PartPointer &partState, const Aws::String &eTag)
void SetBytesTotalSize(uint64_t value)
const Aws::String & GetTargetFilePath() const
void SetMetadata(const Aws::Map< Aws::String, Aws::String > &value)
PartStateMap GetQueuedParts() const
Aws::String GetId() const
const Aws::String GetMultiPartId() const
void SetMultipartId(const Aws::String &value)
TransferHandle(const Aws::String &bucketName, const Aws::String &keyName, uint64_t totalSize, const Aws::String &targetFilePath="")
void SetContext(const std::shared_ptr< const Aws::Client::AsyncCallerContext > &context)
void AddMetadataEntry(const Aws::String &key, const Aws::String &value)
TransferDirection GetTransferDirection() const
Aws::String WritePartToDownloadStream(Aws::IOStream *partStream, uint64_t writeOffset)
const Aws::Map< Aws::String, Aws::String > GetMetadata() const
void AddPendingPart(const PartPointer &partState)
uint64_t GetBytesTransferred() const
const Aws::Client::AWSError< Aws::S3::S3Errors > GetLastError() const
void SetError(const Aws::Client::AWSError< Aws::S3::S3Errors > &error)
TransferHandle(const Aws::String &bucketName, const Aws::String &keyName, CreateDownloadStreamCallback createDownloadStreamFn, const Aws::String &targetFilePath="")
void ApplyDownloadConfiguration(const DownloadConfiguration &downloadConfig)
void GetAllPartsTransactional(PartStateMap &queuedParts, PartStateMap &pendingParts, PartStateMap &failedParts, PartStateMap &completedParts)
const Aws::String & GetBucketName() const
void SetVersionId(const Aws::String &versionId)
void SetContentType(const Aws::String &value)
void ChangePartToFailed(const PartPointer &partState)
Aws::Map< int, PartPointer > PartStateMap
static const char CLASS_TAG[]
AWS_TRANSFER_API Aws::OStream & operator<<(Aws::OStream &s, TransferStatus status)
std::shared_ptr< PartState > PartPointer
std::function< Aws::IOStream *(void)> CreateDownloadStreamCallback
std::map< K, V, std::less< K >, Aws::Allocator< std::pair< const K, V > > > Map
std::basic_iostream< char, std::char_traits< char > > IOStream
std::array< T, N > Array
std::basic_string< char, std::char_traits< char >, Aws::Allocator< char > > String
std::basic_ostream< char, std::char_traits< char > > OStream