Skip to content

Commit

Permalink
TestCommon: Add DatabricksSchemaManager extensions (#326)
Browse files Browse the repository at this point in the history
* Bump Microsoft.Identity (it was vulnerable)

* Release notes and version

* InsertFromCsvFileAsync

* Bump NuGet packages

* Bump Azurite version

* Update source/TestCommon/source/FunctionApp.TestCommon/Databricks/DatabricksSchemaManagerExtensions.cs

Co-authored-by: Ebbe Knudsen <xedkn@energinet.dk>

* Update source/TestCommon/source/FunctionApp.TestCommon/Databricks/DatabricksSchemaManagerExtensions.cs

Co-authored-by: Ebbe Knudsen <xedkn@energinet.dk>

* Update source/TestCommon/source/FunctionApp.TestCommon/Databricks/DatabricksSchemaManagerExtensions.cs

Co-authored-by: Ebbe Knudsen <xedkn@energinet.dk>

* Update source/TestCommon/source/FunctionApp.TestCommon/Databricks/DatabricksSchemaManagerExtensions.cs

Co-authored-by: Ebbe Knudsen <xedkn@energinet.dk>

* Rename

---------

Co-authored-by: Ebbe Knudsen <xedkn@energinet.dk>
  • Loading branch information
dstenroejl and ebbeknudsen authored Jun 27, 2024
1 parent f66b07a commit d8b086d
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 19 deletions.
1 change: 1 addition & 0 deletions .github/workflows/testcommon-bundle-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ jobs:
uses: Energinet-DataHub/.github/.github/actions/dotnet-setup-and-tools@v13
with:
use_azure_functions_tools: "true"
azurite_version: 3.31.0

- name: Build and test solution
uses: Energinet-DataHub/.github/.github/actions/dotnet-solution-build-and-test@v13
Expand Down
5 changes: 5 additions & 0 deletions source/TestCommon/documents/release-notes/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# TestCommon Release notes

## Version 5.3.0

- Added extensions to class `DatabricksSchemaManager`:
- Method `InsertFromCsvFileAsync`

## Version 5.2.1

- Extended `IntegrationTestConfiguration` with the option to pass in `DefaultAzureCredential` from the outside.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ limitations under the License.

<ItemGroup>
<PackageReference Include="Azure.Data.Tables" Version="12.8.3" />
<PackageReference Include="Azure.Identity" Version="1.11.0" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageReference Include="Azure.Storage.Queues" Version="12.17.1" />
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.20.0" />
<PackageReference Include="Azure.Storage.Queues" Version="12.18.0" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="xunit" Version="2.7.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.8">
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2020 Energinet DataHub A/S
//
// Licensed under the Apache License, Version 2.0 (the "License2");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System.Globalization;
using CsvHelper;

namespace Energinet.DataHub.Core.FunctionApp.TestCommon.Databricks;

public static class DatabricksSchemaManagerExtensions
{
public const string DeltaTableArrayOfStrings = "ARRAY<STRING>";

/// <summary>
/// Expects a CSV file which was exported from Databricks.
/// The header must contain the column names and each row must contain the delta table values per column.
/// Delta table arrays must be parsed differently, but otherwise all values can be parsed from the CSV into strings.
/// All parsed rows are then inserted into a delta table.
/// </summary>
public static async Task InsertFromCsvFileAsync(
this DatabricksSchemaManager schemaManager,
string tableName,
Dictionary<string, (string DataType, bool IsNullable)> columnDefinitions,
string csvFilePath)
{
using (var streamReader = new StreamReader(csvFilePath))
using (var csvReader = new CsvReader(streamReader, CultureInfo.InvariantCulture))
{
await csvReader.ReadAsync().ConfigureAwait(false);
csvReader.ReadHeader();

if (csvReader.HeaderRecord == null)
throw new InvalidOperationException("First row of CSV file must contain header information.");

var rows = new List<string[]>();
while (await csvReader.ReadAsync().ConfigureAwait(false))
{
var row = new string[csvReader.HeaderRecord.Length];
for (var columnIndex = 0; columnIndex < csvReader.ColumnCount; columnIndex++)
{
row[columnIndex] = ParseColumnValue(columnDefinitions, csvReader, columnIndex);
}

rows.Add(row);
}

await schemaManager.InsertAsync(tableName, csvReader.HeaderRecord, rows).ConfigureAwait(false);
}
}

/// <summary>
/// Parse CSV column value into a delta table "insertable" value.
/// Only arrays require special handling; all other values can be inserted as "strings".
/// </summary>
private static string ParseColumnValue(
Dictionary<string, (string DataType, bool IsNullable)> columnDefinitions,
CsvReader csvReader,
int columnIndex)
{
var columnName = csvReader.HeaderRecord![columnIndex];
var columnValue = csvReader.GetField(columnIndex);

if (columnDefinitions[columnName].IsNullable && columnValue == string.Empty)
{
return "NULL";
}

if (columnDefinitions[columnName].DataType == DeltaTableArrayOfStrings)
{
var arrayContent = columnValue!
.Replace('[', '(')
.Replace(']', ')');

return $"Array{arrayContent}";
}

return $"'{columnValue}'";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ limitations under the License.

<PropertyGroup>
<PackageId>Energinet.DataHub.Core.FunctionApp.TestCommon</PackageId>
<PackageVersion>5.2.1$(VersionSuffix)</PackageVersion>
<PackageVersion>5.3.0$(VersionSuffix)</PackageVersion>
<Title>FunctionApp TestCommon library</Title>
<Company>Energinet-DataHub</Company>
<Authors>Energinet-DataHub</Authors>
Expand Down Expand Up @@ -80,13 +80,14 @@ limitations under the License.

<ItemGroup>
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.1" />
<PackageReference Include="Azure.Identity" Version="1.11.0" />
<PackageReference Include="Azure.Messaging.EventHubs.Processor" Version="5.11.2" />
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Azure.Messaging.EventHubs.Processor" Version="5.11.3" />
<PackageReference Include="Azure.Messaging.ServiceBus" Version="7.17.5" />
<PackageReference Include="Azure.Messaging.EventHubs" Version="5.11.2" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageReference Include="Azure.Messaging.EventHubs" Version="5.11.3" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.20.0" />
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="Microsoft.Azure.Management.EventHub" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
Expand All @@ -97,10 +98,10 @@ limitations under the License.
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
<PackageReference Include="Polly" Version="8.3.1" />
<PackageReference Include="Polly" Version="8.4.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="System.Management" Version="8.0.0" />
<PackageReference Include="xunit" Version="2.7.1" />
<PackageReference Include="xunit" Version="2.8.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ limitations under the License.

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="xunit" Version="2.7.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.8">
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
4 changes: 2 additions & 2 deletions source/TestCommon/source/TestCommon/TestCommon.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ limitations under the License.

<PropertyGroup>
<PackageId>Energinet.DataHub.Core.TestCommon</PackageId>
<PackageVersion>5.2.1$(VersionSuffix)</PackageVersion>
<PackageVersion>5.3.0$(VersionSuffix)</PackageVersion>
<Title>TestCommon library</Title>
<Company>Energinet-DataHub</Company>
<Authors>Energinet-DataHub</Authors>
Expand Down Expand Up @@ -83,7 +83,7 @@ limitations under the License.
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="xunit" Version="2.7.1" />
<PackageReference Include="xunit" Version="2.8.1" />
</ItemGroup>

</Project>

0 comments on commit d8b086d

Please sign in to comment.