Пример #1
0
        public static StandardReturType Validate <TOutput, TItem>(FacadeMethodInfo <TOutput, TItem> facade) where TOutput : class, IBasicOutput <TItem>, new()
        {
            // Initialize context
            try
            {
                BrokerContext.Initialize(facade.ApplicationToken, facade.UserToken);
            }
            catch (Exception ex)
            {
                return(StandardReturType.InvalidApplicationToken(facade.ApplicationToken));
            }

            // Validate
            StandardReturType validationRet = facade.ValidateInput();

            if (!StandardReturType.IsSucceeded(validationRet))
            {
                Local.Admin.AddNewLog(TraceEventType.Error, BrokerContext.Current.WebMethodMessageName, TextMessages.InvalidInput, null, null);
                if (validationRet == null)
                {
                    validationRet = StandardReturType.UnspecifiedError("Validation failed");
                }
                return(validationRet);
            }
            return(StandardReturType.OK());
        }
Пример #2
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
        }
Пример #3
0
        public static StandardReturType Initialize <TOutput, TItem>(FacadeMethodInfo <TOutput, TItem> facade, out SubMethodRunState[] subMethodRunStates) where TOutput : class, IBasicOutput <TItem>, new()
        {
            // Initialize facade method
            facade.Initialize();

            // have a list of data provider types and corresponding methods to call
            bool missingDataProvidersExist;

            subMethodRunStates = facade.CreateSubMethodRunStates(out missingDataProvidersExist);

            if (missingDataProvidersExist)
            {
                Local.Admin.AddNewLog(TraceEventType.Warning, BrokerContext.Current.WebMethodMessageName, TextMessages.NoDataProvidersFound, null, null);
                return(StandardReturType.Create(HttpErrorCode.DATASOURCE_UNAVAILABLE));
            }
            return(StandardReturType.OK());
        }
Пример #4
0
        public static TOutput GetMethodOutput <TOutput, TItem>(FacadeMethodInfo <TOutput, TItem> facade) where TOutput : class, IBasicOutput <TItem>, new()
        {
            try
            {
                StandardReturType   standardRetur;
                SubMethodRunState[] subMethodRunStates;

                standardRetur = Validate <TOutput, TItem>(facade);
                if (!StandardReturType.IsSucceeded(standardRetur))
                {
                    return(new TOutput()
                    {
                        StandardRetur = standardRetur
                    });
                }


                standardRetur = Initialize <TOutput, TItem>(facade, out subMethodRunStates);
                if (!StandardReturType.IsSucceeded(standardRetur))
                {
                    return(new TOutput()
                    {
                        StandardRetur = standardRetur
                    });
                }

                RunThreads <TOutput, TItem>(facade, subMethodRunStates);
                return(AggregateResults <TOutput, TItem>(facade, subMethodRunStates));
            }
            catch (Exception ex)
            {
                Local.Admin.LogException(ex);
                return(new TOutput()
                {
                    StandardRetur = StandardReturType.UnspecifiedError()
                });
            }
        }
Пример #5
0
        public static void RunThreads <TOutput, TItem>(FacadeMethodInfo <TOutput, TItem> facade, SubMethodRunState[] subMethodRunStates) where TOutput : class, IBasicOutput <TItem>, new()
        {
            #region Creation of sub results in threads
            // Catch the current broker context in a local variable
            var  currentBrokerContext = BrokerContext.Current;
            var  currentHttpContext   = System.Web.HttpContext.Current;
            long finishedThreads      = 0;
            // Now create the sub results
            for (int iSubMethod = 0; iSubMethod < subMethodRunStates.Length; iSubMethod++)
            {
                subMethodRunStates[iSubMethod].ThreadStart = new ParameterizedThreadStart((o) =>
                {
                    // Copy the broker context to this new thread
                    BrokerContext.Current           = currentBrokerContext;
                    System.Web.HttpContext.Current  = currentHttpContext;
                    SubMethodRunState subMethodInfo = subMethodRunStates[(int)o];
                    // Loop over clearData providers until one succeeds
                    foreach (IDataProvider prov in subMethodInfo.DataProviders)
                    {
                        try
                        {
                            object subResult = subMethodInfo.SubMethodInfo.Invoke(prov);
                            // See if result can be used to update local database
                            if (prov is IExternalDataProvider && subMethodInfo.SubMethodInfo.IsUpdatableOutput(subResult))
                            {
                                try
                                {
                                    subMethodInfo.SubMethodInfo.InvokeUpdateMethod(subResult);
                                }
                                catch (Exception updateException)
                                {
                                    string xml = Strings.SerializeObject(subResult);
                                    Local.Admin.LogException(updateException);
                                }
                            }
                            // Exit loop if succeeded
                            if (subMethodInfo.SubMethodInfo.IsSuccessfulOutput(subResult))
                            {
                                subMethodInfo.Result    = subResult;
                                subMethodInfo.Succeeded = true;
                                break;
                            }
                        }
                        catch (Exception dataProviderException)
                        {
                            Local.Admin.LogException(dataProviderException);
                        }
                    }

                    if (!subMethodInfo.Succeeded)
                    {
                        // TODO: Add something here to identify the input for which all data providers have failed
                        Local.Admin.AddNewLog(TraceEventType.Information, BrokerContext.Current.WebMethodMessageName, string.Format("{0}: {1}", TextMessages.AllDataProvidersFailed, subMethodInfo.SubMethodInfo.InputToString()), null, null);
                    }

                    // Signal the end of processing
                    System.Threading.Interlocked.Increment(ref finishedThreads);
                }
                                                                                          );

                if (subMethodRunStates.Length > 1)
                {
                    subMethodRunStates[iSubMethod].Thread = new Thread(subMethodRunStates[iSubMethod].ThreadStart);
                    subMethodRunStates[iSubMethod].Thread.Start(iSubMethod);
                }
            }
            #endregion

            #region Threads control
            if (subMethodRunStates.Length > 1)
            {
                // Wait for sub results to continue
                DateTime executionStartTime = DateTime.Now;

                while (System.Threading.Interlocked.Read(ref finishedThreads) < subMethodRunStates.Length && (DateTime.Now - executionStartTime).TotalMilliseconds < Config.Properties.Settings.Default.DataProviderMillisecondsTimeout)
                {
                    int waitMilliseconds = 100;
                    Thread.Sleep(waitMilliseconds);
                }
                foreach (var mi in subMethodRunStates)
                {
                    mi.Thread.Abort();
                }
            }
            else if (subMethodRunStates.Length == 1)
            {
                subMethodRunStates[0].ThreadStart.Invoke(0);
            }
            #endregion
        }
Пример #6
0
 public static TOutput GetMethodOutput <TOutput, TItem>(FacadeMethodInfo <TOutput, TItem> facade) where TOutput : class, IBasicOutput <TItem>, new()
 {
     return(CprBroker.Engine.Manager.GetMethodOutput <TOutput, TItem>(facade));
 }