private async Task <CosmosContainerSettings> GetContainerSettingsAsync(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            CosmosContainerSettings containerSettings = null;

            if (this.cosmosQueryContext.ResourceTypeEnum.IsCollectionChild())
            {
                CollectionCache collectionCache = await this.cosmosQueryContext.QueryClient.GetCollectionCacheAsync();

                using (
                    DocumentServiceRequest request = DocumentServiceRequest.Create(
                        OperationType.Query,
                        this.cosmosQueryContext.ResourceTypeEnum,
                        this.cosmosQueryContext.ResourceLink.OriginalString,
                        AuthorizationTokenType.Invalid)) //this request doesn't actually go to server
                {
                    containerSettings = await collectionCache.ResolveCollectionAsync(request, cancellationToken);
                }
            }

            if (containerSettings == null)
            {
                throw new ArgumentException($"The container was not found for resource: {this.cosmosQueryContext.ResourceLink.OriginalString} ");
            }

            return(containerSettings);
        }
Ejemplo n.º 2
0
        private DocumentServiceResponse ReadDatabaseFeedRequest(DocumentClient client, INameValueCollection headers)
        {
            DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.ReadFeed, null, ResourceType.Database, AuthorizationTokenType.PrimaryMasterKey, headers);
            var response = client.ReadFeedAsync(request, null).Result;

            return(response);
        }
Ejemplo n.º 3
0
        public void TestSetSessionTokenDoesntWorkForMasterQueries()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

            var    collectionResourceId1 = ResourceId.NewDocumentCollectionId(42, 129).DocumentCollectionId.ToString();
            string collectionFullname1   = "dbs/db1/colls/collName1";

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.ReadFeed, collectionFullname1 + "/docs/42", ResourceType.Collection, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                request.ResourceId = collectionResourceId1;

                sessionContainer.SetSessionToken(request, new StoreRequestNameValueCollection()
                {
                    { HttpConstants.HttpHeaders.SessionToken, "range_0:1" }
                });
            }

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId1, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                ISessionToken token = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_0");

                Assert.AreEqual(null, token);
            }

            using (DocumentServiceRequest request = DocumentServiceRequest.CreateFromName(OperationType.Read, collectionFullname1 + "/docs/42", ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                ISessionToken token = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_0");

                Assert.AreEqual(null, token);
            }
        }
Ejemplo n.º 4
0
        private DocumentServiceResponse CreateDocumentRequest(DocumentClient client, INameValueCollection headers)
        {
            Database database = client.CreateDatabaseAsync(new Database {
                Id = Guid.NewGuid().ToString()
            }).Result;
            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition {
                Paths = new System.Collections.ObjectModel.Collection <string>(new[] { "/id" }), Kind = PartitionKind.Hash
            };
            DocumentCollection collection = client.CreateDocumentCollectionAsync(database.SelfLink,
                                                                                 new DocumentCollection
            {
                Id           = Guid.NewGuid().ToString(),
                PartitionKey = partitionKeyDefinition
            }).Result;
            var document = new Document()
            {
                Id = Guid.NewGuid().ToString()
            };
            DocumentServiceRequest request      = DocumentServiceRequest.Create(OperationType.Create, collection.SelfLink, document, ResourceType.Document, AuthorizationTokenType.Invalid, headers, SerializationFormattingPolicy.None);
            PartitionKey           partitionKey = new PartitionKey(document.Id);

            request.Headers.Set(HttpConstants.HttpHeaders.PartitionKey, partitionKey.InternalKey.ToJsonString());
            var response = client.CreateAsync(request, null).Result;

            return(response);
        }
