public void TestSetSessionTokenDoesNothingOnEmptySessionTokenHeader()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

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

            sessionContainer.SetSessionToken(
                collectionResourceId,
                collectionFullname + "/docs/42",
                new RequestNameValueCollection()
            {
                { HttpConstants.HttpHeaders.SessionToken, "range_0:1#100#4=90#5=1" }
            }
                );

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                string token = sessionContainer.ResolveGlobalSessionToken(request);

                HashSet <string> map = new HashSet <string>(token.Split(','));

                Assert.AreEqual(1, map.Count);
                Assert.IsTrue(map.Contains("range_0:1#100#4=90#5=1"));
            }

            sessionContainer.SetSessionToken(
                collectionResourceId,
                collectionFullname + "/docs/42",
                new RequestNameValueCollection()
                );

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                string token = sessionContainer.ResolveGlobalSessionToken(request);

                HashSet <string> map = new HashSet <string>(token.Split(','));

                Assert.AreEqual(1, map.Count);
                Assert.IsTrue(map.Contains("range_0:1#100#4=90#5=1"));
            }
        }
Example #2
0
        public void TestResolveGlobalSessionTokenReturnsEmptyStringOnCacheMiss()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

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

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

            using (DocumentServiceRequest request = DocumentServiceRequest.CreateFromName(OperationType.Read, "dbs/db1/colls/collName2/docs/42", ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                Assert.AreEqual(string.Empty, sessionContainer.ResolveGlobalSessionToken(request));
            }
        }
Example #3
0
        public void TestSetSessionTokenGivesPriorityToOwnerIdOverResourceIdWhenRequestIsNameBased()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

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

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

                Assert.IsTrue(request.IsNameBased);

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

            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);
            }
        }
Example #4
0
        public void TestResolvePartitionLocalSessionTokenReturnsTokenOnParentMatch()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

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

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

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

            using (DocumentServiceRequest request = DocumentServiceRequest.Create(OperationType.Read, collectionResourceId, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null))
            {
                request.RequestContext.ResolvedPartitionKeyRange         = new PartitionKeyRange();
                request.RequestContext.ResolvedPartitionKeyRange.Parents = new Collection <string>()
                {
                    "range_1"
                };

                ISessionToken token = sessionContainer.ResolvePartitionLocalSessionToken(request, "range_2");

                Assert.AreEqual(101, token.LSN);
            }
        }
        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);
        }
Example #6
0
        public void TestResolveSessionTokenFromParent_Gateway_AfterMerge()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

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

            // Set tokens for the parents
            string parentPKRangeId = "0";
            int    maxGlobalLsn    = 100;
            int    maxLsnRegion1   = 200;
            int    maxLsnRegion2   = 300;
            int    maxLsnRegion3   = 400;

            // Generate 2 tokens, one has max global but lower regional, the other lower global but higher regional
            // Expect the merge to contain all the maxes
            string parentSession = $"1#{maxGlobalLsn}#1={maxLsnRegion1 - 1}#2={maxLsnRegion2}#3={maxLsnRegion3 - 1}";

            sessionContainer.SetSessionToken(
                collectionResourceId,
                collectionFullname,
                new StoreRequestNameValueCollection()
            {
                { HttpConstants.HttpHeaders.SessionToken, $"{parentPKRangeId}:{parentSession}" }
            }
                );

            string parent2PKRangeId = "1";
            string parent2Session   = $"1#{maxGlobalLsn - 1}#1={maxLsnRegion1}#2={maxLsnRegion2 - 1}#3={maxLsnRegion3}";

            sessionContainer.SetSessionToken(
                collectionResourceId,
                collectionFullname,
                new StoreRequestNameValueCollection()
            {
                { HttpConstants.HttpHeaders.SessionToken, $"{parent2PKRangeId}:{parent2Session}" }
            }
                );

            string tokenWithAllMax = $"1#{maxGlobalLsn}#1={maxLsnRegion1}#2={maxLsnRegion2}#3={maxLsnRegion3}";

            // Request for a child from both parents
            string childPKRangeId = "2";

            DocumentServiceRequest documentServiceRequestToChild1 = DocumentServiceRequest.CreateFromName(OperationType.Read, "dbs/db1/colls/collName/docs/42", ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null);

            documentServiceRequestToChild1.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange()
            {
                Id           = childPKRangeId,
                MinInclusive = "",
                MaxExclusive = "FF",
                Parents      = new Collection <string>()
                {
                    parentPKRangeId, parent2PKRangeId
                }                                                                        // PartitionKeyRange says who are the parents
            };

            string resolvedToken = sessionContainer.ResolvePartitionLocalSessionTokenForGateway(
                documentServiceRequestToChild1,
                childPKRangeId);// For one of the children

            // Expect the resulting token is for the child partition but containing all maxes of the lsn of the parents
            Assert.AreEqual($"{childPKRangeId}:{tokenWithAllMax}", resolvedToken);
        }
Example #7
0
        public void TestResolveSessionTokenFromParent_Gateway_AfterSplit()
        {
            SessionContainer sessionContainer = new SessionContainer("127.0.0.1");

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

            // Set token for the parent
            string parentPKRangeId = "0";
            string parentSession   = "1#100#4=90#5=1";

            sessionContainer.SetSessionToken(
                collectionResourceId,
                collectionFullname,
                new StoreRequestNameValueCollection()
            {
                { HttpConstants.HttpHeaders.SessionToken, $"{parentPKRangeId}:{parentSession}" }
            }
                );

            // We send requests for the children

            string childPKRangeId  = "1";
            string childPKRangeId2 = "1";

            DocumentServiceRequest documentServiceRequestToChild1 = DocumentServiceRequest.CreateFromName(OperationType.Read, "dbs/db1/colls/collName/docs/42", ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null);

            documentServiceRequestToChild1.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange()
            {
                Id           = childPKRangeId,
                MinInclusive = "",
                MaxExclusive = "AA",
                Parents      = new Collection <string>()
                {
                    parentPKRangeId
                }                                                      // PartitionKeyRange says who is the parent
            };

            string resolvedToken = sessionContainer.ResolvePartitionLocalSessionTokenForGateway(
                documentServiceRequestToChild1,
                childPKRangeId);// For one of the children

            Assert.AreEqual($"{childPKRangeId}:{parentSession}", resolvedToken);

            DocumentServiceRequest documentServiceRequestToChild2 = DocumentServiceRequest.CreateFromName(OperationType.Read, "dbs/db1/colls/collName/docs/42", ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey, null);

            documentServiceRequestToChild2.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange()
            {
                Id           = childPKRangeId2,
                MinInclusive = "AA",
                MaxExclusive = "FF",
                Parents      = new Collection <string>()
                {
                    parentPKRangeId
                }                                                      // PartitionKeyRange says who is the parent
            };

            resolvedToken = sessionContainer.ResolvePartitionLocalSessionTokenForGateway(
                documentServiceRequestToChild2,
                childPKRangeId2);// For the other child

            Assert.AreEqual($"{childPKRangeId2}:{parentSession}", resolvedToken);
        }