From 7443373aa260e5b0d6df939bfb147f78f9bd0416 Mon Sep 17 00:00:00 2001 From: OmarAlJarrah Date: Wed, 8 Jul 2026 12:35:09 +0300 Subject: [PATCH] docs: simplify redundant KDoc across the SDK surface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trim docstring boilerplate that restated the code without adding information, and de-duplicate rationale that was copy-pasted across overloads. Comments only — no behavioral or API changes. - Collapse fluent builder-setter KDoc to one-line summaries: drop "@return This builder." and @param tags that only echoed the parameter name. Where a tag carried a real fact (a nullability note, an example value, a constraint, a @throws), fold it into the summary rather than dropping it. This brings the Response, Request, Headers, and IdempotencyKeyStep builders in line with the terse setter style the transport and options builders already use. - De-duplicate rationale repeated verbatim across sibling overloads (ClientLogger.at*, the Reactor/AsyncHttpPipeline send/execute pairs, the proxy-resolution source list) down to one canonical copy plus a cross-reference. - Remove facts stated two or three times within a single file, e.g. HttpException/NetworkException retryability and RequestRecoveryChain exception semantics. - Drop a stale reference to an internal planning file from the AuthChallengeParser KDoc. Deliberately preserved the SDK's design rationale (cancellation, thread-safety, equality, and spec-citation notes); the goal was to cut words, not information. Net ~360 fewer lines across 49 files. --- .../org/dexpace/sdk/async/reactor/Reactor.kt | 16 +-- .../sdk/core/auth/AuthChallengeParser.kt | 3 +- .../dexpace/sdk/core/auth/AuthRequirement.kt | 8 +- .../org/dexpace/sdk/core/auth/BearerToken.kt | 4 +- .../sdk/core/auth/DigestChallengeHandler.kt | 9 +- .../org/dexpace/sdk/core/client/HttpClient.kt | 7 +- .../sdk/core/generics/BuilderChecks.kt | 2 - .../dexpace/sdk/core/http/common/Headers.kt | 48 +------- .../dexpace/sdk/core/http/common/HttpRange.kt | 9 +- .../dexpace/sdk/core/http/common/MediaType.kt | 7 +- .../sdk/core/http/context/RequestContext.kt | 11 +- .../core/http/pipeline/AsyncHttpPipeline.kt | 9 +- .../http/pipeline/AsyncHttpPipelineBuilder.kt | 9 +- .../core/http/pipeline/HttpPipelineBuilder.kt | 15 ++- .../pipeline/steps/BearerTokenAuthStep.kt | 13 +- .../sdk/core/http/request/FileRequestBody.kt | 7 +- .../dexpace/sdk/core/http/request/Request.kt | 112 ++---------------- .../sdk/core/http/request/RequestBody.kt | 5 - .../sdk/core/http/response/ParsedResponse.kt | 7 -- .../sdk/core/http/response/Response.kt | 97 +++------------ .../sdk/core/http/response/ResponseBody.kt | 9 +- .../core/http/response/ResponseExtensions.kt | 5 - .../sdk/core/http/response/ResponseHandler.kt | 2 - .../http/response/exception/HttpException.kt | 5 - .../response/exception/NetworkException.kt | 6 +- .../sdk/core/instrumentation/ClientLogger.kt | 20 +--- .../instrumentation/DroppedHeaderLogging.kt | 5 +- .../sdk/core/instrumentation/HttpTracer.kt | 10 -- .../instrumentation/InstrumentationContext.kt | 24 ++-- .../NoopInstrumentationContext.kt | 4 +- .../sdk/core/instrumentation/UrlRedactor.kt | 2 - .../metrics/DoubleHistogram.kt | 5 +- .../sdk/core/instrumentation/metrics/Meter.kt | 18 ++- .../sdk/core/pagination/CloseablePages.kt | 12 +- .../pagination/CursorPaginationStrategy.kt | 3 +- .../sdk/core/pipeline/RequestRecoveryChain.kt | 6 +- .../sdk/core/pipeline/ResponseOutcome.kt | 2 - .../core/pipeline/step/ClientIdentityStep.kt | 2 - .../core/pipeline/step/IdempotencyKeyStep.kt | 35 +----- .../sdk/core/pipeline/step/PipelineStep.kt | 7 +- .../pipeline/step/ResponseRecoveryStep.kt | 3 - .../pipeline/step/retry/RetryAfterParser.kt | 16 ++- .../dexpace/sdk/core/serde/SerdeException.kt | 12 +- .../org/dexpace/sdk/core/util/Futures.kt | 5 +- .../org/dexpace/sdk/core/util/ProxyOptions.kt | 12 +- .../dexpace/sdk/core/util/ValueEquality.kt | 10 +- .../dexpace/sdk/serde/jackson/JacksonSerde.kt | 3 +- .../sdk/transport/jdkhttp/JdkHttpTransport.kt | 2 - .../jdkhttp/internal/BodyPublishers.kt | 24 ++-- 49 files changed, 153 insertions(+), 514 deletions(-) diff --git a/sdk-async-reactor/src/main/kotlin/org/dexpace/sdk/async/reactor/Reactor.kt b/sdk-async-reactor/src/main/kotlin/org/dexpace/sdk/async/reactor/Reactor.kt index 9bd772cd..93f6a06e 100644 --- a/sdk-async-reactor/src/main/kotlin/org/dexpace/sdk/async/reactor/Reactor.kt +++ b/sdk-async-reactor/src/main/kotlin/org/dexpace/sdk/async/reactor/Reactor.kt @@ -59,18 +59,10 @@ public fun AsyncHttpClient.executeMono( ): Mono = deferMono { executeAsync(request, options) } /** - * Pipeline-level [Mono] facade — see [executeMono]. - * - * ## MDC propagation - * - * The SLF4J MDC is captured **per subscription**, not at assembly time: the [Mono.defer] - * wrapper snapshots MDC the moment a subscriber subscribes, so each subscription reinstates - * the *subscriber's* `trace.id` / `span.id` — both in the [AsyncHttpPipeline.sendAsync] - * supplier and in the adapter's own `.doOnSubscribe` / `.doOnCancel` hooks, even when those - * fire on a different scheduler. A `Mono` assembled once and re-subscribed therefore picks - * up the MDC live at each subscribe, not a stale snapshot from the assembling thread. - * To extend MDC propagation through user-supplied downstream operators, enable - * `Hooks.enableAutomaticContextPropagation()` at the application level. + * Pipeline-level [Mono] facade — see [executeMono]. Same cold-publisher and + * per-subscription MDC semantics: each subscription reinstates the subscriber's + * `trace.id` / `span.id` for the [AsyncHttpPipeline.sendAsync] supplier and the + * `.doOnSubscribe` / `.doOnCancel` hooks. */ public fun AsyncHttpPipeline.sendMono(request: Request): Mono = deferMono { sendAsync(request) } diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/AuthChallengeParser.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/AuthChallengeParser.kt index fb800fb8..2e7aad66 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/AuthChallengeParser.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/AuthChallengeParser.kt @@ -24,8 +24,7 @@ import java.util.Locale * delimiters. Escape sequences (`\"`, `\\`) inside quoted strings are unescaped on * read; surrounding quotes are stripped from the stored value. * - * Malformed challenges are skipped — the parser does not throw on bad input. This - * matches the [edge-case guardrails][to-implement.md] for Rank 12. + * Malformed challenges are skipped — the parser does not throw on bad input. */ public object AuthChallengeParser { // Initial capacity for the per-challenge auth-param map. Auth challenges typically diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/AuthRequirement.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/AuthRequirement.kt index c8911c3c..5c43c3d7 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/AuthRequirement.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/AuthRequirement.kt @@ -11,8 +11,8 @@ import org.dexpace.sdk.core.generics.Builder as GenericBuilder /** * A single auth alternative an operation accepts: one [AuthScheme] plus any OAuth-specific - * parameters ([oauthScopes] / [oauthParams]) the auth step should forward to the token - * provider when the chosen scheme is [AuthScheme.OAUTH2]. + * parameters ([oauthScopes] / [oauthParams], e.g. `claims`) the auth step should forward to + * the token provider when the chosen scheme is [AuthScheme.OAUTH2]. * * Each requirement pairs a scheme with its *own* OAuth parameters, so an operation that * accepts OAuth with `read` scopes **or** a static API key is two requirements, only one of @@ -27,10 +27,6 @@ import org.dexpace.sdk.core.generics.Builder as GenericBuilder * copy), so a caller that retains and later mutates the argument collection cannot mutate this * instance. * Instances are obtained via [of] or [Builder], never a public constructor. - * - * @param scheme the auth scheme this alternative selects. - * @param oauthScopes OAuth scopes to forward to the token provider; ignored for non-OAuth schemes. - * @param oauthParams extra OAuth params to forward (e.g. `claims`); ignored for non-OAuth schemes. */ public class AuthRequirement private constructor( scheme: AuthScheme, diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/BearerToken.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/BearerToken.kt index 15a13ea8..2e061aa8 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/BearerToken.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/BearerToken.kt @@ -18,8 +18,8 @@ import java.time.Instant * pre-emptively refresh by passing a `marginBefore` to [isExpiredAt] — useful for avoiding * mid-flight expiries during long requests. * - * Value semantics via `data class` so equal tokens compare equal and can be diffed by - * tests cheaply. + * Value semantics via `data class` gives value-based [equals]/[hashCode], so tokens diff + * cheaply in tests. * * @param token the bearer token string; must not be blank. * @param expiresAt the instant the token becomes invalid, or null for a non-expiring token. diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/DigestChallengeHandler.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/DigestChallengeHandler.kt index d6894459..66db9a15 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/DigestChallengeHandler.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/auth/DigestChallengeHandler.kt @@ -95,12 +95,9 @@ public class DigestChallengeHandler * absent (legacy RFC 2069 style — we'll still handle it), * - it carries a `realm` and `nonce`. * - * Ordering: we scan [preferredAlgorithms] first, then within that scan the - * candidates. This ensures SHA-256 wins over MD5 even when MD5 appears first - * in the header. - * - * Per-challenge validation is delegated to [toCandidate]; this scan only applies - * the algorithm-priority ordering, independent of the order challenges arrived in. + * Per-challenge validation is delegated to [toCandidate]. This scan then applies + * the [preferredAlgorithms] priority ordering — independent of the order challenges + * arrived in — so SHA-256 wins over MD5 even when MD5 appears first in the header. */ private fun pickChallenge( challenges: List, diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/client/HttpClient.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/client/HttpClient.kt index 3277872a..edd97502 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/client/HttpClient.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/client/HttpClient.kt @@ -73,10 +73,9 @@ public fun interface HttpClient : AutoCloseable { ): Response = execute(request) /** - * Releases any resources held by this transport. The default implementation is a no-op so - * SAM literals and lightweight client wrappers do not need to implement [AutoCloseable.close] - * explicitly. Transport implementations that own background threads, connection pools, or - * executors must override this method; see the class-level "Lifecycle" KDoc for the contract. + * Releases any resources held by this transport. The default is a no-op (so SAM literals and + * lightweight wrappers need not implement it); transports that own threads, pools, or executors + * must override it — see the class-level "Lifecycle" KDoc for the contract. */ public override fun close() { // No-op default. Transports with owned resources override this. diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/generics/BuilderChecks.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/generics/BuilderChecks.kt index 25b66cdd..89d38c3b 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/generics/BuilderChecks.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/generics/BuilderChecks.kt @@ -30,8 +30,6 @@ package org.dexpace.sdk.core.generics * across builders with this helper keeps the missing-field diagnostics identical, which * matters most once builders are emitted by codegen. * - * @param name The field name to report in the failure message. - * @param value The field value to validate. * @return [value], guaranteed non-null. * @throws IllegalStateException If [value] is `null`. */ diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/Headers.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/Headers.kt index 800df656..5632f12a 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/Headers.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/Headers.kt @@ -38,7 +38,6 @@ public data class Headers private constructor( * Returns the first header value for the given name, or null if none. * * @param name the header name (case-insensitive) - * @return the first header value, or null if not found */ public fun get(name: String): String? = headersMap[sanitizeName(name)]?.firstOrNull() @@ -71,24 +70,19 @@ public data class Headers private constructor( public fun contains(name: HttpHeaderName): Boolean = headersMap.containsKey(name.caseInsensitiveName) /** - * Returns a point-in-time snapshot of all header names at the time of the call. + * Returns a snapshot of all header names. * - * Returns a defensive copy (`Set`) so that callers cannot observe later - * mutations to this [Headers] instance through the returned set. The set is exposed - * through Kotlin's read-only [Set] type. - * - * @return a snapshot of header names + * A defensive copy (`Set`) exposed through Kotlin's read-only [Set] type, so + * callers cannot observe later mutations to this [Headers] instance through it. */ public fun names(): Set = headersMap.keys.toSet() /** - * Returns a point-in-time snapshot of all header entries at the time of the call. + * Returns a snapshot of all header entries. * * Each entry is copied into a fresh map so that callers cannot observe later mutations * to this [Headers] instance through the returned set. The set and its per-name value * lists are exposed through Kotlin's read-only [Set] / [List] types. - * - * @return a snapshot of header entries as [Map.Entry] */ public fun entries(): Set>> { val snapshot = LinkedHashMap>(headersMap.size) @@ -98,11 +92,7 @@ public data class Headers private constructor( return snapshot.entries } - /** - * Returns a new [Builder] initialized with the existing headers. - * - * @return a new [Builder] - */ + /** Returns a new [Builder] initialized with the existing headers. */ public fun newBuilder(): Builder = Builder(this) override fun toString(): String = headersMap.toString() @@ -120,8 +110,6 @@ public data class Headers private constructor( /** * Creates a new builder initialized with the headers from [headers]. - * - * @param headers the headers to initialize from */ public constructor(headers: Headers) : this() { headers.headersMap.forEach { (key, values) -> @@ -132,10 +120,6 @@ public data class Headers private constructor( /** * Adds a header with the specified name and value. * Multiple headers with the same name are allowed. - * - * @param name the header name - * @param value the header value - * @return this builder */ public fun add( name: String, @@ -144,10 +128,6 @@ public data class Headers private constructor( /** * Adds all header values for the specified name. - * - * @param name the header name - * @param values the list of header values - * @return this builder */ public fun add( name: String, @@ -175,7 +155,6 @@ public data class Headers private constructor( * * @param name the header name * @param value the header value, which may contain non-ASCII bytes - * @return this builder * @throws IllegalArgumentException if [name] is blank or contains a control/non-ASCII byte, * or [value] contains a prohibited control character */ @@ -213,10 +192,6 @@ public data class Headers private constructor( * Sets the header with the specified name to the single value provided. * If headers with this name already exist, they are removed. Passing a `null` * [value] removes the header entirely (Azure / OkHttp semantics). - * - * @param name the header name - * @param value the header value, or `null` to remove - * @return this builder */ public fun set( name: String, @@ -233,10 +208,6 @@ public data class Headers private constructor( /** * Sets the header with the specified name to the values list provided. * If headers with this name already exist, they are removed. - * - * @param name the header name - * @param values the header values - * @return this builder */ public fun set( name: String, @@ -278,9 +249,6 @@ public data class Headers private constructor( /** * Removes any header with the specified name. - * - * @param name the header name - * @return this builder */ public fun remove(name: String): Builder = apply { @@ -309,11 +277,7 @@ public data class Headers private constructor( } } - /** - * Builds an immutable [Headers] instance. - * - * @return the built [Headers] - */ + /** Builds an immutable [Headers] instance. */ public fun build(): Headers { // Deep, defensive copy: snapshot each value list into its own fresh copy so // that later builder mutations cannot reach into the built instance. The diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/HttpRange.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/HttpRange.kt index 0a922056..fa41280d 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/HttpRange.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/HttpRange.kt @@ -78,13 +78,8 @@ public class HttpRange private constructor(private val raw: String) { } /** - * Parses a `Range` header value into an [HttpRange]. The accepted value is stored - * verbatim and round-trips through [toHeaderValue] unchanged, so its exact casing is - * preserved on the wire. - * - * The value must begin with the `bytes=` unit token (matched case-insensitively, with no - * leading whitespace); only the `bytes` unit is accepted, and multi-range values are - * rejected. + * Parses a `Range` header value into an [HttpRange], storing it verbatim so its casing + * round-trips through [toHeaderValue] (see the class KDoc for the accepted-form contract). * * @throws IllegalArgumentException if the value does not begin with the `bytes=` unit * token or contains a comma (multi-range). diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/MediaType.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/MediaType.kt index 12a5ed29..c9b5dc43 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/MediaType.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/common/MediaType.kt @@ -71,9 +71,9 @@ public data class MediaType private constructor( * in a try/catch. * * The lookup is case-insensitive: `UTF-8`, `utf-8`, and `Utf-8` all resolve to the same - * [Charset]. The parameter value is lower-cased before being passed to [Charset.forName], - * normalising the cache key. The JDK accepts any case, but lowercasing here ensures a - * consistent canonical form for comparison and logging purposes. + * [Charset]. The value is lower-cased before [Charset.forName] — the JDK accepts any case, + * but a canonical lower-case form normalises the cache key and keeps comparison and logging + * consistent. */ val charset: Charset? get() = @@ -222,7 +222,6 @@ public data class MediaType private constructor( * Parses a media type string into a [MediaType]. * * @param mediaType the wire-form value (e.g. `application/json;charset=utf-8`). - * @return the parsed [MediaType]. * @throws IllegalArgumentException if the media type cannot be parsed. */ @JvmStatic diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/context/RequestContext.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/context/RequestContext.kt index 9effc0e3..df627ae3 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/context/RequestContext.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/context/RequestContext.kt @@ -17,12 +17,11 @@ import org.dexpace.sdk.core.instrumentation.InstrumentationContext * promotes this into an [ExchangeContext]. Inherits the chain's [callKey] from the * [DispatchContext] it was promoted from. * - * In the normal flow the [callKey] is supplied by [DispatchContext.toRequestContext] so the - * whole chain shares one store slot. When this context is constructed directly off-chain it - * defaults to a freshly generated, call-unique key (`traceId:spanId:n`) via - * [DispatchContext.generateCallKey] — see [DispatchContext] for why the trace/span pair alone is not - * a collision-safe store key. One consequence of the generated default: two default-constructed - * instances are not structurally equal, since each generates a distinct key — pin an explicit + * In the normal flow the [callKey] is supplied by [DispatchContext.toRequestContext] so the whole + * chain shares one store slot. When constructed directly off-chain, [callKey] defaults to a fresh + * call-unique key (`traceId:spanId:n`) via [DispatchContext.generateCallKey] — see [DispatchContext] + * for why the trace/span pair alone is not a collision-safe key. Because each default generates a + * distinct key, two default-constructed instances are not structurally equal; pin an explicit * [callKey] if you need equality. * * @property operationName Optional schema-defined operation id (e.g. `"GetUser"`) for this call, diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/AsyncHttpPipeline.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/AsyncHttpPipeline.kt index 6774cba9..9c2a340d 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/AsyncHttpPipeline.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/AsyncHttpPipeline.kt @@ -94,11 +94,10 @@ public class AsyncHttpPipeline internal constructor( /** * Runs [request] through the pipeline with per-call [options] applied, then maps the response - * with [handler], returning the typed result. Combines the per-call [options] threading of - * [sendAsync]`(request, options)` with the terminal mapping of [sendAsync]`(request, handler)`; - * equivalent to `sendAsync(request, options).handleWith(handler)`. On success the handler's value - * completes the future and the response is closed; on failure the future is failed with the - * unwrapped cause. See [handleWith] for the exact semantics. + * with [handler]. Combines the per-call [options] threading of [sendAsync]`(request, options)` + * with the terminal mapping of [sendAsync]`(request, handler)`; equivalent to + * `sendAsync(request, options).handleWith(handler)`. See [handleWith] for the success/failure + * and response-close semantics. */ public fun sendAsync( request: Request, diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/AsyncHttpPipelineBuilder.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/AsyncHttpPipelineBuilder.kt index 2c336a8b..e8ef194b 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/AsyncHttpPipelineBuilder.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/AsyncHttpPipelineBuilder.kt @@ -35,12 +35,9 @@ public class AsyncHttpPipelineBuilder(private val httpClient: AsyncHttpClient) { /** * Seeds a new builder from [pipeline] by **flattening** it: [pipeline]'s steps become this - * builder's steps and its transport becomes this builder's terminal transport (identical to - * [from]). Prefer this over the generic [AsyncHttpClient] transport constructor whenever the - * argument is an [AsyncHttpPipeline] — the transport constructor would instead **nest** the - * pipeline as an opaque transport, running the outer steps outside the inner pipeline's - * retry / auth loops. Because [AsyncHttpPipeline] is more specific than [AsyncHttpClient], - * `AsyncHttpPipelineBuilder(pipeline)` resolves to this flattening constructor. + * builder's steps and its transport its terminal transport (identical to [from]). Overload + * resolution already picks this constructor for a statically-typed [AsyncHttpPipeline]; see the + * primary constructor KDoc for the flatten-vs-nest distinction. */ public constructor(pipeline: AsyncHttpPipeline) : this(pipeline.httpClient) { steps.reload(pipeline.steps) diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/HttpPipelineBuilder.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/HttpPipelineBuilder.kt index 94becf22..53e9e0fe 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/HttpPipelineBuilder.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/HttpPipelineBuilder.kt @@ -43,11 +43,10 @@ public class HttpPipelineBuilder(private val httpClient: HttpClient) { /** * Seeds a new builder from [pipeline] by **flattening** it: [pipeline]'s steps become this * builder's steps and its transport becomes this builder's terminal transport (identical to - * [from]). Prefer this over the generic [HttpClient] transport constructor whenever the argument - * is an [HttpPipeline] — the transport constructor would instead **nest** the pipeline as an - * opaque transport, running the outer steps outside the inner pipeline's redirect / retry / auth - * loops. Because [HttpPipeline] is more specific than [HttpClient], `HttpPipelineBuilder(pipeline)` - * resolves to this flattening constructor. + * [from]). Prefer this over the generic [HttpClient] transport constructor when the argument + * is an [HttpPipeline]; that constructor would instead **nest** the pipeline (see the primary + * `@constructor` KDoc for the nesting hazard). Because [HttpPipeline] is more specific than + * [HttpClient], `HttpPipelineBuilder(pipeline)` resolves to this flattening constructor. */ public constructor(pipeline: HttpPipeline) : this(pipeline.httpClient) { steps.reload(pipeline.steps) @@ -63,9 +62,9 @@ public class HttpPipelineBuilder(private val httpClient: HttpClient) { public fun appendAll(batch: Iterable): HttpPipelineBuilder = apply { batch.forEach(::append) } /** - * Prepends every step in [batch] via [prepend], preserving iteration order. Note that - * because each call uses [prepend], the final relative ordering inside each stage is the - * reverse of [batch] — the last item ends up at the head. + * Prepends every step in [batch] via [prepend], preserving iteration order. Because each + * call uses [prepend], the final relative ordering inside each stage is the reverse of + * [batch] — the last item ends up at the head. */ public fun prependAll(batch: Iterable): HttpPipelineBuilder = apply { batch.forEach(::prepend) } diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/steps/BearerTokenAuthStep.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/steps/BearerTokenAuthStep.kt index 4518fd67..d4105705 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/steps/BearerTokenAuthStep.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/pipeline/steps/BearerTokenAuthStep.kt @@ -52,15 +52,10 @@ import kotlin.concurrent.withLock * method (the in-step hook is not gated by retry-safety), so a non-idempotent POST is * re-authenticated too. * - * Eviction only fires when the `WWW-Authenticate` header actually advertises a `Bearer` - * challenge. A 401 carrying only a non-bearer challenge (e.g. `Basic`) — or an unparseable - * one — is surfaced unchanged, because refreshing the bearer token would not satisfy it: the - * retry would just be rejected again, at the cost of a wasted token fetch and round trip. - * - * A request that reaches the challenge hook carrying **no** `Authorization` header is a - * cross-origin redirect re-issue whose credential the AUTH stage deliberately suppressed - * (see [CrossOriginRedirectMarker]). In that case the hook re-stamps nothing and surfaces the - * 401 unchanged, so the caller's token is never attached to a server-chosen foreign host. + * Eviction fires only for an actual `Bearer` challenge, and never for a credential-suppressed + * cross-origin redirect re-issue (see [CrossOriginRedirectMarker]); see + * [authorizeRequestOnChallenge] for the exact conditions under which the 401 is surfaced + * unchanged. * * ## Errors from [provider] * diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/FileRequestBody.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/FileRequestBody.kt index 7fa468be..54be4086 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/FileRequestBody.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/FileRequestBody.kt @@ -133,10 +133,9 @@ public class FileRequestBody * is open. Hold the buffer reference for as long as you need to read from it, and drop it * promptly to allow the OS to release the file/page mapping. * - * **Windows note.** On Windows, the file-backed mapping prevents exclusive open of the - * file (e.g. by other processes expecting exclusive access) while the mapping exists. - * Hold the returned [ByteBuffer] no longer than needed and allow it to become unreachable - * so the GC can release the mapping promptly. + * **Windows note.** On Windows the file-backed mapping additionally prevents exclusive open + * of the file (e.g. by other processes expecting exclusive access) while it exists — another + * reason to drop the buffer promptly. * * @throws IllegalStateException if [count] exceeds [Int.MAX_VALUE] (a single ByteBuffer * cannot address more than ~2 GiB). Map smaller slices manually for larger files. diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/Request.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/Request.kt index 61acc223..04424b65 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/Request.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/Request.kt @@ -75,11 +75,7 @@ public data class Request private constructor( return result } - /** - * Returns a new [RequestBuilder] initialized with this request's data. - * - * @return A new builder. - */ + /** Returns a new [RequestBuilder] initialized with this request's data. */ public fun newBuilder(): RequestBuilder = RequestBuilder(this) /** @@ -113,7 +109,6 @@ public data class Request private constructor( * Sets the HTTP method. * * @param method HTTP method, e.g., GET, POST. - * @return This builder. */ public fun method(method: Method): RequestBuilder = apply { @@ -128,7 +123,6 @@ public data class Request private constructor( * [build] rejects a non-`null` body ([Method.permitsRequestBody] is `false` for them). * * @param body The request body, or `null` to clear any previously-set body. - * @return This builder. */ public fun body(body: RequestBody?): RequestBuilder = apply { @@ -139,7 +133,6 @@ public data class Request private constructor( * Sets the URL from a string. * * @param url The URL as a string. - * @return This builder. * @throws IllegalArgumentException If [url] is not a valid URL. */ public fun url(url: String): RequestBuilder = @@ -155,7 +148,6 @@ public data class Request private constructor( * Sets the URL from a [URI]. Converts via [URI.toURL]. * * @param uri The URI to convert and set. - * @return This builder. * @throws IllegalArgumentException If [uri] cannot be converted to a URL. */ public fun url(uri: URI): RequestBuilder = @@ -176,20 +168,13 @@ public data class Request private constructor( * Sets the URL. * * @param url The URL as a [URL] object. - * @return This builder. */ public fun url(url: URL): RequestBuilder = apply { this.url = url } - /** - * Adds a header with the specified name and value. - * - * @param name The header name. - * @param value The header value. - * @return This builder. - */ + /** Adds a header with the specified name and value. */ public fun addHeader( name: String, value: String, @@ -198,13 +183,7 @@ public data class Request private constructor( headersBuilder.add(name, value) } - /** - * Adds a header with the specified name and values. - * - * @param name The header name. - * @param values The header values list. - * @return This builder. - */ + /** Adds a header with the specified name and values. */ public fun addHeader( name: String, values: List, @@ -213,13 +192,7 @@ public data class Request private constructor( headersBuilder.add(name, values) } - /** - * Sets a header with the specified name and value, replacing any existing values. - * - * @param name The header name. - * @param value The header value. - * @return This builder. - */ + /** Sets a header with the specified name and value, replacing any existing values. */ public fun setHeader( name: String, value: String, @@ -228,13 +201,7 @@ public data class Request private constructor( headersBuilder.set(name, value) } - /** - * Sets a header with the specified name and values list, replacing any existing values. - * - * @param name The header name. - * @param values The header values list. - * @return This builder. - */ + /** Sets a header with the specified name and values list, replacing any existing values. */ public fun setHeader( name: String, values: List, @@ -243,13 +210,7 @@ public data class Request private constructor( headersBuilder.set(name, values) } - /** - * Adds a header using a typed [HttpHeaderName] and a single value. - * - * @param name The typed header name. - * @param value The header value. - * @return This builder. - */ + /** Adds a header using a typed [HttpHeaderName] and a single value. */ public fun addHeader( name: HttpHeaderName, value: String, @@ -258,13 +219,7 @@ public data class Request private constructor( headersBuilder.add(name, value) } - /** - * Adds a header using a typed [HttpHeaderName] and a list of values. - * - * @param name The typed header name. - * @param values The header values. - * @return This builder. - */ + /** Adds a header using a typed [HttpHeaderName] and a list of values. */ public fun addHeader( name: HttpHeaderName, values: List, @@ -279,7 +234,6 @@ public data class Request private constructor( * * @param name The typed header name (e.g. [HttpHeaderName.CONTENT_TYPE]). * @param value The media type whose [MediaType.toString] form is used as the header value. - * @return This builder. */ public fun addHeader( name: HttpHeaderName, @@ -289,13 +243,7 @@ public data class Request private constructor( headersBuilder.add(name, value.toString()) } - /** - * Sets a header using a typed [HttpHeaderName] and a single value, replacing any existing values. - * - * @param name The typed header name. - * @param value The header value. - * @return This builder. - */ + /** Sets a header using a typed [HttpHeaderName] and a single value, replacing any existing values. */ public fun setHeader( name: HttpHeaderName, value: String, @@ -304,13 +252,7 @@ public data class Request private constructor( headersBuilder.set(name, value) } - /** - * Sets a header using a typed [HttpHeaderName] and a list of values, replacing any existing values. - * - * @param name The typed header name. - * @param values The header values. - * @return This builder. - */ + /** Sets a header using a typed [HttpHeaderName] and a list of values, replacing any existing values. */ public fun setHeader( name: HttpHeaderName, values: List, @@ -319,34 +261,19 @@ public data class Request private constructor( headersBuilder.set(name, values) } - /** - * Sets a complete Headers instance, replacing all other headers - * - * @param headers The [Headers] instance - * @return This builder. - */ + /** Sets a complete Headers instance, replacing all other headers. */ public fun headers(headers: Headers): RequestBuilder = apply { this.headersBuilder = headers.newBuilder() } - /** - * Removes all headers with the specified name. - * - * @param name The header name. - * @return This builder. - */ + /** Removes all headers with the specified name. */ public fun removeHeader(name: String): RequestBuilder = apply { headersBuilder.remove(name) } - /** - * Removes all headers with the specified typed name. - * - * @param name The typed header name. - * @return This builder. - */ + /** Removes all headers with the specified typed name. */ public fun removeHeader(name: HttpHeaderName): RequestBuilder = apply { headersBuilder.remove(name) @@ -368,8 +295,6 @@ public data class Request private constructor( /** * Sets the method to [Method.GET] and clears any previously-set body. Equivalent to * `method(Method.GET).body(null)`. - * - * @return This builder. */ public fun get(): RequestBuilder = verb(Method.GET, null) @@ -377,7 +302,6 @@ public data class Request private constructor( * Sets the method to [Method.POST] and the body to [body]. * * @param body The request body. - * @return This builder. */ public fun post(body: RequestBody): RequestBuilder = verb(Method.POST, body) @@ -385,7 +309,6 @@ public data class Request private constructor( * Sets the method to [Method.PUT] and the body to [body]. * * @param body The request body. - * @return This builder. */ public fun put(body: RequestBody): RequestBuilder = verb(Method.PUT, body) @@ -394,16 +317,12 @@ public data class Request private constructor( * `method(Method.DELETE).body(null)`. * * DELETE-with-body remains available explicitly via `.method(Method.DELETE).body(body)`. - * - * @return This builder. */ public fun delete(): RequestBuilder = verb(Method.DELETE, null) /** * Sets the method to [Method.HEAD] and clears any previously-set body. Equivalent to * `method(Method.HEAD).body(null)`. - * - * @return This builder. */ public fun head(): RequestBuilder = verb(Method.HEAD, null) @@ -411,7 +330,6 @@ public data class Request private constructor( * Sets the method to [Method.PATCH] and the body to [body]. * * @param body The request body. - * @return This builder. */ public fun patch(body: RequestBody): RequestBuilder = verb(Method.PATCH, body) @@ -468,7 +386,6 @@ public data class Request private constructor( * `builder().url(url).get().build()`. * * @param url The target URL string; throws [IllegalArgumentException] if invalid. - * @return A [Request] with method [Method.GET] and no body. */ @JvmStatic public fun get(url: String): Request = builder().url(url).get().build() @@ -479,7 +396,6 @@ public data class Request private constructor( * * @param url The target URL string; throws [IllegalArgumentException] if invalid. * @param body The request body. - * @return A [Request] with method [Method.POST] and the given [body]. */ @JvmStatic public fun post( @@ -493,7 +409,6 @@ public data class Request private constructor( * * @param url The target URL string; throws [IllegalArgumentException] if invalid. * @param body The request body. - * @return A [Request] with method [Method.PUT] and the given [body]. */ @JvmStatic public fun put( @@ -507,7 +422,6 @@ public data class Request private constructor( * * @param url The target URL string; throws [IllegalArgumentException] if invalid. * @param body The request body. - * @return A [Request] with method [Method.PATCH] and the given [body]. */ @JvmStatic public fun patch( @@ -520,7 +434,6 @@ public data class Request private constructor( * `builder().url(url).delete().build()`. * * @param url The target URL string; throws [IllegalArgumentException] if invalid. - * @return A [Request] with method [Method.DELETE] and no body. */ @JvmStatic public fun delete(url: String): Request = builder().url(url).delete().build() @@ -530,7 +443,6 @@ public data class Request private constructor( * `builder().url(url).head().build()`. * * @param url The target URL string; throws [IllegalArgumentException] if invalid. - * @return A [Request] with method [Method.HEAD] and no body. */ @JvmStatic public fun head(url: String): Request = builder().url(url).head().build() diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/RequestBody.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/RequestBody.kt index 868d5722..d997e3f8 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/RequestBody.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/request/RequestBody.kt @@ -196,11 +196,6 @@ public abstract class RequestBody { * explicit [mediaType] to override the content type for a given call without changing the * serde's default (e.g. when a single serde instance is shared across multiple endpoints * that agree on encoding but declare different `Content-Type` values). - * - * @param value The object to serialize. - * @param serde The serde whose [Serde.serializer] encodes [value] to wire bytes. - * @param mediaType The body's media type; defaults to [Serde.contentType]. - * @return A replayable body whose bytes are the [serde]-encoded form of [value]. */ @JvmStatic @JvmOverloads diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ParsedResponse.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ParsedResponse.kt index d2161d01..da6f949c 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ParsedResponse.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ParsedResponse.kt @@ -119,10 +119,6 @@ public class ParsedResponse internal constructor( /** * Creates a [ParsedResponse] that parses [response] with [handler] on first access. * Java-friendly factory mirroring the Kotlin [Response.parsedWith] extension. - * - * @param response The raw response. - * @param handler Strategy that maps the response to the typed value. - * @return A lazily-parsing [ParsedResponse]. */ @JvmStatic public fun of( @@ -136,8 +132,5 @@ public class ParsedResponse internal constructor( * Wraps this response in a [ParsedResponse] bound to [handler], so the typed value parses lazily * and exactly once while raw status / headers stay accessible. Kotlin-ergonomic mirror of * [ParsedResponse.of]. - * - * @param handler Strategy that maps this response to the typed value. - * @return A lazily-parsing [ParsedResponse]. */ public fun Response.parsedWith(handler: ResponseHandler): ParsedResponse = ParsedResponse(this, handler) diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/Response.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/Response.kt index c21f1a3a..652200b9 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/Response.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/Response.kt @@ -65,11 +65,7 @@ public data class Response private constructor( /** True when [status] is in the 4xx–5xx error range. */ public val isError: Boolean get() = status.isError - /** - * Returns a new [ResponseBuilder] initialized with this response's data. - * - * @return A new builder. - */ + /** Returns a new [ResponseBuilder] initialized with this response's data. */ public fun newBuilder(): ResponseBuilder = ResponseBuilder(this) /** @@ -115,57 +111,31 @@ public data class Response private constructor( this.body = response.body } - /** - * Sets the request that initiated this response. - * - * @param request The originating request. - * @return This builder. - */ + /** Sets the request that initiated this response. */ public fun request(request: Request): ResponseBuilder = apply { this.request = request } - /** - * Sets the protocol used for the response. - * - * @param protocol The protocol (e.g., HTTP/1.1). - * @return This builder. - */ + /** Sets the protocol used for the response (e.g., HTTP/1.1). */ public fun protocol(protocol: Protocol): ResponseBuilder = apply { this.protocol = protocol } - /** - * Sets the HTTP status code. - * - * @param status The HTTP status code. - * @return This builder. - */ + /** Sets the HTTP status code. */ public fun status(status: Status): ResponseBuilder = apply { this.status = status } - /** - * Sets the HTTP reason phrase. - * - * @param message The reason phrase. - * @return This builder. - */ + /** Sets the HTTP reason phrase. */ public fun message(message: String): ResponseBuilder = apply { this.message = message } - /** - * Adds a header with the specified name and value. - * - * @param name The header name. - * @param value The header value. - * @return This builder. - */ + /** Adds a header with the specified name and value. */ public fun addHeader( name: String, value: String, @@ -174,13 +144,7 @@ public data class Response private constructor( headersBuilder.add(name, value) } - /** - * Adds a header with the specified name and values list. - * - * @param name The header name. - * @param values The header values. - * @return This builder. - */ + /** Adds a header with the specified name and values list. */ public fun addHeader( name: String, values: List, @@ -189,13 +153,7 @@ public data class Response private constructor( headersBuilder.add(name, values) } - /** - * Sets a header with the specified name and value, replacing any existing values. - * - * @param name The header name. - * @param value The header value. - * @return This builder. - */ + /** Sets a header with the specified name and value, replacing any existing values. */ public fun setHeader( name: String, value: String, @@ -204,13 +162,7 @@ public data class Response private constructor( headersBuilder.set(name, value) } - /** - * Sets a header with the specified name and values list, replacing any existing values. - * - * @param name The header name. - * @param values The header values list. - * @return This builder. - */ + /** Sets a header with the specified name and values list, replacing any existing values. */ public fun setHeader( name: String, values: List, @@ -219,45 +171,25 @@ public data class Response private constructor( headersBuilder.set(name, values) } - /** - * Removes all headers with the specified name. - * - * @param name The header name. - * @return This builder. - */ + /** Removes all headers with the specified name. */ public fun removeHeader(name: String): ResponseBuilder = apply { headersBuilder.remove(name) } - /** - * Removes all headers with the specified typed name. - * - * @param name The typed header name. - * @return This builder. - */ + /** Removes all headers with the specified typed name. */ public fun removeHeader(name: HttpHeaderName): ResponseBuilder = apply { headersBuilder.remove(name) } - /** - * Sets the response headers. - * - * @param headers The response headers. - * @return This builder. - */ + /** Sets the response headers. */ public fun headers(headers: Headers): ResponseBuilder = apply { headersBuilder = headers.newBuilder() } - /** - * Sets the response body. - * - * @param body The response body, or null if none. - * @return This builder. - */ + /** Sets the response body, or null if none. */ public fun body(body: ResponseBody?): ResponseBuilder = apply { this.body = body @@ -266,8 +198,7 @@ public data class Response private constructor( /** * Builds the [Response]. * - * @return The built response. - * @throws IllegalStateException in case required fields are missing. + * @throws IllegalStateException when required fields are missing. */ override fun build(): Response = Response( diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseBody.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseBody.kt index 01ca8c78..537514e6 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseBody.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseBody.kt @@ -55,11 +55,8 @@ public abstract class ResponseBody : Closeable { public abstract fun contentLength(): Long /** - * Returns a [BufferedSource] to read the response body. - * - * Note: The source can be read only once. Multiple calls will return the same source. - * - * @return The buffered source. + * Returns a [BufferedSource] to read the response body. The source can be read only + * once; every call returns the same source. */ public abstract fun source(): BufferedSource @@ -118,10 +115,8 @@ public abstract class ResponseBody : Closeable { * (single underlying [BufferedSource]); wrap with `LoggableResponseBody` for * repeatable reads. * - * @param source The buffered source to read from. * @param contentLength The length of the content, or `-1` if unknown. * @param mediaType The media type, or `null` if unknown. - * @return A new [ResponseBody] instance. */ @JvmStatic @JvmOverloads diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseExtensions.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseExtensions.kt index 669006e4..cb081374 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseExtensions.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseExtensions.kt @@ -102,9 +102,7 @@ internal fun bufferErrorBody( * thrown by the deserializer are logged at DEBUG and swallowed rather than propagated; this * function never throws. * - * @param deserializer The deserializer to apply. * @param type The target class token required for runtime type dispatch. - * @return The decoded payload, or `null` if the body is absent or decoding fails. */ public fun HttpException.bodyAs( deserializer: Deserializer, @@ -130,7 +128,6 @@ public fun HttpException.bodyAs( * * @param serde The [Serde] bundle whose [Serde.deserializer] is used for decoding. * @param type The target class token required for runtime type dispatch. - * @return The decoded value. * @throws SerdeException if the response body is `null`. */ public fun Response.deserialize( @@ -157,7 +154,6 @@ public fun Response.deserialize( * * @param serde The [Serde] bundle whose [Serde.deserializer] is used for decoding. * @param ref The captured generic target type. - * @return The decoded value. * @throws IllegalStateException if the response body is `null`. */ public fun Response.deserialize( @@ -183,7 +179,6 @@ public fun Response.deserialize( * so it requires a [serde] that resolves generics for a parametric `T`. * * @param serde The [Serde] bundle whose deserializer is used for decoding. - * @return The decoded value. * @throws SerdeException if the response body is `null`. */ public inline fun Response.deserialize(serde: Serde): T = deserialize(serde, object : TypeRef() {}) diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseHandler.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseHandler.kt index f973a327..f9d2d085 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseHandler.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/ResponseHandler.kt @@ -52,8 +52,6 @@ public fun interface ResponseHandler { * Consumes [response] and produces the typed result. Implementations that read the body must * also close [response] before returning. * - * @param response The raw response to map. - * @return The typed result. * @throws IOException If reading the body fails. */ @Throws(IOException::class) diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/exception/HttpException.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/exception/HttpException.kt index 2e090438..b2d1b73e 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/exception/HttpException.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/exception/HttpException.kt @@ -88,11 +88,6 @@ public abstract class HttpException value: Any?, ) : this(response.status, response.headers, response.body, message, cause, value) - /** - * Whether this exception represents a retryable condition. Derived from - * [RetryUtils.isRetryable] over [status]'s code so it can never disagree with the - * live retry policy. - */ override val isRetryable: Boolean = RetryUtils.isRetryable(status.code) /** diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/exception/NetworkException.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/exception/NetworkException.kt index b1a259e0..4453fe64 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/exception/NetworkException.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/http/response/exception/NetworkException.kt @@ -38,10 +38,6 @@ public open class NetworkException message: String? = null, cause: Throwable? = null, ) : IOException(message, cause), Retryable { - /** - * Whether this exception represents a retryable condition. Always `true` for - * `NetworkException` — transport failures with no response are by definition - * transient at the SDK level. - */ + /** Always `true`; see the class-level `## Retryability` section. */ override val isRetryable: Boolean = true } diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/ClientLogger.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/ClientLogger.kt index 785743d3..6c6c9d18 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/ClientLogger.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/ClientLogger.kt @@ -109,28 +109,16 @@ public class ClientLogger private constructor( public val DEFAULT_MDC_KEYS: Set = setOf("trace.id", "span.id") } - /** - * Returns a [LoggingEvent] at [LogLevel.ERROR]. Returns [LoggingEvent.NOOP] (shared singleton, - * zero allocation) when the underlying SLF4J `ERROR` level is disabled. - */ + /** Returns a [LoggingEvent] at [LogLevel.ERROR] (SLF4J `ERROR`); see the class KDoc for the disabled-level NOOP fast path. */ public fun atError(): LoggingEvent = LoggingEvent.create(this, LogLevel.ERROR) - /** - * Returns a [LoggingEvent] at [LogLevel.WARNING]. Returns [LoggingEvent.NOOP] (shared singleton, - * zero allocation) when the underlying SLF4J `WARN` level is disabled. - */ + /** Returns a [LoggingEvent] at [LogLevel.WARNING] (SLF4J `WARN`); see the class KDoc for the disabled-level NOOP fast path. */ public fun atWarning(): LoggingEvent = LoggingEvent.create(this, LogLevel.WARNING) - /** - * Returns a [LoggingEvent] at [LogLevel.INFO]. Returns [LoggingEvent.NOOP] (shared singleton, - * zero allocation) when the underlying SLF4J `INFO` level is disabled. - */ + /** Returns a [LoggingEvent] at [LogLevel.INFO] (SLF4J `INFO`); see the class KDoc for the disabled-level NOOP fast path. */ public fun atInfo(): LoggingEvent = LoggingEvent.create(this, LogLevel.INFO) - /** - * Returns a [LoggingEvent] at [LogLevel.VERBOSE]. Returns [LoggingEvent.NOOP] (shared singleton, - * zero allocation) when the underlying SLF4J `DEBUG` level is disabled. - */ + /** Returns a [LoggingEvent] at [LogLevel.VERBOSE] (SLF4J `DEBUG`); see the class KDoc for the disabled-level NOOP fast path. */ public fun atVerbose(): LoggingEvent = LoggingEvent.create(this, LogLevel.VERBOSE) /** diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/DroppedHeaderLogging.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/DroppedHeaderLogging.kt index a61b11a4..10d3f2f5 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/DroppedHeaderLogging.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/DroppedHeaderLogging.kt @@ -21,9 +21,8 @@ package org.dexpace.sdk.core.instrumentation * pre-drop of a known restricted header the transport recomputes (`Host`, `Content-Length`, …) * always logs at verbose regardless of this setting. * - * Note that the log *level* remains the operator's to filter through their SLF4J backend; this - * policy chooses the level (and dedup) the transport emits at, which a log level alone cannot - * express. + * The log *level* remains the operator's to filter through their SLF4J backend; this policy + * chooses the level (and dedup) the transport emits at, which a log level alone cannot express. */ public enum class DroppedHeaderLogging { /** diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/HttpTracer.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/HttpTracer.kt index d004ff47..c55872bf 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/HttpTracer.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/HttpTracer.kt @@ -77,8 +77,6 @@ public interface HttpTracer { /** * Attempt started — fired at the beginning of each network attempt. The first attempt * is `1`; subsequent retries are `2`, `3`, …. - * - * @param attemptNumber 1-based attempt counter. */ public fun attemptStarted(attemptNumber: Int) {} @@ -109,8 +107,6 @@ public interface HttpTracer { * Request URL resolved — fired after pipeline steps (path templating, query * parameters, endpoint resolution) have produced the final URL that will be put on * the wire. Useful for retry redaction policies and per-host metrics. - * - * @param url The resolved request URL. */ public fun requestUrlResolved(url: String) {} @@ -126,9 +122,6 @@ public interface HttpTracer { * Response headers received — fired as soon as the response status line and headers * are available, before the body is consumed. Useful for time-to-first-byte metrics * and for early routing decisions in tracer policies. - * - * @param status HTTP status code. - * @param headers Response headers. */ public fun responseHeadersReceived( status: Int, @@ -147,9 +140,6 @@ public interface HttpTracer { * Connection acquired — fired when the transport obtains a connection for this * attempt, whether freshly opened or pulled from the pool. Useful for pool-saturation * dashboards. - * - * @param host Resolved host. - * @param port Resolved port. */ public fun connectionAcquired( host: String, diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/InstrumentationContext.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/InstrumentationContext.kt index 7b00cb63..d5c87610 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/InstrumentationContext.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/InstrumentationContext.kt @@ -71,9 +71,9 @@ public value class TraceId(public val value: String) { /** * Sentinel "invalid" trace id — 32 hex zeros, matching the W3C spec reserved value. * - * Exposed as `@JvmStatic` rather than `@JvmField`: Kotlin disallows `@JvmField` - * on inline-class typed properties even though the JVM representation is just a - * `String`. Java callers reach this via `TraceId.getNOOP()`. + * `@JvmStatic`, not `@JvmField` — Kotlin disallows `@JvmField` on inline-class-typed + * properties even though the JVM representation is just a `String`; Java callers use + * `TraceId.getNOOP()`. */ @JvmStatic public val NOOP: TraceId = TraceId("00000000000000000000000000000000") @@ -92,9 +92,9 @@ public value class SpanId(public val value: String) { * Sentinel "invalid" span id — 16 hex zeros, used when tracing is disabled or no * valid span is in scope. * - * Exposed as `@JvmStatic` rather than `@JvmField`: Kotlin disallows `@JvmField` - * on inline-class typed properties even though the JVM representation is just a - * `String`. Java callers reach this via `SpanId.getNOOP()`. + * `@JvmStatic`, not `@JvmField` — Kotlin disallows `@JvmField` on inline-class-typed + * properties even though the JVM representation is just a `String`; Java callers use + * `SpanId.getNOOP()`. */ @JvmStatic public val NOOP: SpanId = SpanId("0000000000000000") @@ -111,9 +111,9 @@ public value class TraceFlags(public val value: String) { /** * Sentinel "no flags set" trace-flags value — the W3C unsampled `"00"` byte. * - * Exposed as `@JvmStatic` rather than `@JvmField`: Kotlin disallows `@JvmField` - * on inline-class typed properties even though the JVM representation is just a - * `String`. Java callers reach this via `TraceFlags.getNOOP()`. + * `@JvmStatic`, not `@JvmField` — Kotlin disallows `@JvmField` on inline-class-typed + * properties even though the JVM representation is just a `String`; Java callers use + * `TraceFlags.getNOOP()`. */ @JvmStatic public val NOOP: TraceFlags = TraceFlags("00") @@ -131,9 +131,9 @@ public value class TraceState(public val value: String) { /** * Sentinel "empty" trace state — no vendor-specific entries. * - * Exposed as `@JvmStatic` rather than `@JvmField`: Kotlin disallows `@JvmField` - * on inline-class typed properties even though the JVM representation is just a - * `String`. Java callers reach this via `TraceState.getNOOP()`. + * `@JvmStatic`, not `@JvmField` — Kotlin disallows `@JvmField` on inline-class-typed + * properties even though the JVM representation is just a `String`; Java callers use + * `TraceState.getNOOP()`. */ @JvmStatic public val NOOP: TraceState = TraceState("") diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/NoopInstrumentationContext.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/NoopInstrumentationContext.kt index 75d1a95a..a63439cd 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/NoopInstrumentationContext.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/NoopInstrumentationContext.kt @@ -9,9 +9,7 @@ package org.dexpace.sdk.core.instrumentation /** * No-operation [InstrumentationContext] used as the default or fallback when tracing is - * disabled. Every identifier resolves to its `NOOP` sentinel: the trace id is the W3C - * reserved all-zero value, the span id is sixteen zero hex chars, trace flags are `"00"`, - * and the trace state is empty. + * disabled. Every identifier resolves to its `NOOP` sentinel (see each property below). * * Shipped as a Kotlin `object` so the instance is shared process-wide with no allocation. */ diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/UrlRedactor.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/UrlRedactor.kt index 48da0af2..e5d25e97 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/UrlRedactor.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/UrlRedactor.kt @@ -58,7 +58,6 @@ public object UrlRedactor { /** * Returns a loggable URL string with userinfo and disallowed query values redacted. * - * @param url the URL to redact; must not be null. * @param allowedQueryParams query parameter names (case-insensitive, decoded form) whose * values should be kept. Empty set means redact every query value. */ @@ -94,7 +93,6 @@ public object UrlRedactor { * an OAuth authorization code, a pre-signed request signature, or an implicit-flow access token. * The value is therefore never logged verbatim while the host/path stays visible for diagnostics. * - * @param value the raw header value. * @param allowedQueryParams query parameter names whose values are kept (see [redact]). */ @JvmStatic diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/metrics/DoubleHistogram.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/metrics/DoubleHistogram.kt index f7a3d771..6362bf3c 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/metrics/DoubleHistogram.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/metrics/DoubleHistogram.kt @@ -35,9 +35,8 @@ public interface DoubleHistogram { * Pass the shared `emptyMap()` (the default) when no attributes are needed to avoid * allocating a fresh map per call. * - * @param value the measurement to record. Non-finite values (`NaN`, infinities) are - * implementation-defined; the noop implementation accepts and discards - * them, while production adapters typically filter and warn. + * @param value the measurement to record; non-finite values are handled per the + * "Non-finite values" note above. * @param attributes key-value pairs describing the measurement dimensions (e.g. * `{"http.request.method": "GET"}`). The map should not be mutated * after the call; implementations may retain a reference for diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/metrics/Meter.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/metrics/Meter.kt index 24e58a41..f2527c1c 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/metrics/Meter.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/instrumentation/metrics/Meter.kt @@ -39,11 +39,10 @@ public interface Meter { /** * Returns a [LongCounter] for emitting monotonically increasing integer measurements. * - * @param name the instrument name, following OpenTelemetry semantic conventions. - * @param description a short human-readable description of what the counter measures. - * @param unit the unit of measurement as a UCUM symbol (e.g. `"{request}"`, `"By"`). - * @return a counter instrument. Implementations may cache and return the same instance - * for repeated calls with identical arguments. + * @param name instrument name (OpenTelemetry semantic conventions). + * @param description what the counter measures. + * @param unit UCUM unit symbol (e.g. `"{request}"`, `"By"`). + * @return a counter instrument. */ public fun counter( name: String, @@ -54,11 +53,10 @@ public interface Meter { /** * Returns a [DoubleHistogram] for recording distributions of floating-point measurements. * - * @param name the instrument name, following OpenTelemetry semantic conventions. - * @param description a short human-readable description of what the histogram measures. - * @param unit the unit of measurement as a UCUM symbol (e.g. `"ms"`, `"s"`). - * @return a histogram instrument. Implementations may cache and return the same instance - * for repeated calls with identical arguments. + * @param name instrument name (OpenTelemetry semantic conventions). + * @param description what the histogram measures. + * @param unit UCUM unit symbol (e.g. `"ms"`, `"s"`). + * @return a histogram instrument. */ public fun histogram( name: String, diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pagination/CloseablePages.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pagination/CloseablePages.kt index 9a2e6c14..fe3fe26b 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pagination/CloseablePages.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pagination/CloseablePages.kt @@ -66,14 +66,12 @@ public class CloseablePages private var iterated: Boolean = false /** - * Returns the single auto-closing iterator over the underlying walk. The page returned by - * `next()` stays open until the next `next()`, exhaustion, or [close]. A page fetched by a - * `hasNext()` probe but never returned by `next()` is retained and released by [close], so - * an abandoned probe never strands a connection. + * Returns the single auto-closing iterator over the underlying walk (hold-open and + * close-on-abandon semantics are described on the class). * - * The underlying walker is a lazy sequence whose `hasNext()` performs the page fetch, so the - * returned iterator's `hasNext()` deliberately pulls that fetched page into a field we own — - * that prefetch is what lets [close] release a page from an abandoned probe (hence the + * The underlying walker's `hasNext()` performs the page fetch, so this iterator's + * `hasNext()` deliberately pulls that fetched page into a field we own — the prefetch that + * lets [close] release a page from an abandoned probe (hence the * `IteratorHasNextCallsNextMethod` suppression). * * @throws IllegalStateException if called more than once on this view. diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pagination/CursorPaginationStrategy.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pagination/CursorPaginationStrategy.kt index ab6840b6..7b10f354 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pagination/CursorPaginationStrategy.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pagination/CursorPaginationStrategy.kt @@ -16,8 +16,7 @@ import org.dexpace.sdk.core.http.response.Response * * A dedicated functional interface (rather than a raw `(Response) -> CursorResult` function type) * gives Java callers a clean SAM to implement — `new CursorExtractor<>() { ... }` or a lambda — - * instead of `kotlin.jvm.functions.Function1`. Kotlin callers pass a lambda unchanged via SAM - * conversion. + * instead of `kotlin.jvm.functions.Function1`. * * @param T Element type carried in the produced [CursorResult]. */ diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/RequestRecoveryChain.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/RequestRecoveryChain.kt index dc86eb76..3899735a 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/RequestRecoveryChain.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/RequestRecoveryChain.kt @@ -17,8 +17,7 @@ import org.dexpace.sdk.core.pipeline.step.RequestPipelineStep * the `BeforeRequest` chain. * * The pipeline preserves the original [Request] when the list is empty — an empty pipeline - * is a no-op. Steps may throw; the [RecoveryChain] catches throwables from this pipeline - * and routes them through the recovery chain rather than propagating them to the caller. + * is a no-op. * * ## Thread-safety * Instances are immutable after construction ([steps] is exposed as a read-only List); they @@ -40,9 +39,6 @@ public class RequestRecoveryChain * Applies every step in [steps] to [request] sequentially under [context] and returns the * final transformed [Request]. An empty chain returns [request] unchanged. * - * @param request The initial request to feed into the chain. - * @param context The shared dispatch context. - * @return The request produced by the last step (or [request] if [steps] is empty). * @throws Throwable Any exception thrown by a step is rethrown unchanged. Callers should * funnel this throwable through the recovery chain (see [RecoveryChain]). */ diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/ResponseOutcome.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/ResponseOutcome.kt index 733b4426..9ea0ffeb 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/ResponseOutcome.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/ResponseOutcome.kt @@ -75,8 +75,6 @@ public sealed class ResponseOutcome { * Mirrors `kotlin.Result.fold` semantics so callers can collapse an outcome into a single * value without an exhaustive `when`. Neither lambda is invoked more than once per call. * - * @param onSuccess Mapper applied to the [Response] when this is a [Success]. - * @param onFailure Mapper applied to the [Throwable] when this is a [Failure]. * @return The result of the selected mapper. */ public inline fun fold( diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/ClientIdentityStep.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/ClientIdentityStep.kt index 6f53868a..a7c85e11 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/ClientIdentityStep.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/ClientIdentityStep.kt @@ -102,8 +102,6 @@ public class ClientIdentityStep * The pre-filled tokens are treated as caller-owned: a subsequent * [ClientIdentityStepBuilder.addToken] appends to them rather than discarding the * default seed (there is no seed to discard once an instance has been materialised). - * - * @return A new builder carrying this instance's configuration. */ public fun newBuilder(): ClientIdentityStepBuilder = ClientIdentityStepBuilder(this) diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/IdempotencyKeyStep.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/IdempotencyKeyStep.kt index e5d3a380..ef6f65ee 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/IdempotencyKeyStep.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/IdempotencyKeyStep.kt @@ -83,8 +83,6 @@ public class IdempotencyKeyStep private constructor( /** * Returns a [Builder] initialized with this step's current configuration so callers can * derive a tweaked instance without re-stating every field. - * - * @return A new builder pre-filled with this instance's fields. */ public fun newBuilder(): Builder = Builder(this) @@ -102,11 +100,7 @@ public class IdempotencyKeyStep private constructor( /** Creates an empty builder seeded with the documented defaults. */ public constructor() - /** - * Creates a builder initialized with the configuration of [step]. - * - * @param step The step whose configuration to copy. - */ + /** Creates a builder initialized with the configuration of [step]. */ public constructor(step: IdempotencyKeyStep) { this.header = step.header this.methods = step.methods @@ -115,12 +109,9 @@ public class IdempotencyKeyStep private constructor( } /** - * Sets the header name to inject. The value is stored verbatim but [Request]'s - * underlying [org.dexpace.sdk.core.http.common.Headers] map is case-insensitive, so - * `idempotency-key` and `Idempotency-Key` interoperate. - * - * @param header Header name (non-blank). - * @return This builder. + * Sets the header name to inject (non-blank). The value is stored verbatim but + * [Request]'s underlying [org.dexpace.sdk.core.http.common.Headers] map is + * case-insensitive, so `idempotency-key` and `Idempotency-Key` interoperate. */ public fun header(header: String): Builder = apply { @@ -130,9 +121,6 @@ public class IdempotencyKeyStep private constructor( /** * Sets the HTTP methods that trigger header injection. The provided set is copied * into an immutable snapshot so later mutations to the caller's set do not leak in. - * - * @param methods Methods that should receive the header. - * @return This builder. */ public fun methods(methods: Set): Builder = apply { @@ -142,9 +130,6 @@ public class IdempotencyKeyStep private constructor( /** * Sets the key-generation strategy using a Kotlin function. Invoked at most once per * applicable request, only after the method/header checks decide injection is needed. - * - * @param strategy Function returning the next key. - * @return This builder. */ public fun keyStrategy(strategy: () -> String): Builder = apply { @@ -155,9 +140,6 @@ public class IdempotencyKeyStep private constructor( * Sets the key-generation strategy from a Java [Supplier]. Internally adapted to the * Kotlin function shape, so the step's behaviour is identical regardless of which * overload was used. - * - * @param supplier Supplier producing the next key. - * @return This builder. */ public fun keyStrategy(supplier: Supplier): Builder = apply { @@ -167,20 +149,13 @@ public class IdempotencyKeyStep private constructor( /** * Sets whether an existing header on the request is respected. See class KDoc for * the semantics of `true` vs `false`. - * - * @param respectExisting `true` to preserve an existing header; `false` to overwrite. - * @return This builder. */ public fun respectExisting(respectExisting: Boolean): Builder = apply { this.respectExisting = respectExisting } - /** - * Builds the immutable [IdempotencyKeyStep]. - * - * @return The configured step. - */ + /** Builds the immutable [IdempotencyKeyStep]. */ override fun build(): IdempotencyKeyStep = IdempotencyKeyStep( header = header, diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/PipelineStep.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/PipelineStep.kt index 7faf61bd..a952d30e 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/PipelineStep.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/PipelineStep.kt @@ -33,11 +33,8 @@ import org.dexpace.sdk.core.http.context.DispatchContext */ public fun interface PipelineStep { /** - * Executes this step against [input] under [context] and returns the transformed value. - * - * @param input The current pipeline value. - * @param context The shared dispatch context. - * @return The transformed value to feed the next step. + * Executes this step against [input] under [context] and returns the transformed value to + * feed the next step. */ public fun execute( input: T, diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/ResponseRecoveryStep.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/ResponseRecoveryStep.kt index 4fe71bcc..8ea7dfff 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/ResponseRecoveryStep.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/ResponseRecoveryStep.kt @@ -56,9 +56,6 @@ public fun interface ResponseRecoveryStep { /** * Inspects [outcome] and returns the (possibly transformed) outcome to feed to the next * step in the recovery chain. - * - * @param outcome The current outcome — may be a success or failure. - * @return The transformed outcome. */ public fun invoke(outcome: ResponseOutcome): ResponseOutcome } diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/retry/RetryAfterParser.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/retry/RetryAfterParser.kt index 1148c4b3..50bfc22c 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/retry/RetryAfterParser.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/pipeline/step/retry/RetryAfterParser.kt @@ -206,16 +206,14 @@ public object RetryAfterParser { /** * Parses [value] as a non-negative count of seconds. Accepts both the RFC 7231 §7.1.3 - * integer (delta-seconds) form and the fractional form (`1.5`) that real servers and - * proxies emit; the fractional part is honoured down to nanosecond resolution. + * integer (delta-seconds) form and the fractional form (`1.5`) real servers and proxies + * emit; the fractional part is honoured to nanosecond resolution. * - * The value is first screened against [NUMERIC_SECONDS] so only the plain decimal grammar - * is honoured: [String.toDoubleOrNull] otherwise accepts Java float literals such as `30d` - * and `0x1p4`, which must instead fall through to the HTTP-date branch (or, ultimately, the - * backoff schedule). Returns `null` on any parse failure, on a negative value, or on a - * non-finite value (`NaN`, `Infinity`). A finite but absurdly large value is clamped to - * [MAX_DELAY] before the nanosecond conversion so the resulting [Duration] can never - * overflow [Duration.toNanos] downstream. + * Screened against [NUMERIC_SECONDS] first (see that regex's KDoc for why the plain-decimal + * screen is required before [String.toDoubleOrNull]). Returns `null` on any parse failure, a + * negative value, or a non-finite value (`NaN`, `Infinity`); a finite but absurdly large + * value is clamped to [MAX_DELAY] before the nanosecond conversion so the resulting + * [Duration] can never overflow [Duration.toNanos]. */ private fun parseNumericSeconds(value: String): Duration? { // The strict screen guarantees a non-negative decimal, so toDoubleOrNull never returns diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/serde/SerdeException.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/serde/SerdeException.kt index 3b919f38..71589ff2 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/serde/SerdeException.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/serde/SerdeException.kt @@ -45,10 +45,8 @@ public open class SerdeException /** * A [SerdeException] raised while **encoding** a value to the wire format — for example an object - * graph the backing codec cannot represent (a reference cycle, an unmapped type). - * - * @param message Human-readable description of the failure. - * @param cause The underlying error (typically the backing library's exception), or `null`. + * graph the backing codec cannot represent (a reference cycle, an unmapped type). See + * [SerdeException] for the `message`/`cause` contract. */ public open class SerializationException @JvmOverloads @@ -59,10 +57,8 @@ public open class SerializationException /** * A [SerdeException] raised while **decoding** wire bytes / strings / streams into a typed value — - * for example a malformed document or a payload whose shape does not match the target type. - * - * @param message Human-readable description of the failure. - * @param cause The underlying error (typically the backing library's exception), or `null`. + * for example a malformed document or a payload whose shape does not match the target type. See + * [SerdeException] for the `message`/`cause` contract. */ public open class DeserializationException @JvmOverloads diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/Futures.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/Futures.kt index e375c643..bf64caaf 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/Futures.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/Futures.kt @@ -62,9 +62,8 @@ public object Futures { * The SDK's async retry/redirect steps compose this with `thenCompose` to insert async * delays into a future chain without blocking a thread. * - * The return type is `CompletableFuture` (not `Unit`) for Java-interop ergonomics — - * Java callers can compose with `CompletableFuture` chains naturally using - * `thenRun`, `thenCompose`, etc., without needing to adapt a Kotlin `Unit` value. + * The return type is `CompletableFuture` (not `Unit`) so Java callers can compose with + * `thenRun`/`thenCompose` chains without adapting a Kotlin `Unit` value. * * Cancellation of the returned future cancels the scheduled task. */ diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/ProxyOptions.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/ProxyOptions.kt index c2801b9e..1e703443 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/ProxyOptions.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/ProxyOptions.kt @@ -187,17 +187,7 @@ public class ProxyOptions * proxy (or bypasses it entirely via `NO_PROXY=*`). A convenience over * [fromConfiguration] that supplies the global configuration, so callers — chiefly the * shipped transports' `proxyFromEnvironment()` builder hooks — don't repeat the lookup. - * - * Resolution follows [fromConfiguration]: system properties win over environment - * variables (JDK convention). Recognised sources: - * - System property `https.proxyHost` / `https.proxyPort` / `https.proxyUser` / - * `https.proxyPassword` (preferred), falling back to `http.proxyHost` / - * `http.proxyPort`. - * - System property `http.nonProxyHosts` (pipe-separated, backslash-escapable). - * - Environment variable `HTTPS_PROXY` / `HTTP_PROXY` — full URL form - * `http://user:pass@proxy:8080`. - * - Environment variable `NO_PROXY` — comma-separated; a bare `*` bypasses the proxy for - * every host, in which case this returns `null`. + * See [fromConfiguration] for the full source precedence and recognised keys. * * Strictly opt-in from a transport's perspective: nothing consults the environment until * this (or [fromConfiguration]) is called. diff --git a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/ValueEquality.kt b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/ValueEquality.kt index cd086b18..b85571ab 100644 --- a/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/ValueEquality.kt +++ b/sdk-core/src/main/kotlin/org/dexpace/sdk/core/util/ValueEquality.kt @@ -68,12 +68,10 @@ public object ValueEquality { * (`Array`/`Array`) arrays, and [contentHashCode] hashes to match. * - Any other value is compared with [Any.equals]. * - * This is exactly the contract of `java.util.Objects.deepEquals`, to which it delegates. - * - * It is a thin wrapper over that JDK method, kept so it pairs symmetrically with - * [contentHashCode] — for which the JDK offers no `Objects.deepHashCode` equivalent — so callers - * reach one discoverable, contract-paired entry point instead of mixing `Objects.deepEquals` - * with a hand-rolled hash. + * This is exactly the contract of `java.util.Objects.deepEquals`, to which it delegates — kept + * as a thin wrapper so it pairs symmetrically with [contentHashCode] (for which the JDK offers no + * `Objects.deepHashCode` equivalent), giving callers one discoverable, contract-paired entry + * point instead of mixing `Objects.deepEquals` with a hand-rolled hash. */ @JvmStatic public fun contentEquals( diff --git a/sdk-serde-jackson/src/main/kotlin/org/dexpace/sdk/serde/jackson/JacksonSerde.kt b/sdk-serde-jackson/src/main/kotlin/org/dexpace/sdk/serde/jackson/JacksonSerde.kt index e9264a39..ab1c0eab 100644 --- a/sdk-serde-jackson/src/main/kotlin/org/dexpace/sdk/serde/jackson/JacksonSerde.kt +++ b/sdk-serde-jackson/src/main/kotlin/org/dexpace/sdk/serde/jackson/JacksonSerde.kt @@ -162,8 +162,7 @@ public class JacksonSerde private constructor( /** * Jackson-backed [Serializer] writing to strings, byte arrays, or output streams. * - * `internal` — not meant for direct consumption; clients pull the [Serde] facade. Strict-mode - * Kotlin requires explicit visibility on every declaration, hence the marker. + * `internal` — not meant for direct consumption; clients pull the [Serde] facade. */ internal class JacksonSerializer internal constructor( private val mapper: ObjectMapper, diff --git a/sdk-transport-jdkhttp/src/main/kotlin/org/dexpace/sdk/transport/jdkhttp/JdkHttpTransport.kt b/sdk-transport-jdkhttp/src/main/kotlin/org/dexpace/sdk/transport/jdkhttp/JdkHttpTransport.kt index c55ae310..ce9bb8e5 100644 --- a/sdk-transport-jdkhttp/src/main/kotlin/org/dexpace/sdk/transport/jdkhttp/JdkHttpTransport.kt +++ b/sdk-transport-jdkhttp/src/main/kotlin/org/dexpace/sdk/transport/jdkhttp/JdkHttpTransport.kt @@ -540,8 +540,6 @@ public class JdkHttpTransport private constructor( * [ProxyAuthenticator]. To authenticate against a Digest-only proxy, pass a * pre-configured `java.net.http.HttpClient` carrying your own `Authenticator` to * [create]; the SDK uses that client as-is. - * - * Credentials are deliberately never logged. */ private fun applyProxy( clientBuilder: java.net.http.HttpClient.Builder, diff --git a/sdk-transport-jdkhttp/src/main/kotlin/org/dexpace/sdk/transport/jdkhttp/internal/BodyPublishers.kt b/sdk-transport-jdkhttp/src/main/kotlin/org/dexpace/sdk/transport/jdkhttp/internal/BodyPublishers.kt index b69f733c..4647d6a5 100644 --- a/sdk-transport-jdkhttp/src/main/kotlin/org/dexpace/sdk/transport/jdkhttp/internal/BodyPublishers.kt +++ b/sdk-transport-jdkhttp/src/main/kotlin/org/dexpace/sdk/transport/jdkhttp/internal/BodyPublishers.kt @@ -139,20 +139,16 @@ internal object BodyPublishers { /** * Streaming publisher for bodies larger than the eager threshold (or of unknown length). * - * The JDK calls the `ofInputStream` supplier **once per subscription** and re-subscribes - * on internal resends (407 proxy-auth retry, HTTP/2 `GOAWAY` replay). Each subscription - * therefore re-reads the body, so the body must be replayable for the resent request to - * carry the correct bytes. If [body] is not already replayable it is buffered once into an - * in-memory copy via [SdkRequestBody.toReplayable]. A body that cannot be made replayable - * (its `toReplayable` throws mid-write) has already been partially consumed and cannot be - * recovered — the bytes drained by the failed buffering attempt are gone and `writeTo` - * cannot be driven a second time on a consume-once body. This method therefore fails with a - * checked [IOException] that wraps the original cause rather than masking it (a second - * `writeTo` would trip a consume-once guard and surface an `IllegalStateException`) or - * shipping a truncated body. Surfacing it as a checked [IOException] keeps the transport's - * `@Throws(IOException)` contract intact and matches the eager path, which already propagates - * a mid-write failure as an [IOException]; callers that need resilience here must supply a - * replayable body. + * The JDK calls the `ofInputStream` supplier **once per subscription** and re-subscribes on + * internal resends (407 proxy-auth retry, HTTP/2 `GOAWAY` replay), so each subscription + * re-reads the body and the body must be replayable. If [body] is not already replayable it is + * buffered once via [SdkRequestBody.toReplayable]. If that buffering throws mid-write the body + * is a partially-consumed consume-once source that cannot be recovered (a second `writeTo` + * would trip its consume-once guard with an `IllegalStateException`), so this method fails with + * a checked [IOException] wrapping the cause — honouring the transport's `@Throws(IOException)` + * contract and matching the eager path, which likewise propagates a mid-write failure as an + * [IOException] — rather than re-driving the body or shipping a truncated one. Callers that need + * resilience here must supply a replayable body. * * For each subscription the supplier: * 1. creates a fresh [PipedOutputStream] / [PipedInputStream] pair;