PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
azure_blob_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 container_name;
44
47 std::string connection_string;
48
51 std::optional<std::string> endpoint_suffix;
52
55 std::optional<std::string> endpoint_url;
56
59 std::size_t block_upload_threshold = 100 * 1024 * 1024;
60
63 std::size_t block_size = 4 * 1024 * 1024;
64
66 std::size_t max_concurrency = 8;
67
69 std::uint32_t connect_timeout_ms = 3000;
70
72 std::uint32_t request_timeout_ms = 60000;
73
75 bool use_https = true;
76
78 std::string access_tier{"Hot"};
79
81 std::uint32_t max_retries = 3;
82
84 std::uint32_t retry_delay_ms = 1000;
85};
86
92 std::string blob_name;
93
95 std::string sop_instance_uid;
96
98 std::string study_instance_uid;
99
102
104 std::size_t size_bytes{0};
105
107 std::string etag;
108
110 std::string content_type{"application/dicom"};
111
113 std::string content_md5;
114};
115
125 std::function<bool(std::size_t bytes_transferred, std::size_t total_bytes)>;
126
171public:
172 // =========================================================================
173 // Client Interface (public for backend implementations in .cpp)
174 // =========================================================================
175
183
184 // =========================================================================
185 // Construction
186 // =========================================================================
187
192 explicit azure_blob_storage(const azure_storage_config &config);
193
198
202
206
207 // =========================================================================
208 // storage_interface Implementation
209 // =========================================================================
210
222 [[nodiscard]] auto store(const core::dicom_dataset &dataset)
223 -> VoidResult override;
224
233 [[nodiscard]] auto retrieve(std::string_view sop_instance_uid)
234 -> Result<core::dicom_dataset> override;
235
242 [[nodiscard]] auto remove(std::string_view sop_instance_uid)
243 -> VoidResult override;
244
253 [[nodiscard]] auto exists(std::string_view sop_instance_uid) const
254 -> bool override;
255
267 [[nodiscard]] auto find(const core::dicom_dataset &query)
269
275 [[nodiscard]] auto get_statistics() const -> storage_statistics override;
276
284 [[nodiscard]] auto verify_integrity() -> VoidResult override;
285
286 // =========================================================================
287 // Azure-specific Operations
288 // =========================================================================
289
297 [[nodiscard]] auto store_with_progress(const core::dicom_dataset &dataset,
299 -> VoidResult;
300
308 [[nodiscard]] auto retrieve_with_progress(std::string_view sop_instance_uid,
310 -> Result<core::dicom_dataset>;
311
318 [[nodiscard]] auto get_blob_name(std::string_view sop_instance_uid) const
319 -> std::string;
320
326 [[nodiscard]] auto container_name() const -> const std::string &;
327
337 [[nodiscard]] auto rebuild_index() -> VoidResult;
338
344 [[nodiscard]] auto is_connected() const -> bool;
345
353 [[nodiscard]] auto set_access_tier(std::string_view sop_instance_uid,
354 std::string_view tier) -> VoidResult;
355
356private:
357 // =========================================================================
358 // Internal Helper Methods
359 // =========================================================================
360
368 [[nodiscard]] auto build_blob_name(std::string_view study_uid,
369 std::string_view series_uid,
370 std::string_view sop_uid) const
371 -> std::string;
372
378 [[nodiscard]] static auto sanitize_uid(std::string_view uid) -> std::string;
379
387 [[nodiscard]] auto upload_block_blob(const std::string &blob_name,
388 const std::vector<std::uint8_t> &data,
390 -> VoidResult;
391
398 [[nodiscard]] static auto matches_query(const core::dicom_dataset &dataset,
399 const core::dicom_dataset &query)
400 -> bool;
401
402 // =========================================================================
403 // Member Variables
404 // =========================================================================
405
408
411
413 std::unordered_map<std::string, azure_blob_info> index_;
414
416 mutable std::shared_mutex mutex_;
417};
418
419} // namespace kcenon::pacs::storage
Abstract interface for Azure Blob client operations.
azure_storage_config config_
Storage configuration.
auto exists(std::string_view sop_instance_uid) const -> bool override
Check if a DICOM instance exists in Azure Storage.
azure_blob_storage(azure_blob_storage &&)=delete
Non-movable (contains mutex)
auto is_connected() const -> bool
Check Azure connectivity.
auto find(const core::dicom_dataset &query) -> Result< std::vector< core::dicom_dataset > > override
Find DICOM datasets matching query criteria.
auto build_blob_name(std::string_view study_uid, std::string_view series_uid, std::string_view sop_uid) const -> std::string
Build blob name for a dataset.
std::unordered_map< std::string, azure_blob_info > index_
Mapping from SOP Instance UID to Azure blob info.
static auto sanitize_uid(std::string_view uid) -> std::string
Sanitize UID for use in blob name.
auto remove(std::string_view sop_instance_uid) -> VoidResult override
Remove a DICOM blob from Azure Storage.
auto rebuild_index() -> VoidResult
Rebuild the local index from Azure.
std::unique_ptr< azure_client_interface > client_
Azure client (mock for testing, Azure SDK for production)
auto store_with_progress(const core::dicom_dataset &dataset, azure_progress_callback callback) -> VoidResult
Store with progress tracking.
auto retrieve_with_progress(std::string_view sop_instance_uid, azure_progress_callback callback) -> Result< core::dicom_dataset >
Retrieve with progress tracking.
auto upload_block_blob(const std::string &blob_name, const std::vector< std::uint8_t > &data, azure_progress_callback callback) -> VoidResult
Execute block blob upload for large files.
azure_blob_storage & operator=(azure_blob_storage &&)=delete
azure_blob_storage(const azure_blob_storage &)=delete
Non-copyable (contains mutex)
std::shared_mutex mutex_
Mutex for thread-safe access.
auto verify_integrity() -> VoidResult override
Verify storage integrity.
auto store(const core::dicom_dataset &dataset) -> VoidResult override
Store a DICOM dataset to Azure Blob Storage.
auto set_access_tier(std::string_view sop_instance_uid, std::string_view tier) -> VoidResult
Set blob access tier.
auto get_blob_name(std::string_view sop_instance_uid) const -> std::string
Get the blob name for a SOP Instance UID.
auto retrieve(std::string_view sop_instance_uid) -> Result< core::dicom_dataset > override
Retrieve a DICOM dataset by SOP Instance UID.
auto container_name() const -> const std::string &
Get the container name.
static auto matches_query(const core::dicom_dataset &dataset, const core::dicom_dataset &query) -> bool
Check if dataset matches query criteria.
auto get_statistics() const -> storage_statistics override
Get storage statistics.
azure_blob_storage & operator=(const azure_blob_storage &)=delete
azure_blob_storage(const azure_storage_config &config)
Construct Azure Blob storage with configuration.
DICOM Dataset - ordered collection of Data Elements.
std::function< bool(std::size_t bytes_transferred, std::size_t total_bytes)> azure_progress_callback
Callback type for upload/download progress tracking.
Abstract storage interface for DICOM persistent storage backends.
Information about an Azure Blob object.
std::string sop_instance_uid
SOP Instance UID from DICOM metadata.
std::size_t size_bytes
Blob size in bytes.
std::string study_instance_uid
Study Instance UID.
std::string blob_name
Blob name (path within container)
std::string series_instance_uid
Series Instance UID.
std::string etag
ETag for integrity verification.
std::string content_md5
Content MD5 hash.
Configuration for Azure Blob storage.
std::optional< std::string > endpoint_suffix
Optional endpoint suffix for sovereign clouds (e.g., "core.chinacloudapi.cn") If empty,...
std::size_t block_upload_threshold
Threshold for block blob upload in bytes (default: 100MB) Files larger than this will use block blob ...
std::size_t block_size
Block size for block blob upload in bytes (default: 4MB) Azure allows up to 4000MB per block (API ver...
bool use_https
Enable HTTPS (default: true)
std::string container_name
Azure Blob container name for storing DICOM files.
std::size_t max_concurrency
Maximum number of concurrent upload threads.
std::string access_tier
Blob tier (Hot, Cool, Archive)
std::optional< std::string > endpoint_url
Optional custom endpoint URL for Azurite emulator If set, this takes precedence over connection_strin...
std::uint32_t connect_timeout_ms
Connection timeout in milliseconds.
std::uint32_t request_timeout_ms
Request timeout in milliseconds.
std::uint32_t max_retries
Retry count for transient failures.
std::string connection_string
Connection string for Azure Storage account Format: DefaultEndpointsProtocol=https;AccountName=....
std::uint32_t retry_delay_ms
Initial retry delay in milliseconds.
std::string_view uid