1
0
mirror of https://github.com/ncblakely/GiantsTools synced 2024-11-22 06:05:38 +01:00

Parameter validation/cleanup.

This commit is contained in:
Nick Blakely 2020-08-08 17:52:26 -07:00
parent 75c2b9474e
commit 81d5d86683
7 changed files with 194 additions and 17 deletions

View File

@ -12,7 +12,7 @@
services.AddSingleton<IServerRegistryStore, CosmosDbServerRegistryStore>(); services.AddSingleton<IServerRegistryStore, CosmosDbServerRegistryStore>();
services.AddSingleton<IDateTimeProvider, DefaultDateTimeProvider>(); services.AddSingleton<IDateTimeProvider, DefaultDateTimeProvider>();
services.AddHostedService<InitializerHostedService>(); services.AddHostedService<InitializerService>();
services.AddHostedService<ServerRegistryCleanupService>(); services.AddHostedService<ServerRegistryCleanupService>();
} }
} }

View File

@ -4,11 +4,11 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
public class InitializerHostedService : IHostedService public class InitializerService : IHostedService
{ {
private readonly IServerRegistryStore serverRegistryStore; private readonly IServerRegistryStore serverRegistryStore;
public InitializerHostedService(IServerRegistryStore serverRegistryStore) public InitializerService(IServerRegistryStore serverRegistryStore)
{ {
this.serverRegistryStore = serverRegistryStore; this.serverRegistryStore = serverRegistryStore;
} }

View File

@ -28,19 +28,12 @@
} }
public async Task AddServer( public async Task AddServer(
ServerInfo server) ServerInfo serverInfo)
{ {
if (server == null) ArgumentUtility.CheckForNull(serverInfo, nameof(serverInfo));
{ ArgumentUtility.CheckStringForNullOrEmpty(serverInfo.HostIpAddress, nameof(serverInfo.HostIpAddress));
throw new ArgumentNullException(nameof(server));
}
if (string.IsNullOrEmpty(server.HostIpAddress)) await this.registryStore.UpsertServerInfo(serverInfo);
{
throw new ArgumentException(nameof(server.HostIpAddress));
}
await this.registryStore.UpsertServerInfo(server ?? throw new ArgumentNullException(nameof(server)));
} }
public async Task<IEnumerable<ServerInfo>> GetAllServers() public async Task<IEnumerable<ServerInfo>> GetAllServers()

View File

