Esempio n. 1
0
        /// <summary>
        /// Worker method to handle fualt and track if retry is needed
        /// </summary>
        /// <param name="state"></param>
        /// <param name="fault"></param>
        /// <returns></returns>
        private CTCRunMultipleResponse RunMultipleRequestsHandleFault(CTCRunMultipleState state, FaultException <OrganizationServiceFault> fault)
        {
            if (fault.Detail.ErrorDetails.Contains("MaxBatchSize"))
            {
                //return request index to last position
                state.RequestIndex -= state.BatchSize;
                var allowedBatchSize = Convert.ToInt32(fault.Detail.ErrorDetails["MaxBatchSize"]);
                if (state.TransactionMode != CTCBulkTransactionMode.Single)
                {
                    state.BatchSize = allowedBatchSize;
                    return(RunMultipleRequestsInternal(state));
                }
            }
            if (fault.Detail.ErrorDetails.Contains("Server Busy"))
            {
                //return request index to last position
                state.RequestIndex -= state.BatchSize;
                if (state.RetryCount == 0)
                {
                    state.Results.StoppedEarly = true;
                    return(state.Results);
                }

                Thread.Sleep(state.RetryDelaySeconds * 1000);
                state.RetryDelaySeconds = state.RetryDelaySeconds * 2;
                state.RetryCount--;
                return(RunMultipleRequestsInternal(state));
            }

            throw fault;
        }
Esempio n. 2
0
        /// <summary>
        /// Helper method called by public method manages faults - will recurse to handle faults
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        private CTCRunMultipleResponse RunMultipleRequestsInternal(CTCRunMultipleState state)
        {
            try
            {
                while (state.RequestIndex < state.Requests.Count)
                {
                    LogStatusStart(CrmBulkOpStatusType.BatchStart, "RunMultipleRequestsInternal", 0);;
                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    if (state.TransactionMode == CTCBulkTransactionMode.Single)
                    {
                        RunMultipleRequestsInternalBatchTransaction(state);
                    }
                    else
                    {
                        RunMultipleRequestsInternalBatch(state);
                    }

                    sw.Stop();
                    LogStatusEnd(CrmBulkOpStatusType.BatchEnd, "RunMultipleRequestsInternal", 0, sw.ElapsedMilliseconds);

                    if (state.Results.StoppedEarly)
                    {
                        return(state.Results);
                    }
                }
            }
            catch (FaultException <OrganizationServiceFault> fault)
            {
                return(RunMultipleRequestsHandleFault(state, fault));
            }

            state.Results.StoppedEarly = false;
            return(state.Results);
        }
