Skip to content

[DAPS-1663] Adding LogContext to dbGetRaw#1885

Open
megatnt1122 wants to merge 1 commit intodevelfrom
refactor-DAPS-1663-Passing-Correlation-ID
Open

[DAPS-1663] Adding LogContext to dbGetRaw#1885
megatnt1122 wants to merge 1 commit intodevelfrom
refactor-DAPS-1663-Passing-Correlation-ID

Conversation

@megatnt1122
Copy link
Collaborator

@megatnt1122 megatnt1122 commented Feb 26, 2026

Ticket

#1663

Description

Added logcontext to dbGetRaw

Tasks

  • - A description of the PR has been provided, and a diagram included if it is a new feature.
  • - Formatter has been run
  • - CHANGELOG comment has been added
  • - Labels have been assigned to the pr
  • - A reviwer has been added
  • - A user has been assigned to work on the pr
  • - If new feature a unit test has been added

Summary by Sourcery

Propagate structured logging context with correlation IDs through authentication and database paths and attach it as an HTTP header on database requests.

New Features:

  • Add generation and propagation of a per-request correlation ID via LogContext through authentication flows and database lookups, including adding it as an x-correlation-id header on outbound database HTTP calls.

Enhancements:

  • Extend AuthenticationManager, AuthMap, and DatabaseAPI interfaces to accept LogContext so that key lookups and UID resolution can participate in structured logging and tracing.
  • Update configuration loading and authentication operator logic to use LogContext-aware methods when checking keys and resolving UIDs.

Tests:

  • Adapt existing AuthMap, AuthenticationManager, and operator unit tests to construct and pass LogContext instances to the updated interfaces.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 26, 2026

Reviewer's Guide

Adds propagation of LogContext (including a correlation ID) through authentication and database lookup paths, and updates dbGetRaw to attach the correlation ID as an HTTP header, with corresponding interface, implementation, and test adjustments.

Sequence diagram for authentication flow with LogContext and dbGetRaw

sequenceDiagram
  actor Client
  participant AuthenticationOperator
  participant AuthenticationManager
  participant AuthMap
  participant DatabaseAPI
  participant DatabaseService

  Client->>AuthenticationOperator: execute(message)
  AuthenticationOperator->>AuthenticationOperator: generate uuid
  AuthenticationOperator->>AuthenticationOperator: create LogContext
  AuthenticationOperator->>AuthenticationManager: hasKey(key, log_context)
  AuthenticationManager->>AuthMap: hasKey(PublicKeyType_TRANSIENT, key, log_context)
  alt key_not_found_transient
    AuthenticationManager->>AuthMap: hasKey(PublicKeyType_SESSION, key, log_context)
    alt key_not_found_session
      AuthenticationManager->>AuthMap: hasKey(PublicKeyType_PERSISTENT, key, log_context)
      alt key_found_persistent
        AuthenticationManager-->>AuthenticationOperator: true
      else key_not_found_any
        AuthenticationManager-->>AuthenticationOperator: false
      end
    else key_found_session
      AuthenticationManager-->>AuthenticationOperator: true
    end
  else key_found_transient
    AuthenticationManager-->>AuthenticationOperator: true
  end

  opt key_found
    AuthenticationOperator->>AuthenticationManager: incrementKeyAccessCounter(key, log_context)
    AuthenticationManager->>AuthMap: incrementKeyAccessCounter(type_for_key, key, log_context)

    AuthenticationOperator->>AuthenticationManager: getUID(key, log_context)
    AuthenticationManager->>AuthMap: getUIDSafe(type_for_key, key, log_context)
    alt uid_in_memory
      AuthMap-->>AuthenticationManager: uid
    else uid_not_in_memory
      AuthMap->>DatabaseAPI: uidByPubKey(key, uid, log_context)
      DatabaseAPI->>DatabaseAPI: buildSearchParamURL(usr_find_by_pub_key)
      DatabaseAPI->>DatabaseAPI: dbGetRaw(url, uid, log_context)
      DatabaseAPI->>DatabaseService: HTTP GET url
      DatabaseService-->>DatabaseAPI: 200 OK body
      DatabaseAPI-->>AuthMap: true uid
      AuthMap-->>AuthenticationManager: uid
    end
    AuthenticationManager-->>AuthenticationOperator: uid
  end

  AuthenticationOperator-->>Client: response with uid
Loading

Sequence diagram for dbGetRaw attaching correlation ID header

