Esempio n. 1
0
        public async void OnDomainChangeRaised(bool async)
        {
            // Arrange
            var shareFileClient = GetShareFileClient(true);

            ConfigureDomainChangedResponse();

            var changeDomainRaised = false;

            shareFileClient.AddChangeDomainHandler((message, redirect) =>
            {
                changeDomainRaised = true;
                ConfigureItemResponse();
                return(EventHandlerResponse.Redirect(redirect));
            });

            var query = shareFileClient.Items.Get(shareFileClient.Items.GetAlias(GetId()));

            // Act
            if (async)
            {
                await query.ExecuteAsync();
            }
            else
            {
                query.Execute();
            }

            // Assert
            changeDomainRaised.Should().BeTrue();
        }
Esempio n. 2
0
    public void IterationSetup()
    {
        var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
        var numEventsProcessed = 0;

        _dispatcher = new Mock <ReverseCallDispatcher>();
        _dispatcher
        .Setup(_ => _.Reject(It.IsAny <EventHandlerRegistrationResponse>(), It.IsAny <CancellationToken>()))
        .Returns(Task.CompletedTask);
        _dispatcher
        .Setup(_ => _.Accept(It.IsAny <EventHandlerRegistrationResponse>(), It.IsAny <CancellationToken>()))
        .Returns(tcs.Task);
        _dispatcher
        .Setup(_ => _.Call(It.IsAny <HandleEventRequest>(), It.IsAny <Dolittle.Runtime.Execution.ExecutionContext>(), It.IsAny <CancellationToken>()))
        .Returns <HandleEventRequest, Dolittle.Runtime.Execution.ExecutionContext, CancellationToken>((request, _, __) =>
        {
            Interlocked.Add(ref numEventsProcessed, 1);
            var response = new EventHandlerResponse();
            if (numEventsProcessed == NumberEventsToProcess)
            {
                tcs.SetResult();
            }
            return(Task.FromResult(response));
        });

        var eventHandlers = new List <IEventHandler>();

        eventHandlers.AddRange(Enumerable.Range(0, EventHandlers).Select(_ => _eventHandlerFactory.Create(
                                                                             new EventHandlerRegistrationArguments(Runtime.CreateExecutionContextFor("d9fd643f-ce74-4ae5-b706-b76859fd8827"), Guid.NewGuid(), _eventTypes, Partitioned, ScopeId.Default),
                                                                             _dispatcher.Object,
                                                                             CancellationToken.None)));
        _eventHandlersToRun = eventHandlers;
    }
        private EventHandlerResponse GetRedirectionAction(
            Response <ODataObject> response,
            HttpResponseMessage responseMessage,
            HttpRequestMessage httpRequestMessage)
        {
            EventHandlerResponse action;
            var redirection = response.Value as Redirection;

            // Removed until API is updated to provide this correctly.
            // !redirection.Available ||
            if (redirection.Uri == null)
            {
                throw new ZoneUnavailableException(responseMessage.RequestMessage.RequestUri, "Destination zone is unavailable");
            }

            if (httpRequestMessage.RequestUri.GetAuthority() != redirection.Uri.GetAuthority())
            {
                action = this.ShareFileClient.OnChangeDomain(httpRequestMessage, redirection);
            }
            else
            {
                action = EventHandlerResponse.Redirect(redirection);
            }
            return(action);
        }
        private Response Execute <TResponse>(QueryBase query, Func <HttpResponseMessage, TResponse> parseSuccessResponse)
            where TResponse : Response
        {
            EventHandlerResponse action = null;
            int retryCount = 0;

            do
            {
                var requestRoundtripWatch = new ActionStopwatch("RequestRoundTrip", ShareFileClient.Logging);

                var apiRequest = ApiRequest.FromQuery(query);

                if (action != null && action.Redirection != null)
                {
                    apiRequest.IsComposed = true;
                    apiRequest.Uri        = action.Redirection.GetCalculatedUri();
                    apiRequest.Body       = action.Redirection.Body;
                    apiRequest.HttpMethod = action.Redirection.Method ?? "GET";
                }

                var httpRequestMessage = BuildRequest(apiRequest);

                if (httpRequestMessage.RequestUri.AbsolutePath.Contains("Sessions/Login"))
                {
                    var authorizationHeader = GetAuthorizationHeaderValue(httpRequestMessage.RequestUri, "Bearer");

                    if (authorizationHeader != null)
                    {
                        httpRequestMessage.Headers.Authorization = authorizationHeader;
                        httpRequestMessage.Headers.Add("X-SFAPI-Tool", ShareFileClient.Configuration.ToolName);
                        httpRequestMessage.Headers.Add("X-SFAPI-ToolVersion", ShareFileClient.Configuration.ToolVersion);
                    }
                }

                var responseMessage = ExecuteRequest(httpRequestMessage, GetCompletionOptionFromResponse(typeof(TResponse)));

                action = null;

                try
                {
                    var response = HandleResponse(responseMessage, parseSuccessResponse, apiRequest, retryCount++);
                    if (response.Action != null)
                    {
                        action = response.Action;
                    }
                    else
                    {
                        return(response);
                    }
                }
                finally
                {
                    requestRoundtripWatch.Stop();
                }
            } while (action != null && (action.Action == EventHandlerResponseAction.Retry || action.Action == EventHandlerResponseAction.Redirect));

            return(Response.CreateAction(action)); //when do we get here? ignore?
        }
        public async Task <Stream> ExecuteAsync(
            IQuery <Stream> query,
            CancellationToken token = default(CancellationToken))
        {
            EventHandlerResponse action = null;
            int retryCount = 0;

            do
            {
                var requestRoundtripWatch = new ActionStopwatch("RequestRoundTrip", ShareFileClient.Logging, RequestId);

                var apiRequest = ApiRequest.FromQuery(query as QueryBase, RequestId);
                if (action != null && action.Redirection != null)
                {
                    apiRequest.IsComposed = true;
                    apiRequest.Uri        = action.Redirection.GetCalculatedUri();
                    apiRequest.Body       = action.Redirection.Body;
                    apiRequest.HttpMethod = action.Redirection.Method ?? "GET";
                }

                action = null;

                var httpRequestMessage = BuildRequest(apiRequest);
                var responseMessage    = await ExecuteRequestAsync(httpRequestMessage, GetCompletionOptionForQuery(typeof(Stream)), token : token).ConfigureAwait(false);

                try
                {
                    var response = await HandleStreamResponse(responseMessage, apiRequest, retryCount ++).ConfigureAwait(false);

                    if (response.Value != null)
                    {
                        return(response.Value);
                    }
                    else
                    {
                        action = response.Action;
                    }
                }
                finally
                {
                    ShareFileClient.Logging.Trace(requestRoundtripWatch);
                }
            }while (action != null && (action.Action == EventHandlerResponseAction.Retry || action.Action == EventHandlerResponseAction.Redirect));

            ShareFileClient.Logging.Error($"App should throw or return before getting to this point. Query: {query}");
            throw new InvalidOperationException("We should throw or return before getting here.");
        }
        public async Task <Stream> ExecuteAsync(
            IQuery <Stream> query,
            CancellationToken?token = null)
        {
            EventHandlerResponse action = null;
            int retryCount = 0;

            do
            {
                var requestRoundtripWatch = new ActionStopwatch("RequestRoundTrip", ShareFileClient.Logging);

                var apiRequest = ApiRequest.FromQuery(query as QueryBase);
                if (action != null && action.Redirection != null && action.Redirection.Body != null)
                {
                    apiRequest.IsComposed = true;
                    apiRequest.Uri        = action.Redirection.Uri;
                    apiRequest.Body       = action.Redirection.Body;
                    apiRequest.HttpMethod = action.Redirection.Method ?? "GET";
                }

                action = null;

                var httpRequestMessage = BuildRequest(apiRequest);
                var responseMessage    = await ExecuteRequestAsync(httpRequestMessage, GetCompletionOptionForQuery(typeof(Stream)), token).ConfigureAwait(false);

                try
                {
                    var response = await HandleStreamResponse(responseMessage, apiRequest, retryCount ++);

                    if (response.Value != null)
                    {
                        return(response.Value);
                    }
                    else
                    {
                        action = response.Action;
                    }
                }
                finally
                {
                    requestRoundtripWatch.Stop();
                }
            } while (action != null && (action.Action == EventHandlerResponseAction.Retry || action.Action == EventHandlerResponseAction.Redirect));

            return(default(Stream));
        }
        private Response Execute <TResponse>(QueryBase query, Func <HttpResponseMessage, TResponse> parseSuccessResponse)
            where TResponse : Response
        {
            EventHandlerResponse action = null;
            int retryCount = 0;

            do
            {
                var requestRoundtripWatch = new ActionStopwatch("RequestRoundTrip", ShareFileClient.Logging, RequestId);

                var apiRequest = ApiRequest.FromQuery(query, RequestId);

                if (action != null && action.Redirection != null)
                {
                    apiRequest.IsComposed = true;
                    apiRequest.Uri        = action.Redirection.GetCalculatedUri();
                    apiRequest.Body       = action.Redirection.Body;
                    apiRequest.HttpMethod = action.Redirection.Method ?? "GET";
                }

                var httpRequestMessage = BuildRequest(apiRequest);

                var responseMessage = ExecuteRequest(httpRequestMessage, GetCompletionOptionFromResponse(typeof(TResponse)));

                action = null;

                try
                {
                    var response = HandleResponse(responseMessage, parseSuccessResponse, apiRequest, retryCount++);
                    if (response.Action != null)
                    {
                        action = response.Action;
                    }
                    else
                    {
                        return(response);
                    }
                }
                finally
                {
                    ShareFileClient.Logging.Trace(requestRoundtripWatch);
                }
            } while (action != null && (action.Action == EventHandlerResponseAction.Retry || action.Action == EventHandlerResponseAction.Redirect));

            return(Response.CreateAction(action)); //when do we get here? ignore?
        }
        public async Task ExecuteAsync(IQuery query, CancellationToken token = default(CancellationToken))
        {
            EventHandlerResponse action = null;
            int retryCount = 0;

            do
            {
                var requestRoundtripWatch = new ActionStopwatch("RequestRoundTrip", ShareFileClient.Logging, RequestId);

                var apiRequest = ApiRequest.FromQuery(query as QueryBase, RequestId);
                if (action != null && action.Redirection != null)
                {
                    apiRequest.IsComposed = true;
                    apiRequest.Uri        = action.Redirection.GetCalculatedUri();
                    apiRequest.Body       = action.Redirection.Body;
                    apiRequest.HttpMethod = action.Redirection.Method ?? "GET";
                }

                var httpRequestMessage = BuildRequest(apiRequest);
                var responseMessage    = await ExecuteRequestAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead, token : token).ConfigureAwait(false);

                action = null;

                try
                {
                    var response = await HandleResponse(responseMessage, apiRequest, retryCount ++).ConfigureAwait(false);

                    if (response.Action != null)
                    {
                        action = response.Action;
                    }
                }
                finally
                {
                    ShareFileClient.Logging.Trace(requestRoundtripWatch);
                }
            } while (action != null && (action.Action == EventHandlerResponseAction.Retry || action.Action == EventHandlerResponseAction.Redirect));
        }
        public async Task <T> ExecuteAsync <T>(IQuery <T> query, CancellationToken token = default(CancellationToken))
            where T : class
        {
            var streamQuery = query as IQuery <Stream>;

            if (streamQuery != null)
            {
                return((T)(object)(await ExecuteAsync(streamQuery, token).ConfigureAwait(false)));
            }

            EventHandlerResponse action = null;
            int retryCount = 0;

            do
            {
                var requestRoundtripWatch = new ActionStopwatch("RequestRoundTrip", ShareFileClient.Logging, RequestId);

                var apiRequest = ApiRequest.FromQuery(query as QueryBase, RequestId);

                if (action != null && action.Redirection != null)
                {
                    apiRequest.IsComposed = true;
                    apiRequest.Uri        = action.Redirection.GetCalculatedUri();
                    apiRequest.Body       = action.Redirection.Body;
                    apiRequest.HttpMethod = action.Redirection.Method ?? "GET";
                }

                var httpRequestMessage = BuildRequest(apiRequest);

                var responseMessage = await ExecuteRequestAsync(httpRequestMessage, GetCompletionOptionForQuery(typeof(T)), token : token).ConfigureAwait(false);

                action = null;

                try
                {
                    if (typeof(T).IsSubclassOf(typeof(ODataObject)))
                    {
                        var response = await HandleTypedResponse <ODataObject>(responseMessage, apiRequest, retryCount ++).ConfigureAwait(false);

                        if (response.Value != null)
                        {
                            string redirectUri;
                            if (response.Value is ODataObject && response.Value.TryGetProperty("Uri", out redirectUri))
                            {
                                var redirect = new Redirection
                                {
                                    Uri = new Uri(redirectUri)
                                };

                                string redirectRoot;
                                if (response.Value.TryGetProperty("Root", out redirectRoot))
                                {
                                    redirect.Root = redirectRoot;
                                }

                                response.Value = redirect;
                            }

                            if (response.Value is Redirection && typeof(T) != typeof(Redirection))
                            {
                                action = GetRedirectionAction(response, responseMessage, httpRequestMessage);
                            }
                            else if (response.Value is AsyncOperation && typeof(T) != typeof(AsyncOperation))
                            {
                                throw new AsyncOperationScheduledException(
                                          new ODataFeed <AsyncOperation>()
                                {
                                    Feed = new[] { (AsyncOperation)response.Value }
                                });
                            }
                            else
                            {
                                return((T)(object)response.Value);
                            }
                        }
                        else
                        {
                            action = response.Action;
                        }
                    }
                    else
                    {
                        var response = await HandleTypedResponse <T>(responseMessage, apiRequest, retryCount ++).ConfigureAwait(false);

                        if (response.Value != null)
                        {
                            return(response.Value);
                        }
                        else
                        {
                            action = response.Action;
                        }
                    }
                }
                finally
                {
                    ShareFileClient.Logging.Trace(requestRoundtripWatch);
                }
            } while (action != null && (action.Action == EventHandlerResponseAction.Retry || action.Action == EventHandlerResponseAction.Redirect));

            ShareFileClient.Logging.Error($"App should throw or return before getting to this point. Query: {query}");
            throw new InvalidOperationException("We should throw or return before getting here.");
        }
        private Response <T> ParseTypedResponse <T>(HttpResponseMessage httpResponseMessage)
            where T : class
        {
            var watch = new ActionStopwatch("ProcessResponse", ShareFileClient.Logging);

            var responseStream = httpResponseMessage.Content.ReadAsStreamAsync().WaitForTask();

            if (responseStream != null)
            {
                if (typeof(T).IsSubclassOf(typeof(ODataObject)))
                {
                    var result = DeserializeStream <ODataObject>(responseStream);

                    LogResponse(result, httpResponseMessage.RequestMessage.RequestUri, httpResponseMessage.Headers.ToString(), httpResponseMessage.StatusCode);
                    ShareFileClient.Logging.Trace(watch);

                    CheckAsyncOperationScheduled(result);

                    //workaround for metadata not returning on Redirections
                    string redirectUri;
                    if (result is ODataObject && result.TryGetProperty("Uri", out redirectUri))
                    {
                        result = new Redirection {
                            Uri = new Uri(redirectUri)
                        };
                    }

                    if (result is Redirection && typeof(T) != typeof(Redirection))
                    {
                        var redirection = result as Redirection;

                        // Removed until API is updated to provide this correctly.
                        // !redirection.Available ||
                        if (redirection.Uri == null)
                        {
                            throw new ZoneUnavailableException(httpResponseMessage.RequestMessage.RequestUri, "Destination zone is unavailable");
                        }

                        if (httpResponseMessage.RequestMessage.RequestUri.GetAuthority() != redirection.Uri.GetAuthority())
                        {
                            return(Response.CreateAction <T>(ShareFileClient.OnChangeDomain(httpResponseMessage.RequestMessage, redirection)));
                        }
                        else
                        {
                            return(Response.CreateAction <T>(EventHandlerResponse.Redirect(redirection)));
                        }
                    }
                    else if (result is T)
                    {
                        return(Response.CreateSuccess(result as T));
                    }
                    else
                    {
                        throw new InvalidApiResponseException(httpResponseMessage.StatusCode, "Unable to parse API return to desired type");
                    }
                }
                else
                {
                    var result = DeserializeStream <T>(responseStream);
                    LogResponse(result, httpResponseMessage.RequestMessage.RequestUri, httpResponseMessage.Headers.ToString(), httpResponseMessage.StatusCode);
                    ShareFileClient.Logging.Trace(watch);

                    return(Response.CreateSuccess(result));
                }
            }

            ShareFileClient.Logging.Trace(watch);

            throw new InvalidApiResponseException(httpResponseMessage.StatusCode, "Unable to read response stream");
        }
        public async Task <T> ExecuteAsync <T>(IQuery <T> query, CancellationToken?token = null)
            where T : class
        {
            var streamQuery = query as IQuery <Stream>;

            if (streamQuery != null)
            {
                return(await this.ExecuteAsync(streamQuery, token) as T);
            }

            EventHandlerResponse action = null;
            int retryCount = 0;

            do
            {
                var requestRoundtripWatch = new ActionStopwatch("RequestRoundTrip", ShareFileClient.Logging);

                var apiRequest = ApiRequest.FromQuery(query as QueryBase);

                if (action != null && action.Redirection != null)
                {
                    apiRequest.IsComposed = true;
                    apiRequest.Uri        = action.Redirection.GetCalculatedUri();
                    apiRequest.Body       = action.Redirection.Body;
                    apiRequest.HttpMethod = action.Redirection.Method ?? "GET";
                }

                var httpRequestMessage = BuildRequest(apiRequest);

                if (httpRequestMessage.RequestUri.AbsolutePath.Contains("Sessions/Login"))
                {
                    var authorizationHeader = GetAuthorizationHeaderValue(httpRequestMessage.RequestUri, "Bearer");

                    if (authorizationHeader != null)
                    {
                        httpRequestMessage.Headers.Authorization = authorizationHeader;
                        httpRequestMessage.Headers.Add("X-SFAPI-Tool", ShareFileClient.Configuration.ToolName);
                        httpRequestMessage.Headers.Add("X-SFAPI-ToolVersion", ShareFileClient.Configuration.ToolVersion);
                    }
                }

                var responseMessage = await ExecuteRequestAsync(httpRequestMessage, GetCompletionOptionForQuery(typeof(T)), token);

                action = null;

                try
                {
                    if (typeof(T).IsSubclassOf(typeof(ODataObject)))
                    {
                        var response = await HandleTypedResponse <ODataObject>(responseMessage, apiRequest, retryCount ++).ConfigureAwait(false);

                        if (response.Value != null)
                        {
                            string redirectUri;
                            if (response.Value is ODataObject && response.Value.TryGetProperty("Uri", out redirectUri))
                            {
                                response.Value = new Redirection
                                {
                                    Uri = new Uri(redirectUri)
                                };
                            }

                            if (response.Value is Redirection && typeof(T) != typeof(Redirection))
                            {
                                var redirection = response.Value as Redirection;

                                // Removed until API is updated to provide this correctly.
                                // !redirection.Available ||
                                if (redirection.Uri == null)
                                {
                                    throw new ZoneUnavailableException(responseMessage.RequestMessage.RequestUri, "Destination zone is unavailable");
                                }

                                if (httpRequestMessage.RequestUri.GetAuthority() != redirection.Uri.GetAuthority())
                                {
                                    action = ShareFileClient.OnChangeDomain(httpRequestMessage, redirection);
                                }
                                else
                                {
                                    action = EventHandlerResponse.Redirect(redirection);
                                }
                            }
                            else
                            {
                                return(response.Value as T);
                            }
                        }
                        else
                        {
                            action = response.Action;
                        }
                    }
                    else
                    {
                        var response = await HandleTypedResponse <T>(responseMessage, apiRequest, retryCount ++).ConfigureAwait(false);

                        if (response.Value != null)
                        {
                            return(response.Value);
                        }
                        else
                        {
                            action = response.Action;
                        }
                    }
                }
                finally
                {
                    requestRoundtripWatch.Stop();
                }
            } while (action != null && (action.Action == EventHandlerResponseAction.Retry || action.Action == EventHandlerResponseAction.Redirect));

            return(default(T));
        }