Ejemplo n.º 5
0
        public void AddressCacheMockTest()
        {
            // create a real document service request
            DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey);

            // setup mocks for address information
            AddressInformation[] addressInformation = new AddressInformation[3];
            for (int i = 0; i < 3; i++)
            {
                addressInformation[i] = new AddressInformation
                {
                    PhysicalUri = "http://replica-" + i.ToString("G", CultureInfo.CurrentCulture)
                };
            }

            // Address Selector is an internal sealed class that can't be mocked, but its dependency
            // AddressCache can be mocked.
            Mock <IAddressResolver> mockAddressCache = new Mock <IAddressResolver>();

            mockAddressCache.Setup(
                cache => cache.ResolveAsync(
                    It.IsAny <DocumentServiceRequest>(),
                    false /*forceRefresh*/,
                    new CancellationToken()))
            .ReturnsAsync(new PartitionAddressInformation(addressInformation, null, null));

            // validate that the mock works
            PartitionAddressInformation addressInfo = mockAddressCache.Object.ResolveAsync(entity, false, new CancellationToken()).Result;

            Assert.IsTrue(addressInfo.AllAddresses[0] == addressInformation[0]);
        }
        public async Task TestSessionTokenAvailability()
        {
            GatewayStoreModel storeModel = GetGatewayStoreModelForConsistencyTest();

            using (DocumentServiceRequest request =
                       DocumentServiceRequest.Create(
                           Documents.OperationType.Read,
                           Documents.ResourceType.Collection,
                           new Uri("https://foo.com/dbs/db1/colls/coll1", UriKind.Absolute),
                           new MemoryStream(Encoding.UTF8.GetBytes("collection")),
                           AuthorizationTokenType.PrimaryMasterKey,
                           null))
            {
                await TestGatewayStoreModelProcessMessageAsync(storeModel, request);
            }

            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("document")),
                           AuthorizationTokenType.PrimaryMasterKey,
                           null))
            {
                await TestGatewayStoreModelProcessMessageAsync(storeModel, request);
            }
        }
Ejemplo n.º 7
0
        public void TransportClient_DoesThrowFor404WithReadSessionNotAvailable_WithUseStatusCodeForFailures()
        {
            using (DocumentServiceRequest request =
                       DocumentServiceRequest.Create(
                           OperationType.Query,
                           ResourceType.Document,
                           ExceptionlessTests.resourceUri,
                           new MemoryStream(Encoding.UTF8.GetBytes("content1")),
                           AuthorizationTokenType.PrimaryMasterKey,
                           null))
            {
                request.UseStatusCodeForFailures = true;
                StoreResponse mockStoreResponse404 = new StoreResponse();
                mockStoreResponse404.ResponseHeaderNames = new string[1] {
                    WFConstants.BackendHeaders.SubStatus
                };
                mockStoreResponse404.ResponseHeaderValues = new string[1] {
                    ((int)SubStatusCodes.ReadSessionNotAvailable).ToString()
                };
                mockStoreResponse404.Status = (int)HttpStatusCode.NotFound;


                TransportClient.ThrowServerException(
                    string.Empty,
                    mockStoreResponse404,
                    ExceptionlessTests.resourceUri,
                    Guid.NewGuid(),
                    request);
            }
        }
