ResourcePoolService
using Polly;
using Relativity.Transfer.Dto;
using Relativity.Transfer.Resources;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace Relativity.Transfer
{
internal class ResourcePoolService : IResourcePoolService
{
private readonly RelativityConnectionInfo connectionInfo;
private readonly ITransferLog transferLog;
public RelativityConnectionInfo ConnectionInfo => connectionInfo;
public int MaxRetryAttempts { get; set; }
public double TimeoutSeconds { get; set; }
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "This object is properly disposed.")]
public ResourcePoolService(RelativityConnectionInfo connectionInfo)
: this(connectionInfo, new NullTransferLog())
{
}
public ResourcePoolService(RelativityConnectionInfo connectionInfo, ITransferLog log)
: this(connectionInfo, log, 5, 300)
{
}
public ResourcePoolService(RelativityConnectionInfo connectionInfo, ITransferLog log, int maxRetryAttempts, double timeoutSeconds)
{
if (connectionInfo == null)
throw new ArgumentNullException("connectionInfo");
if (log == null)
throw new ArgumentNullException("log");
this.connectionInfo = connectionInfo;
transferLog = log;
MaxRetryAttempts = maxRetryAttempts;
TimeoutSeconds = timeoutSeconds;
}
public Task<IEnumerable<ResourcePool>> GetResourcePoolsAsync(CancellationToken token)
{
return GetResourcePoolsAsync(null, token);
}
public async Task<ResourcePool> GetResourcePoolAsync(string name, CancellationToken token)
{
return (await GetResourcePoolsAsync($"""{name}""", token).ConfigureAwait(false)).FirstOrDefault();
}
public async Task<IEnumerable<ResourcePool>> GetResourcePoolsAsync(string condition, CancellationToken token)
{
transferLog.LogDebug("Preparing to retrieve all resource pools that match the '{Condition}' query condition from the '{Host}' Relativity server.", condition, connectionInfo.Host);
RestClient restClient = new RestClient(new HttpConnectionInfo(connectionInfo), transferLog, TimeoutSeconds, MaxRetryAttempts);
string content = SerializationHelper.SerializeToJson(new QueryDto {
Query = {
Condition = condition
}
});
QueryResultSetDto<ResourcePoolDto> queryResultSetDto = await restClient.RequestPostAsync<QueryResultSetDto<ResourcePoolDto>>("/relativity.rest/api/Relativity.Services.ResourcePool.IResourcePoolModule/Resource%20Pool%20Service/QueryAsync", content, (int retryAttempt) => TimeSpan.FromSeconds(Math.Pow(2, (double)retryAttempt)), delegate(Exception exception, TimeSpan timespan, Context context) {
transferLog.LogError(exception, "Retry - {Timespan} - Failed to retrieve all resource pools from the '{Host}' Relativity server.", timespan, connectionInfo.Host);
}, (HttpStatusCode code) => "query resource pools by condition", (HttpStatusCode code) => string.Format(CultureInfo.CurrentCulture, CoreStrings.ResourcePoolHttpPostExceptionMessage, connectionInfo.Host), token).ConfigureAwait(false);
if (!queryResultSetDto.Success)
throw new TransferException(queryResultSetDto.CreateExceptionMessage());
List<ResourcePool> list = (from x in queryResultSetDto.Results
select CreateResourcePool(x.Artifact)).ToList();
transferLog.LogDebug("Successfully retrieved {ResourcePoolCount} resource pools that matched the '{Condition}' query condition from the '{Host}' Relativity server.", list.Count, condition, connectionInfo.Host);
return list;
}
public Task<IEnumerable<ResourceServer>> GetResourceServersAsync(ResourcePool pool, CancellationToken token)
{
if (pool == null)
throw new ArgumentNullException("pool");
return GetResourceServersAsync(pool, null, token);
}
public async Task<IEnumerable<ResourceServer>> GetResourceServersAsync(ResourcePool pool, string condition, CancellationToken token)
{
if (pool == null)
throw new ArgumentNullException("pool");
transferLog.LogDebug("Preparing to retrieve the all resource servers within the '{ResourcePool}' from the '{Host}' Relativity server.", pool.Name, connectionInfo.Host);
RestClient restClient = new RestClient(new HttpConnectionInfo(connectionInfo), transferLog, TimeoutSeconds, MaxRetryAttempts);
string content = SerializationHelper.SerializeToJson(new {
resourcePool = new {
ArtifactID = pool.ArtifactId
}
});
List<ResourceServerDto> obj = await restClient.RequestPostAsync<List<ResourceServerDto>>("/relativity.rest/api/Relativity.Services.ResourcePool.IResourcePoolModule/Resource%20Pool%20Service/RetrieveResourceServersAsync", content, (int retryAttempt) => TimeSpan.FromSeconds(Math.Pow(2, (double)retryAttempt)), delegate(Exception exception, TimeSpan timespan, Context context) {
transferLog.LogError(exception, "Retry - {Timespan} - Failed to retrieve all resource server information from the '{Host}' Relativity server.", timespan, connectionInfo.Host);
}, (HttpStatusCode code) => "query resource servers by resource pool and condition", (HttpStatusCode code) => string.Format(CultureInfo.CurrentCulture, CoreStrings.ResourceServerHttpPostExceptionMessage, connectionInfo.Host), token).ConfigureAwait(false);
List<ResourceServer> list = new List<ResourceServer>();
foreach (ResourceServerDto item in obj) {
list.Add(CreateResourceServer(pool, item));
}
transferLog.LogDebug("Successfully retrieved {ResourcePoolCount} within the '{ResourcePool}' from the '{Host}' Relativity server.", list.Count, pool.Name, connectionInfo.Host);
return list;
}
private static ResourcePool CreateResourcePool(ResourcePoolDto dto)
{
return new ResourcePool {
ArtifactId = dto.ArtifactId,
Name = dto.Name
};
}
private static ResourceServer CreateResourceServer(ResourcePool pool, ResourceServerDto dto)
{
return new ResourceServer {
ArtifactId = dto.ArtifactId,
Name = dto.Name,
ResourcePool = pool,
ResourceServerType = new ResourceServerType {
ArtifactId = (dto.ServerType?.ArtifactId ?? 0),
Name = dto.ServerType?.Name
}
};
}
}
}