private void SetRequestId() { if (string.IsNullOrWhiteSpace(RequestId)) { RequestId = SafeTry.IgnoreException(() => Info.RequestId); } }
/// <summary> /// Retrieves a setting /// </summary> /// <param name="services">The collection of lookup services</param> /// <param name="name">The name of the setting to retrieve</param> /// <param name="defaultValue">If the setting is not found, or there is an error retrieving the setting, this will be returned instead</param> /// <returns>The string setting (If you need to convert to something else, that will be done outside this call)</returns> public static string Get(ILookupServices <T, TS> services, string name, string defaultValue) => SafeTry.IgnoreException( () => { var service = services.Service; if (service.Key == null) { return(defaultValue); } var cachingSeconds = CachingSeconds(service); // Get the collection of settings inside a Lock (this is possibly recursive, so can't use semaphore locking) var settingsCollection = NamedLocker.Lock($"{service.Key}_Locker", num => num > 1 ? null // If recursive (will be allowed in lock again), the default value will be used instead of a real lookup : GetItems(cachingSeconds, service, services.Cache)); // If the above failed to find anything (eg. no settings, or a recursive call) if (settingsCollection.IsDefault()) { return(defaultValue); } // Return the setting value (or default if no setting exists) var setting = service.GetItem(settingsCollection, name); return(setting.IsDefault() ? defaultValue : service.GetValue(setting)); }, defaultValue );
public virtual string RetrieveIdentityErrorFromJwt(string jwt = null) { jwt ??= Http.Jwt; if (string.IsNullOrWhiteSpace(jwt)) { return("No JWT provided"); } var decrypted = SafeTry.IgnoreException(() => jwt.Decrypt(Encryption)); if (string.IsNullOrWhiteSpace(decrypted?.Value)) { return("Unable to decrypt JWT"); } var identity = SafeTry.IgnoreException(() => decrypted.Value.DeserializeJson <T>()); if (identity.IsDefault()) { return("Unable to deserialize"); } // ReSharper disable once ConvertIfStatementToReturnStatement if (IsExpired(identity)) { return("JWT has expired"); } return("Valid identity JWT"); }
public static NameValueCollection ToNameValueCollection(this string json, JsonSerializerSettings jsonSettings = null) { return(SafeTry.IgnoreException(() => { var nvc = new NameValueCollection(); if (string.IsNullOrWhiteSpace(json)) { return nvc; } // If this is a basic object, attempt that var dict = SafeTry.IgnoreException(() => json.DeserializeJson <Dictionary <string, object> >(jsonSettings)); if (dict.IsPopulated()) { return ToNameValueCollection(dict, jsonSettings); } // The JSON could be a collection, but I'm not going to break it down any further // Only benefit to breaking this down is to allow more granular ignoreData // Don't know, so just log the raw json nvc.Add("Raw", json); return nvc; }, DefaultNvc)); }
public async Task SaveResponse(HttpResponse response) { SaveResult( response.StatusCode, await SafeTry.IgnoreException(async() => await response.GetBodyAsync()) ); }
private void SetUser(BaseIdentity identity) { if (!UserId.HasValue) { UserId = SafeTry.IgnoreException(() => identity?.Id); } }
private void SetSession() { if (string.IsNullOrWhiteSpace(Session)) { Session = SafeTry.IgnoreException(() => Info.SessionId); } }
/// <summary> /// Wrapper for multiple Sql calls across multiple databases within a transaction /// </summary> /// <remarks>This will use individual connections using a distributed transactions (performance hit)</remarks> /// <param name="logger">The logger for the transaction sequence</param> /// <param name="method">The actual SQL calls</param> /// <param name="exceptionMethod">Default = ExceptionRethrow. If an exception is thrown during "method", how will it be handled (besides being rolled back)</param> /// <returns>True if the transaction was committed, false if rolled back</returns> public static async Task <bool> Distributed(ILogger logger, Func <Task <TransactionResponse> > method, Func <Exception, bool> exceptionMethod = null) { DatabaseInformation info = null; if (logger != null) { info = logger.DatabaseEntry("Database Transaction", "Action Distributed Transaction"); } using var scope = new TransactionScope(); var success = await SafeTry.OnException( async() => { var response = await method(); if (response.Success) { scope.Complete(); } return(response.Success); }, exceptionMethod); if (logger != null) { logger.DatabaseExit(info); } return(success); }
/// <summary> /// Wrapper for multiple Sql calls across multiple databases within a transaction /// </summary> /// <remarks>This will use individual connections using a distributed transactions (performance hit)</remarks> /// <typeparam name="T">Return type of the complete transaction</typeparam> /// <param name="logger">The logger for the transaction sequence</param> /// <param name="method">The actual SQL calls</param> /// <param name="exceptionMethod">Default = ExceptionRethrow. If an exception is thrown during "method", how will it be handled (besides being rolled back)</param> /// <param name="defaultValue">Default = Default(T). If an exception is thrown during "method", and it is not rethrowing the exception, this will instead be returned</param> /// <returns>The result from the SQL calls (method) - or possibly default(T) if there was an exception</returns> public static async Task <T> Distributed <T>(ILogger logger, Func <Task <TransactionResponse <T> > > method, Func <Exception, T, T> exceptionMethod, T defaultValue = default) { DatabaseInformation info = null; if (logger != null) { info = logger.DatabaseEntry("Database Transaction", "Func Distributed Transaction"); } using var scope = new TransactionScope(); var result = await SafeTry.OnException( async() => { var response = await method(); if (response.Success) { scope.Complete(); } return(response.Response); }, ex => exceptionMethod(ex, defaultValue)); if (logger != null) { logger.DatabaseExit(info); } return(result); }
public virtual void Initialize(Exception ex, string title, bool messageOnly) { InitializeBase(Severity); Ex = ex; MessageOnly = messageOnly; Title = string.IsNullOrWhiteSpace(title) ? ex.GetType().ToString() : title; Category = SafeTry.IgnoreException(() => $"{(Severity == TraceEventType.Warning ? "Hidden " : "")}{Title} Exception", ""); }
public HealthCheck(HealthReport r, IEnvironmentSettings env) { Status = r.Status.ToString(); Version = SafeTry.IgnoreException(() => SettingsEnvironmental.Get(env, "version") ?? Assembly.GetEntryAssembly()?.GetName().Version.ToString(), "Unknown" ); Errors = r.Entries.Select(e => new { key = e.Key, value = e.Value.Status.ToString() }); }
public static void CacheInvalidation(IServiceProvider sp) { var env = ServiceLocator.Get <IEnvironmentSettings>(sp); var url = SettingsEnvironmental.Get(env, "URL:Hub:Cache"); var logger = ServiceLocator.Get <ILogger>(sp); var signalR = ServiceLocator.Get <ISignalR>(sp); var memory = ServiceLocator.Get <IMemoryCache>(sp); _ = SafeTry.LogException(logger, async() => await SignalRHub.Receive <string>(signalR, url, "Invalidate Cache", memory.Remove)); }
public virtual void SetProperties(ILoggerConfiguration config) { if (!IsInitialized) { throw new Exception("Logging Information Initialization has not occurred"); } SafeTry.IgnoreException(() => Machine = System.Environment.MachineName); SafeTry.IgnoreException(() => Application = AppSettings.Name); }
/// <summary> /// Updates the user preference and clears cache so that it can be retrieved next time /// </summary> /// <param name="logger">The ILogger implementation</param> /// <param name="service">The user preferences settings</param> /// <param name="cache">The ICache implementation</param> /// <param name="key">The setting key</param> /// <param name="value">The setting value</param> /// <returns>True/False for if this was successfully updated</returns> public static async Task <bool> Update( ILogger logger, IUserPreferenceSettings service, ICache cache, string key, string value) { var updateTask = SafeTry.LogException( logger, async() => await service.Update(key, value) ); var removeTask = Caching.RemoveAsync(cache, service.Key); await Task.WhenAll(updateTask, removeTask); return(updateTask.Result && removeTask.Result.IsDefault()); }
private void SetOrder() { if (Order != null) { return; } // Get the prefix string from the request Order = SafeTry.IgnoreException(() => Info.LogOrderPrefix) ?? ""; // Each request will increment this request property const string key = "logging_order"; // I don't think this lock is really necessary, as most everything will occur on main thread so this will be synchronous. // But leaving lock in case a thread is trying to log something Order += NamedLocker.Lock($"{key}_{Info.RequestId}", num => Info.LoggingOrder++); }
/// <summary> /// Wrapper for multiple Sql calls (Single database) within a transaction /// </summary> /// <param name="logger">The logger for the transaction sequence</param> /// <param name="cnnStr">The connection string to use for all calls within the transaction</param> /// <param name="method">The actual SQL calls</param> /// <param name="isolation">Default = ReadCommitted. Isolation level for the transaction.</param> /// <param name="exceptionMethod">Default = ExceptionRethrow. If an exception is thrown during "method", how will it be handled (besides being rolled back)</param> /// <returns>True if the transaction was committed, false if rolled back</returns> public static async Task <bool> Run(ILogger logger, string cnnStr, Func <IDbTransaction, Task <TransactionResponse> > method, IsolationLevel isolation, Func <Exception, bool> exceptionMethod) { DatabaseInformation info = null; if (logger != null) { info = logger.DatabaseEntry(cnnStr, "Action Transaction"); } await using var cnn = new TC { ConnectionString = $"{cnnStr};MultipleActiveResultSets=True" }; if (cnn.State != ConnectionState.Open) { await cnn.OpenAsync(); } await using var transaction = await cnn.BeginTransactionAsync(isolation); var success = await SafeTry.OnException( async() => { var response = await method(transaction); if (response.Success) { await transaction.CommitAsync(); } else { await transaction.RollbackAsync(); } return(response.Success); }, async ex => { await transaction.RollbackAsync(); return(exceptionMethod(ex)); }); if (logger != null) { logger.DatabaseExit(info); } return(success); }
public static NameValueCollection ToNameValueCollection(this IDictionary dict, JsonSerializerSettings jsonSettings = null) { return(SafeTry.IgnoreException(() => { var nvc = new NameValueCollection(); if (dict == null) { return nvc; } foreach (var key in dict.Keys) { var o = dict[key]; var s = o as string; nvc.Add(key.ToString(), s ?? o.SerializeJson(jsonSettings)); } return nvc; }, DefaultNvc)); }
protected void DoLog(BaseLogInformation info, Action errorAction = null) { _ = SafeTry.EmailException( EmailImpl, App, async() => { // Set properties on the object (ones that aren't set on the constructor that may take a bit) info.SetProperties(Config); // Log it (Insert) await DoAllLoggerInserts(info, errorAction); // Waited for complete above so that this can be set (free it up for updates) if (info is TimerBaseInformation timer) { timer.SetComplete = true; } }
public static void Logger(IServiceProvider sp) { var email = ServiceLocator.Get <IEmail>(sp); var app = ServiceLocator.Get <IApplicationSettings>(sp); var logger = ServiceLocator.Get <ILogger>(sp); // Not at all sure how to get this to log out issues... this happens outside the scope of HttpRequest, meaning that the logger will fail :( SignalR.SignalR.SetLogger( async msg => await SafeTry.EmailException( email, app, () => logger.Log(TraceEventType.Suspend, msg, "SignalR") ), async ex => await SafeTry.EmailException( email, app, () => logger.Exception(ex) ) ); }
public override bool IsValid(object value) { if (value == null) { return(true); } var str = value.ToString(); if (string.IsNullOrWhiteSpace(str)) { return(true); } return(SafeTry.IgnoreException(() => { // ReSharper disable once AssignmentIsFullyDiscarded _ = Regex.Match("", str); return true; })); }
/// <summary> /// Converts a NameValueCollection into a human readable string representation /// </summary> /// <param name="nvc">The NameValueCollection</param> /// <param name="name">The name of the collection</param> /// <param name="hideKeys">If there is any values that need to be hidden</param> /// <returns>Human readable string</returns> public static string AsString(this NameValueCollection nvc, string name = null, CaseInsensitiveBinaryList <string> hideKeys = null) => SafeTry.IgnoreException(() => { var sb = new StringBuilder(); if (!string.IsNullOrWhiteSpace(name)) { sb.Append(name); sb.AppendLine(": "); } if (nvc?.IsDefault() ?? true) { return(sb.ToString()); } if (hideKeys == null) { hideKeys = new List <string>().ToCaseInsensitiveBinaryList(); } foreach (var key in nvc.AllKeys) { sb.Append(key); sb.Append(" = "); if (hideKeys.Has(key)) { sb.Append("*****,"); } else { sb.Append(nvc[key] + ","); } sb.AppendLine(); } return(sb.ToString()); }, $"Unable to obtain {name ?? "Unknown"}" );
public override Task <IEnumerable <UserPreferenceSetting> > GetAll() => SafeTry.EmailException( EmailImpl, App, async() => await Service.GetAll(App.Name, UserId) );
/// <summary> /// Retrieves the actual IP address from the request /// </summary> /// <param name="context">The HttpContext</param> /// <returns>The actual/full IP Address (could be null)</returns> public static string IpAddress(this HttpContext context) => SafeTry.IgnoreException(() => context.Connection.RemoteIpAddress.ToString());
public override Task <IEnumerable <FeatureToggleSetting> > GetAll() => SafeTry.EmailException( EmailImpl, App, async() => await Service.GetAll(App.Name, CustomerId) );
public override Task <bool> Update(string key, string value) => SafeTry.LogException( Logger, async() => await Service.Update(App.Name, UserId, key, value) );
// Can not use logging or email exception handling, since that would circular reference back to getting a variable public override Task <IEnumerable <VariableSetting> > GetAll() => SafeTry.IgnoreException(async() => await Service.GetAll(App.Name, CustomerId));