Ejemplo n.º 8
0
        public void TestSetSessionTokenOverwritesLowerLSN()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

            var    collectionResourceId1 = ResourceId.NewDocumentCollectionId(42, 129).DocumentCollectionId.ToString();
            string collectionFullname1   = "dbs/db1/colls/collName1";

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionFullname1 + "/docs/42", ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                request.ResourceId = collectionResourceId1;

                sessionContainer.SetSessionToken(request, new DictionaryNameValueCollection()
                {
                    { HttpConstants.HttpHeaders.SessionToken, "range_0:1#100#4=90#5=1" }
                });
            }

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionFullname1 + "/docs/42", ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                request.ResourceId = collectionResourceId1;

                sessionContainer.SetSessionToken(request, new DictionaryNameValueCollection()
                {
                    { HttpConstants.HttpHeaders.SessionToken, "range_0:1#105#4=90#5=1" }
                });
            }

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId1, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                ISessionToken token = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_0");

                Assert.AreEqual(105, token.LSN);
            }
        }
 private Uri ResolveEndpointForReadRequest(bool masterResourceType)
 {
     using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, masterResourceType ? ResourceType.Database : ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey))
     {
         return(this.cache.ResolveServiceEndpoint(request));
     }
 }
        private async Task <ContainerProperties> ReadCollectionAsync(
            string collectionLink,
            IDocumentClientRetryPolicy retryPolicyInstance,
            ITrace trace,
            IClientSideRequestStatistics clientSideRequestStatistics,
            CancellationToken cancellationToken)
        {
            using (ITrace childTrace = trace.StartChild("Read Collection", TraceComponent.Transport, TraceLevel.Info))
            {
                cancellationToken.ThrowIfCancellationRequested();

                RequestNameValueCollection headers = new RequestNameValueCollection();
                using (DocumentServiceRequest request = DocumentServiceRequest.Create(
                           OperationType.Read,
                           ResourceType.Collection,
                           collectionLink,
                           AuthorizationTokenType.PrimaryMasterKey,
                           headers))
                {
                    headers.XDate = Rfc1123DateTimeCache.UtcNow();

                    request.RequestContext.ClientRequestStatistics = clientSideRequestStatistics ?? new ClientSideRequestStatisticsTraceDatum(DateTime.UtcNow, trace.Summary);
                    if (clientSideRequestStatistics == null)
                    {
                        childTrace.AddDatum(
                            "Client Side Request Stats",
                            request.RequestContext.ClientRequestStatistics);
                    }

                    string authorizationToken = await this.tokenProvider.GetUserAuthorizationTokenAsync(
                        request.ResourceAddress,
                        PathsHelper.GetResourcePath(request.ResourceType),
                        HttpConstants.HttpMethods.Get,
                        request.Headers,
                        AuthorizationTokenType.PrimaryMasterKey,
                        childTrace);

                    headers.Authorization = authorizationToken;

                    using (new ActivityScope(Guid.NewGuid()))
                    {
                        retryPolicyInstance?.OnBeforeSendRequest(request);

                        try
                        {
                            using (DocumentServiceResponse response =
                                       await this.storeModel.ProcessMessageAsync(request))
                            {
                                return(CosmosResource.FromStream <ContainerProperties>(response));
                            }
                        }
                        catch (DocumentClientException ex)
                        {
                            childTrace.AddDatum("Exception Message", ex.Message);
                            throw;
                        }
                    }
                }
            }
        }
        public void TestGatewayAddressCacheAutoRefreshOnSuboptimalPartition()
        {
            FakeMessageHandler messageHandler = new FakeMessageHandler();
            HttpClient         httpClient     = new HttpClient(messageHandler);

            httpClient.Timeout = TimeSpan.FromSeconds(120);
            GatewayAddressCache cache = new GatewayAddressCache(
                new Uri(GatewayAddressCacheTests.DatabaseAccountApiEndpoint),
                Documents.Client.Protocol.Https,
                this.mockTokenProvider.Object,
                this.mockServiceConfigReader.Object,
                MockCosmosUtil.CreateCosmosHttpClient(() => httpClient),
                suboptimalPartitionForceRefreshIntervalInSeconds: 2);

            int initialAddressesCount = cache.TryGetAddressesAsync(
                DocumentServiceRequest.Create(OperationType.Invalid, ResourceType.Address, AuthorizationTokenType.Invalid),
                this.testPartitionKeyRangeIdentity,
                this.serviceIdentity,
                false,
                CancellationToken.None).Result.AllAddresses.Count();

            Assert.IsTrue(initialAddressesCount < this.targetReplicaSetSize);

            Task.Delay(3000).Wait();

            int finalAddressCount = cache.TryGetAddressesAsync(
                DocumentServiceRequest.Create(OperationType.Invalid, ResourceType.Address, AuthorizationTokenType.Invalid),
                this.testPartitionKeyRangeIdentity,
                this.serviceIdentity,
                false,
                CancellationToken.None).Result.AllAddresses.Count();

            Assert.IsTrue(finalAddressCount == this.targetReplicaSetSize);
        }
        public async Task TestGatewayModelSession()
        {
            ContainerProperties containerProperties = await this.Container.GetCachedContainerPropertiesAsync(
                false,
                Trace.GetRootTrace("Test"),
                CancellationToken.None);

            ISessionContainer sessionContainer = this.cosmosClient.DocumentClient.sessionContainer;
            string            docLink          = "dbs/" + this.database.Id + "/colls/" + containerProperties.Id + "/docs/3";

            Documents.Collections.INameValueCollection headers = new StoreRequestNameValueCollection();
            headers.Set(HttpConstants.HttpHeaders.PartitionKey, "[\"Status3\"]");

            DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, docLink, AuthorizationTokenType.PrimaryMasterKey, headers);
            string globalSessionToken      = sessionContainer.ResolveGlobalSessionToken(request);

            Assert.IsTrue(globalSessionToken.Split(',').Length > 1);

            await GatewayStoreModel.ApplySessionTokenAsync(request,
                                                           Cosmos.ConsistencyLevel.Session,
                                                           sessionContainer,
                                                           await this.cosmosClient.DocumentClient.GetPartitionKeyRangeCacheAsync(NoOpTrace.Singleton),
                                                           await this.cosmosClient.DocumentClient.GetCollectionCacheAsync(NoOpTrace.Singleton));

            string sessionToken = request.Headers[HttpConstants.HttpHeaders.SessionToken];

            Assert.IsTrue(!string.IsNullOrEmpty(sessionToken) && sessionToken.Split(',').Length == 1);
        }
        public void TransportClient_DoesNotThrowFor429_WithUseStatusCodeFor429()
        {
            using (DocumentServiceRequest request =
                       DocumentServiceRequest.Create(
                           OperationType.Query,
                           ResourceType.Document,
                           ExceptionlessTests.resourceUri,
                           new MemoryStream(Encoding.UTF8.GetBytes("content1")),
                           AuthorizationTokenType.PrimaryMasterKey,
                           null))
            {
                request.UseStatusCodeFor429 = true;
                StoreResponse mockStoreResponse429 = new StoreResponse
                {
                    Status = (int)StatusCodes.TooManyRequests
                };

                TransportClient.ThrowServerException(
                    string.Empty,
                    mockStoreResponse429,
                    ExceptionlessTests.resourceUri,
                    Guid.NewGuid(),
                    request);
            }
        }
        private async Task GatewayStoreModel_Exception_UpdateSessionTokenOnKnownException(Exception ex)
        {
            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 =>
            {
                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,
                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.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(updatedSessionToken, sessionContainer.GetSessionToken("dbs/OVJwAA==/colls/OVJwAOcMtA0="));
                }
            }
        }
