We use Java 8
and msal4j
version 0.6.0-preview
. To connect to Kusto, we use JWT Token:
ConnectionStringBuilder csb = ConnectionStringBuilder.createWithAadAccessTokenAuthentication(resourceUri, accessToken);
Client kustoClient = ClientFactory.createClient(csb);
Inside thencreateWithAadAccessTokenAuthentication()
, it is calling this ConnectionStringBuilder
constructor:
public static ConnectionStringBuilder createWithAadAccessTokenAuthentication(String resourceUri, String token) {
if (StringUtils.isEmpty(resourceUri)) {
throw new IllegalArgumentException("resourceUri cannot be null or empty");
} else if (StringUtils.isEmpty(token)) {
throw new IllegalArgumentException("token cannot be null or empty");
} else {
ConnectionStringBuilder csb = new ConnectionStringBuilder(resourceUri);
csb.accessToken = token;
return csb;
}
}
it is setting every field to null
except for clusterUri
.
private ConnectionStringBuilder(String resourceUri) {
this.clusterUri = resourceUri;
this.usernameHint = null;
this.applicationClientId = null;
this.applicationKey = null;
this.aadAuthorityId = null;
this.x509Certificate = null;
this.privateKey = null;
this.accessToken = null;
this.tokenProvider = null;
}
Thus we got an error from createClient()
method. Because it is calling ClientImpl(csb)
. host
and auth
are returning null, which triggers null pointer exception in this line: String auth = clusterUri.getAuthority().toLowerCase();
public static Client createClient(ConnectionStringBuilder csb) throws URISyntaxException {
return new ClientImpl(csb);
}
public ClientImpl(ConnectionStringBuilder csb) throws URISyntaxException {
String url = csb.getClusterUrl();
URI clusterUri = new URI(url);
String host = clusterUri.getHost();
String auth = clusterUri.getAuthority().toLowerCase();
if (host == null && auth.endsWith(";fed=true")) {
url = (new URIBuilder()).setScheme(clusterUri.getScheme()).setHost(auth.substring(0, clusterUri.getAuthority().indexOf(";fed=true"))).toString();
csb.setClusterUrl(url);
}
this.clusterUrl = url;
this.aadAuthenticationHelper = TokenProviderFactory.createTokenProvider(csb);
this.clientVersionForTracing = "Kusto.Java.Client";
String version = Utils.getPackageVersion();
if (StringUtils.isNotBlank(version)) {
this.clientVersionForTracing = this.clientVersionForTracing + ":" + version;
}
if (StringUtils.isNotBlank(csb.getClientVersionForTracing())) {
this.clientVersionForTracing = this.clientVersionForTracing + "[" + csb.getClientVersionForTracing() + "]";
}
this.applicationNameForTracing = csb.getApplicationNameForTracing();
}
What are the other alternatives here?
After talking F2F we found the issue is with the value passed in the resourceUri param, while this expects a url of the cluster ("https://cluster.region.kusto.windows.net") the provided uri was the ARM resource uri hence no host and no auth sections of the URL were parsed by the call to new URI().