Esempio n. 3
0
        private void RunMultipleRequestsExecuteMultiple(CTCRunMultipleState state, CTCRunMultipleTaskState currentTask, ExecuteMultipleRequest req)
        {
            try
            {
                var response = _Service.Execute(req) as ExecuteMultipleResponse;

                if (state.TransactionMode == CTCBulkTransactionMode.None)
                {
                    var requestList = currentTask.Requests.ToArray <OrganizationRequest>();

                    foreach (var item in response.Responses)
                    {
                        CTCRunMultipleResponseItem resultItem = new CTCRunMultipleResponseItem();
                        resultItem.Fault    = item.Fault;
                        resultItem.Request  = requestList[item.RequestIndex];
                        resultItem.Response = item.Response;
                        currentTask.Responses.Add(resultItem);
                    }
                }
                else
                {
                    var tranResponse = response.Responses.FirstOrDefault().Response as ExecuteTransactionResponse;
                    int requestIndex = 0;
                    foreach (var item in tranResponse.Responses)
                    {
                        var requestList = currentTask.Requests.ToArray <OrganizationRequest>();
                        CTCRunMultipleResponseItem resultItem = new CTCRunMultipleResponseItem();
                        resultItem.Request = requestList[requestIndex];
                        requestIndex++;
                        resultItem.Response = item;
                        currentTask.Responses.Add(resultItem);
                    }
                }
                if ((!state.ContinueOnError) && (response.IsFaulted))
                {
                    state.Results.StoppedEarly = true;
                }
            }

            catch (FaultException <OrganizationServiceFault> fault)
            {
                RunMultipleRequestsHandleFault(state, fault);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Worker method to run multiple requests used by all helper methods but can be used standalone to invoke any series of CRM Organization Requests
        /// </summary>
        /// <param name="requests"></param>
        /// <param name="batchSize"></param>
        /// <param name="returnResponses"></param>
        /// <param name="continueOnError"></param>
        /// <param name="retryCount"></param>
        /// <param name="retrySeconds"></param>
        /// <param name="transactionMode"></param>
        /// <returns></returns>
        public CTCRunMultipleResponse RunMultipleRequests(List <OrganizationRequest> requests, int batchSize = 100,
                                                          bool returnResponses = true, bool continueOnError = true, int retryCount = 3, int retrySeconds = 10,
                                                          CTCBulkTransactionMode transactionMode = CTCBulkTransactionMode.None)
        {
            CTCRunMultipleState state = new CTCRunMultipleState();

            state.RequestIndex        = 0;
            state.Results             = new CTCRunMultipleResponse();
            state.Results.ResultItems = new List <CTCRunMultipleResponseItem>();
            state.RetryCount          = retryCount;
            state.RetryDelaySeconds   = retrySeconds;
            state.BatchSize           = batchSize;
            state.ContinueOnError     = continueOnError;
            state.ReturnResponses     = true;
            state.TransactionMode     = transactionMode;
            state.Requests            = requests;


            return(RunMultipleRequestsInternal(state));
        }
Esempio n. 5
0
        private void RunMultipleRequestsInternalBatchTransaction(CTCRunMultipleState state)
        {
            CTCRunMultipleTaskState taskState = new CTCRunMultipleTaskState();

            taskState.Service         = _Service;
            taskState.ReturnResponses = state.ReturnResponses;
            taskState.ContinueOnError = state.ContinueOnError;
            taskState.Requests        = state.Requests.Skip(state.RequestIndex).Take(state.BatchSize);
            state.RequestIndex       += state.BatchSize;
            taskState.Responses       = new List <CTCRunMultipleResponseItem>();

            ExecuteTransactionRequest req = new ExecuteTransactionRequest()
            {
                Requests = new OrganizationRequestCollection()
            };

            req.Requests.AddRange(taskState.Requests);
            try
            {
                var response = _Service.Execute(req) as ExecuteTransactionResponse;
                int reqIndex = 0;
                foreach (var item in response.Responses)
                {
                    CTCRunMultipleResponseItem resultItem = new CTCRunMultipleResponseItem();
                    resultItem.Request = req.Requests[reqIndex];
                    reqIndex++;
                    resultItem.Response = item;
                    taskState.Responses.Add(resultItem);
                }
            }

            catch (FaultException <OrganizationServiceFault> fault)
            {
                RunMultipleRequestsHandleFault(state, fault);
            }

            state.Results.ResultItems.AddRange(taskState.Responses);
        }
Esempio n. 6
0
        /// <summary>
        /// Worker method to process batch of requests
        /// </summary>
        /// <param name="state"></param>
        private void RunMultipleRequestsInternalBatch(CTCRunMultipleState state)
        {
            var taskStateList = new List <CTCRunMultipleTaskState>();

            foreach (var service in _Services)
            {
                CTCRunMultipleTaskState taskState = new CTCRunMultipleTaskState();
                taskState.Service         = service;
                taskState.ReturnResponses = state.ReturnResponses;
                taskState.ContinueOnError = state.ContinueOnError;
                taskState.Requests        = state.Requests.Skip(state.RequestIndex).Take(state.BatchSize);
                state.RequestIndex       += state.BatchSize;
                taskState.Responses       = new List <CTCRunMultipleResponseItem>();
                taskStateList.Add(taskState);
            }
            Parallel.ForEach <CTCRunMultipleTaskState>(taskStateList, new ParallelOptions {
                MaxDegreeOfParallelism = _Services.Count
            }, currentTask =>
            {
                if (currentTask.Requests.Count() > 1)
                {
                    ExecuteMultipleRequest req = new ExecuteMultipleRequest()
                    {
                        Settings = new ExecuteMultipleSettings(), Requests = new OrganizationRequestCollection()
                    };
                    req.Settings.ContinueOnError = currentTask.ContinueOnError;
                    req.Settings.ReturnResponses = currentTask.ReturnResponses;
                    if (state.TransactionMode == CTCBulkTransactionMode.None)
                    {
                        req.Requests.AddRange(currentTask.Requests);
                    }
                    else
                    {
                        ExecuteTransactionRequest tranRequest = new ExecuteTransactionRequest()
                        {
                            Requests = new OrganizationRequestCollection()
                        };
                        tranRequest.Requests.AddRange(currentTask.Requests);
                        tranRequest.ReturnResponses = state.ReturnResponses;
                        req.Requests.Add(tranRequest);
                        req.Settings.ReturnResponses = true;
                    }
                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    LogStatusStart(CrmBulkOpStatusType.ThreadStart, "RunMultipleRequestsInternalBatch", currentTask.Requests.Count());
                    RunMultipleRequestsExecuteMultiple(state, currentTask, req);
                    sw.Stop();
                    LogStatusEnd(CrmBulkOpStatusType.ThreadEnd, "RunMultipleRequestsInternalBatch", currentTask.Requests.Count(), sw.ElapsedMilliseconds);
                }
                else
                {
                    var request = currentTask.Requests.FirstOrDefault();
                    if (request != null)
                    {
                        var response = _Service.Execute(request);

                        CTCRunMultipleResponseItem resultItem = new CTCRunMultipleResponseItem();
                        resultItem.Fault    = null;
                        resultItem.Request  = request;
                        resultItem.Response = response;
                        currentTask.Responses.Add(resultItem);
                    }
                }
            });

            foreach (var task in taskStateList)
            {
                state.Results.ResultItems.AddRange(task.Responses);
            }
        }