Skip to content

Commit 624a321

Browse files
authored
Merge branch 'main' into samikshya-db/regexUserAgent
2 parents 4e6f991 + 6e71a0d commit 624a321

27 files changed

+592
-75
lines changed

CHANGELOG.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,73 @@
11
# Version changelog
22

3+
## [Release] Release v0.32.2
4+
5+
### Bug Fixes
6+
7+
* Make `UserAgent`'s `otherInfo` thread-safe ([#357](https://github.com/databricks/databricks-sdk-java/pull/357)).
8+
9+
10+
11+
12+
## [Release] Release v0.32.1
13+
14+
### Bug Fixes
15+
16+
* Retry on too many auth requests ([#355](https://github.com/databricks/databricks-sdk-java/pull/355)).
17+
18+
19+
20+
21+
## [Release] Release v0.32.0
22+
23+
### Bug Fixes
24+
25+
* Fix listAccountMetastoreAssignments Integration test ([#350](https://github.com/databricks/databricks-sdk-java/pull/350))
26+
* Fix parsing issue in ErrorDetail ([#328](https://github.com/databricks/databricks-sdk-java/pull/328))
27+
28+
### Internal Changes
29+
30+
* Update SDK to OpenAPI spec ([#346](https://github.com/databricks/databricks-sdk-java/pull/346)).
31+
* Add DCO guidelines ([#351](https://github.com/databricks/databricks-sdk-java/pull/351))
32+
33+
34+
### API Changes:
35+
36+
* Added `workspaceClient.disableLegacyAccess()` service and `accountClient.disableLegacyFeatures()` service.
37+
* Added `workspaceClient.temporaryTableCredentials()` service.
38+
* Added `putAiGateway()` method for `workspaceClient.servingEndpoints()` service.
39+
* Added `com.databricks.sdk.service.apps.ApplicationState`, `com.databricks.sdk.service.apps.ApplicationStatus`, `com.databricks.sdk.service.apps.ComputeState` and `com.databricks.sdk.service.apps.ComputeStatus` classes.
40+
* Added `com.databricks.sdk.service.catalog.AwsCredentials`, `com.databricks.sdk.service.catalog.AzureUserDelegationSas`, `com.databricks.sdk.service.catalog.GcpOauthToken`, `com.databricks.sdk.service.catalog.GenerateTemporaryTableCredentialRequest`, `com.databricks.sdk.service.catalog.GenerateTemporaryTableCredentialResponse`, `com.databricks.sdk.service.catalog.R2Credentials` and `com.databricks.sdk.service.catalog.TableOperation` classes.
41+
* Added `com.databricks.sdk.service.serving.AiGatewayConfig`, `com.databricks.sdk.service.serving.AiGatewayGuardrailParameters`, `com.databricks.sdk.service.serving.AiGatewayGuardrailPiiBehavior`, `com.databricks.sdk.service.serving.AiGatewayGuardrailPiiBehaviorBehavior`, `com.databricks.sdk.service.serving.AiGatewayGuardrails`, `com.databricks.sdk.service.serving.AiGatewayInferenceTableConfig`, `com.databricks.sdk.service.serving.AiGatewayRateLimit`, `com.databricks.sdk.service.serving.AiGatewayRateLimitKey`, `com.databricks.sdk.service.serving.AiGatewayRateLimitRenewalPeriod`, `com.databricks.sdk.service.serving.AiGatewayUsageTrackingConfig`, `com.databricks.sdk.service.serving.PutAiGatewayRequest` and `com.databricks.sdk.service.serving.PutAiGatewayResponse` classes.
42+
* Added `com.databricks.sdk.service.settings.BooleanMessage`, `com.databricks.sdk.service.settings.DeleteDisableLegacyAccessRequest`, `com.databricks.sdk.service.settings.DeleteDisableLegacyAccessResponse`, `com.databricks.sdk.service.settings.DeleteDisableLegacyFeaturesRequest`, `com.databricks.sdk.service.settings.DeleteDisableLegacyFeaturesResponse`, `com.databricks.sdk.service.settings.DisableLegacyAccess`, `com.databricks.sdk.service.settings.DisableLegacyFeatures`, `com.databricks.sdk.service.settings.GetDisableLegacyAccessRequest`, `com.databricks.sdk.service.settings.GetDisableLegacyFeaturesRequest`, `com.databricks.sdk.service.settings.UpdateDisableLegacyAccessRequest` and `com.databricks.sdk.service.settings.UpdateDisableLegacyFeaturesRequest` classes.
43+
* Added `appStatus` and `computeStatus` fields for `com.databricks.sdk.service.apps.App`.
44+
* Added `deploymentId` field for `com.databricks.sdk.service.apps.CreateAppDeploymentRequest`.
45+
* Added `externalAccessEnabled` field for `com.databricks.sdk.service.catalog.GetMetastoreSummaryResponse`.
46+
* Added `includeManifestCapabilities` field for `com.databricks.sdk.service.catalog.GetTableRequest`.
47+
* Added `includeManifestCapabilities` field for `com.databricks.sdk.service.catalog.ListSummariesRequest`.
48+
* Added `includeManifestCapabilities` field for `com.databricks.sdk.service.catalog.ListTablesRequest`.
49+
* Added `externalAccessEnabled` field for `com.databricks.sdk.service.catalog.MetastoreInfo`.
50+
* Added `budgetPolicyId` field for `com.databricks.sdk.service.pipelines.CreatePipeline`.
51+
* Added `budgetPolicyId` field for `com.databricks.sdk.service.pipelines.EditPipeline`.
52+
* Added `effectiveBudgetPolicyId` field for `com.databricks.sdk.service.pipelines.GetPipelineResponse`.
53+
* Added `budgetPolicyId` field for `com.databricks.sdk.service.pipelines.PipelineSpec`.
54+
* Added `aiGateway` field for `com.databricks.sdk.service.serving.CreateServingEndpoint`.
55+
* Added `aiGateway` field for `com.databricks.sdk.service.serving.ServingEndpoint`.
56+
* Added `aiGateway` field for `com.databricks.sdk.service.serving.ServingEndpointDetailed`.
57+
* Added `workspaceId` field for `com.databricks.sdk.service.settings.TokenInfo`.
58+
* Changed `delete()`, `start()` and `stop()` methods for `workspaceClient.apps()` service to return `com.databricks.sdk.service.apps.App` class.
59+
* Changed `deploy()` method for `workspaceClient.apps()` service with new required argument order.
60+
* Changed `sourceCodePath` field for `com.databricks.sdk.service.apps.AppDeployment` to no longer be required.
61+
* Changed `sourceCodePath` field for `com.databricks.sdk.service.apps.CreateAppDeploymentRequest` to no longer be required.
62+
* Changed `returnParams` and `routineDependencies` fields for `com.databricks.sdk.service.catalog.CreateFunction` to no longer be required.
63+
* Removed `com.databricks.sdk.service.apps.AppState`, `com.databricks.sdk.service.apps.AppStatus`, `Object` and `Object` classes.
64+
* Removed `com.databricks.sdk.service.sql.ClientCallContext`, `com.databricks.sdk.service.sql.EncodedText`, `com.databricks.sdk.service.sql.EncodedTextEncoding`, `com.databricks.sdk.service.sql.QuerySource`, `com.databricks.sdk.service.sql.QuerySourceDriverInfo`, `com.databricks.sdk.service.sql.QuerySourceEntryPoint`, `com.databricks.sdk.service.sql.QuerySourceJobManager`, `com.databricks.sdk.service.sql.QuerySourceTrigger` and `com.databricks.sdk.service.sql.ServerlessChannelInfo` classes.
65+
* Removed `status` field for `com.databricks.sdk.service.apps.App`.
66+
* Removed `querySource` field for `com.databricks.sdk.service.sql.QueryInfo`.
67+
68+
OpenAPI SHA: 6f6b1371e640f2dfeba72d365ac566368656f6b6, Date: 2024-09-19
69+
70+
371
## [Release] Release v0.31.1
472

573
### New Features and Improvements

CONTRIBUTING.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@ New contributors should look for the following tags when searching for a first c
1818

1919
[good first issue](https://github.com/databricks/databricks-sdk-java/labels/good%20first%20issue)
2020

21+
## Developer Certificate of Origin
22+
23+
To contribute to this repository, you must sign off your commits to certify that you have the right to contribute the code and that it complies with the open source license.
24+
You can easily do this by adding a "Signed-off-by" line to your commit message to certify your compliance. Please use use your real name as pseudonymous/anonymous contributions are not accepted.
25+
26+
```
27+
Signed-off-by: Joe Smith <[email protected]>
28+
```
29+
30+
If you set your `user.name` and `user.email` git configs, you can sign your commit automatically with git commit -s:
31+
32+
```
33+
git commit -s -m "Your commit message"
34+
```
35+
36+
2137
## Contribution Workflow
2238

2339
Code contributions—bug fixes, new development, test improvement—all follow a GitHub-centered workflow. To participate in Databricks Java SDK development, set up a GitHub account. Then:
@@ -43,7 +59,7 @@ Code contributions—bug fixes, new development, test improvement—all follow a
4359
```bash
4460
git add -A
4561
46-
git commit -m "commit message here"
62+
git commit -s -m "commit message here"
4763
```
4864

4965
1. Push your changes to your GitHub repo.

DCO

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Developer's Certificate of Origin 1.1
2+
By making a contribution to this project, I certify that:
3+
(a) The contribution was created in whole or in part by me and I
4+
have the right to submit it under the open source license
5+
indicated in the file; or
6+
(b) The contribution is based upon previous work that, to the best
7+
of my knowledge, is covered under an appropriate open source
8+
license and I have the right under that license to submit that
9+
work with modifications, whether created in whole or in part
10+
by me, under the same open source license (unless I am
11+
permitted to submit under a different license), as indicated
12+
in the file; or
13+
(c) The contribution was provided directly to me by some other
14+
person who certified (a), (b) or (c) and I have not modified
15+
it.
16+
(d) I understand and agree that this project and the contribution
17+
are public and that a record of the contribution (including all
18+
personal information I submit with it, including my sign-off) is
19+
maintained indefinitely and may be redistributed consistent with
20+
this project or the open source license(s) involved.

databricks-sdk-java/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>com.databricks</groupId>
77
<artifactId>databricks-sdk-parent</artifactId>
8-
<version>0.31.1</version>
8+
<version>0.32.2</version>
99
</parent>
1010
<artifactId>databricks-sdk-java</artifactId>
1111
<properties>

databricks-sdk-java/src/main/java/com/databricks/sdk/core/ApiClient.java

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.time.ZonedDateTime;
2222
import java.time.format.DateTimeFormatter;
2323
import java.util.*;
24+
import java.util.function.Function;
2425
import org.slf4j.Logger;
2526
import org.slf4j.LoggerFactory;
2627

@@ -29,55 +30,125 @@
2930
* guessing
3031
*/
3132
public class ApiClient {
33+
public static class Builder {
34+
private Timer timer;
35+
private Function<Void, Map<String, String>> authenticateFunc;
36+
private Function<Void, String> getHostFunc;
37+
private Function<Void, String> getAuthTypeFunc;
38+
private Integer debugTruncateBytes;
39+
private HttpClient httpClient;
40+
private String accountId;
41+
private RetryStrategyPicker retryStrategyPicker;
42+
private boolean isDebugHeaders;
43+
44+
public Builder withDatabricksConfig(DatabricksConfig config) {
45+
this.authenticateFunc = v -> config.authenticate();
46+
this.getHostFunc = v -> config.getHost();
47+
this.getAuthTypeFunc = v -> config.getAuthType();
48+
this.httpClient = config.getHttpClient();
49+
this.debugTruncateBytes = config.getDebugTruncateBytes();
50+
this.accountId = config.getAccountId();
51+
this.retryStrategyPicker = new RequestBasedRetryStrategyPicker(config.getHost());
52+
this.isDebugHeaders = config.isDebugHeaders();
53+
54+
return this;
55+
}
56+
57+
public Builder withTimer(Timer timer) {
58+
this.timer = timer;
59+
return this;
60+
}
61+
62+
public Builder withAuthenticateFunc(Function<Void, Map<String, String>> authenticateFunc) {
63+
this.authenticateFunc = authenticateFunc;
64+
return this;
65+
}
66+
67+
public Builder withGetHostFunc(Function<Void, String> getHostFunc) {
68+
this.getHostFunc = getHostFunc;
69+
return this;
70+
}
71+
72+
public Builder withGetAuthTypeFunc(Function<Void, String> getAuthTypeFunc) {
73+
this.getAuthTypeFunc = getAuthTypeFunc;
74+
return this;
75+
}
76+
77+
public Builder withHttpClient(HttpClient httpClient) {
78+
this.httpClient = httpClient;
79+
return this;
80+
}
81+
82+
public Builder withRetryStrategyPicker(RetryStrategyPicker retryStrategyPicker) {
83+
this.retryStrategyPicker = retryStrategyPicker;
84+
return this;
85+
}
86+
87+
public ApiClient build() {
88+
return new ApiClient(this);
89+
}
90+
}
91+
3292
private static final Logger LOG = LoggerFactory.getLogger(ApiClient.class);
3393

3494
private final int maxAttempts;
3595

3696
private final ObjectMapper mapper;
3797

38-
private final DatabricksConfig config;
39-
4098
private final Random random;
4199

42100
private final HttpClient httpClient;
43101
private final BodyLogger bodyLogger;
44102
private final RetryStrategyPicker retryStrategyPicker;
45103
private final Timer timer;
104+
private final Function<Void, Map<String, String>> authenticateFunc;
105+
private final Function<Void, String> getHostFunc;
106+
private final Function<Void, String> getAuthTypeFunc;
107+
private final String accountId;
108+
private final boolean isDebugHeaders;
46109
private static final String RETRY_AFTER_HEADER = "retry-after";
47110

48111
public ApiClient() {
49112
this(ConfigLoader.getDefault());
50113
}
51114

52115
public String configuredAccountID() {
53-
return config.getAccountId();
116+
return accountId;
54117
}
55118

56119
public ApiClient(DatabricksConfig config) {
57120
this(config, new SystemTimer());
58121
}
59122

60123
public ApiClient(DatabricksConfig config, Timer timer) {
61-
this.config = config;
62-
config.resolve();
63-
64-
Integer rateLimit = config.getRateLimit();
65-
if (rateLimit == null) {
66-
rateLimit = 15;
67-
}
68-
69-
Integer debugTruncateBytes = config.getDebugTruncateBytes();
124+
this(new Builder().withDatabricksConfig(config.resolve()).withTimer(timer));
125+
}
126+
127+
private ApiClient(Builder builder) {
128+
this.timer = builder.timer != null ? builder.timer : new SystemTimer();
129+
this.authenticateFunc =
130+
builder.authenticateFunc != null
131+
? builder.authenticateFunc
132+
: v -> new HashMap<String, String>();
133+
this.getHostFunc = builder.getHostFunc != null ? builder.getHostFunc : v -> "";
134+
this.getAuthTypeFunc = builder.getAuthTypeFunc != null ? builder.getAuthTypeFunc : v -> "";
135+
this.httpClient = builder.httpClient;
136+
this.accountId = builder.accountId;
137+
this.retryStrategyPicker =
138+
builder.retryStrategyPicker != null
139+
? builder.retryStrategyPicker
140+
: new RequestBasedRetryStrategyPicker(this.getHostFunc.apply(null));
141+
this.isDebugHeaders = builder.isDebugHeaders;
142+
143+
Integer debugTruncateBytes = builder.debugTruncateBytes;
70144
if (debugTruncateBytes == null) {
71145
debugTruncateBytes = 96;
72146
}
73147

74148
maxAttempts = 4;
75149
mapper = SerDeUtils.createMapper();
76150
random = new Random();
77-
httpClient = config.getHttpClient();
78151
bodyLogger = new BodyLogger(mapper, 1024, debugTruncateBytes);
79-
retryStrategyPicker = new RequestBasedRetryStrategyPicker(this.config);
80-
this.timer = timer;
81152
}
82153

83154
private static <I> void setQuery(Request in, I entity) {
@@ -203,7 +274,7 @@ private <I> Request prepareBaseRequest(String method, String path, I in)
203274
InputStream body = (InputStream) in;
204275
return new Request(method, path, body);
205276
} else {
206-
String body = serialize(in);
277+
String body = (in instanceof String) ? (String) in : serialize(in);
207278
return new Request(method, path, body);
208279
}
209280
}
@@ -245,15 +316,19 @@ private Response executeInner(Request in, String path) {
245316
Response out = null;
246317

247318
// Authenticate the request. Failures should not be retried.
248-
in.withHeaders(config.authenticate());
319+
in.withHeaders(authenticateFunc.apply(null));
249320

250321
// Prepend host to URL only after config.authenticate().
251322
// This call may configure the host (e.g. in case of notebook native auth).
252-
in.withUrl(config.getHost() + path);
323+
in.withUrl(getHostFunc.apply(null) + path);
253324

254325
// Set User-Agent with auth type info, which is available only
255326
// after the first invocation to config.authenticate()
256-
String userAgent = String.format("%s auth/%s", UserAgent.asString(), config.getAuthType());
327+
String userAgent = UserAgent.asString();
328+
String authType = getAuthTypeFunc.apply(null);
329+
if (authType != "") {
330+
userAgent += String.format(" auth/%s", authType);
331+
}
257332
in.withHeader("User-Agent", userAgent);
258333

259334
// Make the request, catching any exceptions, as we may want to retry.
@@ -347,9 +422,9 @@ private String makeLogRecord(Request in, Response out) {
347422
StringBuilder sb = new StringBuilder();
348423
sb.append("> ");
349424
sb.append(in.getRequestLine());
350-
if (config.isDebugHeaders()) {
425+
if (this.isDebugHeaders) {
351426
sb.append("\n * Host: ");
352-
sb.append(config.getHost());
427+
sb.append(this.getHostFunc.apply(null));
353428
in.getHeaders()
354429
.forEach((header, value) -> sb.append(String.format("\n * %s: %s", header, value)));
355430
}

databricks-sdk-java/src/main/java/com/databricks/sdk/core/DatabricksConfig.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -581,12 +581,15 @@ private OpenIDConnectEndpoints fetchDefaultOidcEndpoints() throws IOException {
581581
return new OpenIDConnectEndpoints(prefix + "/v1/token", prefix + "/v1/authorize");
582582
}
583583

584-
String oidcEndpoint = getHost() + "/oidc/.well-known/oauth-authorization-server";
585-
Response resp = getHttpClient().execute(new Request("GET", oidcEndpoint));
586-
if (resp.getStatusCode() != 200) {
587-
return null;
588-
}
589-
return new ObjectMapper().readValue(resp.getBody(), OpenIDConnectEndpoints.class);
584+
ApiClient apiClient =
585+
new ApiClient.Builder()
586+
.withHttpClient(getHttpClient())
587+
.withGetHostFunc(v -> getHost())
588+
.build();
589+
return apiClient.GET(
590+
"/oidc/.well-known/oauth-authorization-server",
591+
OpenIDConnectEndpoints.class,
592+
new HashMap<>());
590593
}
591594

592595
@Override

databricks-sdk-java/src/main/java/com/databricks/sdk/core/UserAgent.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public String getValue() {
3232
// TODO: check if reading from
3333
// /META-INF/maven/com.databricks/databrics-sdk-java/pom.properties
3434
// or getClass().getPackage().getImplementationVersion() is enough.
35-
private static final String version = "0.31.1";
35+
private static final String version = "0.32.2";
3636

3737
public static void withProduct(String product, String productVersion) {
3838
UserAgent.product = product;
@@ -92,7 +92,9 @@ public static void withPartner(String partner) {
9292
public static void withOtherInfo(String key, String value) {
9393
matchAlphanum(key);
9494
matchAlphanumOrSemVer(value);
95-
otherInfo.add(new Info(key, value));
95+
synchronized (otherInfo) {
96+
otherInfo.add(new Info(key, value));
97+
}
9698
}
9799

98100
private static String osName() {
@@ -119,10 +121,13 @@ public static String asString() {
119121
segments.add(String.format("databricks-sdk-java/%s", version));
120122
segments.add(String.format("jvm/%s", jvmVersion()));
121123
segments.add(String.format("os/%s", osName()));
122-
segments.addAll(
123-
otherInfo.stream()
124-
.map(e -> String.format("%s/%s", e.getKey(), e.getValue()))
125-
.collect(Collectors.toSet()));
124+
// Concurrent iteration over ArrayList must be guarded with synchronized.
125+
synchronized (otherInfo) {
126+
segments.addAll(
127+
otherInfo.stream()
128+
.map(e -> String.format("%s/%s", e.getKey(), e.getValue()))
129+
.collect(Collectors.toSet()));
130+
}
126131
return segments.stream().collect(Collectors.joining(" "));
127132
}
128133
}

databricks-sdk-java/src/main/java/com/databricks/sdk/core/error/ErrorDetail.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public ErrorDetail(
2626
this.type = type;
2727
this.reason = reason;
2828
this.domain = domain;
29-
this.metadata = Collections.unmodifiableMap(metadata);
29+
this.metadata = metadata != null ? Collections.unmodifiableMap(metadata) : null;
3030
}
3131

3232
public String getType() {

0 commit comments

Comments
 (0)