Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.1.0-alpha.3"
".": "0.1.0-alpha.4"
}
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# Changelog

## 0.1.0-alpha.4 (2025-01-30)

Full Changelog: [v0.1.0-alpha.3...v0.1.0-alpha.4](https://github.com/terminaldotshop/terminal-sdk-java/compare/v0.1.0-alpha.3...v0.1.0-alpha.4)

### Features

* **client:** add `_queryParams` and `_headers` methods ([#57](https://github.com/terminaldotshop/terminal-sdk-java/issues/57)) ([c0236ee](https://github.com/terminaldotshop/terminal-sdk-java/commit/c0236eeb02e547f4f980c51054906ba7104f99ba))


### Bug Fixes

* **client:** don't leak responses when retrying ([#59](https://github.com/terminaldotshop/terminal-sdk-java/issues/59)) ([7812702](https://github.com/terminaldotshop/terminal-sdk-java/commit/7812702fd8e246c4e351d814e3994d730b10455a))


### Chores

* **internal:** improve `RetryingHttpClientTest` ([#58](https://github.com/terminaldotshop/terminal-sdk-java/issues/58)) ([3bf7913](https://github.com/terminaldotshop/terminal-sdk-java/commit/3bf7913aed72f0a3d47061112f546e7d39835f8b))


### Documentation

* builder, enum, and union comments ([#55](https://github.com/terminaldotshop/terminal-sdk-java/issues/55)) ([a1f1edf](https://github.com/terminaldotshop/terminal-sdk-java/commit/a1f1edf3638c1dcacbf144c9f265c5c8c5c754ab))


### Refactors

* **internal:** extract request preparation logic ([c0236ee](https://github.com/terminaldotshop/terminal-sdk-java/commit/c0236eeb02e547f4f980c51054906ba7104f99ba))

## 0.1.0-alpha.3 (2025-01-28)

Full Changelog: [v0.1.0-alpha.2...v0.1.0-alpha.3](https://github.com/terminaldotshop/terminal-sdk-java/compare/v0.1.0-alpha.2...v0.1.0-alpha.3)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<!-- x-release-please-start-version -->

[![Maven Central](https://img.shields.io/maven-central/v/shop.terminal.api/terminal-java)](https://central.sonatype.com/artifact/shop.terminal.api/terminal-java/0.1.0-alpha.3)
[![Maven Central](https://img.shields.io/maven-central/v/shop.terminal.api/terminal-java)](https://central.sonatype.com/artifact/shop.terminal.api/terminal-java/0.1.0-alpha.4)

<!-- x-release-please-end -->

Expand All @@ -21,7 +21,7 @@ The REST API documentation can be found on [terminal.shop](https://terminal.shop
### Gradle

```kotlin
implementation("shop.terminal.api:terminal-java:0.1.0-alpha.3")
implementation("shop.terminal.api:terminal-java:0.1.0-alpha.4")
```

### Maven
Expand All @@ -30,7 +30,7 @@ implementation("shop.terminal.api:terminal-java:0.1.0-alpha.3")
<dependency>
<groupId>shop.terminal.api</groupId>
<artifactId>terminal-java</artifactId>
<version>0.1.0-alpha.3</version>
<version>0.1.0-alpha.4</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
allprojects {
group = "shop.terminal.api"
version = "0.1.0-alpha.3" // x-release-please-version
version = "0.1.0-alpha.4" // x-release-please-version
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class TerminalOkHttpClient private constructor() {
@JvmStatic fun fromEnv(): TerminalClient = builder().fromEnv().build()
}

/** A builder for [TerminalOkHttpClient]. */
class Builder internal constructor() {

private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class TerminalOkHttpClientAsync private constructor() {
@JvmStatic fun fromEnv(): TerminalClientAsync = builder().fromEnv().build()
}

/** A builder for [TerminalOkHttpClientAsync]. */
class Builder internal constructor() {

private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ private constructor(
@JvmStatic fun fromEnv(): ClientOptions = builder().fromEnv().build()
}

/** A builder for [ClientOptions]. */
class Builder internal constructor() {

private var httpClient: HttpClient? = null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package shop.terminal.api.core

import shop.terminal.api.core.http.Headers
import shop.terminal.api.core.http.QueryParams

/** An interface representing parameters passed to a service method. */
interface Params {
/** The full set of headers in the parameters, including both fixed and additional headers. */
fun _headers(): Headers

/**
* The full set of query params in the parameters, including both fixed and additional query
* params.
*/
fun _queryParams(): QueryParams
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@file:JvmName("PrepareRequest")

package shop.terminal.api.core

import java.util.concurrent.CompletableFuture
import shop.terminal.api.core.http.HttpRequest

@JvmSynthetic
internal fun HttpRequest.prepare(clientOptions: ClientOptions, params: Params): HttpRequest =
toBuilder()
.putAllQueryParams(clientOptions.queryParams)
.replaceAllQueryParams(params._queryParams())
.putAllHeaders(clientOptions.headers)
.replaceAllHeaders(params._headers())
.build()

@JvmSynthetic
internal fun HttpRequest.prepareAsync(
clientOptions: ClientOptions,
params: Params
): CompletableFuture<HttpRequest> =
// This async version exists to make it easier to add async specific preparation logic in the
// future.
CompletableFuture.completedFuture(prepare(clientOptions, params))
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,17 @@ private constructor(
}

response
} catch (t: Throwable) {
if (++retries > maxRetries || !shouldRetry(t)) {
throw t
} catch (throwable: Throwable) {
if (++retries > maxRetries || !shouldRetry(throwable)) {
throw throwable
}

null
}

val backoffMillis = getRetryBackoffMillis(retries, response)
// All responses must be closed, so close the failed one before retrying.
response?.close()
Thread.sleep(backoffMillis.toMillis())
}
}
Expand Down Expand Up @@ -113,6 +115,8 @@ private constructor(
}

val backoffMillis = getRetryBackoffMillis(retries, response)
// All responses must be closed, so close the failed one before retrying.
response?.close()
return sleepAsync(backoffMillis.toMillis()).thenCompose {
executeWithRetries(requestWithRetryCount, requestOptions)
}
Expand Down Expand Up @@ -223,23 +227,23 @@ private constructor(
return Duration.ofNanos((TimeUnit.SECONDS.toNanos(1) * backoffSeconds * jitter).toLong())
}

private fun sleepAsync(millis: Long): CompletableFuture<Void> {
val future = CompletableFuture<Void>()
TIMER.schedule(
object : TimerTask() {
override fun run() {
future.complete(null)
}
},
millis
)
return future
}

companion object {

private val TIMER = Timer("RetryingHttpClient", true)

private fun sleepAsync(millis: Long): CompletableFuture<Void> {
val future = CompletableFuture<Void>()
TIMER.schedule(
object : TimerTask() {
override fun run() {
future.complete(null)
}
},
millis
)
return future
}

@JvmStatic fun builder() = Builder()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private constructor(
@JvmStatic fun builder() = Builder()
}

/** A builder for [TerminalError]. */
class Builder internal constructor() {

private var additionalProperties: MutableMap<String, JsonValue> = mutableMapOf()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ private constructor(
@JvmStatic fun builder() = Builder()
}

/** A builder for [Address]. */
class Builder internal constructor() {

private var id: JsonField<String>? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import shop.terminal.api.core.JsonField
import shop.terminal.api.core.JsonMissing
import shop.terminal.api.core.JsonValue
import shop.terminal.api.core.NoAutoDetect
import shop.terminal.api.core.Params
import shop.terminal.api.core.checkRequired
import shop.terminal.api.core.http.Headers
import shop.terminal.api.core.http.QueryParams
Expand All @@ -25,7 +26,7 @@ private constructor(
private val body: AddressCreateBody,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
) {
) : Params {

/** City of the address. */
fun city(): String = body.city()
Expand Down Expand Up @@ -81,11 +82,11 @@ private constructor(

fun _additionalQueryParams(): QueryParams = additionalQueryParams

@JvmSynthetic internal fun getBody(): AddressCreateBody = body
@JvmSynthetic internal fun _body(): AddressCreateBody = body

@JvmSynthetic internal fun getHeaders(): Headers = additionalHeaders
override fun _headers(): Headers = additionalHeaders

@JvmSynthetic internal fun getQueryParams(): QueryParams = additionalQueryParams
override fun _queryParams(): QueryParams = additionalQueryParams

/** Address information. */
@NoAutoDetect
Expand Down Expand Up @@ -195,6 +196,7 @@ private constructor(
@JvmStatic fun builder() = Builder()
}

/** A builder for [AddressCreateBody]. */
class Builder internal constructor() {

private var city: JsonField<String>? = null
Expand Down Expand Up @@ -326,6 +328,7 @@ private constructor(
@JvmStatic fun builder() = Builder()
}

/** A builder for [AddressCreateParams]. */
@NoAutoDetect
class Builder internal constructor() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ private constructor(
@JvmStatic fun builder() = Builder()
}

/** A builder for [AddressCreateResponse]. */
class Builder internal constructor() {

private var data: JsonField<String>? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import java.util.Objects
import java.util.Optional
import shop.terminal.api.core.JsonValue
import shop.terminal.api.core.NoAutoDetect
import shop.terminal.api.core.Params
import shop.terminal.api.core.checkRequired
import shop.terminal.api.core.http.Headers
import shop.terminal.api.core.http.QueryParams
Expand All @@ -18,7 +19,7 @@ private constructor(
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
private val additionalBodyProperties: Map<String, JsonValue>,
) {
) : Params {

/** ID of the shipping address to delete. */
fun id(): String = id
Expand All @@ -30,12 +31,12 @@ private constructor(
fun _additionalBodyProperties(): Map<String, JsonValue> = additionalBodyProperties

@JvmSynthetic
internal fun getBody(): Optional<Map<String, JsonValue>> =
internal fun _body(): Optional<Map<String, JsonValue>> =
Optional.ofNullable(additionalBodyProperties.ifEmpty { null })

@JvmSynthetic internal fun getHeaders(): Headers = additionalHeaders
override fun _headers(): Headers = additionalHeaders

@JvmSynthetic internal fun getQueryParams(): QueryParams = additionalQueryParams
override fun _queryParams(): QueryParams = additionalQueryParams

fun getPathParam(index: Int): String {
return when (index) {
Expand All @@ -51,6 +52,7 @@ private constructor(
@JvmStatic fun builder() = Builder()
}

/** A builder for [AddressDeleteParams]. */
@NoAutoDetect
class Builder internal constructor() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ private constructor(
@JvmStatic fun builder() = Builder()
}

/** A builder for [AddressDeleteResponse]. */
class Builder internal constructor() {

private var data: JsonField<Data>? = null
Expand Down Expand Up @@ -96,6 +97,14 @@ private constructor(
private val value: JsonField<String>,
) : Enum {

/**
* Returns this class instance's raw value.
*
* This is usually only useful if this instance was deserialized from data that doesn't
* match any known member, and you want to know that value. For example, if the SDK is on an
* older version than the API, then the API may respond with new members that the SDK is
* unaware of.
*/
@com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField<String> = value

companion object {
Expand All @@ -105,21 +114,48 @@ private constructor(
@JvmStatic fun of(value: String) = Data(JsonField.of(value))
}

/** An enum containing [Data]'s known values. */
enum class Known {
OK,
}

/**
* An enum containing [Data]'s known values, as well as an [_UNKNOWN] member.
*
* An instance of [Data] can contain an unknown value in a couple of cases:
* - It was deserialized from data that doesn't match any known member. For example, if the
* SDK is on an older version than the API, then the API may respond with new members that
* the SDK is unaware of.
* - It was constructed with an arbitrary value using the [of] method.
*/
enum class Value {
OK,
/** An enum member indicating that [Data] was instantiated with an unknown value. */
_UNKNOWN,
}

/**
* Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN]
* if the class was instantiated with an unknown value.
*
* Use the [known] method instead if you're certain the value is always known or if you want
* to throw for the unknown case.
*/
fun value(): Value =
when (this) {
OK -> Value.OK
else -> Value._UNKNOWN
}

/**
* Returns an enum member corresponding to this class instance's value.
*
* Use the [value] method instead if you're uncertain the value is always known and don't
* want to throw for the unknown case.
*
* @throws TerminalInvalidDataException if this class instance's value is a not a known
* member.
*/
fun known(): Known =
when (this) {
OK -> Known.OK
Expand Down
Loading