sequenceDiagram
  participant Caller as DatabaseAPI_caller
  participant DatabaseAPI
  participant CURL
  participant DatabaseService

  Caller->>DatabaseAPI: dbGetRaw(url, result, log_context)
  DatabaseAPI->>DatabaseAPI: a_result.clear()
  DatabaseAPI->>CURL: curl_easy_setopt(m_curl, CURLOPT_URL, url)
  DatabaseAPI->>CURL: curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeCallback)
  DatabaseAPI->>CURL: curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, a_result)
  DatabaseAPI->>CURL: curl_easy_setopt(m_curl, CURLOPT_ERRORBUFFER, error)
  DatabaseAPI->>CURL: curl_easy_setopt(m_curl, CURLOPT_HTTPGET, 1)
  DatabaseAPI->>DatabaseAPI: header = x-correlation-id + log_context.correlation_id
  DatabaseAPI->>CURL: headers = curl_slist_append(headers, header)
  DatabaseAPI->>CURL: curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers)

  DatabaseAPI->>CURL: curl_easy_perform(m_curl)
  CURL->>DatabaseService: HTTP GET url with x-correlation-id
  DatabaseService-->>CURL: HTTP response
  CURL-->>DatabaseAPI: res

  DatabaseAPI->>CURL: curl_slist_free_all(headers)
  DatabaseAPI->>CURL: curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, http_code)
  alt success_2xx
    DatabaseAPI-->>Caller: true
  else failure
    DatabaseAPI-->>Caller: false
  end
Loading

Class diagram for authentication and database components with LogContext

classDiagram
  class LogContext {
    +string correlation_id
  }

  class IAuthenticationManager {
    <<interface>>
    +incrementKeyAccessCounter(public_key string, log_context LogContext) void
    +hasKey(pub_key string, log_context LogContext) bool
    +getUID(pub_key string, log_context LogContext) string
  }

  class AuthenticationManager {
    +incrementKeyAccessCounter(public_key string, log_context LogContext) void
    +purge(pub_key_type PublicKeyType) void
    +hasKey(pub_key string, log_context LogContext) bool
    +addKey(pub_key_type PublicKeyType, public_key string, uid string) void
    +hasKey(pub_key_type PublicKeyType, public_key string, log_context LogContext) bool
    +migrateKey(from_type PublicKeyType, to_type PublicKeyType, public_key string) void
    +clearAllNonPersistentKeys() void
    +getUID(pub_key string, log_context LogContext) string
    +getUIDSafe(pub_key string, log_context LogContext) string
    -m_auth_mapper AuthMap
    -m_lock mutex
  }

  class AuthMap {
    +getUID(pub_key_type PublicKeyType, public_key string, log_context LogContext) string
    +getUIDSafe(pub_key_type PublicKeyType, public_key string, log_context LogContext) string
    +size(pub_key_type PublicKeyType) size_t
    +hasKey(pub_key_type PublicKeyType, public_key string, log_context LogContext) bool
    +incrementKeyAccessCounter(pub_key_type PublicKeyType, public_key string, log_context LogContext) void
    +addKey(pub_key_type PublicKeyType, public_key string, uid string) void
    +getAccessCount(pub_key_type PublicKeyType, public_key string) size_t
    +hasKeyType(pub_key_type PublicKeyType, public_key string) bool
    -m_db_url string
    -m_db_user string
    -m_db_pass string
  }

  class DatabaseAPI {
    +DatabaseAPI(db_url string, db_user string, db_pass string)
    +uidByPubKey(a_pub_key string, a_uid string&, log_context LogContext) bool
    +userGetKeys(a_pub_key string&, a_priv_key string&, log_context LogContext) bool
    +userSetKeys(a_pub_key string, a_priv_key string, log_context LogContext) void
    +userSetAccessToken(a_acc_tok string, a_refresh_tok string, a_expires_in uint32_t, other_token_data string, log_context LogContext) void
    +getExpiringAccessTokens(a_expires_in uint32_t, a_expiring_tokens vector~UserTokenInfo~&, log_context LogContext) void
    +purgeTransferRecords(age size_t, log_context LogContext) void
    -dbGet(a_url_path const char*, a_params vector~pair~string_string~~, a_result libjson_Value&, log_context LogContext, a_log bool) long
    -dbGetRaw(url string, a_result string&, log_context LogContext) bool
    -dbPost(a_url_path const char*, a_params vector~pair~string_string~~, a_body string*, a_result libjson_Value&, log_context LogContext) long
  }

  class AuthenticationOperator {
    +execute(message IMessage&) void
    -m_authentication_manager IAuthenticationManager*
  }

  class Promote {
    +enforce(auth_map AuthMap&, public_key string) void
    -m_promote_from PublicKeyType
    -m_promote_to PublicKeyType
    -m_transient_to_session_count_threshold size_t
  }

  IAuthenticationManager <|.. AuthenticationManager
  AuthenticationManager *-- AuthMap
  AuthMap ..> DatabaseAPI
  AuthenticationOperator --> IAuthenticationManager
  Promote --> AuthMap
  DatabaseAPI ..> LogContext
  AuthenticationManager ..> LogContext
  AuthMap ..> LogContext
  AuthenticationOperator ..> LogContext
  Promote ..> LogContext
