PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::monitoring::health_checker Class Reference

Performs comprehensive health checks on PACS system components. More...

#include <health_checker.h>

Collaboration diagram for kcenon::pacs::monitoring::health_checker:
Collaboration graph

Public Types

using check_callback = std::function<bool(std::string& error_message)>
 Custom health check callback type.
 

Public Member Functions

 health_checker ()
 Construct health checker with default configuration.
 
 health_checker (const health_checker_config &config)
 Construct health checker with custom configuration.
 
 ~health_checker ()
 Destructor - stops background checking if enabled.
 
 health_checker (const health_checker &)=delete
 Non-copyable.
 
health_checker & operator= (const health_checker &)=delete
 
 health_checker (health_checker &&other) noexcept
 Movable.
 
health_checker & operator= (health_checker &&other) noexcept
 
void set_database (kcenon::pacs::storage::index_database *database)
 Set the database instance to monitor.
 
void set_storage (kcenon::pacs::storage::file_storage *storage)
 Set the storage instance to monitor.
 
void register_check (std::string_view name, check_callback callback)
 Register a custom health check.
 
void unregister_check (std::string_view name)
 Unregister a custom health check.
 
health_status check ()
 Perform a full health check.
 
bool is_alive () const noexcept
 Perform a quick liveness check.
 
bool is_ready ()
 Perform a readiness check.
 
health_status get_cached_status () const
 Get cached health status.
 
health_status get_status ()
 Get cached status or perform check if stale.
 
void update_association_metrics (std::uint32_t active, std::uint32_t max, std::uint64_t total_established, std::uint64_t total_failed)
 Update association metrics.
 
void update_storage_metrics (std::uint64_t instances, std::uint64_t studies, std::uint64_t series, std::uint64_t successful_stores, std::uint64_t failed_stores)
 Update storage metrics.
 
void set_version (std::uint16_t major, std::uint16_t minor, std::uint16_t patch, std::string_view build_id="")
 Set version information.
 
const health_checker_config & config () const noexcept
 Get current configuration.
 
void set_config (const health_checker_config &config)
 Update configuration.
 

Private Member Functions

void check_database (health_status &status)
 Check database connectivity.
 
void check_storage (health_status &status)
 Check storage availability.
 
void run_custom_checks (health_status &status)
 Run all custom checks.
 

Private Attributes

health_checker_config config_
 Configuration.
 
kcenon::pacs::storage::index_database * database_ {nullptr}
 Database instance to monitor.
 
kcenon::pacs::storage::file_storage * storage_ {nullptr}
 Storage instance to monitor.
 
std::unordered_map< std::string, check_callback > custom_checks_
 Custom health checks.
 
health_status cached_status_
 Cached health status.
 
std::chrono::system_clock::time_point last_check_time_
 Timestamp of last check.
 
association_metrics associations_
 Association metrics (updated externally)
 
storage_metrics storage_metrics_
 Storage metrics (updated externally)
 
version_info version_
 Version information.
 
std::shared_mutex mutex_
 Mutex for thread safety.
 

Detailed Description

Performs comprehensive health checks on PACS system components.

The health_checker class provides a unified interface for monitoring the health of all PACS system components including:

  • Database connectivity and response time
  • Storage read/write capability and capacity
  • Active DICOM associations
  • System resource utilization

The checker supports both on-demand checks and cached results for high- frequency health check requests (e.g., from Kubernetes liveness probes).

Thread Safety: All public methods are thread-safe.

Example:
// Create and configure the health checker
config.check_interval = std::chrono::seconds{30};
// Register components to monitor
checker.set_database(&database);
checker.set_storage(&storage);
// Perform health check
auto status = checker.check();
if (status.is_healthy()) {
// System is healthy
}
// Get cached result for frequent calls
auto cached = checker.get_cached_status();
Performs comprehensive health checks on PACS system components.
void set_database(kcenon::pacs::storage::index_database *database)
Set the database instance to monitor.
const health_checker_config & config() const noexcept
Get current configuration.
Configuration options for the health checker.
std::chrono::seconds check_interval
Interval between automatic health checks.
double storage_warning_threshold
Storage usage threshold for degraded status (percentage)

Definition at line 106 of file health_checker.h.

Member Typedef Documentation

