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")); } }
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)); } }
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); } }
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); }
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); }
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); }