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;