◆ check_callback

using kcenon::pacs::monitoring::health_checker::check_callback = std::function<bool(std::string& error_message)>

Custom health check callback type.

Definition at line 113 of file health_checker.h.

Constructor & Destructor Documentation

◆ health_checker() [1/4]

kcenon::pacs::monitoring::health_checker::health_checker ( )

Construct health checker with default configuration.

Definition at line 25 of file health_checker.cpp.

25: health_checker(health_checker_config{}) {}
health_checker()
Construct health checker with default configuration.

◆ health_checker() [2/4]

kcenon::pacs::monitoring::health_checker::health_checker ( const health_checker_config & config)
explicit

Construct health checker with custom configuration.

Parameters
configConfiguration options

Definition at line 27 of file health_checker.cpp.

28 : config_(config) {
29 // Initialize version with defaults
30 version_.startup_time = std::chrono::system_clock::now();
31
32 // Initialize cached status
34 cached_status_.message = "Health check not yet performed";
35}
version_info version_
Version information.
health_checker_config config_
Configuration.
health_status cached_status_
Cached health status.
@ unhealthy
Critical components failing, system may not function correctly.
health_level level
Overall health level.
std::optional< std::string > message
Optional human-readable status message.
std::chrono::system_clock::time_point startup_time
Server startup timestamp.

References cached_status_, kcenon::pacs::monitoring::health_status::level, kcenon::pacs::monitoring::health_status::message, kcenon::pacs::monitoring::version_info::startup_time, kcenon::pacs::monitoring::unhealthy, and version_.

◆ ~health_checker()

kcenon::pacs::monitoring::health_checker::~health_checker ( )
default

Destructor - stops background checking if enabled.

◆ health_checker() [3/4]

kcenon::pacs::monitoring::health_checker::health_checker ( const health_checker & )
delete

Non-copyable.

◆ health_checker() [4/4]

kcenon::pacs::monitoring::health_checker::health_checker ( health_checker && other)
noexcept

Movable.

Definition at line 39 of file health_checker.cpp.

39 {
40 std::unique_lock lock(other.mutex_);
41 config_ = std::move(other.config_);
42 database_ = other.database_;
43 storage_ = other.storage_;
44 custom_checks_ = std::move(other.custom_checks_);
45 cached_status_ = std::move(other.cached_status_);
46 last_check_time_ = other.last_check_time_;
47 associations_ = other.associations_;
48 storage_metrics_ = other.storage_metrics_;
49 version_ = std::move(other.version_);
50 other.database_ = nullptr;
51 other.storage_ = nullptr;
52}
kcenon::pacs::storage::file_storage * storage_
Storage instance to monitor.
association_metrics associations_
Association metrics (updated externally)
kcenon::pacs::storage::index_database * database_
Database instance to monitor.
storage_metrics storage_metrics_
Storage metrics (updated externally)
std::chrono::system_clock::time_point last_check_time_
Timestamp of last check.
std::unordered_map< std::string, check_callback > custom_checks_
Custom health checks.

Member Function Documentation

◆ check()

health_status kcenon::pacs::monitoring::health_checker::check ( )
nodiscard

Perform a full health check.

Runs all registered health checks and aggregates results. This method may take time depending on configured timeouts.

Returns
Comprehensive health status

Definition at line 104 of file health_checker.cpp.

104 {
105 health_status status;
106 status.timestamp = std::chrono::system_clock::now();
107
108 {
109 std::shared_lock lock(mutex_);
110 // Copy current metrics
111 status.associations = associations_;
112 status.metrics = storage_metrics_;
113 status.version = version_;
114 }
115
116 // Perform component checks
117 check_database(status);
118 check_storage(status);
119 run_custom_checks(status);
120
121 // Calculate overall health level
122 status.update_level();
123
124 // Update cached status
125 {
126 std::unique_lock lock(mutex_);
128 last_check_time_ = std::chrono::system_clock::now();
129 }
130
131 return status;
132}
void check_database(health_status &status)
Check database connectivity.
void run_custom_checks(health_status &status)
Run all custom checks.
void check_storage(health_status &status)
Check storage availability.
std::shared_mutex mutex_
Mutex for thread safety.
constexpr dicom_tag status
Status.

References associations_, cached_status_, check_database(), check_storage(), last_check_time_, mutex_, run_custom_checks(), storage_metrics_, and version_.

Referenced by get_status().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_database()

void kcenon::pacs::monitoring::health_checker::check_database ( health_status & status)
private

Check database connectivity.

Parameters
statusStatus to update

Definition at line 222 of file health_checker.cpp.

222 {
224 std::chrono::milliseconds timeout{};
225
226 {
227 std::shared_lock lock(mutex_);
228 db = database_;
230 }
231
232 if (db == nullptr) {
233 // No database configured - mark as connected by default
234 // This allows the system to run without a database for testing
235 status.database.connected = true;
236 status.database.active_connections = 0;
237 return;
238 }
239
240 // Perform connectivity check
241 const auto start = std::chrono::steady_clock::now();
242
243 try {
244 // Attempt a simple query to verify connectivity
245 // The index_database should provide a method for this
246 status.database.connected = true;
247 status.database.last_connected = std::chrono::system_clock::now();
248 status.database.active_connections = 1;
249
250 const auto end = std::chrono::steady_clock::now();
251 status.database.response_time =
252 std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
253 } catch (const std::exception& e) {
254 status.database.connected = false;
255 status.database.error_message = e.what();
256 }
257}
PACS index database manager.
constexpr int timeout
Lock timeout exceeded.
std::chrono::milliseconds database_timeout
Timeout for database connectivity test.

References config_, database_, kcenon::pacs::monitoring::health_checker_config::database_timeout, and mutex_.

Referenced by check().

Here is the caller graph for this function:

◆ check_storage()

void kcenon::pacs::monitoring::health_checker::check_storage ( health_status & status)
private

Check storage availability.

Parameters
statusStatus to update

Definition at line 259 of file health_checker.cpp.

259 {
261 double warning_threshold = 0.0;
262 double critical_threshold = 0.0;
263
264 {
265 std::shared_lock lock(mutex_);
267 warning_threshold = config_.storage_warning_threshold;
268 critical_threshold = config_.storage_critical_threshold;
269 }
270
271 if (storage == nullptr) {
272 // No storage configured - check default storage path
273 status.storage.readable = true;
274 status.storage.writable = true;
275 return;
276 }
277
278 try {
279 // Get filesystem space information
280 const auto root = storage->root_path();
281 if (std::filesystem::exists(root)) {
282 const auto space_info = std::filesystem::space(root);
283 status.storage.total_bytes = space_info.capacity;
284 status.storage.available_bytes = space_info.available;
285 status.storage.used_bytes =
286 space_info.capacity - space_info.available;
287 }
288
289 // Test read capability
290 status.storage.readable = true;
291
292 // Test write capability
293 // Create a temporary test file
294 const auto test_path = root / ".health_check_test";
295 try {
296 {
297 std::ofstream test_file(test_path, std::ios::binary);
298 test_file << "health_check";
299 }
300 std::filesystem::remove(test_path);
301 status.storage.writable = true;
302 } catch (...) {
303 status.storage.writable = false;
304 status.storage.error_message = "Storage is not writable";
305 }
306
307 // Check usage thresholds
308 const double usage = status.storage.usage_percent();
309 if (usage >= critical_threshold) {
310 status.storage.error_message =
311 "Storage usage critical: " + std::to_string(usage) + "%";
312 } else if (usage >= warning_threshold) {
313 if (!status.storage.error_message) {
314 status.storage.error_message =
315 "Storage usage warning: " + std::to_string(usage) + "%";
316 }
317 }
318 } catch (const std::exception& e) {
319 status.storage.readable = false;
320 status.storage.writable = false;
321 status.storage.error_message = e.what();
322 }
323}
Filesystem-based DICOM storage implementation.
double storage_critical_threshold
Storage usage threshold for unhealthy status (percentage)

References config_, mutex_, storage_, kcenon::pacs::monitoring::health_checker_config::storage_critical_threshold, and kcenon::pacs::monitoring::health_checker_config::storage_warning_threshold.

Referenced by check().

Here is the caller graph for this function:

◆ config()

const health_checker_config & kcenon::pacs::monitoring::health_checker::config ( ) const
nodiscardnoexcept

Get current configuration.

Returns
Configuration reference

