// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Threading; using System.Threading.Tasks; using EpicGames.Horde.Artifacts; using EpicGames.Horde.Compute; using EpicGames.Horde.Logs; using EpicGames.Horde.Projects; using EpicGames.Horde.Secrets; using EpicGames.Horde.Storage; using EpicGames.Horde.Tools; using Grpc.Core; using Microsoft.Extensions.Logging; namespace EpicGames.Horde { /// /// Interface for Horde functionality. /// public interface IHordeClient { /// /// URL of the horde server /// Uri ServerUrl { get; } /// /// Accessor for the artifact collection /// IArtifactCollection Artifacts { get; } /// /// Accessor for the compute client /// IComputeClient Compute { get; } /// /// Accessor for the project collection /// IProjectCollection Projects { get; } /// /// Accessor for the secret collection /// ISecretCollection Secrets { get; } /// /// Accessor for the tools collection /// IToolCollection Tools { get; } /// /// Event triggered whenever the access token state changes /// event Action? OnAccessTokenStateChanged; /// /// Connect to the Horde server /// /// Whether to allow prompting for credentials /// Cancellation token for the operation /// True if the connection succeded Task LoginAsync(bool interactive, CancellationToken cancellationToken); /// /// Gets the current connection state /// bool HasValidAccessToken(); /// /// Gets an access token for the server /// Task GetAccessTokenAsync(bool interactive, CancellationToken cancellationToken = default); /// /// Gets a gRPC client interface /// Task CreateGrpcClientAsync(CancellationToken cancellationToken = default) where TClient : ClientBase; /// /// Creates a Horde HTTP client /// HordeHttpClient CreateHttpClient(); /// /// Creates a storage namespace for the given base path /// IStorageNamespace GetStorageNamespace(string relativePath, string? accessToken = null); /// /// Creates a logger device that writes data to the server /// IServerLogger CreateServerLogger(LogId logId, LogLevel minimumLevel = LogLevel.Information); } /// /// Interface for a Horde client with a known lifetime /// public interface IHordeClientWithLifetime : IHordeClient, IAsyncDisposable { } /// /// Extension methods for /// public static class HordeClientExtensions { /// /// Creates a storage namespace for a particular id /// public static IStorageNamespace GetStorageNamespace(this IHordeClient hordeClient, NamespaceId namespaceId, string? accessToken = null) => hordeClient.GetStorageNamespace($"api/v1/storage/{namespaceId}", accessToken); /// /// Creates a storage namespace for a particular artifact /// public static IStorageNamespace GetStorageNamespace(this IHordeClient hordeClient, ArtifactId artifactId) => hordeClient.GetStorageNamespace($"api/v2/artifacts/{artifactId}"); /// /// Creates a storage namespace for a particular log /// public static IStorageNamespace GetStorageNamespace(this IHordeClient hordeClient, LogId logId) => hordeClient.GetStorageNamespace($"api/v1/logs/{logId}"); /// /// Creates a storage namespace for a particular tool /// public static IStorageNamespace GetStorageNamespace(this IHordeClient hordeClient, ToolId toolId) => hordeClient.GetStorageNamespace($"api/v1/tools/{toolId}"); /// /// Reads a blob storage ref from a path /// public static async Task TryReadRefAsync(this IHordeClient hordeClient, string path, RefCacheTime cacheTime = default, CancellationToken cancellationToken = default) { ReadRefResponse? response = await hordeClient.CreateHttpClient().TryReadRefAsync(path, cacheTime, cancellationToken); if (response == null) { return null; } IStorageNamespace storageNamespace = hordeClient.GetStorageNamespace(response.BasePath); return storageNamespace.CreateBlobRef(response.Target); } /// /// Reads a typed blob storage ref from a path /// public static async Task?> TryReadRefAsync(this IHordeClient hordeClient, string path, RefCacheTime cacheTime = default, CancellationToken cancellationToken = default) { IBlobRef? blobRef = await hordeClient.TryReadRefAsync(path, cacheTime, cancellationToken); return blobRef?.ForType(); } } }