Ejemplo n.º 15
0
        public void TestResolvePartitionLocalSessionTokenReturnsNullOnCollectionMiss()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

            var    collectionResourceId1 = ResourceId.NewDocumentCollectionId(42, 129).DocumentCollectionId.ToString();
            string collectionFullname    = "dbs/db1/colls/collName";

            sessionContainer.SetSessionToken(
                collectionResourceId1,
                collectionFullname,
                new DictionaryNameValueCollection()
            {
                { HttpConstants.HttpHeaders.SessionToken, "range_0:1#100#4=90#5=1" }
            }
                );

            sessionContainer.SetSessionToken(
                collectionResourceId1,
                collectionFullname,
                new DictionaryNameValueCollection()
            {
                { HttpConstants.HttpHeaders.SessionToken, "range_1:1#101#4=90#5=1" }
            }
                );

            var collectionResourceId2 = ResourceId.NewDocumentCollectionId(42, 130).DocumentCollectionId.ToString();

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId2, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                ISessionToken token = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_1");

                Assert.AreEqual(null, token);
            }
        }
        private async Task <DocumentServiceResponse> ExecutePartitionKeyRangeReadChangeFeedAsync(string collectionRid,
                                                                                                 INameValueCollection headers,
                                                                                                 ITrace trace)
        {
            using (ITrace childTrace = trace.StartChild("Read PartitionKeyRange Change Feed", TraceComponent.Transport, Tracing.TraceLevel.Info))
            {
                using (DocumentServiceRequest request = DocumentServiceRequest.Create(
                           OperationType.ReadFeed,
                           collectionRid,
                           ResourceType.PartitionKeyRange,
                           AuthorizationTokenType.PrimaryMasterKey,
                           headers))
                {
                    string authorizationToken = null;
                    try
                    {
                        authorizationToken = (await this.authorizationTokenProvider.GetUserAuthorizationAsync(
                                                  request.ResourceAddress,
                                                  PathsHelper.GetResourcePath(request.ResourceType),
                                                  HttpConstants.HttpMethods.Get,
                                                  request.Headers,
                                                  AuthorizationTokenType.PrimaryMasterKey)).token;
                    }
                    catch (UnauthorizedException)
                    {
                    }

                    if (authorizationToken == null)
                    {
                        // User doesn't have rid based resource token. Maybe he has name based.
                        throw new NotSupportedException("Resource tokens are not supported");

                        ////CosmosContainerSettings collection = await this.collectionCache.ResolveCollectionAsync(request, CancellationToken.None);
                        ////authorizationToken =
                        ////    this.authorizationTokenProvider.GetUserAuthorizationTokenAsync(
                        ////        collection.AltLink,
                        ////        PathsHelper.GetResourcePath(request.ResourceType),
                        ////        HttpConstants.HttpMethods.Get,
                        ////        request.Headers,
                        ////        AuthorizationTokenType.PrimaryMasterKey);
                    }

                    request.Headers[HttpConstants.HttpHeaders.Authorization] = authorizationToken;

                    using (new ActivityScope(Guid.NewGuid()))
                    {
                        try
                        {
                            return(await this.storeModel.ProcessMessageAsync(request));
                        }
                        catch (DocumentClientException ex)
                        {
                            childTrace.AddDatum("Exception Message", ex.Message);
                            throw;
                        }
                    }
                }
            }
        }
        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,
                    new HttpClient(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();
            }
        }
        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());
            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);
                }
            }

            Assert.IsTrue(run > 0);
        }
 private Uri ResolveEndpointForWriteRequest(ResourceType resourceType, bool useAlternateWriteEndpoint)
 {
     using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Create, resourceType, AuthorizationTokenType.PrimaryMasterKey))
     {
         request.RequestContext.RouteToLocation(useAlternateWriteEndpoint ? 1 : 0, resourceType.IsCollectionChild());
         return(this.cache.ResolveServiceEndpoint(request));
     }
 }
