PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
ai_service_connector.cpp File Reference

Implementation of AI service connector. More...

#include <kcenon/pacs/ai/ai_service_connector.h>
#include <kcenon/pacs/integration/logger_adapter.h>
#include <kcenon/pacs/integration/monitoring_adapter.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iomanip>
#include <mutex>
#include <queue>
#include <shared_mutex>
#include <sstream>
#include <thread>
#include <unordered_map>
Include dependency graph for ai_service_connector.cpp:

Go to the source code of this file.

Classes

struct  http_response
 Simple HTTP response structure. More...
 
class  socket_handle
 RAII wrapper for platform socket handle. More...
 
struct  parsed_url
 Parse URL into host, port, and path components. More...
 
class  http_client
 HTTP client for AI service communication. More...
 
class  job_tracker
 Tracks active inference jobs. More...
 
class  ai_service_connector::impl
 

Namespaces

namespace  kcenon
 
namespace  kcenon::pacs
 
namespace  kcenon::pacs::ai
 
namespace  kcenon::pacs::ai::metrics
 
namespace  kcenon::pacs::ai::json_util
 

Functions

std::string kcenon::pacs::ai::json_util::escape_string (std::string_view str)
 Escape special characters in JSON string.
 
std::string kcenon::pacs::ai::json_util::to_iso8601 (std::chrono::system_clock::time_point tp)
 Convert time_point to ISO 8601 string.
 
std::optional< std::chrono::system_clock::time_point > kcenon::pacs::ai::json_util::from_iso8601 (const std::string &str)
 Parse ISO 8601 string to time_point.
 
std::optional< std::string > kcenon::pacs::ai::json_util::extract_string (const std::string &json, const std::string &key)
 Simple JSON value extractor (for basic parsing)
 
std::optional< int > kcenon::pacs::ai::json_util::extract_int (const std::string &json, const std::string &key)
 Simple JSON integer extractor.
 
std::string kcenon::pacs::ai::json_util::build_request_json (const inference_request &request)
 Build inference request JSON.
 
 kcenon::pacs::ai::if (!request.parameters.empty())
 
 kcenon::pacs::ai::if (!request.metadata.empty())
 
std::optional< inference_status > parse_status_json (const std::string &json)
 Parse inference status from JSON response.
 
std::optional< model_info > parse_model_json (const std::string &json)
 Parse model info from JSON.
 
std::string base64_encode (std::string_view input)
 Encode data to Base64.
 
std::vector< std::string > extract_json_array_objects (const std::string &json)
 Extract JSON objects from a JSON array string.
 

Variables

constexpr const char * kcenon::pacs::ai::metrics::inference_requests_total = "pacs_ai_inference_requests_total"
 
constexpr const char * kcenon::pacs::ai::metrics::inference_requests_success = "pacs_ai_inference_requests_success"
 
constexpr const char * kcenon::pacs::ai::metrics::inference_requests_failed = "pacs_ai_inference_requests_failed"
 
constexpr const char * kcenon::pacs::ai::metrics::inference_duration = "pacs_ai_inference_duration_seconds"
 
constexpr const char * kcenon::pacs::ai::metrics::active_jobs = "pacs_ai_active_jobs"
 

Detailed Description

Implementation of AI service connector.

Definition in file ai_service_connector.cpp.

Function Documentation

◆ base64_encode()

std::string base64_encode ( std::string_view input)
inlinenodiscard

Encode data to Base64.

Definition at line 364 of file ai_service_connector.cpp.

364 {
365 static constexpr char table[] =
366 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
367
368 std::string result;
369 result.reserve(((input.size() + 2) / 3) * 4);
370
371 auto ptr = reinterpret_cast<const unsigned char*>(input.data());
372 auto len = input.size();
373
374 for (std::size_t i = 0; i < len; i += 3) {
375 uint32_t octet_a = ptr[i];
376 uint32_t octet_b = (i + 1 < len) ? ptr[i + 1] : 0;
377 uint32_t octet_c = (i + 2 < len) ? ptr[i + 2] : 0;
378
379 uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;
380
381 result += table[(triple >> 18) & 0x3F];
382 result += table[(triple >> 12) & 0x3F];
383 result += (i + 1 < len) ? table[(triple >> 6) & 0x3F] : '=';
384 result += (i + 2 < len) ? table[triple & 0x3F] : '=';
385 }
386
387 return result;
388}

◆ extract_json_array_objects()

std::vector< std::string > extract_json_array_objects ( const std::string & json)
inlinenodiscard

Extract JSON objects from a JSON array string.

Definition at line 393 of file ai_service_connector.cpp.

