protected async Task <IActionResult> RunTrigger(HttpRequest req, IDurableOrchestrationClient starter, int version, string entityId, ILogger log)
        {
            req.ApplyThreadCulture();

            var changeRequest = await req.ReadAsObjectAsync <ChangeRequest>(_workforceIntegrationOptions.WorkforceIntegrationSecret).ConfigureAwait(false);

            ChangeResponse changeResponse = new ChangeResponse(changeRequest);

            if (IsPassThroughRequest(req.Headers))
            {
                // as this change has occurred as a result of a connector action, bypass all further processing
                return(new ChangeSuccessResult(changeResponse));
            }

            log.LogChangeRequest(changeRequest, entityId);

            if (!TryValidateChangeRequest(changeRequest, version, entityId, log, out var validationResponse))
            {
                return(validationResponse);
            }

            IActionResult actionResult = null;

            try
            {
                bool handled = false;
                foreach (var handler in _handlers)
                {
                    if (handler.CanHandleChangeRequest(changeRequest, out var changeItemRequest))
                    {
                        log.LogTrace("Change Request handled by: {handlerName}", handler.GetType().Name);
                        if (TryValidateChangeItemRequest(changeItemRequest, changeResponse, out validationResponse))
                        {
                            actionResult = await handler.HandleRequest(changeRequest, changeItemRequest, changeResponse, entityId, log, starter).ConfigureAwait(false);
                        }
                        else
                        {
                            actionResult = validationResponse;
                        }
                        handled = true;
                        break;
                    }
                }

                if (!handled)
                {
                    // we have no handler for this.
                    actionResult = new ChangeErrorResult(changeResponse, ErrorCodes.UnsupportedOperation, _stringLocalizer[ErrorCodes.UnsupportedOperation], HttpStatusCode.Forbidden);
                }
            }
            catch (Exception ex)
            {
                log.LogChangeError(ex, entityId);
                actionResult = new ChangeErrorResult(changeResponse, ErrorCodes.InternalError, _stringLocalizer[ErrorCodes.InternalError], HttpStatusCode.InternalServerError);
            }

            log.LogChangeResult(actionResult);

            return(actionResult);
        }
        private bool TryValidateChangeItemRequest(ChangeItemRequest changeItemRequest, ChangeResponse changeResponse, out IActionResult validationResponse)
        {
            validationResponse = null;

            if (changeItemRequest.Headers == null || changeItemRequest.Headers.Count == 0)
            {
                return(true);
            }

            if (changeItemRequest.Headers.Expires.HasValue && DateTime.UtcNow > changeItemRequest.Headers.Expires.Value)
            {
                validationResponse = new ChangeErrorResult(changeResponse, changeItemRequest, ErrorCodes.RequestExpired, _stringLocalizer[ErrorCodes.RequestExpired]);
                return(false);
            }

            return(true);
        }