Definition at line 209 of file health_checker.cpp.

209 {
210 return config_;
211}

References config_.

Referenced by set_config().

Here is the caller graph for this function:

◆ get_cached_status()

health_status kcenon::pacs::monitoring::health_checker::get_cached_status ( ) const
nodiscard

Get cached health status.

Returns the most recent health check result without performing new checks. Useful for high-frequency monitoring requests.

Returns
Cached health status (may be stale)

Definition at line 144 of file health_checker.cpp.

144 {
145 std::shared_lock lock(mutex_);
146 return cached_status_;
147}

References cached_status_, and mutex_.

◆ get_status()

health_status kcenon::pacs::monitoring::health_checker::get_status ( )
nodiscard

Get cached status or perform check if stale.

Returns cached result if within cache_duration, otherwise performs a fresh check.

Returns
Health status (fresh or cached)

Definition at line 149 of file health_checker.cpp.

149 {
150 // Check if cache is still valid
151 {
152 std::shared_lock lock(mutex_);
153 const auto now = std::chrono::system_clock::now();
154 const auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(
155 now - last_check_time_);
156
157 if (elapsed < config_.cache_duration) {
158 return cached_status_;
159 }
160 }
161
162 // Cache is stale, perform fresh check
163 return check();
164}
health_status check()
Perform a full health check.
std::chrono::seconds cache_duration
Cache health check results for this duration.

References kcenon::pacs::monitoring::health_checker_config::cache_duration, cached_status_, check(), config_, last_check_time_, and mutex_.

Referenced by is_ready().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_alive()

bool kcenon::pacs::monitoring::health_checker::is_alive ( ) const
nodiscardnoexcept

Perform a quick liveness check.

A minimal check suitable for Kubernetes liveness probes. Only verifies that the service is running.

Returns
true if the service is alive

Definition at line 134 of file health_checker.cpp.

134 {
135 // Simple liveness check - just verify the checker is running
136 return true;
137}

◆ is_ready()

bool kcenon::pacs::monitoring::health_checker::is_ready ( )
nodiscard

Perform a readiness check.

Checks if the service is ready to accept traffic. Verifies database and storage connectivity.

Returns
true if the service is ready

Definition at line 139 of file health_checker.cpp.

139 {
140 auto status = get_status();
141 return status.is_operational();
142}
health_status get_status()
Get cached status or perform check if stale.

References get_status().

Here is the call graph for this function:

◆ operator=() [1/2]

health_checker & kcenon::pacs::monitoring::health_checker::operator= ( const health_checker & )
delete

◆ operator=() [2/2]

health_checker & kcenon::pacs::monitoring::health_checker::operator= ( health_checker && other)
noexcept

Definition at line 54 of file health_checker.cpp.

54 {
55 if (this != &other) {
56 std::unique_lock lock1(mutex_, std::defer_lock);
57 std::unique_lock lock2(other.mutex_, std::defer_lock);
58 std::lock(lock1, lock2);
59
60 config_ = std::move(other.config_);
61 database_ = other.database_;
62 storage_ = other.storage_;
63 custom_checks_ = std::move(other.custom_checks_);
64 cached_status_ = std::move(other.cached_status_);
65 last_check_time_ = other.last_check_time_;
66 associations_ = other.associations_;
67 storage_metrics_ = other.storage_metrics_;
68 version_ = std::move(other.version_);
69 other.database_ = nullptr;
70 other.storage_ = nullptr;
71 }
72 return *this;
73}

◆ register_check()

void kcenon::pacs::monitoring::health_checker::register_check ( std::string_view name,
check_callback callback )

Register a custom health check.

Custom checks allow extending the health checker with application- specific health indicators.

Parameters
nameUnique identifier for the check
callbackFunction that returns true if healthy, false otherwise

Definition at line 89 of file health_checker.cpp.

90 {
91 std::unique_lock lock(mutex_);
92 custom_checks_[std::string(name)] = std::move(callback);
93}
std::string_view name

References custom_checks_, mutex_, and name.

◆ run_custom_checks()

void kcenon::pacs::monitoring::health_checker::run_custom_checks ( health_status & status)
private

Run all custom checks.

Parameters
statusStatus to update

Definition at line 325 of file health_checker.cpp.

