up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
sdk-generator-smoke / sdk-smoke (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
sdk-generator-smoke / sdk-smoke (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
// Generated by StellaOps SDK generator — do not edit.
|
||||
package com.stellaops.sdk.hooks;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Logger;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public final class Hooks {
|
||||
private Hooks() {}
|
||||
|
||||
public static OkHttpClient withAll(OkHttpClient base, AuthProvider auth, RetryOptions retry,
|
||||
TelemetryOptions telemetry) {
|
||||
OkHttpClient.Builder builder = base.newBuilder();
|
||||
if (auth != null) {
|
||||
builder.addInterceptor(new StellaAuthInterceptor(auth));
|
||||
}
|
||||
if (telemetry != null) {
|
||||
builder.addInterceptor(new StellaTelemetryInterceptor(telemetry));
|
||||
}
|
||||
if (retry != null) {
|
||||
builder.addInterceptor(new StellaRetryInterceptor(retry));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public interface AuthProvider {
|
||||
String token();
|
||||
|
||||
default String headerName() {
|
||||
return "Authorization";
|
||||
}
|
||||
|
||||
default String scheme() {
|
||||
return "Bearer";
|
||||
}
|
||||
}
|
||||
|
||||
public static final class RetryOptions {
|
||||
public int retries = 2;
|
||||
public long backoffMillis = 200L;
|
||||
public Set<Integer> statusCodes = new HashSet<>();
|
||||
public Logger logger = Logger.getLogger("StellaRetry");
|
||||
|
||||
public RetryOptions() {
|
||||
statusCodes.add(429);
|
||||
statusCodes.add(500);
|
||||
statusCodes.add(502);
|
||||
statusCodes.add(503);
|
||||
statusCodes.add(504);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class TelemetryOptions {
|
||||
public String source = "";
|
||||
public String traceParent = "";
|
||||
public String headerName = "X-Stella-Client";
|
||||
}
|
||||
|
||||
static final class StellaAuthInterceptor implements Interceptor {
|
||||
private final AuthProvider provider;
|
||||
|
||||
StellaAuthInterceptor(AuthProvider provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
String token = provider.token();
|
||||
if (token != null && !token.isEmpty()) {
|
||||
String scheme = provider.scheme();
|
||||
String value = (scheme == null || scheme.isEmpty()) ? token : scheme + " " + token;
|
||||
request = request.newBuilder()
|
||||
.header(provider.headerName(), value)
|
||||
.build();
|
||||
}
|
||||
return chain.proceed(request);
|
||||
}
|
||||
}
|
||||
|
||||
static final class StellaTelemetryInterceptor implements Interceptor {
|
||||
private final TelemetryOptions options;
|
||||
|
||||
StellaTelemetryInterceptor(TelemetryOptions options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
Request.Builder builder = request.newBuilder();
|
||||
if (options.source != null && !options.source.isEmpty()) {
|
||||
builder.header(options.headerName, options.source);
|
||||
}
|
||||
if (options.traceParent != null && !options.traceParent.isEmpty()) {
|
||||
builder.header("traceparent", options.traceParent);
|
||||
}
|
||||
return chain.proceed(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
static final class StellaRetryInterceptor implements Interceptor {
|
||||
private final RetryOptions options;
|
||||
|
||||
StellaRetryInterceptor(RetryOptions options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
int attempts = 0;
|
||||
IOException lastError = null;
|
||||
while (attempts <= options.retries) {
|
||||
try {
|
||||
Response response = chain.proceed(chain.request());
|
||||
if (!options.statusCodes.contains(response.code()) || attempts == options.retries) {
|
||||
return response;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
lastError = ex;
|
||||
if (attempts == options.retries) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(options.backoffMillis * (1L << attempts));
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("retry interrupted", ie);
|
||||
}
|
||||
attempts += 1;
|
||||
}
|
||||
if (lastError != null) {
|
||||
throw lastError;
|
||||
}
|
||||
return chain.proceed(chain.request());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
// Generated by StellaOps SDK generator — do not edit.
|
||||
|
||||
package org.stellaops.sdk;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* Reusable hooks for auth, telemetry, retries, and pagination helpers.
|
||||
*/
|
||||
public final class Hooks {
|
||||
|
||||
private Hooks() {}
|
||||
|
||||
public static Interceptor auth(Supplier<String> tokenProvider, String headerName, String scheme) {
|
||||
return chain -> {
|
||||
Request original = chain.request();
|
||||
String token = tokenProvider != null ? tokenProvider.get() : null;
|
||||
if (token == null || token.isEmpty()) {
|
||||
return chain.proceed(original);
|
||||
}
|
||||
|
||||
String header = scheme != null && !scheme.isEmpty() ? scheme + " " + token : token;
|
||||
Request authed = original.newBuilder()
|
||||
.header(firstNonEmpty(headerName, "Authorization"), header)
|
||||
.build();
|
||||
return chain.proceed(authed);
|
||||
};
|
||||
}
|
||||
|
||||
public static Interceptor telemetry(String source, String traceParent, String headerName) {
|
||||
return chain -> {
|
||||
Request.Builder builder = chain.request().newBuilder();
|
||||
if (source != null && !source.isEmpty()) {
|
||||
builder.header(firstNonEmpty(headerName, "X-Stella-Client"), source);
|
||||
}
|
||||
if (traceParent != null && !traceParent.isEmpty()) {
|
||||
builder.header("traceparent", traceParent);
|
||||
}
|
||||
return chain.proceed(builder.build());
|
||||
};
|
||||
}
|
||||
|
||||
public static Interceptor retries(int retries, Duration backoff, Set<Integer> statusCodes) {
|
||||
final int maxAttempts = Math.max(retries, 2);
|
||||
final Duration baseBackoff = backoff != null && !backoff.isNegative() && !backoff.isZero()
|
||||
? backoff : Duration.ofMillis(200);
|
||||
final Set<Integer> retryable = statusCodes == null || statusCodes.isEmpty()
|
||||
? Set.of(429, 500, 502, 503, 504)
|
||||
: statusCodes;
|
||||
|
||||
return new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
IOException lastError = null;
|
||||
Response lastResponse = null;
|
||||
|
||||
for (int attempt = 0; attempt <= maxAttempts; attempt++) {
|
||||
try {
|
||||
Response resp = chain.proceed(chain.request());
|
||||
if (!retryable.contains(resp.code()) || attempt == maxAttempts) {
|
||||
return resp;
|
||||
}
|
||||
lastResponse = resp;
|
||||
} catch (IOException ex) {
|
||||
lastError = ex;
|
||||
if (attempt == maxAttempts) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(baseBackoff.toMillis() * (1L << attempt));
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Retry interrupted", ie);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastError != null) {
|
||||
throw lastError;
|
||||
}
|
||||
return lastResponse;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static OkHttpClient withHooks(OkHttpClient base, Interceptor... interceptors) {
|
||||
OkHttpClient.Builder builder = base != null ? base.newBuilder() : new OkHttpClient.Builder();
|
||||
for (Interceptor interceptor : interceptors) {
|
||||
if (interceptor != null) {
|
||||
builder.addInterceptor(interceptor);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static <T> PaginationResult<T> paginate(String startCursor, Pager<T> pager) throws Exception {
|
||||
String cursor = startCursor;
|
||||
PaginationResult<T> result = new PaginationResult<>();
|
||||
while (true) {
|
||||
Page<T> page = pager.fetch(cursor);
|
||||
result.items.addAll(page.items());
|
||||
if (page.nextCursor() == null || page.nextCursor().isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
cursor = page.nextCursor();
|
||||
}
|
||||
}
|
||||
|
||||
public interface Pager<T> {
|
||||
Page<T> fetch(String cursor) throws Exception;
|
||||
}
|
||||
|
||||
public record Page<T>(java.util.List<T> items, String nextCursor) {}
|
||||
|
||||
public static final class PaginationResult<T> {
|
||||
public final java.util.List<T> items = new java.util.ArrayList<>();
|
||||
}
|
||||
|
||||
private static String firstNonEmpty(String... values) {
|
||||
if (values == null) return "";
|
||||
for (String v : values) {
|
||||
if (v != null && !v.isEmpty()) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user