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.105.1"
".": "0.106.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 169
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-1d44bb7fad99487af1161eb24dfd5369440eda7e80ed237cbc1acc6802a7d212.yml
openapi_spec_hash: 1b6b6215b60094b76b91c56b925a251a
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-fbbce0ea11d3e86e532f705804f3d79e8eecfb8a7796e3a6ad3c50cccee14bb1.yml
openapi_spec_hash: 3f44b97866ca74effe5e70fc9c64effb
config_hash: 768e8f0faa1a21e26b07e6cdc395cebf
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

## 0.106.0 (2025-09-25)

Full Changelog: [v0.105.1...v0.106.0](https://github.com/lithic-com/lithic-java/compare/v0.105.1...v0.106.0)

### Features

* **client:** add convenience overloads for some methods ([1835a3b](https://github.com/lithic-com/lithic-java/commit/1835a3b3fe9563ec6043c9e332b66ec1054f2d67))
* **client:** expose sleeper option ([3006825](https://github.com/lithic-com/lithic-java/commit/300682586590f3cd263ae552c62603f0bf06b74c))


### Bug Fixes

* **client:** deserialization of empty objects ([b24cf62](https://github.com/lithic-com/lithic-java/commit/b24cf622050e2d014d54e61b34760b45cf42d713))
* **client:** ensure single timer is created per client ([3006825](https://github.com/lithic-com/lithic-java/commit/300682586590f3cd263ae552c62603f0bf06b74c))


### Chores

* **docs:** small updates to doc strings on a few endpoints ([472d95b](https://github.com/lithic-com/lithic-java/commit/472d95b0e63d7530e5e40674d9d65e5e3a66e6f4))
* improve formatter performance ([36fa6d6](https://github.com/lithic-com/lithic-java/commit/36fa6d6a567c00b8c24b63fd4eff99a93ed5f787))
* **internal:** change some comment formatting ([f09453c](https://github.com/lithic-com/lithic-java/commit/f09453c5007dc265cc5fc06dc161395605d12ccf))

## 0.105.1 (2025-09-15)

Full Changelog: [v0.105.0...v0.105.1](https://github.com/lithic-com/lithic-java/compare/v0.105.0...v0.105.1)
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

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

[![Maven Central](https://img.shields.io/maven-central/v/com.lithic.api/lithic-java)](https://central.sonatype.com/artifact/com.lithic.api/lithic-java/0.105.1)
[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.105.1/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.105.1)
[![Maven Central](https://img.shields.io/maven-central/v/com.lithic.api/lithic-java)](https://central.sonatype.com/artifact/com.lithic.api/lithic-java/0.106.0)
[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.106.0/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.106.0)

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

Expand All @@ -13,7 +13,7 @@ The Lithic Java SDK is similar to the Lithic Kotlin SDK but with minor differenc

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

The REST API documentation can be found on [docs.lithic.com](https://docs.lithic.com). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.lithic.api/lithic-java/0.105.1).
The REST API documentation can be found on [docs.lithic.com](https://docs.lithic.com). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.lithic.api/lithic-java/0.106.0).

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

Expand All @@ -24,7 +24,7 @@ The REST API documentation can be found on [docs.lithic.com](https://docs.lithic
### Gradle

```kotlin
implementation("com.lithic.api:lithic-java:0.105.1")
implementation("com.lithic.api:lithic-java:0.106.0")
```

### Maven
Expand All @@ -33,7 +33,7 @@ implementation("com.lithic.api:lithic-java:0.105.1")
<dependency>
<groupId>com.lithic.api</groupId>
<artifactId>lithic-java</artifactId>
<version>0.105.1</version>
<version>0.106.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repositories {

allprojects {
group = "com.lithic.api"
version = "0.105.1" // x-release-please-version
version = "0.106.0" // x-release-please-version
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.json.JsonMapper
import com.lithic.api.client.LithicClient
import com.lithic.api.client.LithicClientImpl
import com.lithic.api.core.ClientOptions
import com.lithic.api.core.Sleeper
import com.lithic.api.core.Timeout
import com.lithic.api.core.http.AsyncStreamResponse
import com.lithic.api.core.http.Headers
Expand Down Expand Up @@ -133,6 +134,17 @@ class LithicOkHttpClient private constructor() {
clientOptions.streamHandlerExecutor(streamHandlerExecutor)
}

/**
* The interface to use for delaying execution, like during retries.
*
* This is primarily useful for using fake delays in tests.
*
* Defaults to real execution delays.
*
* This class takes ownership of the sleeper and closes it when closed.
*/
fun sleeper(sleeper: Sleeper) = apply { clientOptions.sleeper(sleeper) }

/**
* The clock to use for operations that require timing, like retries.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.json.JsonMapper
import com.lithic.api.client.LithicClientAsync
import com.lithic.api.client.LithicClientAsyncImpl
import com.lithic.api.core.ClientOptions
import com.lithic.api.core.Sleeper
import com.lithic.api.core.Timeout
import com.lithic.api.core.http.AsyncStreamResponse
import com.lithic.api.core.http.Headers
Expand Down Expand Up @@ -133,6 +134,17 @@ class LithicOkHttpClientAsync private constructor() {
clientOptions.streamHandlerExecutor(streamHandlerExecutor)
}

/**
* The interface to use for delaying execution, like during retries.
*
* This is primarily useful for using fake delays in tests.
*
* Defaults to real execution delays.
*
* This class takes ownership of the sleeper and closes it when closed.
*/
fun sleeper(sleeper: Sleeper) = apply { clientOptions.sleeper(sleeper) }

/**
* The clock to use for operations that require timing, like retries.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ private constructor(
* This class takes ownership of the executor and shuts it down, if possible, when closed.
*/
@get:JvmName("streamHandlerExecutor") val streamHandlerExecutor: Executor,
/**
* The interface to use for delaying execution, like during retries.
*
* This is primarily useful for using fake delays in tests.
*
* Defaults to real execution delays.
*
* This class takes ownership of the sleeper and closes it when closed.
*/
@get:JvmName("sleeper") val sleeper: Sleeper,
/**
* The clock to use for operations that require timing, like retries.
*
Expand Down Expand Up @@ -153,6 +163,7 @@ private constructor(
private var checkJacksonVersionCompatibility: Boolean = true
private var jsonMapper: JsonMapper = jsonMapper()
private var streamHandlerExecutor: Executor? = null
private var sleeper: Sleeper? = null
private var clock: Clock = Clock.systemUTC()
private var baseUrl: String? = null
private var headers: Headers.Builder = Headers.builder()
Expand All @@ -169,6 +180,7 @@ private constructor(
checkJacksonVersionCompatibility = clientOptions.checkJacksonVersionCompatibility
jsonMapper = clientOptions.jsonMapper
streamHandlerExecutor = clientOptions.streamHandlerExecutor
sleeper = clientOptions.sleeper
clock = clientOptions.clock
baseUrl = clientOptions.baseUrl
headers = clientOptions.headers.toBuilder()
Expand Down Expand Up @@ -224,6 +236,17 @@ private constructor(
else streamHandlerExecutor
}

/**
* The interface to use for delaying execution, like during retries.
*
* This is primarily useful for using fake delays in tests.
*
* Defaults to real execution delays.
*
* This class takes ownership of the sleeper and closes it when closed.
*/
fun sleeper(sleeper: Sleeper) = apply { this.sleeper = PhantomReachableSleeper(sleeper) }

/**
* The clock to use for operations that require timing, like retries.
*
Expand Down Expand Up @@ -422,6 +445,25 @@ private constructor(
*/
fun build(): ClientOptions {
val httpClient = checkRequired("httpClient", httpClient)
val streamHandlerExecutor =
streamHandlerExecutor
?: PhantomReachableExecutorService(
Executors.newCachedThreadPool(
object : ThreadFactory {

private val threadFactory: ThreadFactory =
Executors.defaultThreadFactory()
private val count = AtomicLong(0)

override fun newThread(runnable: Runnable): Thread =
threadFactory.newThread(runnable).also {
it.name =
"lithic-stream-handler-thread-${count.getAndIncrement()}"
}
}
)
)
val sleeper = sleeper ?: PhantomReachableSleeper(DefaultSleeper())
val apiKey = checkRequired("apiKey", apiKey)

val headers = Headers.builder()
Expand All @@ -446,26 +488,14 @@ private constructor(
httpClient,
RetryingHttpClient.builder()
.httpClient(httpClient)
.sleeper(sleeper)
.clock(clock)
.maxRetries(maxRetries)
.build(),
checkJacksonVersionCompatibility,
jsonMapper,
streamHandlerExecutor
?: Executors.newCachedThreadPool(
object : ThreadFactory {

private val threadFactory: ThreadFactory =
Executors.defaultThreadFactory()
private val count = AtomicLong(0)

override fun newThread(runnable: Runnable): Thread =
threadFactory.newThread(runnable).also {
it.name =
"lithic-stream-handler-thread-${count.getAndIncrement()}"
}
}
),
streamHandlerExecutor,
sleeper,
clock,
baseUrl,
headers.build(),
Expand All @@ -492,5 +522,6 @@ private constructor(
fun close() {
httpClient.close()
(streamHandlerExecutor as? ExecutorService)?.shutdown()
sleeper.close()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.lithic.api.core

import java.time.Duration
import java.util.Timer
import java.util.TimerTask
import java.util.concurrent.CompletableFuture

class DefaultSleeper : Sleeper {

private val timer = Timer("DefaultSleeper", true)

override fun sleep(duration: Duration) = Thread.sleep(duration.toMillis())

override fun sleepAsync(duration: Duration): CompletableFuture<Void> {
val future = CompletableFuture<Void>()
timer.schedule(
object : TimerTask() {
override fun run() {
future.complete(null)
}
},
duration.toMillis(),
)
return future
}

override fun close() = timer.cancel()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.lithic.api.core

import java.time.Duration
import java.util.concurrent.CompletableFuture

/**
* A delegating wrapper around a [Sleeper] that closes it once it's only phantom reachable.
*
* This class ensures the [Sleeper] is closed even if the user forgets to do it.
*/
internal class PhantomReachableSleeper(private val sleeper: Sleeper) : Sleeper {

init {
closeWhenPhantomReachable(this, sleeper)
}

override fun sleep(duration: Duration) = sleeper.sleep(duration)

override fun sleepAsync(duration: Duration): CompletableFuture<Void> =
sleeper.sleepAsync(duration)

override fun close() = sleeper.close()
}
21 changes: 21 additions & 0 deletions lithic-java-core/src/main/kotlin/com/lithic/api/core/Sleeper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.lithic.api.core

import java.time.Duration
import java.util.concurrent.CompletableFuture

/**
* An interface for delaying execution for a specified amount of time.
*
* Useful for testing and cleaning up resources.
*/
interface Sleeper : AutoCloseable {

/** Synchronously pauses execution for the given [duration]. */
fun sleep(duration: Duration)

/** Asynchronously pauses execution for the given [duration]. */
fun sleepAsync(duration: Duration): CompletableFuture<Void>

/** Overridden from [AutoCloseable] to not have a checked exception in its signature. */
override fun close()
}
Loading