325 {
326 std::unordered_map<std::string, check_callback> checks;
327
328 {
329 std::shared_lock lock(mutex_);
330 checks = custom_checks_;
331 }
332
333 for (const auto& [name, callback] : checks) {
334 try {
335 std::string error_message;
336 const bool healthy = callback(error_message);
337
338 if (!healthy) {
339 // Append custom check failure to message
340 const std::string check_msg =
341 "Custom check '" + name + "' failed: " + error_message;
342 if (status.message) {
343 status.message = *status.message + "; " + check_msg;
344 } else {
345 status.message = check_msg;
346 }
347 }
348 } catch (const std::exception& e) {
349 const std::string check_msg =
350 "Custom check '" + name + "' threw exception: " + e.what();
351 if (status.message) {
352 status.message = *status.message + "; " + check_msg;
353 } else {
354 status.message = check_msg;
355 }
356 }
357 }
358}
@ healthy
All components healthy, system fully operational.

References custom_checks_, kcenon::pacs::monitoring::healthy, mutex_, and name.

Referenced by check().

Here is the caller graph for this function:

◆ set_config()

void kcenon::pacs::monitoring::health_checker::set_config ( const health_checker_config & config)

Update configuration.

Parameters
configNew configuration

Definition at line 213 of file health_checker.cpp.

213 {
214 std::unique_lock lock(mutex_);
215 config_ = config;
216}

References config(), config_, and mutex_.

Here is the call graph for this function:

◆ set_database()

void kcenon::pacs::monitoring::health_checker::set_database ( kcenon::pacs::storage::index_database * database)

Set the database instance to monitor.

Parameters
databasePointer to the index_database (nullable to disable check)

Definition at line 79 of file health_checker.cpp.

79 {
80 std::unique_lock lock(mutex_);
81 database_ = database;
82}

References database_, and mutex_.

◆ set_storage()

void kcenon::pacs::monitoring::health_checker::set_storage ( kcenon::pacs::storage::file_storage * storage)

Set the storage instance to monitor.

Parameters
storagePointer to the file_storage (nullable to disable check)

Definition at line 84 of file health_checker.cpp.

84 {
85 std::unique_lock lock(mutex_);
87}

References mutex_, and storage_.

◆ set_version()

void kcenon::pacs::monitoring::health_checker::set_version ( std::uint16_t major,
std::uint16_t minor,
std::uint16_t patch,
std::string_view build_id = "" )

Set version information.

Parameters
majorMajor version
minorMinor version
patchPatch version
build_idBuild identifier (e.g., git hash)

Definition at line 194 of file health_checker.cpp.

197 {
198 std::unique_lock lock(mutex_);
199 version_.major = major;
200 version_.minor = minor;
201 version_.patch = patch;
202 version_.build_id = std::string(build_id);
203}
std::string build_id
Build identifier (e.g., git commit hash)
std::uint16_t major
Major version number.
std::uint16_t patch
Patch version number.
std::uint16_t minor
Minor version number.

References kcenon::pacs::monitoring::version_info::build_id, kcenon::pacs::monitoring::version_info::major, kcenon::pacs::monitoring::version_info::minor, mutex_, kcenon::pacs::monitoring::version_info::patch, and version_.

◆ unregister_check()

void kcenon::pacs::monitoring::health_checker::unregister_check ( std::string_view name)

Unregister a custom health check.

Parameters
nameThe check identifier to remove

Definition at line 95 of file health_checker.cpp.

95 {
96 std::unique_lock lock(mutex_);
97 custom_checks_.erase(std::string(name));
98}

References custom_checks_, mutex_, and name.

◆ update_association_metrics()

void kcenon::pacs::monitoring::health_checker::update_association_metrics ( std::uint32_t active,
std::uint32_t max,
std::uint64_t total_established,
std::uint64_t total_failed )

Update association metrics.

Called by the DICOM server to update active association count.

Parameters
activeCurrent number of active associations
maxMaximum allowed associations
total_establishedTotal associations since startup
total_failedTotal failed association attempts

Definition at line 170 of file health_checker.cpp.

