private static Dictionary <int, string> GetJournalFileIndexMap(JournalConfiguration configuration, bool validateJournalSequence) { var journalIndexPathMap = new Dictionary <int, string>(); if (!Directory.Exists(configuration.JournalDirectory)) { throw new DirectoryNotFoundException("Could not find journal directory at path: " + configuration.JournalDirectory); } var files = Directory.GetFiles(configuration.JournalDirectory, configuration.JournalFileName + ".*"); if (!files.Any()) { throw new FileNotFoundException("No journal files found at path: " + configuration.JournalDirectory); } Array.ForEach(files, filePath => { var idxString = Path.GetExtension(filePath); int idx; if (!int.TryParse(idxString, out idx)) { return; } journalIndexPathMap.Add(idx, filePath); }); if (!journalIndexPathMap.Any()) { throw new FileLoadException("Failed to find any valid journal files to load at path: " + configuration.JournalDirectory); } var orderedJournalIndexPathMap = journalIndexPathMap .OrderBy(x => x.Key) .ToDictionary(k => k.Key, v => v.Value); if (validateJournalSequence) { var keys = orderedJournalIndexPathMap.Keys.ToArray(); if (Enumerable.Range(0, keys.Length).Any(i => keys[i] != keys[0] + i)) { throw new FileLoadException( "The loaded journal files were not in sequential order. " + "Please ensure the specified journal directory contains all journal files created by the journal object."); } } return(orderedJournalIndexPathMap); }
public UnbufferedJournalFileWriter(JournalConfiguration journalConfiguration) : base(journalConfiguration) { }
/// <summary> /// Performs the 'common' workload before and after executing the underlying /// method. /// </summary> /// <param name="context">Execution context.</param> /// <param name="request">Request message.</param> /// <returns>Response message.</returns> public async Task <Rp> RunAsync(ExecutionContext context, Rq request) { #region Validations if (context == null) { throw new ArgumentNullException(nameof(context)); } #endregion /* * Where's my request? This can happen, when the user doesn't * provide a "{}" during the JSON post. */ if (request == null) { throw new ZincException(ER.MethodInvoker_RequestIsNull); } /* * */ JournalConfiguration config = ZincConfiguration.Current.Journaling; if (config.To == null) { throw new ZincException(ER.Journaling_NotConfigured); } ZincJournal journalConfig = ZincConfiguration.Current.Journals.FirstOrDefault(j => j.Name == config.To); if (journalConfig == null) { throw new ZincException(ER.Journaling_JournalNotFound, config.To); } IExecutionJournal journal; try { journal = Platinum.Activator.Create <IExecutionJournal>(journalConfig.Type); } catch (ActorException ex) { throw new ZincException(ER.Journaling_InvalidMoniker, ex, config.To); } /* * Normalize WCF dates, so that they are ALL DateTimeKind = Utc * Once normalized, secrefy the message. */ WalkFix(request); var jrequest = Secrets.Strip <Rq>(request); /* * Pre-log */ if (config.Type == MethodLoggingType.PrePost) { await journal.PreAsync(context, jrequest); } /* * Validate */ ValidationResult vr; try { vr = Validator.Validate <Rq>(request); } catch (Exception ex) { var vex = new ZincException(ER.MethodInvoker_RequestValidate, ex, request.GetType().FullName); context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, null, vex); } else { await journal.FullAsync(context, jrequest, null, vex); } throw vex; } if (vr.IsValid == false) { ActorAggregateException agex = new ActorAggregateException(vr.Errors); var vex = new ZincException(ER.MethodInvoker_RequestInvalid, agex, request.GetType().FullName); context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, null, vex); } else { await journal.FullAsync(context, jrequest, null, vex); } throw vex; } /* * */ T method = System.Activator.CreateInstance <T>(); /* * Run */ Rp response; try { response = await method.RunAsync(context, request); } catch (ActorException ex) { context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, null, ex); } else { await journal.FullAsync(context, jrequest, null, ex); } throw; } catch (AggregateException ex) { if (ex.InnerExceptions.Count == 1 && ex.InnerExceptions[0] is ActorException) { var aex = (ActorException)ex.InnerExceptions[0]; context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, null, aex); } else { await journal.FullAsync(context, jrequest, null, aex); } // Yes, this will re-write exception stack :-( throw aex; } else if (ex.InnerExceptions.All(x => x is ActorException) == true) { ActorAggregateException agg = new ActorAggregateException(ex.InnerExceptions.Select(x => x as ActorException)); var uex = new ZincAggregateException(ex.InnerExceptions[0] as ActorException, agg); context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, null, uex); } else { await journal.FullAsync(context, jrequest, null, uex); } throw uex; } else { var uex = new ZincException(ER.MethodInvoker_UnhandledException, ex, typeof(T).FullName, ex.Message); context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, null, uex); } else { await journal.FullAsync(context, jrequest, null, uex); } throw uex; } } catch (Exception ex) { var uex = new ZincException(ER.MethodInvoker_UnhandledException, ex, typeof(T).FullName, ex.Message); context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, null, uex); } else { await journal.FullAsync(context, jrequest, null, uex); } throw uex; } /* * We always expect a response: we should never accept a null response! */ if (response == null) { throw new ZincException(ER.MethodInvoker_ResponseIsNull, typeof(T).FullName); } /* * */ WalkFix(response); var jresponse = Secrets.Strip <Rp>(response); /* * Validate */ try { vr = Validator.Validate <Rp>(response); } catch (Exception ex) { var vex = new ZincException(ER.MethodInvoker_ResponseValidate, ex, request.GetType().FullName); context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, jresponse, vex); } else { await journal.FullAsync(context, jrequest, jresponse, vex); } throw vex; } if (vr.IsValid == false) { ActorAggregateException agex = new ActorAggregateException(vr.Errors); var vex = new ZincException(ER.MethodInvoker_ResponseInvalid, agex, request.GetType().FullName); context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, jresponse, vex); } else { await journal.FullAsync(context, jrequest, jresponse, vex); } throw vex; } /* * Post-log */ context.MomentEnd = PreciseDateTime.UtcNow; if (config.Type == MethodLoggingType.PrePost) { await journal.PostAsync(context, jresponse, null); } else { await journal.FullAsync(context, jrequest, jresponse, null); } return(response); }
public PadToAlignToSector(JournalConfiguration journalConfiguration) { _journalConfiguration = journalConfiguration; }
protected JournalFileWriter(JournalConfiguration journalConfiguration) { _journalConfiguration = journalConfiguration; }
public JournalReader(JournalConfiguration configuration, bool validateJournalSequence) { _journalIndexPathMap = GetJournalFileIndexMap(configuration, validateJournalSequence); }