394 {
395 std::vector<std::string> objects;
396
397 // Find array start
398 auto arr_start = json.find('[');
399 if (arr_start == std::string::npos) {
400 return objects;
401 }
402
403 int depth = 0;
404 std::size_t obj_start = std::string::npos;
405
406 for (std::size_t i = arr_start + 1; i < json.size(); ++i) {
407 char c = json[i];
408
409 if (c == '"') {
410 // Skip string content
411 ++i;
412 while (i < json.size() && json[i] != '"') {
413 if (json[i] == '\\') ++i; // Skip escaped character
414 ++i;
415 }
416 continue;
417 }
418
419 if (c == '{') {
420 if (depth == 0) {
421 obj_start = i;
422 }
423 ++depth;
424 } else if (c == '}') {
425 --depth;
426 if (depth == 0 && obj_start != std::string::npos) {
427 objects.push_back(json.substr(obj_start, i - obj_start + 1));
428 obj_start = std::string::npos;
429 }
430 } else if (c == ']' && depth == 0) {
431 break;
432 }
433 }
434
435 return objects;
436}

◆ parse_model_json()

std::optional< model_info > parse_model_json ( const std::string & json)
inlinenodiscard

Parse model info from JSON.

Definition at line 333 of file ai_service_connector.cpp.

334 {
335 model_info info;
336
337 auto model_id = extract_string(json, "model_id");
338 if (!model_id) {
339 return std::nullopt;
340 }
341 info.model_id = *model_id;
342
343 auto name = extract_string(json, "name");
344 if (name) {
345 info.name = *name;
346 }
347
348 auto description = extract_string(json, "description");
349 if (description) {
350 info.description = *description;
351 }
352
353 auto version = extract_string(json, "version");
354 if (version) {
355 info.version = *version;
356 }
357
358 return info;
359}
std::optional< std::string > extract_string(const std::string &json, const std::string &key)
Simple JSON value extractor (for basic parsing)
std::string_view name

References kcenon::pacs::ai::json_util::extract_string(), and name.

Here is the call graph for this function:

◆ parse_status_json()

std::optional< inference_status > parse_status_json ( const std::string & json)
inlinenodiscard

Parse inference status from JSON response.

Definition at line 261 of file ai_service_connector.cpp.

262 {
263 inference_status status;
264
265 auto job_id = extract_string(json, "job_id");
266 if (!job_id) {
267 return std::nullopt;
268 }
269 status.job_id = *job_id;
270
271 auto status_str = extract_string(json, "status");
272 if (status_str) {
273 if (*status_str == "pending") {
274 status.status = inference_status_code::pending;
275 } else if (*status_str == "running") {
276 status.status = inference_status_code::running;
277 } else if (*status_str == "completed") {
278 status.status = inference_status_code::completed;
279 } else if (*status_str == "failed") {
280 status.status = inference_status_code::failed;
281 } else if (*status_str == "cancelled") {
282 status.status = inference_status_code::cancelled;
283 } else if (*status_str == "timeout") {
284 status.status = inference_status_code::timeout;
285 }
286 }
287
288 auto progress = extract_int(json, "progress");
289 if (progress) {
290 status.progress = *progress;
291 }
292
293 auto message = extract_string(json, "message");
294 if (message) {
295 status.message = *message;
296 }
297
298 auto error = extract_string(json, "error_message");
299 if (error) {
300 status.error_message = *error;
301 }
302
303 auto created_at = extract_string(json, "created_at");
304 if (created_at) {
305 auto tp = from_iso8601(*created_at);
306 if (tp) {
307 status.created_at = *tp;
308 }
309 }
310
311 auto started_at = extract_string(json, "started_at");
312 if (started_at) {
313 auto tp = from_iso8601(*started_at);
314 if (tp) {
315 status.started_at = *tp;
316 }
317 }
318
319 auto completed_at = extract_string(json, "completed_at");
320 if (completed_at) {
321 auto tp = from_iso8601(*completed_at);
322 if (tp) {
323 status.completed_at = *tp;
324 }
325 }
326
327 return status;
328}
std::optional< std::chrono::system_clock::time_point > from_iso8601(const std::string &str)
Parse ISO 8601 string to time_point.
std::optional< int > extract_int(const std::string &json, const std::string &key)
Simple JSON integer extractor.
@ error
Node returned an error.
constexpr dicom_tag status
Status.

References kcenon::pacs::ai::cancelled, kcenon::pacs::ai::completed, kcenon::pacs::ai::json_util::extract_int(), kcenon::pacs::ai::json_util::extract_string(), kcenon::pacs::ai::failed, kcenon::pacs::ai::json_util::from_iso8601(), kcenon::pacs::ai::pending, kcenon::pacs::ai::running, and kcenon::pacs::ai::timeout.

Here is the call graph for this function: