From d16a778a307afff83cf9af9ee8faf2796fa81ff1 Mon Sep 17 00:00:00 2001 From: fern-api <115122769+fern-api[bot]@users.noreply.github.com> Date: Tue, 26 May 2026 22:41:56 +0000 Subject: [PATCH 1/2] [fern-generated] Update SDK Generated by Fern CLI Version: unknown Generators: - fernapi/fern-java-sdk: 4.8.11 --- .fern/metadata.json | 13 +- README.md | 4 +- build.gradle | 4 +- reference.md | 85 ++++ .../com/pipedream/api/AsyncBaseClient.java | 8 + .../pipedream/api/AsyncBaseClientBuilder.java | 80 ++-- .../java/com/pipedream/api/BaseClient.java | 8 + .../com/pipedream/api/BaseClientBuilder.java | 80 ++-- .../com/pipedream/api/core/ClientOptions.java | 4 +- .../api/resources/proxy/AsyncProxyClient.java | 114 +----- .../resources/proxy/AsyncRawProxyClient.java | 139 +++---- .../api/resources/proxy/ProxyClient.java | 108 +---- .../api/resources/proxy/RawProxyClient.java | 114 +++--- .../proxy/requests/ProxyDeleteRequest.java | 16 + .../proxy/requests/ProxyGetRequest.java | 16 + .../proxy/requests/ProxyPatchRequest.java | 16 + .../proxy/requests/ProxyPostRequest.java | 16 + .../proxy/requests/ProxyPutRequest.java | 16 + .../resources/proxy/types/ProxyResponse.java | 190 --------- .../workflows/AsyncRawWorkflowsClient.java | 268 ------------- .../workflows/AsyncWorkflowsClient.java | 128 ------ .../workflows/RawWorkflowsClient.java | 241 ----------- .../resources/workflows/WorkflowsClient.java | 125 ------ .../api/resources/workflows/package-info.java | 27 -- .../InvokeWorkflowForExternalUserOpts.java | 182 --------- .../requests/InvokeWorkflowOpts.java | 164 -------- .../com/pipedream/api/types/HTTPAuthType.java | 42 -- .../pipedream/api/OauthTokensWireTest.java | 119 ------ .../pipedream/api/ProxyClientWireTest.java | 379 ------------------ .../com/pipedream/api/TokensWireTest.java | 109 ----- .../pipedream/api/testutil/MockResponse.java | 36 -- .../pipedream/api/testutil/MockWebServer.java | 99 ----- .../api/testutil/RecordedRequest.java | 45 --- 33 files changed, 404 insertions(+), 2591 deletions(-) delete mode 100644 src/main/java/com/pipedream/api/resources/proxy/types/ProxyResponse.java delete mode 100644 src/main/java/com/pipedream/api/resources/workflows/AsyncRawWorkflowsClient.java delete mode 100644 src/main/java/com/pipedream/api/resources/workflows/AsyncWorkflowsClient.java delete mode 100644 src/main/java/com/pipedream/api/resources/workflows/RawWorkflowsClient.java delete mode 100644 src/main/java/com/pipedream/api/resources/workflows/WorkflowsClient.java delete mode 100644 src/main/java/com/pipedream/api/resources/workflows/package-info.java delete mode 100644 src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowForExternalUserOpts.java delete mode 100644 src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowOpts.java delete mode 100644 src/main/java/com/pipedream/api/types/HTTPAuthType.java delete mode 100644 src/test/java/com/pipedream/api/OauthTokensWireTest.java delete mode 100644 src/test/java/com/pipedream/api/ProxyClientWireTest.java delete mode 100644 src/test/java/com/pipedream/api/TokensWireTest.java delete mode 100644 src/test/java/com/pipedream/api/testutil/MockResponse.java delete mode 100644 src/test/java/com/pipedream/api/testutil/MockWebServer.java delete mode 100644 src/test/java/com/pipedream/api/testutil/RecordedRequest.java diff --git a/.fern/metadata.json b/.fern/metadata.json index 3430f57..4d61a92 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { - "cliVersion": "5.17.0", + "cliVersion": "5.37.12", "generatorName": "fernapi/fern-java-sdk", - "generatorVersion": "4.8.4", + "generatorVersion": "4.8.11", "generatorConfig": { "publish-to": "central", "client-class-name": "BaseClient", @@ -10,9 +10,8 @@ ], "retry-status-codes": "legacy" }, - "originGitCommit": "fa2fad94474bee68b5a4c87f25775ff6701a0fe6", - "originGitCommitIsDirty": false, - "invokedBy": "ci", - "ciProvider": "github", - "sdkVersion": "2.0.4" + "originGitCommit": "320eac6d2809f95097ec1bb8cdb630cf13316b22", + "originGitCommitIsDirty": true, + "invokedBy": "manual", + "sdkVersion": "2.0.5" } \ No newline at end of file diff --git a/README.md b/README.md index 5ee2fb3..3e9bf5c 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Add the dependency in your `build.gradle` file: ```groovy dependencies { - implementation 'com.pipedream:pipedream:2.0.4' + implementation 'com.pipedream:pipedream:2.0.5' } ``` @@ -42,7 +42,7 @@ Add the dependency in your `pom.xml` file: com.pipedream pipedream - 2.0.4 + 2.0.5 ``` diff --git a/build.gradle b/build.gradle index d037e3f..8c6b958 100644 --- a/build.gradle +++ b/build.gradle @@ -48,7 +48,7 @@ java { group = 'com.pipedream' -version = '2.0.4' +version = '2.0.5' jar { dependsOn(":generatePomFileForMavenPublication") @@ -79,7 +79,7 @@ publishing { maven(MavenPublication) { groupId = 'com.pipedream' artifactId = 'pipedream' - version = '2.0.4' + version = '2.0.5' from components.java pom { name = 'pipedream' diff --git a/reference.md b/reference.md index 7376761..de3b6f7 100644 --- a/reference.md +++ b/reference.md @@ -727,6 +727,91 @@ client.accounts().deleteByApp("app_id"); + + + + +
client.accounts.listByExternalUser(projectId, externalUserId) -> List&lt;Account&gt; +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List all connected accounts for a specific external user. Equivalent to GET /accounts with external_user_id filter but uses path-based routing. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.accounts().listByExternalUser( + "external_user_id", + AccountsListByExternalUserRequest + .builder() + .includeCredentials(true) + .app("app") + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `String` — The project ID, which starts with `proj_`. + +
+
+ +
+
+ +**externalUserId:** `String` + +
+
+ +
+
+ +**includeCredentials:** `Optional` + +
+
+ +
+
+ +**app:** `Optional` + +
+
+
+
+ +
diff --git a/src/main/java/com/pipedream/api/AsyncBaseClient.java b/src/main/java/com/pipedream/api/AsyncBaseClient.java index 3635ca6..f48620f 100644 --- a/src/main/java/com/pipedream/api/AsyncBaseClient.java +++ b/src/main/java/com/pipedream/api/AsyncBaseClient.java @@ -152,4 +152,12 @@ public static AsyncBaseClientBuilder._TokenAuth withToken(String token) { public static AsyncBaseClientBuilder._CredentialsAuth withCredentials(String clientId, String clientSecret) { return AsyncBaseClientBuilder.withCredentials(clientId, clientSecret); } + + /** + * Creates a new client builder. + * @return A builder for configuring and creating the client + */ + public static AsyncBaseClientBuilder._Builder builder() { + return AsyncBaseClientBuilder.builder(); + } } diff --git a/src/main/java/com/pipedream/api/AsyncBaseClientBuilder.java b/src/main/java/com/pipedream/api/AsyncBaseClientBuilder.java index e6ad3c8..0dc7662 100644 --- a/src/main/java/com/pipedream/api/AsyncBaseClientBuilder.java +++ b/src/main/java/com/pipedream/api/AsyncBaseClientBuilder.java @@ -1,3 +1,6 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ package com.pipedream.api; import com.pipedream.api.core.ClientOptions; @@ -10,7 +13,7 @@ import java.util.Optional; import okhttp3.OkHttpClient; -public class AsyncBaseClientBuilder> { +public class AsyncBaseClientBuilder { private Optional timeout = Optional.empty(); private Optional maxRetries = Optional.empty(); @@ -64,51 +67,51 @@ public static _Builder builder() { /** * Sets projectEnvironment */ - public T projectEnvironment(String projectEnvironment) { + public AsyncBaseClientBuilder projectEnvironment(String projectEnvironment) { this.projectEnvironment = projectEnvironment; - return (T) this; + return this; } - public T environment(Environment environment) { + public AsyncBaseClientBuilder environment(Environment environment) { this.environment = environment; - return (T) this; + return this; } - public T url(String url) { + public AsyncBaseClientBuilder url(String url) { this.environment = Environment.custom(url); - return (T) this; + return this; } /** * Sets the timeout (in seconds) for the client. Defaults to 60 seconds. */ - public T timeout(int timeout) { + public AsyncBaseClientBuilder timeout(int timeout) { this.timeout = Optional.of(timeout); - return (T) this; + return this; } /** * Sets the maximum number of retries for the client. Defaults to 2 retries. */ - public T maxRetries(int maxRetries) { + public AsyncBaseClientBuilder maxRetries(int maxRetries) { this.maxRetries = Optional.of(maxRetries); - return (T) this; + return this; } /** * Sets the underlying OkHttp client */ - public T httpClient(OkHttpClient httpClient) { + public AsyncBaseClientBuilder httpClient(OkHttpClient httpClient) { this.httpClient = httpClient; - return (T) this; + return this; } /** * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. */ - public T logging(LogConfig logging) { + public AsyncBaseClientBuilder logging(LogConfig logging) { this.logging = Optional.of(logging); - return (T) this; + return this; } /** @@ -119,14 +122,14 @@ public T logging(LogConfig logging) { * @param value The header value * @return This builder for method chaining */ - public T addHeader(String name, String value) { + public AsyncBaseClientBuilder addHeader(String name, String value) { this.customHeaders.put(name, value); - return (T) this; + return this; } - public T projectId(String projectId) { + public AsyncBaseClientBuilder projectId(String projectId) { this.projectId = projectId; - return (T) this; + return this; } protected ClientOptions buildClientOptions() { @@ -295,7 +298,7 @@ public AsyncBaseClient build() { return new AsyncBaseClient(buildClientOptions()); } - public static final class _TokenAuth extends AsyncBaseClientBuilder<_TokenAuth> { + public static final class _TokenAuth extends AsyncBaseClientBuilder { private final String token; _TokenAuth(String token) { @@ -308,7 +311,7 @@ protected void setAuthentication(ClientOptions.Builder builder) { } } - public static final class _CredentialsAuth extends AsyncBaseClientBuilder<_CredentialsAuth> { + public static final class _CredentialsAuth extends AsyncBaseClientBuilder { private final String clientId; private final String clientSecret; @@ -348,8 +351,6 @@ public static final class _Builder { private OkHttpClient httpClient; - private Optional logging = Optional.empty(); - private final Map headers = new HashMap<>(); public _Builder environment(Environment environment) { @@ -386,14 +387,6 @@ public _Builder httpClient(OkHttpClient httpClient) { return this; } - /** - * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. - */ - public _Builder logging(LogConfig logging) { - this.logging = Optional.of(logging); - return this; - } - /** * Add a custom header to be sent with all requests. * @param name The header name @@ -415,7 +408,21 @@ public _Builder addHeader(String name, String value) { */ public _TokenAuth token(String token) { _TokenAuth auth = new _TokenAuth(token); - applyTo(auth); + if (this.environment != null) { + auth.environment = this.environment; + } + if (this.timeout.isPresent()) { + auth.timeout(this.timeout.get()); + } + if (this.maxRetries.isPresent()) { + auth.maxRetries(this.maxRetries.get()); + } + if (this.httpClient != null) { + auth.httpClient(this.httpClient); + } + for (Map.Entry header : this.headers.entrySet()) { + auth.addHeader(header.getKey(), header.getValue()); + } return auth; } @@ -429,11 +436,6 @@ public _TokenAuth token(String token) { */ public _CredentialsAuth credentials(String clientId, String clientSecret) { _CredentialsAuth auth = new _CredentialsAuth(clientId, clientSecret); - applyTo(auth); - return auth; - } - - private > void applyTo(B auth) { if (this.environment != null) { auth.environment = this.environment; } @@ -446,12 +448,10 @@ private > void applyTo(B auth) { if (this.httpClient != null) { auth.httpClient(this.httpClient); } - if (this.logging.isPresent()) { - auth.logging(this.logging.get()); - } for (Map.Entry header : this.headers.entrySet()) { auth.addHeader(header.getKey(), header.getValue()); } + return auth; } } } diff --git a/src/main/java/com/pipedream/api/BaseClient.java b/src/main/java/com/pipedream/api/BaseClient.java index 056a9f9..6d39477 100644 --- a/src/main/java/com/pipedream/api/BaseClient.java +++ b/src/main/java/com/pipedream/api/BaseClient.java @@ -152,4 +152,12 @@ public static BaseClientBuilder._TokenAuth withToken(String token) { public static BaseClientBuilder._CredentialsAuth withCredentials(String clientId, String clientSecret) { return BaseClientBuilder.withCredentials(clientId, clientSecret); } + + /** + * Creates a new client builder. + * @return A builder for configuring and creating the client + */ + public static BaseClientBuilder._Builder builder() { + return BaseClientBuilder.builder(); + } } diff --git a/src/main/java/com/pipedream/api/BaseClientBuilder.java b/src/main/java/com/pipedream/api/BaseClientBuilder.java index 74601de..d632962 100644 --- a/src/main/java/com/pipedream/api/BaseClientBuilder.java +++ b/src/main/java/com/pipedream/api/BaseClientBuilder.java @@ -1,3 +1,6 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ package com.pipedream.api; import com.pipedream.api.core.ClientOptions; @@ -10,7 +13,7 @@ import java.util.Optional; import okhttp3.OkHttpClient; -public class BaseClientBuilder> { +public class BaseClientBuilder { private Optional timeout = Optional.empty(); private Optional maxRetries = Optional.empty(); @@ -64,51 +67,51 @@ public static _Builder builder() { /** * Sets projectEnvironment */ - public T projectEnvironment(String projectEnvironment) { + public BaseClientBuilder projectEnvironment(String projectEnvironment) { this.projectEnvironment = projectEnvironment; - return (T) this; + return this; } - public T environment(Environment environment) { + public BaseClientBuilder environment(Environment environment) { this.environment = environment; - return (T) this; + return this; } - public T url(String url) { + public BaseClientBuilder url(String url) { this.environment = Environment.custom(url); - return (T) this; + return this; } /** * Sets the timeout (in seconds) for the client. Defaults to 60 seconds. */ - public T timeout(int timeout) { + public BaseClientBuilder timeout(int timeout) { this.timeout = Optional.of(timeout); - return (T) this; + return this; } /** * Sets the maximum number of retries for the client. Defaults to 2 retries. */ - public T maxRetries(int maxRetries) { + public BaseClientBuilder maxRetries(int maxRetries) { this.maxRetries = Optional.of(maxRetries); - return (T) this; + return this; } /** * Sets the underlying OkHttp client */ - public T httpClient(OkHttpClient httpClient) { + public BaseClientBuilder httpClient(OkHttpClient httpClient) { this.httpClient = httpClient; - return (T) this; + return this; } /** * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. */ - public T logging(LogConfig logging) { + public BaseClientBuilder logging(LogConfig logging) { this.logging = Optional.of(logging); - return (T) this; + return this; } /** @@ -119,14 +122,14 @@ public T logging(LogConfig logging) { * @param value The header value * @return This builder for method chaining */ - public T addHeader(String name, String value) { + public BaseClientBuilder addHeader(String name, String value) { this.customHeaders.put(name, value); - return (T) this; + return this; } - public T projectId(String projectId) { + public BaseClientBuilder projectId(String projectId) { this.projectId = projectId; - return (T) this; + return this; } protected ClientOptions buildClientOptions() { @@ -295,7 +298,7 @@ public BaseClient build() { return new BaseClient(buildClientOptions()); } - public static final class _TokenAuth extends BaseClientBuilder<_TokenAuth> { + public static final class _TokenAuth extends BaseClientBuilder { private final String token; _TokenAuth(String token) { @@ -308,7 +311,7 @@ protected void setAuthentication(ClientOptions.Builder builder) { } } - public static final class _CredentialsAuth extends BaseClientBuilder<_CredentialsAuth> { + public static final class _CredentialsAuth extends BaseClientBuilder { private final String clientId; private final String clientSecret; @@ -348,8 +351,6 @@ public static final class _Builder { private OkHttpClient httpClient; - private Optional logging = Optional.empty(); - private final Map headers = new HashMap<>(); public _Builder environment(Environment environment) { @@ -386,14 +387,6 @@ public _Builder httpClient(OkHttpClient httpClient) { return this; } - /** - * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. - */ - public _Builder logging(LogConfig logging) { - this.logging = Optional.of(logging); - return this; - } - /** * Add a custom header to be sent with all requests. * @param name The header name @@ -415,7 +408,21 @@ public _Builder addHeader(String name, String value) { */ public _TokenAuth token(String token) { _TokenAuth auth = new _TokenAuth(token); - applyTo(auth); + if (this.environment != null) { + auth.environment = this.environment; + } + if (this.timeout.isPresent()) { + auth.timeout(this.timeout.get()); + } + if (this.maxRetries.isPresent()) { + auth.maxRetries(this.maxRetries.get()); + } + if (this.httpClient != null) { + auth.httpClient(this.httpClient); + } + for (Map.Entry header : this.headers.entrySet()) { + auth.addHeader(header.getKey(), header.getValue()); + } return auth; } @@ -429,11 +436,6 @@ public _TokenAuth token(String token) { */ public _CredentialsAuth credentials(String clientId, String clientSecret) { _CredentialsAuth auth = new _CredentialsAuth(clientId, clientSecret); - applyTo(auth); - return auth; - } - - private > void applyTo(B auth) { if (this.environment != null) { auth.environment = this.environment; } @@ -446,12 +448,10 @@ private > void applyTo(B auth) { if (this.httpClient != null) { auth.httpClient(this.httpClient); } - if (this.logging.isPresent()) { - auth.logging(this.logging.get()); - } for (Map.Entry header : this.headers.entrySet()) { auth.addHeader(header.getKey(), header.getValue()); } + return auth; } } } diff --git a/src/main/java/com/pipedream/api/core/ClientOptions.java b/src/main/java/com/pipedream/api/core/ClientOptions.java index 09c0bdf..2b7f8c0 100644 --- a/src/main/java/com/pipedream/api/core/ClientOptions.java +++ b/src/main/java/com/pipedream/api/core/ClientOptions.java @@ -41,10 +41,10 @@ private ClientOptions( this.headers.putAll(headers); this.headers.putAll(new HashMap() { { - put("User-Agent", "com.pipedream:pipedream/2.0.4"); + put("User-Agent", "com.pipedream:pipedream/2.0.5"); put("X-Fern-Language", "JAVA"); put("X-Fern-SDK-Name", "com.pipedream.fern:api-sdk"); - put("X-Fern-SDK-Version", "2.0.4"); + put("X-Fern-SDK-Version", "2.0.5"); } }); this.headerSuppliers = headerSuppliers; diff --git a/src/main/java/com/pipedream/api/resources/proxy/AsyncProxyClient.java b/src/main/java/com/pipedream/api/resources/proxy/AsyncProxyClient.java index 90eb2ba..a5ba2bd 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/AsyncProxyClient.java +++ b/src/main/java/com/pipedream/api/resources/proxy/AsyncProxyClient.java @@ -10,10 +10,8 @@ import com.pipedream.api.resources.proxy.requests.ProxyPatchRequest; import com.pipedream.api.resources.proxy.requests.ProxyPostRequest; import com.pipedream.api.resources.proxy.requests.ProxyPutRequest; -import com.pipedream.api.resources.proxy.types.ProxyResponse; -import java.util.Base64; +import java.io.InputStream; import java.util.concurrent.CompletableFuture; -import okhttp3.HttpUrl; public class AsyncProxyClient { protected final ClientOptions clientOptions; @@ -25,10 +23,6 @@ public AsyncProxyClient(ClientOptions clientOptions) { this.rawClient = new AsyncRawProxyClient(clientOptions); } - private String encodeUrl(String url) { - return Base64.getUrlEncoder().encodeToString(url.getBytes()); - } - /** * Get responses with HTTP metadata like headers */ @@ -39,154 +33,72 @@ public AsyncRawProxyClient withRawResponse() { /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public CompletableFuture get(String url, ProxyGetRequest request) { - final String url64 = encodeUrl(url); + public CompletableFuture get(String url64, ProxyGetRequest request) { return this.rawClient.get(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public CompletableFuture get(HttpUrl url, ProxyGetRequest request) { - return get(url.toString(), request); - } - - /** - * Forward an authenticated GET request to an external API using an external user's account credentials - */ - public CompletableFuture get(String url, ProxyGetRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public CompletableFuture get(String url64, ProxyGetRequest request, RequestOptions requestOptions) { return this.rawClient.get(url64, request, requestOptions).thenApply(response -> response.body()); } - /** - * Forward an authenticated GET request to an external API using an external user's account credentials - */ - public CompletableFuture get(HttpUrl url, ProxyGetRequest request, RequestOptions requestOptions) { - return get(url.toString(), request, requestOptions); - } - /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public CompletableFuture post(String url, ProxyPostRequest request) { - final String url64 = encodeUrl(url); + public CompletableFuture post(String url64, ProxyPostRequest request) { return this.rawClient.post(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public CompletableFuture post(HttpUrl url, ProxyPostRequest request) { - return post(url.toString(), request); - } - - /** - * Forward an authenticated POST request to an external API using an external user's account credentials - */ - public CompletableFuture post(String url, ProxyPostRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public CompletableFuture post(String url64, ProxyPostRequest request, RequestOptions requestOptions) { return this.rawClient.post(url64, request, requestOptions).thenApply(response -> response.body()); } - /** - * Forward an authenticated POST request to an external API using an external user's account credentials - */ - public CompletableFuture post(HttpUrl url, ProxyPostRequest request, RequestOptions requestOptions) { - return post(url.toString(), request, requestOptions); - } - /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public CompletableFuture put(String url, ProxyPutRequest request) { - final String url64 = encodeUrl(url); + public CompletableFuture put(String url64, ProxyPutRequest request) { return this.rawClient.put(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public CompletableFuture put(HttpUrl url, ProxyPutRequest request) { - return put(url.toString(), request); - } - - /** - * Forward an authenticated PUT request to an external API using an external user's account credentials - */ - public CompletableFuture put(String url, ProxyPutRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public CompletableFuture put(String url64, ProxyPutRequest request, RequestOptions requestOptions) { return this.rawClient.put(url64, request, requestOptions).thenApply(response -> response.body()); } - /** - * Forward an authenticated PUT request to an external API using an external user's account credentials - */ - public CompletableFuture put(HttpUrl url, ProxyPutRequest request, RequestOptions requestOptions) { - return put(url.toString(), request, requestOptions); - } - /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public CompletableFuture delete(String url, ProxyDeleteRequest request) { - final String url64 = encodeUrl(url); + public CompletableFuture delete(String url64, ProxyDeleteRequest request) { return this.rawClient.delete(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public CompletableFuture delete(HttpUrl url, ProxyDeleteRequest request) { - return delete(url.toString(), request); - } - - /** - * Forward an authenticated DELETE request to an external API using an external user's account credentials - */ - public CompletableFuture delete( - String url, ProxyDeleteRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public CompletableFuture delete( + String url64, ProxyDeleteRequest request, RequestOptions requestOptions) { return this.rawClient.delete(url64, request, requestOptions).thenApply(response -> response.body()); } - /** - * Forward an authenticated DELETE request to an external API using an external user's account credentials - */ - public CompletableFuture delete( - HttpUrl url, ProxyDeleteRequest request, RequestOptions requestOptions) { - return delete(url.toString(), request, requestOptions); - } - /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public CompletableFuture patch(String url, ProxyPatchRequest request) { - final String url64 = encodeUrl(url); + public CompletableFuture patch(String url64, ProxyPatchRequest request) { return this.rawClient.patch(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public CompletableFuture patch(HttpUrl url, ProxyPatchRequest request) { - return patch(url.toString(), request); - } - - /** - * Forward an authenticated PATCH request to an external API using an external user's account credentials - */ - public CompletableFuture patch( - String url, ProxyPatchRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public CompletableFuture patch( + String url64, ProxyPatchRequest request, RequestOptions requestOptions) { return this.rawClient.patch(url64, request, requestOptions).thenApply(response -> response.body()); } - - /** - * Forward an authenticated PATCH request to an external API using an external user's account credentials - */ - public CompletableFuture patch( - HttpUrl url, ProxyPatchRequest request, RequestOptions requestOptions) { - return patch(url.toString(), request, requestOptions); - } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java b/src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java index 0df5a24..e21e9e8 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java +++ b/src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java @@ -19,14 +19,13 @@ import com.pipedream.api.resources.proxy.requests.ProxyPatchRequest; import com.pipedream.api.resources.proxy.requests.ProxyPostRequest; import com.pipedream.api.resources.proxy.requests.ProxyPutRequest; -import com.pipedream.api.resources.proxy.types.ProxyResponse; import java.io.IOException; +import java.io.InputStream; import java.util.concurrent.CompletableFuture; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Headers; import okhttp3.HttpUrl; -import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; @@ -41,58 +40,17 @@ public AsyncRawProxyClient(ClientOptions clientOptions) { this.clientOptions = clientOptions; } - private static boolean isJsonContentType(MediaType contentType) { - if (contentType == null) { - return false; - } - return "application".equals(contentType.type()) && "json".equals(contentType.subtype()); - } - - private static void handleSuccessResponse( - Response response, - ResponseBody responseBody, - CompletableFuture> future) { - MediaType contentType = responseBody != null ? responseBody.contentType() : null; - String contentTypeString = contentType != null ? contentType.toString() : null; - ProxyResponse proxyBody; - if (isJsonContentType(contentType)) { - try { - String responseBodyString = responseBody.string(); - Object parsed = ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class); - proxyBody = ProxyResponse.json(parsed, contentTypeString); - } catch (JsonProcessingException e) { - future.completeExceptionally(new BaseClientException( - "Response Content-Type was application/json but body is not valid JSON", e)); - return; - } catch (IOException e) { - future.completeExceptionally(new BaseClientException("Error reading response body", e)); - return; - } finally { - response.close(); - } - } else { - try { - proxyBody = ProxyResponse.stream(new ResponseBodyInputStream(response), contentTypeString); - } catch (IOException e) { - future.completeExceptionally(new BaseClientException("Error creating response stream", e)); - response.close(); - return; - } - } - future.complete(new BaseClientHttpResponse<>(proxyBody, response)); - } - /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public CompletableFuture> get(String url64, ProxyGetRequest request) { + public CompletableFuture> get(String url64, ProxyGetRequest request) { return get(url64, request, null); } /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public CompletableFuture> get( + public CompletableFuture> get( String url64, ProxyGetRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -102,6 +60,11 @@ public CompletableFuture> get( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), 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) @@ -112,14 +75,14 @@ public CompletableFuture> get( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - handleSuccessResponse(response, responseBody, future); + future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -132,11 +95,9 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response)); + "Error with status code " + response.code(), response.code(), errorBody, response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); @@ -154,14 +115,14 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public CompletableFuture> post(String url64, ProxyPostRequest request) { + public CompletableFuture> post(String url64, ProxyPostRequest request) { return post(url64, request, null); } /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public CompletableFuture> post( + public CompletableFuture> post( String url64, ProxyPostRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -171,6 +132,11 @@ public CompletableFuture> post( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); + if (requestOptions != null) { + requestOptions.getQueryParameters().forEach((_key, _value) -> { + httpUrl.addQueryParameter(_key, _value); + }); + } RequestBody body; try { body = RequestBody.create( @@ -189,14 +155,14 @@ public CompletableFuture> post( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - handleSuccessResponse(response, responseBody, future); + future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -209,11 +175,9 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response)); + "Error with status code " + response.code(), response.code(), errorBody, response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); @@ -231,14 +195,14 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public CompletableFuture> put(String url64, ProxyPutRequest request) { + public CompletableFuture> put(String url64, ProxyPutRequest request) { return put(url64, request, null); } /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public CompletableFuture> put( + public CompletableFuture> put( String url64, ProxyPutRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -248,6 +212,11 @@ public CompletableFuture> put( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); + if (requestOptions != null) { + requestOptions.getQueryParameters().forEach((_key, _value) -> { + httpUrl.addQueryParameter(_key, _value); + }); + } RequestBody body; try { body = RequestBody.create( @@ -266,14 +235,14 @@ public CompletableFuture> put( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - handleSuccessResponse(response, responseBody, future); + future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -286,11 +255,9 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response)); + "Error with status code " + response.code(), response.code(), errorBody, response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); @@ -308,14 +275,14 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public CompletableFuture> delete(String url64, ProxyDeleteRequest request) { + public CompletableFuture> delete(String url64, ProxyDeleteRequest request) { return delete(url64, request, null); } /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public CompletableFuture> delete( + public CompletableFuture> delete( String url64, ProxyDeleteRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -325,6 +292,11 @@ public CompletableFuture> delete( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); + if (requestOptions != null) { + requestOptions.getQueryParameters().forEach((_key, _value) -> { + httpUrl.addQueryParameter(_key, _value); + }); + } Request.Builder _requestBuilder = new Request.Builder() .url(httpUrl.build()) .method("DELETE", null) @@ -335,14 +307,14 @@ public CompletableFuture> delete( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - handleSuccessResponse(response, responseBody, future); + future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -355,11 +327,9 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response)); + "Error with status code " + response.code(), response.code(), errorBody, response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); @@ -377,14 +347,14 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public CompletableFuture> patch(String url64, ProxyPatchRequest request) { + public CompletableFuture> patch(String url64, ProxyPatchRequest request) { return patch(url64, request, null); } /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public CompletableFuture> patch( + public CompletableFuture> patch( String url64, ProxyPatchRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -394,6 +364,11 @@ public CompletableFuture> patch( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); + if (requestOptions != null) { + requestOptions.getQueryParameters().forEach((_key, _value) -> { + httpUrl.addQueryParameter(_key, _value); + }); + } RequestBody body; try { body = RequestBody.create( @@ -412,14 +387,14 @@ public CompletableFuture> patch( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - handleSuccessResponse(response, responseBody, future); + future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -432,11 +407,9 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response)); + "Error with status code " + response.code(), response.code(), errorBody, response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); diff --git a/src/main/java/com/pipedream/api/resources/proxy/ProxyClient.java b/src/main/java/com/pipedream/api/resources/proxy/ProxyClient.java index 7e19ade..c21c055 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/ProxyClient.java +++ b/src/main/java/com/pipedream/api/resources/proxy/ProxyClient.java @@ -10,9 +10,7 @@ import com.pipedream.api.resources.proxy.requests.ProxyPatchRequest; import com.pipedream.api.resources.proxy.requests.ProxyPostRequest; import com.pipedream.api.resources.proxy.requests.ProxyPutRequest; -import com.pipedream.api.resources.proxy.types.ProxyResponse; -import java.util.Base64; -import okhttp3.HttpUrl; +import java.io.InputStream; public class ProxyClient { protected final ClientOptions clientOptions; @@ -24,10 +22,6 @@ public ProxyClient(ClientOptions clientOptions) { this.rawClient = new RawProxyClient(clientOptions); } - private String encodeUrl(String url) { - return Base64.getUrlEncoder().encodeToString(url.getBytes()); - } - /** * Get responses with HTTP metadata like headers */ @@ -38,150 +32,70 @@ public RawProxyClient withRawResponse() { /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public ProxyResponse get(String url, ProxyGetRequest request) { - final String url64 = encodeUrl(url); + public InputStream get(String url64, ProxyGetRequest request) { return this.rawClient.get(url64, request).body(); } /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public ProxyResponse get(HttpUrl url, ProxyGetRequest request) { - return get(url.toString(), request); - } - - /** - * Forward an authenticated GET request to an external API using an external user's account credentials - */ - public ProxyResponse get(String url, ProxyGetRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public InputStream get(String url64, ProxyGetRequest request, RequestOptions requestOptions) { return this.rawClient.get(url64, request, requestOptions).body(); } - /** - * Forward an authenticated GET request to an external API using an external user's account credentials - */ - public ProxyResponse get(HttpUrl url, ProxyGetRequest request, RequestOptions requestOptions) { - return get(url.toString(), request, requestOptions); - } - /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public ProxyResponse post(String url, ProxyPostRequest request) { - final String url64 = encodeUrl(url); + public InputStream post(String url64, ProxyPostRequest request) { return this.rawClient.post(url64, request).body(); } /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public ProxyResponse post(HttpUrl url, ProxyPostRequest request) { - return post(url.toString(), request); - } - - /** - * Forward an authenticated POST request to an external API using an external user's account credentials - */ - public ProxyResponse post(String url, ProxyPostRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public InputStream post(String url64, ProxyPostRequest request, RequestOptions requestOptions) { return this.rawClient.post(url64, request, requestOptions).body(); } - /** - * Forward an authenticated POST request to an external API using an external user's account credentials - */ - public ProxyResponse post(HttpUrl url, ProxyPostRequest request, RequestOptions requestOptions) { - return post(url.toString(), request, requestOptions); - } - /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public ProxyResponse put(String url, ProxyPutRequest request) { - final String url64 = encodeUrl(url); + public InputStream put(String url64, ProxyPutRequest request) { return this.rawClient.put(url64, request).body(); } /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public ProxyResponse put(HttpUrl url, ProxyPutRequest request) { - return put(url.toString(), request); - } - - /** - * Forward an authenticated PUT request to an external API using an external user's account credentials - */ - public ProxyResponse put(String url, ProxyPutRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public InputStream put(String url64, ProxyPutRequest request, RequestOptions requestOptions) { return this.rawClient.put(url64, request, requestOptions).body(); } - /** - * Forward an authenticated PUT request to an external API using an external user's account credentials - */ - public ProxyResponse put(HttpUrl url, ProxyPutRequest request, RequestOptions requestOptions) { - return put(url.toString(), request, requestOptions); - } - /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public ProxyResponse delete(String url, ProxyDeleteRequest request) { - final String url64 = encodeUrl(url); + public InputStream delete(String url64, ProxyDeleteRequest request) { return this.rawClient.delete(url64, request).body(); } /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public ProxyResponse delete(HttpUrl url, ProxyDeleteRequest request) { - return delete(url.toString(), request); - } - - /** - * Forward an authenticated DELETE request to an external API using an external user's account credentials - */ - public ProxyResponse delete(String url, ProxyDeleteRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public InputStream delete(String url64, ProxyDeleteRequest request, RequestOptions requestOptions) { return this.rawClient.delete(url64, request, requestOptions).body(); } - /** - * Forward an authenticated DELETE request to an external API using an external user's account credentials - */ - public ProxyResponse delete(HttpUrl url, ProxyDeleteRequest request, RequestOptions requestOptions) { - return delete(url.toString(), request, requestOptions); - } - /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public ProxyResponse patch(String url, ProxyPatchRequest request) { - final String url64 = encodeUrl(url); + public InputStream patch(String url64, ProxyPatchRequest request) { return this.rawClient.patch(url64, request).body(); } /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public ProxyResponse patch(HttpUrl url, ProxyPatchRequest request) { - return patch(url.toString(), request); - } - - /** - * Forward an authenticated PATCH request to an external API using an external user's account credentials - */ - public ProxyResponse patch(String url, ProxyPatchRequest request, RequestOptions requestOptions) { - final String url64 = encodeUrl(url); + public InputStream patch(String url64, ProxyPatchRequest request, RequestOptions requestOptions) { return this.rawClient.patch(url64, request, requestOptions).body(); } - - /** - * Forward an authenticated PATCH request to an external API using an external user's account credentials - */ - public ProxyResponse patch(HttpUrl url, ProxyPatchRequest request, RequestOptions requestOptions) { - return patch(url.toString(), request, requestOptions); - } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java b/src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java index b03c111..307e886 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java +++ b/src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java @@ -19,11 +19,10 @@ import com.pipedream.api.resources.proxy.requests.ProxyPatchRequest; import com.pipedream.api.resources.proxy.requests.ProxyPostRequest; import com.pipedream.api.resources.proxy.requests.ProxyPutRequest; -import com.pipedream.api.resources.proxy.types.ProxyResponse; import java.io.IOException; +import java.io.InputStream; import okhttp3.Headers; import okhttp3.HttpUrl; -import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; @@ -37,43 +36,17 @@ public RawProxyClient(ClientOptions clientOptions) { this.clientOptions = clientOptions; } - private static boolean isJsonContentType(MediaType contentType) { - if (contentType == null) { - return false; - } - return "application".equals(contentType.type()) && "json".equals(contentType.subtype()); - } - - private static ProxyResponse parseSuccessResponse(Response response, ResponseBody responseBody) throws IOException { - MediaType contentType = responseBody != null ? responseBody.contentType() : null; - String contentTypeString = contentType != null ? contentType.toString() : null; - if (isJsonContentType(contentType)) { - String responseBodyString = responseBody.string(); - try { - Object parsed = ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class); - return ProxyResponse.json(parsed, contentTypeString); - } catch (JsonProcessingException e) { - throw new BaseClientException( - "Response Content-Type was application/json but body is not valid JSON", e); - } finally { - response.close(); - } - } else { - return ProxyResponse.stream(new ResponseBodyInputStream(response), contentTypeString); - } - } - /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public BaseClientHttpResponse get(String url64, ProxyGetRequest request) { + public BaseClientHttpResponse get(String url64, ProxyGetRequest request) { return get(url64, request, null); } /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public BaseClientHttpResponse get( + public BaseClientHttpResponse get( String url64, ProxyGetRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -83,6 +56,11 @@ public BaseClientHttpResponse get( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), 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) @@ -97,7 +75,7 @@ public BaseClientHttpResponse get( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); + return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -108,11 +86,9 @@ public BaseClientHttpResponse get( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response); + "Error with status code " + response.code(), response.code(), errorBody, response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } @@ -121,14 +97,14 @@ public BaseClientHttpResponse get( /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public BaseClientHttpResponse post(String url64, ProxyPostRequest request) { + public BaseClientHttpResponse post(String url64, ProxyPostRequest request) { return post(url64, request, null); } /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public BaseClientHttpResponse post( + public BaseClientHttpResponse post( String url64, ProxyPostRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -138,6 +114,11 @@ public BaseClientHttpResponse post( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); + if (requestOptions != null) { + requestOptions.getQueryParameters().forEach((_key, _value) -> { + httpUrl.addQueryParameter(_key, _value); + }); + } RequestBody body; try { body = RequestBody.create( @@ -160,7 +141,7 @@ public BaseClientHttpResponse post( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); + return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -171,11 +152,9 @@ public BaseClientHttpResponse post( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response); + "Error with status code " + response.code(), response.code(), errorBody, response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } @@ -184,14 +163,14 @@ public BaseClientHttpResponse post( /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public BaseClientHttpResponse put(String url64, ProxyPutRequest request) { + public BaseClientHttpResponse put(String url64, ProxyPutRequest request) { return put(url64, request, null); } /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public BaseClientHttpResponse put( + public BaseClientHttpResponse put( String url64, ProxyPutRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -201,6 +180,11 @@ public BaseClientHttpResponse put( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); + if (requestOptions != null) { + requestOptions.getQueryParameters().forEach((_key, _value) -> { + httpUrl.addQueryParameter(_key, _value); + }); + } RequestBody body; try { body = RequestBody.create( @@ -223,7 +207,7 @@ public BaseClientHttpResponse put( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); + return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -234,11 +218,9 @@ public BaseClientHttpResponse put( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response); + "Error with status code " + response.code(), response.code(), errorBody, response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } @@ -247,14 +229,14 @@ public BaseClientHttpResponse put( /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public BaseClientHttpResponse delete(String url64, ProxyDeleteRequest request) { + public BaseClientHttpResponse delete(String url64, ProxyDeleteRequest request) { return delete(url64, request, null); } /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public BaseClientHttpResponse delete( + public BaseClientHttpResponse delete( String url64, ProxyDeleteRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -264,6 +246,11 @@ public BaseClientHttpResponse delete( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); + if (requestOptions != null) { + requestOptions.getQueryParameters().forEach((_key, _value) -> { + httpUrl.addQueryParameter(_key, _value); + }); + } Request.Builder _requestBuilder = new Request.Builder() .url(httpUrl.build()) .method("DELETE", null) @@ -278,7 +265,7 @@ public BaseClientHttpResponse delete( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); + return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -289,11 +276,9 @@ public BaseClientHttpResponse delete( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response); + "Error with status code " + response.code(), response.code(), errorBody, response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } @@ -302,14 +287,14 @@ public BaseClientHttpResponse delete( /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public BaseClientHttpResponse patch(String url64, ProxyPatchRequest request) { + public BaseClientHttpResponse patch(String url64, ProxyPatchRequest request) { return patch(url64, request, null); } /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public BaseClientHttpResponse patch( + public BaseClientHttpResponse patch( String url64, ProxyPatchRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -319,6 +304,11 @@ public BaseClientHttpResponse patch( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); + if (requestOptions != null) { + requestOptions.getQueryParameters().forEach((_key, _value) -> { + httpUrl.addQueryParameter(_key, _value); + }); + } RequestBody body; try { body = RequestBody.create( @@ -341,7 +331,7 @@ public BaseClientHttpResponse patch( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); + return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -352,11 +342,9 @@ public BaseClientHttpResponse patch( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response); + "Error with status code " + response.code(), response.code(), errorBody, response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } diff --git a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyDeleteRequest.java b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyDeleteRequest.java index f956f17..dbf3dd6 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyDeleteRequest.java +++ b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyDeleteRequest.java @@ -94,6 +94,10 @@ public interface AccountIdStage { public interface _FinalStage { ProxyDeleteRequest build(); + + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(Map additionalProperties); } @JsonIgnoreProperties(ignoreUnknown = true) @@ -142,5 +146,17 @@ public _FinalStage accountId(@NotNull String accountId) { public ProxyDeleteRequest build() { return new ProxyDeleteRequest(externalUserId, accountId, additionalProperties); } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyGetRequest.java b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyGetRequest.java index bf09229..13e092f 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyGetRequest.java +++ b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyGetRequest.java @@ -94,6 +94,10 @@ public interface AccountIdStage { public interface _FinalStage { ProxyGetRequest build(); + + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(Map additionalProperties); } @JsonIgnoreProperties(ignoreUnknown = true) @@ -142,5 +146,17 @@ public _FinalStage accountId(@NotNull String accountId) { public ProxyGetRequest build() { return new ProxyGetRequest(externalUserId, accountId, additionalProperties); } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPatchRequest.java b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPatchRequest.java index c221032..55e165b 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPatchRequest.java +++ b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPatchRequest.java @@ -114,6 +114,10 @@ public interface AccountIdStage { public interface _FinalStage { ProxyPatchRequest build(); + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(Map additionalProperties); + /** *

Request body to forward to the target API

*/ @@ -208,5 +212,17 @@ public _FinalStage body(Map body) { public ProxyPatchRequest build() { return new ProxyPatchRequest(externalUserId, accountId, body, additionalProperties); } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPostRequest.java b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPostRequest.java index 3c052fd..5d0230a 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPostRequest.java +++ b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPostRequest.java @@ -114,6 +114,10 @@ public interface AccountIdStage { public interface _FinalStage { ProxyPostRequest build(); + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(Map additionalProperties); + /** *

Request body to forward to the target API

*/ @@ -208,5 +212,17 @@ public _FinalStage body(Map body) { public ProxyPostRequest build() { return new ProxyPostRequest(externalUserId, accountId, body, additionalProperties); } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPutRequest.java b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPutRequest.java index 9ba3dc8..4026aca 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPutRequest.java +++ b/src/main/java/com/pipedream/api/resources/proxy/requests/ProxyPutRequest.java @@ -114,6 +114,10 @@ public interface AccountIdStage { public interface _FinalStage { ProxyPutRequest build(); + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(Map additionalProperties); + /** *

Request body to forward to the target API

*/ @@ -208,5 +212,17 @@ public _FinalStage body(Map body) { public ProxyPutRequest build() { return new ProxyPutRequest(externalUserId, accountId, body, additionalProperties); } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/types/ProxyResponse.java b/src/main/java/com/pipedream/api/resources/proxy/types/ProxyResponse.java deleted file mode 100644 index 2b0bf56..0000000 --- a/src/main/java/com/pipedream/api/resources/proxy/types/ProxyResponse.java +++ /dev/null @@ -1,190 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.pipedream.api.resources.proxy.types; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.util.Optional; - -/** - * A union type that represents either a parsed JSON response or a raw binary stream response - * from the proxy API. The type is determined by the Content-Type header of the HTTP response. - * - *

For responses with Content-Type "application/json" (or derivations like - * "application/json; charset=utf-8"), the response body is parsed as JSON and can be - * accessed via {@link #json()}. - * - *

For all other Content-Types (or missing Content-Type headers), the response body - * is returned as a raw InputStream that can be accessed via {@link #stream()}. - * - *

This class implements {@link Closeable} to ensure proper resource management. - * When the response contains a stream, callers should close the ProxyResponse to - * release the underlying HTTP connection. - * - *

Example usage: - *

{@code
- * try (ProxyResponse response = client.proxy().get(url64, request)) {
- *     if (response.isJson()) {
- *         Object json = response.json();
- *         // Work with parsed JSON
- *     } else {
- *         InputStream stream = response.stream();
- *         // Work with binary data
- *     }
- * }
- * }
- */ -public final class ProxyResponse implements Closeable { - - /** - * The type of content contained in this response. - */ - public enum Type { - /** - * The response contains parsed JSON data. - */ - JSON, - /** - * The response contains a raw binary stream. - */ - STREAM - } - - private final Type type; - private final Object jsonValue; - private final InputStream streamValue; - private final String contentType; - - private ProxyResponse(Type type, Object jsonValue, InputStream streamValue, String contentType) { - this.type = type; - this.jsonValue = jsonValue; - this.streamValue = streamValue; - this.contentType = contentType; - } - - /** - * Creates a ProxyResponse containing parsed JSON data. - * - * @param value the parsed JSON value (Map, List, String, Number, Boolean, or null) - * @param contentType the original Content-Type header value - * @return a new ProxyResponse of type JSON - */ - public static ProxyResponse json(Object value, String contentType) { - return new ProxyResponse(Type.JSON, value, null, contentType); - } - - /** - * Creates a ProxyResponse containing a raw binary stream. - * - * @param stream the raw InputStream - * @param contentType the original Content-Type header value - * @return a new ProxyResponse of type STREAM - */ - public static ProxyResponse stream(InputStream stream, String contentType) { - return new ProxyResponse(Type.STREAM, null, stream, contentType); - } - - /** - * Returns true if this response contains parsed JSON data. - * - * @return true if this is a JSON response - */ - public boolean isJson() { - return type == Type.JSON; - } - - /** - * Returns true if this response contains a raw binary stream. - * - * @return true if this is a stream response - */ - public boolean isStream() { - return type == Type.STREAM; - } - - /** - * Returns the type of content contained in this response. - * - * @return the response type - */ - public Type getType() { - return type; - } - - /** - * Returns the parsed JSON value if this is a JSON response. - * - * @return an Optional containing the JSON value, or empty if this is a stream response - */ - public Optional asJson() { - return Optional.ofNullable(jsonValue); - } - - /** - * Returns the raw stream if this is a stream response. - * - * @return an Optional containing the InputStream, or empty if this is a JSON response - */ - public Optional asStream() { - return Optional.ofNullable(streamValue); - } - - /** - * Returns the parsed JSON value. - * - * @return the parsed JSON value (Map, List, String, Number, Boolean, or null) - * @throws IllegalStateException if this is not a JSON response - */ - public Object json() { - if (type != Type.JSON) { - throw new IllegalStateException("ProxyResponse is not JSON, it is " + type); - } - return jsonValue; - } - - /** - * Returns the raw binary stream. - * - * @return the raw InputStream - * @throws IllegalStateException if this is not a stream response - */ - public InputStream stream() { - if (type != Type.STREAM) { - throw new IllegalStateException("ProxyResponse is not a stream, it is " + type); - } - return streamValue; - } - - /** - * Returns the original Content-Type header value from the HTTP response. - * - * @return an Optional containing the Content-Type, or empty if no Content-Type was present - */ - public Optional getContentType() { - return Optional.ofNullable(contentType); - } - - /** - * Closes the underlying stream if this response contains one. - * For JSON responses, this method has no effect. - * - * @throws IOException if an I/O error occurs - */ - @Override - public void close() throws IOException { - if (streamValue != null) { - streamValue.close(); - } - } - - @Override - public String toString() { - if (type == Type.JSON) { - return "ProxyResponse{type=JSON, contentType=" + contentType + ", value=" + jsonValue + "}"; - } else { - return "ProxyResponse{type=STREAM, contentType=" + contentType + "}"; - } - } -} diff --git a/src/main/java/com/pipedream/api/resources/workflows/AsyncRawWorkflowsClient.java b/src/main/java/com/pipedream/api/resources/workflows/AsyncRawWorkflowsClient.java deleted file mode 100644 index d523b9d..0000000 --- a/src/main/java/com/pipedream/api/resources/workflows/AsyncRawWorkflowsClient.java +++ /dev/null @@ -1,268 +0,0 @@ -/** - * This file was manually created to add workflow invocation support. - */ -package com.pipedream.api.resources.workflows; - -import com.pipedream.api.core.BaseClientApiException; -import com.pipedream.api.core.BaseClientException; -import com.pipedream.api.core.BaseClientHttpResponse; -import com.pipedream.api.core.ClientOptions; -import com.pipedream.api.core.MediaTypes; -import com.pipedream.api.core.ObjectMappers; -import com.pipedream.api.core.RequestOptions; -import com.pipedream.api.resources.workflows.requests.InvokeWorkflowForExternalUserOpts; -import com.pipedream.api.resources.workflows.requests.InvokeWorkflowOpts; -import com.pipedream.api.types.HTTPAuthType; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.Headers; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import okhttp3.ResponseBody; - -public class AsyncRawWorkflowsClient { - protected final ClientOptions clientOptions; - private final String workflowDomain; - private final String urlProtocol; - - public AsyncRawWorkflowsClient(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - this.workflowDomain = getDefaultWorkflowDomain(); - this.urlProtocol = getUrlProtocol(); - } - - public CompletableFuture> invoke(InvokeWorkflowOpts request) { - return invoke(request, null); - } - - public CompletableFuture> invoke( - InvokeWorkflowOpts request, RequestOptions requestOptions) { - - // Build the workflow URL - String urlString = buildWorkflowUrl(request.getUrlOrEndpoint()); - - HttpUrl httpUrl; - try { - httpUrl = HttpUrl.parse(urlString); - if (httpUrl == null) { - throw new IllegalArgumentException("Invalid URL: " + urlString); - } - } catch (Exception e) { - CompletableFuture> future = new CompletableFuture<>(); - future.completeExceptionally(new IllegalArgumentException("Invalid URL: " + urlString, e)); - return future; - } - - // Determine auth type - default to OAuth if not specified - HTTPAuthType authType = request.getAuthType().orElse(HTTPAuthType.OAUTH); - - // Prepare headers - start with client options headers (includes OAuth auth if configured) - Map allHeaders = new HashMap<>(clientOptions.headers(requestOptions)); - - // Handle authentication based on type - if (authType == HTTPAuthType.OAUTH) { - // For OAuth, the Authorization header should already be in clientOptions.headers() - // No additional action needed - } else if (authType == HTTPAuthType.STATIC_BEARER) { - // For static_bearer, users must provide the Authorization header in request.getHeaders() - // Their header will override any existing OAuth header when we merge request headers - } else if (authType == HTTPAuthType.NONE) { - // For NONE auth type, set Authorization header to empty string (matches Python SDK) - allHeaders.put("Authorization", ""); - } - - // Add request-specific headers (can override auth headers for STATIC_BEARER) - if (request.getHeaders().isPresent()) { - allHeaders.putAll(request.getHeaders().get()); - } - - // Determine HTTP method - String method = request.getMethod().orElse("POST").toUpperCase(); - - // Prepare request body if needed - RequestBody body = null; - if (request.getBody().isPresent()) { - try { - body = RequestBody.create( - ObjectMappers.JSON_MAPPER.writeValueAsBytes( - request.getBody().get()), - MediaTypes.APPLICATION_JSON); - allHeaders.put("Content-Type", "application/json"); - } catch (Exception e) { - CompletableFuture> future = new CompletableFuture<>(); - future.completeExceptionally(new RuntimeException("Failed to serialize request body", e)); - return future; - } - } else if (("POST".equals(method) || "PUT".equals(method) || "PATCH".equals(method))) { - // For methods that typically require a body, send an empty body - // to avoid OkHttp's "method POST must have a request body" error - body = RequestBody.create(new byte[0], null); - } - - // Build the request - Request.Builder requestBuilder = - new Request.Builder().url(httpUrl).method(method, body).headers(Headers.of(allHeaders)); - - if (!allHeaders.containsKey("Accept")) { - requestBuilder.addHeader("Accept", "application/json"); - } - - Request okhttpRequest = requestBuilder.build(); - - // Execute the request asynchronously - OkHttpClient client = clientOptions.httpClient(); - if (requestOptions != null && requestOptions.getTimeout().isPresent()) { - client = clientOptions.httpClientWithTimeout(requestOptions); - } - - CompletableFuture> future = new CompletableFuture<>(); - - client.newCall(okhttpRequest).enqueue(new Callback() { - @Override - public void onFailure(Call call, IOException e) { - future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); - } - - @Override - public void onResponse(Call call, Response response) throws IOException { - try (ResponseBody responseBody = response.body()) { - if (response.isSuccessful()) { - String responseBodyString = responseBody != null ? responseBody.string() : "{}"; - Object parsedResponse; - try { - parsedResponse = ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class); - } catch (Exception e) { - // If JSON parsing fails, return the raw string - parsedResponse = responseBodyString; - } - future.complete(new BaseClientHttpResponse<>(parsedResponse, response)); - } else { - String responseBodyString = responseBody != null ? responseBody.string() : "{}"; - future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response)); - } - } catch (Exception e) { - future.completeExceptionally(e); - } - } - }); - - return future; - } - - public CompletableFuture> invokeForExternalUser( - InvokeWorkflowForExternalUserOpts request) { - return invokeForExternalUser(request, null); - } - - public CompletableFuture> invokeForExternalUser( - InvokeWorkflowForExternalUserOpts request, RequestOptions requestOptions) { - - // Validate inputs - if (request.getExternalUserId() == null - || request.getExternalUserId().trim().isEmpty()) { - CompletableFuture> future = new CompletableFuture<>(); - future.completeExceptionally(new IllegalArgumentException("External user ID is required")); - return future; - } - - if (request.getUrl() == null || request.getUrl().trim().isEmpty()) { - CompletableFuture> future = new CompletableFuture<>(); - future.completeExceptionally(new IllegalArgumentException("Workflow URL is required")); - return future; - } - - // Prepare headers with external user ID - Map headers = new HashMap<>(); - if (request.getHeaders().isPresent()) { - headers.putAll(request.getHeaders().get()); - } - headers.put("X-PD-External-User-ID", request.getExternalUserId()); - - // Create a new request with the authentication from the original request and the external user header - InvokeWorkflowOpts invokeRequest = InvokeWorkflowOpts.builder() - .urlOrEndpoint(request.getUrl()) - .body(request.getBody()) - .headers(headers) - .method(request.getMethod()) - .authType(request.getAuthType().orElse(HTTPAuthType.OAUTH)) - .build(); - - return invoke(invokeRequest, requestOptions); - } - - /** - * Builds a full workflow URL based on the input. - * - * @param input Either a full URL (with or without protocol) or just an endpoint ID. - * @return The fully constructed URL. - */ - private String buildWorkflowUrl(String input) { - String sanitizedInput = input.trim().toLowerCase(); - if (sanitizedInput.isEmpty()) { - throw new IllegalArgumentException("URL or endpoint ID is required"); - } - - // Check if it's already a full URL - if (sanitizedInput.startsWith("http://") || sanitizedInput.startsWith("https://")) { - try { - URL url = new URL(input); - // Validate the hostname - String workflowDomain = this.workflowDomain; - if (!url.getHost().endsWith(this.workflowDomain)) { - throw new IllegalArgumentException( - "Invalid workflow domain. URL must end with " + this.workflowDomain); - } - return input; - } catch (MalformedURLException e) { - throw new IllegalArgumentException("The provided URL is malformed: " + input, e); - } - } - - // Check if it's a URL without protocol - if (sanitizedInput.contains(".")) { - return buildWorkflowUrl("https://" + input); - } - - // It's an endpoint ID - if (!sanitizedInput.matches("^e[no][a-z0-9-]+$")) { - throw new IllegalArgumentException( - "Invalid endpoint ID format. Must contain only letters, numbers, and hyphens, " - + "and start with either 'en' or 'eo'."); - } - - return urlProtocol + "://" + sanitizedInput + "." + workflowDomain; - } - - private String getDefaultWorkflowDomain() { - String envUrl = clientOptions.environment().getUrl(); - // For non-prod environments (dev, staging), use dev domain - if (!envUrl.equals("https://api.pipedream.com") && !envUrl.equals("https://api2.pipedream.com")) { - return "m.d.pipedream.net"; - } - // For prod and canary, use standard domain - return "m.pipedream.net"; - } - - private String getUrlProtocol() { - String envUrl = clientOptions.environment().getUrl(); - // For non-prod environments (dev, staging), use http - if (!envUrl.equals("https://api.pipedream.com") && !envUrl.equals("https://api2.pipedream.com")) { - return "http"; - } - // For prod and canary, use https - return "https"; - } -} diff --git a/src/main/java/com/pipedream/api/resources/workflows/AsyncWorkflowsClient.java b/src/main/java/com/pipedream/api/resources/workflows/AsyncWorkflowsClient.java deleted file mode 100644 index 08f9081..0000000 --- a/src/main/java/com/pipedream/api/resources/workflows/AsyncWorkflowsClient.java +++ /dev/null @@ -1,128 +0,0 @@ -/** - * This file was manually created to add workflow invocation support. - */ -package com.pipedream.api.resources.workflows; - -import com.pipedream.api.core.ClientOptions; -import com.pipedream.api.core.RequestOptions; -import com.pipedream.api.resources.workflows.requests.InvokeWorkflowForExternalUserOpts; -import com.pipedream.api.resources.workflows.requests.InvokeWorkflowOpts; -import java.util.concurrent.CompletableFuture; - -public class AsyncWorkflowsClient { - protected final ClientOptions clientOptions; - - private final AsyncRawWorkflowsClient rawClient; - - public AsyncWorkflowsClient(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - this.rawClient = new AsyncRawWorkflowsClient(clientOptions); - } - - /** - * Get responses with HTTP metadata like headers - */ - public AsyncRawWorkflowsClient withRawResponse() { - return this.rawClient; - } - - /** - * Invokes a workflow using the URL of its HTTP interface(s). - * - * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint - * @return A future containing the response from the workflow - */ - public CompletableFuture invoke(String urlOrEndpoint) { - InvokeWorkflowOpts request = - InvokeWorkflowOpts.builder().urlOrEndpoint(urlOrEndpoint).build(); - return this.rawClient.invoke(request).thenApply(response -> response.body()); - } - - /** - * Invokes a workflow using the URL of its HTTP interface(s). - * - * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint - * @param requestOptions Additional request options - * @return A future containing the response from the workflow - */ - public CompletableFuture invoke(String urlOrEndpoint, RequestOptions requestOptions) { - InvokeWorkflowOpts request = - InvokeWorkflowOpts.builder().urlOrEndpoint(urlOrEndpoint).build(); - return this.rawClient.invoke(request, requestOptions).thenApply(response -> response.body()); - } - - /** - * Invokes a workflow using the InvokeWorkflowOpts request object. - * - * @param request The request containing workflow invocation parameters - * @return A future containing the response from the workflow - */ - public CompletableFuture invoke(InvokeWorkflowOpts request) { - return this.rawClient.invoke(request).thenApply(response -> response.body()); - } - - /** - * Invokes a workflow using the InvokeWorkflowOpts request object. - * - * @param request The request containing workflow invocation parameters - * @param requestOptions Additional request options - * @return A future containing the response from the workflow - */ - public CompletableFuture invoke(InvokeWorkflowOpts request, RequestOptions requestOptions) { - return this.rawClient.invoke(request, requestOptions).thenApply(response -> response.body()); - } - - /** - * Invokes a workflow for a Pipedream Connect user in a project. - * - * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint - * @param externalUserId Your end user ID, for whom you're invoking the workflow - * @return A future containing the response from the workflow - */ - public CompletableFuture invokeForExternalUser(String urlOrEndpoint, String externalUserId) { - InvokeWorkflowForExternalUserOpts request = InvokeWorkflowForExternalUserOpts.builder() - .url(urlOrEndpoint) - .externalUserId(externalUserId) - .build(); - return this.rawClient.invokeForExternalUser(request).thenApply(response -> response.body()); - } - - /** - * Invokes a workflow for a Pipedream Connect user in a project. - * - * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint - * @param externalUserId Your end user ID, for whom you're invoking the workflow - * @param requestOptions Additional request options - * @return A future containing the response from the workflow - */ - public CompletableFuture invokeForExternalUser( - String urlOrEndpoint, String externalUserId, RequestOptions requestOptions) { - InvokeWorkflowForExternalUserOpts request = InvokeWorkflowForExternalUserOpts.builder() - .url(urlOrEndpoint) - .externalUserId(externalUserId) - .build(); - return this.rawClient.invokeForExternalUser(request, requestOptions).thenApply(response -> response.body()); - } - - /** - * Invokes a workflow for a Pipedream Connect user using the InvokeWorkflowForExternalUserOpts request object. - * - * @param request The request containing workflow invocation parameters - * @return A future containing the response from the workflow - */ - public CompletableFuture invokeForExternalUser(InvokeWorkflowForExternalUserOpts request) { - return this.rawClient.invokeForExternalUser(request).thenApply(response -> response.body()); - } - - /** - * Invokes a workflow for a Pipedream Connect user using the InvokeWorkflowForExternalUserOpts request object. - * - * @param request The request containing workflow invocation parameters - * @param requestOptions Additional request options - * @return A future containing the response from the workflow - */ - public CompletableFuture invokeForExternalUser( - InvokeWorkflowForExternalUserOpts request, RequestOptions requestOptions) { - return this.rawClient.invokeForExternalUser(request, requestOptions).thenApply(response -> response.body()); - } -} diff --git a/src/main/java/com/pipedream/api/resources/workflows/RawWorkflowsClient.java b/src/main/java/com/pipedream/api/resources/workflows/RawWorkflowsClient.java deleted file mode 100644 index d4dd787..0000000 --- a/src/main/java/com/pipedream/api/resources/workflows/RawWorkflowsClient.java +++ /dev/null @@ -1,241 +0,0 @@ -/** - * This file was manually created to add workflow invocation support. - */ -package com.pipedream.api.resources.workflows; - -import com.pipedream.api.core.BaseClientApiException; -import com.pipedream.api.core.BaseClientException; -import com.pipedream.api.core.BaseClientHttpResponse; -import com.pipedream.api.core.ClientOptions; -import com.pipedream.api.core.MediaTypes; -import com.pipedream.api.core.ObjectMappers; -import com.pipedream.api.core.RequestOptions; -import com.pipedream.api.resources.workflows.requests.InvokeWorkflowForExternalUserOpts; -import com.pipedream.api.resources.workflows.requests.InvokeWorkflowOpts; -import com.pipedream.api.types.HTTPAuthType; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import okhttp3.Headers; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import okhttp3.ResponseBody; - -public class RawWorkflowsClient { - protected final ClientOptions clientOptions; - private final String workflowDomain; - private final String urlProtocol; - - public RawWorkflowsClient(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - String workflowDomainEnv = System.getenv("PIPEDREAM_WORKFLOW_DOMAIN"); - this.workflowDomain = workflowDomainEnv != null ? workflowDomainEnv : getDefaultWorkflowDomain(); - this.urlProtocol = getUrlProtocol(); - } - - public BaseClientHttpResponse invoke(InvokeWorkflowOpts request) { - return invoke(request, null); - } - - public BaseClientHttpResponse invoke(InvokeWorkflowOpts request, RequestOptions requestOptions) { - // Build the workflow URL - String urlString = buildWorkflowUrl(request.getUrlOrEndpoint()); - - HttpUrl httpUrl; - try { - httpUrl = HttpUrl.parse(urlString); - if (httpUrl == null) { - throw new IllegalArgumentException("Invalid URL: " + urlString); - } - } catch (Exception e) { - throw new IllegalArgumentException("Invalid URL: " + urlString, e); - } - - // Determine auth type - default to OAuth if not specified - HTTPAuthType authType = request.getAuthType().orElse(HTTPAuthType.OAUTH); - - // Prepare headers - start with client options headers (includes OAuth auth if configured) - Map allHeaders = new HashMap<>(clientOptions.headers(requestOptions)); - - // Handle authentication based on type - if (authType == HTTPAuthType.OAUTH) { - // For OAuth, the Authorization header should already be in clientOptions.headers() - // No additional action needed - } else if (authType == HTTPAuthType.STATIC_BEARER) { - // For static_bearer, users must provide the Authorization header in request.getHeaders() - // Their header will override any existing OAuth header when we merge request headers - } else if (authType == HTTPAuthType.NONE) { - // For NONE auth type, set Authorization header to empty string (matches Python SDK) - allHeaders.put("Authorization", ""); - } - - // Add request-specific headers (can override auth headers for STATIC_BEARER) - if (request.getHeaders().isPresent()) { - allHeaders.putAll(request.getHeaders().get()); - } - - // Determine HTTP method - String method = request.getMethod().orElse("POST").toUpperCase(); - - // Prepare request body if needed - RequestBody body = null; - if (request.getBody().isPresent()) { - try { - body = RequestBody.create( - ObjectMappers.JSON_MAPPER.writeValueAsBytes( - request.getBody().get()), - MediaTypes.APPLICATION_JSON); - allHeaders.put("Content-Type", "application/json"); - } catch (Exception e) { - throw new RuntimeException("Failed to serialize request body", e); - } - } else if (("POST".equals(method) || "PUT".equals(method) || "PATCH".equals(method))) { - // For methods that typically require a body, send an empty body - // to avoid OkHttp's "method POST must have a request body" error - body = RequestBody.create(new byte[0], null); - } - - // Build the request - Request.Builder requestBuilder = - new Request.Builder().url(httpUrl).method(method, body).headers(Headers.of(allHeaders)); - - if (!allHeaders.containsKey("Accept")) { - requestBuilder.addHeader("Accept", "application/json"); - } - - Request okhttpRequest = requestBuilder.build(); - - // Execute the request - OkHttpClient client = clientOptions.httpClient(); - if (requestOptions != null && requestOptions.getTimeout().isPresent()) { - client = clientOptions.httpClientWithTimeout(requestOptions); - } - - try (Response response = client.newCall(okhttpRequest).execute()) { - ResponseBody responseBody = response.body(); - if (response.isSuccessful()) { - String responseBodyString = responseBody != null ? responseBody.string() : "{}"; - Object parsedResponse; - try { - parsedResponse = ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class); - } catch (Exception e) { - // If JSON parsing fails, return the raw string - parsedResponse = responseBodyString; - } - return new BaseClientHttpResponse<>(parsedResponse, response); - } - String responseBodyString = responseBody != null ? responseBody.string() : "{}"; - throw new BaseClientApiException( - "Error with status code " + response.code(), - response.code(), - ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), - response); - } catch (IOException e) { - throw new BaseClientException("Network error executing HTTP request", e); - } - } - - public BaseClientHttpResponse invokeForExternalUser(InvokeWorkflowForExternalUserOpts request) { - return invokeForExternalUser(request, null); - } - - public BaseClientHttpResponse invokeForExternalUser( - InvokeWorkflowForExternalUserOpts request, RequestOptions requestOptions) { - - // Validate inputs - if (request.getExternalUserId() == null - || request.getExternalUserId().trim().isEmpty()) { - throw new IllegalArgumentException("External user ID is required"); - } - - if (request.getUrl() == null || request.getUrl().trim().isEmpty()) { - throw new IllegalArgumentException("Workflow URL is required"); - } - - // Prepare headers with external user ID - Map headers = new HashMap<>(); - if (request.getHeaders().isPresent()) { - headers.putAll(request.getHeaders().get()); - } - headers.put("X-PD-External-User-ID", request.getExternalUserId()); - - // Create a new request with the authentication from the original request and the external user header - InvokeWorkflowOpts invokeRequest = InvokeWorkflowOpts.builder() - .urlOrEndpoint(request.getUrl()) - .body(request.getBody()) - .headers(headers) - .method(request.getMethod()) - .authType(request.getAuthType().orElse(HTTPAuthType.OAUTH)) - .build(); - - return invoke(invokeRequest, requestOptions); - } - - /** - * Builds a full workflow URL based on the input. - * - * @param input Either a full URL (with or without protocol) or just an endpoint ID. - * @return The fully constructed URL. - */ - private String buildWorkflowUrl(String input) { - String sanitizedInput = input.trim().toLowerCase(); - if (sanitizedInput.isEmpty()) { - throw new IllegalArgumentException("URL or endpoint ID is required"); - } - - // Check if it's already a full URL - if (sanitizedInput.startsWith("http://") || sanitizedInput.startsWith("https://")) { - try { - URL url = new URL(input); - // Validate the hostname - String workflowDomain = this.workflowDomain; - if (!url.getHost().endsWith(this.workflowDomain)) { - throw new IllegalArgumentException( - "Invalid workflow domain. URL must end with " + this.workflowDomain); - } - return input; - } catch (MalformedURLException e) { - throw new IllegalArgumentException("The provided URL is malformed: " + input, e); - } - } - - // Check if it's a URL without protocol - if (sanitizedInput.contains(".")) { - return buildWorkflowUrl("https://" + input); - } - - // It's an endpoint ID - if (!sanitizedInput.matches("^e[no][a-z0-9-]+$")) { - throw new IllegalArgumentException( - "Invalid endpoint ID format. Must contain only letters, numbers, and hyphens, " - + "and start with either 'en' or 'eo'."); - } - - return urlProtocol + "://" + sanitizedInput + "." + workflowDomain; - } - - private String getDefaultWorkflowDomain() { - String envUrl = clientOptions.environment().getUrl(); - // For non-prod environments (dev, staging), use dev domain - if (!envUrl.equals("https://api.pipedream.com") && !envUrl.equals("https://api2.pipedream.com")) { - return "m.d.pipedream.net"; - } - // For prod and canary, use standard domain - return "m.pipedream.net"; - } - - private String getUrlProtocol() { - String envUrl = clientOptions.environment().getUrl(); - // For non-prod environments (dev, staging), use http - if (!envUrl.equals("https://api.pipedream.com") && !envUrl.equals("https://api2.pipedream.com")) { - return "http"; - } - // For prod and canary, use https - return "https"; - } -} diff --git a/src/main/java/com/pipedream/api/resources/workflows/WorkflowsClient.java b/src/main/java/com/pipedream/api/resources/workflows/WorkflowsClient.java deleted file mode 100644 index 935ce7d..0000000 --- a/src/main/java/com/pipedream/api/resources/workflows/WorkflowsClient.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * This file was manually created to add workflow invocation support. - */ -package com.pipedream.api.resources.workflows; - -import com.pipedream.api.core.ClientOptions; -import com.pipedream.api.core.RequestOptions; -import com.pipedream.api.resources.workflows.requests.InvokeWorkflowForExternalUserOpts; -import com.pipedream.api.resources.workflows.requests.InvokeWorkflowOpts; - -public class WorkflowsClient { - protected final ClientOptions clientOptions; - - private final RawWorkflowsClient rawClient; - - public WorkflowsClient(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - this.rawClient = new RawWorkflowsClient(clientOptions); - } - - /** - * Get responses with HTTP metadata like headers - */ - public RawWorkflowsClient withRawResponse() { - return this.rawClient; - } - - /** - * Invokes a workflow using the URL of its HTTP interface(s). - * - * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint - * @return The response from the workflow - */ - public Object invoke(String urlOrEndpoint) { - InvokeWorkflowOpts request = - InvokeWorkflowOpts.builder().urlOrEndpoint(urlOrEndpoint).build(); - return this.rawClient.invoke(request).body(); - } - - /** - * Invokes a workflow using the URL of its HTTP interface(s). - * - * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint - * @param requestOptions Additional request options - * @return The response from the workflow - */ - public Object invoke(String urlOrEndpoint, RequestOptions requestOptions) { - InvokeWorkflowOpts request = - InvokeWorkflowOpts.builder().urlOrEndpoint(urlOrEndpoint).build(); - return this.rawClient.invoke(request, requestOptions).body(); - } - - /** - * Invokes a workflow using the InvokeWorkflowOpts request object. - * - * @param request The request containing workflow invocation parameters - * @return The response from the workflow - */ - public Object invoke(InvokeWorkflowOpts request) { - return this.rawClient.invoke(request).body(); - } - - /** - * Invokes a workflow using the InvokeWorkflowOpts request object. - * - * @param request The request containing workflow invocation parameters - * @param requestOptions Additional request options - * @return The response from the workflow - */ - public Object invoke(InvokeWorkflowOpts request, RequestOptions requestOptions) { - return this.rawClient.invoke(request, requestOptions).body(); - } - - /** - * Invokes a workflow for a Pipedream Connect user in a project. - * - * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint - * @param externalUserId Your end user ID, for whom you're invoking the workflow - * @return The response from the workflow - */ - public Object invokeForExternalUser(String urlOrEndpoint, String externalUserId) { - InvokeWorkflowForExternalUserOpts request = InvokeWorkflowForExternalUserOpts.builder() - .url(urlOrEndpoint) - .externalUserId(externalUserId) - .build(); - return this.rawClient.invokeForExternalUser(request).body(); - } - - /** - * Invokes a workflow for a Pipedream Connect user in a project. - * - * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint - * @param externalUserId Your end user ID, for whom you're invoking the workflow - * @param requestOptions Additional request options - * @return The response from the workflow - */ - public Object invokeForExternalUser(String urlOrEndpoint, String externalUserId, RequestOptions requestOptions) { - InvokeWorkflowForExternalUserOpts request = InvokeWorkflowForExternalUserOpts.builder() - .url(urlOrEndpoint) - .externalUserId(externalUserId) - .build(); - return this.rawClient.invokeForExternalUser(request, requestOptions).body(); - } - - /** - * Invokes a workflow for a Pipedream Connect user using the InvokeWorkflowForExternalUserOpts request object. - * - * @param request The request containing workflow invocation parameters - * @return The response from the workflow - */ - public Object invokeForExternalUser(InvokeWorkflowForExternalUserOpts request) { - return this.rawClient.invokeForExternalUser(request).body(); - } - - /** - * Invokes a workflow for a Pipedream Connect user using the InvokeWorkflowForExternalUserOpts request object. - * - * @param request The request containing workflow invocation parameters - * @param requestOptions Additional request options - * @return The response from the workflow - */ - public Object invokeForExternalUser(InvokeWorkflowForExternalUserOpts request, RequestOptions requestOptions) { - return this.rawClient.invokeForExternalUser(request, requestOptions).body(); - } -} diff --git a/src/main/java/com/pipedream/api/resources/workflows/package-info.java b/src/main/java/com/pipedream/api/resources/workflows/package-info.java deleted file mode 100644 index cbd2a49..0000000 --- a/src/main/java/com/pipedream/api/resources/workflows/package-info.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This package contains client classes for invoking Pipedream workflows. - * - *

The workflows package provides functionality to: - *

    - *
  • Invoke workflows using their HTTP interface URLs or endpoint IDs
  • - *
  • Invoke workflows on behalf of external users (Pipedream Connect)
  • - *
  • Support both synchronous and asynchronous invocation patterns
  • - *
- * - *

Example usage: - *

- * // Invoke a workflow
- * Object response = client.workflows().invoke("https://your-workflow.m.pipedream.net",
- *     "POST", Map.of("key", "value"), null, HTTPAuthType.OAUTH);
- *
- * // Invoke a workflow for an external user
- * Object response = client.workflows().invokeForExternalUser(
- *     "https://your-workflow.m.pipedream.net",
- *     "external-user-123",
- *     "POST",
- *     Map.of("data", "payload"),
- *     null
- * );
- * 
- */ -package com.pipedream.api.resources.workflows; diff --git a/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowForExternalUserOpts.java b/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowForExternalUserOpts.java deleted file mode 100644 index 296fb55..0000000 --- a/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowForExternalUserOpts.java +++ /dev/null @@ -1,182 +0,0 @@ -/** - * This file was manually created to add workflow invocation support. - */ -package com.pipedream.api.resources.workflows.requests; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.pipedream.api.types.HTTPAuthType; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = InvokeWorkflowForExternalUserOpts.Builder.class) -public final class InvokeWorkflowForExternalUserOpts { - private final String url; - - private final String externalUserId; - - private final Optional body; - - private final Optional> headers; - - private final Optional method; - - private final Optional authType; - - private InvokeWorkflowForExternalUserOpts( - String url, - String externalUserId, - Optional body, - Optional> headers, - Optional method, - Optional authType) { - this.url = url; - this.externalUserId = externalUserId; - this.body = body; - this.headers = headers; - this.method = method; - this.authType = authType; - } - - @JsonProperty("url") - public String getUrl() { - return url; - } - - @JsonProperty("externalUserId") - public String getExternalUserId() { - return externalUserId; - } - - @JsonProperty("body") - public Optional getBody() { - return body; - } - - @JsonProperty("headers") - public Optional> getHeaders() { - return headers; - } - - @JsonProperty("method") - public Optional getMethod() { - return method; - } - - @JsonProperty("authType") - public Optional getAuthType() { - return authType; - } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof InvokeWorkflowForExternalUserOpts && equalTo((InvokeWorkflowForExternalUserOpts) other); - } - - private boolean equalTo(InvokeWorkflowForExternalUserOpts other) { - return url.equals(other.url) - && externalUserId.equals(other.externalUserId) - && body.equals(other.body) - && headers.equals(other.headers) - && method.equals(other.method) - && authType.equals(other.authType); - } - - @Override - public int hashCode() { - return Objects.hash(this.url, this.externalUserId, this.body, this.headers, this.method, this.authType); - } - - @Override - public String toString() { - return "InvokeWorkflowForExternalUserOpts{url: " + url + ", externalUserId: " + externalUserId + ", body: " - + body + ", headers: " + headers + ", method: " + method + ", authType: " + authType + "}"; - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - private String url; - - private String externalUserId; - - private Optional body = Optional.empty(); - - private Optional> headers = Optional.empty(); - - private Optional method = Optional.empty(); - - private Optional authType = Optional.empty(); - - private Builder() {} - - @JsonSetter("url") - public Builder url(String url) { - this.url = url; - return this; - } - - @JsonSetter("externalUserId") - public Builder externalUserId(String externalUserId) { - this.externalUserId = externalUserId; - return this; - } - - @JsonSetter(value = "body", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) - public Builder body(Optional body) { - this.body = body; - return this; - } - - public Builder body(Object body) { - this.body = Optional.ofNullable(body); - return this; - } - - @JsonSetter(value = "headers", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) - public Builder headers(Optional> headers) { - this.headers = headers; - return this; - } - - public Builder headers(Map headers) { - this.headers = Optional.ofNullable(headers); - return this; - } - - @JsonSetter(value = "method", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) - public Builder method(Optional method) { - this.method = method; - return this; - } - - public Builder method(String method) { - this.method = Optional.ofNullable(method); - return this; - } - - @JsonSetter(value = "authType", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) - public Builder authType(Optional authType) { - this.authType = authType; - return this; - } - - public Builder authType(HTTPAuthType authType) { - this.authType = Optional.ofNullable(authType); - return this; - } - - public InvokeWorkflowForExternalUserOpts build() { - return new InvokeWorkflowForExternalUserOpts(url, externalUserId, body, headers, method, authType); - } - } -} diff --git a/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowOpts.java b/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowOpts.java deleted file mode 100644 index 468d227..0000000 --- a/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowOpts.java +++ /dev/null @@ -1,164 +0,0 @@ -/** - * This file was manually created to add workflow invocation support. - */ -package com.pipedream.api.resources.workflows.requests; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.pipedream.api.types.HTTPAuthType; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = InvokeWorkflowOpts.Builder.class) -public final class InvokeWorkflowOpts { - private final String urlOrEndpoint; - - private final Optional body; - - private final Optional> headers; - - private final Optional method; - - private final Optional authType; - - private InvokeWorkflowOpts( - String urlOrEndpoint, - Optional body, - Optional> headers, - Optional method, - Optional authType) { - this.urlOrEndpoint = urlOrEndpoint; - this.body = body; - this.headers = headers; - this.method = method; - this.authType = authType; - } - - @JsonProperty("urlOrEndpoint") - public String getUrlOrEndpoint() { - return urlOrEndpoint; - } - - @JsonProperty("body") - public Optional getBody() { - return body; - } - - @JsonProperty("headers") - public Optional> getHeaders() { - return headers; - } - - @JsonProperty("method") - public Optional getMethod() { - return method; - } - - @JsonProperty("authType") - public Optional getAuthType() { - return authType; - } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof InvokeWorkflowOpts && equalTo((InvokeWorkflowOpts) other); - } - - private boolean equalTo(InvokeWorkflowOpts other) { - return urlOrEndpoint.equals(other.urlOrEndpoint) - && body.equals(other.body) - && headers.equals(other.headers) - && method.equals(other.method) - && authType.equals(other.authType); - } - - @Override - public int hashCode() { - return Objects.hash(this.urlOrEndpoint, this.body, this.headers, this.method, this.authType); - } - - @Override - public String toString() { - return "InvokeWorkflowOpts{urlOrEndpoint: " + urlOrEndpoint + ", body: " + body + ", headers: " + headers - + ", method: " + method + ", authType: " + authType + "}"; - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - private String urlOrEndpoint; - - private Optional body = Optional.empty(); - - private Optional> headers = Optional.empty(); - - private Optional method = Optional.empty(); - - private Optional authType = Optional.empty(); - - private Builder() {} - - @JsonSetter("urlOrEndpoint") - public Builder urlOrEndpoint(String urlOrEndpoint) { - this.urlOrEndpoint = urlOrEndpoint; - return this; - } - - @JsonSetter(value = "body", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) - public Builder body(Optional body) { - this.body = body; - return this; - } - - public Builder body(Object body) { - this.body = Optional.ofNullable(body); - return this; - } - - @JsonSetter(value = "headers", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) - public Builder headers(Optional> headers) { - this.headers = headers; - return this; - } - - public Builder headers(Map headers) { - this.headers = Optional.ofNullable(headers); - return this; - } - - @JsonSetter(value = "method", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) - public Builder method(Optional method) { - this.method = method; - return this; - } - - public Builder method(String method) { - this.method = Optional.ofNullable(method); - return this; - } - - @JsonSetter(value = "authType", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) - public Builder authType(Optional authType) { - this.authType = authType; - return this; - } - - public Builder authType(HTTPAuthType authType) { - this.authType = Optional.ofNullable(authType); - return this; - } - - public InvokeWorkflowOpts build() { - return new InvokeWorkflowOpts(urlOrEndpoint, body, headers, method, authType); - } - } -} diff --git a/src/main/java/com/pipedream/api/types/HTTPAuthType.java b/src/main/java/com/pipedream/api/types/HTTPAuthType.java deleted file mode 100644 index d4e4d15..0000000 --- a/src/main/java/com/pipedream/api/types/HTTPAuthType.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * This file was manually created to add workflow invocation support. - */ -package com.pipedream.api.types; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -/** - * Authentication types for workflow invocation - */ -public enum HTTPAuthType { - NONE("none"), - STATIC_BEARER("static_bearer_token"), - OAUTH("oauth"); - - private final String value; - - HTTPAuthType(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } - - @JsonCreator - public static HTTPAuthType fromValue(String value) { - for (HTTPAuthType type : HTTPAuthType.values()) { - if (type.value.equals(value)) { - return type; - } - } - throw new IllegalArgumentException("Unknown HTTPAuthType: " + value); - } - - @Override - public String toString() { - return value; - } -} diff --git a/src/test/java/com/pipedream/api/OauthTokensWireTest.java b/src/test/java/com/pipedream/api/OauthTokensWireTest.java deleted file mode 100644 index 5ded14b..0000000 --- a/src/test/java/com/pipedream/api/OauthTokensWireTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.pipedream.api; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.pipedream.api.core.ObjectMappers; -import com.pipedream.api.resources.oauthtokens.requests.CreateOAuthTokenOpts; -import com.pipedream.api.testutil.MockResponse; -import com.pipedream.api.testutil.MockWebServer; -import com.pipedream.api.testutil.RecordedRequest; -import com.pipedream.api.types.CreateOAuthTokenResponse; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class OauthTokensWireTest { - private MockWebServer server; - private BaseClient client; - private ObjectMapper objectMapper = ObjectMappers.JSON_MAPPER; - - @BeforeEach - public void setup() throws Exception { - server = new MockWebServer(); - server.start(); - client = PipedreamClient.builder().url(server.url("/").toString()).build(); - } - - @AfterEach - public void teardown() throws Exception { - server.shutdown(); - } - - @Test - public void testCreate() throws Exception { - server.enqueue(new MockResponse() - .setResponseCode(200) - .setBody("{\"access_token\":\"access_token\",\"token_type\":\"token_type\",\"expires_in\":1}")); - CreateOAuthTokenResponse response = client.oauthTokens() - .create(CreateOAuthTokenOpts.builder() - .clientId("client_id") - .clientSecret("client_secret") - .build()); - RecordedRequest request = server.takeRequest(); - Assertions.assertNotNull(request); - Assertions.assertEquals("POST", request.getMethod()); - // Validate request body - String actualRequestBody = request.getBody().readUtf8(); - String expectedRequestBody = "" - + "{\n" - + " \"grant_type\": \"client_credentials\",\n" - + " \"client_id\": \"client_id\",\n" - + " \"client_secret\": \"client_secret\"\n" - + "}"; - JsonNode actualJson = objectMapper.readTree(actualRequestBody); - JsonNode expectedJson = objectMapper.readTree(expectedRequestBody); - Assertions.assertEquals(expectedJson, actualJson, "Request body structure does not match expected"); - if (actualJson.has("type") || actualJson.has("_type") || actualJson.has("kind")) { - String discriminator = null; - if (actualJson.has("type")) discriminator = actualJson.get("type").asText(); - else if (actualJson.has("_type")) - discriminator = actualJson.get("_type").asText(); - else if (actualJson.has("kind")) - discriminator = actualJson.get("kind").asText(); - Assertions.assertNotNull(discriminator, "Union type should have a discriminator field"); - Assertions.assertFalse(discriminator.isEmpty(), "Union discriminator should not be empty"); - } - - if (!actualJson.isNull()) { - Assertions.assertTrue( - actualJson.isObject() || actualJson.isArray() || actualJson.isValueNode(), - "request should be a valid JSON value"); - } - - if (actualJson.isArray()) { - Assertions.assertTrue(actualJson.size() >= 0, "Array should have valid size"); - } - if (actualJson.isObject()) { - Assertions.assertTrue(actualJson.size() >= 0, "Object should have valid field count"); - } - - // Validate response body - Assertions.assertNotNull(response, "Response should not be null"); - String actualResponseJson = objectMapper.writeValueAsString(response); - String expectedResponseBody = "" - + "{\n" - + " \"access_token\": \"access_token\",\n" - + " \"token_type\": \"token_type\",\n" - + " \"expires_in\": 1\n" - + "}"; - JsonNode actualResponseNode = objectMapper.readTree(actualResponseJson); - JsonNode expectedResponseNode = objectMapper.readTree(expectedResponseBody); - Assertions.assertEquals( - expectedResponseNode, actualResponseNode, "Response body structure does not match expected"); - if (actualResponseNode.has("type") || actualResponseNode.has("_type") || actualResponseNode.has("kind")) { - String discriminator = null; - if (actualResponseNode.has("type")) - discriminator = actualResponseNode.get("type").asText(); - else if (actualResponseNode.has("_type")) - discriminator = actualResponseNode.get("_type").asText(); - else if (actualResponseNode.has("kind")) - discriminator = actualResponseNode.get("kind").asText(); - Assertions.assertNotNull(discriminator, "Union type should have a discriminator field"); - Assertions.assertFalse(discriminator.isEmpty(), "Union discriminator should not be empty"); - } - - if (!actualResponseNode.isNull()) { - Assertions.assertTrue( - actualResponseNode.isObject() || actualResponseNode.isArray() || actualResponseNode.isValueNode(), - "response should be a valid JSON value"); - } - - if (actualResponseNode.isArray()) { - Assertions.assertTrue(actualResponseNode.size() >= 0, "Array should have valid size"); - } - if (actualResponseNode.isObject()) { - Assertions.assertTrue(actualResponseNode.size() >= 0, "Object should have valid field count"); - } - } -} diff --git a/src/test/java/com/pipedream/api/ProxyClientWireTest.java b/src/test/java/com/pipedream/api/ProxyClientWireTest.java deleted file mode 100644 index 1069e10..0000000 --- a/src/test/java/com/pipedream/api/ProxyClientWireTest.java +++ /dev/null @@ -1,379 +0,0 @@ -package com.pipedream.api; - -import static org.junit.jupiter.api.Assertions.*; - -import com.pipedream.api.resources.proxy.requests.ProxyGetRequest; -import com.pipedream.api.resources.proxy.types.ProxyResponse; -import com.pipedream.api.testutil.MockResponse; -import com.pipedream.api.testutil.MockWebServer; -import com.pipedream.api.testutil.RecordedRequest; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import okhttp3.HttpUrl; -import okio.Buffer; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class ProxyClientWireTest { - private MockWebServer server; - private BaseClient client; - private AsyncBaseClient asyncClient; - - private static final String TEST_EXTERNAL_USER_ID = "test-user-123"; - private static final String TEST_ACCOUNT_ID = "test-account-456"; - private static final String TEST_URL = "https://api.example.com/data"; - - @BeforeEach - public void setup() throws Exception { - server = new MockWebServer(); - server.start(); - String baseUrl = server.url("/").toString(); - // Explicitly set credentials to null to avoid OAuth token fetching - // (environment variables might be set, which would trigger network calls) - client = - PipedreamClient.builder().url(baseUrl).projectId("test-project").build(); - asyncClient = AsyncPipedreamClient.builder() - .url(baseUrl) - .projectId("test-project") - .build(); - } - - @AfterEach - public void teardown() throws Exception { - server.shutdown(); - } - - private ProxyGetRequest createGetRequest() { - return ProxyGetRequest.builder() - .externalUserId(TEST_EXTERNAL_USER_ID) - .accountId(TEST_ACCOUNT_ID) - .build(); - } - - /** - * Java 8-compatible replacement for InputStream.readAllBytes() (Java 9+). - */ - private byte[] readAllBytes(InputStream is) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - byte[] data = new byte[1024]; - int bytesRead; - while ((bytesRead = is.read(data, 0, data.length)) != -1) { - buffer.write(data, 0, bytesRead); - } - return buffer.toByteArray(); - } - - // ==================== Sync Client Tests ==================== - - @Test - public void testGetJsonResponse() throws Exception { - String jsonBody = "{\"key\":\"value\",\"number\":42}"; - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/json") - .setBody(jsonBody)); - - try (ProxyResponse response = client.proxy().get(TEST_URL, createGetRequest())) { - - // Verify response type - assertTrue(response.isJson(), "Response should be JSON"); - assertFalse(response.isStream(), "Response should not be a stream"); - - // Verify parsed JSON content - Object json = response.json(); - assertNotNull(json, "JSON body should not be null"); - assertInstanceOf(Map.class, json, "JSON body should be a Map"); - - @SuppressWarnings("unchecked") - Map jsonMap = (Map) json; - assertEquals("value", jsonMap.get("key")); - assertEquals(42, jsonMap.get("number")); - - // Verify content type is preserved - assertTrue(response.getContentType().isPresent()); - assertEquals("application/json", response.getContentType().get()); - } - - // Verify request was made correctly - RecordedRequest request = server.takeRequest(); - assertNotNull(request); - assertEquals("GET", request.getMethod()); - } - - @Test - public void testGetJsonResponseWithCharset() throws Exception { - String jsonBody = "{\"message\":\"hello\"}"; - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/json; charset=utf-8") - .setBody(jsonBody)); - - try (ProxyResponse response = client.proxy().get(TEST_URL, createGetRequest())) { - - // Should still be detected as JSON even with charset parameter - assertTrue(response.isJson(), "Response should be JSON even with charset"); - - @SuppressWarnings("unchecked") - Map jsonMap = (Map) response.json(); - assertEquals("hello", jsonMap.get("message")); - } - } - - @Test - public void testGetOctetStreamResponse() throws Exception { - byte[] binaryData = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; - Buffer buffer = new Buffer(); - buffer.write(binaryData); - - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/octet-stream") - .setBody(buffer)); - - try (ProxyResponse response = client.proxy().get(TEST_URL, createGetRequest())) { - - // Verify response type - assertTrue(response.isStream(), "Response should be a stream"); - assertFalse(response.isJson(), "Response should not be JSON"); - - // Verify binary content - byte[] actualData = readAllBytes(response.stream()); - assertArrayEquals(binaryData, actualData, "Binary data should match"); - - // Verify content type is preserved - assertTrue(response.getContentType().isPresent()); - assertEquals("application/octet-stream", response.getContentType().get()); - } - - // Verify request was made correctly - RecordedRequest request = server.takeRequest(); - assertNotNull(request); - assertEquals("GET", request.getMethod()); - } - - @Test - public void testGetRedirectFollowed() throws Exception { - // First response: 302 redirect - server.enqueue(new MockResponse() - .setResponseCode(302) - .setHeader("Location", server.url("/redirected").toString())); - - // Second response: 200 OK with JSON - String jsonBody = "{\"redirected\":true,\"status\":\"success\"}"; - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/json") - .setBody(jsonBody)); - - try (ProxyResponse response = client.proxy().get(TEST_URL, createGetRequest())) { - - // Verify we got the final response (redirect was followed) - assertTrue(response.isJson(), "Response should be JSON after redirect"); - - @SuppressWarnings("unchecked") - Map jsonMap = (Map) response.json(); - assertEquals(true, jsonMap.get("redirected")); - assertEquals("success", jsonMap.get("status")); - } - - // Verify both requests were made (original + redirect) - RecordedRequest firstRequest = server.takeRequest(); - assertNotNull(firstRequest); - assertEquals("GET", firstRequest.getMethod()); - - RecordedRequest secondRequest = server.takeRequest(); - assertNotNull(secondRequest); - assertEquals("GET", secondRequest.getMethod()); - assertNotNull(secondRequest.getPath()); - assertTrue(secondRequest.getPath().contains("redirected")); - } - - // ==================== Async Client Tests ==================== - - @Test - public void testAsyncGetJsonResponse() throws Exception { - String jsonBody = "{\"async\":true,\"data\":\"test\"}"; - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/json") - .setBody(jsonBody)); - - CompletableFuture future = asyncClient.proxy().get(TEST_URL, createGetRequest()); - try (ProxyResponse response = future.get(10, TimeUnit.SECONDS)) { - - // Verify response type - assertTrue(response.isJson(), "Response should be JSON"); - assertFalse(response.isStream(), "Response should not be a stream"); - - // Verify parsed JSON content - @SuppressWarnings("unchecked") - Map jsonMap = (Map) response.json(); - assertEquals(true, jsonMap.get("async")); - assertEquals("test", jsonMap.get("data")); - } - - // Verify request was made correctly - RecordedRequest request = server.takeRequest(); - assertNotNull(request); - assertEquals("GET", request.getMethod()); - } - - @Test - public void testAsyncGetOctetStreamResponse() throws Exception { - byte[] binaryData = new byte[] {(byte) 0xFF, (byte) 0xFE, (byte) 0xFD}; - Buffer buffer = new Buffer(); - buffer.write(binaryData); - - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/octet-stream") - .setBody(buffer)); - - CompletableFuture future = asyncClient.proxy().get(TEST_URL, createGetRequest()); - try (ProxyResponse response = future.get(10, TimeUnit.SECONDS)) { - - // Verify response type - assertTrue(response.isStream(), "Response should be a stream"); - assertFalse(response.isJson(), "Response should not be JSON"); - - // Verify binary content - byte[] actualData = readAllBytes(response.stream()); - assertArrayEquals(binaryData, actualData, "Binary data should match"); - } - - // Verify request was made correctly - RecordedRequest request = server.takeRequest(); - assertNotNull(request); - assertEquals("GET", request.getMethod()); - } - - @Test - public void testAsyncGetRedirectFollowed() throws Exception { - // First response: 302 redirect - server.enqueue(new MockResponse() - .setResponseCode(302) - .setHeader("Location", server.url("/async-redirected").toString())); - - // Second response: 200 OK with JSON - String jsonBody = "{\"asyncRedirected\":true}"; - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/json") - .setBody(jsonBody)); - - CompletableFuture future = asyncClient.proxy().get(TEST_URL, createGetRequest()); - try (ProxyResponse response = future.get(10, TimeUnit.SECONDS)) { - - // Verify we got the final response (redirect was followed) - assertTrue(response.isJson(), "Response should be JSON after redirect"); - - @SuppressWarnings("unchecked") - Map jsonMap = (Map) response.json(); - assertEquals(true, jsonMap.get("asyncRedirected")); - } - - // Verify both requests were made (original + redirect) - RecordedRequest firstRequest = server.takeRequest(); - assertNotNull(firstRequest); - - RecordedRequest secondRequest = server.takeRequest(); - assertNotNull(secondRequest); - assertNotNull(secondRequest.getPath()); - assertTrue(secondRequest.getPath().contains("async-redirected")); - } - - // ==================== HttpUrl Overload Tests ==================== - - @Test - public void testGetWithHttpUrl() throws Exception { - String jsonBody = "{\"key\":\"value\"}"; - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/json") - .setBody(jsonBody)); - - // Build URL with query parameters using HttpUrl - HttpUrl url = HttpUrl.parse(TEST_URL) - .newBuilder() - .addQueryParameter("fields", "name,mimeType") - .addQueryParameter("limit", "10") - .build(); - - try (ProxyResponse response = client.proxy().get(url, createGetRequest())) { - assertTrue(response.isJson(), "Response should be JSON"); - - @SuppressWarnings("unchecked") - Map jsonMap = (Map) response.json(); - assertEquals("value", jsonMap.get("key")); - } - - // Verify request was made correctly - RecordedRequest request = server.takeRequest(); - assertNotNull(request); - assertEquals("GET", request.getMethod()); - - // Verify the base64-encoded URL in the path contains the query parameters - String path = request.getPath(); - assertNotNull(path); - // The URL with query params should be base64-encoded in the path - // We can't easily decode it here, but we verify the request was made - } - - @Test - public void testGetWithHttpUrlAndSpecialCharacters() throws Exception { - String jsonBody = "{\"result\":\"ok\"}"; - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/json") - .setBody(jsonBody)); - - // Build URL with query parameters containing special characters - HttpUrl url = HttpUrl.parse(TEST_URL) - .newBuilder() - .addQueryParameter("filter", "status=active&type=user") - .addQueryParameter("name", "John Doe") - .build(); - - try (ProxyResponse response = client.proxy().get(url, createGetRequest())) { - assertTrue(response.isJson(), "Response should be JSON"); - } - - RecordedRequest request = server.takeRequest(); - assertNotNull(request); - assertEquals("GET", request.getMethod()); - } - - @Test - public void testAsyncGetWithHttpUrl() throws Exception { - String jsonBody = "{\"async\":true}"; - server.enqueue(new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/json") - .setBody(jsonBody)); - - // Build URL with query parameters using HttpUrl - HttpUrl url = HttpUrl.parse(TEST_URL) - .newBuilder() - .addQueryParameter("page", "1") - .addQueryParameter("size", "20") - .build(); - - CompletableFuture future = asyncClient.proxy().get(url, createGetRequest()); - try (ProxyResponse response = future.get(10, TimeUnit.SECONDS)) { - assertTrue(response.isJson(), "Response should be JSON"); - - @SuppressWarnings("unchecked") - Map jsonMap = (Map) response.json(); - assertEquals(true, jsonMap.get("async")); - } - - RecordedRequest request = server.takeRequest(); - assertNotNull(request); - assertEquals("GET", request.getMethod()); - } -} diff --git a/src/test/java/com/pipedream/api/TokensWireTest.java b/src/test/java/com/pipedream/api/TokensWireTest.java deleted file mode 100644 index d503c8c..0000000 --- a/src/test/java/com/pipedream/api/TokensWireTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.pipedream.api; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.pipedream.api.core.ObjectMappers; -import com.pipedream.api.resources.tokens.requests.TokensValidateRequest; -import com.pipedream.api.testutil.MockResponse; -import com.pipedream.api.testutil.MockWebServer; -import com.pipedream.api.testutil.RecordedRequest; -import com.pipedream.api.types.ValidateTokenResponse; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class TokensWireTest { - private MockWebServer server; - private BaseClient client; - private ObjectMapper objectMapper = ObjectMappers.JSON_MAPPER; - - @BeforeEach - public void setup() throws Exception { - server = new MockWebServer(); - server.start(); - client = PipedreamClient.builder().url(server.url("/").toString()).build(); - } - - @AfterEach - public void teardown() throws Exception { - server.shutdown(); - } - - @Test - public void testValidate() throws Exception { - server.enqueue( - new MockResponse() - .setResponseCode(200) - .setBody( - "{\"app\":{\"id\":\"id\",\"name_slug\":\"name_slug\",\"name\":\"name\",\"auth_type\":\"keys\",\"description\":\"description\",\"img_src\":\"img_src\",\"custom_fields_json\":\"custom_fields_json\",\"categories\":[\"categories\"],\"featured_weight\":1.1},\"error\":\"error\",\"error_redirect_uri\":\"error_redirect_uri\",\"oauth_app_id\":\"oauth_app_id\",\"project_app_name\":\"project_app_name\",\"project_environment\":\"project_environment\",\"project_id\":\"project_id\",\"project_support_email\":\"project_support_email\",\"success\":true,\"success_redirect_uri\":\"success_redirect_uri\"}")); - ValidateTokenResponse response = client.tokens() - .validate( - "ctok", - TokensValidateRequest.builder() - .appId("app_id") - .oauthAppId("oauth_app_id") - .build()); - RecordedRequest request = server.takeRequest(); - Assertions.assertNotNull(request); - Assertions.assertEquals("GET", request.getMethod()); - - // Validate response body - Assertions.assertNotNull(response, "Response should not be null"); - String actualResponseJson = objectMapper.writeValueAsString(response); - String expectedResponseBody = "" - + "{\n" - + " \"app\": {\n" - + " \"id\": \"id\",\n" - + " \"name_slug\": \"name_slug\",\n" - + " \"name\": \"name\",\n" - + " \"auth_type\": \"keys\",\n" - + " \"description\": \"description\",\n" - + " \"img_src\": \"img_src\",\n" - + " \"custom_fields_json\": \"custom_fields_json\",\n" - + " \"categories\": [\n" - + " \"categories\"\n" - + " ],\n" - + " \"featured_weight\": 1.1,\n" - + " \"scope_profiles\": []\n" - + " },\n" - + " \"error\": \"error\",\n" - + " \"error_redirect_uri\": \"error_redirect_uri\",\n" - + " \"oauth_app_id\": \"oauth_app_id\",\n" - + " \"project_app_name\": \"project_app_name\",\n" - + " \"project_environment\": \"project_environment\",\n" - + " \"project_id\": \"project_id\",\n" - + " \"project_support_email\": \"project_support_email\",\n" - + " \"success\": true,\n" - + " \"success_redirect_uri\": \"success_redirect_uri\"\n" - + "}"; - JsonNode actualResponseNode = objectMapper.readTree(actualResponseJson); - JsonNode expectedResponseNode = objectMapper.readTree(expectedResponseBody); - Assertions.assertEquals( - expectedResponseNode, actualResponseNode, "Response body structure does not match expected"); - if (actualResponseNode.has("type") || actualResponseNode.has("_type") || actualResponseNode.has("kind")) { - String discriminator = null; - if (actualResponseNode.has("type")) - discriminator = actualResponseNode.get("type").asText(); - else if (actualResponseNode.has("_type")) - discriminator = actualResponseNode.get("_type").asText(); - else if (actualResponseNode.has("kind")) - discriminator = actualResponseNode.get("kind").asText(); - Assertions.assertNotNull(discriminator, "Union type should have a discriminator field"); - Assertions.assertFalse(discriminator.isEmpty(), "Union discriminator should not be empty"); - } - - if (!actualResponseNode.isNull()) { - Assertions.assertTrue( - actualResponseNode.isObject() || actualResponseNode.isArray() || actualResponseNode.isValueNode(), - "response should be a valid JSON value"); - } - - if (actualResponseNode.isArray()) { - Assertions.assertTrue(actualResponseNode.size() >= 0, "Array should have valid size"); - } - if (actualResponseNode.isObject()) { - Assertions.assertTrue(actualResponseNode.size() >= 0, "Object should have valid field count"); - } - } -} diff --git a/src/test/java/com/pipedream/api/testutil/MockResponse.java b/src/test/java/com/pipedream/api/testutil/MockResponse.java deleted file mode 100644 index 84f54c2..0000000 --- a/src/test/java/com/pipedream/api/testutil/MockResponse.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.pipedream.api.testutil; - -import java.nio.charset.StandardCharsets; -import java.util.LinkedHashMap; -import java.util.Map; -import okio.Buffer; - -/** - * Drop-in replacement for {@code okhttp3.mockwebserver.MockResponse} backed by JDK primitives. - * Exposes only the surface used by the wire tests in this repo. - */ -public final class MockResponse { - int code = 200; - final Map headers = new LinkedHashMap<>(); - byte[] body = new byte[0]; - - public MockResponse setResponseCode(int code) { - this.code = code; - return this; - } - - public MockResponse setHeader(String name, String value) { - this.headers.put(name, value); - return this; - } - - public MockResponse setBody(String body) { - this.body = body.getBytes(StandardCharsets.UTF_8); - return this; - } - - public MockResponse setBody(Buffer body) { - this.body = body.readByteArray(); - return this; - } -} diff --git a/src/test/java/com/pipedream/api/testutil/MockWebServer.java b/src/test/java/com/pipedream/api/testutil/MockWebServer.java deleted file mode 100644 index d1e5315..0000000 --- a/src/test/java/com/pipedream/api/testutil/MockWebServer.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.pipedream.api.testutil; - -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpServer; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.util.Map; -import java.util.concurrent.BlockingDeque; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.TimeUnit; -import okhttp3.HttpUrl; - -/** - * Drop-in replacement for {@code okhttp3.mockwebserver.MockWebServer} that uses the JDK's - * built-in {@link HttpServer}. Exists so the wire tests in this repo do not require an - * external mock-server dependency that would have to be threaded into the Fern-managed - * {@code build.gradle}. - * - *

Implements only the surface used here: {@code start()}, {@code shutdown()}, - * {@code url(String)}, {@code enqueue(MockResponse)}, and {@code takeRequest()}. - */ -public final class MockWebServer { - private final HttpServer server; - private final ExecutorService executor; - private final BlockingDeque responses = new LinkedBlockingDeque<>(); - private final BlockingDeque requests = new LinkedBlockingDeque<>(); - - public MockWebServer() throws IOException { - this.server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0); - this.executor = Executors.newCachedThreadPool(); - this.server.setExecutor(executor); - this.server.createContext("/", this::handle); - } - - public void start() { - server.start(); - } - - public void shutdown() { - server.stop(0); - executor.shutdownNow(); - } - - public HttpUrl url(String path) { - if (!path.startsWith("/")) path = "/" + path; - return HttpUrl.parse("http://" + server.getAddress().getHostString() + ":" - + server.getAddress().getPort() + path); - } - - public void enqueue(MockResponse response) { - responses.add(response); - } - - public RecordedRequest takeRequest() throws InterruptedException { - return requests.poll(10, TimeUnit.SECONDS); - } - - private void handle(HttpExchange exchange) throws IOException { - byte[] requestBody = readAllBytes(exchange.getRequestBody()); - requests.add(new RecordedRequest( - exchange.getRequestMethod(), exchange.getRequestURI().toString(), requestBody)); - - MockResponse response = responses.poll(); - if (response == null) { - exchange.sendResponseHeaders(503, -1); - exchange.close(); - return; - } - - for (Map.Entry header : response.headers.entrySet()) { - exchange.getResponseHeaders().add(header.getKey(), header.getValue()); - } - - if (response.body.length == 0) { - exchange.sendResponseHeaders(response.code, -1); - } else { - exchange.sendResponseHeaders(response.code, response.body.length); - try (OutputStream out = exchange.getResponseBody()) { - out.write(response.body); - } - } - exchange.close(); - } - - private static byte[] readAllBytes(InputStream is) throws IOException { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - byte[] chunk = new byte[1024]; - int n; - while ((n = is.read(chunk)) != -1) { - buf.write(chunk, 0, n); - } - return buf.toByteArray(); - } -} diff --git a/src/test/java/com/pipedream/api/testutil/RecordedRequest.java b/src/test/java/com/pipedream/api/testutil/RecordedRequest.java deleted file mode 100644 index 8e7e319..0000000 --- a/src/test/java/com/pipedream/api/testutil/RecordedRequest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.pipedream.api.testutil; - -import java.nio.charset.StandardCharsets; - -/** - * Drop-in replacement for {@code okhttp3.mockwebserver.RecordedRequest}. Exposes only - * the {@code getMethod()}, {@code getPath()}, and {@code getBody().readUtf8()} surface - * used by the wire tests in this repo. - */ -public final class RecordedRequest { - private final String method; - private final String path; - private final byte[] body; - - public RecordedRequest(String method, String path, byte[] body) { - this.method = method; - this.path = path; - this.body = body; - } - - public String getMethod() { - return method; - } - - public String getPath() { - return path; - } - - public Body getBody() { - return new Body(body); - } - - /** Minimal stand-in for {@code okio.Buffer} as exposed by {@code RecordedRequest.getBody()}. */ - public static final class Body { - private final byte[] bytes; - - Body(byte[] bytes) { - this.bytes = bytes; - } - - public String readUtf8() { - return new String(bytes, StandardCharsets.UTF_8); - } - } -} From c015dfe8cd47358683f689b66685d4d87e67e386 Mon Sep 17 00:00:00 2001 From: Jay Vercellone Date: Tue, 26 May 2026 17:01:49 -0700 Subject: [PATCH 2/2] Custom changes --- reference.md | 939 +++++++++++------- .../com/pipedream/api/AsyncBaseClient.java | 8 - .../pipedream/api/AsyncBaseClientBuilder.java | 80 +- .../java/com/pipedream/api/BaseClient.java | 8 - .../com/pipedream/api/BaseClientBuilder.java | 80 +- .../api/resources/proxy/AsyncProxyClient.java | 114 ++- .../resources/proxy/AsyncRawProxyClient.java | 139 +-- .../api/resources/proxy/ProxyClient.java | 108 +- .../api/resources/proxy/RawProxyClient.java | 114 ++- .../resources/proxy/types/ProxyResponse.java | 190 ++++ .../workflows/AsyncRawWorkflowsClient.java | 268 +++++ .../workflows/AsyncWorkflowsClient.java | 128 +++ .../workflows/RawWorkflowsClient.java | 241 +++++ .../resources/workflows/WorkflowsClient.java | 125 +++ .../api/resources/workflows/package-info.java | 27 + .../InvokeWorkflowForExternalUserOpts.java | 182 ++++ .../requests/InvokeWorkflowOpts.java | 164 +++ .../com/pipedream/api/types/HTTPAuthType.java | 42 + 18 files changed, 2361 insertions(+), 596 deletions(-) create mode 100644 src/main/java/com/pipedream/api/resources/proxy/types/ProxyResponse.java create mode 100644 src/main/java/com/pipedream/api/resources/workflows/AsyncRawWorkflowsClient.java create mode 100644 src/main/java/com/pipedream/api/resources/workflows/AsyncWorkflowsClient.java create mode 100644 src/main/java/com/pipedream/api/resources/workflows/RawWorkflowsClient.java create mode 100644 src/main/java/com/pipedream/api/resources/workflows/WorkflowsClient.java create mode 100644 src/main/java/com/pipedream/api/resources/workflows/package-info.java create mode 100644 src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowForExternalUserOpts.java create mode 100644 src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowOpts.java create mode 100644 src/main/java/com/pipedream/api/types/HTTPAuthType.java diff --git a/reference.md b/reference.md index de3b6f7..4d75a73 100644 --- a/reference.md +++ b/reference.md @@ -1,5 +1,7 @@ # Reference + ## AppCategories +

client.appCategories.list() -> List&lt;AppCategory&gt;
@@ -29,12 +31,12 @@ Retrieve all available categories for integrated apps ```java client.appCategories().list(); ``` +
-
@@ -68,6 +70,7 @@ Get details of a specific app category by its ID ```java client.appCategories().retrieve("id"); ``` + @@ -82,18 +85,18 @@ client.appCategories().retrieve("id");
**id:** `String` — The ID of the app category to retrieve - +
- ## Apps +
client.apps.list() -> SyncPagingIterable&lt;App&gt;
@@ -139,6 +142,7 @@ client.apps().list( .build() ); ``` +
@@ -153,7 +157,7 @@ client.apps().list(
**after:** `Optional` — The cursor to start from for pagination - +
@@ -161,7 +165,7 @@ client.apps().list(
**before:** `Optional` — The cursor to end before for pagination - +
@@ -169,7 +173,7 @@ client.apps().list(
**limit:** `Optional` — The maximum number of results to return - +
@@ -177,7 +181,7 @@ client.apps().list(
**q:** `Optional` — A search query to filter the apps - +
@@ -185,7 +189,7 @@ client.apps().list(
**sortKey:** `Optional` — The key to sort the apps by - +
@@ -193,7 +197,7 @@ client.apps().list(
**sortDirection:** `Optional` — The direction to sort the apps - +
@@ -201,7 +205,7 @@ client.apps().list(
**categoryIds:** `Optional` — Only return apps in these categories - +
@@ -209,7 +213,7 @@ client.apps().list(
**hasComponents:** `Optional` — Only return apps that have components (actions or triggers) - +
@@ -217,7 +221,7 @@ client.apps().list(
**hasActions:** `Optional` — Only return apps that have actions - +
@@ -225,13 +229,12 @@ client.apps().list(
**hasTriggers:** `Optional` — Only return apps that have triggers - +
-
@@ -265,6 +268,7 @@ Get detailed information about a specific app by ID or name slug ```java client.apps().retrieve("app_id"); ``` + @@ -279,18 +283,18 @@ client.apps().retrieve("app_id");
**appId:** `String` — The name slug or ID of the app (e.g., 'slack', 'github') - +
- ## Accounts +
client.accounts.list(projectId) -> SyncPagingIterable&lt;Account&gt;
@@ -331,6 +335,7 @@ client.accounts().list( .build() ); ``` +
@@ -345,15 +350,15 @@ client.accounts().list(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**externalUserId:** `Optional` - +**externalUserId:** `Optional` +
@@ -361,7 +366,7 @@ client.accounts().list(
**oauthAppId:** `Optional` — The OAuth app ID to filter by, if applicable - +
@@ -369,7 +374,7 @@ client.accounts().list(
**after:** `Optional` — The cursor to start from for pagination - +
@@ -377,7 +382,7 @@ client.accounts().list(
**before:** `Optional` — The cursor to end before for pagination - +
@@ -385,7 +390,7 @@ client.accounts().list(
**limit:** `Optional` — The maximum number of results to return - +
@@ -393,7 +398,7 @@ client.accounts().list(
**app:** `Optional` — The app slug or ID to filter accounts by. - +
@@ -401,13 +406,12 @@ client.accounts().list(
**includeCredentials:** `Optional` — Whether to retrieve the account's credentials or not - +
-
@@ -450,6 +454,7 @@ client.accounts().create( .build() ); ``` + @@ -464,15 +469,15 @@ client.accounts().create(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**externalUserId:** `Optional` - +**externalUserId:** `Optional` +
@@ -480,7 +485,7 @@ client.accounts().create(
**oauthAppId:** `Optional` — The OAuth app ID to filter by, if applicable - +
@@ -488,7 +493,7 @@ client.accounts().create(
**appSlug:** `String` — The app slug for the account - +
@@ -496,7 +501,7 @@ client.accounts().create(
**cfmapJson:** `String` — JSON string containing the custom fields mapping - +
@@ -504,7 +509,7 @@ client.accounts().create(
**connectToken:** `String` — The connect token for authentication - +
@@ -512,7 +517,7 @@ client.accounts().create(
**name:** `Optional` — Optional name for the account - +
@@ -520,13 +525,12 @@ client.accounts().create(
**accountId:** `Optional` — An existing account ID to reconnect. When provided, the account's credentials are updated instead of creating a new account. Must belong to the same external user and project environment as the connect token, and match the app identified by app_slug. - +
- @@ -566,6 +570,7 @@ client.accounts().retrieve( .build() ); ``` + @@ -580,15 +585,15 @@ client.accounts().retrieve(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**accountId:** `String` - +**accountId:** `String` +
@@ -596,13 +601,12 @@ client.accounts().retrieve(
**includeCredentials:** `Optional` — Whether to retrieve the account's credentials or not - +
- @@ -636,6 +640,7 @@ Remove a connected account and its associated credentials ```java client.accounts().delete("account_id"); ``` + @@ -650,21 +655,20 @@ client.accounts().delete("account_id");
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**accountId:** `String` - +**accountId:** `String` +
- @@ -698,6 +702,7 @@ Remove all connected accounts for a specific app ```java client.accounts().deleteByApp("app_id"); ``` + @@ -712,21 +717,20 @@ client.accounts().deleteByApp("app_id");
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**appId:** `String` - +**appId:** `String` +
- @@ -767,6 +771,7 @@ client.accounts().listByExternalUser( .build() ); ``` + @@ -781,42 +786,42 @@ client.accounts().listByExternalUser(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**externalUserId:** `String` - +**externalUserId:** `String` +
-**includeCredentials:** `Optional` - +**includeCredentials:** `Optional` +
-**app:** `Optional` - +**app:** `Optional` +
- ## Users +
client.users.deleteExternalUser(projectId, externalUserId)
@@ -846,6 +851,7 @@ Remove an external user and all their associated accounts and resources ```java client.users().deleteExternalUser("external_user_id"); ``` +
@@ -860,21 +866,20 @@ client.users().deleteExternalUser("external_user_id");
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**externalUserId:** `String` - +**externalUserId:** `String` +
-
@@ -916,6 +921,7 @@ client.users().list( .build() ); ``` + @@ -930,7 +936,7 @@ client.users().list(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -938,7 +944,7 @@ client.users().list(
**after:** `Optional` — The cursor to start from for pagination - +
@@ -946,7 +952,7 @@ client.users().list(
**before:** `Optional` — The cursor to end before for pagination - +
@@ -954,7 +960,7 @@ client.users().list(
**limit:** `Optional` — The maximum number of results to return - +
@@ -962,18 +968,18 @@ client.users().list(
**q:** `Optional` — Filter users by external_id (partial match) - +
- ## Components +
client.components.list(projectId) -> SyncPagingIterable&lt;Component&gt;
@@ -1014,6 +1020,7 @@ client.components().list( .build() ); ``` +
@@ -1028,7 +1035,7 @@ client.components().list(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -1036,7 +1043,7 @@ client.components().list(
**after:** `Optional` — The cursor to start from for pagination - +
@@ -1044,7 +1051,7 @@ client.components().list(
**before:** `Optional` — The cursor to end before for pagination - +
@@ -1052,7 +1059,7 @@ client.components().list(
**limit:** `Optional` — The maximum number of results to return - +
@@ -1060,7 +1067,7 @@ client.components().list(
**q:** `Optional` — A search query to filter the components - +
@@ -1068,7 +1075,7 @@ client.components().list(
**app:** `Optional` — The ID or name slug of the app to filter the components - +
@@ -1076,7 +1083,7 @@ client.components().list(
**registry:** `Optional` — The registry to retrieve components from. Defaults to 'all' ('public', 'private', or 'all') - +
@@ -1084,13 +1091,12 @@ client.components().list(
**componentType:** `Optional` — The type of the component to filter the components - +
-
@@ -1130,6 +1136,7 @@ client.components().retrieve( .build() ); ``` + @@ -1144,7 +1151,7 @@ client.components().retrieve(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -1152,7 +1159,7 @@ client.components().retrieve(
**componentId:** `String` — The key that uniquely identifies the component (e.g., 'slack-send-message') - +
@@ -1160,13 +1167,12 @@ client.components().retrieve(
**version:** `Optional` — Optional semantic version of the component to retrieve (for example '1.0.0') - +
- @@ -1207,6 +1213,7 @@ client.components().configureProp( .build() ); ``` + @@ -1221,21 +1228,20 @@ client.components().configureProp(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**request:** `ConfigurePropOpts` - +**request:** `ConfigurePropOpts` +
- @@ -1275,6 +1281,7 @@ client.components().reloadProps( .build() ); ``` + @@ -1289,26 +1296,26 @@ client.components().reloadProps(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**request:** `ReloadPropsOpts` - +**request:** `ReloadPropsOpts` +
- ## Actions +
client.actions.list(projectId) -> SyncPagingIterable&lt;Component&gt;
@@ -1348,6 +1355,7 @@ client.actions().list( .build() ); ``` +
@@ -1362,7 +1370,7 @@ client.actions().list(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -1370,7 +1378,7 @@ client.actions().list(
**after:** `Optional` — The cursor to start from for pagination - +
@@ -1378,7 +1386,7 @@ client.actions().list(
**before:** `Optional` — The cursor to end before for pagination - +
@@ -1386,7 +1394,7 @@ client.actions().list(
**limit:** `Optional` — The maximum number of results to return - +
@@ -1394,7 +1402,7 @@ client.actions().list(
**q:** `Optional` — A search query to filter the actions - +
@@ -1402,7 +1410,7 @@ client.actions().list(
**app:** `Optional` — The ID or name slug of the app to filter the actions - +
@@ -1410,13 +1418,12 @@ client.actions().list(
**registry:** `Optional` — The registry to retrieve actions from. Defaults to 'all' ('public', 'private', or 'all') - +
-
@@ -1456,6 +1463,7 @@ client.actions().retrieve( .build() ); ``` + @@ -1470,7 +1478,7 @@ client.actions().retrieve(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -1478,7 +1486,7 @@ client.actions().retrieve(
**componentId:** `String` — The key that uniquely identifies the component (e.g., 'slack-send-message') - +
@@ -1486,13 +1494,12 @@ client.actions().retrieve(
**version:** `Optional` — Optional semantic version of the component to retrieve (for example '1.0.0') - +
- @@ -1533,6 +1540,7 @@ client.actions().configureProp( .build() ); ``` + @@ -1547,21 +1555,20 @@ client.actions().configureProp(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**request:** `ConfigurePropOpts` - +**request:** `ConfigurePropOpts` +
- @@ -1601,6 +1608,7 @@ client.actions().reloadProps( .build() ); ``` + @@ -1615,21 +1623,20 @@ client.actions().reloadProps(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**request:** `ReloadPropsOpts` - +**request:** `ReloadPropsOpts` +
- @@ -1669,6 +1676,7 @@ client.actions().run( .build() ); ``` + @@ -1683,7 +1691,7 @@ client.actions().run(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -1691,7 +1699,7 @@ client.actions().run(
**id:** `String` — The action component ID - +
@@ -1699,7 +1707,7 @@ client.actions().run(
**version:** `Optional` — Optional action component version (in SemVer format, for example '1.0.0'), defaults to latest - +
@@ -1707,15 +1715,15 @@ client.actions().run(
**externalUserId:** `String` — The external user ID - +
-**configuredProps:** `Optional>` - +**configuredProps:** `Optional>` +
@@ -1723,26 +1731,26 @@ client.actions().run(
**dynamicPropsId:** `Optional` — The ID for dynamic props - +
-**stashId:** `Optional` - +**stashId:** `Optional` +
- ## Triggers +
client.triggers.list(projectId) -> SyncPagingIterable&lt;Component&gt;
@@ -1782,6 +1790,7 @@ client.triggers().list( .build() ); ``` +
@@ -1796,7 +1805,7 @@ client.triggers().list(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -1804,7 +1813,7 @@ client.triggers().list(
**after:** `Optional` — The cursor to start from for pagination - +
@@ -1812,7 +1821,7 @@ client.triggers().list(
**before:** `Optional` — The cursor to end before for pagination - +
@@ -1820,7 +1829,7 @@ client.triggers().list(
**limit:** `Optional` — The maximum number of results to return - +
@@ -1828,7 +1837,7 @@ client.triggers().list(
**q:** `Optional` — A search query to filter the triggers - +
@@ -1836,7 +1845,7 @@ client.triggers().list(
**app:** `Optional` — The ID or name slug of the app to filter the triggers - +
@@ -1844,13 +1853,12 @@ client.triggers().list(
**registry:** `Optional` — The registry to retrieve triggers from. Defaults to 'all' ('public', 'private', or 'all') - +
-
@@ -1890,6 +1898,7 @@ client.triggers().retrieve( .build() ); ``` + @@ -1904,7 +1913,7 @@ client.triggers().retrieve(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -1912,7 +1921,7 @@ client.triggers().retrieve(
**componentId:** `String` — The key that uniquely identifies the component (e.g., 'slack-send-message') - +
@@ -1920,13 +1929,12 @@ client.triggers().retrieve(
**version:** `Optional` — Optional semantic version of the component to retrieve (for example '1.0.0') - +
- @@ -1967,6 +1975,7 @@ client.triggers().configureProp( .build() ); ``` + @@ -1981,21 +1990,20 @@ client.triggers().configureProp(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**request:** `ConfigurePropOpts` - +**request:** `ConfigurePropOpts` +
- @@ -2035,6 +2043,7 @@ client.triggers().reloadProps( .build() ); ``` + @@ -2049,21 +2058,20 @@ client.triggers().reloadProps(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**request:** `ReloadPropsOpts` - +**request:** `ReloadPropsOpts` +
- @@ -2103,6 +2111,7 @@ client.triggers().deploy( .build() ); ``` + @@ -2117,7 +2126,7 @@ client.triggers().deploy(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -2125,7 +2134,7 @@ client.triggers().deploy(
**id:** `String` — The trigger component ID - +
@@ -2133,7 +2142,7 @@ client.triggers().deploy(
**version:** `Optional` — Optional trigger component version (in SemVer format, for example '1.0.0'), defaults to latest - +
@@ -2141,15 +2150,15 @@ client.triggers().deploy(
**externalUserId:** `String` — The external user ID - +
-**configuredProps:** `Optional>` - +**configuredProps:** `Optional>` +
@@ -2157,7 +2166,7 @@ client.triggers().deploy(
**dynamicPropsId:** `Optional` — The ID for dynamic props - +
@@ -2165,7 +2174,7 @@ client.triggers().deploy(
**workflowId:** `Optional` — Optional ID of a workflow to receive trigger events - +
@@ -2173,7 +2182,7 @@ client.triggers().deploy(
**webhookUrl:** `Optional` — Optional webhook URL to receive trigger events - +
@@ -2181,18 +2190,18 @@ client.triggers().deploy(
**emitOnDeploy:** `Optional` — Whether the trigger should emit events during the deploy hook execution. Defaults to true if not specified. - +
- ## DeployedTriggers +
client.deployedTriggers.list(projectId) -> SyncPagingIterable&lt;Emitter&gt;
@@ -2231,6 +2240,7 @@ client.deployedTriggers().list( .build() ); ``` +
@@ -2245,7 +2255,7 @@ client.deployedTriggers().list(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -2253,7 +2263,7 @@ client.deployedTriggers().list(
**after:** `Optional` — The cursor to start from for pagination - +
@@ -2261,7 +2271,7 @@ client.deployedTriggers().list(
**before:** `Optional` — The cursor to end before for pagination - +
@@ -2269,7 +2279,7 @@ client.deployedTriggers().list(
**limit:** `Optional` — The maximum number of results to return - +
@@ -2277,7 +2287,7 @@ client.deployedTriggers().list(
**externalUserId:** `String` — Your end user ID, for whom you deployed the trigger - +
@@ -2285,13 +2295,12 @@ client.deployedTriggers().list(
**emitterType:** `Optional` — Filter deployed triggers by emitter type (defaults to 'source' if not provided) - +
-
@@ -2331,6 +2340,7 @@ client.deployedTriggers().retrieve( .build() ); ``` + @@ -2345,15 +2355,15 @@ client.deployedTriggers().retrieve(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
@@ -2361,13 +2371,12 @@ client.deployedTriggers().retrieve(
**externalUserId:** `String` — Your end user ID, for whom you deployed the trigger - +
- @@ -2407,6 +2416,7 @@ client.deployedTriggers().update( .build() ); ``` + @@ -2421,15 +2431,15 @@ client.deployedTriggers().update(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
@@ -2437,7 +2447,7 @@ client.deployedTriggers().update(
**externalUserId:** `String` — The external user ID who owns the trigger - +
@@ -2445,15 +2455,15 @@ client.deployedTriggers().update(
**active:** `Optional` — Whether the trigger should be active - +
-**configuredProps:** `Optional>` - +**configuredProps:** `Optional>` +
@@ -2461,7 +2471,7 @@ client.deployedTriggers().update(
**name:** `Optional` — The name of the trigger - +
@@ -2469,13 +2479,12 @@ client.deployedTriggers().update(
**emitOnDeploy:** `Optional` — Whether the trigger should emit events during deployment - +
- @@ -2516,6 +2525,7 @@ client.deployedTriggers().delete( .build() ); ``` + @@ -2530,15 +2540,15 @@ client.deployedTriggers().delete(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
@@ -2546,7 +2556,7 @@ client.deployedTriggers().delete(
**externalUserId:** `String` — The external user ID who owns the trigger - +
@@ -2554,13 +2564,12 @@ client.deployedTriggers().delete(
**ignoreHookErrors:** `Optional` — Whether to ignore errors during deactivation hook - +
- @@ -2601,6 +2610,7 @@ client.deployedTriggers().listEvents( .build() ); ``` + @@ -2615,15 +2625,15 @@ client.deployedTriggers().listEvents(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
@@ -2631,7 +2641,7 @@ client.deployedTriggers().listEvents(
**externalUserId:** `String` — Your end user ID, for whom you deployed the trigger - +
@@ -2639,13 +2649,12 @@ client.deployedTriggers().listEvents(
**n:** `Optional` — The number of events to retrieve (defaults to 20 if not provided) - +
- @@ -2685,6 +2694,7 @@ client.deployedTriggers().listWorkflows( .build() ); ``` + @@ -2699,15 +2709,15 @@ client.deployedTriggers().listWorkflows(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
@@ -2715,13 +2725,12 @@ client.deployedTriggers().listWorkflows(
**externalUserId:** `String` — The external user ID who owns the trigger - +
- @@ -2764,6 +2773,7 @@ client.deployedTriggers().updateWorkflows( .build() ); ``` + @@ -2778,15 +2788,15 @@ client.deployedTriggers().updateWorkflows(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
@@ -2794,7 +2804,7 @@ client.deployedTriggers().updateWorkflows(
**externalUserId:** `String` — The external user ID who owns the trigger - +
@@ -2802,13 +2812,12 @@ client.deployedTriggers().updateWorkflows(
**workflowIds:** `List` — Array of workflow IDs to set - +
- @@ -2848,6 +2857,7 @@ client.deployedTriggers().listWebhooks( .build() ); ``` + @@ -2862,15 +2872,15 @@ client.deployedTriggers().listWebhooks(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
@@ -2878,13 +2888,12 @@ client.deployedTriggers().listWebhooks(
**externalUserId:** `String` — The external user ID who owns the trigger - +
- @@ -2927,6 +2936,7 @@ client.deployedTriggers().updateWebhooks( .build() ); ``` + @@ -2941,15 +2951,15 @@ client.deployedTriggers().updateWebhooks(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
@@ -2957,7 +2967,7 @@ client.deployedTriggers().updateWebhooks(
**externalUserId:** `String` — The external user ID who owns the trigger - +
@@ -2965,13 +2975,12 @@ client.deployedTriggers().updateWebhooks(
**webhookUrls:** `List` — Array of webhook URLs to set - +
- @@ -3012,6 +3021,7 @@ client.deployedTriggers().retrieveWebhook( .build() ); ``` + @@ -3026,23 +3036,23 @@ client.deployedTriggers().retrieveWebhook(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
-**webhookId:** `String` - +**webhookId:** `String` +
@@ -3050,13 +3060,12 @@ client.deployedTriggers().retrieveWebhook(
**externalUserId:** `String` — The external user ID who owns the trigger - +
- @@ -3097,6 +3106,7 @@ client.deployedTriggers().regenerateWebhookSigningKey( .build() ); ``` + @@ -3111,23 +3121,23 @@ client.deployedTriggers().regenerateWebhookSigningKey(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**triggerId:** `String` - +**triggerId:** `String` +
-**webhookId:** `String` - +**webhookId:** `String` +
@@ -3135,18 +3145,18 @@ client.deployedTriggers().regenerateWebhookSigningKey(
**externalUserId:** `String` — The external user ID who owns the trigger - +
- ## ProjectEnvironment +
client.projectEnvironment.retrieveWebhook(projectId) -> GetWebhookResponse
@@ -3176,6 +3186,7 @@ Retrieve the webhook configured for a project environment ```java client.projectEnvironment().retrieveWebhook(); ``` +
@@ -3190,13 +3201,12 @@ client.projectEnvironment().retrieveWebhook();
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-
@@ -3235,6 +3245,7 @@ client.projectEnvironment().updateWebhook( .build() ); ``` + @@ -3249,7 +3260,7 @@ client.projectEnvironment().updateWebhook(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -3257,13 +3268,12 @@ client.projectEnvironment().updateWebhook(
**url:** `String` — The webhook URL to set - +
- @@ -3297,6 +3307,7 @@ Remove the webhook configured for a project environment ```java client.projectEnvironment().deleteWebhook(); ``` + @@ -3311,13 +3322,12 @@ client.projectEnvironment().deleteWebhook();
**projectId:** `String` — The project ID, which starts with `proj_`. - +
- @@ -3351,6 +3361,7 @@ Regenerate the signing key for the project environment webhook ```java client.projectEnvironment().regenerateWebhookSigningKey(); ``` + @@ -3365,18 +3376,18 @@ client.projectEnvironment().regenerateWebhookSigningKey();
**projectId:** `String` — The project ID, which starts with `proj_`. - +
- ## Projects +
client.projects.list() -> SyncPagingIterable&lt;Project&gt;
@@ -3414,6 +3425,7 @@ client.projects().list( .build() ); ``` +
@@ -3428,7 +3440,7 @@ client.projects().list(
**after:** `Optional` — The cursor to start from for pagination - +
@@ -3436,7 +3448,7 @@ client.projects().list(
**before:** `Optional` — The cursor to end before for pagination - +
@@ -3444,7 +3456,7 @@ client.projects().list(
**limit:** `Optional` — The maximum number of results to return - +
@@ -3452,13 +3464,12 @@ client.projects().list(
**q:** `Optional` — A search query to filter the projects - +
-
@@ -3497,6 +3508,7 @@ client.projects().create( .build() ); ``` + @@ -3511,7 +3523,7 @@ client.projects().create(
**name:** `String` — Name of the project - +
@@ -3519,7 +3531,7 @@ client.projects().create(
**appName:** `Optional` — Display name for the Connect application - +
@@ -3527,7 +3539,7 @@ client.projects().create(
**supportEmail:** `Optional` — Support email displayed to end users - +
@@ -3535,13 +3547,12 @@ client.projects().create(
**connectRequireKeyAuthTest:** `Optional` — Send a test request to the upstream API when adding Connect accounts for key-based apps - +
- @@ -3575,6 +3586,7 @@ Get the project details for a specific project ```java client.projects().retrieve("project_id"); ``` + @@ -3589,13 +3601,12 @@ client.projects().retrieve("project_id");
**projectId:** `String` — The project ID, which starts with `proj_`. - +
- @@ -3629,6 +3640,7 @@ Delete a project owned by the authenticated workspace ```java client.projects().delete("project_id"); ``` + @@ -3643,13 +3655,12 @@ client.projects().delete("project_id");
**projectId:** `String` — The project ID, which starts with `proj_`. - +
- @@ -3688,6 +3699,7 @@ client.projects().update( .build() ); ``` + @@ -3702,7 +3714,7 @@ client.projects().update(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -3710,7 +3722,7 @@ client.projects().update(
**name:** `Optional` — Name of the project - +
@@ -3718,7 +3730,7 @@ client.projects().update(
**appName:** `Optional` — Display name for the Connect application - +
@@ -3726,7 +3738,7 @@ client.projects().update(
**supportEmail:** `Optional` — Support email displayed to end users - +
@@ -3734,13 +3746,12 @@ client.projects().update(
**connectRequireKeyAuthTest:** `Optional` — Send a test request to the upstream API when adding Connect accounts for key-based apps - +
- @@ -3780,6 +3791,7 @@ client.projects().updateLogo( .build() ); ``` + @@ -3794,7 +3806,7 @@ client.projects().updateLogo(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -3802,13 +3814,12 @@ client.projects().updateLogo(
**logo:** `String` — Data URI containing the new Base64 encoded image - +
- @@ -3842,6 +3853,7 @@ Retrieve project configuration and environment details ```java client.projects().retrieveInfo(); ``` + @@ -3856,18 +3868,18 @@ client.projects().retrieveInfo();
**projectId:** `String` — The project ID, which starts with `proj_`. - +
- ## FileStash +
client.fileStash.downloadFile(projectId) -> InputStream
@@ -3902,6 +3914,7 @@ client.fileStash().downloadFile( .build() ); ``` +
@@ -3916,27 +3929,50 @@ client.fileStash().downloadFile(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
-**s3Key:** `String` - +**s3Key:** `String` +
-
## Proxy -
client.proxy.get(projectId, url64) -> InputStream + +The Proxy client forwards authenticated HTTP requests to a third-party API using credentials +from a connected account stored in Pipedream Connect. Pass the target URL as a `String` (or +`okhttp3.HttpUrl`) — the client Base64-encodes it internally before calling the Pipedream API. + +Every method returns a `ProxyResponse`, which is a closeable union of either a parsed JSON +value (`response.isJson()` / `response.json()`) or a raw `InputStream` (`response.isStream()` / +`response.stream()`), determined by the upstream `Content-Type`. Stream responses should be +consumed inside a try-with-resources block to release the underlying HTTP connection: + +```java +try (ProxyResponse response = client.proxy().get("https://api.example.com/users", request)) { + if (response.isJson()) { + Object json = response.json(); + } else { + InputStream body = response.stream(); + } +} +``` + +For full HTTP metadata (status code, headers), use `client.proxy().withRawResponse()`. The +async client (`asyncClient.proxy().get(...)`) exposes the same surface with +`CompletableFuture` return types. + +
client.proxy.get(url, request) -> ProxyResponse
@@ -3964,7 +4000,7 @@ Forward an authenticated GET request to an external API using an external user's ```java client.proxy().get( - "url_64", + "https://api.example.com/users", ProxyGetRequest .builder() .externalUserId("external_user_id") @@ -3972,6 +4008,7 @@ client.proxy().get( .build() ); ``` +
@@ -3985,16 +4022,8 @@ client.proxy().get(
-**projectId:** `String` — The project ID, which starts with `proj_`. - -
-
- -
-
+**url:** `String` — Target URL to forward the request to. Base64-encoded internally before being sent to Pipedream. An `okhttp3.HttpUrl` overload is also available. -**url64:** `String` — Base64-encoded target URL -
@@ -4002,7 +4031,7 @@ client.proxy().get(
**externalUserId:** `String` — The external user ID for the proxy request - +
@@ -4010,18 +4039,17 @@ client.proxy().get(
**accountId:** `String` — The account ID to use for authentication - +
-
-
client.proxy.post(projectId, url64, request) -> InputStream +
client.proxy.post(url, request) -> ProxyResponse
@@ -4049,21 +4077,21 @@ Forward an authenticated POST request to an external API using an external user' ```java client.proxy().post( - "url_64", + "https://api.example.com/users", ProxyPostRequest .builder() .externalUserId("external_user_id") .accountId("account_id") .body( new HashMap() {{ - put("string", new - HashMap() {{put("key", "value"); - }}); + put("name", "Jane Doe"); + put("email", "jane@example.com"); }} ) .build() ); ``` +
@@ -4077,16 +4105,8 @@ client.proxy().post(
-**projectId:** `String` — The project ID, which starts with `proj_`. - -
-
- -
-
+**url:** `String` — Target URL to forward the request to. Base64-encoded internally before being sent to Pipedream. An `okhttp3.HttpUrl` overload is also available. -**url64:** `String` — Base64-encoded target URL -
@@ -4094,7 +4114,7 @@ client.proxy().post(
**externalUserId:** `String` — The external user ID for the proxy request - +
@@ -4102,26 +4122,25 @@ client.proxy().post(
**accountId:** `String` — The account ID to use for authentication - +
-**request:** `Map` — Request body to forward to the target API - +**body:** `Map` — Request body to forward to the target API +
-
-
client.proxy.put(projectId, url64, request) -> InputStream +
client.proxy.put(url, request) -> ProxyResponse
@@ -4149,21 +4168,21 @@ Forward an authenticated PUT request to an external API using an external user's ```java client.proxy().put( - "url_64", + "https://api.example.com/users/42", ProxyPutRequest .builder() .externalUserId("external_user_id") .accountId("account_id") .body( new HashMap() {{ - put("string", new - HashMap() {{put("key", "value"); - }}); + put("name", "Jane Doe"); + put("email", "jane@example.com"); }} ) .build() ); ``` +
@@ -4177,16 +4196,8 @@ client.proxy().put(
-**projectId:** `String` — The project ID, which starts with `proj_`. - -
-
- -
-
+**url:** `String` — Target URL to forward the request to. Base64-encoded internally before being sent to Pipedream. An `okhttp3.HttpUrl` overload is also available. -**url64:** `String` — Base64-encoded target URL -
@@ -4194,7 +4205,7 @@ client.proxy().put(
**externalUserId:** `String` — The external user ID for the proxy request - +
@@ -4202,26 +4213,25 @@ client.proxy().put(
**accountId:** `String` — The account ID to use for authentication - +
-**request:** `Map` — Request body to forward to the target API - +**body:** `Map` — Request body to forward to the target API +
-
-
client.proxy.delete(projectId, url64) -> InputStream +
client.proxy.delete(url, request) -> ProxyResponse
@@ -4249,7 +4259,7 @@ Forward an authenticated DELETE request to an external API using an external use ```java client.proxy().delete( - "url_64", + "https://api.example.com/users/42", ProxyDeleteRequest .builder() .externalUserId("external_user_id") @@ -4257,6 +4267,7 @@ client.proxy().delete( .build() ); ``` +
@@ -4270,16 +4281,8 @@ client.proxy().delete(
-**projectId:** `String` — The project ID, which starts with `proj_`. - -
-
+**url:** `String` — Target URL to forward the request to. Base64-encoded internally before being sent to Pipedream. An `okhttp3.HttpUrl` overload is also available. -
-
- -**url64:** `String` — Base64-encoded target URL -
@@ -4287,7 +4290,7 @@ client.proxy().delete(
**externalUserId:** `String` — The external user ID for the proxy request - +
@@ -4295,18 +4298,17 @@ client.proxy().delete(
**accountId:** `String` — The account ID to use for authentication - +
-
-
client.proxy.patch(projectId, url64, request) -> InputStream +
client.proxy.patch(url, request) -> ProxyResponse
@@ -4334,21 +4336,20 @@ Forward an authenticated PATCH request to an external API using an external user ```java client.proxy().patch( - "url_64", + "https://api.example.com/users/42", ProxyPatchRequest .builder() .externalUserId("external_user_id") .accountId("account_id") .body( new HashMap() {{ - put("string", new - HashMap() {{put("key", "value"); - }}); + put("email", "jane.new@example.com"); }} ) .build() ); ``` +
@@ -4362,16 +4363,8 @@ client.proxy().patch(
-**projectId:** `String` — The project ID, which starts with `proj_`. - -
-
+**url:** `String` — Target URL to forward the request to. Base64-encoded internally before being sent to Pipedream. An `okhttp3.HttpUrl` overload is also available. -
-
- -**url64:** `String` — Base64-encoded target URL -
@@ -4379,7 +4372,7 @@ client.proxy().patch(
**externalUserId:** `String` — The external user ID for the proxy request - +
@@ -4387,26 +4380,26 @@ client.proxy().patch(
**accountId:** `String` — The account ID to use for authentication - +
-**request:** `Map` — Request body to forward to the target API - +**body:** `Map` — Request body to forward to the target API +
-
## Tokens +
client.tokens.create(projectId, request) -> CreateTokenResponse
@@ -4441,6 +4434,7 @@ client.tokens().create( .build() ); ``` +
@@ -4455,7 +4449,7 @@ client.tokens().create(
**projectId:** `String` — The project ID, which starts with `proj_`. - +
@@ -4463,7 +4457,7 @@ client.tokens().create(
**allowedOrigins:** `Optional>` — List of allowed origins for CORS - +
@@ -4471,7 +4465,7 @@ client.tokens().create(
**errorRedirectUri:** `Optional` — URI to redirect to on error - +
@@ -4479,7 +4473,7 @@ client.tokens().create(
**expiresIn:** `Optional` — Token TTL in seconds (max 14400 = 4 hours). Defaults to 4 hours if not specified. - +
@@ -4487,15 +4481,15 @@ client.tokens().create(
**externalUserId:** `String` — Your end user ID, for whom you're creating the token - +
-**scope:** `Optional` — Space-separated scopes to restrict token permissions. Defaults to 'connect:*' if not specified. See https://pipedream.com/docs/connect/api-reference/authentication#connect-token-scopes for more information. - +**scope:** `Optional` — Space-separated scopes to restrict token permissions. Defaults to 'connect:*' if not specified. See for more information. +
@@ -4503,7 +4497,7 @@ client.tokens().create(
**successRedirectUri:** `Optional` — URI to redirect to on success - +
@@ -4511,7 +4505,7 @@ client.tokens().create(
**webhookUri:** `Optional` — Webhook URI for notifications - +
@@ -4519,13 +4513,12 @@ client.tokens().create(
**allowProgressiveScopes:** `Optional` — When true, end users may authorize a subset of the app's OAuth scopes; only the app's functional scopes (needed for the post-OAuth test request) are enforced. Defaults to false. - +
-
@@ -4567,6 +4560,7 @@ client.tokens().validate( .build() ); ``` + @@ -4580,8 +4574,8 @@ client.tokens().validate(
-**ctok:** `String` - +**ctok:** `String` +
@@ -4589,7 +4583,7 @@ client.tokens().validate(
**appId:** `String` — The app ID to validate against - +
@@ -4597,7 +4591,7 @@ client.tokens().validate(
**accountId:** `Optional` — An existing account ID to reconnect. Must belong to the app identified by app_id. - +
@@ -4605,18 +4599,18 @@ client.tokens().validate(
**oauthAppId:** `Optional` — The OAuth app ID to validate against (if the token is for an OAuth app) - +
-
## Usage +
client.usage.list() -> ConnectUsageResponse
@@ -4652,6 +4646,7 @@ client.usage().list( .build() ); ``` +
@@ -4666,7 +4661,7 @@ client.usage().list(
**startTs:** `Integer` — Usage window start timestamp (seconds) - +
@@ -4674,18 +4669,18 @@ client.usage().list(
**endTs:** `Integer` — Usage window end timestamp (seconds) - +
-
## OauthTokens +
client.oauthTokens.create(request) -> CreateOAuthTokenResponse
@@ -4721,6 +4716,7 @@ client.oauthTokens().create( .build() ); ``` +
@@ -4734,24 +4730,24 @@ client.oauthTokens().create(
-**grantType:** `String` - +**grantType:** `String` +
-**clientId:** `String` - +**clientId:** `String` +
-**clientSecret:** `String` - +**clientSecret:** `String` +
@@ -4759,14 +4755,219 @@ client.oauthTokens().create(
**scope:** `Optional` — Optional space-separated scopes for the access token. Defaults to `*`. - + +
+ + + + + + +
+ +## Workflows + +The Workflows client invokes a Pipedream workflow via its HTTP interface. Pass either a full +workflow URL (`https://eo3xxxx.m.pipedream.net`) or just the endpoint ID (`eo3xxxx`). Both +methods return the workflow's response body as a deserialized `Object` (typically a `Map`, +`List`, or scalar — see Jackson's default deserialization). The async client +(`asyncClient.workflows().invoke(...)` / `invokeForExternalUser(...)`) exposes the same two +methods returning `CompletableFuture`. + +
client.workflows.invoke(urlOrEndpoint) -> Object +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +// Simple workflow invocation (uses OAuth authentication by default) +client.workflows().invoke("eo3xxxx"); + +// Advanced workflow invocation with all options +client.workflows().invoke( + InvokeWorkflowOpts + .builder() + .urlOrEndpoint("https://eo3xxxx.m.pipedream.net") + .body( + new HashMap() {{ + put("name", "John Doe"); + put("email", "john@example.com"); + }} + ) + .headers( + new HashMap() {{ + put("Content-Type", "application/json"); + put("Authorization", "Bearer your-token"); // For STATIC_BEARER auth + }} + ) + .method("POST") + .authType(HTTPAuthType.STATIC_BEARER) + .build() +); +``` +
+#### ⚙️ Parameters + +
+
+ +
+
+ +**urlOrEndpoint:** `String` — Either a workflow endpoint ID (e.g., `eo3xxxx`) or a full workflow URL + +
+
+ +
+
+ +**body:** `Optional` — Request body to send to the workflow (will be JSON serialized) + + + + +
+
+ +**headers:** `Optional>` — Additional headers to include in the request + +
+
+ +
+
+ +**method:** `Optional` — HTTP method to use (defaults to `POST`) + +
+
+ +
+
+ +**authType:** `Optional` — Authentication type: `OAUTH` (default), `STATIC_BEARER`, or `NONE` + +
+
+ + +
client.workflows.invokeForExternalUser(urlOrEndpoint, externalUserId) -> Object +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +// Simple external user invocation (uses OAuth authentication by default) +client.workflows().invokeForExternalUser("eo3xxxx", "user123"); + +// Advanced external user invocation with all options +client.workflows().invokeForExternalUser( + InvokeWorkflowForExternalUserOpts + .builder() + .url("https://eo3xxxx.m.pipedream.net") + .externalUserId("user123") + .body( + new HashMap() {{ + put("action", "process_data"); + put("data", Arrays.asList("item1", "item2")); + }} + ) + .headers( + new HashMap() {{ + put("X-Custom-Header", "value"); + }} + ) + .method("POST") + .authType(HTTPAuthType.OAUTH) + .build() +); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**url:** `String` — The full workflow URL to invoke + +
+
+ +
+
+ +**externalUserId:** `String` — Your end user ID, for whom you're invoking the workflow (Pipedream Connect) + +
+
+ +
+
+ +**body:** `Optional` — Request body to send to the workflow (will be JSON serialized) + + + + +
+
+ +**headers:** `Optional>` — Additional headers to include in the request + +
+
+ +
+
+ +**method:** `Optional` — HTTP method to use (defaults to `POST`) + +
+
+ +
+
+ +**authType:** `Optional` — Authentication type: `OAUTH` (default), `STATIC_BEARER`, or `NONE` + +
+
+ + + + + + diff --git a/src/main/java/com/pipedream/api/AsyncBaseClient.java b/src/main/java/com/pipedream/api/AsyncBaseClient.java index f48620f..3635ca6 100644 --- a/src/main/java/com/pipedream/api/AsyncBaseClient.java +++ b/src/main/java/com/pipedream/api/AsyncBaseClient.java @@ -152,12 +152,4 @@ public static AsyncBaseClientBuilder._TokenAuth withToken(String token) { public static AsyncBaseClientBuilder._CredentialsAuth withCredentials(String clientId, String clientSecret) { return AsyncBaseClientBuilder.withCredentials(clientId, clientSecret); } - - /** - * Creates a new client builder. - * @return A builder for configuring and creating the client - */ - public static AsyncBaseClientBuilder._Builder builder() { - return AsyncBaseClientBuilder.builder(); - } } diff --git a/src/main/java/com/pipedream/api/AsyncBaseClientBuilder.java b/src/main/java/com/pipedream/api/AsyncBaseClientBuilder.java index 0dc7662..e6ad3c8 100644 --- a/src/main/java/com/pipedream/api/AsyncBaseClientBuilder.java +++ b/src/main/java/com/pipedream/api/AsyncBaseClientBuilder.java @@ -1,6 +1,3 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ package com.pipedream.api; import com.pipedream.api.core.ClientOptions; @@ -13,7 +10,7 @@ import java.util.Optional; import okhttp3.OkHttpClient; -public class AsyncBaseClientBuilder { +public class AsyncBaseClientBuilder> { private Optional timeout = Optional.empty(); private Optional maxRetries = Optional.empty(); @@ -67,51 +64,51 @@ public static _Builder builder() { /** * Sets projectEnvironment */ - public AsyncBaseClientBuilder projectEnvironment(String projectEnvironment) { + public T projectEnvironment(String projectEnvironment) { this.projectEnvironment = projectEnvironment; - return this; + return (T) this; } - public AsyncBaseClientBuilder environment(Environment environment) { + public T environment(Environment environment) { this.environment = environment; - return this; + return (T) this; } - public AsyncBaseClientBuilder url(String url) { + public T url(String url) { this.environment = Environment.custom(url); - return this; + return (T) this; } /** * Sets the timeout (in seconds) for the client. Defaults to 60 seconds. */ - public AsyncBaseClientBuilder timeout(int timeout) { + public T timeout(int timeout) { this.timeout = Optional.of(timeout); - return this; + return (T) this; } /** * Sets the maximum number of retries for the client. Defaults to 2 retries. */ - public AsyncBaseClientBuilder maxRetries(int maxRetries) { + public T maxRetries(int maxRetries) { this.maxRetries = Optional.of(maxRetries); - return this; + return (T) this; } /** * Sets the underlying OkHttp client */ - public AsyncBaseClientBuilder httpClient(OkHttpClient httpClient) { + public T httpClient(OkHttpClient httpClient) { this.httpClient = httpClient; - return this; + return (T) this; } /** * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. */ - public AsyncBaseClientBuilder logging(LogConfig logging) { + public T logging(LogConfig logging) { this.logging = Optional.of(logging); - return this; + return (T) this; } /** @@ -122,14 +119,14 @@ public AsyncBaseClientBuilder logging(LogConfig logging) { * @param value The header value * @return This builder for method chaining */ - public AsyncBaseClientBuilder addHeader(String name, String value) { + public T addHeader(String name, String value) { this.customHeaders.put(name, value); - return this; + return (T) this; } - public AsyncBaseClientBuilder projectId(String projectId) { + public T projectId(String projectId) { this.projectId = projectId; - return this; + return (T) this; } protected ClientOptions buildClientOptions() { @@ -298,7 +295,7 @@ public AsyncBaseClient build() { return new AsyncBaseClient(buildClientOptions()); } - public static final class _TokenAuth extends AsyncBaseClientBuilder { + public static final class _TokenAuth extends AsyncBaseClientBuilder<_TokenAuth> { private final String token; _TokenAuth(String token) { @@ -311,7 +308,7 @@ protected void setAuthentication(ClientOptions.Builder builder) { } } - public static final class _CredentialsAuth extends AsyncBaseClientBuilder { + public static final class _CredentialsAuth extends AsyncBaseClientBuilder<_CredentialsAuth> { private final String clientId; private final String clientSecret; @@ -351,6 +348,8 @@ public static final class _Builder { private OkHttpClient httpClient; + private Optional logging = Optional.empty(); + private final Map headers = new HashMap<>(); public _Builder environment(Environment environment) { @@ -387,6 +386,14 @@ public _Builder httpClient(OkHttpClient httpClient) { return this; } + /** + * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. + */ + public _Builder logging(LogConfig logging) { + this.logging = Optional.of(logging); + return this; + } + /** * Add a custom header to be sent with all requests. * @param name The header name @@ -408,21 +415,7 @@ public _Builder addHeader(String name, String value) { */ public _TokenAuth token(String token) { _TokenAuth auth = new _TokenAuth(token); - if (this.environment != null) { - auth.environment = this.environment; - } - if (this.timeout.isPresent()) { - auth.timeout(this.timeout.get()); - } - if (this.maxRetries.isPresent()) { - auth.maxRetries(this.maxRetries.get()); - } - if (this.httpClient != null) { - auth.httpClient(this.httpClient); - } - for (Map.Entry header : this.headers.entrySet()) { - auth.addHeader(header.getKey(), header.getValue()); - } + applyTo(auth); return auth; } @@ -436,6 +429,11 @@ public _TokenAuth token(String token) { */ public _CredentialsAuth credentials(String clientId, String clientSecret) { _CredentialsAuth auth = new _CredentialsAuth(clientId, clientSecret); + applyTo(auth); + return auth; + } + + private > void applyTo(B auth) { if (this.environment != null) { auth.environment = this.environment; } @@ -448,10 +446,12 @@ public _CredentialsAuth credentials(String clientId, String clientSecret) { if (this.httpClient != null) { auth.httpClient(this.httpClient); } + if (this.logging.isPresent()) { + auth.logging(this.logging.get()); + } for (Map.Entry header : this.headers.entrySet()) { auth.addHeader(header.getKey(), header.getValue()); } - return auth; } } } diff --git a/src/main/java/com/pipedream/api/BaseClient.java b/src/main/java/com/pipedream/api/BaseClient.java index 6d39477..056a9f9 100644 --- a/src/main/java/com/pipedream/api/BaseClient.java +++ b/src/main/java/com/pipedream/api/BaseClient.java @@ -152,12 +152,4 @@ public static BaseClientBuilder._TokenAuth withToken(String token) { public static BaseClientBuilder._CredentialsAuth withCredentials(String clientId, String clientSecret) { return BaseClientBuilder.withCredentials(clientId, clientSecret); } - - /** - * Creates a new client builder. - * @return A builder for configuring and creating the client - */ - public static BaseClientBuilder._Builder builder() { - return BaseClientBuilder.builder(); - } } diff --git a/src/main/java/com/pipedream/api/BaseClientBuilder.java b/src/main/java/com/pipedream/api/BaseClientBuilder.java index d632962..74601de 100644 --- a/src/main/java/com/pipedream/api/BaseClientBuilder.java +++ b/src/main/java/com/pipedream/api/BaseClientBuilder.java @@ -1,6 +1,3 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ package com.pipedream.api; import com.pipedream.api.core.ClientOptions; @@ -13,7 +10,7 @@ import java.util.Optional; import okhttp3.OkHttpClient; -public class BaseClientBuilder { +public class BaseClientBuilder> { private Optional timeout = Optional.empty(); private Optional maxRetries = Optional.empty(); @@ -67,51 +64,51 @@ public static _Builder builder() { /** * Sets projectEnvironment */ - public BaseClientBuilder projectEnvironment(String projectEnvironment) { + public T projectEnvironment(String projectEnvironment) { this.projectEnvironment = projectEnvironment; - return this; + return (T) this; } - public BaseClientBuilder environment(Environment environment) { + public T environment(Environment environment) { this.environment = environment; - return this; + return (T) this; } - public BaseClientBuilder url(String url) { + public T url(String url) { this.environment = Environment.custom(url); - return this; + return (T) this; } /** * Sets the timeout (in seconds) for the client. Defaults to 60 seconds. */ - public BaseClientBuilder timeout(int timeout) { + public T timeout(int timeout) { this.timeout = Optional.of(timeout); - return this; + return (T) this; } /** * Sets the maximum number of retries for the client. Defaults to 2 retries. */ - public BaseClientBuilder maxRetries(int maxRetries) { + public T maxRetries(int maxRetries) { this.maxRetries = Optional.of(maxRetries); - return this; + return (T) this; } /** * Sets the underlying OkHttp client */ - public BaseClientBuilder httpClient(OkHttpClient httpClient) { + public T httpClient(OkHttpClient httpClient) { this.httpClient = httpClient; - return this; + return (T) this; } /** * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. */ - public BaseClientBuilder logging(LogConfig logging) { + public T logging(LogConfig logging) { this.logging = Optional.of(logging); - return this; + return (T) this; } /** @@ -122,14 +119,14 @@ public BaseClientBuilder logging(LogConfig logging) { * @param value The header value * @return This builder for method chaining */ - public BaseClientBuilder addHeader(String name, String value) { + public T addHeader(String name, String value) { this.customHeaders.put(name, value); - return this; + return (T) this; } - public BaseClientBuilder projectId(String projectId) { + public T projectId(String projectId) { this.projectId = projectId; - return this; + return (T) this; } protected ClientOptions buildClientOptions() { @@ -298,7 +295,7 @@ public BaseClient build() { return new BaseClient(buildClientOptions()); } - public static final class _TokenAuth extends BaseClientBuilder { + public static final class _TokenAuth extends BaseClientBuilder<_TokenAuth> { private final String token; _TokenAuth(String token) { @@ -311,7 +308,7 @@ protected void setAuthentication(ClientOptions.Builder builder) { } } - public static final class _CredentialsAuth extends BaseClientBuilder { + public static final class _CredentialsAuth extends BaseClientBuilder<_CredentialsAuth> { private final String clientId; private final String clientSecret; @@ -351,6 +348,8 @@ public static final class _Builder { private OkHttpClient httpClient; + private Optional logging = Optional.empty(); + private final Map headers = new HashMap<>(); public _Builder environment(Environment environment) { @@ -387,6 +386,14 @@ public _Builder httpClient(OkHttpClient httpClient) { return this; } + /** + * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. + */ + public _Builder logging(LogConfig logging) { + this.logging = Optional.of(logging); + return this; + } + /** * Add a custom header to be sent with all requests. * @param name The header name @@ -408,21 +415,7 @@ public _Builder addHeader(String name, String value) { */ public _TokenAuth token(String token) { _TokenAuth auth = new _TokenAuth(token); - if (this.environment != null) { - auth.environment = this.environment; - } - if (this.timeout.isPresent()) { - auth.timeout(this.timeout.get()); - } - if (this.maxRetries.isPresent()) { - auth.maxRetries(this.maxRetries.get()); - } - if (this.httpClient != null) { - auth.httpClient(this.httpClient); - } - for (Map.Entry header : this.headers.entrySet()) { - auth.addHeader(header.getKey(), header.getValue()); - } + applyTo(auth); return auth; } @@ -436,6 +429,11 @@ public _TokenAuth token(String token) { */ public _CredentialsAuth credentials(String clientId, String clientSecret) { _CredentialsAuth auth = new _CredentialsAuth(clientId, clientSecret); + applyTo(auth); + return auth; + } + + private > void applyTo(B auth) { if (this.environment != null) { auth.environment = this.environment; } @@ -448,10 +446,12 @@ public _CredentialsAuth credentials(String clientId, String clientSecret) { if (this.httpClient != null) { auth.httpClient(this.httpClient); } + if (this.logging.isPresent()) { + auth.logging(this.logging.get()); + } for (Map.Entry header : this.headers.entrySet()) { auth.addHeader(header.getKey(), header.getValue()); } - return auth; } } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/AsyncProxyClient.java b/src/main/java/com/pipedream/api/resources/proxy/AsyncProxyClient.java index a5ba2bd..90eb2ba 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/AsyncProxyClient.java +++ b/src/main/java/com/pipedream/api/resources/proxy/AsyncProxyClient.java @@ -10,8 +10,10 @@ import com.pipedream.api.resources.proxy.requests.ProxyPatchRequest; import com.pipedream.api.resources.proxy.requests.ProxyPostRequest; import com.pipedream.api.resources.proxy.requests.ProxyPutRequest; -import java.io.InputStream; +import com.pipedream.api.resources.proxy.types.ProxyResponse; +import java.util.Base64; import java.util.concurrent.CompletableFuture; +import okhttp3.HttpUrl; public class AsyncProxyClient { protected final ClientOptions clientOptions; @@ -23,6 +25,10 @@ public AsyncProxyClient(ClientOptions clientOptions) { this.rawClient = new AsyncRawProxyClient(clientOptions); } + private String encodeUrl(String url) { + return Base64.getUrlEncoder().encodeToString(url.getBytes()); + } + /** * Get responses with HTTP metadata like headers */ @@ -33,72 +39,154 @@ public AsyncRawProxyClient withRawResponse() { /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public CompletableFuture get(String url64, ProxyGetRequest request) { + public CompletableFuture get(String url, ProxyGetRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.get(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public CompletableFuture get(String url64, ProxyGetRequest request, RequestOptions requestOptions) { + public CompletableFuture get(HttpUrl url, ProxyGetRequest request) { + return get(url.toString(), request); + } + + /** + * Forward an authenticated GET request to an external API using an external user's account credentials + */ + public CompletableFuture get(String url, ProxyGetRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.get(url64, request, requestOptions).thenApply(response -> response.body()); } + /** + * Forward an authenticated GET request to an external API using an external user's account credentials + */ + public CompletableFuture get(HttpUrl url, ProxyGetRequest request, RequestOptions requestOptions) { + return get(url.toString(), request, requestOptions); + } + /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public CompletableFuture post(String url64, ProxyPostRequest request) { + public CompletableFuture post(String url, ProxyPostRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.post(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public CompletableFuture post(String url64, ProxyPostRequest request, RequestOptions requestOptions) { + public CompletableFuture post(HttpUrl url, ProxyPostRequest request) { + return post(url.toString(), request); + } + + /** + * Forward an authenticated POST request to an external API using an external user's account credentials + */ + public CompletableFuture post(String url, ProxyPostRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.post(url64, request, requestOptions).thenApply(response -> response.body()); } + /** + * Forward an authenticated POST request to an external API using an external user's account credentials + */ + public CompletableFuture post(HttpUrl url, ProxyPostRequest request, RequestOptions requestOptions) { + return post(url.toString(), request, requestOptions); + } + /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public CompletableFuture put(String url64, ProxyPutRequest request) { + public CompletableFuture put(String url, ProxyPutRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.put(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public CompletableFuture put(String url64, ProxyPutRequest request, RequestOptions requestOptions) { + public CompletableFuture put(HttpUrl url, ProxyPutRequest request) { + return put(url.toString(), request); + } + + /** + * Forward an authenticated PUT request to an external API using an external user's account credentials + */ + public CompletableFuture put(String url, ProxyPutRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.put(url64, request, requestOptions).thenApply(response -> response.body()); } + /** + * Forward an authenticated PUT request to an external API using an external user's account credentials + */ + public CompletableFuture put(HttpUrl url, ProxyPutRequest request, RequestOptions requestOptions) { + return put(url.toString(), request, requestOptions); + } + /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public CompletableFuture delete(String url64, ProxyDeleteRequest request) { + public CompletableFuture delete(String url, ProxyDeleteRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.delete(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public CompletableFuture delete( - String url64, ProxyDeleteRequest request, RequestOptions requestOptions) { + public CompletableFuture delete(HttpUrl url, ProxyDeleteRequest request) { + return delete(url.toString(), request); + } + + /** + * Forward an authenticated DELETE request to an external API using an external user's account credentials + */ + public CompletableFuture delete( + String url, ProxyDeleteRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.delete(url64, request, requestOptions).thenApply(response -> response.body()); } + /** + * Forward an authenticated DELETE request to an external API using an external user's account credentials + */ + public CompletableFuture delete( + HttpUrl url, ProxyDeleteRequest request, RequestOptions requestOptions) { + return delete(url.toString(), request, requestOptions); + } + /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public CompletableFuture patch(String url64, ProxyPatchRequest request) { + public CompletableFuture patch(String url, ProxyPatchRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.patch(url64, request).thenApply(response -> response.body()); } /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public CompletableFuture patch( - String url64, ProxyPatchRequest request, RequestOptions requestOptions) { + public CompletableFuture patch(HttpUrl url, ProxyPatchRequest request) { + return patch(url.toString(), request); + } + + /** + * Forward an authenticated PATCH request to an external API using an external user's account credentials + */ + public CompletableFuture patch( + String url, ProxyPatchRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.patch(url64, request, requestOptions).thenApply(response -> response.body()); } + + /** + * Forward an authenticated PATCH request to an external API using an external user's account credentials + */ + public CompletableFuture patch( + HttpUrl url, ProxyPatchRequest request, RequestOptions requestOptions) { + return patch(url.toString(), request, requestOptions); + } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java b/src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java index e21e9e8..0df5a24 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java +++ b/src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java @@ -19,13 +19,14 @@ import com.pipedream.api.resources.proxy.requests.ProxyPatchRequest; import com.pipedream.api.resources.proxy.requests.ProxyPostRequest; import com.pipedream.api.resources.proxy.requests.ProxyPutRequest; +import com.pipedream.api.resources.proxy.types.ProxyResponse; import java.io.IOException; -import java.io.InputStream; import java.util.concurrent.CompletableFuture; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Headers; import okhttp3.HttpUrl; +import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; @@ -40,17 +41,58 @@ public AsyncRawProxyClient(ClientOptions clientOptions) { this.clientOptions = clientOptions; } + private static boolean isJsonContentType(MediaType contentType) { + if (contentType == null) { + return false; + } + return "application".equals(contentType.type()) && "json".equals(contentType.subtype()); + } + + private static void handleSuccessResponse( + Response response, + ResponseBody responseBody, + CompletableFuture> future) { + MediaType contentType = responseBody != null ? responseBody.contentType() : null; + String contentTypeString = contentType != null ? contentType.toString() : null; + ProxyResponse proxyBody; + if (isJsonContentType(contentType)) { + try { + String responseBodyString = responseBody.string(); + Object parsed = ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class); + proxyBody = ProxyResponse.json(parsed, contentTypeString); + } catch (JsonProcessingException e) { + future.completeExceptionally(new BaseClientException( + "Response Content-Type was application/json but body is not valid JSON", e)); + return; + } catch (IOException e) { + future.completeExceptionally(new BaseClientException("Error reading response body", e)); + return; + } finally { + response.close(); + } + } else { + try { + proxyBody = ProxyResponse.stream(new ResponseBodyInputStream(response), contentTypeString); + } catch (IOException e) { + future.completeExceptionally(new BaseClientException("Error creating response stream", e)); + response.close(); + return; + } + } + future.complete(new BaseClientHttpResponse<>(proxyBody, response)); + } + /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public CompletableFuture> get(String url64, ProxyGetRequest request) { + public CompletableFuture> get(String url64, ProxyGetRequest request) { return get(url64, request, null); } /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public CompletableFuture> get( + public CompletableFuture> get( String url64, ProxyGetRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -60,11 +102,6 @@ public CompletableFuture> get( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), 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) @@ -75,14 +112,14 @@ public CompletableFuture> get( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); + handleSuccessResponse(response, responseBody, future); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -95,9 +132,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response)); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); @@ -115,14 +154,14 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public CompletableFuture> post(String url64, ProxyPostRequest request) { + public CompletableFuture> post(String url64, ProxyPostRequest request) { return post(url64, request, null); } /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public CompletableFuture> post( + public CompletableFuture> post( String url64, ProxyPostRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -132,11 +171,6 @@ public CompletableFuture> post( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); - if (requestOptions != null) { - requestOptions.getQueryParameters().forEach((_key, _value) -> { - httpUrl.addQueryParameter(_key, _value); - }); - } RequestBody body; try { body = RequestBody.create( @@ -155,14 +189,14 @@ public CompletableFuture> post( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); + handleSuccessResponse(response, responseBody, future); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -175,9 +209,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response)); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); @@ -195,14 +231,14 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public CompletableFuture> put(String url64, ProxyPutRequest request) { + public CompletableFuture> put(String url64, ProxyPutRequest request) { return put(url64, request, null); } /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public CompletableFuture> put( + public CompletableFuture> put( String url64, ProxyPutRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -212,11 +248,6 @@ public CompletableFuture> put( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); - if (requestOptions != null) { - requestOptions.getQueryParameters().forEach((_key, _value) -> { - httpUrl.addQueryParameter(_key, _value); - }); - } RequestBody body; try { body = RequestBody.create( @@ -235,14 +266,14 @@ public CompletableFuture> put( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); + handleSuccessResponse(response, responseBody, future); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -255,9 +286,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response)); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); @@ -275,14 +308,14 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public CompletableFuture> delete(String url64, ProxyDeleteRequest request) { + public CompletableFuture> delete(String url64, ProxyDeleteRequest request) { return delete(url64, request, null); } /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public CompletableFuture> delete( + public CompletableFuture> delete( String url64, ProxyDeleteRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -292,11 +325,6 @@ public CompletableFuture> delete( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); - if (requestOptions != null) { - requestOptions.getQueryParameters().forEach((_key, _value) -> { - httpUrl.addQueryParameter(_key, _value); - }); - } Request.Builder _requestBuilder = new Request.Builder() .url(httpUrl.build()) .method("DELETE", null) @@ -307,14 +335,14 @@ public CompletableFuture> delete( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); + handleSuccessResponse(response, responseBody, future); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -327,9 +355,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response)); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); @@ -347,14 +377,14 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public CompletableFuture> patch(String url64, ProxyPatchRequest request) { + public CompletableFuture> patch(String url64, ProxyPatchRequest request) { return patch(url64, request, null); } /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public CompletableFuture> patch( + public CompletableFuture> patch( String url64, ProxyPatchRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -364,11 +394,6 @@ public CompletableFuture> patch( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); - if (requestOptions != null) { - requestOptions.getQueryParameters().forEach((_key, _value) -> { - httpUrl.addQueryParameter(_key, _value); - }); - } RequestBody body; try { body = RequestBody.create( @@ -387,14 +412,14 @@ public CompletableFuture> patch( if (requestOptions != null && requestOptions.getTimeout().isPresent()) { client = clientOptions.httpClientWithTimeout(requestOptions); } - CompletableFuture> future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); client.newCall(okhttpRequest).enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { try { ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - future.complete(new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response)); + handleSuccessResponse(response, responseBody, future); return; } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; @@ -407,9 +432,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); future.completeExceptionally(new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response)); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response)); return; } catch (IOException e) { future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); diff --git a/src/main/java/com/pipedream/api/resources/proxy/ProxyClient.java b/src/main/java/com/pipedream/api/resources/proxy/ProxyClient.java index c21c055..7e19ade 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/ProxyClient.java +++ b/src/main/java/com/pipedream/api/resources/proxy/ProxyClient.java @@ -10,7 +10,9 @@ import com.pipedream.api.resources.proxy.requests.ProxyPatchRequest; import com.pipedream.api.resources.proxy.requests.ProxyPostRequest; import com.pipedream.api.resources.proxy.requests.ProxyPutRequest; -import java.io.InputStream; +import com.pipedream.api.resources.proxy.types.ProxyResponse; +import java.util.Base64; +import okhttp3.HttpUrl; public class ProxyClient { protected final ClientOptions clientOptions; @@ -22,6 +24,10 @@ public ProxyClient(ClientOptions clientOptions) { this.rawClient = new RawProxyClient(clientOptions); } + private String encodeUrl(String url) { + return Base64.getUrlEncoder().encodeToString(url.getBytes()); + } + /** * Get responses with HTTP metadata like headers */ @@ -32,70 +38,150 @@ public RawProxyClient withRawResponse() { /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public InputStream get(String url64, ProxyGetRequest request) { + public ProxyResponse get(String url, ProxyGetRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.get(url64, request).body(); } /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public InputStream get(String url64, ProxyGetRequest request, RequestOptions requestOptions) { + public ProxyResponse get(HttpUrl url, ProxyGetRequest request) { + return get(url.toString(), request); + } + + /** + * Forward an authenticated GET request to an external API using an external user's account credentials + */ + public ProxyResponse get(String url, ProxyGetRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.get(url64, request, requestOptions).body(); } + /** + * Forward an authenticated GET request to an external API using an external user's account credentials + */ + public ProxyResponse get(HttpUrl url, ProxyGetRequest request, RequestOptions requestOptions) { + return get(url.toString(), request, requestOptions); + } + /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public InputStream post(String url64, ProxyPostRequest request) { + public ProxyResponse post(String url, ProxyPostRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.post(url64, request).body(); } /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public InputStream post(String url64, ProxyPostRequest request, RequestOptions requestOptions) { + public ProxyResponse post(HttpUrl url, ProxyPostRequest request) { + return post(url.toString(), request); + } + + /** + * Forward an authenticated POST request to an external API using an external user's account credentials + */ + public ProxyResponse post(String url, ProxyPostRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.post(url64, request, requestOptions).body(); } + /** + * Forward an authenticated POST request to an external API using an external user's account credentials + */ + public ProxyResponse post(HttpUrl url, ProxyPostRequest request, RequestOptions requestOptions) { + return post(url.toString(), request, requestOptions); + } + /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public InputStream put(String url64, ProxyPutRequest request) { + public ProxyResponse put(String url, ProxyPutRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.put(url64, request).body(); } /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public InputStream put(String url64, ProxyPutRequest request, RequestOptions requestOptions) { + public ProxyResponse put(HttpUrl url, ProxyPutRequest request) { + return put(url.toString(), request); + } + + /** + * Forward an authenticated PUT request to an external API using an external user's account credentials + */ + public ProxyResponse put(String url, ProxyPutRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.put(url64, request, requestOptions).body(); } + /** + * Forward an authenticated PUT request to an external API using an external user's account credentials + */ + public ProxyResponse put(HttpUrl url, ProxyPutRequest request, RequestOptions requestOptions) { + return put(url.toString(), request, requestOptions); + } + /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public InputStream delete(String url64, ProxyDeleteRequest request) { + public ProxyResponse delete(String url, ProxyDeleteRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.delete(url64, request).body(); } /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public InputStream delete(String url64, ProxyDeleteRequest request, RequestOptions requestOptions) { + public ProxyResponse delete(HttpUrl url, ProxyDeleteRequest request) { + return delete(url.toString(), request); + } + + /** + * Forward an authenticated DELETE request to an external API using an external user's account credentials + */ + public ProxyResponse delete(String url, ProxyDeleteRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.delete(url64, request, requestOptions).body(); } + /** + * Forward an authenticated DELETE request to an external API using an external user's account credentials + */ + public ProxyResponse delete(HttpUrl url, ProxyDeleteRequest request, RequestOptions requestOptions) { + return delete(url.toString(), request, requestOptions); + } + /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public InputStream patch(String url64, ProxyPatchRequest request) { + public ProxyResponse patch(String url, ProxyPatchRequest request) { + final String url64 = encodeUrl(url); return this.rawClient.patch(url64, request).body(); } /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public InputStream patch(String url64, ProxyPatchRequest request, RequestOptions requestOptions) { + public ProxyResponse patch(HttpUrl url, ProxyPatchRequest request) { + return patch(url.toString(), request); + } + + /** + * Forward an authenticated PATCH request to an external API using an external user's account credentials + */ + public ProxyResponse patch(String url, ProxyPatchRequest request, RequestOptions requestOptions) { + final String url64 = encodeUrl(url); return this.rawClient.patch(url64, request, requestOptions).body(); } + + /** + * Forward an authenticated PATCH request to an external API using an external user's account credentials + */ + public ProxyResponse patch(HttpUrl url, ProxyPatchRequest request, RequestOptions requestOptions) { + return patch(url.toString(), request, requestOptions); + } } diff --git a/src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java b/src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java index 307e886..b03c111 100644 --- a/src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java +++ b/src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java @@ -19,10 +19,11 @@ import com.pipedream.api.resources.proxy.requests.ProxyPatchRequest; import com.pipedream.api.resources.proxy.requests.ProxyPostRequest; import com.pipedream.api.resources.proxy.requests.ProxyPutRequest; +import com.pipedream.api.resources.proxy.types.ProxyResponse; import java.io.IOException; -import java.io.InputStream; import okhttp3.Headers; import okhttp3.HttpUrl; +import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; @@ -36,17 +37,43 @@ public RawProxyClient(ClientOptions clientOptions) { this.clientOptions = clientOptions; } + private static boolean isJsonContentType(MediaType contentType) { + if (contentType == null) { + return false; + } + return "application".equals(contentType.type()) && "json".equals(contentType.subtype()); + } + + private static ProxyResponse parseSuccessResponse(Response response, ResponseBody responseBody) throws IOException { + MediaType contentType = responseBody != null ? responseBody.contentType() : null; + String contentTypeString = contentType != null ? contentType.toString() : null; + if (isJsonContentType(contentType)) { + String responseBodyString = responseBody.string(); + try { + Object parsed = ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class); + return ProxyResponse.json(parsed, contentTypeString); + } catch (JsonProcessingException e) { + throw new BaseClientException( + "Response Content-Type was application/json but body is not valid JSON", e); + } finally { + response.close(); + } + } else { + return ProxyResponse.stream(new ResponseBodyInputStream(response), contentTypeString); + } + } + /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public BaseClientHttpResponse get(String url64, ProxyGetRequest request) { + public BaseClientHttpResponse get(String url64, ProxyGetRequest request) { return get(url64, request, null); } /** * Forward an authenticated GET request to an external API using an external user's account credentials */ - public BaseClientHttpResponse get( + public BaseClientHttpResponse get( String url64, ProxyGetRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -56,11 +83,6 @@ public BaseClientHttpResponse get( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), 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) @@ -75,7 +97,7 @@ public BaseClientHttpResponse get( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); + return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -86,9 +108,11 @@ public BaseClientHttpResponse get( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } @@ -97,14 +121,14 @@ public BaseClientHttpResponse get( /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public BaseClientHttpResponse post(String url64, ProxyPostRequest request) { + public BaseClientHttpResponse post(String url64, ProxyPostRequest request) { return post(url64, request, null); } /** * Forward an authenticated POST request to an external API using an external user's account credentials */ - public BaseClientHttpResponse post( + public BaseClientHttpResponse post( String url64, ProxyPostRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -114,11 +138,6 @@ public BaseClientHttpResponse post( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); - if (requestOptions != null) { - requestOptions.getQueryParameters().forEach((_key, _value) -> { - httpUrl.addQueryParameter(_key, _value); - }); - } RequestBody body; try { body = RequestBody.create( @@ -141,7 +160,7 @@ public BaseClientHttpResponse post( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); + return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -152,9 +171,11 @@ public BaseClientHttpResponse post( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } @@ -163,14 +184,14 @@ public BaseClientHttpResponse post( /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public BaseClientHttpResponse put(String url64, ProxyPutRequest request) { + public BaseClientHttpResponse put(String url64, ProxyPutRequest request) { return put(url64, request, null); } /** * Forward an authenticated PUT request to an external API using an external user's account credentials */ - public BaseClientHttpResponse put( + public BaseClientHttpResponse put( String url64, ProxyPutRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -180,11 +201,6 @@ public BaseClientHttpResponse put( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); - if (requestOptions != null) { - requestOptions.getQueryParameters().forEach((_key, _value) -> { - httpUrl.addQueryParameter(_key, _value); - }); - } RequestBody body; try { body = RequestBody.create( @@ -207,7 +223,7 @@ public BaseClientHttpResponse put( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); + return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -218,9 +234,11 @@ public BaseClientHttpResponse put( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } @@ -229,14 +247,14 @@ public BaseClientHttpResponse put( /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public BaseClientHttpResponse delete(String url64, ProxyDeleteRequest request) { + public BaseClientHttpResponse delete(String url64, ProxyDeleteRequest request) { return delete(url64, request, null); } /** * Forward an authenticated DELETE request to an external API using an external user's account credentials */ - public BaseClientHttpResponse delete( + public BaseClientHttpResponse delete( String url64, ProxyDeleteRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -246,11 +264,6 @@ public BaseClientHttpResponse delete( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); - if (requestOptions != null) { - requestOptions.getQueryParameters().forEach((_key, _value) -> { - httpUrl.addQueryParameter(_key, _value); - }); - } Request.Builder _requestBuilder = new Request.Builder() .url(httpUrl.build()) .method("DELETE", null) @@ -265,7 +278,7 @@ public BaseClientHttpResponse delete( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); + return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -276,9 +289,11 @@ public BaseClientHttpResponse delete( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } @@ -287,14 +302,14 @@ public BaseClientHttpResponse delete( /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public BaseClientHttpResponse patch(String url64, ProxyPatchRequest request) { + public BaseClientHttpResponse patch(String url64, ProxyPatchRequest request) { return patch(url64, request, null); } /** * Forward an authenticated PATCH request to an external API using an external user's account credentials */ - public BaseClientHttpResponse patch( + public BaseClientHttpResponse patch( String url64, ProxyPatchRequest request, RequestOptions requestOptions) { HttpUrl.Builder httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) .newBuilder() @@ -304,11 +319,6 @@ public BaseClientHttpResponse patch( .addPathSegment(url64); QueryStringMapper.addQueryParameter(httpUrl, "external_user_id", request.getExternalUserId(), false); QueryStringMapper.addQueryParameter(httpUrl, "account_id", request.getAccountId(), false); - if (requestOptions != null) { - requestOptions.getQueryParameters().forEach((_key, _value) -> { - httpUrl.addQueryParameter(_key, _value); - }); - } RequestBody body; try { body = RequestBody.create( @@ -331,7 +341,7 @@ public BaseClientHttpResponse patch( Response response = client.newCall(okhttpRequest).execute(); ResponseBody responseBody = response.body(); if (response.isSuccessful()) { - return new BaseClientHttpResponse<>(new ResponseBodyInputStream(response), response); + return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; try { @@ -342,9 +352,11 @@ public BaseClientHttpResponse patch( } catch (JsonProcessingException ignored) { // unable to map error response, throwing generic error } - Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); throw new BaseClientApiException( - "Error with status code " + response.code(), response.code(), errorBody, response); + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response); } catch (IOException e) { throw new BaseClientException("Network error executing HTTP request", e); } diff --git a/src/main/java/com/pipedream/api/resources/proxy/types/ProxyResponse.java b/src/main/java/com/pipedream/api/resources/proxy/types/ProxyResponse.java new file mode 100644 index 0000000..2b0bf56 --- /dev/null +++ b/src/main/java/com/pipedream/api/resources/proxy/types/ProxyResponse.java @@ -0,0 +1,190 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.pipedream.api.resources.proxy.types; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; + +/** + * A union type that represents either a parsed JSON response or a raw binary stream response + * from the proxy API. The type is determined by the Content-Type header of the HTTP response. + * + *

For responses with Content-Type "application/json" (or derivations like + * "application/json; charset=utf-8"), the response body is parsed as JSON and can be + * accessed via {@link #json()}. + * + *

For all other Content-Types (or missing Content-Type headers), the response body + * is returned as a raw InputStream that can be accessed via {@link #stream()}. + * + *

This class implements {@link Closeable} to ensure proper resource management. + * When the response contains a stream, callers should close the ProxyResponse to + * release the underlying HTTP connection. + * + *

Example usage: + *

{@code
+ * try (ProxyResponse response = client.proxy().get(url64, request)) {
+ *     if (response.isJson()) {
+ *         Object json = response.json();
+ *         // Work with parsed JSON
+ *     } else {
+ *         InputStream stream = response.stream();
+ *         // Work with binary data
+ *     }
+ * }
+ * }
+ */ +public final class ProxyResponse implements Closeable { + + /** + * The type of content contained in this response. + */ + public enum Type { + /** + * The response contains parsed JSON data. + */ + JSON, + /** + * The response contains a raw binary stream. + */ + STREAM + } + + private final Type type; + private final Object jsonValue; + private final InputStream streamValue; + private final String contentType; + + private ProxyResponse(Type type, Object jsonValue, InputStream streamValue, String contentType) { + this.type = type; + this.jsonValue = jsonValue; + this.streamValue = streamValue; + this.contentType = contentType; + } + + /** + * Creates a ProxyResponse containing parsed JSON data. + * + * @param value the parsed JSON value (Map, List, String, Number, Boolean, or null) + * @param contentType the original Content-Type header value + * @return a new ProxyResponse of type JSON + */ + public static ProxyResponse json(Object value, String contentType) { + return new ProxyResponse(Type.JSON, value, null, contentType); + } + + /** + * Creates a ProxyResponse containing a raw binary stream. + * + * @param stream the raw InputStream + * @param contentType the original Content-Type header value + * @return a new ProxyResponse of type STREAM + */ + public static ProxyResponse stream(InputStream stream, String contentType) { + return new ProxyResponse(Type.STREAM, null, stream, contentType); + } + + /** + * Returns true if this response contains parsed JSON data. + * + * @return true if this is a JSON response + */ + public boolean isJson() { + return type == Type.JSON; + } + + /** + * Returns true if this response contains a raw binary stream. + * + * @return true if this is a stream response + */ + public boolean isStream() { + return type == Type.STREAM; + } + + /** + * Returns the type of content contained in this response. + * + * @return the response type + */ + public Type getType() { + return type; + } + + /** + * Returns the parsed JSON value if this is a JSON response. + * + * @return an Optional containing the JSON value, or empty if this is a stream response + */ + public Optional asJson() { + return Optional.ofNullable(jsonValue); + } + + /** + * Returns the raw stream if this is a stream response. + * + * @return an Optional containing the InputStream, or empty if this is a JSON response + */ + public Optional asStream() { + return Optional.ofNullable(streamValue); + } + + /** + * Returns the parsed JSON value. + * + * @return the parsed JSON value (Map, List, String, Number, Boolean, or null) + * @throws IllegalStateException if this is not a JSON response + */ + public Object json() { + if (type != Type.JSON) { + throw new IllegalStateException("ProxyResponse is not JSON, it is " + type); + } + return jsonValue; + } + + /** + * Returns the raw binary stream. + * + * @return the raw InputStream + * @throws IllegalStateException if this is not a stream response + */ + public InputStream stream() { + if (type != Type.STREAM) { + throw new IllegalStateException("ProxyResponse is not a stream, it is " + type); + } + return streamValue; + } + + /** + * Returns the original Content-Type header value from the HTTP response. + * + * @return an Optional containing the Content-Type, or empty if no Content-Type was present + */ + public Optional getContentType() { + return Optional.ofNullable(contentType); + } + + /** + * Closes the underlying stream if this response contains one. + * For JSON responses, this method has no effect. + * + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + if (streamValue != null) { + streamValue.close(); + } + } + + @Override + public String toString() { + if (type == Type.JSON) { + return "ProxyResponse{type=JSON, contentType=" + contentType + ", value=" + jsonValue + "}"; + } else { + return "ProxyResponse{type=STREAM, contentType=" + contentType + "}"; + } + } +} diff --git a/src/main/java/com/pipedream/api/resources/workflows/AsyncRawWorkflowsClient.java b/src/main/java/com/pipedream/api/resources/workflows/AsyncRawWorkflowsClient.java new file mode 100644 index 0000000..d523b9d --- /dev/null +++ b/src/main/java/com/pipedream/api/resources/workflows/AsyncRawWorkflowsClient.java @@ -0,0 +1,268 @@ +/** + * This file was manually created to add workflow invocation support. + */ +package com.pipedream.api.resources.workflows; + +import com.pipedream.api.core.BaseClientApiException; +import com.pipedream.api.core.BaseClientException; +import com.pipedream.api.core.BaseClientHttpResponse; +import com.pipedream.api.core.ClientOptions; +import com.pipedream.api.core.MediaTypes; +import com.pipedream.api.core.ObjectMappers; +import com.pipedream.api.core.RequestOptions; +import com.pipedream.api.resources.workflows.requests.InvokeWorkflowForExternalUserOpts; +import com.pipedream.api.resources.workflows.requests.InvokeWorkflowOpts; +import com.pipedream.api.types.HTTPAuthType; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.Headers; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; + +public class AsyncRawWorkflowsClient { + protected final ClientOptions clientOptions; + private final String workflowDomain; + private final String urlProtocol; + + public AsyncRawWorkflowsClient(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + this.workflowDomain = getDefaultWorkflowDomain(); + this.urlProtocol = getUrlProtocol(); + } + + public CompletableFuture> invoke(InvokeWorkflowOpts request) { + return invoke(request, null); + } + + public CompletableFuture> invoke( + InvokeWorkflowOpts request, RequestOptions requestOptions) { + + // Build the workflow URL + String urlString = buildWorkflowUrl(request.getUrlOrEndpoint()); + + HttpUrl httpUrl; + try { + httpUrl = HttpUrl.parse(urlString); + if (httpUrl == null) { + throw new IllegalArgumentException("Invalid URL: " + urlString); + } + } catch (Exception e) { + CompletableFuture> future = new CompletableFuture<>(); + future.completeExceptionally(new IllegalArgumentException("Invalid URL: " + urlString, e)); + return future; + } + + // Determine auth type - default to OAuth if not specified + HTTPAuthType authType = request.getAuthType().orElse(HTTPAuthType.OAUTH); + + // Prepare headers - start with client options headers (includes OAuth auth if configured) + Map allHeaders = new HashMap<>(clientOptions.headers(requestOptions)); + + // Handle authentication based on type + if (authType == HTTPAuthType.OAUTH) { + // For OAuth, the Authorization header should already be in clientOptions.headers() + // No additional action needed + } else if (authType == HTTPAuthType.STATIC_BEARER) { + // For static_bearer, users must provide the Authorization header in request.getHeaders() + // Their header will override any existing OAuth header when we merge request headers + } else if (authType == HTTPAuthType.NONE) { + // For NONE auth type, set Authorization header to empty string (matches Python SDK) + allHeaders.put("Authorization", ""); + } + + // Add request-specific headers (can override auth headers for STATIC_BEARER) + if (request.getHeaders().isPresent()) { + allHeaders.putAll(request.getHeaders().get()); + } + + // Determine HTTP method + String method = request.getMethod().orElse("POST").toUpperCase(); + + // Prepare request body if needed + RequestBody body = null; + if (request.getBody().isPresent()) { + try { + body = RequestBody.create( + ObjectMappers.JSON_MAPPER.writeValueAsBytes( + request.getBody().get()), + MediaTypes.APPLICATION_JSON); + allHeaders.put("Content-Type", "application/json"); + } catch (Exception e) { + CompletableFuture> future = new CompletableFuture<>(); + future.completeExceptionally(new RuntimeException("Failed to serialize request body", e)); + return future; + } + } else if (("POST".equals(method) || "PUT".equals(method) || "PATCH".equals(method))) { + // For methods that typically require a body, send an empty body + // to avoid OkHttp's "method POST must have a request body" error + body = RequestBody.create(new byte[0], null); + } + + // Build the request + Request.Builder requestBuilder = + new Request.Builder().url(httpUrl).method(method, body).headers(Headers.of(allHeaders)); + + if (!allHeaders.containsKey("Accept")) { + requestBuilder.addHeader("Accept", "application/json"); + } + + Request okhttpRequest = requestBuilder.build(); + + // Execute the request asynchronously + OkHttpClient client = clientOptions.httpClient(); + if (requestOptions != null && requestOptions.getTimeout().isPresent()) { + client = clientOptions.httpClientWithTimeout(requestOptions); + } + + CompletableFuture> future = new CompletableFuture<>(); + + client.newCall(okhttpRequest).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e)); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + try (ResponseBody responseBody = response.body()) { + if (response.isSuccessful()) { + String responseBodyString = responseBody != null ? responseBody.string() : "{}"; + Object parsedResponse; + try { + parsedResponse = ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class); + } catch (Exception e) { + // If JSON parsing fails, return the raw string + parsedResponse = responseBodyString; + } + future.complete(new BaseClientHttpResponse<>(parsedResponse, response)); + } else { + String responseBodyString = responseBody != null ? responseBody.string() : "{}"; + future.completeExceptionally(new BaseClientApiException( + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response)); + } + } catch (Exception e) { + future.completeExceptionally(e); + } + } + }); + + return future; + } + + public CompletableFuture> invokeForExternalUser( + InvokeWorkflowForExternalUserOpts request) { + return invokeForExternalUser(request, null); + } + + public CompletableFuture> invokeForExternalUser( + InvokeWorkflowForExternalUserOpts request, RequestOptions requestOptions) { + + // Validate inputs + if (request.getExternalUserId() == null + || request.getExternalUserId().trim().isEmpty()) { + CompletableFuture> future = new CompletableFuture<>(); + future.completeExceptionally(new IllegalArgumentException("External user ID is required")); + return future; + } + + if (request.getUrl() == null || request.getUrl().trim().isEmpty()) { + CompletableFuture> future = new CompletableFuture<>(); + future.completeExceptionally(new IllegalArgumentException("Workflow URL is required")); + return future; + } + + // Prepare headers with external user ID + Map headers = new HashMap<>(); + if (request.getHeaders().isPresent()) { + headers.putAll(request.getHeaders().get()); + } + headers.put("X-PD-External-User-ID", request.getExternalUserId()); + + // Create a new request with the authentication from the original request and the external user header + InvokeWorkflowOpts invokeRequest = InvokeWorkflowOpts.builder() + .urlOrEndpoint(request.getUrl()) + .body(request.getBody()) + .headers(headers) + .method(request.getMethod()) + .authType(request.getAuthType().orElse(HTTPAuthType.OAUTH)) + .build(); + + return invoke(invokeRequest, requestOptions); + } + + /** + * Builds a full workflow URL based on the input. + * + * @param input Either a full URL (with or without protocol) or just an endpoint ID. + * @return The fully constructed URL. + */ + private String buildWorkflowUrl(String input) { + String sanitizedInput = input.trim().toLowerCase(); + if (sanitizedInput.isEmpty()) { + throw new IllegalArgumentException("URL or endpoint ID is required"); + } + + // Check if it's already a full URL + if (sanitizedInput.startsWith("http://") || sanitizedInput.startsWith("https://")) { + try { + URL url = new URL(input); + // Validate the hostname + String workflowDomain = this.workflowDomain; + if (!url.getHost().endsWith(this.workflowDomain)) { + throw new IllegalArgumentException( + "Invalid workflow domain. URL must end with " + this.workflowDomain); + } + return input; + } catch (MalformedURLException e) { + throw new IllegalArgumentException("The provided URL is malformed: " + input, e); + } + } + + // Check if it's a URL without protocol + if (sanitizedInput.contains(".")) { + return buildWorkflowUrl("https://" + input); + } + + // It's an endpoint ID + if (!sanitizedInput.matches("^e[no][a-z0-9-]+$")) { + throw new IllegalArgumentException( + "Invalid endpoint ID format. Must contain only letters, numbers, and hyphens, " + + "and start with either 'en' or 'eo'."); + } + + return urlProtocol + "://" + sanitizedInput + "." + workflowDomain; + } + + private String getDefaultWorkflowDomain() { + String envUrl = clientOptions.environment().getUrl(); + // For non-prod environments (dev, staging), use dev domain + if (!envUrl.equals("https://api.pipedream.com") && !envUrl.equals("https://api2.pipedream.com")) { + return "m.d.pipedream.net"; + } + // For prod and canary, use standard domain + return "m.pipedream.net"; + } + + private String getUrlProtocol() { + String envUrl = clientOptions.environment().getUrl(); + // For non-prod environments (dev, staging), use http + if (!envUrl.equals("https://api.pipedream.com") && !envUrl.equals("https://api2.pipedream.com")) { + return "http"; + } + // For prod and canary, use https + return "https"; + } +} diff --git a/src/main/java/com/pipedream/api/resources/workflows/AsyncWorkflowsClient.java b/src/main/java/com/pipedream/api/resources/workflows/AsyncWorkflowsClient.java new file mode 100644 index 0000000..08f9081 --- /dev/null +++ b/src/main/java/com/pipedream/api/resources/workflows/AsyncWorkflowsClient.java @@ -0,0 +1,128 @@ +/** + * This file was manually created to add workflow invocation support. + */ +package com.pipedream.api.resources.workflows; + +import com.pipedream.api.core.ClientOptions; +import com.pipedream.api.core.RequestOptions; +import com.pipedream.api.resources.workflows.requests.InvokeWorkflowForExternalUserOpts; +import com.pipedream.api.resources.workflows.requests.InvokeWorkflowOpts; +import java.util.concurrent.CompletableFuture; + +public class AsyncWorkflowsClient { + protected final ClientOptions clientOptions; + + private final AsyncRawWorkflowsClient rawClient; + + public AsyncWorkflowsClient(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + this.rawClient = new AsyncRawWorkflowsClient(clientOptions); + } + + /** + * Get responses with HTTP metadata like headers + */ + public AsyncRawWorkflowsClient withRawResponse() { + return this.rawClient; + } + + /** + * Invokes a workflow using the URL of its HTTP interface(s). + * + * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint + * @return A future containing the response from the workflow + */ + public CompletableFuture invoke(String urlOrEndpoint) { + InvokeWorkflowOpts request = + InvokeWorkflowOpts.builder().urlOrEndpoint(urlOrEndpoint).build(); + return this.rawClient.invoke(request).thenApply(response -> response.body()); + } + + /** + * Invokes a workflow using the URL of its HTTP interface(s). + * + * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint + * @param requestOptions Additional request options + * @return A future containing the response from the workflow + */ + public CompletableFuture invoke(String urlOrEndpoint, RequestOptions requestOptions) { + InvokeWorkflowOpts request = + InvokeWorkflowOpts.builder().urlOrEndpoint(urlOrEndpoint).build(); + return this.rawClient.invoke(request, requestOptions).thenApply(response -> response.body()); + } + + /** + * Invokes a workflow using the InvokeWorkflowOpts request object. + * + * @param request The request containing workflow invocation parameters + * @return A future containing the response from the workflow + */ + public CompletableFuture invoke(InvokeWorkflowOpts request) { + return this.rawClient.invoke(request).thenApply(response -> response.body()); + } + + /** + * Invokes a workflow using the InvokeWorkflowOpts request object. + * + * @param request The request containing workflow invocation parameters + * @param requestOptions Additional request options + * @return A future containing the response from the workflow + */ + public CompletableFuture invoke(InvokeWorkflowOpts request, RequestOptions requestOptions) { + return this.rawClient.invoke(request, requestOptions).thenApply(response -> response.body()); + } + + /** + * Invokes a workflow for a Pipedream Connect user in a project. + * + * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint + * @param externalUserId Your end user ID, for whom you're invoking the workflow + * @return A future containing the response from the workflow + */ + public CompletableFuture invokeForExternalUser(String urlOrEndpoint, String externalUserId) { + InvokeWorkflowForExternalUserOpts request = InvokeWorkflowForExternalUserOpts.builder() + .url(urlOrEndpoint) + .externalUserId(externalUserId) + .build(); + return this.rawClient.invokeForExternalUser(request).thenApply(response -> response.body()); + } + + /** + * Invokes a workflow for a Pipedream Connect user in a project. + * + * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint + * @param externalUserId Your end user ID, for whom you're invoking the workflow + * @param requestOptions Additional request options + * @return A future containing the response from the workflow + */ + public CompletableFuture invokeForExternalUser( + String urlOrEndpoint, String externalUserId, RequestOptions requestOptions) { + InvokeWorkflowForExternalUserOpts request = InvokeWorkflowForExternalUserOpts.builder() + .url(urlOrEndpoint) + .externalUserId(externalUserId) + .build(); + return this.rawClient.invokeForExternalUser(request, requestOptions).thenApply(response -> response.body()); + } + + /** + * Invokes a workflow for a Pipedream Connect user using the InvokeWorkflowForExternalUserOpts request object. + * + * @param request The request containing workflow invocation parameters + * @return A future containing the response from the workflow + */ + public CompletableFuture invokeForExternalUser(InvokeWorkflowForExternalUserOpts request) { + return this.rawClient.invokeForExternalUser(request).thenApply(response -> response.body()); + } + + /** + * Invokes a workflow for a Pipedream Connect user using the InvokeWorkflowForExternalUserOpts request object. + * + * @param request The request containing workflow invocation parameters + * @param requestOptions Additional request options + * @return A future containing the response from the workflow + */ + public CompletableFuture invokeForExternalUser( + InvokeWorkflowForExternalUserOpts request, RequestOptions requestOptions) { + return this.rawClient.invokeForExternalUser(request, requestOptions).thenApply(response -> response.body()); + } +} diff --git a/src/main/java/com/pipedream/api/resources/workflows/RawWorkflowsClient.java b/src/main/java/com/pipedream/api/resources/workflows/RawWorkflowsClient.java new file mode 100644 index 0000000..d4dd787 --- /dev/null +++ b/src/main/java/com/pipedream/api/resources/workflows/RawWorkflowsClient.java @@ -0,0 +1,241 @@ +/** + * This file was manually created to add workflow invocation support. + */ +package com.pipedream.api.resources.workflows; + +import com.pipedream.api.core.BaseClientApiException; +import com.pipedream.api.core.BaseClientException; +import com.pipedream.api.core.BaseClientHttpResponse; +import com.pipedream.api.core.ClientOptions; +import com.pipedream.api.core.MediaTypes; +import com.pipedream.api.core.ObjectMappers; +import com.pipedream.api.core.RequestOptions; +import com.pipedream.api.resources.workflows.requests.InvokeWorkflowForExternalUserOpts; +import com.pipedream.api.resources.workflows.requests.InvokeWorkflowOpts; +import com.pipedream.api.types.HTTPAuthType; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import okhttp3.Headers; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; + +public class RawWorkflowsClient { + protected final ClientOptions clientOptions; + private final String workflowDomain; + private final String urlProtocol; + + public RawWorkflowsClient(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + String workflowDomainEnv = System.getenv("PIPEDREAM_WORKFLOW_DOMAIN"); + this.workflowDomain = workflowDomainEnv != null ? workflowDomainEnv : getDefaultWorkflowDomain(); + this.urlProtocol = getUrlProtocol(); + } + + public BaseClientHttpResponse invoke(InvokeWorkflowOpts request) { + return invoke(request, null); + } + + public BaseClientHttpResponse invoke(InvokeWorkflowOpts request, RequestOptions requestOptions) { + // Build the workflow URL + String urlString = buildWorkflowUrl(request.getUrlOrEndpoint()); + + HttpUrl httpUrl; + try { + httpUrl = HttpUrl.parse(urlString); + if (httpUrl == null) { + throw new IllegalArgumentException("Invalid URL: " + urlString); + } + } catch (Exception e) { + throw new IllegalArgumentException("Invalid URL: " + urlString, e); + } + + // Determine auth type - default to OAuth if not specified + HTTPAuthType authType = request.getAuthType().orElse(HTTPAuthType.OAUTH); + + // Prepare headers - start with client options headers (includes OAuth auth if configured) + Map allHeaders = new HashMap<>(clientOptions.headers(requestOptions)); + + // Handle authentication based on type + if (authType == HTTPAuthType.OAUTH) { + // For OAuth, the Authorization header should already be in clientOptions.headers() + // No additional action needed + } else if (authType == HTTPAuthType.STATIC_BEARER) { + // For static_bearer, users must provide the Authorization header in request.getHeaders() + // Their header will override any existing OAuth header when we merge request headers + } else if (authType == HTTPAuthType.NONE) { + // For NONE auth type, set Authorization header to empty string (matches Python SDK) + allHeaders.put("Authorization", ""); + } + + // Add request-specific headers (can override auth headers for STATIC_BEARER) + if (request.getHeaders().isPresent()) { + allHeaders.putAll(request.getHeaders().get()); + } + + // Determine HTTP method + String method = request.getMethod().orElse("POST").toUpperCase(); + + // Prepare request body if needed + RequestBody body = null; + if (request.getBody().isPresent()) { + try { + body = RequestBody.create( + ObjectMappers.JSON_MAPPER.writeValueAsBytes( + request.getBody().get()), + MediaTypes.APPLICATION_JSON); + allHeaders.put("Content-Type", "application/json"); + } catch (Exception e) { + throw new RuntimeException("Failed to serialize request body", e); + } + } else if (("POST".equals(method) || "PUT".equals(method) || "PATCH".equals(method))) { + // For methods that typically require a body, send an empty body + // to avoid OkHttp's "method POST must have a request body" error + body = RequestBody.create(new byte[0], null); + } + + // Build the request + Request.Builder requestBuilder = + new Request.Builder().url(httpUrl).method(method, body).headers(Headers.of(allHeaders)); + + if (!allHeaders.containsKey("Accept")) { + requestBuilder.addHeader("Accept", "application/json"); + } + + Request okhttpRequest = requestBuilder.build(); + + // Execute the request + OkHttpClient client = clientOptions.httpClient(); + if (requestOptions != null && requestOptions.getTimeout().isPresent()) { + client = clientOptions.httpClientWithTimeout(requestOptions); + } + + try (Response response = client.newCall(okhttpRequest).execute()) { + ResponseBody responseBody = response.body(); + if (response.isSuccessful()) { + String responseBodyString = responseBody != null ? responseBody.string() : "{}"; + Object parsedResponse; + try { + parsedResponse = ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class); + } catch (Exception e) { + // If JSON parsing fails, return the raw string + parsedResponse = responseBodyString; + } + return new BaseClientHttpResponse<>(parsedResponse, response); + } + String responseBodyString = responseBody != null ? responseBody.string() : "{}"; + throw new BaseClientApiException( + "Error with status code " + response.code(), + response.code(), + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response); + } catch (IOException e) { + throw new BaseClientException("Network error executing HTTP request", e); + } + } + + public BaseClientHttpResponse invokeForExternalUser(InvokeWorkflowForExternalUserOpts request) { + return invokeForExternalUser(request, null); + } + + public BaseClientHttpResponse invokeForExternalUser( + InvokeWorkflowForExternalUserOpts request, RequestOptions requestOptions) { + + // Validate inputs + if (request.getExternalUserId() == null + || request.getExternalUserId().trim().isEmpty()) { + throw new IllegalArgumentException("External user ID is required"); + } + + if (request.getUrl() == null || request.getUrl().trim().isEmpty()) { + throw new IllegalArgumentException("Workflow URL is required"); + } + + // Prepare headers with external user ID + Map headers = new HashMap<>(); + if (request.getHeaders().isPresent()) { + headers.putAll(request.getHeaders().get()); + } + headers.put("X-PD-External-User-ID", request.getExternalUserId()); + + // Create a new request with the authentication from the original request and the external user header + InvokeWorkflowOpts invokeRequest = InvokeWorkflowOpts.builder() + .urlOrEndpoint(request.getUrl()) + .body(request.getBody()) + .headers(headers) + .method(request.getMethod()) + .authType(request.getAuthType().orElse(HTTPAuthType.OAUTH)) + .build(); + + return invoke(invokeRequest, requestOptions); + } + + /** + * Builds a full workflow URL based on the input. + * + * @param input Either a full URL (with or without protocol) or just an endpoint ID. + * @return The fully constructed URL. + */ + private String buildWorkflowUrl(String input) { + String sanitizedInput = input.trim().toLowerCase(); + if (sanitizedInput.isEmpty()) { + throw new IllegalArgumentException("URL or endpoint ID is required"); + } + + // Check if it's already a full URL + if (sanitizedInput.startsWith("http://") || sanitizedInput.startsWith("https://")) { + try { + URL url = new URL(input); + // Validate the hostname + String workflowDomain = this.workflowDomain; + if (!url.getHost().endsWith(this.workflowDomain)) { + throw new IllegalArgumentException( + "Invalid workflow domain. URL must end with " + this.workflowDomain); + } + return input; + } catch (MalformedURLException e) { + throw new IllegalArgumentException("The provided URL is malformed: " + input, e); + } + } + + // Check if it's a URL without protocol + if (sanitizedInput.contains(".")) { + return buildWorkflowUrl("https://" + input); + } + + // It's an endpoint ID + if (!sanitizedInput.matches("^e[no][a-z0-9-]+$")) { + throw new IllegalArgumentException( + "Invalid endpoint ID format. Must contain only letters, numbers, and hyphens, " + + "and start with either 'en' or 'eo'."); + } + + return urlProtocol + "://" + sanitizedInput + "." + workflowDomain; + } + + private String getDefaultWorkflowDomain() { + String envUrl = clientOptions.environment().getUrl(); + // For non-prod environments (dev, staging), use dev domain + if (!envUrl.equals("https://api.pipedream.com") && !envUrl.equals("https://api2.pipedream.com")) { + return "m.d.pipedream.net"; + } + // For prod and canary, use standard domain + return "m.pipedream.net"; + } + + private String getUrlProtocol() { + String envUrl = clientOptions.environment().getUrl(); + // For non-prod environments (dev, staging), use http + if (!envUrl.equals("https://api.pipedream.com") && !envUrl.equals("https://api2.pipedream.com")) { + return "http"; + } + // For prod and canary, use https + return "https"; + } +} diff --git a/src/main/java/com/pipedream/api/resources/workflows/WorkflowsClient.java b/src/main/java/com/pipedream/api/resources/workflows/WorkflowsClient.java new file mode 100644 index 0000000..935ce7d --- /dev/null +++ b/src/main/java/com/pipedream/api/resources/workflows/WorkflowsClient.java @@ -0,0 +1,125 @@ +/** + * This file was manually created to add workflow invocation support. + */ +package com.pipedream.api.resources.workflows; + +import com.pipedream.api.core.ClientOptions; +import com.pipedream.api.core.RequestOptions; +import com.pipedream.api.resources.workflows.requests.InvokeWorkflowForExternalUserOpts; +import com.pipedream.api.resources.workflows.requests.InvokeWorkflowOpts; + +public class WorkflowsClient { + protected final ClientOptions clientOptions; + + private final RawWorkflowsClient rawClient; + + public WorkflowsClient(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + this.rawClient = new RawWorkflowsClient(clientOptions); + } + + /** + * Get responses with HTTP metadata like headers + */ + public RawWorkflowsClient withRawResponse() { + return this.rawClient; + } + + /** + * Invokes a workflow using the URL of its HTTP interface(s). + * + * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint + * @return The response from the workflow + */ + public Object invoke(String urlOrEndpoint) { + InvokeWorkflowOpts request = + InvokeWorkflowOpts.builder().urlOrEndpoint(urlOrEndpoint).build(); + return this.rawClient.invoke(request).body(); + } + + /** + * Invokes a workflow using the URL of its HTTP interface(s). + * + * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint + * @param requestOptions Additional request options + * @return The response from the workflow + */ + public Object invoke(String urlOrEndpoint, RequestOptions requestOptions) { + InvokeWorkflowOpts request = + InvokeWorkflowOpts.builder().urlOrEndpoint(urlOrEndpoint).build(); + return this.rawClient.invoke(request, requestOptions).body(); + } + + /** + * Invokes a workflow using the InvokeWorkflowOpts request object. + * + * @param request The request containing workflow invocation parameters + * @return The response from the workflow + */ + public Object invoke(InvokeWorkflowOpts request) { + return this.rawClient.invoke(request).body(); + } + + /** + * Invokes a workflow using the InvokeWorkflowOpts request object. + * + * @param request The request containing workflow invocation parameters + * @param requestOptions Additional request options + * @return The response from the workflow + */ + public Object invoke(InvokeWorkflowOpts request, RequestOptions requestOptions) { + return this.rawClient.invoke(request, requestOptions).body(); + } + + /** + * Invokes a workflow for a Pipedream Connect user in a project. + * + * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint + * @param externalUserId Your end user ID, for whom you're invoking the workflow + * @return The response from the workflow + */ + public Object invokeForExternalUser(String urlOrEndpoint, String externalUserId) { + InvokeWorkflowForExternalUserOpts request = InvokeWorkflowForExternalUserOpts.builder() + .url(urlOrEndpoint) + .externalUserId(externalUserId) + .build(); + return this.rawClient.invokeForExternalUser(request).body(); + } + + /** + * Invokes a workflow for a Pipedream Connect user in a project. + * + * @param urlOrEndpoint The URL of the workflow's HTTP interface, or the ID of the endpoint + * @param externalUserId Your end user ID, for whom you're invoking the workflow + * @param requestOptions Additional request options + * @return The response from the workflow + */ + public Object invokeForExternalUser(String urlOrEndpoint, String externalUserId, RequestOptions requestOptions) { + InvokeWorkflowForExternalUserOpts request = InvokeWorkflowForExternalUserOpts.builder() + .url(urlOrEndpoint) + .externalUserId(externalUserId) + .build(); + return this.rawClient.invokeForExternalUser(request, requestOptions).body(); + } + + /** + * Invokes a workflow for a Pipedream Connect user using the InvokeWorkflowForExternalUserOpts request object. + * + * @param request The request containing workflow invocation parameters + * @return The response from the workflow + */ + public Object invokeForExternalUser(InvokeWorkflowForExternalUserOpts request) { + return this.rawClient.invokeForExternalUser(request).body(); + } + + /** + * Invokes a workflow for a Pipedream Connect user using the InvokeWorkflowForExternalUserOpts request object. + * + * @param request The request containing workflow invocation parameters + * @param requestOptions Additional request options + * @return The response from the workflow + */ + public Object invokeForExternalUser(InvokeWorkflowForExternalUserOpts request, RequestOptions requestOptions) { + return this.rawClient.invokeForExternalUser(request, requestOptions).body(); + } +} diff --git a/src/main/java/com/pipedream/api/resources/workflows/package-info.java b/src/main/java/com/pipedream/api/resources/workflows/package-info.java new file mode 100644 index 0000000..cbd2a49 --- /dev/null +++ b/src/main/java/com/pipedream/api/resources/workflows/package-info.java @@ -0,0 +1,27 @@ +/** + * This package contains client classes for invoking Pipedream workflows. + * + *

The workflows package provides functionality to: + *

    + *
  • Invoke workflows using their HTTP interface URLs or endpoint IDs
  • + *
  • Invoke workflows on behalf of external users (Pipedream Connect)
  • + *
  • Support both synchronous and asynchronous invocation patterns
  • + *
+ * + *

Example usage: + *

+ * // Invoke a workflow
+ * Object response = client.workflows().invoke("https://your-workflow.m.pipedream.net",
+ *     "POST", Map.of("key", "value"), null, HTTPAuthType.OAUTH);
+ *
+ * // Invoke a workflow for an external user
+ * Object response = client.workflows().invokeForExternalUser(
+ *     "https://your-workflow.m.pipedream.net",
+ *     "external-user-123",
+ *     "POST",
+ *     Map.of("data", "payload"),
+ *     null
+ * );
+ * 
+ */ +package com.pipedream.api.resources.workflows; diff --git a/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowForExternalUserOpts.java b/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowForExternalUserOpts.java new file mode 100644 index 0000000..296fb55 --- /dev/null +++ b/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowForExternalUserOpts.java @@ -0,0 +1,182 @@ +/** + * This file was manually created to add workflow invocation support. + */ +package com.pipedream.api.resources.workflows.requests; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.pipedream.api.types.HTTPAuthType; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = InvokeWorkflowForExternalUserOpts.Builder.class) +public final class InvokeWorkflowForExternalUserOpts { + private final String url; + + private final String externalUserId; + + private final Optional body; + + private final Optional> headers; + + private final Optional method; + + private final Optional authType; + + private InvokeWorkflowForExternalUserOpts( + String url, + String externalUserId, + Optional body, + Optional> headers, + Optional method, + Optional authType) { + this.url = url; + this.externalUserId = externalUserId; + this.body = body; + this.headers = headers; + this.method = method; + this.authType = authType; + } + + @JsonProperty("url") + public String getUrl() { + return url; + } + + @JsonProperty("externalUserId") + public String getExternalUserId() { + return externalUserId; + } + + @JsonProperty("body") + public Optional getBody() { + return body; + } + + @JsonProperty("headers") + public Optional> getHeaders() { + return headers; + } + + @JsonProperty("method") + public Optional getMethod() { + return method; + } + + @JsonProperty("authType") + public Optional getAuthType() { + return authType; + } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof InvokeWorkflowForExternalUserOpts && equalTo((InvokeWorkflowForExternalUserOpts) other); + } + + private boolean equalTo(InvokeWorkflowForExternalUserOpts other) { + return url.equals(other.url) + && externalUserId.equals(other.externalUserId) + && body.equals(other.body) + && headers.equals(other.headers) + && method.equals(other.method) + && authType.equals(other.authType); + } + + @Override + public int hashCode() { + return Objects.hash(this.url, this.externalUserId, this.body, this.headers, this.method, this.authType); + } + + @Override + public String toString() { + return "InvokeWorkflowForExternalUserOpts{url: " + url + ", externalUserId: " + externalUserId + ", body: " + + body + ", headers: " + headers + ", method: " + method + ", authType: " + authType + "}"; + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private String url; + + private String externalUserId; + + private Optional body = Optional.empty(); + + private Optional> headers = Optional.empty(); + + private Optional method = Optional.empty(); + + private Optional authType = Optional.empty(); + + private Builder() {} + + @JsonSetter("url") + public Builder url(String url) { + this.url = url; + return this; + } + + @JsonSetter("externalUserId") + public Builder externalUserId(String externalUserId) { + this.externalUserId = externalUserId; + return this; + } + + @JsonSetter(value = "body", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + public Builder body(Optional body) { + this.body = body; + return this; + } + + public Builder body(Object body) { + this.body = Optional.ofNullable(body); + return this; + } + + @JsonSetter(value = "headers", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + public Builder headers(Optional> headers) { + this.headers = headers; + return this; + } + + public Builder headers(Map headers) { + this.headers = Optional.ofNullable(headers); + return this; + } + + @JsonSetter(value = "method", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + public Builder method(Optional method) { + this.method = method; + return this; + } + + public Builder method(String method) { + this.method = Optional.ofNullable(method); + return this; + } + + @JsonSetter(value = "authType", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + public Builder authType(Optional authType) { + this.authType = authType; + return this; + } + + public Builder authType(HTTPAuthType authType) { + this.authType = Optional.ofNullable(authType); + return this; + } + + public InvokeWorkflowForExternalUserOpts build() { + return new InvokeWorkflowForExternalUserOpts(url, externalUserId, body, headers, method, authType); + } + } +} diff --git a/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowOpts.java b/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowOpts.java new file mode 100644 index 0000000..468d227 --- /dev/null +++ b/src/main/java/com/pipedream/api/resources/workflows/requests/InvokeWorkflowOpts.java @@ -0,0 +1,164 @@ +/** + * This file was manually created to add workflow invocation support. + */ +package com.pipedream.api.resources.workflows.requests; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.pipedream.api.types.HTTPAuthType; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = InvokeWorkflowOpts.Builder.class) +public final class InvokeWorkflowOpts { + private final String urlOrEndpoint; + + private final Optional body; + + private final Optional> headers; + + private final Optional method; + + private final Optional authType; + + private InvokeWorkflowOpts( + String urlOrEndpoint, + Optional body, + Optional> headers, + Optional method, + Optional authType) { + this.urlOrEndpoint = urlOrEndpoint; + this.body = body; + this.headers = headers; + this.method = method; + this.authType = authType; + } + + @JsonProperty("urlOrEndpoint") + public String getUrlOrEndpoint() { + return urlOrEndpoint; + } + + @JsonProperty("body") + public Optional getBody() { + return body; + } + + @JsonProperty("headers") + public Optional> getHeaders() { + return headers; + } + + @JsonProperty("method") + public Optional getMethod() { + return method; + } + + @JsonProperty("authType") + public Optional getAuthType() { + return authType; + } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof InvokeWorkflowOpts && equalTo((InvokeWorkflowOpts) other); + } + + private boolean equalTo(InvokeWorkflowOpts other) { + return urlOrEndpoint.equals(other.urlOrEndpoint) + && body.equals(other.body) + && headers.equals(other.headers) + && method.equals(other.method) + && authType.equals(other.authType); + } + + @Override + public int hashCode() { + return Objects.hash(this.urlOrEndpoint, this.body, this.headers, this.method, this.authType); + } + + @Override + public String toString() { + return "InvokeWorkflowOpts{urlOrEndpoint: " + urlOrEndpoint + ", body: " + body + ", headers: " + headers + + ", method: " + method + ", authType: " + authType + "}"; + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private String urlOrEndpoint; + + private Optional body = Optional.empty(); + + private Optional> headers = Optional.empty(); + + private Optional method = Optional.empty(); + + private Optional authType = Optional.empty(); + + private Builder() {} + + @JsonSetter("urlOrEndpoint") + public Builder urlOrEndpoint(String urlOrEndpoint) { + this.urlOrEndpoint = urlOrEndpoint; + return this; + } + + @JsonSetter(value = "body", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + public Builder body(Optional body) { + this.body = body; + return this; + } + + public Builder body(Object body) { + this.body = Optional.ofNullable(body); + return this; + } + + @JsonSetter(value = "headers", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + public Builder headers(Optional> headers) { + this.headers = headers; + return this; + } + + public Builder headers(Map headers) { + this.headers = Optional.ofNullable(headers); + return this; + } + + @JsonSetter(value = "method", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + public Builder method(Optional method) { + this.method = method; + return this; + } + + public Builder method(String method) { + this.method = Optional.ofNullable(method); + return this; + } + + @JsonSetter(value = "authType", nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + public Builder authType(Optional authType) { + this.authType = authType; + return this; + } + + public Builder authType(HTTPAuthType authType) { + this.authType = Optional.ofNullable(authType); + return this; + } + + public InvokeWorkflowOpts build() { + return new InvokeWorkflowOpts(urlOrEndpoint, body, headers, method, authType); + } + } +} diff --git a/src/main/java/com/pipedream/api/types/HTTPAuthType.java b/src/main/java/com/pipedream/api/types/HTTPAuthType.java new file mode 100644 index 0000000..d4e4d15 --- /dev/null +++ b/src/main/java/com/pipedream/api/types/HTTPAuthType.java @@ -0,0 +1,42 @@ +/** + * This file was manually created to add workflow invocation support. + */ +package com.pipedream.api.types; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Authentication types for workflow invocation + */ +public enum HTTPAuthType { + NONE("none"), + STATIC_BEARER("static_bearer_token"), + OAUTH("oauth"); + + private final String value; + + HTTPAuthType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @JsonCreator + public static HTTPAuthType fromValue(String value) { + for (HTTPAuthType type : HTTPAuthType.values()) { + if (type.value.equals(value)) { + return type; + } + } + throw new IllegalArgumentException("Unknown HTTPAuthType: " + value); + } + + @Override + public String toString() { + return value; + } +}