コード例 #1
0
        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);
        }
コード例 #2
0
 public UnbufferedJournalFileWriter(JournalConfiguration journalConfiguration)
     : base(journalConfiguration)
 {
 }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
 public PadToAlignToSector(JournalConfiguration journalConfiguration)
 {
     _journalConfiguration = journalConfiguration;
 }
コード例 #5
0
 protected JournalFileWriter(JournalConfiguration journalConfiguration)
 {
     _journalConfiguration = journalConfiguration;
 }
コード例 #6
0
 public JournalReader(JournalConfiguration configuration, bool validateJournalSequence)
 {
     _journalIndexPathMap = GetJournalFileIndexMap(configuration, validateJournalSequence);
 }