csharp/Microsoft.Azure.Databricks.Client/ApiClient.cs (114 lines of code) (raw):
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.Azure.Databricks.Client.Converters;
using System;
using System.Net.Http;
using System.Net.Mime;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Azure.Databricks.Client;
public abstract class ApiClient : IDisposable
{
protected readonly HttpClient HttpClient;
protected virtual string ApiVersion => "2.0";
protected string BaseUnityCatalogUri => "2.1/unity-catalog";
protected string BaseMLFlowApiUri => "2.0/mlflow";
protected static readonly JsonSerializerOptions Options = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
PropertyNameCaseInsensitive = true,
Converters = {
new JsonStringEnumConverter(),
new MillisecondEpochDateTimeConverter(),
new LibraryConverter(),
new SecretScopeConverter(),
new AclPermissionItemConverter(),
new DepedencyConverter(),
new TableConstraintConverter(),
}
};
protected ApiClient(HttpClient httpClient)
{
HttpClient = httpClient;
}
protected static ClientApiException CreateApiException(HttpResponseMessage response)
{
var statusCode = response.StatusCode;
var errorContent = response.Content.ReadAsStringAsync().Result;
return new ClientApiException(errorContent, statusCode);
}
private static async Task<TResult> SendRequest<TBody, TResult>(HttpClient httpClient, HttpMethod method, string requestUri, TBody body, CancellationToken cancellationToken = default)
{
var request = new HttpRequestMessage(method, requestUri)
{
Content = body == null ? null : new StringContent(JsonSerializer.Serialize(body, Options), Encoding.UTF8, MediaTypeNames.Application.Json)
};
using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
throw CreateApiException(response);
}
using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
return await JsonSerializer.DeserializeAsync<TResult>(responseStream, Options, cancellationToken).ConfigureAwait(false);
}
private static async Task SendRequest<TBody>(HttpClient httpClient, HttpMethod method, string requestUri, TBody body, CancellationToken cancellationToken = default)
{
var request = new HttpRequestMessage(method, requestUri)
{
Content = body == null ? null : new StringContent(JsonSerializer.Serialize(body, Options), Encoding.UTF8, MediaTypeNames.Application.Json)
};
using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
throw CreateApiException(response);
}
}
protected static async Task<T> HttpGet<T>(HttpClient httpClient, string requestUri, CancellationToken cancellationToken = default)
{
return await SendRequest<object, T>(httpClient, HttpMethod.Get, requestUri, null, cancellationToken).ConfigureAwait(false);
}
protected static async Task HttpPost<TBody>(HttpClient httpClient, string requestUri, TBody body, CancellationToken cancellationToken = default)
{
await SendRequest(httpClient, HttpMethod.Post, requestUri, body, cancellationToken).ConfigureAwait(false);
}
protected static async Task<TResult> HttpPost<TBody, TResult>(HttpClient httpClient, string requestUri,
TBody body, CancellationToken cancellationToken = default)
{
return await SendRequest<TBody, TResult>(httpClient, HttpMethod.Post, requestUri, body, cancellationToken).ConfigureAwait(false);
}
protected static async Task HttpPatch<TBody>(HttpClient httpClient, string requestUri, TBody body, CancellationToken cancellationToken = default)
{
await SendRequest(httpClient, HttpMethod.Patch, requestUri, body, cancellationToken).ConfigureAwait(false);
}
protected static async Task<TResult> HttpPatch<TBody, TResult>(HttpClient httpClient, string requestUri, TBody body, CancellationToken cancellationToken = default)
{
return await SendRequest<TBody, TResult>(httpClient, HttpMethod.Patch, requestUri, body, cancellationToken).ConfigureAwait(false);
}
protected static async Task<TResult> HttpPut<TBody, TResult>(HttpClient httpClient, string requestUri, TBody body, CancellationToken cancellationToken = default)
{
return await SendRequest<TBody, TResult>(httpClient, HttpMethod.Put, requestUri, body, cancellationToken).ConfigureAwait(false);
}
protected static async Task HttpPut<TBody>(HttpClient httpClient, string requestUri, TBody body, CancellationToken cancellationToken = default)
{
await SendRequest(httpClient, HttpMethod.Put, requestUri, body, cancellationToken).ConfigureAwait(false);
}
protected static async Task HttpDelete(HttpClient httpClient, string requestUri,
CancellationToken cancellationToken = default)
{
await SendRequest<object>(httpClient, HttpMethod.Delete, requestUri, null, cancellationToken).ConfigureAwait(false);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
HttpClient?.Dispose();
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}