PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
s3_storage.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
17#pragma once
18
19#include "storage_interface.h"
20
22
23#include <cstddef>
24#include <cstdint>
25#include <functional>
26#include <memory>
27#include <mutex>
28#include <optional>
29#include <shared_mutex>
30#include <string>
31#include <unordered_map>
32
33namespace kcenon::pacs::storage {
34
43 std::string bucket_name;
44
46 std::string region{"us-east-1"};
47
49 std::string access_key_id;
50
52 std::string secret_access_key;
53
56 std::optional<std::string> endpoint_url;
57
60 std::size_t multipart_threshold = 100 * 1024 * 1024;
61
63 std::size_t part_size = 10 * 1024 * 1024;
64
66 std::size_t max_connections = 25;
67
69 std::uint32_t connect_timeout_ms = 3000;
70
72 std::uint32_t request_timeout_ms = 30000;
73
75 bool enable_encryption = false;
76
78 std::string storage_class{"STANDARD"};
79};
80
86 std::string key;
87
89 std::string sop_instance_uid;
90
92 std::string study_instance_uid;
93
96
98 std::size_t size_bytes{0};
99
101 std::string etag;
102
104 std::string content_type{"application/dicom"};
105};
106
116 std::function<bool(std::size_t bytes_transferred, std::size_t total_bytes)>;
117
164public:
165 // =========================================================================
166 // Client Interface (public for backend implementations in .cpp)
167 // =========================================================================
168
176
177 // =========================================================================
178 // Construction
179 // =========================================================================
180
185 explicit s3_storage(const cloud_storage_config &config);
186
190 ~s3_storage() override;
191
193 s3_storage(const s3_storage &) = delete;
194 s3_storage &operator=(const s3_storage &) = delete;
195
197 s3_storage(s3_storage &&) = delete;
199
200 // =========================================================================
201 // storage_interface Implementation
202 // =========================================================================
203
215 [[nodiscard]] auto store(const core::dicom_dataset &dataset)
216 -> VoidResult override;
217
226 [[nodiscard]] auto retrieve(std::string_view sop_instance_uid)
227 -> Result<core::dicom_dataset> override;
228
235 [[nodiscard]] auto remove(std::string_view sop_instance_uid)
236 -> VoidResult override;
237
246 [[nodiscard]] auto exists(std::string_view sop_instance_uid) const
247 -> bool override;
248
260 [[nodiscard]] auto find(const core::dicom_dataset &query)
262
268 [[nodiscard]] auto get_statistics() const -> storage_statistics override;
269
277 [[nodiscard]] auto verify_integrity() -> VoidResult override;
278
279 // =========================================================================
280 // S3-specific Operations
281 // =========================================================================
282
290 [[nodiscard]] auto store_with_progress(const core::dicom_dataset &dataset,
291 progress_callback callback)
292 -> VoidResult;
293
301 [[nodiscard]] auto retrieve_with_progress(std::string_view sop_instance_uid,
302 progress_callback callback)
303 -> Result<core::dicom_dataset>;
304
311 [[nodiscard]] auto get_object_key(std::string_view sop_instance_uid) const
312 -> std::string;
313
319 [[nodiscard]] auto bucket_name() const -> const std::string &;
320
330 [[nodiscard]] auto rebuild_index() -> VoidResult;
331
337 [[nodiscard]] auto is_connected() const -> bool;
338
339private:
340 // =========================================================================
341 // Internal Helper Methods
342 // =========================================================================
343
351 [[nodiscard]] auto build_object_key(std::string_view study_uid,
352 std::string_view series_uid,
353 std::string_view sop_uid) const
354 -> std::string;
355
361 [[nodiscard]] static auto sanitize_uid(std::string_view uid) -> std::string;
362
370 [[nodiscard]] auto upload_multipart(const std::string &key,
371 const std::vector<std::uint8_t> &data,
372 progress_callback callback) -> VoidResult;
373
380 [[nodiscard]] static auto matches_query(const core::dicom_dataset &dataset,
381 const core::dicom_dataset &query)
382 -> bool;
383
384 // =========================================================================
385 // Member Variables
386 // =========================================================================
387
390
392 std::unique_ptr<s3_client_interface> client_;
393
395 std::unordered_map<std::string, s3_object_info> index_;
396
398 mutable std::shared_mutex mutex_;
399};
400
401} // namespace kcenon::pacs::storage
Abstract interface for S3 client operations.
auto build_object_key(std::string_view study_uid, std::string_view series_uid, std::string_view sop_uid) const -> std::string
Build S3 object key for a dataset.
s3_storage(s3_storage &&)=delete
Non-movable (contains mutex)
s3_storage & operator=(s3_storage &&)=delete
auto rebuild_index() -> VoidResult
Rebuild the local index from S3.
auto get_object_key(std::string_view sop_instance_uid) const -> std::string
Get the S3 object key for a SOP Instance UID.
auto store(const core::dicom_dataset &dataset) -> VoidResult override
Store a DICOM dataset to S3.
static auto sanitize_uid(std::string_view uid) -> std::string
Sanitize UID for use in S3 object key.
cloud_storage_config config_
Storage configuration.
Definition s3_storage.h:389
auto retrieve(std::string_view sop_instance_uid) -> Result< core::dicom_dataset > override
Retrieve a DICOM dataset by SOP Instance UID.
s3_storage & operator=(const s3_storage &)=delete
auto remove(std::string_view sop_instance_uid) -> VoidResult override
Remove a DICOM object from S3.
auto get_statistics() const -> storage_statistics override
Get storage statistics.
std::unique_ptr< s3_client_interface > client_
S3 client (mock for testing, AWS SDK for production)
Definition s3_storage.h:392
auto verify_integrity() -> VoidResult override
Verify storage integrity.
std::shared_mutex mutex_
Mutex for thread-safe access.
Definition s3_storage.h:398
s3_storage(const cloud_storage_config &config)
Construct S3 storage with configuration.
auto is_connected() const -> bool
Check S3 connectivity.
auto exists(std::string_view sop_instance_uid) const -> bool override
Check if a DICOM instance exists in S3.
auto retrieve_with_progress(std::string_view sop_instance_uid, progress_callback callback) -> Result< core::dicom_dataset >
Retrieve with progress tracking.
auto store_with_progress(const core::dicom_dataset &dataset, progress_callback callback) -> VoidResult
Store with progress tracking.
auto find(const core::dicom_dataset &query) -> Result< std::vector< core::dicom_dataset > > override
Find DICOM datasets matching query criteria.
auto upload_multipart(const std::string &key, const std::vector< std::uint8_t > &data, progress_callback callback) -> VoidResult
Execute multipart upload for large files.
std::unordered_map< std::string, s3_object_info > index_
Mapping from SOP Instance UID to S3 object info.
Definition s3_storage.h:395
s3_storage(const s3_storage &)=delete
Non-copyable (contains mutex)
~s3_storage() override
Destructor.
static auto matches_query(const core::dicom_dataset &dataset, const core::dicom_dataset &query) -> bool
Check if dataset matches query criteria.
auto bucket_name() const -> const std::string &
Get the bucket name.
DICOM Dataset - ordered collection of Data Elements.
std::function< bool(std::size_t bytes_transferred, std::size_t total_bytes)> progress_callback
Callback type for upload/download progress tracking.
Definition s3_storage.h:115
Abstract storage interface for DICOM persistent storage backends.
Configuration for S3-compatible cloud storage.
Definition s3_storage.h:41
std::string region
AWS region (e.g., "us-east-1", "eu-west-1")
Definition s3_storage.h:46
std::string storage_class
Storage class for S3 objects (STANDARD, INTELLIGENT_TIERING, etc.)
Definition s3_storage.h:78
std::string secret_access_key
AWS secret access key for authentication.
Definition s3_storage.h:52
std::optional< std::string > endpoint_url
Optional custom endpoint URL for MinIO or S3-compatible services If empty, uses the default AWS S3 en...
Definition s3_storage.h:56
std::string access_key_id
AWS access key ID for authentication.
Definition s3_storage.h:49
std::string bucket_name
S3 bucket name for storing DICOM files.
Definition s3_storage.h:43
std::size_t max_connections
Maximum number of concurrent upload connections.
Definition s3_storage.h:66
bool enable_encryption
Enable server-side encryption (SSE-S3)
Definition s3_storage.h:75
std::size_t part_size
Part size for multipart upload in bytes (default: 10MB)
Definition s3_storage.h:63
std::uint32_t request_timeout_ms
Request timeout in milliseconds.
Definition s3_storage.h:72
std::uint32_t connect_timeout_ms
Connection timeout in milliseconds.
Definition s3_storage.h:69
std::size_t multipart_threshold
Threshold for multipart upload in bytes (default: 100MB) Files larger than this will use multipart up...
Definition s3_storage.h:60
Information about an S3 object.
Definition s3_storage.h:84
std::string key
S3 object key (path within bucket)
Definition s3_storage.h:86
std::string study_instance_uid
Study Instance UID.
Definition s3_storage.h:92
std::string etag
ETag for integrity verification.
Definition s3_storage.h:101
std::string content_type
Content type.
Definition s3_storage.h:104
std::string sop_instance_uid
SOP Instance UID from DICOM metadata.
Definition s3_storage.h:89
std::size_t size_bytes
Object size in bytes.
Definition s3_storage.h:98
std::string series_instance_uid
Series Instance UID.
Definition s3_storage.h:95
std::string_view uid