Ejemplo n.º 20
0
        private DocumentServiceResponse ReadDocumentRequest(DocumentClient client, Document doc, INameValueCollection headers)
        {
            DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, doc.SelfLink, AuthorizationTokenType.PrimaryMasterKey, headers);

            request.Headers.Set(HttpConstants.HttpHeaders.PartitionKey, (new PartitionKey(doc.Id)).InternalKey.ToJsonString());
            var retrievedDocResponse = client.ReadAsync(request, null).Result;

            return(retrievedDocResponse);
        }
Ejemplo n.º 21
0
        public void VerifyAllReadRegionsAreVisited(int numOfReadRegions)
        {
            Mock <IGlobalEndpointManager> mockEndpointManager = new Mock <IGlobalEndpointManager>(MockBehavior.Strict);

            GlobalPartitionEndpointManagerCore failoverManager = new GlobalPartitionEndpointManagerCore(mockEndpointManager.Object);
            List <Uri> readRegions = new List <Uri>();

            for (int i = 0; i < numOfReadRegions; i++)
            {
                readRegions.Add(new Uri($"https://localhost:{i}/"));
            }

            mockEndpointManager.Setup(x => x.ReadEndpoints).Returns(() => new ReadOnlyCollection <Uri>(readRegions));

            // Create a random pk range
            PartitionKeyRange partitionKeyRange = new PartitionKeyRange()
            {
                Id           = "0",
                MinInclusive = "",
                MaxExclusive = "BB"
            };

            PartitionKeyRange partitionKeyRangeNotOverriden = new PartitionKeyRange()
            {
                Id           = "1",
                MinInclusive = "BB",
                MaxExclusive = "FF"
            };

            using DocumentServiceRequest createRequest             = DocumentServiceRequest.Create(OperationType.Create, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey);
            createRequest.RequestContext.ResolvedPartitionKeyRange = partitionKeyRange;
            createRequest.RequestContext.RouteToLocation(readRegions.First());

            mockEndpointManager.Setup(x => x.CanUseMultipleWriteLocations(createRequest)).Returns(false);

            foreach (Uri region in readRegions)
            {
                Assert.AreEqual(region, createRequest.RequestContext.LocationEndpointToRoute);
                bool tryFailover = failoverManager.TryMarkEndpointUnavailableForPartitionKeyRange(
                    createRequest);

                // If there are no more regions to failover it will return false.
                if (region == readRegions.Last())
                {
                    Assert.IsFalse(tryFailover);
                    Assert.IsFalse(failoverManager.TryAddPartitionLevelLocationOverride(createRequest));
                }
                else
                {
                    Assert.IsTrue(tryFailover);
                    Assert.IsTrue(failoverManager.TryAddPartitionLevelLocationOverride(createRequest));
                    Assert.AreNotEqual(region, createRequest.RequestContext.LocationEndpointToRoute);
                }
            }
        }
Ejemplo n.º 22
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();
            }
        }
        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());
                    }
                }
            }
        }
 private DocumentServiceRequest CreateRequest(bool isReadRequest, bool isMasterResourceType)
 {
     if (isReadRequest)
     {
         return(DocumentServiceRequest.Create(OperationType.Read, isMasterResourceType ? ResourceType.Database : ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey));
     }
     else
     {
         return(DocumentServiceRequest.Create(OperationType.Create, isMasterResourceType ? ResourceType.Database : ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey));
     }
 }
Ejemplo n.º 25
0
        public void TestClearTokenKeepsUnmatchedCollection()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

            var    collectionResourceId1 = ResourceId.NewDocumentCollectionId(42, 129).DocumentCollectionId.ToString();
            string collectionFullname1   = "dbs/db1/colls/collName1";

            sessionContainer.SetSessionToken(
                collectionResourceId1,
                collectionFullname1,
                new DictionaryNameValueCollection()
            {
                { HttpConstants.HttpHeaders.SessionToken, "range_0:1#100#4=90#5=1" }
            }
                );

            var    collectionResourceId2 = ResourceId.NewDocumentCollectionId(42, 130).DocumentCollectionId.ToString();
            string collectionFullname2   = "dbs/db1/colls/collName2";

            sessionContainer.SetSessionToken(
                collectionResourceId2,
                collectionFullname2,
                new DictionaryNameValueCollection()
            {
                { HttpConstants.HttpHeaders.SessionToken, "range_0:1#100#4=90#5=1" }
            }
                );

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId1, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                ISessionToken token = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_0");
                Assert.AreEqual(100, token.LSN);
            }

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId2, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                ISessionToken token = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_0");
                Assert.AreEqual(100, token.LSN);
            }

            sessionContainer.ClearTokenByResourceId(collectionResourceId1);

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId1, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                ISessionToken token = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_0");
                Assert.AreEqual(null, token);
            }

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId2, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                ISessionToken token = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_0");
                Assert.AreEqual(100, token.LSN);
            }
        }
Ejemplo n.º 26
0
        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"));

            using GlobalEndpointManager endpointManager = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy());
            SessionContainer          sessionContainer = new SessionContainer(string.Empty);
            DocumentClientEventSource eventSource      = DocumentClientEventSource.Instance;
            HttpMessageHandler        messageHandler   = new MockMessageHandler(sendFunc);

            using 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,
                           "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="));
                }
            }
        }
