Skip to content

Commit

Permalink
Bump to .NET8 and align code structure for Databricks (#290)
Browse files Browse the repository at this point in the history
* Add Directory.Build.props and .editorconfig file for Databricks project

* Update target framework and language version

* Remove unused using statements

* Fix warnings in DatabricksStatementResponse.cs

* Fix file-scope namespace and .ConfigureAwait()

* Remove unused packages

* Bump target framework to .NET8

* Remove unused rules from .editorconfig

* Update async/await configuration in DatabricksSqlWarehouseQueryExecutor.cs

* Add missing ConfigureAwait()

Co-authored-by: Dan Stenrøjl <51327761+dstenroejl@users.noreply.github.com>

* Add missing .ConfigureAwait(false)

---------

Co-authored-by: Dan Stenrøjl <51327761+dstenroejl@users.noreply.github.com>
  • Loading branch information
Sondergaard and dstenroejl authored Mar 11, 2024
1 parent dd5bd50 commit 7c9cd10
Show file tree
Hide file tree
Showing 35 changed files with 880 additions and 356 deletions.
538 changes: 538 additions & 0 deletions source/Databricks/.editorconfig

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions source/Databricks/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
<!-- RunAnalyzersDuringXxx: https://learn.microsoft.com/en-us/visualstudio/code-quality/disable-code-analysis?view=vs-2022#net-framework-projects -->
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
<RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>
<!-- EnforceCodeStyleInBuild: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/overview?tabs=net-8#enable-on-build -->
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<!--
Add stylecop for all projects (so long as they don't override Directory.Build.props) with a common ruleset.
See also: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2019#search-scope
-->
<ItemGroup>
<!--
IMPORTANT: Do NOT add NuGet package dependencies in this file, except for "StyleCop.Analyzers".
-->
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

<!--
Additional settings for specific rules (e.g. SA1200 specify namespaces must be placed correctly, the json file then defines what "correctly" means)
See also [stylecop.json](https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md)
-->
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\..\stylecop.json"/>
</ItemGroup>
</Project>
4 changes: 4 additions & 0 deletions source/Databricks/documents/release-notes/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Databricks Release Notes

## Version 10.0.0

Bump to .NET 8.0 for TargetFramework.

## Version 9.0.2

Cancel statement if token cancellation is requested.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,93 +28,92 @@
using Moq.Protected;
using NodaTime;

namespace Energinet.DataHub.Core.Databricks.Jobs.IntegrationTests.Fixtures
namespace Energinet.DataHub.Core.Databricks.Jobs.IntegrationTests.Fixtures;

public sealed class HealthChecksFixture : IDisposable
{
public sealed class HealthChecksFixture : IDisposable
private readonly TestServer _server;

public HealthChecksFixture()
{
private readonly TestServer _server;

public HealthChecksFixture()
{
var webHostBuilder = CreateWebHostBuilder();
_server = new TestServer(webHostBuilder);
HttpClient = _server.CreateClient();
}

public HttpClient HttpClient { get; }

public void Dispose()
{
_server.Dispose();
}

private static IWebHostBuilder CreateWebHostBuilder()
{
return new WebHostBuilder()
.ConfigureServices(services =>
{
services.AddOptions<DatabricksJobsOptions>().Configure(options =>
{
options.WarehouseId = "baz";
options.WorkspaceToken = "bar";
options.WorkspaceUrl = "https://foo.com";
options.DatabricksHealthCheckStartHour = 0;
options.DatabricksHealthCheckEndHour = 23;
});

services.AddRouting();

RegisterHttpClientFactoryMock(services);
RegisterJobsApiClientMock(services);

services.AddScoped(typeof(IClock), _ => SystemClock.Instance);

services.AddHealthChecks()
.AddLiveCheck()
.AddDatabricksJobsApiHealthCheck();
})
.Configure(app =>
var webHostBuilder = CreateWebHostBuilder();
_server = new TestServer(webHostBuilder);
HttpClient = _server.CreateClient();
}

public HttpClient HttpClient { get; }

public void Dispose()
{
_server.Dispose();
}

private static IWebHostBuilder CreateWebHostBuilder()
{
return new WebHostBuilder()
.ConfigureServices(services =>
{
services.AddOptions<DatabricksJobsOptions>().Configure(options =>
{
app.UseRouting();
options.WarehouseId = "baz";
options.WorkspaceToken = "bar";
options.WorkspaceUrl = "https://foo.com";
options.DatabricksHealthCheckStartHour = 0;
options.DatabricksHealthCheckEndHour = 23;
});

services.AddRouting();

RegisterHttpClientFactoryMock(services);
RegisterJobsApiClientMock(services);

services.AddScoped(typeof(IClock), _ => SystemClock.Instance);

app.UseEndpoints(endpoints =>
{
endpoints.MapLiveHealthChecks();
endpoints.MapReadyHealthChecks();
});
services.AddHealthChecks()
.AddLiveCheck()
.AddDatabricksJobsApiHealthCheck();
})
.Configure(app =>
{
app.UseRouting();

app.UseEndpoints(endpoints =>
{
endpoints.MapLiveHealthChecks();
endpoints.MapReadyHealthChecks();
});
}

private static void RegisterJobsApiClientMock(IServiceCollection services)
{
var jobsApiClientMock = new Mock<IJobsApiClient>();
jobsApiClientMock.Setup(x => x.Jobs).Returns(new Mock<IJobsApi>().Object);
services.AddScoped(_ => jobsApiClientMock.Object);
}

private static void RegisterHttpClientFactoryMock(IServiceCollection services)
{
var httpMessageHandlerMock = new Mock<HttpMessageHandler>();

var response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK };

httpMessageHandlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(response);

var httpClient = new HttpClient(httpMessageHandlerMock.Object);
services.AddScoped(_ => httpClient);

var httpClientFactoryMock = new Mock<IHttpClientFactory>();
httpClientFactoryMock
.Setup(x => x.CreateClient(Options.DefaultName))
.Returns(() => httpClient);

services.AddScoped(_ => httpClientFactoryMock.Object);
}
});
}

private static void RegisterJobsApiClientMock(IServiceCollection services)
{
var jobsApiClientMock = new Mock<IJobsApiClient>();
jobsApiClientMock.Setup(x => x.Jobs).Returns(new Mock<IJobsApi>().Object);
services.AddScoped(_ => jobsApiClientMock.Object);
}

private static void RegisterHttpClientFactoryMock(IServiceCollection services)
{
var httpMessageHandlerMock = new Mock<HttpMessageHandler>();

var response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK };

httpMessageHandlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(response);

var httpClient = new HttpClient(httpMessageHandlerMock.Object);
services.AddScoped(_ => httpClient);

var httpClientFactoryMock = new Mock<IHttpClientFactory>();
httpClientFactoryMock
.Setup(x => x.CreateClient(Options.DefaultName))
.Returns(() => httpClient);

services.AddScoped(_ => httpClientFactoryMock.Object);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ limitations under the License.
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ limitations under the License.
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
55 changes: 27 additions & 28 deletions source/Databricks/source/Jobs/Client/JobsApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,42 +16,41 @@
using Energinet.DataHub.Core.Databricks.Jobs.Constants;
using Microsoft.Azure.Databricks.Client;

namespace Energinet.DataHub.Core.Databricks.Jobs.Client
namespace Energinet.DataHub.Core.Databricks.Jobs.Client;

/// <summary>
/// A databricks client based on the Microsoft.Azure.JobsApiClient, which is using Job API 2.0.
/// The client is extended with a method for reading jobs created using Python Wheels, using Job API 2.1.
/// Because the Job API 2.0 does not support reading python wheel settings.
/// Which is used when we run new jobs and need to know the existing parameters of the job.
/// The code is based on https://github.com/Azure/azure-databricks-client and can be replaced by the official
/// package when support for Job API 2.1 is added.
/// </summary>
public sealed class JobsApiClient : IDisposable, IJobsApiClient
{
/// <summary>
/// A databricks client based on the Microsoft.Azure.JobsApiClient, which is using Job API 2.0.
/// The client is extended with a method for reading jobs created using Python Wheels, using Job API 2.1.
/// Because the Job API 2.0 does not support reading python wheel settings.
/// Which is used when we run new jobs and need to know the existing parameters of the job.
/// The code is based on https://github.com/Azure/azure-databricks-client and can be replaced by the official
/// package when support for Job API 2.1 is added.
/// Create Databricks Jobs client object with a Http client.
/// </summary>
public sealed class JobsApiClient : IDisposable, IJobsApiClient
/// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
public JobsApiClient(IHttpClientFactory httpClientFactory)
{
/// <summary>
/// Create Databricks Jobs client object with a Http client.
/// </summary>
/// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
public JobsApiClient(IHttpClientFactory httpClientFactory)
{
var httpClient = httpClientFactory.CreateClient(HttpClientNameConstants.DatabricksJobsApi);
Jobs = new Microsoft.Azure.Databricks.Client.JobsApiClient(httpClient);
}
var httpClient = httpClientFactory.CreateClient(HttpClientNameConstants.DatabricksJobsApi);
Jobs = new Microsoft.Azure.Databricks.Client.JobsApiClient(httpClient);
}

public IJobsApi Jobs { get; }
public IJobsApi Jobs { get; }

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
private void Dispose(bool disposing)
{
if (disposing)
{
if (disposing)
{
Jobs.Dispose();
}
Jobs.Dispose();
}
}
}
Loading

0 comments on commit 7c9cd10

Please sign in to comment.