Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
2374611
First draft
emmyzhou-db May 28, 2025
5148136
Update test
emmyzhou-db May 28, 2025
78c03a8
Clean up unit tests
emmyzhou-db May 30, 2025
5a37c59
Clean up comments
emmyzhou-db May 30, 2025
f5e4f8a
Add Javadoc to Token.java
emmyzhou-db May 30, 2025
3e65109
Add a token expiry buffer field
emmyzhou-db May 30, 2025
dfce414
Fix for comments
emmyzhou-db Jun 2, 2025
5bd4215
Update tests
emmyzhou-db Jun 3, 2025
93e0baf
Clean up tests
emmyzhou-db Jun 3, 2025
15e221d
Add logging
emmyzhou-db Jun 3, 2025
7589dab
Performance optimization
emmyzhou-db Jun 3, 2025
d97c734
Furter optimizations
emmyzhou-db Jun 3, 2025
105bc99
Add extra token state check in async refresh
emmyzhou-db Jun 3, 2025
b24a0fc
Change LocalDateTime to Instant
emmyzhou-db Jun 3, 2025
6f81b4c
Update parseExpiry in CilTokenSource
emmyzhou-db Jun 4, 2025
daac1b2
Update javadoc
emmyzhou-db Jun 4, 2025
f3d4b8a
Update javadoc
emmyzhou-db Jun 4, 2025
12123a9
Retrigger tests
emmyzhou-db Jun 5, 2025
def03c5
Merge branch 'main' into emmyzhou-db/localdatetime-to-instant
parthban-db Jun 5, 2025
8705ff5
Save progress
emmyzhou-db Jun 6, 2025
0ce06d8
Revert "Save progress"
emmyzhou-db Jun 6, 2025
fdc50ef
Removed redundant date formattters
emmyzhou-db Jun 6, 2025
48a5310
Change all usage of LocalDateTime to Instant
emmyzhou-db Jun 6, 2025
70934b2
Change clock supplier to use UTC time
emmyzhou-db Jun 6, 2025
1bd052f
Add support for space separated expiry strings
emmyzhou-db Jun 7, 2025
408f3b4
revert test data
emmyzhou-db Jun 7, 2025
14d2a8f
Update CilTokenSource
emmyzhou-db Jun 10, 2025
7fccff9
Update exception handling
emmyzhou-db Jun 11, 2025
64313f8
Update Javadoc
emmyzhou-db Jun 11, 2025
447eae2
Added more tests to CilTokenSourceTest
emmyzhou-db Jun 11, 2025
66335a7
Add test to verify perserved behaviour
emmyzhou-db Jun 12, 2025
3a824eb
Generate all timezones
emmyzhou-db Jun 12, 2025
c1367bf
Merge branch 'emmyzhou-db/test_time' into emmyzhou-db/localdatetime-t…
emmyzhou-db Jun 12, 2025
4d31c1e
Merge branch 'emmyzhou-db/test_time' into emmyzhou-db/localdatetime-t…
emmyzhou-db Jun 12, 2025
95a3c6d
Update test
emmyzhou-db Jun 12, 2025
a5c65c5
update tests
emmyzhou-db Jun 12, 2025
a165b72
Date formats are generated at run-time
emmyzhou-db Jun 12, 2025
d1c1a6c
Generate date formats at run-time
emmyzhou-db Jun 12, 2025
785c400
Update stream of test cases
emmyzhou-db Jun 13, 2025
f35988d
Merge branch 'emmyzhou-db/test_time' into emmyzhou-db/localdatetime-t…
emmyzhou-db Jun 13, 2025
9d5c85e
Add comment
emmyzhou-db Jun 13, 2025
2a7cd95
Add comment
emmyzhou-db Jun 13, 2025
257998c
Update comment
emmyzhou-db Jun 13, 2025
ac99bbe
Merge branch 'emmyzhou-db/test_time' into emmyzhou-db/localdatetime-t…
emmyzhou-db Jun 13, 2025
ceea58a
update stream of tests
emmyzhou-db Jun 13, 2025
0697fae
Polish comments
emmyzhou-db Jun 13, 2025
451bd27
Merge branch 'emmyzhou-db/localdatetime-to-instant' into emmyzhou-db/…
emmyzhou-db Jun 13, 2025
9845308
Merge branch 'main' into emmyzhou-db/async_token_cache
emmyzhou-db Jun 16, 2025
60c0890
Merge branch 'main' into emmyzhou-db/async_token_cache
emmyzhou-db Jun 16, 2025
490091c
Small fixes
emmyzhou-db Jun 16, 2025
1b88b29
More small fixes
emmyzhou-db Jun 16, 2025
c07669b
Update comment
emmyzhou-db Jun 16, 2025
d8db181
Small fix
emmyzhou-db Jun 16, 2025
87800e6
Rename SystemClockSupplier
emmyzhou-db Jun 16, 2025
99ba2b1
Update test to use TestClockSupplier instead
emmyzhou-db Jun 16, 2025
536a283
Small refactor of getToken
emmyzhou-db Jun 17, 2025
6b01587
Add env variable to enable async refresh
emmyzhou-db Jun 17, 2025
37bbe33
Trigger CI
emmyzhou-db Jun 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
import org.slf4j.LoggerFactory;