@ -36,6 +36,8 @@
string partitionKey = null) string partitionKey = null)
where T : IIdentifiable where T : IIdentifiable
{ {
ArgumentUtility.CheckForNull(selectExpression, nameof(selectExpression));
if (partitionKey == null) if (partitionKey == null)
{ {
partitionKey = typeof(T).Name; partitionKey = typeof(T).Name;
@ -109,6 +111,8 @@
public async Task<T> GetItemById<T>(string id, string partitionKey = null) public async Task<T> GetItemById<T>(string id, string partitionKey = null)
where T : IIdentifiable where T : IIdentifiable
{ {
ArgumentUtility.CheckStringForNullOrEmpty(id, nameof(id));
return (await this.GetItems<T>(t => t.id == id, partitionKey)).FirstOrDefault(); return (await this.GetItems<T>(t => t.id == id, partitionKey)).FirstOrDefault();
} }
@ -118,6 +122,8 @@
ItemRequestOptions itemRequestOptions = null) ItemRequestOptions itemRequestOptions = null)
where T : IIdentifiable where T : IIdentifiable
{ {
ArgumentUtility.CheckForNull(item, nameof(item));
await this.container.UpsertItemAsync(item, partitionKey, itemRequestOptions); await this.container.UpsertItemAsync(item, partitionKey, itemRequestOptions);
} }
@ -142,6 +148,8 @@
string partitionKey = null, string partitionKey = null,
ItemRequestOptions requestOptions = null) ItemRequestOptions requestOptions = null)
{ {
ArgumentUtility.CheckStringForNullOrEmpty(id, nameof(id));
if (partitionKey == null) if (partitionKey == null)
{ {
partitionKey = typeof(T).Name; partitionKey = typeof(T).Name;

View File

@ -34,6 +34,8 @@
Expression<Func<ServerInfo, bool>> whereExpression = null, Expression<Func<ServerInfo, bool>> whereExpression = null,
string partitionKey = null) string partitionKey = null)
{ {
ArgumentUtility.CheckForNull(selectExpression, nameof(selectExpression));
return await this.client.GetItems<ServerInfo, TSelect>( return await this.client.GetItems<ServerInfo, TSelect>(
selectExpression: selectExpression, selectExpression: selectExpression,
whereExpression: whereExpression, whereExpression: whereExpression,
@ -42,11 +44,15 @@
public async Task<ServerInfo> GetServerInfo(string ipAddress) public async Task<ServerInfo> GetServerInfo(string ipAddress)
{ {
ArgumentUtility.CheckStringForNullOrEmpty(ipAddress, nameof(ipAddress));
return await this.client.GetItemById<ServerInfo>(ipAddress); return await this.client.GetItemById<ServerInfo>(ipAddress);
} }
public async Task UpsertServerInfo(ServerInfo serverInfo) public async Task UpsertServerInfo(ServerInfo serverInfo)
{ {
ArgumentUtility.CheckForNull(serverInfo, nameof(serverInfo));
await this.client.UpsertItem( await this.client.UpsertItem(
item: serverInfo, item: serverInfo,
partitionKey: new PartitionKey(serverInfo.DocumentType)); partitionKey: new PartitionKey(serverInfo.DocumentType));
@ -54,6 +60,8 @@
public async Task DeleteServers(IEnumerable<string> ids, string partitionKey = null) public async Task DeleteServers(IEnumerable<string> ids, string partitionKey = null)
{ {
ArgumentUtility.CheckEnumerableForNullOrEmpty(ids, nameof(ids));
foreach (string id in ids) foreach (string id in ids)
{ {
this.logger.LogInformation("Deleting server for host IP {IPAddress}", id); this.logger.LogInformation("Deleting server for host IP {IPAddress}", id);

View File

@ -0,0 +1,153 @@
namespace Giants.Services
{
// Decompiled with JetBrains decompiler
// Type: Microsoft.VisualStudio.Services.Common.ArgumentUtility
// Assembly: Microsoft.VisualStudio.Services.Common, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// MVID: 8C174B92-2E1F-4F71-9E6B-FC8D9F2C517A
using System;
using System.Collections;
using System.ComponentModel;
using System.Runtime.CompilerServices;
[EditorBrowsable(EditorBrowsableState.Never)]
public static class ArgumentUtility
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CheckForNull(object var, string varName)
{
if (var == null)
throw new ArgumentNullException(varName);
}
public static void CheckStringForNullOrEmpty(
string stringVar,
string stringVarName)
{
ArgumentUtility.CheckStringForNullOrEmpty(stringVar, stringVarName, false);
}
public static void CheckForNonnegativeInt(int var, string varName)
{
if (var < 0)
throw new ArgumentOutOfRangeException(varName);
}
public static void CheckForNonPositiveInt(int var, string varName)
{
if (var <= 0)
throw new ArgumentOutOfRangeException(varName);
}
public static void CheckStringForNullOrEmpty(
string stringVar,
string stringVarName,
bool trim)
{
ArgumentUtility.CheckForNull((object)stringVar, stringVarName);
if (trim)
stringVar = stringVar.Trim();
if (stringVar.Length == 0)
throw new ArgumentException("Empty string not allowed.", stringVarName);
}
public static void CheckStringLength(
string stringVar,
string stringVarName,
int maxLength,
int minLength = 0)
{
ArgumentUtility.CheckForNull((object)stringVar, stringVarName);
if (stringVar.Length < minLength || stringVar.Length > maxLength)
throw new ArgumentException("String length not allowed.", stringVarName);
}
public static void CheckEnumerableForNullOrEmpty(
IEnumerable enumerable,
string enumerableName)
{
ArgumentUtility.CheckForNull((object)enumerable, enumerableName);
if (!enumerable.GetEnumerator().MoveNext())
throw new ArgumentException("Collection cannot be null or empty.", enumerableName);
}
public static void CheckEnumerableForNullElement(
IEnumerable enumerable,
string enumerableName)
{
ArgumentUtility.CheckForNull((object)enumerable, enumerableName);
foreach (object obj in enumerable)
{
if (obj == null)
throw new ArgumentException("NullElementNotAllowedInCollection", enumerableName);
}
}
public static void CheckForEmptyGuid(Guid guid, string varName)
{
if (guid.Equals(Guid.Empty))
throw new ArgumentException("EmptyGuidNotAllowed", varName);
}
public static void CheckBoundsInclusive(
int value,
int minValue,
int maxValue,
string varName)
{
if (value < minValue || value > maxValue)
throw new ArgumentOutOfRangeException(varName, "ValueOutOfRange");
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CheckForOutOfRange<T>(
T var,
string varName,
T minimum)
where T : IComparable<T>
{
ArgumentUtility.CheckForNull((object)var, varName);
if (var.CompareTo(minimum) < 0)
throw new ArgumentOutOfRangeException(varName, (object)var, "OutOfRange");
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CheckForOutOfRange(
int var,
string varName,
int minimum,
int maximum)
{
if (var < minimum || var > maximum)
throw new ArgumentOutOfRangeException(varName, (object)var, "OutOfRange");
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CheckForOutOfRange(
long var,
string varName,
long minimum,
long maximum)
{
if (var < minimum || var > maximum)
throw new ArgumentOutOfRangeException(varName, (object)var, "OutOfRange");
}
public static void CheckForDateTimeRange(
DateTime var,
string varName,
DateTime minimum,
DateTime maximum)
{
if (var < minimum || var > maximum)
throw new ArgumentOutOfRangeException(varName, (object)var, "OutOfRange");
}
public static void EnsureIsNull(object var, string varName)
{
if (var != null)
throw new ArgumentException("NullValueNecessary");
}
}
}

View File

@ -39,7 +39,7 @@ namespace Giants.Web.Controllers
IEnumerable<Services.ServerInfo> serverInfo = await this.serverRegistryService.GetAllServers(); IEnumerable<Services.ServerInfo> serverInfo = await this.serverRegistryService.GetAllServers();
IMapper mapper = Services.Mapper.GetMapper(); IMapper mapper = Services.Mapper.GetMapper();
return serverInfo var mappedServers = serverInfo
.Select(x => .Select(x =>
{ {
var serverInfo = mapper.Map<ServerInfoWithHostAddress>(x); var serverInfo = mapper.Map<ServerInfoWithHostAddress>(x);
@ -47,19 +47,34 @@ namespace Giants.Web.Controllers
return serverInfo; return serverInfo;
}) })
.ToList(); .ToList();
string requestIpAddress = this.GetRequestIpAddress();
logger.LogInformation("Returning {Count} servers to {IPAddress}", mappedServers.Count, requestIpAddress);
return mappedServers;
} }
[HttpPost] [HttpPost]
public async Task AddServer([FromBody]DataContract.ServerInfo serverInfo) public async Task AddServer([FromBody]DataContract.ServerInfo serverInfo)
{ {
IPAddress requestIpAddress = this.httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4(); ArgumentUtility.CheckForNull(serverInfo, nameof(serverInfo));
this.logger.LogInformation($"Request to add server from {requestIpAddress}");
string requestIpAddress = this.GetRequestIpAddress();
this.logger.LogInformation("Request to add server from {IPAddress}", requestIpAddress);
var serverInfoEntity = mapper.Map<Services.ServerInfo>(serverInfo); var serverInfoEntity = mapper.Map<Services.ServerInfo>(serverInfo);
serverInfoEntity.HostIpAddress = requestIpAddress.ToString(); serverInfoEntity.HostIpAddress = requestIpAddress.ToString();
serverInfoEntity.LastHeartbeat = DateTime.UtcNow; serverInfoEntity.LastHeartbeat = DateTime.UtcNow;
await this.serverRegistryService.AddServer(serverInfoEntity); await this.serverRegistryService.AddServer(serverInfoEntity);
this.logger.LogInformation("Added server successfully for {IPAddress}", requestIpAddress);
}
private string GetRequestIpAddress()
{
return this.httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
} }
} }
} }