Example #1
0
        public static TOutput AggregateResults <TOutput, TItem>(FacadeMethodInfo <TOutput, TItem> facade, SubMethodRunState[] subMethodRunStates) where TOutput : class, IBasicOutput <TItem>, new()
        {
            #region Final aggregation

            var succeededCount = (from mi in subMethodRunStates where mi.Succeeded select mi).Count();
            var subResults     = (from mi in subMethodRunStates select mi.Result).ToArray();

            bool canAggregate = facade.AggregationFailOption == AggregationFailOption.FailNever ||
                                facade.AggregationFailOption == AggregationFailOption.FailOnAll && succeededCount > 0 ||
                                facade.AggregationFailOption == AggregationFailOption.FailOnAny && succeededCount == subMethodRunStates.Length;

            if (canAggregate)
            {
                var outputMainItem = facade.Aggregate(subResults);
                if (facade.IsValidResult(outputMainItem))
                {
                    Local.Admin.AddNewLog(TraceEventType.Information, BrokerContext.Current.WebMethodMessageName, TextMessages.Succeeded, null, null);
                    var output = new TOutput();
                    output.SetMainItem(outputMainItem);
                    if (succeededCount == subMethodRunStates.Length)
                    {
                        output.StandardRetur = StandardReturType.OK();
                    }
                    else
                    {
                        var failedSubMethods         = subMethodRunStates.Where(smi => !smi.Succeeded).Select(smi => smi.SubMethodInfo);
                        var failedSubMethodsByReason = failedSubMethods.GroupBy(smi => smi.PossibleErrorReason());
                        var failuresAndReasons       = failedSubMethodsByReason.ToDictionary(grp => grp.Key, grp => grp.Select(smi => smi.InputToString()));
                        output.StandardRetur = StandardReturType.PartialSuccess(failuresAndReasons);
                    }

                    return(output);
                }
                else
                {
                    string xml = Strings.SerializeObject(outputMainItem);
                    Local.Admin.AddNewLog(TraceEventType.Error, BrokerContext.Current.WebMethodMessageName, TextMessages.ResultGatheringFailed, typeof(TOutput).ToString(), xml);
                    return(new TOutput()
                    {
                        StandardRetur = StandardReturType.UnspecifiedError("Aggregation failed")
                    });
                }
            }
            else
            {
                // TODO: Is it possible to put details why each item has failed?
                return(new TOutput()
                {
                    StandardRetur = StandardReturType.Create(HttpErrorCode.DATASOURCE_UNAVAILABLE)
                });
            }
            #endregion
        }
Example #2
0
        public TOutput Aggregate <TOutput>(Element[] elements)
            where TOutput : IBasicOutput <TOutputElement[]>, new()
        {
            // Set output item - only copy succeeded elements
            var ret = new TOutput();

            ret.Item = elements.Select(
                s => this.IsElementSucceeded(s) ? s.Output : default(TOutputElement)
                ).ToArray();

            // Set standard return
            var failed         = elements.Where(s => !IsElementSucceeded(s)).ToArray();
            var succeededCount = elements.Length - failed.Length;

            if (succeededCount == 0)
            {
                ret.StandardRetur = StandardReturType.Create(HttpErrorCode.DATASOURCE_UNAVAILABLE);
            }
            else if (succeededCount < elements.Length)
            {
                var failuresAndReasons = failed
                                         .GroupBy(s => s.PossibleErrorReason)
                                         .ToDictionary(
                    g => g.Key,
                    g => g.ToArray()
                    .Select(s => string.Format("{0}", s.Input))
                    );
                ret.StandardRetur = StandardReturType.PartialSuccess(failuresAndReasons);
            }
            else
            {
                ret.StandardRetur = StandardReturType.OK();
            }

            // final return
            return(ret);
        }
Example #3
0
        public TOutput Run <TOutput>(IEnumerable <TInterface> providers) where TOutput : IBasicOutput <TSingleOutputItem[]>, new()
        {
            foreach (var prov in providers)
            {
                var currentStates = States
                                    .Where(s => !IsSucceededStatus(s)).ToArray();

                if (currentStates.Length == 0)
                {
                    break;
                }

                var currentInput = currentStates
                                   .Select(kvp => kvp.Input).ToArray();

                try
                {
                    var currentOutput          = Run(prov, currentInput);
                    var currentSucceededStates = new List <Status>();
                    for (int i = 0; i < currentStates.Length; i++)
                    {
                        currentStates[i].Output = currentOutput[i];
                        if (IsSucceededStatus(currentStates[i]))
                        {
                            currentSucceededStates.Add(currentStates[i]);
                        }
                    }

                    if (prov is IExternalDataProvider)
                    {
                        InvokeUpdateMethod(
                            currentSucceededStates.Select(s => s.Input).ToArray(),
                            currentSucceededStates.Select(s => s.Output).ToArray()
                            );
                    }
                }
                catch (Exception ex)
                {
                    Local.Admin.LogException(ex);
                }
            }

            // Now create the result
            var failed         = States.Where(s => !IsSucceededStatus(s)).ToArray();
            var result         = States.Select(s => s.Output).ToArray();
            var succeededCount = States.Length - failed.Length;

            var ret = new TOutput();

            ret.SetMainItem(result);

            if (succeededCount == 0)
            {
                ret.StandardRetur = StandardReturType.Create(HttpErrorCode.DATASOURCE_UNAVAILABLE);
            }
            else if (succeededCount < States.Length)
            {
                var failuresAndReasons = failed
                                         .GroupBy(s => s.PossibleErrorReason)
                                         .ToDictionary(
                    g => g.Key,
                    g => g.ToArray()
                    .Select(s => string.Format("{0}", s.Input))
                    );
                ret.StandardRetur = StandardReturType.PartialSuccess(failuresAndReasons);
            }
            else
            {
                ret.StandardRetur = StandardReturType.OK();
            }
            return(ret);
        }