public class AzureCliCredentialsProvider implements CredentialsProvider {

private final ObjectMapper mapper = new ObjectMapper();
private static final Logger LOG = LoggerFactory.getLogger(AzureCliCredentialsProvider.class);

public static final String AZURE_CLI = "azure-cli";

@Override
Expand All @@ -27,11 +27,11 @@ public CliTokenSource tokenSourceFor(DatabricksConfig config, String resource) {
new ArrayList<>(
Arrays.asList(
azPath, "account", "get-access-token", "--resource", resource, "--output", "json"));

Optional<String> subscription = getSubscription(config);
if (subscription.isPresent()) {
// This will fail if the user has access to the workspace, but not to the subscription
// itself.
// In such case, we fall back to not using the subscription.
// itself. In such case, we fall back to not using the subscription.
List<String> extendedCmd = new ArrayList<>(cmd);
extendedCmd.addAll(Arrays.asList("--subscription", subscription.get()));
try {
Expand Down Expand Up @@ -60,11 +60,13 @@ private Optional<String> getSubscription(DatabricksConfig config) {
if (resourceId == null || resourceId.equals("")) {
return Optional.empty();
}

String[] components = resourceId.split("/");
if (components.length < 3) {
LOG.warn("Invalid azure workspace resource ID");
return Optional.empty();
}

return Optional.of(components[2]);
}

Expand All @@ -78,14 +80,18 @@ public OAuthHeaderFactory configure(DatabricksConfig config) {
AzureUtils.ensureHostPresent(config, mapper, this::tokenSourceFor);
String resource = config.getEffectiveAzureLoginAppId();
CliTokenSource tokenSource = tokenSourceFor(config, resource);
tokenSource.withAsyncRefresh(config.getEnableExperimentalAsyncTokenRefresh());

CliTokenSource mgmtTokenSource;
try {
mgmtTokenSource =
tokenSourceFor(config, config.getAzureEnvironment().getServiceManagementEndpoint());
mgmtTokenSource.withAsyncRefresh(config.getEnableExperimentalAsyncTokenRefresh());
} catch (Exception e) {
LOG.debug("Not including service management token in headers", e);
mgmtTokenSource = null;
}

CliTokenSource finalMgmtTokenSource = mgmtTokenSource;
return OAuthHeaderFactory.fromSuppliers(
tokenSource::getToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
public class DatabricksCliCredentialsProvider implements CredentialsProvider {

private static final Logger LOG = LoggerFactory.getLogger(DatabricksCliCredentialsProvider.class);

public static final String DATABRICKS_CLI = "databricks-cli";

@Override
Expand All @@ -26,12 +25,15 @@ private CliTokenSource getDatabricksCliTokenSource(DatabricksConfig config) {
LOG.debug("Databricks CLI could not be found");
return null;
}

List<String> cmd =
new ArrayList<>(Arrays.asList(cliPath, "auth", "token", "--host", config.getHost()));

if (config.isAccountClient()) {
cmd.add("--account-id");
cmd.add(config.getAccountId());
}

return new CliTokenSource(cmd, "token_type", "access_token", "expiry", config.getEnv());
}

Expand All @@ -47,7 +49,9 @@ public OAuthHeaderFactory configure(DatabricksConfig config) {
if (tokenSource == null) {
return null;
}

tokenSource.getToken(); // We need this for checking if databricks CLI is installed.
tokenSource.withAsyncRefresh(config.getEnableExperimentalAsyncTokenRefresh());
return OAuthHeaderFactory.fromTokenSource(tokenSource);
} catch (DatabricksException e) {
String stderr = e.getMessage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ public class DatabricksConfig {
@ConfigAttribute(env = "DATABRICKS_OIDC_TOKEN_ENV", auth = "env-oidc")
private String oidcTokenEnv;

/**
* Whether to enable experimental async token refresh.
*
* <p><b>Experimental:</b> This feature and its setting are experimental and may be removed in
* future releases.
*/
@ConfigAttribute(env = "DATABRICKS_ENABLE_EXPERIMENTAL_ASYNC_TOKEN_REFRESH")
private Boolean enableExperimentalAsyncTokenRefresh;

public Environment getEnv() {
return env;
}
Expand Down Expand Up @@ -575,6 +584,16 @@ public DatabricksConfig setOidcTokenEnv(String oidcTokenEnv) {
return this;
}

public Boolean getEnableExperimentalAsyncTokenRefresh() {
return enableExperimentalAsyncTokenRefresh;
}

public DatabricksConfig setEnableExperimentalAsyncTokenRefresh(
Boolean enableExperimentalAsyncTokenRefresh) {
this.enableExperimentalAsyncTokenRefresh = enableExperimentalAsyncTokenRefresh;
return this;
}

public boolean isAzure() {
if (azureWorkspaceResourceId != null) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public OAuthHeaderFactory configure(DatabricksConfig config) {
return null;
}

TokenSource tokenSource =
OidcTokenSource tokenSource =
new OidcTokenSource(
config.getHttpClient(),
config.getDatabricksEnvironment().getAzureEnvironment().getActiveDirectoryEndpoint()
Expand All @@ -47,6 +47,7 @@ public OAuthHeaderFactory configure(DatabricksConfig config) {
idToken.get(),
"urn:ietf:params:oauth:client-assertion-type:jwt-bearer");

tokenSource.withAsyncRefresh(config.getEnableExperimentalAsyncTokenRefresh());
return OAuthHeaderFactory.fromTokenSource(tokenSource);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ public OAuthHeaderFactory configure(DatabricksConfig config) {
|| config.getAzureTenantId() == null) {
return null;
}

AzureUtils.ensureHostPresent(
config, mapper, AzureServicePrincipalCredentialsProvider::tokenSourceFor);

RefreshableTokenSource inner = tokenSourceFor(config, config.getEffectiveAzureLoginAppId());
inner.withAsyncRefresh(config.getEnableExperimentalAsyncTokenRefresh());
RefreshableTokenSource cloud =
tokenSourceFor(config, config.getAzureEnvironment().getServiceManagementEndpoint());
cloud.withAsyncRefresh(config.getEnableExperimentalAsyncTokenRefresh());

return OAuthHeaderFactory.fromSuppliers(
inner::getToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public OAuthHeaderFactory configure(DatabricksConfig config) {
.withAuthParameterPosition(AuthParameterPosition.HEADER)
.build();

tokenSource.withAsyncRefresh(config.getEnableExperimentalAsyncTokenRefresh());
return OAuthHeaderFactory.fromTokenSource(tokenSource);
} catch (IOException e) {
// TODO: Log exception
Expand Down
Loading
Loading