interceptors = httpClientBuilder.interceptors();
+ for (int i = 0; i < interceptors.size(); i++) {
+ if (interceptors.get(i) instanceof RetryInterceptor) {
+ interceptors.set(
+ i,
+ new RetryInterceptor(
+ this.maxRetries,
+ this.initialRetryDelayMillis,
+ this.maxRetryDelayMillis,
+ this.retryJitterFactor,
+ this.retryOnStatusCodes,
+ this.retryDelays));
+ }
+ }
} else {
httpClientBuilder
.callTimeout(this.timeout.orElse(60), TimeUnit.SECONDS)
@@ -334,9 +435,18 @@ public ClientOptions build() {
this.maxRetries,
this.initialRetryDelayMillis,
this.maxRetryDelayMillis,
- this.retryJitterFactor));
+ this.retryJitterFactor,
+ this.retryOnStatusCodes,
+ this.retryDelays));
}
+ this.maxConcurrentRequests.ifPresent(limit -> {
+ httpClientBuilder
+ .interceptors()
+ .removeIf(interceptor -> interceptor instanceof ConcurrencyLimitingInterceptor);
+ httpClientBuilder.addInterceptor(new ConcurrencyLimitingInterceptor(limit));
+ });
+
Logger logger = Logger.from(this.logging);
httpClientBuilder.addInterceptor(new LoggingInterceptor(logger));
httpClientBuilder.addInterceptor(new ResponseDecompressionInterceptor());
@@ -361,6 +471,8 @@ public ClientOptions build() {
this.initialRetryDelayMillis,
this.maxRetryDelayMillis,
this.retryJitterFactor,
+ this.retryOnStatusCodes,
+ this.retryDelays,
this.logging);
}
@@ -381,6 +493,8 @@ public static Builder from(ClientOptions clientOptions) {
builder.initialRetryDelayMillis = clientOptions.initialRetryDelayMillis();
builder.maxRetryDelayMillis = clientOptions.maxRetryDelayMillis();
builder.retryJitterFactor = clientOptions.retryJitterFactor();
+ builder.retryOnStatusCodes = clientOptions.retryOnStatusCodes();
+ builder.retryDelays = clientOptions.retryDelays();
builder.logging = clientOptions.logging();
return builder;
}
diff --git a/src/main/java/com/schematic/api/core/ConcurrencyLimitingInterceptor.java b/src/main/java/com/schematic/api/core/ConcurrencyLimitingInterceptor.java
new file mode 100644
index 00000000..b9e60cbe
--- /dev/null
+++ b/src/main/java/com/schematic/api/core/ConcurrencyLimitingInterceptor.java
@@ -0,0 +1,150 @@
+/**
+ * This file was auto-generated by Fern from our API Definition.
+ */
+package com.schematic.api.core;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import okhttp3.Call;
+import okhttp3.Interceptor;
+import okhttp3.MediaType;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import okio.BufferedSource;
+import okio.ForwardingSource;
+import okio.Okio;
+
+/**
+ * Caps how many requests are in flight at the same time. OkHttp itself only bounds idle connections (the connection
+ * pool) and asynchronous calls (the dispatcher), so a synchronous client is otherwise limited only by the number of
+ * calling threads.
+ *
+ * A permit is taken before a request is sent and handed back once its response body has been closed (or the
+ * request failed), so both {@code execute()} and {@code enqueue()} callers are bounded. A caller waiting for a permit
+ * gives up as soon as its call is cancelled, which is also what the call timeout does when it fires, so the wait never
+ * outlives the call timeout. Retries scheduled by {@code RetryInterceptor} release their permit while they wait for
+ * the backoff delay, because that interceptor runs before this one.
+ *
+ *
The generated clients always close response bodies (try-with-resources). Code that uses the {@code OkHttpClient}
+ * directly must do the same: a response body that is never closed keeps its permit for good.
+ */
+public class ConcurrencyLimitingInterceptor implements Interceptor {
+
+ private static final long CANCELLATION_POLL_NANOS = TimeUnit.MILLISECONDS.toNanos(100);
+
+ private final int maxConcurrentRequests;
+ private final Semaphore permits;
+
+ public ConcurrencyLimitingInterceptor(int maxConcurrentRequests) {
+ if (maxConcurrentRequests <= 0) {
+ throw new IllegalArgumentException("maxConcurrentRequests must be positive");
+ }
+ this.maxConcurrentRequests = maxConcurrentRequests;
+ this.permits = new Semaphore(maxConcurrentRequests, true);
+ }
+
+ public int getMaxConcurrentRequests() {
+ return maxConcurrentRequests;
+ }
+
+ /** Number of requests that could start right now without waiting. */
+ public int availablePermits() {
+ return permits.availablePermits();
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ acquirePermit(chain.call());
+ Response response;
+ try {
+ response = chain.proceed(chain.request());
+ } catch (Throwable t) {
+ permits.release();
+ throw t;
+ }
+ ResponseBody body = response.body();
+ if (body == null) {
+ permits.release();
+ return response;
+ }
+ return response.newBuilder()
+ .body(new PermitReleasingResponseBody(body, permits))
+ .build();
+ }
+
+ /**
+ * Waits for a permit in short slices so that cancellation of the call (explicit, or by OkHttp's call timeout
+ * watchdog) is honoured promptly. The configured call timeout is also applied as an absolute upper bound.
+ */
+ private void acquirePermit(Call call) throws IOException {
+ long callTimeoutNanos = call.timeout().timeoutNanos();
+ long deadlineNanos = callTimeoutNanos > 0 ? System.nanoTime() + callTimeoutNanos : Long.MAX_VALUE;
+ try {
+ while (true) {
+ if (call.isCanceled()) {
+ throw new IOException("Canceled");
+ }
+ long waitNanos = CANCELLATION_POLL_NANOS;
+ if (deadlineNanos != Long.MAX_VALUE) {
+ long remainingNanos = deadlineNanos - System.nanoTime();
+ if (remainingNanos <= 0) {
+ throw new InterruptedIOException("Timed out waiting for one of " + maxConcurrentRequests
+ + " concurrent request permits");
+ }
+ waitNanos = Math.min(waitNanos, remainingNanos);
+ }
+ if (permits.tryAcquire(waitNanos, TimeUnit.NANOSECONDS)) {
+ return;
+ }
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ InterruptedIOException interrupted =
+ new InterruptedIOException("Interrupted while waiting for a concurrent request permit");
+ interrupted.initCause(e);
+ throw interrupted;
+ }
+ }
+
+ /** Closes the wrapped body and releases the permit exactly once, when the body is closed. */
+ private static final class PermitReleasingResponseBody extends ResponseBody {
+
+ private final ResponseBody delegate;
+ private final BufferedSource source;
+ private final AtomicBoolean released = new AtomicBoolean(false);
+
+ PermitReleasingResponseBody(ResponseBody delegate, Semaphore permits) {
+ this.delegate = delegate;
+ this.source = Okio.buffer(new ForwardingSource(delegate.source()) {
+ @Override
+ public void close() throws IOException {
+ try {
+ delegate.close();
+ } finally {
+ if (released.compareAndSet(false, true)) {
+ permits.release();
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public MediaType contentType() {
+ return delegate.contentType();
+ }
+
+ @Override
+ public long contentLength() {
+ return delegate.contentLength();
+ }
+
+ @Override
+ public BufferedSource source() {
+ return source;
+ }
+ }
+}
diff --git a/src/main/java/com/schematic/api/core/ObjectMappers.java b/src/main/java/com/schematic/api/core/ObjectMappers.java
index 245e74e6..771068b8 100644
--- a/src/main/java/com/schematic/api/core/ObjectMappers.java
+++ b/src/main/java/com/schematic/api/core/ObjectMappers.java
@@ -3,34 +3,27 @@
*/
package com.schematic.api.core;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.IOException;
public final class ObjectMappers {
- public static final ObjectMapper JSON_MAPPER = JsonMapper.builder()
- .addModule(new Jdk8Module())
- .addModule(new JavaTimeModule())
- .addModule(DateTimeDeserializer.getModule())
- .addModule(DoubleSerializer.getModule())
+ public static final ObjectMapper JSON_MAPPER = new ObjectMapper()
+ .registerModule(new Jdk8Module())
+ .registerModule(new JavaTimeModule())
+ .registerModule(DateTimeDeserializer.getModule())
+ .registerModule(DoubleSerializer.getModule())
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
- .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
- .build();
+ .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
private ObjectMappers() {}
public static String stringify(Object o) {
try {
- return JSON_MAPPER
- .setSerializationInclusion(JsonInclude.Include.ALWAYS)
- .writerWithDefaultPrettyPrinter()
- .writeValueAsString(o);
+ return JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(o);
} catch (IOException e) {
return o.getClass().getName() + "@" + Integer.toHexString(o.hashCode());
}
@@ -39,7 +32,7 @@ public static String stringify(Object o) {
public static Object parseErrorBody(String responseBodyString) {
try {
return JSON_MAPPER.readValue(responseBodyString, Object.class);
- } catch (JsonProcessingException ignored) {
+ } catch (IOException ignored) {
return responseBodyString;
}
}
diff --git a/src/main/java/com/schematic/api/core/RetryInterceptor.java b/src/main/java/com/schematic/api/core/RetryInterceptor.java
index cc0f24ed..509fe653 100644
--- a/src/main/java/com/schematic/api/core/RetryInterceptor.java
+++ b/src/main/java/com/schematic/api/core/RetryInterceptor.java
@@ -9,8 +9,13 @@
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
import java.util.Optional;
import java.util.Random;
+import java.util.Set;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -34,6 +39,8 @@ public class RetryInterceptor implements Interceptor {
private final Duration initialRetryDelay;
private final Duration maxRetryDelay;
private final double jitterFactor;
+ private final Optional> retryOnStatusCodes;
+ private final Optional> retryDelays;
private final Random random = new Random();
public RetryInterceptor(int maxRetries) {
@@ -45,6 +52,41 @@ public RetryInterceptor(
Optional initialRetryDelayMillis,
Optional maxRetryDelayMillis,
Optional jitterFactor) {
+ this(maxRetries, initialRetryDelayMillis, maxRetryDelayMillis, jitterFactor, Optional.empty());
+ }
+
+ /**
+ * @param retryOnStatusCodes when present, the only HTTP status codes that trigger a retry; when empty, the
+ * generated default set (see {@link #shouldRetry(int)}) is used.
+ */
+ public RetryInterceptor(
+ int maxRetries,
+ Optional initialRetryDelayMillis,
+ Optional maxRetryDelayMillis,
+ Optional jitterFactor,
+ Optional> retryOnStatusCodes) {
+ this(
+ maxRetries,
+ initialRetryDelayMillis,
+ maxRetryDelayMillis,
+ jitterFactor,
+ retryOnStatusCodes,
+ Optional.empty());
+ }
+
+ /**
+ * @param retryDelays when present, an explicit retry schedule: the n-th retry waits for the n-th duration and the
+ * call stops retrying once the list is exhausted, so its size replaces {@code maxRetries} (a per-request
+ * {@link MaxRetriesOverride} can still lower the count). The exponential backoff settings are not used, but a
+ * {@code Retry-After} / {@code X-RateLimit-Reset} header still takes precedence over the scheduled delay.
+ */
+ public RetryInterceptor(
+ int maxRetries,
+ Optional initialRetryDelayMillis,
+ Optional maxRetryDelayMillis,
+ Optional jitterFactor,
+ Optional> retryOnStatusCodes,
+ Optional> retryDelays) {
initialRetryDelayMillis.ifPresent(delay -> {
if (delay < 0) {
throw new IllegalArgumentException("initialRetryDelayMillis must be non-negative");
@@ -64,6 +106,31 @@ public RetryInterceptor(
this.initialRetryDelay = initialRetryDelayMillis.map(Duration::ofMillis).orElse(DEFAULT_INITIAL_RETRY_DELAY);
this.maxRetryDelay = maxRetryDelayMillis.map(Duration::ofMillis).orElse(DEFAULT_MAX_RETRY_DELAY);
this.jitterFactor = jitterFactor.orElse(DEFAULT_JITTER_FACTOR);
+ this.retryOnStatusCodes = retryOnStatusCodes.map(RetryInterceptor::copyStatusCodes);
+ this.retryDelays = retryDelays.map(RetryInterceptor::copyRetryDelays);
+ }
+
+ private static List copyRetryDelays(List delays) {
+ List copy = new ArrayList<>(delays.size());
+ for (Duration delay : delays) {
+ if (delay == null || delay.isNegative()) {
+ throw new IllegalArgumentException("retryDelays must only contain non-negative durations: " + delay);
+ }
+ copy.add(delay);
+ }
+ return Collections.unmodifiableList(copy);
+ }
+
+ private static Set copyStatusCodes(Set statusCodes) {
+ Set copy = new HashSet<>();
+ for (Integer statusCode : statusCodes) {
+ if (statusCode == null || statusCode < 100 || statusCode > 599) {
+ throw new IllegalArgumentException(
+ "retryOnStatusCodes contains an invalid HTTP status code: " + statusCode);
+ }
+ copy.add(statusCode);
+ }
+ return Collections.unmodifiableSet(copy);
}
@Override
@@ -85,6 +152,10 @@ public Response intercept(Chain chain) throws IOException {
private int resolveMaxRetries(Request request) {
MaxRetriesOverride override = request.tag(MaxRetriesOverride.class);
+ if (retryDelays.isPresent()) {
+ int scheduled = retryDelays.get().size();
+ return override != null ? Math.min(override.getValue(), scheduled) : scheduled;
+ }
return override != null ? override.getValue() : this.maxRetries;
}
@@ -171,6 +242,7 @@ private static ScheduledThreadPoolExecutor create() {
}
private static final class AsyncRetryingCall implements AsyncCall, Callback {
+ private final RetryInterceptor retryInterceptor;
private final OkHttpClient client;
private final Request request;
private final ExponentialBackoff backoff;
@@ -186,6 +258,7 @@ private static final class AsyncRetryingCall implements AsyncCall, Callback {
private boolean completed;
AsyncRetryingCall(RetryInterceptor retryInterceptor, OkHttpClient client, Request request, int maxRetries) {
+ this.retryInterceptor = retryInterceptor;
this.client = client;
this.request = request.newBuilder()
.tag(AsyncAttempt.class, AsyncAttempt.INSTANCE)
@@ -242,7 +315,7 @@ private void startRetry() {
@Override
public void onResponse(Call call, Response response) throws IOException {
- if (backoff != null && shouldRetry(response.code())) {
+ if (backoff != null && retryInterceptor.shouldRetry(response.code())) {
Optional delay = backoff.nextBackoff(response);
if (delay.isPresent()) {
Response buffered = bufferResponse(response);
@@ -440,6 +513,13 @@ private Duration getRetryDelayFromHeaders(Response response, int retryAttempt) {
}
}
+ // An explicit schedule replaces exponential backoff (no jitter: the caller chose the exact delays). The
+ // attempt count is bounded by the schedule size in resolveMaxRetries; clamp defensively anyway.
+ if (retryDelays.isPresent() && !retryDelays.get().isEmpty()) {
+ List schedule = retryDelays.get();
+ return schedule.get(Math.min(retryAttempt, schedule.size() - 1));
+ }
+
// Fall back to exponential backoff, with symmetric jitter
long initialDelayMillis = initialRetryDelay.toMillis();
long maxDelayMillis = maxRetryDelay.toMillis();
@@ -499,7 +579,10 @@ private long addSymmetricJitter(long delayMs) {
return (long) (delayMs * jitterMultiplier);
}
- private static boolean shouldRetry(int statusCode) {
+ private boolean shouldRetry(int statusCode) {
+ if (retryOnStatusCodes.isPresent()) {
+ return retryOnStatusCodes.get().contains(statusCode);
+ }
return statusCode == 408 || statusCode == 429 || statusCode >= 500;
}
diff --git a/src/main/java/com/schematic/api/resources/accounts/AsyncRawAccountsClient.java b/src/main/java/com/schematic/api/resources/accounts/AsyncRawAccountsClient.java
index 0acf2be4..302783d8 100644
--- a/src/main/java/com/schematic/api/resources/accounts/AsyncRawAccountsClient.java
+++ b/src/main/java/com/schematic/api/resources/accounts/AsyncRawAccountsClient.java
@@ -777,6 +777,10 @@ public CompletableFuture> listA
QueryStringMapper.addQueryParameter(
httpUrl, "actor_type", request.getActorType().get(), false);
}
+ if (request.getCompanyId().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl, "company_id", request.getCompanyId().get(), false);
+ }
if (request.getEndTime().isPresent()) {
QueryStringMapper.addQueryParameter(
httpUrl, "end_time", request.getEndTime().get(), false);
@@ -1014,6 +1018,10 @@ public CompletableFuture> coun
QueryStringMapper.addQueryParameter(
httpUrl, "actor_type", request.getActorType().get(), false);
}
+ if (request.getCompanyId().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl, "company_id", request.getCompanyId().get(), false);
+ }
if (request.getEndTime().isPresent()) {
QueryStringMapper.addQueryParameter(
httpUrl, "end_time", request.getEndTime().get(), false);
diff --git a/src/main/java/com/schematic/api/resources/accounts/RawAccountsClient.java b/src/main/java/com/schematic/api/resources/accounts/RawAccountsClient.java
index 19f919ff..58ab83a8 100644
--- a/src/main/java/com/schematic/api/resources/accounts/RawAccountsClient.java
+++ b/src/main/java/com/schematic/api/resources/accounts/RawAccountsClient.java
@@ -584,6 +584,10 @@ public BaseSchematicHttpResponse listAuditLogs(
QueryStringMapper.addQueryParameter(
httpUrl, "actor_type", request.getActorType().get(), false);
}
+ if (request.getCompanyId().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl, "company_id", request.getCompanyId().get(), false);
+ }
if (request.getEndTime().isPresent()) {
QueryStringMapper.addQueryParameter(
httpUrl, "end_time", request.getEndTime().get(), false);
@@ -759,6 +763,10 @@ public BaseSchematicHttpResponse countAuditLogs(
QueryStringMapper.addQueryParameter(
httpUrl, "actor_type", request.getActorType().get(), false);
}
+ if (request.getCompanyId().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl, "company_id", request.getCompanyId().get(), false);
+ }
if (request.getEndTime().isPresent()) {
QueryStringMapper.addQueryParameter(
httpUrl, "end_time", request.getEndTime().get(), false);
diff --git a/src/main/java/com/schematic/api/resources/accounts/requests/CountAuditLogsRequest.java b/src/main/java/com/schematic/api/resources/accounts/requests/CountAuditLogsRequest.java
index 58bed38f..e52fcb7b 100644
--- a/src/main/java/com/schematic/api/resources/accounts/requests/CountAuditLogsRequest.java
+++ b/src/main/java/com/schematic/api/resources/accounts/requests/CountAuditLogsRequest.java
@@ -24,6 +24,8 @@
public final class CountAuditLogsRequest {
private final Optional actorType;
+ private final Optional companyId;
+
private final Optional endTime;
private final Optional environmentId;
@@ -40,6 +42,7 @@ public final class CountAuditLogsRequest {
private CountAuditLogsRequest(
Optional actorType,
+ Optional companyId,
Optional endTime,
Optional environmentId,
Optional q,
@@ -48,6 +51,7 @@ private CountAuditLogsRequest(
Optional offset,
Map additionalProperties) {
this.actorType = actorType;
+ this.companyId = companyId;
this.endTime = endTime;
this.environmentId = environmentId;
this.q = q;
@@ -62,6 +66,11 @@ public Optional getActorType() {
return actorType;
}
+ @JsonProperty("company_id")
+ public Optional getCompanyId() {
+ return companyId;
+ }
+
@JsonProperty("end_time")
public Optional getEndTime() {
return endTime;
@@ -111,6 +120,7 @@ public Map getAdditionalProperties() {
private boolean equalTo(CountAuditLogsRequest other) {
return actorType.equals(other.actorType)
+ && companyId.equals(other.companyId)
&& endTime.equals(other.endTime)
&& environmentId.equals(other.environmentId)
&& q.equals(other.q)
@@ -122,7 +132,14 @@ private boolean equalTo(CountAuditLogsRequest other) {
@java.lang.Override
public int hashCode() {
return Objects.hash(
- this.actorType, this.endTime, this.environmentId, this.q, this.startTime, this.limit, this.offset);
+ this.actorType,
+ this.companyId,
+ this.endTime,
+ this.environmentId,
+ this.q,
+ this.startTime,
+ this.limit,
+ this.offset);
}
@java.lang.Override
@@ -138,6 +155,8 @@ public static Builder builder() {
public static final class Builder {
private Optional actorType = Optional.empty();
+ private Optional companyId = Optional.empty();
+
private Optional endTime = Optional.empty();
private Optional environmentId = Optional.empty();
@@ -156,6 +175,7 @@ private Builder() {}
public Builder from(CountAuditLogsRequest other) {
actorType(other.getActorType());
+ companyId(other.getCompanyId());
endTime(other.getEndTime());
environmentId(other.getEnvironmentId());
q(other.getQ());
@@ -176,6 +196,17 @@ public Builder actorType(ActorType actorType) {
return this;
}
+ @JsonSetter(value = "company_id", nulls = Nulls.SKIP)
+ public Builder companyId(Optional companyId) {
+ this.companyId = companyId;
+ return this;
+ }
+
+ public Builder companyId(String companyId) {
+ this.companyId = Optional.ofNullable(companyId);
+ return this;
+ }
+
@JsonSetter(value = "end_time", nulls = Nulls.SKIP)
public Builder endTime(Optional endTime) {
this.endTime = endTime;
@@ -250,12 +281,13 @@ public Builder offset(Long offset) {
public CountAuditLogsRequest build() {
return new CountAuditLogsRequest(
- actorType, endTime, environmentId, q, startTime, limit, offset, additionalProperties);
+ actorType, companyId, endTime, environmentId, q, startTime, limit, offset, additionalProperties);
}
@JsonAnySetter
private void putAdditionalPropertyFromJson(String key, Object value) {
if (key.equalsIgnoreCase("actor_type")
+ || key.equalsIgnoreCase("company_id")
|| key.equalsIgnoreCase("end_time")
|| key.equalsIgnoreCase("environment_id")
|| key.equalsIgnoreCase("q")
diff --git a/src/main/java/com/schematic/api/resources/accounts/requests/ListAuditLogsRequest.java b/src/main/java/com/schematic/api/resources/accounts/requests/ListAuditLogsRequest.java
index 9d6761b9..6f353985 100644
--- a/src/main/java/com/schematic/api/resources/accounts/requests/ListAuditLogsRequest.java
+++ b/src/main/java/com/schematic/api/resources/accounts/requests/ListAuditLogsRequest.java
@@ -24,6 +24,8 @@
public final class ListAuditLogsRequest {
private final Optional actorType;
+ private final Optional companyId;
+
private final Optional endTime;
private final Optional environmentId;
@@ -40,6 +42,7 @@ public final class ListAuditLogsRequest {
private ListAuditLogsRequest(
Optional actorType,
+ Optional companyId,
Optional endTime,
Optional environmentId,
Optional q,
@@ -48,6 +51,7 @@ private ListAuditLogsRequest(
Optional offset,
Map additionalProperties) {
this.actorType = actorType;
+ this.companyId = companyId;
this.endTime = endTime;
this.environmentId = environmentId;
this.q = q;
@@ -62,6 +66,11 @@ public Optional getActorType() {
return actorType;
}
+ @JsonProperty("company_id")
+ public Optional getCompanyId() {
+ return companyId;
+ }
+
@JsonProperty("end_time")
public Optional getEndTime() {
return endTime;
@@ -111,6 +120,7 @@ public Map getAdditionalProperties() {
private boolean equalTo(ListAuditLogsRequest other) {
return actorType.equals(other.actorType)
+ && companyId.equals(other.companyId)
&& endTime.equals(other.endTime)
&& environmentId.equals(other.environmentId)
&& q.equals(other.q)
@@ -122,7 +132,14 @@ private boolean equalTo(ListAuditLogsRequest other) {
@java.lang.Override
public int hashCode() {
return Objects.hash(
- this.actorType, this.endTime, this.environmentId, this.q, this.startTime, this.limit, this.offset);
+ this.actorType,
+ this.companyId,
+ this.endTime,
+ this.environmentId,
+ this.q,
+ this.startTime,
+ this.limit,
+ this.offset);
}
@java.lang.Override
@@ -138,6 +155,8 @@ public static Builder builder() {
public static final class Builder {
private Optional actorType = Optional.empty();
+ private Optional companyId = Optional.empty();
+
private Optional endTime = Optional.empty();
private Optional environmentId = Optional.empty();
@@ -156,6 +175,7 @@ private Builder() {}
public Builder from(ListAuditLogsRequest other) {
actorType(other.getActorType());
+ companyId(other.getCompanyId());
endTime(other.getEndTime());
environmentId(other.getEnvironmentId());
q(other.getQ());
@@ -176,6 +196,17 @@ public Builder actorType(ActorType actorType) {
return this;
}
+ @JsonSetter(value = "company_id", nulls = Nulls.SKIP)
+ public Builder companyId(Optional companyId) {
+ this.companyId = companyId;
+ return this;
+ }
+
+ public Builder companyId(String companyId) {
+ this.companyId = Optional.ofNullable(companyId);
+ return this;
+ }
+
@JsonSetter(value = "end_time", nulls = Nulls.SKIP)
public Builder endTime(Optional endTime) {
this.endTime = endTime;
@@ -250,12 +281,13 @@ public Builder offset(Long offset) {
public ListAuditLogsRequest build() {
return new ListAuditLogsRequest(
- actorType, endTime, environmentId, q, startTime, limit, offset, additionalProperties);
+ actorType, companyId, endTime, environmentId, q, startTime, limit, offset, additionalProperties);
}
@JsonAnySetter
private void putAdditionalPropertyFromJson(String key, Object value) {
if (key.equalsIgnoreCase("actor_type")
+ || key.equalsIgnoreCase("company_id")
|| key.equalsIgnoreCase("end_time")
|| key.equalsIgnoreCase("environment_id")
|| key.equalsIgnoreCase("q")
diff --git a/src/main/java/com/schematic/api/resources/accounts/types/CountAuditLogsParams.java b/src/main/java/com/schematic/api/resources/accounts/types/CountAuditLogsParams.java
index 694d7a7c..1fa59135 100644
--- a/src/main/java/com/schematic/api/resources/accounts/types/CountAuditLogsParams.java
+++ b/src/main/java/com/schematic/api/resources/accounts/types/CountAuditLogsParams.java
@@ -24,6 +24,8 @@
public final class CountAuditLogsParams {
private final Optional actorType;
+ private final Optional companyId;
+
private final Optional endTime;
private final Optional environmentId;
@@ -40,6 +42,7 @@ public final class CountAuditLogsParams {
private CountAuditLogsParams(
Optional actorType,
+ Optional companyId,
Optional endTime,
Optional environmentId,
Optional limit,
@@ -48,6 +51,7 @@ private CountAuditLogsParams(
Optional startTime,
Map additionalProperties) {
this.actorType = actorType;
+ this.companyId = companyId;
this.endTime = endTime;
this.environmentId = environmentId;
this.limit = limit;
@@ -62,6 +66,11 @@ public Optional getActorType() {
return actorType;
}
+ @JsonProperty("company_id")
+ public Optional getCompanyId() {
+ return companyId;
+ }
+
@JsonProperty("end_time")
public Optional getEndTime() {
return endTime;
@@ -111,6 +120,7 @@ public Map getAdditionalProperties() {
private boolean equalTo(CountAuditLogsParams other) {
return actorType.equals(other.actorType)
+ && companyId.equals(other.companyId)
&& endTime.equals(other.endTime)
&& environmentId.equals(other.environmentId)
&& limit.equals(other.limit)
@@ -122,7 +132,14 @@ private boolean equalTo(CountAuditLogsParams other) {
@java.lang.Override
public int hashCode() {
return Objects.hash(
- this.actorType, this.endTime, this.environmentId, this.limit, this.offset, this.q, this.startTime);
+ this.actorType,
+ this.companyId,
+ this.endTime,
+ this.environmentId,
+ this.limit,
+ this.offset,
+ this.q,
+ this.startTime);
}
@java.lang.Override
@@ -138,6 +155,8 @@ public static Builder builder() {
public static final class Builder {
private Optional actorType = Optional.empty();
+ private Optional companyId = Optional.empty();
+
private Optional endTime = Optional.empty();
private Optional environmentId = Optional.empty();
@@ -156,6 +175,7 @@ private Builder() {}
public Builder from(CountAuditLogsParams other) {
actorType(other.getActorType());
+ companyId(other.getCompanyId());
endTime(other.getEndTime());
environmentId(other.getEnvironmentId());
limit(other.getLimit());
@@ -176,6 +196,17 @@ public Builder actorType(ActorType actorType) {
return this;
}
+ @JsonSetter(value = "company_id", nulls = Nulls.SKIP)
+ public Builder companyId(Optional companyId) {
+ this.companyId = companyId;
+ return this;
+ }
+
+ public Builder companyId(String companyId) {
+ this.companyId = Optional.ofNullable(companyId);
+ return this;
+ }
+
@JsonSetter(value = "end_time", nulls = Nulls.SKIP)
public Builder endTime(Optional endTime) {
this.endTime = endTime;
@@ -250,12 +281,13 @@ public Builder startTime(OffsetDateTime startTime) {
public CountAuditLogsParams build() {
return new CountAuditLogsParams(
- actorType, endTime, environmentId, limit, offset, q, startTime, additionalProperties);
+ actorType, companyId, endTime, environmentId, limit, offset, q, startTime, additionalProperties);
}
@JsonAnySetter
private void putAdditionalPropertyFromJson(String key, Object value) {
if (key.equalsIgnoreCase("actor_type")
+ || key.equalsIgnoreCase("company_id")
|| key.equalsIgnoreCase("end_time")
|| key.equalsIgnoreCase("environment_id")
|| key.equalsIgnoreCase("limit")
diff --git a/src/main/java/com/schematic/api/resources/accounts/types/ListAuditLogsParams.java b/src/main/java/com/schematic/api/resources/accounts/types/ListAuditLogsParams.java
index 93b70e60..15630e44 100644
--- a/src/main/java/com/schematic/api/resources/accounts/types/ListAuditLogsParams.java
+++ b/src/main/java/com/schematic/api/resources/accounts/types/ListAuditLogsParams.java
@@ -24,6 +24,8 @@
public final class ListAuditLogsParams {
private final Optional actorType;
+ private final Optional companyId;
+
private final Optional endTime;
private final Optional environmentId;
@@ -40,6 +42,7 @@ public final class ListAuditLogsParams {
private ListAuditLogsParams(
Optional actorType,
+ Optional companyId,
Optional endTime,
Optional environmentId,
Optional limit,
@@ -48,6 +51,7 @@ private ListAuditLogsParams(
Optional startTime,
Map additionalProperties) {
this.actorType = actorType;
+ this.companyId = companyId;
this.endTime = endTime;
this.environmentId = environmentId;
this.limit = limit;
@@ -62,6 +66,11 @@ public Optional getActorType() {
return actorType;
}
+ @JsonProperty("company_id")
+ public Optional getCompanyId() {
+ return companyId;
+ }
+
@JsonProperty("end_time")
public Optional getEndTime() {
return endTime;
@@ -111,6 +120,7 @@ public Map getAdditionalProperties() {
private boolean equalTo(ListAuditLogsParams other) {
return actorType.equals(other.actorType)
+ && companyId.equals(other.companyId)
&& endTime.equals(other.endTime)
&& environmentId.equals(other.environmentId)
&& limit.equals(other.limit)
@@ -122,7 +132,14 @@ private boolean equalTo(ListAuditLogsParams other) {
@java.lang.Override
public int hashCode() {
return Objects.hash(
- this.actorType, this.endTime, this.environmentId, this.limit, this.offset, this.q, this.startTime);
+ this.actorType,
+ this.companyId,
+ this.endTime,
+ this.environmentId,
+ this.limit,
+ this.offset,
+ this.q,
+ this.startTime);
}
@java.lang.Override
@@ -138,6 +155,8 @@ public static Builder builder() {
public static final class Builder {
private Optional actorType = Optional.empty();
+ private Optional companyId = Optional.empty();
+
private Optional endTime = Optional.empty();
private Optional environmentId = Optional.empty();
@@ -156,6 +175,7 @@ private Builder() {}
public Builder from(ListAuditLogsParams other) {
actorType(other.getActorType());
+ companyId(other.getCompanyId());
endTime(other.getEndTime());
environmentId(other.getEnvironmentId());
limit(other.getLimit());
@@ -176,6 +196,17 @@ public Builder actorType(ActorType actorType) {
return this;
}
+ @JsonSetter(value = "company_id", nulls = Nulls.SKIP)
+ public Builder companyId(Optional companyId) {
+ this.companyId = companyId;
+ return this;
+ }
+
+ public Builder companyId(String companyId) {
+ this.companyId = Optional.ofNullable(companyId);
+ return this;
+ }
+
@JsonSetter(value = "end_time", nulls = Nulls.SKIP)
public Builder endTime(Optional endTime) {
this.endTime = endTime;
@@ -250,12 +281,13 @@ public Builder startTime(OffsetDateTime startTime) {
public ListAuditLogsParams build() {
return new ListAuditLogsParams(
- actorType, endTime, environmentId, limit, offset, q, startTime, additionalProperties);
+ actorType, companyId, endTime, environmentId, limit, offset, q, startTime, additionalProperties);
}
@JsonAnySetter
private void putAdditionalPropertyFromJson(String key, Object value) {
if (key.equalsIgnoreCase("actor_type")
+ || key.equalsIgnoreCase("company_id")
|| key.equalsIgnoreCase("end_time")
|| key.equalsIgnoreCase("environment_id")
|| key.equalsIgnoreCase("limit")
diff --git a/src/main/java/com/schematic/api/resources/billing/requests/UpdateCompanyBillingProfileRequestBody.java b/src/main/java/com/schematic/api/resources/billing/requests/UpdateCompanyBillingProfileRequestBody.java
index 5bc75edb..8c04bcfc 100644
--- a/src/main/java/com/schematic/api/resources/billing/requests/UpdateCompanyBillingProfileRequestBody.java
+++ b/src/main/java/com/schematic/api/resources/billing/requests/UpdateCompanyBillingProfileRequestBody.java
@@ -13,6 +13,8 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.schematic.api.core.ObjectMappers;
import com.schematic.api.types.BillingCollectionMethod;
+import com.schematic.api.types.Currency;
+import com.schematic.api.types.PaymentGating;
import com.schematic.api.types.ProrationBehavior;
import java.util.HashMap;
import java.util.Map;
@@ -25,12 +27,20 @@
public final class UpdateCompanyBillingProfileRequestBody {
private final BillingCollectionMethod collectionMethod;
+ private final Optional currency;
+
private final Optional daysUntilDue;
+ private final Optional gatingDays;
+
private final Optional isDefault;
private final Optional name;
+ private final Optional overdraftLimit;
+
+ private final Optional paymentGating;
+
private final Optional paymentMethodId;
private final Optional prorationBehavior;
@@ -39,16 +49,24 @@ public final class UpdateCompanyBillingProfileRequestBody {
private UpdateCompanyBillingProfileRequestBody(
BillingCollectionMethod collectionMethod,
+ Optional currency,
Optional daysUntilDue,
+ Optional gatingDays,
Optional isDefault,
Optional name,
+ Optional overdraftLimit,
+ Optional paymentGating,
Optional paymentMethodId,
Optional prorationBehavior,
Map additionalProperties) {
this.collectionMethod = collectionMethod;
+ this.currency = currency;
this.daysUntilDue = daysUntilDue;
+ this.gatingDays = gatingDays;
this.isDefault = isDefault;
this.name = name;
+ this.overdraftLimit = overdraftLimit;
+ this.paymentGating = paymentGating;
this.paymentMethodId = paymentMethodId;
this.prorationBehavior = prorationBehavior;
this.additionalProperties = additionalProperties;
@@ -59,11 +77,21 @@ public BillingCollectionMethod getCollectionMethod() {
return collectionMethod;
}
+ @JsonProperty("currency")
+ public Optional getCurrency() {
+ return currency;
+ }
+
@JsonProperty("days_until_due")
public Optional getDaysUntilDue() {
return daysUntilDue;
}
+ @JsonProperty("gating_days")
+ public Optional getGatingDays() {
+ return gatingDays;
+ }
+
@JsonProperty("is_default")
public Optional getIsDefault() {
return isDefault;
@@ -74,6 +102,16 @@ public Optional getName() {
return name;
}
+ @JsonProperty("overdraft_limit")
+ public Optional getOverdraftLimit() {
+ return overdraftLimit;
+ }
+
+ @JsonProperty("payment_gating")
+ public Optional getPaymentGating() {
+ return paymentGating;
+ }
+
@JsonProperty("payment_method_id")
public Optional getPaymentMethodId() {
return paymentMethodId;
@@ -98,9 +136,13 @@ public Map getAdditionalProperties() {
private boolean equalTo(UpdateCompanyBillingProfileRequestBody other) {
return collectionMethod.equals(other.collectionMethod)
+ && currency.equals(other.currency)
&& daysUntilDue.equals(other.daysUntilDue)
+ && gatingDays.equals(other.gatingDays)
&& isDefault.equals(other.isDefault)
&& name.equals(other.name)
+ && overdraftLimit.equals(other.overdraftLimit)
+ && paymentGating.equals(other.paymentGating)
&& paymentMethodId.equals(other.paymentMethodId)
&& prorationBehavior.equals(other.prorationBehavior);
}
@@ -109,9 +151,13 @@ private boolean equalTo(UpdateCompanyBillingProfileRequestBody other) {
public int hashCode() {
return Objects.hash(
this.collectionMethod,
+ this.currency,
this.daysUntilDue,
+ this.gatingDays,
this.isDefault,
this.name,
+ this.overdraftLimit,
+ this.paymentGating,
this.paymentMethodId,
this.prorationBehavior);
}
@@ -138,10 +184,18 @@ public interface _FinalStage {
_FinalStage additionalProperties(Map additionalProperties);
+ _FinalStage currency(Optional currency);
+
+ _FinalStage currency(Currency currency);
+
_FinalStage daysUntilDue(Optional daysUntilDue);
_FinalStage daysUntilDue(Long daysUntilDue);
+ _FinalStage gatingDays(Optional gatingDays);
+
+ _FinalStage gatingDays(Long gatingDays);
+
_FinalStage isDefault(Optional isDefault);
_FinalStage isDefault(Boolean isDefault);
@@ -150,6 +204,14 @@ public interface _FinalStage {
_FinalStage name(String name);
+ _FinalStage overdraftLimit(Optional overdraftLimit);
+
+ _FinalStage overdraftLimit(Long overdraftLimit);
+
+ _FinalStage paymentGating(Optional paymentGating);
+
+ _FinalStage paymentGating(PaymentGating paymentGating);
+
_FinalStage paymentMethodId(Optional paymentMethodId);
_FinalStage paymentMethodId(String paymentMethodId);
@@ -167,12 +229,20 @@ public static final class Builder implements CollectionMethodStage, _FinalStage
private Optional paymentMethodId = Optional.empty();
+ private Optional paymentGating = Optional.empty();
+
+ private Optional overdraftLimit = Optional.empty();
+
private Optional name = Optional.empty();
private Optional isDefault = Optional.empty();
+ private Optional gatingDays = Optional.empty();
+
private Optional daysUntilDue = Optional.empty();
+ private Optional currency = Optional.empty();
+
private Map additionalProperties = new HashMap<>();
private Builder() {}
@@ -180,9 +250,13 @@ private Builder() {}
@java.lang.Override
public Builder from(UpdateCompanyBillingProfileRequestBody other) {
collectionMethod(other.getCollectionMethod());
+ currency(other.getCurrency());
daysUntilDue(other.getDaysUntilDue());
+ gatingDays(other.getGatingDays());
isDefault(other.getIsDefault());
name(other.getName());
+ overdraftLimit(other.getOverdraftLimit());
+ paymentGating(other.getPaymentGating());
paymentMethodId(other.getPaymentMethodId());
prorationBehavior(other.getProrationBehavior());
return this;
@@ -221,6 +295,32 @@ public _FinalStage paymentMethodId(Optional paymentMethodId) {
return this;
}
+ @java.lang.Override
+ public _FinalStage paymentGating(PaymentGating paymentGating) {
+ this.paymentGating = Optional.ofNullable(paymentGating);
+ return this;
+ }
+
+ @java.lang.Override
+ @JsonSetter(value = "payment_gating", nulls = Nulls.SKIP)
+ public _FinalStage paymentGating(Optional paymentGating) {
+ this.paymentGating = paymentGating;
+ return this;
+ }
+
+ @java.lang.Override
+ public _FinalStage overdraftLimit(Long overdraftLimit) {
+ this.overdraftLimit = Optional.ofNullable(overdraftLimit);
+ return this;
+ }
+
+ @java.lang.Override
+ @JsonSetter(value = "overdraft_limit", nulls = Nulls.SKIP)
+ public _FinalStage overdraftLimit(Optional overdraftLimit) {
+ this.overdraftLimit = overdraftLimit;
+ return this;
+ }
+
@java.lang.Override
public _FinalStage name(String name) {
this.name = Optional.ofNullable(name);
@@ -247,6 +347,19 @@ public _FinalStage isDefault(Optional isDefault) {
return this;
}
+ @java.lang.Override
+ public _FinalStage gatingDays(Long gatingDays) {
+ this.gatingDays = Optional.ofNullable(gatingDays);
+ return this;
+ }
+
+ @java.lang.Override
+ @JsonSetter(value = "gating_days", nulls = Nulls.SKIP)
+ public _FinalStage gatingDays(Optional gatingDays) {
+ this.gatingDays = gatingDays;
+ return this;
+ }
+
@java.lang.Override
public _FinalStage daysUntilDue(Long daysUntilDue) {
this.daysUntilDue = Optional.ofNullable(daysUntilDue);
@@ -260,13 +373,30 @@ public _FinalStage daysUntilDue(Optional daysUntilDue) {
return this;
}
+ @java.lang.Override
+ public _FinalStage currency(Currency currency) {
+ this.currency = Optional.ofNullable(currency);
+ return this;
+ }
+
+ @java.lang.Override
+ @JsonSetter(value = "currency", nulls = Nulls.SKIP)
+ public _FinalStage currency(Optional currency) {
+ this.currency = currency;
+ return this;
+ }
+
@java.lang.Override
public UpdateCompanyBillingProfileRequestBody build() {
return new UpdateCompanyBillingProfileRequestBody(
collectionMethod,
+ currency,
daysUntilDue,
+ gatingDays,
isDefault,
name,
+ overdraftLimit,
+ paymentGating,
paymentMethodId,
prorationBehavior,
additionalProperties);
@@ -275,9 +405,13 @@ public UpdateCompanyBillingProfileRequestBody build() {
@JsonAnySetter
private void putAdditionalPropertyFromJson(String key, Object value) {
if (key.equalsIgnoreCase("collection_method")
+ || key.equalsIgnoreCase("currency")
|| key.equalsIgnoreCase("days_until_due")
+ || key.equalsIgnoreCase("gating_days")
|| key.equalsIgnoreCase("is_default")
|| key.equalsIgnoreCase("name")
+ || key.equalsIgnoreCase("overdraft_limit")
+ || key.equalsIgnoreCase("payment_gating")
|| key.equalsIgnoreCase("payment_method_id")
|| key.equalsIgnoreCase("proration_behavior")) {
return;
diff --git a/src/main/java/com/schematic/api/resources/companies/AsyncCompaniesClient.java b/src/main/java/com/schematic/api/resources/companies/AsyncCompaniesClient.java
index f404a284..4e3823f1 100644
--- a/src/main/java/com/schematic/api/resources/companies/AsyncCompaniesClient.java
+++ b/src/main/java/com/schematic/api/resources/companies/AsyncCompaniesClient.java
@@ -18,6 +18,7 @@
import com.schematic.api.resources.companies.requests.GetActiveCompanySubscriptionRequest;
import com.schematic.api.resources.companies.requests.GetBillingEntityChildSubscriptionsRequest;
import com.schematic.api.resources.companies.requests.GetCompanyBillingEntityRequest;
+import com.schematic.api.resources.companies.requests.GetCompanyInferenceCostRequest;
import com.schematic.api.resources.companies.requests.GetEntityTraitValuesRequest;
import com.schematic.api.resources.companies.requests.GetOrCreateCompanyMembershipRequestBody;
import com.schematic.api.resources.companies.requests.ListCompaniesRequest;
@@ -50,6 +51,7 @@
import com.schematic.api.resources.companies.types.GetActiveCompanySubscriptionResponse;
import com.schematic.api.resources.companies.types.GetBillingEntityChildSubscriptionsResponse;
import com.schematic.api.resources.companies.types.GetCompanyBillingEntityResponse;
+import com.schematic.api.resources.companies.types.GetCompanyInferenceCostResponse;
import com.schematic.api.resources.companies.types.GetCompanyResponse;
import com.schematic.api.resources.companies.types.GetEntityTraitDefinitionResponse;
import com.schematic.api.resources.companies.types.GetEntityTraitDefinitionUsageResponse;
@@ -243,6 +245,57 @@ public CompletableFuture deleteCompany(
return future;
}
+ public CompletableFuture getCompanyInferenceCost(String companyId) {
+ CompletableFuture> rawFuture =
+ this.rawClient.getCompanyInferenceCost(companyId);
+ CompletableFuture future = rawFuture.thenApply(response -> response.body());
+ future.whenComplete((result_, throwable_) -> {
+ if (future.isCancelled()) {
+ rawFuture.cancel(true);
+ }
+ });
+ return future;
+ }
+
+ public CompletableFuture getCompanyInferenceCost(
+ String companyId, RequestOptions requestOptions) {
+ CompletableFuture> rawFuture =
+ this.rawClient.getCompanyInferenceCost(companyId, requestOptions);
+ CompletableFuture future = rawFuture.thenApply(response -> response.body());
+ future.whenComplete((result_, throwable_) -> {
+ if (future.isCancelled()) {
+ rawFuture.cancel(true);
+ }
+ });
+ return future;
+ }
+
+ public CompletableFuture getCompanyInferenceCost(
+ String companyId, GetCompanyInferenceCostRequest request) {
+ CompletableFuture> rawFuture =
+ this.rawClient.getCompanyInferenceCost(companyId, request);
+ CompletableFuture future = rawFuture.thenApply(response -> response.body());
+ future.whenComplete((result_, throwable_) -> {
+ if (future.isCancelled()) {
+ rawFuture.cancel(true);
+ }
+ });
+ return future;
+ }
+
+ public CompletableFuture getCompanyInferenceCost(
+ String companyId, GetCompanyInferenceCostRequest request, RequestOptions requestOptions) {
+ CompletableFuture> rawFuture =
+ this.rawClient.getCompanyInferenceCost(companyId, request, requestOptions);
+ CompletableFuture future = rawFuture.thenApply(response -> response.body());
+ future.whenComplete((result_, throwable_) -> {
+ if (future.isCancelled()) {
+ rawFuture.cancel(true);
+ }
+ });
+ return future;
+ }
+
public CompletableFuture countCompanies() {
CompletableFuture> rawFuture =
this.rawClient.countCompanies();
diff --git a/src/main/java/com/schematic/api/resources/companies/AsyncRawCompaniesClient.java b/src/main/java/com/schematic/api/resources/companies/AsyncRawCompaniesClient.java
index fedc651c..8efd06c7 100644
--- a/src/main/java/com/schematic/api/resources/companies/AsyncRawCompaniesClient.java
+++ b/src/main/java/com/schematic/api/resources/companies/AsyncRawCompaniesClient.java
@@ -32,6 +32,7 @@
import com.schematic.api.resources.companies.requests.GetActiveCompanySubscriptionRequest;
import com.schematic.api.resources.companies.requests.GetBillingEntityChildSubscriptionsRequest;
import com.schematic.api.resources.companies.requests.GetCompanyBillingEntityRequest;
+import com.schematic.api.resources.companies.requests.GetCompanyInferenceCostRequest;
import com.schematic.api.resources.companies.requests.GetEntityTraitValuesRequest;
import com.schematic.api.resources.companies.requests.GetOrCreateCompanyMembershipRequestBody;
import com.schematic.api.resources.companies.requests.ListCompaniesRequest;
@@ -64,6 +65,7 @@
import com.schematic.api.resources.companies.types.GetActiveCompanySubscriptionResponse;
import com.schematic.api.resources.companies.types.GetBillingEntityChildSubscriptionsResponse;
import com.schematic.api.resources.companies.types.GetCompanyBillingEntityResponse;
+import com.schematic.api.resources.companies.types.GetCompanyInferenceCostResponse;
import com.schematic.api.resources.companies.types.GetCompanyResponse;
import com.schematic.api.resources.companies.types.GetEntityTraitDefinitionResponse;
import com.schematic.api.resources.companies.types.GetEntityTraitDefinitionUsageResponse;
@@ -132,6 +134,13 @@ public CompletableFuture> listC
HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl())
.newBuilder()
.addPathSegments("companies");
+ if (request.getCancelAtPeriodEnd().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl,
+ "cancel_at_period_end",
+ request.getCancelAtPeriodEnd().get(),
+ false);
+ }
if (request.getHasScheduledDowngrade().isPresent()) {
QueryStringMapper.addQueryParameter(
httpUrl,
@@ -672,6 +681,128 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) {
return future;
}
+ public CompletableFuture> getCompanyInferenceCost(
+ String companyId) {
+ return getCompanyInferenceCost(
+ companyId, GetCompanyInferenceCostRequest.builder().build());
+ }
+
+ public CompletableFuture> getCompanyInferenceCost(
+ String companyId, RequestOptions requestOptions) {
+ return getCompanyInferenceCost(
+ companyId, GetCompanyInferenceCostRequest.builder().build(), requestOptions);
+ }
+
+ public CompletableFuture> getCompanyInferenceCost(
+ String companyId, GetCompanyInferenceCostRequest request) {
+ return getCompanyInferenceCost(companyId, request, null);
+ }
+
+ public CompletableFuture> getCompanyInferenceCost(
+ String companyId, GetCompanyInferenceCostRequest request, RequestOptions requestOptions) {
+ HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl())
+ .newBuilder()
+ .addPathSegments("companies")
+ .addPathSegment(PathSegments.validate(companyId))
+ .addPathSegments("inference-cost");
+ if (request.getEndTime().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl, "end_time", request.getEndTime().get(), false);
+ }
+ if (request.getStartTime().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl, "start_time", request.getStartTime().get(), false);
+ }
+ if (requestOptions != null) {
+ requestOptions.getQueryParameters().forEach((_key, _value) -> {
+ httpUrl.addQueryParameter(_key, _value);
+ });
+ }
+ Request.Builder _requestBuilder = new Request.Builder()
+ .url(httpUrl.build())
+ .method("GET", null)
+ .headers(Headers.of(clientOptions.headers(requestOptions)))
+ .addHeader("Accept", "application/json");
+ Request okhttpRequest = _requestBuilder.build();
+ OkHttpClient client = clientOptions.httpClient();
+ if (requestOptions != null && requestOptions.getTimeout().isPresent()) {
+ client = clientOptions.httpClientWithTimeout(requestOptions);
+ }
+ if (requestOptions != null && requestOptions.getMaxRetries().isPresent()) {
+ okhttpRequest = okhttpRequest
+ .newBuilder()
+ .tag(
+ RetryInterceptor.MaxRetriesOverride.class,
+ new RetryInterceptor.MaxRetriesOverride(
+ requestOptions.getMaxRetries().get()))
+ .build();
+ }
+ CompletableFuture> future =
+ new CompletableFuture<>();
+ RetryInterceptor.AsyncCall okhttpCall = RetryInterceptor.newAsyncCall(client, okhttpRequest);
+ okhttpCall.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+ try (ResponseBody responseBody = response.body()) {
+ String responseBodyString = responseBody != null ? responseBody.string() : "{}";
+ if (response.isSuccessful()) {
+ future.complete(new BaseSchematicHttpResponse<>(
+ ObjectMappers.JSON_MAPPER.readValue(
+ responseBodyString, GetCompanyInferenceCostResponse.class),
+ response));
+ return;
+ }
+ try {
+ switch (response.code()) {
+ case 401:
+ future.completeExceptionally(new UnauthorizedError(
+ ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ApiError.class),
+ response));
+ return;
+ case 403:
+ future.completeExceptionally(new ForbiddenError(
+ ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ApiError.class),
+ response));
+ return;
+ case 404:
+ future.completeExceptionally(new NotFoundError(
+ ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ApiError.class),
+ response));
+ return;
+ case 500:
+ future.completeExceptionally(new InternalServerError(
+ ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ApiError.class),
+ response));
+ return;
+ }
+ } catch (JsonProcessingException ignored) {
+ // unable to map error response, throwing generic error
+ }
+ Object errorBody = ObjectMappers.parseErrorBody(responseBodyString);
+ future.completeExceptionally(new BaseSchematicApiException(
+ "Error with status code " + response.code(), response.code(), errorBody, response));
+ return;
+ } catch (JsonProcessingException e) {
+ future.completeExceptionally(
+ new BaseSchematicException("Failed to deserialize response: " + e.getMessage(), e));
+ } catch (IOException e) {
+ future.completeExceptionally(new BaseSchematicException("Network error executing HTTP request", e));
+ }
+ }
+
+ @Override
+ public void onFailure(@NotNull Call call, @NotNull IOException e) {
+ future.completeExceptionally(new BaseSchematicException("Network error executing HTTP request", e));
+ }
+ });
+ future.whenComplete((result_, throwable_) -> {
+ if (future.isCancelled()) {
+ okhttpCall.cancel();
+ }
+ });
+ return future;
+ }
+
public CompletableFuture> countCompanies() {
return countCompanies(CountCompaniesRequest.builder().build());
}
@@ -691,6 +822,13 @@ public CompletableFuture> coun
HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl())
.newBuilder()
.addPathSegments("companies/count");
+ if (request.getCancelAtPeriodEnd().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl,
+ "cancel_at_period_end",
+ request.getCancelAtPeriodEnd().get(),
+ false);
+ }
if (request.getHasScheduledDowngrade().isPresent()) {
QueryStringMapper.addQueryParameter(
httpUrl,
diff --git a/src/main/java/com/schematic/api/resources/companies/CompaniesClient.java b/src/main/java/com/schematic/api/resources/companies/CompaniesClient.java
index 7b6fe1c8..56ea3d42 100644
--- a/src/main/java/com/schematic/api/resources/companies/CompaniesClient.java
+++ b/src/main/java/com/schematic/api/resources/companies/CompaniesClient.java
@@ -17,6 +17,7 @@
import com.schematic.api.resources.companies.requests.GetActiveCompanySubscriptionRequest;
import com.schematic.api.resources.companies.requests.GetBillingEntityChildSubscriptionsRequest;
import com.schematic.api.resources.companies.requests.GetCompanyBillingEntityRequest;
+import com.schematic.api.resources.companies.requests.GetCompanyInferenceCostRequest;
import com.schematic.api.resources.companies.requests.GetEntityTraitValuesRequest;
import com.schematic.api.resources.companies.requests.GetOrCreateCompanyMembershipRequestBody;
import com.schematic.api.resources.companies.requests.ListCompaniesRequest;
@@ -49,6 +50,7 @@
import com.schematic.api.resources.companies.types.GetActiveCompanySubscriptionResponse;
import com.schematic.api.resources.companies.types.GetBillingEntityChildSubscriptionsResponse;
import com.schematic.api.resources.companies.types.GetCompanyBillingEntityResponse;
+import com.schematic.api.resources.companies.types.GetCompanyInferenceCostResponse;
import com.schematic.api.resources.companies.types.GetCompanyResponse;
import com.schematic.api.resources.companies.types.GetEntityTraitDefinitionResponse;
import com.schematic.api.resources.companies.types.GetEntityTraitDefinitionUsageResponse;
@@ -144,6 +146,26 @@ public DeleteCompanyResponse deleteCompany(
return this.rawClient.deleteCompany(companyId, request, requestOptions).body();
}
+ public GetCompanyInferenceCostResponse getCompanyInferenceCost(String companyId) {
+ return this.rawClient.getCompanyInferenceCost(companyId).body();
+ }
+
+ public GetCompanyInferenceCostResponse getCompanyInferenceCost(String companyId, RequestOptions requestOptions) {
+ return this.rawClient.getCompanyInferenceCost(companyId, requestOptions).body();
+ }
+
+ public GetCompanyInferenceCostResponse getCompanyInferenceCost(
+ String companyId, GetCompanyInferenceCostRequest request) {
+ return this.rawClient.getCompanyInferenceCost(companyId, request).body();
+ }
+
+ public GetCompanyInferenceCostResponse getCompanyInferenceCost(
+ String companyId, GetCompanyInferenceCostRequest request, RequestOptions requestOptions) {
+ return this.rawClient
+ .getCompanyInferenceCost(companyId, request, requestOptions)
+ .body();
+ }
+
public CountCompaniesResponse countCompanies() {
return this.rawClient.countCompanies().body();
}
diff --git a/src/main/java/com/schematic/api/resources/companies/RawCompaniesClient.java b/src/main/java/com/schematic/api/resources/companies/RawCompaniesClient.java
index fcf8ca68..03b0530a 100644
--- a/src/main/java/com/schematic/api/resources/companies/RawCompaniesClient.java
+++ b/src/main/java/com/schematic/api/resources/companies/RawCompaniesClient.java
@@ -32,6 +32,7 @@
import com.schematic.api.resources.companies.requests.GetActiveCompanySubscriptionRequest;
import com.schematic.api.resources.companies.requests.GetBillingEntityChildSubscriptionsRequest;
import com.schematic.api.resources.companies.requests.GetCompanyBillingEntityRequest;
+import com.schematic.api.resources.companies.requests.GetCompanyInferenceCostRequest;
import com.schematic.api.resources.companies.requests.GetEntityTraitValuesRequest;
import com.schematic.api.resources.companies.requests.GetOrCreateCompanyMembershipRequestBody;
import com.schematic.api.resources.companies.requests.ListCompaniesRequest;
@@ -64,6 +65,7 @@
import com.schematic.api.resources.companies.types.GetActiveCompanySubscriptionResponse;
import com.schematic.api.resources.companies.types.GetBillingEntityChildSubscriptionsResponse;
import com.schematic.api.resources.companies.types.GetCompanyBillingEntityResponse;
+import com.schematic.api.resources.companies.types.GetCompanyInferenceCostResponse;
import com.schematic.api.resources.companies.types.GetCompanyResponse;
import com.schematic.api.resources.companies.types.GetEntityTraitDefinitionResponse;
import com.schematic.api.resources.companies.types.GetEntityTraitDefinitionUsageResponse;
@@ -126,6 +128,13 @@ public BaseSchematicHttpResponse listCompanies(
HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl())
.newBuilder()
.addPathSegments("companies");
+ if (request.getCancelAtPeriodEnd().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl,
+ "cancel_at_period_end",
+ request.getCancelAtPeriodEnd().get(),
+ false);
+ }
if (request.getHasScheduledDowngrade().isPresent()) {
QueryStringMapper.addQueryParameter(
httpUrl,
@@ -542,6 +551,97 @@ public BaseSchematicHttpResponse deleteCompany(
}
}
+ public BaseSchematicHttpResponse getCompanyInferenceCost(String companyId) {
+ return getCompanyInferenceCost(
+ companyId, GetCompanyInferenceCostRequest.builder().build());
+ }
+
+ public BaseSchematicHttpResponse getCompanyInferenceCost(
+ String companyId, RequestOptions requestOptions) {
+ return getCompanyInferenceCost(
+ companyId, GetCompanyInferenceCostRequest.builder().build(), requestOptions);
+ }
+
+ public BaseSchematicHttpResponse getCompanyInferenceCost(
+ String companyId, GetCompanyInferenceCostRequest request) {
+ return getCompanyInferenceCost(companyId, request, null);
+ }
+
+ public BaseSchematicHttpResponse getCompanyInferenceCost(
+ String companyId, GetCompanyInferenceCostRequest request, RequestOptions requestOptions) {
+ HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl())
+ .newBuilder()
+ .addPathSegments("companies")
+ .addPathSegment(PathSegments.validate(companyId))
+ .addPathSegments("inference-cost");
+ if (request.getEndTime().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl, "end_time", request.getEndTime().get(), false);
+ }
+ if (request.getStartTime().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl, "start_time", request.getStartTime().get(), false);
+ }
+ if (requestOptions != null) {
+ requestOptions.getQueryParameters().forEach((_key, _value) -> {
+ httpUrl.addQueryParameter(_key, _value);
+ });
+ }
+ Request.Builder _requestBuilder = new Request.Builder()
+ .url(httpUrl.build())
+ .method("GET", null)
+ .headers(Headers.of(clientOptions.headers(requestOptions)))
+ .addHeader("Accept", "application/json");
+ Request okhttpRequest = _requestBuilder.build();
+ OkHttpClient client = clientOptions.httpClient();
+ if (requestOptions != null && requestOptions.getTimeout().isPresent()) {
+ client = clientOptions.httpClientWithTimeout(requestOptions);
+ }
+ if (requestOptions != null && requestOptions.getMaxRetries().isPresent()) {
+ okhttpRequest = okhttpRequest
+ .newBuilder()
+ .tag(
+ RetryInterceptor.MaxRetriesOverride.class,
+ new RetryInterceptor.MaxRetriesOverride(
+ requestOptions.getMaxRetries().get()))
+ .build();
+ }
+ try (Response response = client.newCall(okhttpRequest).execute()) {
+ ResponseBody responseBody = response.body();
+ String responseBodyString = responseBody != null ? responseBody.string() : "{}";
+ if (response.isSuccessful()) {
+ return new BaseSchematicHttpResponse<>(
+ ObjectMappers.JSON_MAPPER.readValue(responseBodyString, GetCompanyInferenceCostResponse.class),
+ response);
+ }
+ try {
+ switch (response.code()) {
+ case 401:
+ throw new UnauthorizedError(
+ ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ApiError.class), response);
+ case 403:
+ throw new ForbiddenError(
+ ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ApiError.class), response);
+ case 404:
+ throw new NotFoundError(
+ ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ApiError.class), response);
+ case 500:
+ throw new InternalServerError(
+ ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ApiError.class), response);
+ }
+ } catch (JsonProcessingException ignored) {
+ // unable to map error response, throwing generic error
+ }
+ Object errorBody = ObjectMappers.parseErrorBody(responseBodyString);
+ throw new BaseSchematicApiException(
+ "Error with status code " + response.code(), response.code(), errorBody, response);
+ } catch (JsonProcessingException e) {
+ throw new BaseSchematicException("Failed to deserialize response: " + e.getMessage(), e);
+ } catch (IOException e) {
+ throw new BaseSchematicException("Network error executing HTTP request", e);
+ }
+ }
+
public BaseSchematicHttpResponse countCompanies() {
return countCompanies(CountCompaniesRequest.builder().build());
}
@@ -559,6 +659,13 @@ public BaseSchematicHttpResponse countCompanies(
HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl())
.newBuilder()
.addPathSegments("companies/count");
+ if (request.getCancelAtPeriodEnd().isPresent()) {
+ QueryStringMapper.addQueryParameter(
+ httpUrl,
+ "cancel_at_period_end",
+ request.getCancelAtPeriodEnd().get(),
+ false);
+ }
if (request.getHasScheduledDowngrade().isPresent()) {
QueryStringMapper.addQueryParameter(
httpUrl,
diff --git a/src/main/java/com/schematic/api/resources/companies/requests/CountCompaniesRequest.java b/src/main/java/com/schematic/api/resources/companies/requests/CountCompaniesRequest.java
index 567a0e07..91fd1c42 100644
--- a/src/main/java/com/schematic/api/resources/companies/requests/CountCompaniesRequest.java
+++ b/src/main/java/com/schematic/api/resources/companies/requests/CountCompaniesRequest.java
@@ -37,6 +37,8 @@ public final class CountCompaniesRequest {
private final Optional> subscriptionTypes;
+ private final Optional cancelAtPeriodEnd;
+
private final Optional hasScheduledDowngrade;
private final Optional monetizedSubscriptions;
@@ -76,6 +78,7 @@ private CountCompaniesRequest(
Optional> planVersionIds,
Optional> subscriptionStatuses,
Optional> subscriptionTypes,
+ Optional cancelAtPeriodEnd,
Optional hasScheduledDowngrade,
Optional monetizedSubscriptions,
Optional planId,
@@ -98,6 +101,7 @@ private CountCompaniesRequest(
this.planVersionIds = planVersionIds;
this.subscriptionStatuses = subscriptionStatuses;
this.subscriptionTypes = subscriptionTypes;
+ this.cancelAtPeriodEnd = cancelAtPeriodEnd;
this.hasScheduledDowngrade = hasScheduledDowngrade;
this.monetizedSubscriptions = monetizedSubscriptions;
this.planId = planId;
@@ -165,7 +169,15 @@ public Optional> getSubscriptionTypes() {
}
/**
- * @return Filter companies that have a pending scheduled downgrade
+ * @return If true, filter companies with an active subscription that is set to cancel at the end of the current period; if false, filter companies without one
+ */
+ @JsonProperty("cancel_at_period_end")
+ public Optional getCancelAtPeriodEnd() {
+ return cancelAtPeriodEnd;
+ }
+
+ /**
+ * @return If true, filter companies that have a pending scheduled downgrade; if false, filter companies that do not
*/
@JsonProperty("has_scheduled_downgrade")
public Optional getHasScheduledDowngrade() {
@@ -302,6 +314,7 @@ private boolean equalTo(CountCompaniesRequest other) {
&& planVersionIds.equals(other.planVersionIds)
&& subscriptionStatuses.equals(other.subscriptionStatuses)
&& subscriptionTypes.equals(other.subscriptionTypes)
+ && cancelAtPeriodEnd.equals(other.cancelAtPeriodEnd)
&& hasScheduledDowngrade.equals(other.hasScheduledDowngrade)
&& monetizedSubscriptions.equals(other.monetizedSubscriptions)
&& planId.equals(other.planId)
@@ -328,6 +341,7 @@ public int hashCode() {
this.planVersionIds,
this.subscriptionStatuses,
this.subscriptionTypes,
+ this.cancelAtPeriodEnd,
this.hasScheduledDowngrade,
this.monetizedSubscriptions,
this.planId,
@@ -368,6 +382,8 @@ public static final class Builder {
private Optional> subscriptionTypes = Optional.empty();
+ private Optional cancelAtPeriodEnd = Optional.empty();
+
private Optional