Loading

File-Level Changes

Change Details Files
Thread LogContext (correlation id) through authentication manager and map operations so DB lookups can be correlated per request.
  • Update IAuthenticationManager interface methods (incrementKeyAccessCounter, hasKey, getUID) to accept a LogContext parameter.
  • Update AuthenticationManager and AuthMap method signatures and implementations to take LogContext and pass it down when calling into AuthMap and DatabaseAPI.
  • Adjust usages in AuthenticationOperator, Config, Condition, and unit tests to construct a LogContext and pass it through authentication calls.
common/include/common/IAuthenticationManager.hpp
core/server/AuthenticationManager.hpp
core/server/AuthenticationManager.cpp
core/server/AuthMap.hpp
core/server/AuthMap.cpp
common/source/operators/AuthenticationOperator.cpp
core/server/Config.cpp
core/server/Condition.cpp
core/server/tests/unit/test_AuthenticationManager.cpp
core/server/tests/unit/test_AuthMap.cpp
common/tests/unit/test_OperatorFactory.cpp
Attach correlation ID from LogContext to outbound database HTTP requests via dbGetRaw and propagate LogContext through DatabaseAPI.
  • Change DatabaseAPI::dbGetRaw to take LogContext and set an x-correlation-id header on the CURL handle based on log_context.correlation_id, freeing the header list after the request.
  • Update DatabaseAPI methods that rely on dbGetRaw (uidByPubKey, userSetAccessToken, purgeTransferRecords) to accept/forward LogContext.
  • Propagate LogContext from AuthMap’s DB lookups into DatabaseAPI::uidByPubKey so authentication-related DB calls carry the correlation id.
core/server/DatabaseAPI.hpp
core/server/DatabaseAPI.cpp
core/server/AuthMap.cpp
Generate per-request correlation IDs at authentication entry points and use them for logging and DB calls.
  • In AuthenticationOperator::execute, generate a UUID-based correlation_id, populate a LogContext, and use it for AuthenticationManager calls.
  • In Condition::Promote::enforce, generate a correlation_id LogContext when promoting keys and use it for AuthMap::getUID to ensure DB lookups are correlated.
common/source/operators/AuthenticationOperator.cpp
core/server/Condition.cpp

Possibly linked issues

  • #[Core] - Logging add correlation id to requests going to foxx api: PR adds LogContext and x-correlation-id to dbGetRaw and uidByPubKey paths, partially implementing the correlation ID logging issue.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • Most of the new LogContext parameters are passed by value, including in interfaces; consider passing them as const LogContext& to avoid unnecessary copies and make the intent (read-only context) clearer.
  • Correlation ID generation with Boost UUID is now duplicated in AuthenticationOperator::execute and Promote::enforce; consider extracting a small helper/factory to centralize correlation ID creation and keep this logic consistent.
  • Condition.cpp uses LogContext but only adds Boost UUID headers; make sure to include the header that defines LogContext (e.g., common/DynaLog.hpp) here instead of relying on transitive includes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Most of the new `LogContext` parameters are passed by value, including in interfaces; consider passing them as `const LogContext&` to avoid unnecessary copies and make the intent (read-only context) clearer.
- Correlation ID generation with Boost UUID is now duplicated in `AuthenticationOperator::execute` and `Promote::enforce`; consider extracting a small helper/factory to centralize correlation ID creation and keep this logic consistent.
- `Condition.cpp` uses `LogContext` but only adds Boost UUID headers; make sure to include the header that defines `LogContext` (e.g., `common/DynaLog.hpp`) here instead of relying on transitive includes.

