Skip to content

Commit ac7bb09

Browse files
committed
implement cache for access token
1 parent 52f3818 commit ac7bb09

File tree

1 file changed

+44
-17
lines changed

1 file changed

+44
-17
lines changed

packages/cubejs-databricks-jdbc-driver/src/DatabricksDriver.ts

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ export class DatabricksDriver extends JDBCDriver {
162162

163163
private readonly parsedConnectionProperties: ParsedConnectionProperties;
164164

165+
private accessToken: string | undefined;
166+
167+
private accessTokenExpires: number = 0;
168+
165169
public static dialectClass() {
166170
return DatabricksQuery;
167171
}
@@ -332,29 +336,52 @@ export class DatabricksDriver extends JDBCDriver {
332336
this.showDeprecations();
333337
}
334338

339+
private async fetchAccessToken(): Promise<void> {
340+
// Need to exchange client ID + Secret => Access token
341+
342+
const basicAuth = Buffer.from(`${this.config.properties.OAuth2ClientID}:${this.config.properties.OAuth2Secret}`).toString('base64');
343+
344+
const res = await fetch(`https://${this.parsedConnectionProperties.host}/oidc/v1/token`, {
345+
method: 'POST',
346+
headers: {
347+
Authorization: `Basic ${basicAuth}`,
348+
'Content-Type': 'application/x-www-form-urlencoded',
349+
},
350+
body: new URLSearchParams({
351+
grant_type: 'client_credentials',
352+
scope: 'all-apis',
353+
}),
354+
});
355+
356+
if (!res.ok) {
357+
throw new Error(`Failed to get access token: ${res.statusText}`);
358+
}
359+
360+
const resp = await res.json();
361+
362+
this.accessToken = resp.access_token;
363+
this.accessTokenExpires = Date.now() + resp.expires_in * 1000 - 60_000;
364+
}
365+
366+
private async getValidAccessToken(): Promise<string> {
367+
if (
368+
!this.accessToken ||
369+
!this.accessTokenExpires ||
370+
Date.now() >= this.accessTokenExpires
371+
) {
372+
await this.fetchAccessToken();
373+
}
374+
return this.accessToken!;
375+
}
376+
335377
public override async testConnection() {
336378
let token: string;
337379

338380
// Databricks docs on accessing REST API
339381
// https://docs.databricks.com/aws/en/dev-tools/auth/oauth-m2m
340382
if (this.config.properties.OAuth2Secret) {
341-
// Need to exchange client ID + Secret => Access token
342-
343-
const basicAuth = Buffer.from(`${this.config.properties.OAuth2ClientID}:${this.config.properties.OAuth2Secret}`).toString('base64');
344-
345-
const res = await fetch(`https://${this.parsedConnectionProperties.host}/oidc/v1/token`, {
346-
method: 'POST',
347-
headers: {
348-
Authorization: `Basic ${basicAuth}`,
349-
'Content-Type': 'application/x-www-form-urlencoded',
350-
},
351-
body: new URLSearchParams({
352-
grant_type: 'client_credentials',
353-
scope: 'all-apis',
354-
}),
355-
});
356-
const resp = await res.json();
357-
token = resp.access_token;
383+
const at = await this.getValidAccessToken();
384+
token = `Bearer ${at}`;
358385
} else {
359386
token = `Bearer ${this.config.properties.PWD}`;
360387
}

0 commit comments

Comments
 (0)