Skip to content

Commit 8f852e9

Browse files
authored
fix(csharp/src): handle HTTP authorization exception for Thrift-based drivers (apache#3551)
C# Thrift-based drivers using HTTP transport don't throw AdbcException with AdbcStatusCode of Unauthorized. As a best practice, drivers should indicate if the connection encountered an authentication or authorization error when attempting to open. Connection should throw an AdbcException with Status == AdbcStatusCode.Unauthorized. This handles all Apache (Hive, Impala, Spark) and Databricks drivers that use HTTP transport. Notes: * required an update to Thrift version 0.22.0 (then also System.Text.Json 9.0.0) closes apache#3550
1 parent ad2b150 commit 8f852e9

File tree

10 files changed

+39
-8
lines changed

10 files changed

+39
-8
lines changed

csharp/src/Apache.Arrow.Adbc/AdbcException.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public AdbcException(string message, AdbcStatusCode statusCode)
4444
public AdbcException(string message, AdbcStatusCode statusCode, Exception innerException)
4545
: base(message, innerException)
4646
{
47+
_statusCode = statusCode;
4748
}
4849

4950
public AdbcException(string message, Exception innerException)

csharp/src/Apache.Arrow.Adbc/Apache.Arrow.Adbc.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
@@ -10,7 +10,7 @@
1010
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="9.0.6" />
1111
</ItemGroup>
1212
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net6.0'))">
13-
<PackageReference Include="System.Text.Json" Version="8.0.5" />
13+
<PackageReference Include="System.Text.Json" Version="9.0.9" />
1414
</ItemGroup>
1515
<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net6.0'))">
1616
<Compile Remove="C\NativeLibrary.cs" />

csharp/src/Drivers/Apache/Apache.Arrow.Adbc.Drivers.Apache.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="ApacheThrift" Version="0.21.0" />
8+
<PackageReference Include="ApacheThrift" Version="0.22.0" />
99
</ItemGroup>
1010
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net6.0'))">
1111
<PackageReference Include="System.Net.Http" Version="4.3.4" />
12-
<PackageReference Include="System.Text.Json" Version="8.0.5" />
12+
<PackageReference Include="System.Text.Json" Version="9.0.9" />
1313
</ItemGroup>
1414

1515
<ItemGroup>

csharp/src/Drivers/Apache/Hive2/HiveServer2Connection.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
using System.Diagnostics;
2121
using System.Diagnostics.CodeAnalysis;
2222
using System.Linq;
23+
using System.Net;
24+
using System.Net.Http;
2325
using System.Reflection;
2426
using System.Text;
2527
using System.Text.RegularExpressions;
@@ -356,6 +358,11 @@ await this.TraceActivity(async activity =>
356358
{
357359
session = await Client.OpenSession(request, cancellationToken);
358360
}
361+
catch (TTransportException transportEx)
362+
when (ApacheUtility.ContainsException(transportEx, out HttpRequestException? httpEx) && IsUnauthorized(httpEx!))
363+
{
364+
throw new HiveServer2Exception(transportEx.Message, AdbcStatusCode.Unauthorized, transportEx);
365+
}
359366
catch (Exception)
360367
{
361368
if (FallbackProtocolVersions.Any())
@@ -381,6 +388,15 @@ await this.TraceActivity(async activity =>
381388
});
382389
}
383390

391+
private static bool IsUnauthorized(HttpRequestException httpEx)
392+
{
393+
#if NET5_0_OR_GREATER
394+
return httpEx.StatusCode == HttpStatusCode.Unauthorized;
395+
#else
396+
return httpEx.Message.IndexOf("unauthorized", StringComparison.OrdinalIgnoreCase) >= 0 || httpEx.Message.IndexOf("authenticat", StringComparison.OrdinalIgnoreCase) >= 0;
397+
#endif
398+
}
399+
384400
private async Task<TOpenSessionResp?> TryOpenSessionWithFallbackAsync(TOpenSessionReq originalRequest, CancellationToken cancellationToken)
385401
{
386402
Exception? lastException = null;
@@ -405,6 +421,11 @@ await this.TraceActivity(async activity =>
405421
{
406422
throw new TimeoutException("The operation timed out while attempting to open a session. Please try increasing connect timeout.", ex);
407423
}
424+
catch (TTransportException transportEx)
425+
when (ApacheUtility.ContainsException(transportEx, out HttpRequestException? httpEx) && IsUnauthorized(httpEx!))
426+
{
427+
throw new HiveServer2Exception(transportEx.Message, AdbcStatusCode.Unauthorized, transportEx);
428+
}
408429
catch (Exception ex)
409430
{
410431
lastException = ex;

csharp/src/Drivers/BigQuery/Apache.Arrow.Adbc.Drivers.BigQuery.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<PackageReference Include="Google.Cloud.BigQuery.V2" Version="3.11.0" />
1010
</ItemGroup>
1111
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net6.0'))">
12-
<PackageReference Include="System.Text.Json" Version="8.0.5" />
12+
<PackageReference Include="System.Text.Json" Version="9.0.9" />
1313
</ItemGroup>
1414
<ItemGroup>
1515
<ProjectReference Include="..\..\Apache.Arrow.Adbc\Apache.Arrow.Adbc.csproj" />

csharp/src/Telemetry/Traces/Listeners/Apache.Arrow.Adbc.Telemetry.Traces.Listeners.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
@@ -7,7 +7,7 @@
77

88
<ItemGroup>
99
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="9.0.6" />
10-
<PackageReference Include="System.Text.Json" Version="8.0.5" />
10+
<PackageReference Include="System.Text.Json" Version="9.0.9" />
1111
<PackageReference Include="System.Threading.Channels" Version="9.0.8" />
1212
</ItemGroup>
1313

csharp/test/Apache.Arrow.Adbc.Tests/Apache.Arrow.Adbc.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<PackageReference Include="Moq" Version="4.20.72" />
1414
<PackageReference Include="OpenTelemetry" Version="1.12.0" />
1515
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="9.0.6" />
16-
<PackageReference Include="System.Text.Json" Version="8.0.5" />
16+
<PackageReference Include="System.Text.Json" Version="9.0.9" />
1717
<PackageReference Include="xunit" Version="2.9.3" />
1818
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
1919
<PrivateAssets>all</PrivateAssets>

csharp/test/Drivers/Apache/Hive2/DriverTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
using System;
1919
using System.Collections.Generic;
20+
using Apache.Arrow.Adbc.Drivers.Apache;
2021
using Apache.Arrow.Adbc.Drivers.Apache.Hive2;
2122
using Xunit;
2223
using Xunit.Abstractions;
@@ -96,6 +97,8 @@ public override void CanDetectInvalidAuthentication()
9697

9798
AdbcDatabase database = driver.Open(parameters);
9899
AggregateException exception = Assert.ThrowsAny<AggregateException>(() => database.Connect(parameters));
100+
Assert.True(ApacheUtility.ContainsException(exception, out AdbcException? adbcException), $"Expect AdbcException. Actual type: {exception.GetType().Name}");
101+
Assert.Equal(AdbcStatusCode.Unauthorized, adbcException!.Status);
99102
OutputHelper?.WriteLine(exception.Message);
100103
}
101104

csharp/test/Drivers/Apache/Impala/DriverTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
using System;
1919
using System.Collections.Generic;
20+
using Apache.Arrow.Adbc.Drivers.Apache;
2021
using Apache.Arrow.Adbc.Drivers.Apache.Impala;
2122
using Apache.Arrow.Adbc.Tests.Metadata;
2223
using Xunit;
@@ -75,6 +76,8 @@ public override void CanDetectInvalidServer()
7576

7677
AdbcDatabase database = driver.Open(parameters);
7778
AggregateException exception = Assert.ThrowsAny<AggregateException>(() => database.Connect(parameters));
79+
Assert.True(ApacheUtility.ContainsException(exception, out AdbcException? adbcException), $"Expect AdbcException. Actual type: {exception.GetType().Name}");
80+
Assert.Equal(AdbcStatusCode.Unauthorized, adbcException!.Status);
7881
OutputHelper?.WriteLine(exception.Message);
7982
}
8083

csharp/test/Drivers/Databricks/E2E/DriverTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using System;
1919
using System.Collections.Generic;
2020
using System.Threading.Tasks;
21+
using Apache.Arrow.Adbc.Drivers.Apache;
2122
using Apache.Arrow.Adbc.Drivers.Apache.Spark;
2223
using Apache.Arrow.Adbc.Tests.Drivers.Apache.Common;
2324
using Xunit;
@@ -130,6 +131,8 @@ public override void CanDetectInvalidAuthentication()
130131

131132
AdbcDatabase database = driver.Open(parameters);
132133
AggregateException exception = Assert.ThrowsAny<AggregateException>(() => database.Connect(parameters));
134+
Assert.True(ApacheUtility.ContainsException(exception, out AdbcException? adbcException), $"Expect AdbcException. Actual type: {exception.GetType().Name}");
135+
Assert.Equal(AdbcStatusCode.Unauthorized, adbcException!.Status);
133136
OutputHelper?.WriteLine(exception.Message);
134137
}
135138

0 commit comments

Comments
 (0)