## Individual Comments

### Comment 1
<location path="core/server/DatabaseAPI.cpp" line_range="186-195" />
<code_context>
   curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &a_result);
   curl_easy_setopt(m_curl, CURLOPT_ERRORBUFFER, error);
   curl_easy_setopt(m_curl, CURLOPT_HTTPGET, 1);
+  struct curl_slist* headers = nullptr;
+
+  // safe: curl_slist_append copies the string internally
+  std::string header = "x-correlation-id: " + log_context.correlation_id;
+  headers = curl_slist_append(headers, header.c_str());
+
+  // attach headers to the CURL handle
+  curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers);

   CURLcode res = curl_easy_perform(m_curl);
+  curl_slist_free_all(headers);
   long http_code = 0;
   curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &http_code);
</code_context>
<issue_to_address>
**issue (bug_risk):** Reset CURLOPT_HTTPHEADER after freeing the curl_slist to avoid a dangling pointer in the CURL handle.

After `curl_slist_free_all(headers)`, `m_curl` still has `CURLOPT_HTTPHEADER` set to the freed list. If this handle is reused and a request is performed before `CURLOPT_HTTPHEADER` is updated, libcurl may dereference freed memory.

To avoid that, clear the option after freeing:

```c++
CURLcode res = curl_easy_perform(m_curl);
curl_slist_free_all(headers);
headers = nullptr;
curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, nullptr);
```

This keeps the handle from holding a pointer to freed header data between requests.
</issue_to_address>

### Comment 2
<location path="core/server/AuthenticationManager.hpp" line_range="57-60" />
<code_context>
    *not be purged.
    **/
-  virtual void incrementKeyAccessCounter(const std::string &public_key) final;
+  virtual void incrementKeyAccessCounter(const std::string &public_key, LogContext log_context) final;

   /**
</code_context>
<issue_to_address>
**suggestion (performance):** Consider passing LogContext by const reference instead of by value through the authentication APIs.

All public `AuthenticationManager` / `IAuthenticationManager` methods now take `LogContext` by value and forward it through to `AuthMap` and `DatabaseAPI`. To avoid repeated copies as `LogContext` grows, you could change these to accept `const LogContext&` instead and propagate that through the implementation and call sites, e.g.:

```c++
virtual void incrementKeyAccessCounter(const std::string &public_key, const LogContext &log_context) final;
virtual bool hasKey(const std::string &pub_key, const LogContext &log_context) const final;
virtual std::string getUID(const std::string &pub_key, const LogContext &log_context) const final;
std::string getUIDSafe(const std::string &pub_key, const LogContext &log_context) const;
```

Suggested implementation:

```
   *allotted purge time frame. If the count is above one then the session key
   *not be purged.
   **/
  virtual void incrementKeyAccessCounter(const std::string &public_key, const LogContext &log_context) final;

  /**
   * This will purge all keys of a particular type that have expired.
   * - SESSION
   * - PERSISTENT
   **/
  virtual bool hasKey(const std::string &pub_key, const LogContext &log_context) const final;