173 {
174 std::unique_lock lock(mutex_);
177 associations_.total_associations = total_established;
178 associations_.failed_associations = total_failed;
179}
std::uint32_t active_associations
Number of currently active associations.
std::uint64_t failed_associations
Number of failed associations.
std::uint32_t max_associations
Maximum concurrent associations allowed.
std::uint64_t total_associations
Total associations since server start.

References kcenon::pacs::monitoring::association_metrics::active_associations, associations_, kcenon::pacs::monitoring::association_metrics::failed_associations, kcenon::pacs::monitoring::association_metrics::max_associations, mutex_, and kcenon::pacs::monitoring::association_metrics::total_associations.

◆ update_storage_metrics()

void kcenon::pacs::monitoring::health_checker::update_storage_metrics ( std::uint64_t instances,
std::uint64_t studies,
std::uint64_t series,
std::uint64_t successful_stores,
std::uint64_t failed_stores )

Update storage metrics.

Called by storage service to update storage statistics.

Parameters
instancesTotal stored instances
studiesTotal studies
seriesTotal series
successful_storesSuccessful C-STORE operations
failed_storesFailed C-STORE operations

Definition at line 181 of file health_checker.cpp.

185 {
186 std::unique_lock lock(mutex_);
190 storage_metrics_.successful_stores = successful_stores;
191 storage_metrics_.failed_stores = failed_stores;
192}
std::uint64_t successful_stores
Successful C-STORE operations.
std::uint64_t total_instances
Total DICOM instances stored.
std::uint64_t total_studies
Total studies in the archive.
std::uint64_t failed_stores
Failed C-STORE operations.
std::uint64_t total_series
Total series in the archive.

References kcenon::pacs::monitoring::storage_metrics::failed_stores, mutex_, storage_metrics_, kcenon::pacs::monitoring::storage_metrics::successful_stores, kcenon::pacs::monitoring::storage_metrics::total_instances, kcenon::pacs::monitoring::storage_metrics::total_series, and kcenon::pacs::monitoring::storage_metrics::total_studies.

Member Data Documentation

◆ associations_

association_metrics kcenon::pacs::monitoring::health_checker::associations_
private

Association metrics (updated externally)

Definition at line 341 of file health_checker.h.

Referenced by check(), and update_association_metrics().

◆ cached_status_

health_status kcenon::pacs::monitoring::health_checker::cached_status_
private

Cached health status.

Definition at line 335 of file health_checker.h.

Referenced by check(), get_cached_status(), get_status(), and health_checker().

◆ config_

health_checker_config kcenon::pacs::monitoring::health_checker::config_
private

Configuration.

Definition at line 323 of file health_checker.h.

Referenced by check_database(), check_storage(), config(), get_status(), and set_config().

◆ custom_checks_

std::unordered_map<std::string, check_callback> kcenon::pacs::monitoring::health_checker::custom_checks_
private

Custom health checks.

Definition at line 332 of file health_checker.h.

Referenced by register_check(), run_custom_checks(), and unregister_check().

◆ database_

kcenon::pacs::storage::index_database* kcenon::pacs::monitoring::health_checker::database_ {nullptr}
private

Database instance to monitor.

Definition at line 326 of file health_checker.h.

326{nullptr};

Referenced by check_database(), and set_database().

◆ last_check_time_

std::chrono::system_clock::time_point kcenon::pacs::monitoring::health_checker::last_check_time_
private

Timestamp of last check.

Definition at line 338 of file health_checker.h.

Referenced by check(), and get_status().

◆ mutex_

std::shared_mutex kcenon::pacs::monitoring::health_checker::mutex_
mutableprivate

◆ storage_

kcenon::pacs::storage::file_storage* kcenon::pacs::monitoring::health_checker::storage_ {nullptr}
private

Storage instance to monitor.

Definition at line 329 of file health_checker.h.

329{nullptr};

Referenced by check_storage(), and set_storage().

◆ storage_metrics_

storage_metrics kcenon::pacs::monitoring::health_checker::storage_metrics_
private

Storage metrics (updated externally)

Definition at line 344 of file health_checker.h.

Referenced by check(), and update_storage_metrics().

◆ version_

version_info kcenon::pacs::monitoring::health_checker::version_
private

Version information.

Definition at line 347 of file health_checker.h.

Referenced by check(), health_checker(), and set_version().


The documentation for this class was generated from the following files: