Beispiel #1
0
        public async Task TestRetries()
        {
            int run = 0;
            Func <HttpRequestMessage, Task <HttpResponseMessage> > sendFunc = async request =>
            {
                string content = await request.Content.ReadAsStringAsync();

                Assert.AreEqual("content1", content);

                if (run == 0)
                {
                    run++;
                    throw new WebException("", WebExceptionStatus.ConnectFailure);
                }
                else
                {
                    return(new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new StringContent("Response")
                    });
                }
            };

            Mock <IDocumentClientInternal> mockDocumentClient = new Mock <IDocumentClientInternal>();

            mockDocumentClient.Setup(client => client.ServiceEndpoint).Returns(new Uri("https://foo"));

            GlobalEndpointManager     endpointManager  = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy());
            DocumentClientEventSource envetSource      = new DocumentClientEventSource();
            ISessionContainer         sessionContainer = new SessionContainer(string.Empty);
            DocumentClientEventSource eventSource      = new DocumentClientEventSource();
            HttpMessageHandler        messageHandler   = new MockMessageHandler(sendFunc);
            GatewayStoreModel         storeModel       = new GatewayStoreModel(
                endpointManager,
                sessionContainer,
                TimeSpan.FromSeconds(5),
                ConsistencyLevel.Eventual,
                eventSource,
                new UserAgentContainer(),
                ApiType.None,
                messageHandler);

            using (DocumentServiceRequest request =
                       DocumentServiceRequest.Create(
                           Cosmos.Internal.OperationType.Query,
                           Cosmos.Internal.ResourceType.Document,
                           new Uri("https://foo.com/dbs/db1/colls/coll1", UriKind.Absolute),
                           new MemoryStream(Encoding.UTF8.GetBytes("content1")),
                           AuthorizationTokenType.PrimaryMasterKey,
                           null))
            {
                await storeModel.ProcessMessageAsync(request);
            }

            Assert.IsTrue(run > 0);
        }
Beispiel #2
0
        private async Task GatewayStoreModel_Exception_NotUpdateSessionTokenOnKnownException(Exception ex)
        {
            const string originalSessionToken = "0:1#100#1=20#2=5#3=30";

            Func <HttpRequestMessage, Task <HttpResponseMessage> > sendFunc = request =>
            {
                throw ex;
            };

            Mock <IDocumentClientInternal> mockDocumentClient = new Mock <IDocumentClientInternal>();

            mockDocumentClient.Setup(client => client.ServiceEndpoint).Returns(new Uri("https://foo"));

            GlobalEndpointManager     endpointManager  = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy());
            SessionContainer          sessionContainer = new SessionContainer(string.Empty);
            DocumentClientEventSource eventSource      = DocumentClientEventSource.Instance;
            HttpMessageHandler        messageHandler   = new MockMessageHandler(sendFunc);
            GatewayStoreModel         storeModel       = new GatewayStoreModel(
                endpointManager,
                sessionContainer,
                ConsistencyLevel.Eventual,
                eventSource,
                null,
                MockCosmosUtil.CreateCosmosHttpClient(() => new HttpClient(messageHandler)));

            INameValueCollection headers = new StoreRequestNameValueCollection();

            headers.Set(HttpConstants.HttpHeaders.ConsistencyLevel, ConsistencyLevel.Session.ToString());
            headers.Set(HttpConstants.HttpHeaders.SessionToken, originalSessionToken);
            headers.Set(WFConstants.BackendHeaders.PartitionKeyRangeId, "0");

            using (new ActivityScope(Guid.NewGuid()))
            {
                using (DocumentServiceRequest request = DocumentServiceRequest.Create(
                           OperationType.Read,
                           ResourceType.Document,
                           "dbs/OVJwAA==/colls/OVJwAOcMtA0=/docs/OVJwAOcMtA0BAAAAAAAAAA==/",
                           AuthorizationTokenType.PrimaryMasterKey,
                           headers))
                {
                    request.UseStatusCodeFor429      = true;
                    request.UseStatusCodeForFailures = true;
                    try
                    {
                        DocumentServiceResponse response = await storeModel.ProcessMessageAsync(request);

                        Assert.Fail("Should had thrown exception");
                    }
                    catch (Exception)
                    {
                        // Expecting exception
                    }
                    Assert.AreEqual(string.Empty, sessionContainer.GetSessionToken("dbs/OVJwAA==/colls/OVJwAOcMtA0="));
                }
            }
        }
        private async Task GatewayStoreModel_Exceptionless_NotUpdateSessionTokenOnKnownResponses(ResourceType resourceType, HttpStatusCode httpStatusCode, SubStatusCodes subStatusCode = SubStatusCodes.Unknown)
        {
            const string originalSessionToken = "0:1#100#1=20#2=5#3=30";
            const string updatedSessionToken  = "0:1#100#1=20#2=5#3=31";

            Func <HttpRequestMessage, Task <HttpResponseMessage> > sendFunc = request =>
            {
                HttpResponseMessage response = new HttpResponseMessage(httpStatusCode);
                response.Headers.Add(HttpConstants.HttpHeaders.SessionToken, updatedSessionToken);
                response.Headers.Add(WFConstants.BackendHeaders.SubStatus, subStatusCode.ToString());
                return(Task.FromResult(response));
            };

            Mock <IDocumentClientInternal> mockDocumentClient = new Mock <IDocumentClientInternal>();

            mockDocumentClient.Setup(client => client.ServiceEndpoint).Returns(new Uri("https://foo"));

            GlobalEndpointManager     endpointManager  = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy());
            SessionContainer          sessionContainer = new SessionContainer(string.Empty);
            DocumentClientEventSource eventSource      = DocumentClientEventSource.Instance;
            HttpMessageHandler        messageHandler   = new MockMessageHandler(sendFunc);
            GatewayStoreModel         storeModel       = new GatewayStoreModel(
                endpointManager,
                sessionContainer,
                TimeSpan.FromSeconds(5),
                ConsistencyLevel.Eventual,
                eventSource,
                null,
                new UserAgentContainer(),
                ApiType.None,
                messageHandler);

            INameValueCollection headers = new DictionaryNameValueCollection();

            headers.Set(HttpConstants.HttpHeaders.ConsistencyLevel, ConsistencyLevel.Session.ToString());
            headers.Set(HttpConstants.HttpHeaders.SessionToken, originalSessionToken);
            headers.Set(WFConstants.BackendHeaders.PartitionKeyRangeId, "0");

            using (new ActivityScope(Guid.NewGuid()))
            {
                using (DocumentServiceRequest request = DocumentServiceRequest.Create(
                           OperationType.Read,
                           resourceType,
                           "dbs/OVJwAA==/colls/OVJwAOcMtA0=/docs/OVJwAOcMtA0BAAAAAAAAAA==/",
                           AuthorizationTokenType.PrimaryMasterKey,
                           headers))
                {
                    request.UseStatusCodeFor429      = true;
                    request.UseStatusCodeForFailures = true;
                    DocumentServiceResponse response = await storeModel.ProcessMessageAsync(request);

                    Assert.AreEqual(string.Empty, sessionContainer.GetSessionToken("dbs/OVJwAA==/colls/OVJwAOcMtA0="));
                }
            }
        }
        public async Task TestErrorResponsesProvideBody()
        {
            string testContent = "Content";
            Func <HttpRequestMessage, Task <HttpResponseMessage> > sendFunc = request =>
            {
                return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.Conflict)
                {
                    Content = new StringContent(testContent)
                }));
            };

            Mock <IDocumentClientInternal> mockDocumentClient = new Mock <IDocumentClientInternal>();

            mockDocumentClient.Setup(client => client.ServiceEndpoint).Returns(new Uri("https://foo"));

            GlobalEndpointManager     endpointManager  = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy());
            ISessionContainer         sessionContainer = new SessionContainer(string.Empty);
            DocumentClientEventSource eventSource      = DocumentClientEventSource.Instance;
            HttpMessageHandler        messageHandler   = new MockMessageHandler(sendFunc);
            GatewayStoreModel         storeModel       = new GatewayStoreModel(
                endpointManager,
                sessionContainer,
                TimeSpan.FromSeconds(5),
                ConsistencyLevel.Eventual,
                eventSource,
                null,
                new UserAgentContainer(),
                ApiType.None,
                messageHandler);

            using (new ActivityScope(Guid.NewGuid()))
            {
                using (DocumentServiceRequest request =
                           DocumentServiceRequest.Create(
                               Documents.OperationType.Query,
                               Documents.ResourceType.Document,
                               new Uri("https://foo.com/dbs/db1/colls/coll1", UriKind.Absolute),
                               new MemoryStream(Encoding.UTF8.GetBytes("content1")),
                               AuthorizationTokenType.PrimaryMasterKey,
                               null))
                {
                    request.UseStatusCodeForFailures = true;
                    request.UseStatusCodeFor429      = true;

                    DocumentServiceResponse response = await storeModel.ProcessMessageAsync(request);

                    Assert.IsNotNull(response.ResponseBody);
                    using (StreamReader reader = new StreamReader(response.ResponseBody))
                    {
                        Assert.AreEqual(testContent, await reader.ReadToEndAsync());
                    }
                }
            }
        }
Beispiel #5
0
        public async Task GatewayProcessMessageAsyncCancelsOnDeadline()
        {
            // Cancellation deadline is before Request timeout
            using (CancellationTokenSource source = new CancellationTokenSource(TimeSpan.FromSeconds(2)))
            {
                CancellationToken cancellationToken = source.Token;

                Func <HttpRequestMessage, Task <HttpResponseMessage> > sendFunc = async request =>
                {
                    string content = await request.Content.ReadAsStringAsync();

                    Assert.AreEqual("content1", content);

                    // Wait until CancellationTokenSource deadline expires
                    Thread.Sleep(2000);
                    // Force retries
                    throw new WebException("", WebExceptionStatus.ConnectFailure);
                };

                Mock <IDocumentClientInternal> mockDocumentClient = new Mock <IDocumentClientInternal>();
                mockDocumentClient.Setup(client => client.ServiceEndpoint).Returns(new Uri("https://foo"));

                GlobalEndpointManager     endpointManager  = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy());
                ISessionContainer         sessionContainer = new SessionContainer(string.Empty);
                DocumentClientEventSource eventSource      = DocumentClientEventSource.Instance;
                HttpMessageHandler        messageHandler   = new MockMessageHandler(sendFunc);
                GatewayStoreModel         storeModel       = new GatewayStoreModel(
                    endpointManager,
                    sessionContainer,
                    TimeSpan.FromSeconds(5),
                    ConsistencyLevel.Eventual,
                    eventSource,
                    null,
                    new UserAgentContainer(),
                    ApiType.None,
                    messageHandler);

                using (new ActivityScope(Guid.NewGuid()))
                {
                    using (DocumentServiceRequest request =
                               DocumentServiceRequest.Create(
                                   Documents.OperationType.Query,
                                   Documents.ResourceType.Document,
                                   new Uri("https://foo.com/dbs/db1/colls/coll1", UriKind.Absolute),
                                   new MemoryStream(Encoding.UTF8.GetBytes("content1")),
                                   AuthorizationTokenType.PrimaryMasterKey,
                                   null))
                    {
                        await storeModel.ProcessMessageAsync(request, cancellationToken);
                    }
                }
                Assert.Fail();
            }
        }
 private GatewayStoreModel(
     GlobalEndpointManager endpointManager,
     ISessionContainer sessionContainer,
     ConsistencyLevel defaultConsistencyLevel,
     DocumentClientEventSource eventSource)
 {
     // CookieContainer is not really required, but is helpful in debugging.
     this.cookieJar               = new CookieContainer();
     this.endpointManager         = endpointManager;
     this.sessionContainer        = sessionContainer;
     this.defaultConsistencyLevel = defaultConsistencyLevel;
     this.eventSource             = eventSource;
 }
Beispiel #7
0
        public GatewayStoreModel(
            GlobalEndpointManager endpointManager,
            ISessionContainer sessionContainer,
            TimeSpan requestTimeout,
            ConsistencyLevel defaultConsistencyLevel,
            DocumentClientEventSource eventSource,
            JsonSerializerSettings serializerSettings,
            UserAgentContainer userAgent,
            ApiType apiType = ApiType.None,
            HttpMessageHandler messageHandler = null)
        {
            // CookieContainer is not really required, but is helpful in debugging.
            this.cookieJar       = new CookieContainer();
            this.endpointManager = endpointManager;
            HttpClient httpClient = new HttpClient(messageHandler ?? new HttpClientHandler {
                CookieContainer = this.cookieJar
            });

            this.sessionContainer        = sessionContainer;
            this.defaultConsistencyLevel = defaultConsistencyLevel;

            // Use max of client specified and our own request timeout value when sending
            // requests to gateway. Otherwise, we will have gateway's transient
            // error hiding retries are of no use.
            httpClient.Timeout = (requestTimeout > this.requestTimeout) ? requestTimeout : this.requestTimeout;
            httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue {
                NoCache = true
            };

            httpClient.AddUserAgentHeader(userAgent);
            httpClient.AddApiTypeHeader(apiType);

            // Set requested API version header that can be used for
            // version enforcement.
            httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.Version,
                                                 HttpConstants.Versions.CurrentVersion);

            httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.Accept, RuntimeConstants.MediaTypes.Json);

            this.eventSource        = eventSource;
            this.gatewayStoreClient = new GatewayStoreClient(
                httpClient,
                this.eventSource,
                serializerSettings);
        }
Beispiel #8
0
        public GatewayStoreModel(
            GlobalEndpointManager endpointManager,
            ISessionContainer sessionContainer,
            ConsistencyLevel defaultConsistencyLevel,
            DocumentClientEventSource eventSource,
            JsonSerializerSettings serializerSettings,
            HttpClient httpClient)
        {
            this.endpointManager         = endpointManager;
            this.sessionContainer        = sessionContainer;
            this.defaultConsistencyLevel = defaultConsistencyLevel;
            this.eventSource             = eventSource;

            this.gatewayStoreClient = new GatewayStoreClient(
                httpClient,
                this.eventSource,
                serializerSettings);
        }
 public GatewayStoreModel(
     GlobalEndpointManager endpointManager,
     ISessionContainer sessionContainer,
     TimeSpan requestTimeout,
     ConsistencyLevel defaultConsistencyLevel,
     DocumentClientEventSource eventSource,
     JsonSerializerSettings serializerSettings,
     UserAgentContainer userAgent,
     ApiType apiType,
     HttpMessageHandler messageHandler)
     : this(endpointManager,
            sessionContainer,
            defaultConsistencyLevel,
            eventSource)
 {
     this.InitializeGatewayStoreClient(
         requestTimeout,
         serializerSettings,
         userAgent,
         apiType,
         new HttpClient(messageHandler ?? new HttpClientHandler {
         CookieContainer = this.cookieJar
     }));
 }
        private GatewayStoreModel GetGatewayStoreModelForConsistencyTest()
        {
            Func <HttpRequestMessage, Task <HttpResponseMessage> > messageHandler = async request =>
            {
                String content = await request.Content.ReadAsStringAsync();

                if (content.Equals("document"))
                {
                    IEnumerable <string> sessionTokens = request.Headers.GetValues("x-ms-session-token");
                    string sessionToken = "";
                    foreach (string singleToken in sessionTokens)
                    {
                        sessionToken = singleToken;
                        break;
                    }
                    Assert.AreEqual(sessionToken, "range_0:1#9#4=8#5=7");
                }
                else
                {
                    IEnumerable <string> enumerable;
                    Assert.IsFalse(request.Headers.TryGetValues("x-ms-session-token", out enumerable));
                }
                return(new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent("Response")
                });
            };

            Mock <IDocumentClientInternal> mockDocumentClient = new Mock <IDocumentClientInternal>();

            mockDocumentClient.Setup(client => client.ServiceEndpoint).Returns(new Uri("https://foo"));
            mockDocumentClient.Setup(client => client.ConsistencyLevel).Returns(Documents.ConsistencyLevel.Session);

            GlobalEndpointManager endpointManager = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy());

            SessionContainer sessionContainer = new SessionContainer(string.Empty);

            sessionContainer.SetSessionToken(
                ResourceId.NewDocumentCollectionId(42, 129).DocumentCollectionId.ToString(),
                "dbs/db1/colls/coll1",
                new DictionaryNameValueCollection()
            {
                { HttpConstants.HttpHeaders.SessionToken, "range_0:1#9#4=8#5=7" }
            });

            DocumentClientEventSource eventSource        = DocumentClientEventSource.Instance;
            HttpMessageHandler        httpMessageHandler = new MockMessageHandler(messageHandler);

            GatewayStoreModel storeModel = new GatewayStoreModel(
                endpointManager,
                sessionContainer,
                TimeSpan.FromSeconds(50),
                ConsistencyLevel.Session,
                eventSource,
                null,
                new UserAgentContainer(),
                ApiType.None,
                httpMessageHandler);

            return(storeModel);
        }
