Skip to content

Utilities resource (status, headers, user) + §6.4 exception rename#3

Closed
MarketDataDev03 wants to merge 5 commits into
mainfrom
02_endopoint_v1_user
Closed

Utilities resource (status, headers, user) + §6.4 exception rename#3
MarketDataDev03 wants to merge 5 commits into
mainfrom
02_endopoint_v1_user

Conversation

@MarketDataDev03

Copy link
Copy Markdown
Collaborator

feat: Utilities resource (status, headers, user) + §6.4 exception rename

Branch 02_endopoint_v1_usermain · 1 commit · 36 files · +1373 / −169

Stacked on top of 01_endpoint_v1_markets_status. This description treats that
branch as the merge base — only the delta on top of it is described here.

Adds the second endpoint group: utilities with all three methods named in SDK requirements §1.2 / §2.2 — status, headers, user. Reuses the HTTP transport + wire-format pattern landed by the markets PR; introduces the small extensions needed to handle endpoints that live outside /v1/. Also wires validateOnStartup to actually call /user/, and aligns the exception subtype names with §6.4's Java idiom.

What's included

com.marketdata.sdk.utilities — the new resource

Method Endpoint Wire format Auth
client.utilities().status() GET /status/ parallel arrays (6 fields × N services) no
client.utilities().headers() GET /headers/ flat object with arbitrary keys yes (echoed redacted)
client.utilities().user() GET /user/ flat object with @JsonProperty keys yes

All three live at the API root, not under /v1/ (a backend quirk: the user/status/headers viewsets are mounted on the admin router which binds to root). New domain types: UserInfo, ServiceStatus, ServiceHealth, RequestHeaders. Two new wire-format adapters — ServiceStatusDeserializer (parallel-arrays, mirrors the markets pattern) and RequestHeadersDeserializer (collapses arbitrary keys into a case-insensitive Map).

RequestSpec.getAtRoot(...) — small extension to the transport contract

RequestSpec gained a second factory next to get(...): paths built via getAtRoot(...) skip the /v1/ version prefix. HttpTransport.buildUri now reads the new versioned flag on the spec to decide. Default behavior unchanged for every endpoint that landed in 01 — only utilities uses the root path today.

validateOnStartup actually does something now

The flag existed in 01 as a seam. This PR wires it to call client.utilities().user() from the MarketDataClient constructor when enabled (default true) and a token is present — failing fast with AuthenticationException from the constructor if the token is invalid. The same call also seeds the rate-limit snapshot at boot per SDK requirements §8.1.

Exception subtype rename per §6.4

The 7 sealed subtypes of MarketDataException went from *Error (literal §6.1 names) to *Exception (Java idiom mandated by §6.4). The base class was already MarketDataException; this aligns the leaves with it. Error in Java has a specific JVM meaning ("don't catch this") that conflicted with our RuntimeException subtypes — the rename removes that signal mismatch.

Renamed: AuthenticationError → AuthenticationException, BadRequestError → BadRequestException, NotFoundError → NotFoundException, RateLimitError → RateLimitException, ServerError → ServerException, NetworkError → NetworkException, ParseError → ParseException. getSupportInfo() output's Type: line now reads RateLimitException instead of RateLimitError, which is what §6.4's Java example shows.

FAIL_ON_UNKNOWN_PROPERTIES = false

The shared ObjectMapper in HttpTransport is now configured to ignore unknown JSON properties. Found empirically when integration-testing /user/: the API returns the s status field on most endpoints, including ones whose canonical schema doesn't list it. Defaulting Jackson to lenient is the canonical posture for a long-lived SDK — when the API adds a new response field, existing consumers don't break. The custom deserializers (parallel-arrays decoders) handle their own validation explicitly anyway.

Tests

Suite Count Notes
ServiceStatusDeserializerTest 5 parallel-arrays edge cases (no_data, mismatched sizes, unknown s, allOnline logic)
RequestHeadersDeserializerTest 3 arbitrary-key parsing, lowercase normalization, case-insensitive lookup
UtilitiesResourceTest 11 full Resource → Transport → in-process HttpServer path, parameterized over sync/async for the load-bearing scenarios
MarketDataClientStartupValidationTest 4 the new validateOnStartup ctor behavior — 401 fails the build, demo mode skips, opt-out skips, success populates the rate-limit snapshot
MarketDataExceptionTest +1 new supportInfoRendersNAForMissingFields brings the package's branch coverage to 100 %
UtilitiesUserIT, UtilitiesStatusIT, UtilitiesHeadersIT 12 invocations one IT per method, parameterized SYNC/ASYNC against the live API

Existing tests (MarketsResourceTest, MarketDataClientTest, etc.) updated mechanically for the exception rename and to be robust against the presence of MARKETDATA_TOKEN in .env (relevant once the consumer-test app or local dev configures one).

Coverage at the merge gate

Metric Value
Lines 96.6 %
Methods 100 %
Branches 78.8 %

Codecov 5 pp ratchet vs base branch is satisfied (no regression).

@codecov

codecov Bot commented May 6, 2026

Copy link
Copy Markdown

The author of this PR, MarketDataDev03, is not an activated member of this organization on Codecov.
Please activate this user on Codecov to display this PR comment.
Coverage data is still being uploaded to Codecov.io for purposes of overall coverage calculations.
Please don't hesitate to email us at support@codecov.io with any questions.

@MarketDataDev03 MarketDataDev03 force-pushed the 01_endpoint_v1_markets_status branch 2 times, most recently from d617db2 to 63fc0a6 Compare May 11, 2026 17:47
Base automatically changed from 01_endpoint_v1_markets_status to main May 12, 2026 19:12
@MarketDataDev03 MarketDataDev03 deleted the 02_endopoint_v1_user branch June 9, 2026 18:56
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