Skip to content

Commit c879465

Browse files
committed
Add HostType to HostMetadata
Signed-off-by: Tanmay Rustagi <tanmay.rustagi@databricks.com>
1 parent f3156e2 commit c879465

File tree

5 files changed

+186
-1
lines changed

5 files changed

+186
-1
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ public class DatabricksConfig {
162162

163163
private DatabricksEnvironment databricksEnvironment;
164164

165+
/**
166+
* The host type resolved from the /.well-known/databricks-config discovery endpoint. When set,
167+
* this takes priority over URL-based host type detection in {@link #getHostType()}.
168+
*/
169+
private HostType resolvedHostType;
170+
165171
/**
166172
* When using Workload Identity Federation, the audience to specify when fetching an ID token from
167173
* the ID token supplier.
@@ -723,6 +729,17 @@ public DatabricksConfig setDisableOauthRefreshToken(boolean disable) {
723729
return this;
724730
}
725731

732+
/** Returns the host type resolved from host metadata, or {@code null} if not yet resolved. */
733+
HostType getResolvedHostType() {
734+
return resolvedHostType;
735+
}
736+
737+
/** Sets the resolved host type. Package-private for testing. */
738+
DatabricksConfig setResolvedHostType(HostType resolvedHostType) {
739+
this.resolvedHostType = resolvedHostType;
740+
return this;
741+
}
742+
726743
public boolean isAzure() {
727744
if (azureWorkspaceResourceId != null) {
728745
return true;
@@ -889,6 +906,13 @@ void resolveHostMetadata() throws IOException {
889906
LOG.debug("Resolved workspace_id from host metadata: \"{}\"", meta.getWorkspaceId());
890907
workspaceId = meta.getWorkspaceId();
891908
}
909+
if (resolvedHostType == null && meta.getHostType() != null) {
910+
HostType ht = HostType.fromApiValue(meta.getHostType());
911+
if (ht != null) {
912+
LOG.debug("Resolved host_type from host metadata: \"{}\"", ht);
913+
resolvedHostType = ht;
914+
}
915+
}
892916
if (discoveryUrl == null) {
893917
if (meta.getOidcEndpoint() == null || meta.getOidcEndpoint().isEmpty()) {
894918
LOG.warn("Host metadata missing oidc_endpoint; skipping discovery URL resolution");

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,25 @@ public enum HostType {
1212
ACCOUNTS,
1313

1414
/** Unified host supporting both workspace and account operations. */
15-
UNIFIED
15+
UNIFIED;
16+
17+
/**
18+
* Converts an API-level host type string (e.g. "workspace", "account", "unified") to the
19+
* corresponding enum value. Returns {@code null} for unknown or empty values.
20+
*/
21+
public static HostType fromApiValue(String value) {
22+
if (value == null || value.isEmpty()) {
23+
return null;
24+
}
25+
switch (value.toLowerCase()) {
26+
case "workspace":
27+
return WORKSPACE;
28+
case "account":
29+
return ACCOUNTS;
30+
case "unified":
31+
return UNIFIED;
32+
default:
33+
return null;
34+
}
35+
}
1636
}

databricks-sdk-java/src/main/java/com/databricks/sdk/core/oauth/HostMetadata.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public class HostMetadata {
2323
@JsonProperty("cloud")
2424
private String cloud;
2525

26+
@JsonProperty("host_type")
27+
private String hostType;
28+
2629
public HostMetadata() {}
2730

2831
public HostMetadata(String oidcEndpoint, String accountId, String workspaceId) {
@@ -53,4 +56,8 @@ public String getWorkspaceId() {
5356
public String getCloud() {
5457
return cloud;
5558
}
59+
60+
public String getHostType() {
61+
return hostType;
62+
}
5663
}

databricks-sdk-java/src/test/java/com/databricks/sdk/core/DatabricksConfigTest.java

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,94 @@ public void testEnsureResolvedHostMetadataMissingAccountIdWithPlaceholderNonFata
712712
}
713713
}
714714

715+
// --- resolveHostMetadata host type tests ---
716+
717+
@Test
718+
public void testResolveHostMetadataPopulatesResolvedHostType() throws IOException {
719+
String response =
720+
"{\"oidc_endpoint\":\"https://ws.databricks.com/oidc\","
721+
+ "\"account_id\":\""
722+
+ DUMMY_ACCOUNT_ID
723+
+ "\","
724+
+ "\"host_type\":\"workspace\"}";
725+
try (FixtureServer server =
726+
new FixtureServer().with("GET", "/.well-known/databricks-config", response, 200)) {
727+
DatabricksConfig config = new DatabricksConfig().setHost(server.getUrl());
728+
config.resolve(emptyEnv());
729+
config.resolveHostMetadata();
730+
assertEquals(HostType.WORKSPACE, config.getResolvedHostType());
731+
}
732+
}
733+
734+
@Test
735+
public void testResolveHostMetadataDoesNotOverwriteExistingHostType() throws IOException {
736+
String response =
737+
"{\"oidc_endpoint\":\"https://ws.databricks.com/oidc\","
738+
+ "\"account_id\":\""
739+
+ DUMMY_ACCOUNT_ID
740+
+ "\","
741+
+ "\"host_type\":\"workspace\"}";
742+
try (FixtureServer server =
743+
new FixtureServer().with("GET", "/.well-known/databricks-config", response, 200)) {
744+
DatabricksConfig config = new DatabricksConfig().setHost(server.getUrl());
745+
config.resolve(emptyEnv());
746+
config.setResolvedHostType(HostType.UNIFIED);
747+
config.resolveHostMetadata();
748+
assertEquals(HostType.UNIFIED, config.getResolvedHostType());
749+
}
750+
}
751+
752+
@Test
753+
public void testResolveHostMetadataUnknownHostTypeIgnored() throws IOException {
754+
String response =
755+
"{\"oidc_endpoint\":\"https://ws.databricks.com/oidc\","
756+
+ "\"account_id\":\""
757+
+ DUMMY_ACCOUNT_ID
758+
+ "\","
759+
+ "\"host_type\":\"unknown_value\"}";
760+
try (FixtureServer server =
761+
new FixtureServer().with("GET", "/.well-known/databricks-config", response, 200)) {
762+
DatabricksConfig config = new DatabricksConfig().setHost(server.getUrl());
763+
config.resolve(emptyEnv());
764+
config.resolveHostMetadata();
765+
assertNull(config.getResolvedHostType());
766+
}
767+
}
768+
769+
@Test
770+
public void testResolveHostMetadataHostTypeAccount() throws IOException {
771+
String response =
772+
"{\"oidc_endpoint\":\"https://ws.databricks.com/oidc\","
773+
+ "\"account_id\":\""
774+
+ DUMMY_ACCOUNT_ID
775+
+ "\","
776+
+ "\"host_type\":\"account\"}";
777+
try (FixtureServer server =
778+
new FixtureServer().with("GET", "/.well-known/databricks-config", response, 200)) {
779+
DatabricksConfig config = new DatabricksConfig().setHost(server.getUrl());
780+
config.resolve(emptyEnv());
781+
config.resolveHostMetadata();
782+
assertEquals(HostType.ACCOUNTS, config.getResolvedHostType());
783+
}
784+
}
785+
786+
@Test
787+
public void testResolveHostMetadataHostTypeUnified() throws IOException {
788+
String response =
789+
"{\"oidc_endpoint\":\"https://ws.databricks.com/oidc\","
790+
+ "\"account_id\":\""
791+
+ DUMMY_ACCOUNT_ID
792+
+ "\","
793+
+ "\"host_type\":\"unified\"}";
794+
try (FixtureServer server =
795+
new FixtureServer().with("GET", "/.well-known/databricks-config", response, 200)) {
796+
DatabricksConfig config = new DatabricksConfig().setHost(server.getUrl());
797+
config.resolve(emptyEnv());
798+
config.resolveHostMetadata();
799+
assertEquals(HostType.UNIFIED, config.getResolvedHostType());
800+
}
801+
}
802+
715803
// --- discoveryUrl / OIDC endpoint tests ---
716804

717805
@Test
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.databricks.sdk.core;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class HostTypeTest {
8+
9+
@Test
10+
public void testFromApiValueWorkspace() {
11+
assertEquals(HostType.WORKSPACE, HostType.fromApiValue("workspace"));
12+
}
13+
14+
@Test
15+
public void testFromApiValueAccount() {
16+
assertEquals(HostType.ACCOUNTS, HostType.fromApiValue("account"));
17+
}
18+
19+
@Test
20+
public void testFromApiValueUnified() {
21+
assertEquals(HostType.UNIFIED, HostType.fromApiValue("unified"));
22+
}
23+
24+
@Test
25+
public void testFromApiValueCaseInsensitive() {
26+
assertEquals(HostType.WORKSPACE, HostType.fromApiValue("WORKSPACE"));
27+
assertEquals(HostType.ACCOUNTS, HostType.fromApiValue("Account"));
28+
assertEquals(HostType.UNIFIED, HostType.fromApiValue("UNIFIED"));
29+
}
30+
31+
@Test
32+
public void testFromApiValueNull() {
33+
assertNull(HostType.fromApiValue(null));
34+
}
35+
36+
@Test
37+
public void testFromApiValueEmpty() {
38+
assertNull(HostType.fromApiValue(""));
39+
}
40+
41+
@Test
42+
public void testFromApiValueUnknown() {
43+
assertNull(HostType.fromApiValue("unknown"));
44+
assertNull(HostType.fromApiValue("something_else"));
45+
}
46+
}

0 commit comments

Comments
 (0)