Beispiel #11
0
        public async Task GatewayProcessMessageAsyncCancels()
        {
            using (CancellationTokenSource source = new CancellationTokenSource())
            {
                CancellationToken cancellationToken = source.Token;

                int run = 0;
                Func <HttpRequestMessage, Task <HttpResponseMessage> > sendFunc = async request =>
                {
                    string content = await request.Content.ReadAsStringAsync();

                    Assert.AreEqual("content1", content);

                    if (run == 0)
                    {
                        // We force a retry but cancel the token to verify if the retry mechanism cancels inbetween
                        source.Cancel();
                        throw new WebException("", WebExceptionStatus.ConnectFailure);
                    }

                    return(new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new StringContent("Response")
                    });
                };

                Mock <IDocumentClientInternal> mockDocumentClient = new Mock <IDocumentClientInternal>();
                mockDocumentClient.Setup(client => client.ServiceEndpoint).Returns(new Uri("https://foo"));

                GlobalEndpointManager     endpointManager  = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy());
                ISessionContainer         sessionContainer = new SessionContainer(string.Empty);
                DocumentClientEventSource eventSource      = DocumentClientEventSource.Instance;
                HttpMessageHandler        messageHandler   = new MockMessageHandler(sendFunc);
                GatewayStoreModel         storeModel       = new GatewayStoreModel(
                    endpointManager,
                    sessionContainer,
                    ConsistencyLevel.Eventual,
                    eventSource,
                    null,
                    MockCosmosUtil.CreateCosmosHttpClient(
                        () => new HttpClient(messageHandler),
                        eventSource));

                using (new ActivityScope(Guid.NewGuid()))
                {
                    using (DocumentServiceRequest request =
                               DocumentServiceRequest.Create(
                                   Documents.OperationType.Query,
                                   Documents.ResourceType.Document,
                                   new Uri("https://foo.com/dbs/db1/colls/coll1", UriKind.Absolute),
                                   new MemoryStream(Encoding.UTF8.GetBytes("content1")),
                                   AuthorizationTokenType.PrimaryMasterKey,
                                   null))
                    {
                        await storeModel.ProcessMessageAsync(request, cancellationToken);
                    }
                }

                Assert.Fail();
            }
        }