Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
package com.microsoft.azure.kusto.ingest.v2;

import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.TokenRequestContext;
import com.azure.identity.AzureCliCredentialBuilder;
import reactor.core.publisher.Mono;

/**
* Test-only credential: calls {@code az} once at class load, reuses the token forever.
*/
public class CachingTokenCredential implements TokenCredential {

private static final AccessToken TOKEN;

static {
// Runs once on main thread before any reactor threads — .block() is safe here.
TOKEN = new AzureCliCredentialBuilder().build()
.getToken(new TokenRequestContext().addScopes("https://kusto.kusto.windows.net/.default"))
.block();
}

public static final TokenCredential INSTANCE = new CachingTokenCredential();

@Override
public Mono<AccessToken> getToken(TokenRequestContext request) {
return Mono.just(TOKEN);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package com.microsoft.azure.kusto.ingest.v2;

import com.azure.core.credential.TokenCredential;
import com.azure.identity.AzureCliCredentialBuilder;
import com.microsoft.azure.kusto.data.Client;
import com.microsoft.azure.kusto.data.ClientFactory;
import com.microsoft.azure.kusto.data.KustoResultSetTable;
Expand Down Expand Up @@ -40,7 +39,8 @@ public abstract class IngestV2JavaTestBase {

public IngestV2JavaTestBase(Class<?> testClass) {
this.logger = LoggerFactory.getLogger(testClass);
this.tokenProvider = new AzureCliCredentialBuilder().build();
// Reuse the shared CachingTokenCredential singleton to prevent multiple concurrent requests to fetch token from azcli
this.tokenProvider = CachingTokenCredential.INSTANCE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This token provider here can be AzureCliTokenProvider perhaps , initialized once


// Get configuration from environment variables
this.database = System.getenv("TEST_DATABASE") != null
Expand Down Expand Up @@ -116,9 +116,10 @@ public void createTables() throws Exception {
}
mappingBuilder.append("\n]```");

// Create admin client
// Create admin client using the shared CachingTokenCredential to prevent
// concurrent az subprocess invocations from parallel test threads
adminClusterClient = ClientFactory.createClient(
ConnectionStringBuilder.createWithAzureCli(engineEndpoint)
ConnectionStringBuilder.createWithTokenCredential(engineEndpoint, tokenProvider)
);

// Execute table creation and mapping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
package com.microsoft.azure.kusto.ingest.v2

import com.azure.core.credential.TokenCredential
import com.azure.identity.AzureCliCredentialBuilder
import com.microsoft.azure.kusto.data.Client
import com.microsoft.azure.kusto.data.ClientFactory
import com.microsoft.azure.kusto.data.auth.ConnectionStringBuilder
Expand All @@ -21,8 +20,11 @@ import kotlin.test.assertTrue

abstract class IngestV2TestBase(testClass: Class<*>) {
protected val logger: Logger = LoggerFactory.getLogger(testClass)
protected val tokenProvider: TokenCredential =
AzureCliCredentialBuilder().build()

// Shared across all test class instances via CachingTokenCredential singleton.
// Ensures az account get-access-token is invoked only once per scope.
protected val tokenProvider: TokenCredential = CachingTokenCredential.INSTANCE

protected val database = System.getenv("TEST_DATABASE") ?: "e2e"
protected val dmEndpoint: String =
System.getenv("DM_CONNECTION_STRING")
Expand Down Expand Up @@ -75,8 +77,9 @@ abstract class IngestV2TestBase(testClass: Class<*>) {
.trimIndent()
adminClusterClient =
ClientFactory.createClient(
ConnectionStringBuilder.createWithAzureCli(
ConnectionStringBuilder.createWithTokenCredential(
engineEndpoint,
tokenProvider,
),
)
adminClusterClient.executeMgmt(database, createTableScript)
Expand Down Expand Up @@ -157,4 +160,4 @@ abstract class IngestV2TestBase(testClass: Class<*>) {
)
}
}
}
}
Loading