Ejemplo n.º 27
0
        public void TransportClientMockTest()
        {
            // create a real document service request
            DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey);

            // setup mocks for address information
            AddressInformation[] addressInformation = new AddressInformation[3];

            // construct URIs that look like the actual uri
            // rntbd://yt1prdddc01-docdb-1.documents.azure.com:14003/apps/ce8ab332-f59e-4ce7-a68e-db7e7cfaa128/services/68cc0b50-04c6-4716-bc31-2dfefd29e3ee/partitions/5604283d-0907-4bf4-9357-4fa9e62de7b5/replicas/131170760736528207s/
            for (int i = 0; i < 3; i++)
            {
                addressInformation[i] = new AddressInformation
                {
                    PhysicalUri =
                        "rntbd://dummytenant.documents.azure.com:14003/apps/APPGUID/services/SERVICEGUID/partitions/PARTITIONGUID/replicas/"
                        + i.ToString("G", CultureInfo.CurrentCulture) + (i == 0 ? "p" : "s") + "/"
                };
            }

            // create objects for all the dependencies of the StoreReader
            Mock <TransportClient> mockTransportClient = new Mock <TransportClient>();

            // create mock store response object
            StoreResponse mockStoreResponse = new StoreResponse
            {
                // set lsn and activityid on the store response.
                Headers = new DictionaryNameValueCollection(
                    new NameValueCollection()
                {
                    { WFConstants.BackendHeaders.LSN, "50" },
                    { WFConstants.BackendHeaders.ActivityId, "ACTIVITYID1_1" }
                })
            };

            // setup mock transport client
            mockTransportClient.Setup(
                client => client.InvokeResourceOperationAsync(
                    new Uri(addressInformation[0].PhysicalUri), It.IsAny <DocumentServiceRequest>()))
            .ReturnsAsync(mockStoreResponse);

            TransportClient mockTransportClientObject = mockTransportClient.Object;
            // get response from mock object
            StoreResponse response = mockTransportClientObject.InvokeResourceOperationAsync(new Uri(addressInformation[0].PhysicalUri), entity).Result;

            // validate that the LSN matches
            Assert.IsTrue(response.LSN == 50);

            response.TryGetHeaderValue(WFConstants.BackendHeaders.ActivityId, out string activityId);

            // validate that the ActivityId Matches
            Assert.IsTrue(activityId == "ACTIVITYID1_1");
        }
        private async Task <ShouldRetryResult> ShouldRetryAsyncInternal(
            HttpStatusCode?statusCode,
            SubStatusCodes?subStatusCode,
            CancellationToken cancellationToken,
            Func <Task <ShouldRetryResult> > continueIfNotHandled)
        {
            if (statusCode.HasValue &&
                subStatusCode.HasValue &&
                statusCode == HttpStatusCode.Gone &&
                subStatusCode == SubStatusCodes.PartitionKeyRangeGone)
            {
                if (this.retried)
                {
                    return(ShouldRetryResult.NoRetry());
                }

                using (DocumentServiceRequest request = DocumentServiceRequest.Create(
                           OperationType.Read,
                           ResourceType.Collection,
                           this.collectionLink,
                           null,
                           AuthorizationTokenType.PrimaryMasterKey))
                {
                    CosmosContainerSettings collection = await this.collectionCache.ResolveCollectionAsync(request, cancellationToken);

                    CollectionRoutingMap routingMap = await this.partitionKeyRangeCache.TryLookupAsync(collection.ResourceId, null, request, false, cancellationToken);

                    if (routingMap != null)
                    {
                        // Force refresh.
                        await this.partitionKeyRangeCache.TryLookupAsync(
                            collection.ResourceId,
                            routingMap,
                            request,
                            false,
                            cancellationToken);
                    }
                }

                this.retried = true;
                return(ShouldRetryResult.RetryAfter(TimeSpan.FromSeconds(0)));
            }

            if (continueIfNotHandled != null)
            {
                return(await continueIfNotHandled() ?? ShouldRetryResult.NoRetry());
            }
            else
            {
                return(await Task.FromResult(ShouldRetryResult.NoRetry()));
            }
        }
        private async Task <ShouldRetryResult> ShouldRetryInternalAsync(
            HttpStatusCode?statusCode,
            SubStatusCodes?subStatusCode,
            CancellationToken cancellationToken)
        {
            if (!statusCode.HasValue &&
                (!subStatusCode.HasValue ||
                 subStatusCode.Value == SubStatusCodes.Unknown))
            {
                return(null);
            }

            if (statusCode == HttpStatusCode.Gone &&
                subStatusCode == SubStatusCodes.PartitionKeyRangeGone)
            {
                if (this.retried)
                {
                    return(ShouldRetryResult.NoRetry());
                }

                using (DocumentServiceRequest request = DocumentServiceRequest.Create(
                           OperationType.Read,
                           ResourceType.Collection,
                           this.collectionLink,
                           null,
                           AuthorizationTokenType.PrimaryMasterKey))
                {
                    ContainerProperties collection = await this.collectionCache.ResolveCollectionAsync(request, cancellationToken, this.trace);

                    CollectionRoutingMap routingMap = await this.partitionKeyRangeCache.TryLookupAsync(
                        collectionRid : collection.ResourceId,
                        previousValue : null,
                        request : request,
                        trace : this.trace);

                    if (routingMap != null)
                    {
                        // Force refresh.
                        await this.partitionKeyRangeCache.TryLookupAsync(
                            collectionRid : collection.ResourceId,
                            previousValue : routingMap,
                            request : request,
                            trace : this.trace);
                    }
                }

                this.retried = true;
                return(ShouldRetryResult.RetryAfter(TimeSpan.FromSeconds(0)));
            }

            return(null);
        }