```

To fully implement the suggestion, you should also:
1. Update all other `AuthenticationManager` / `IAuthenticationManager` method declarations in this header that currently take `LogContext` by value to instead take `const LogContext &` (e.g. `getUID`, `getUIDSafe`, and any similar methods).
2. Update the corresponding method definitions in the `.cpp` files (e.g. `AuthenticationManager.cpp`, `AuthMap.cpp`, `DatabaseAPI` implementations) to match the new signatures (`const LogContext &`).
3. Adjust all call sites that pass a `LogContext` to these methods so they pass by reference; typically no call-site syntax change is required, but ensure there are no temporary rvalues that would now bind to a `const LogContext &`.
4. If there are overridden methods in derived classes, make sure their signatures are also updated to use `const LogContext &` so they still correctly override the interface.
</issue_to_address>

### Comment 3
<location path="common/tests/unit/test_OperatorFactory.cpp" line_range="42" />
<code_context>
    * Methods only available via the interface
    **/
-  virtual void incrementKeyAccessCounter(const std::string &pub_key) final {
+  virtual void incrementKeyAccessCounter(const std::string &pub_key, LogContext log_context) final {
     ++m_counters.at(pub_key);
   }
</code_context>
<issue_to_address>
**suggestion (testing):** Improve Operator/Authentication integration tests to validate LogContext usage and correlation-id generation

`DummyAuthManager` now accepts a `LogContext`, but the tests don't verify how it's used. Since `AuthenticationOperator::execute` generates a correlation ID and passes the same `LogContext` to `hasKey`, `incrementKeyAccessCounter`, and `getUID`, please enhance the tests to:
- Have `DummyAuthManager` store the last `LogContext` it receives, and
- Assert that `execute()` provides a non-empty correlation ID and reuses the same `LogContext` across all three calls.

This will validate the new wiring rather than just exercising the updated signature.

Suggested implementation:

```cpp
  /**
   * Methods only available via the interface
   **/
  virtual void incrementKeyAccessCounter(const std::string &pub_key, LogContext log_context) final {
    ++m_counters.at(pub_key);
    m_log_contexts.push_back(log_context);
  }

  virtual bool hasKey(const std::string &pub_key, LogContext log_context) const {
    m_log_contexts.push_back(log_context);
    return m_counters.count(pub_key);
  }
  // Just assume all keys map to the anon_uid
  virtual std::string getUID(const std::string &, LogContext log_context) const {
    m_log_contexts.push_back(log_context);
    return "authenticated_uid";
  }

  const std::vector<LogContext> &logContexts() const {
    return m_log_contexts;
  }

