feat(destination, agent-memory, core): support binding rotation in HTTP clients - #290
feat(destination, agent-memory, core): support binding rotation in HTTP clients#290cassiofariasmachado wants to merge 7 commits into
Conversation
…n in HTTP clients
c64beee to
b85c7cb
Compare
| ) from exc | ||
|
|
||
| return ConfigFactory( | ||
| module="hana-agent-memory", |
There was a problem hiding this comment.
I believe we already have some enum for telemetry, can we extract it to core and reuse?
|
Great solution! |
SDK Module Review
Findings (5)
5 finding(s): 5 posted as inline comment(s) on the affected lines, 0 not tied to a code line (listed above). Generated by sdk-review-skill · v1 |
| f"Request timed out: {method.value} {path}" | ||
| ) from exc | ||
| except RequestException as exc: | ||
| raise AgentMemoryHttpError( |
There was a problem hiding this comment.
[FLAG] PY-CON-01
String literal 'agentID' appears 3× — extract module-level constant
| ) from exc | ||
| except RequestException as exc: | ||
| raise AgentMemoryHttpError( | ||
| f"Request failed: {method.value} {path} — {exc}" |
There was a problem hiding this comment.
[FLAG] PY-CON-01
String literal 'invokerID' appears 3× — extract module-level constant
| except RequestException as exc: | ||
| raise AgentMemoryHttpError( | ||
| f"Request failed: {method.value} {path} — {exc}" | ||
| ) from exc |
There was a problem hiding this comment.
[FLAG] PY-CON-01
String literal 'content' appears 5× — extract module-level constant
| base_url = getattr(self._auth_provider, "base_url", None) or self._base_url | ||
| else: | ||
| if self._plain_session is None: | ||
| self._plain_session = requests.Session() |
There was a problem hiding this comment.
[FLAG] HTTP-01
HTTP session created per invocation — prefer single instance in init
| _DEFAULT_INSTANCE = "default" | ||
|
|
||
|
|
||
| def _build_destination_http( |
There was a problem hiding this comment.
[FLAG] PY-PT-08
Public function create_client missing type annotations: return type
Description
Introduces a shared
HttpClient+XsuaaAuthProviderlayer incore/that all service module transports compose. Solves a silent failure mode where long-lived clients hold frozen credentials — after a BTP secret rotation the old token expires and every call fails with 401 until the client is re-instantiated.Two layers of rotation resilience:
ConfigFactory.has_changed()checks the binding directory mtime before serving each cached token; on change it evicts the full token cache and re-reads credentials immediately.HttpClient.requestinvalidates the token cache entry and retries once on any 401 response.Migrates both
destinationandagent_memorymodules to composeHttpClientdirectly (removesHttpTransportfromagent_memory; replacesTokenProviderindestination). Rewrites unit test suites for both modules to use module-levelmock_httpfixtures and a_make_responsehelper.Related Issue
No linked issue.
Type of Change
How to Test
uv run pytest tests/agent_memory/— 248 passed, 12 skippeduv run pytest tests/destination/— all passinguvx pre-commit run --all-files— all hooks pass (ruff-format, ruff-check, ty)Checklist
Breaking Changes
None.
AgentMemoryClientandDestinationClientpublic APIs are unchanged. InternalHttpTransportclass is removed but was never part of the public API.Additional Notes
auditloganddata_anonymizationmodules are out of scope for this PR and can adoptHttpClientin a follow-up.data_anonymizationuses mTLS and would need anMTlsAuthProviderimplementation.ConfigFactoryis generic (ConfigFactory[C]) and can be reused by any future module that needs binding re-read on rotation.