Ejemplo n.º 30
0
        public void TestSessionContainer()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

            int numCollections          = 2;
            int numPartitionKeyRangeIds = 5;

            for (uint i = 0; i < numCollections; i++)
            {
                var    collectionResourceId = ResourceId.NewDocumentCollectionId(42, 129 + i).DocumentCollectionId.ToString();
                string collectionFullname   = "dbs/db1/colls/collName_" + i;

                for (int j = 0; j < numPartitionKeyRangeIds; j++)
                {
                    string partitionKeyRangeId = "range_" + j;
                    string lsn = "1#" + j + "#4=90#5=2";

                    sessionContainer.SetSessionToken(
                        collectionResourceId,
                        collectionFullname,
                        new DictionaryNameValueCollection()
                    {
                        { HttpConstants.HttpHeaders.SessionToken, $"{partitionKeyRangeId}:{lsn}" }
                    });
                }
            }

            using (DocumentServiceRequest request =
                       DocumentServiceRequest.Create(
                           OperationType.ReadFeed,
                           ResourceType.Collection,
                           new Uri("https://foo.com/dbs/db1/colls/collName_1", UriKind.Absolute),
                           new MemoryStream(Encoding.UTF8.GetBytes("content1")),
                           AuthorizationTokenType.PrimaryMasterKey,
                           null))
            {
                ISessionToken sessionToken = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_1");
                Assert.IsTrue(sessionToken.LSN == 1);

                DocumentServiceRequestContext dsrContext      = new DocumentServiceRequestContext();
                PartitionKeyRange             resolvedPKRange = new PartitionKeyRange();
                resolvedPKRange.Id      = "range_" + (numPartitionKeyRangeIds + 10);
                resolvedPKRange.Parents = new Collection <string>(new List <string> {
                    "range_2", "range_x"
                });
                dsrContext.ResolvedPartitionKeyRange = resolvedPKRange;
                request.RequestContext = dsrContext;

                sessionToken = sessionContainer.ResolvePartitionLocalSessionToken(request, resolvedPKRange.Id);
                Assert.IsTrue(sessionToken.LSN == 2);
            }
        }