```

To fully implement the test coverage you described, you will also need to:

1. Add a member field to `DummyAuthManager` (in the same class where `m_counters` is defined):
   ```c++
   mutable std::vector<LogContext> m_log_contexts;
   ```
   Make sure the header `<vector>` is included if it is not already.

2. In the relevant Operator/Authentication integration test that invokes `AuthenticationOperator::execute(...)` (or uses `OperatorFactory` to create the authentication operator with `DummyAuthManager`), add assertions such as:
   ```c++
   const auto &log_contexts = dummy_auth_manager.logContexts();
   ASSERT_EQ(log_contexts.size(), 3u); // hasKey, incrementKeyAccessCounter, getUID

   // All three calls must receive the same LogContext instance
   EXPECT_TRUE(log_contexts[0] == log_contexts[1]);
   EXPECT_TRUE(log_contexts[1] == log_contexts[2]);

   // And the correlation id must be non-empty
   const auto &ctx = log_contexts[0];
   // Adjust the accessor below to however correlation-id is exposed by LogContext
   EXPECT_FALSE(ctx.correlation_id().empty());
   ```
   If `LogContext` does not support `operator==` or `correlation_id()`, adapt the checks accordingly (for example, compare pointer identity if `LogContext` is a smart pointer type, or use the appropriate getter for the correlation ID as defined in `common/DynaLog.hpp`).

3. If the same `DummyAuthManager` instance is reused across tests, ensure you clear `m_log_contexts` (e.g., via a `clearLogContexts()` helper) between test cases or create a fresh instance per test so that `logContexts().size()` is deterministic.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +186 to 195
struct curl_slist* headers = nullptr;

// safe: curl_slist_append copies the string internally
std::string header = "x-correlation-id: " + log_context.correlation_id;
headers = curl_slist_append(headers, header.c_str());

// attach headers to the CURL handle
curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers);

CURLcode res = curl_easy_perform(m_curl);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Reset CURLOPT_HTTPHEADER after freeing the curl_slist to avoid a dangling pointer in the CURL handle.

After curl_slist_free_all(headers), m_curl still has CURLOPT_HTTPHEADER set to the freed list. If this handle is reused and a request is performed before CURLOPT_HTTPHEADER is updated, libcurl may dereference freed memory.

To avoid that, clear the option after freeing:

CURLcode res = curl_easy_perform(m_curl);
curl_slist_free_all(headers);
headers = nullptr;
curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, nullptr);

This keeps the handle from holding a pointer to freed header data between requests.

Comment on lines +57 to 60
virtual void incrementKeyAccessCounter(const std::string &public_key, LogContext log_context) final;

/**
* This will purge all keys of a particular type that have expired.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): Consider passing LogContext by const reference instead of by value through the authentication APIs.

All public AuthenticationManager / IAuthenticationManager methods now take LogContext by value and forward it through to AuthMap and DatabaseAPI. To avoid repeated copies as LogContext grows, you could change these to accept const LogContext& instead and propagate that through the implementation and call sites, e.g.:

virtual void incrementKeyAccessCounter(const std::string &public_key, const LogContext &log_context) final;
virtual bool hasKey(const std::string &pub_key, const LogContext &log_context) const final;
virtual std::string getUID(const std::string &pub_key, const LogContext &log_context) const final;
std::string getUIDSafe(const std::string &pub_key, const LogContext &log_context) const;

Suggested implementation:

   *allotted purge time frame. If the count is above one then the session key
   *not be purged.
   **/
  virtual void incrementKeyAccessCounter(const std::string &public_key, const LogContext &log_context) final;

  /**
   * This will purge all keys of a particular type that have expired.
   * - SESSION
   * - PERSISTENT
   **/
  virtual bool hasKey(const std::string &pub_key, const LogContext &log_context) const final;

To fully implement the suggestion, you should also:

  1. Update all other AuthenticationManager / IAuthenticationManager method declarations in this header that currently take LogContext by value to instead take const LogContext & (e.g. getUID, getUIDSafe, and any similar methods).
  2. Update the corresponding method definitions in the .cpp files (e.g. AuthenticationManager.cpp, AuthMap.cpp, DatabaseAPI implementations) to match the new signatures (const LogContext &).
  3. Adjust all call sites that pass a LogContext to these methods so they pass by reference; typically no call-site syntax change is required, but ensure there are no temporary rvalues that would now bind to a const LogContext &.
  4. If there are overridden methods in derived classes, make sure their signatures are also updated to use const LogContext & so they still correctly override the interface.

* Methods only available via the interface
**/
virtual void incrementKeyAccessCounter(const std::string &pub_key) final {
virtual void incrementKeyAccessCounter(const std::string &pub_key, LogContext log_context) final {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Improve Operator/Authentication integration tests to validate LogContext usage and correlation-id generation

DummyAuthManager now accepts a LogContext, but the tests don't verify how it's used. Since AuthenticationOperator::execute generates a correlation ID and passes the same LogContext to hasKey, incrementKeyAccessCounter, and getUID, please enhance the tests to:

  • Have DummyAuthManager store the last LogContext it receives, and
  • Assert that execute() provides a non-empty correlation ID and reuses the same LogContext across all three calls.

This will validate the new wiring rather than just exercising the updated signature.

Suggested implementation:

  /**
   * Methods only available via the interface
   **/
  virtual void incrementKeyAccessCounter(const std::string &pub_key, LogContext log_context) final {
    ++m_counters.at(pub_key);
    m_log_contexts.push_back(log_context);
  }

  virtual bool hasKey(const std::string &pub_key, LogContext log_context) const {
    m_log_contexts.push_back(log_context);
    return m_counters.count(pub_key);
  }
  // Just assume all keys map to the anon_uid
  virtual std::string getUID(const std::string &, LogContext log_context) const {
    m_log_contexts.push_back(log_context);
    return "authenticated_uid";
  }

  const std::vector<LogContext> &logContexts() const {
    return m_log_contexts;
  }

To fully implement the test coverage you described, you will also need to:

  1. Add a member field to DummyAuthManager (in the same class where m_counters is defined):

    mutable std::vector<LogContext> m_log_contexts;

    Make sure the header <vector> is included if it is not already.

  2. In the relevant Operator/Authentication integration test that invokes AuthenticationOperator::execute(...) (or uses OperatorFactory to create the authentication operator with DummyAuthManager), add assertions such as:

    const auto &log_contexts = dummy_auth_manager.logContexts();
    ASSERT_EQ(log_contexts.size(), 3u); // hasKey, incrementKeyAccessCounter, getUID
    
    // All three calls must receive the same LogContext instance
    EXPECT_TRUE(log_contexts[0] == log_contexts[1]);
    EXPECT_TRUE(log_contexts[1] == log_contexts[2]);
    
    // And the correlation id must be non-empty
    const auto &ctx = log_contexts[0];
    // Adjust the accessor below to however correlation-id is exposed by LogContext
    EXPECT_FALSE(ctx.correlation_id().empty());

    If LogContext does not support operator== or correlation_id(), adapt the checks accordingly (for example, compare pointer identity if LogContext is a smart pointer type, or use the appropriate getter for the correlation ID as defined in common/DynaLog.hpp).

  3. If the same DummyAuthManager instance is reused across tests, ensure you clear m_log_contexts (e.g., via a clearLogContexts() helper) between test cases or create a fresh instance per test so that logContexts().size() is deterministic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant