public async Task AddPartitionKeyRangeToContinuationTokenOnSplit()
        {
            const string                      BackendToken = "backendToken";
            StringKeyValueCollection          headers      = new StringKeyValueCollection();
            List <CompositeContinuationToken> compositeContinuationTokensFromSplit = new List <CompositeContinuationToken>
            {
                new CompositeContinuationToken {
                    Token = "someToken", Range = new Range <string>("A", "B", true, false)
                },
                new CompositeContinuationToken {
                    Token = "anotherToken", Range = new Range <string>("B", "C", true, false)
                }
            };

            PartitionRoutingHelper partitionRoutingHelper = new PartitionRoutingHelper();

            //With backend header
            headers.Add(HttpConstants.HttpHeaders.Continuation, BackendToken);
            ResolvedRangeInfo resolvedRangeInfo = new ResolvedRangeInfo(new PartitionKeyRange(), new List <CompositeContinuationToken>(compositeContinuationTokensFromSplit));
            bool result = await partitionRoutingHelper.TryAddPartitionKeyRangeToContinuationTokenAsync(
                headers,
                null,
                null,
                null,
                resolvedRangeInfo,
                RntdbEnumerationDirection.Reverse);

            List <CompositeContinuationToken> compositeContinuationTokens = JsonConvert.DeserializeObject <List <CompositeContinuationToken> >(headers.Get(HttpConstants.HttpHeaders.Continuation));

            Assert.IsTrue(result);
            Assert.AreEqual(compositeContinuationTokensFromSplit.Count, compositeContinuationTokens.Count);
            Assert.AreEqual(BackendToken, compositeContinuationTokens.First().Token);
            Assert.AreNotEqual(BackendToken, compositeContinuationTokens.Last().Token);

            //Without backend header
            headers.Remove(HttpConstants.HttpHeaders.Continuation);
            resolvedRangeInfo = new ResolvedRangeInfo(new PartitionKeyRange(), new List <CompositeContinuationToken>(compositeContinuationTokensFromSplit));
            result            = await partitionRoutingHelper.TryAddPartitionKeyRangeToContinuationTokenAsync(
                headers,
                null,
                null,
                null,
                resolvedRangeInfo,
                RntdbEnumerationDirection.Reverse);

            compositeContinuationTokens = JsonConvert.DeserializeObject <List <CompositeContinuationToken> >(headers.Get(HttpConstants.HttpHeaders.Continuation));
            Assert.IsTrue(result);
            Assert.IsTrue(compositeContinuationTokens.Count == compositeContinuationTokensFromSplit.Count - 1);
            Assert.AreEqual(compositeContinuationTokensFromSplit.Last().Token, compositeContinuationTokens.First().Token);
        }
예제 #2
0
        public static StringKeyValueCollection BuildGameDescriptionProperties(IComponentUniqueId componentUniqueId, string gameName, VersionNumber version, IComponentUniqueId engineUniqueId, string gamePart, IServerPath projectPath)
        {
            var properties = new StringKeyValueCollection();

            properties.Add(new StringKeyValue(AntPropertyNames.GamePartUniqueID, componentUniqueId.Value));
            properties.Add(new StringKeyValue(AntPropertyNames.GameUniqueName, gameName));
            properties.Add(new StringKeyValue(AntPropertyNames.GameVersion, version.ToString()));
            properties.Add(new StringKeyValue(AntPropertyNames.ParentGameEngineUniqueID, engineUniqueId.Value));
            properties.Add(new StringKeyValue(AntPropertyNames.GamePart, gamePart));
            properties.Add(new StringKeyValue(AntPropertyNames.ProjDir, projectPath.AsString()));
            properties.Add(new StringKeyValue(AntPropertyNames.PublishDate, DateTime.Now.ToString()));
            return(properties);
        }
예제 #3
0
        private void ValidateIndexingDirective(DocumentClient client)
        {
            //Will keep this as V2 OM, because we can pass invalid IndexingDirective from V3 onwarsds
            // Number out of range.
            INameValueCollection headers = new StringKeyValueCollection();

            headers.Add(HttpConstants.HttpHeaders.IndexingDirective, "\"Invalid Value\"");

            try
            {
                CreateDocumentRequest(client, headers);
                Assert.Fail("Should throw an exception");
            }
            catch (Exception ex)
            {
                var innerException = ex.InnerException as DocumentClientException;
                Assert.IsTrue(innerException.StatusCode == HttpStatusCode.BadRequest, "Invalid status code");
            }

            headers = new StringKeyValueCollection();
            headers.Add("indexAction", "\"Invalid Value\"");

            try
            {
                CreateDocumentScript(client, headers);
                Assert.Fail("Should throw an exception");
            }
            catch (Exception ex)
            {
                var innerException = ex.InnerException as DocumentClientException;
                Assert.IsTrue(innerException.StatusCode == HttpStatusCode.BadRequest, "Invalid status code");
            }

            // Valid Indexing Directive
            headers = new StringKeyValueCollection();
            headers.Add(HttpConstants.HttpHeaders.IndexingDirective, IndexingDirective.Exclude.ToString());
            var response = CreateDocumentRequest(client, headers);

            Assert.IsTrue(response.StatusCode == HttpStatusCode.Created);

            headers = new StringKeyValueCollection();
            headers.Add("indexAction", "\"exclude\"");
            var result = CreateDocumentScript(client, headers);

            Assert.IsTrue(result.StatusCode == HttpStatusCode.OK, "Invalid status code");
        }
        public void CompositeContinuationTokenIsNotPassedToBackend()
        {
            Range <string>             expectedRange = new Range <string>("A", "B", true, false);
            string                     expectedToken = "someToken";
            CompositeContinuationToken compositeContinuationToken = new CompositeContinuationToken {
                Range = expectedRange, Token = expectedToken
            };
            string continuation = JsonConvert.SerializeObject(compositeContinuationToken);
            PartitionRoutingHelper   partitionRoutingHelper = new PartitionRoutingHelper();
            StringKeyValueCollection headers = new StringKeyValueCollection();

            headers.Add(HttpConstants.HttpHeaders.Continuation, continuation);
            Range <string> range = partitionRoutingHelper.ExtractPartitionKeyRangeFromContinuationToken(headers, out List <CompositeContinuationToken> compositeContinuationTokens);

            Assert.IsTrue(expectedRange.Equals(range));
            Assert.AreEqual(expectedToken, headers.Get(HttpConstants.HttpHeaders.Continuation)); //not a composite token
        }
예제 #5
0
        private async Task <CosmosAccountSettings> GetDatabaseAccountAsync(Uri serviceEndpoint)
        {
            HttpClient httpClient = this.messageHandler == null ? new HttpClient() : new HttpClient(this.messageHandler);

            httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.Version,
                                                 HttpConstants.Versions.CurrentVersion);

            // Send client version.
            httpClient.AddUserAgentHeader(this.connectionPolicy.UserAgentContainer);
            httpClient.AddApiTypeHeader(this.apiType);

            string authorizationToken = string.Empty;

            if (this.hasAuthKeyResourceToken)
            {
                authorizationToken = HttpUtility.UrlEncode(this.authKeyResourceToken);
            }
            else
            {
                // Retrieve the document service properties.
                string xDate = DateTime.UtcNow.ToString("r", CultureInfo.InvariantCulture);
                httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.XDate, xDate);

                INameValueCollection headersCollection = new StringKeyValueCollection();
                headersCollection.Add(HttpConstants.HttpHeaders.XDate, xDate);

                authorizationToken = AuthorizationHelper.GenerateKeyAuthorizationSignature(
                    HttpConstants.HttpMethods.Get,
                    serviceEndpoint,
                    headersCollection,
                    this.authKeyHashFunction);
            }

            httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.Authorization, authorizationToken);

            using (HttpResponseMessage responseMessage = await httpClient.GetHttpAsync(
                       serviceEndpoint))
            {
                using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(responseMessage))
                {
                    CosmosAccountSettings databaseAccount = documentServiceResponse.GetInternalResource <CosmosAccountSettings>(CosmosAccountSettings.CreateNewInstance);

                    return(databaseAccount);
                }
            }
        }
예제 #6
0
        private void ValidateCosistencyLevel(DocumentClient client)
        {
            //this is can be only tested with V2 OM, V3 doesnt allow to set invalid consistencty
            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;

            // Value not supported
            INameValueCollection headers = new StringKeyValueCollection();

            headers.Add(HttpConstants.HttpHeaders.ConsistencyLevel, "Not a valid value");

            try
            {
                ReadDocumentFeedRequest(client, collection.ResourceId, headers);
                Assert.Fail("Should throw an exception");
            }
            catch (Exception ex)
            {
                var innerException = ex.InnerException as DocumentClientException;
                Assert.IsTrue(innerException.StatusCode == HttpStatusCode.BadRequest, "invalid status code");
            }

            // Supported value
            headers = new StringKeyValueCollection();
            headers.Add(HttpConstants.HttpHeaders.ConsistencyLevel, ConsistencyLevel.Eventual.ToString());
            var response = ReadDocumentFeedRequest(client, collection.ResourceId, headers);

            Assert.IsTrue(response.StatusCode == HttpStatusCode.OK, "Invalid status code");
        }
예제 #7
0
        private void ValidateEnableLowPrecisionOrderBy(DocumentClient client, bool isHttps = false)
        {
            // Value not boolean
            INameValueCollection headers = new StringKeyValueCollection();

            headers.Add(HttpConstants.HttpHeaders.EnableLowPrecisionOrderBy, "Not a boolean");

            var document = CreateDocumentRequest(client, new StringKeyValueCollection()).GetResource <Document>();

            try
            {
                var response = ReadDocumentRequest(client, document, headers);
                if (isHttps)
                {
                    Assert.Fail("Should throw an exception");
                }
                else
                {
                    // Invalid boolean is treated as false by TCP"
                    Assert.IsTrue(response.StatusCode == HttpStatusCode.OK, "Invalid status code");
                }
            }
            catch (Exception ex)
            {
                var innerException = ex.InnerException as DocumentClientException;
                Assert.IsTrue(innerException.StatusCode == HttpStatusCode.BadRequest, "Invalid status code");
            }

            // Valid boolean
            document = CreateDocumentRequest(client, new StringKeyValueCollection()).GetResource <Document>();
            headers  = new StringKeyValueCollection();
            headers.Add(HttpConstants.HttpHeaders.EnableLowPrecisionOrderBy, "true");
            var response2 = ReadDocumentRequest(client, document, headers);

            Assert.IsTrue(response2.StatusCode == HttpStatusCode.OK, "Invalid status code");
        }
예제 #8
0
        private void ValidatePageSize(DocumentClient client)
        {
            // Invalid parsing
            INameValueCollection headers = new StringKeyValueCollection();

            headers.Add(HttpConstants.HttpHeaders.PageSize, "\"Invalid header type\"");

            try
            {
                ReadDatabaseFeedRequest(client, headers);
                Assert.Fail("Should throw an exception");
            }
            catch (Exception ex)
            {
                var innerException = ex.InnerException as DocumentClientException;
                Assert.IsTrue(innerException.StatusCode == HttpStatusCode.BadRequest, "Invalid status code");
            }

            headers = new StringKeyValueCollection();
            headers.Add("pageSize", "\"Invalid header type\"");

            try
            {
                ReadFeedScript(client, headers);
                Assert.Fail("Should throw an exception");
            }
            catch (Exception ex)
            {
                var innerException = ex.InnerException as DocumentClientException;
                Assert.IsTrue(innerException.StatusCode == HttpStatusCode.BadRequest, "Invalid status code");
            }

            // Invalid value
            headers = new StringKeyValueCollection();
            headers.Add(HttpConstants.HttpHeaders.PageSize, "-2");

            try
            {
                ReadDatabaseFeedRequest(client, headers);
                Assert.Fail("Should throw an exception");
            }
            catch (Exception ex)
            {
                var innerException = ex.InnerException as DocumentClientException;
                Assert.IsTrue(innerException.StatusCode == HttpStatusCode.BadRequest, "Invalid status code");
            }

            headers = new StringKeyValueCollection();
            headers.Add(HttpConstants.HttpHeaders.PageSize, Int64.MaxValue.ToString(CultureInfo.InvariantCulture));

            try
            {
                ReadFeedScript(client, headers);
                Assert.Fail("Should throw an exception");
            }
            catch (Exception ex)
            {
                var innerException = ex.InnerException as DocumentClientException;
                Assert.IsTrue(innerException.StatusCode == HttpStatusCode.BadRequest, "Invalid status code");
            }

            // Valid page size
            headers = new StringKeyValueCollection();
            headers.Add(HttpConstants.HttpHeaders.PageSize, "20");
            var response = ReadDatabaseFeedRequest(client, headers);

            Assert.IsTrue(response.StatusCode == HttpStatusCode.OK);

            headers = new StringKeyValueCollection();
            headers.Add("pageSize", "20");
            var result = ReadFeedScript(client, headers);

            Assert.IsTrue(result.StatusCode == HttpStatusCode.OK);

            // dynamic page size
            headers = new StringKeyValueCollection();
            headers.Add(HttpConstants.HttpHeaders.PageSize, "-1");
            response = ReadDatabaseFeedRequest(client, headers);
            Assert.IsTrue(response.StatusCode == HttpStatusCode.OK);

            headers = new StringKeyValueCollection();
            headers.Add("pageSize", "-1");
            result = ReadFeedScript(client, headers);
            Assert.IsTrue(result.StatusCode == HttpStatusCode.OK);
        }
        private async Task <FeedResource <Address> > GetServerAddressesViaGatewayAsync(
            DocumentServiceRequest request,
            string collectionRid,
            IEnumerable <string> partitionKeyRangeIds,
            bool forceRefresh)
        {
            string entryUrl = PathsHelper.GeneratePath(ResourceType.Document, collectionRid, true);

            INameValueCollection addressQuery = new StringKeyValueCollection();

            addressQuery.Add(HttpConstants.QueryStrings.Url, HttpUtility.UrlEncode(entryUrl));

            INameValueCollection headers = new StringKeyValueCollection();

            if (forceRefresh)
            {
                headers.Set(HttpConstants.HttpHeaders.ForceRefresh, bool.TrueString);
            }

            if (request.ForceCollectionRoutingMapRefresh)
            {
                headers.Set(HttpConstants.HttpHeaders.ForceCollectionRoutingMapRefresh, bool.TrueString);
            }

            addressQuery.Add(HttpConstants.QueryStrings.Filter, this.protocolFilter);
            addressQuery.Add(HttpConstants.QueryStrings.PartitionKeyRangeIds, string.Join(",", partitionKeyRangeIds));

            string resourceTypeToSign = PathsHelper.GetResourcePath(ResourceType.Document);

            headers.Set(HttpConstants.HttpHeaders.XDate, DateTime.UtcNow.ToString("r", CultureInfo.InvariantCulture));
            string token = null;

            try
            {
                token = this.tokenProvider.GetUserAuthorizationToken(
                    collectionRid,
                    resourceTypeToSign,
                    HttpConstants.HttpMethods.Get,
                    headers,
                    AuthorizationTokenType.PrimaryMasterKey);
            }
            catch (UnauthorizedException)
            {
            }

            if (token == null && request.IsNameBased)
            {
                // User doesn't have rid based resource token. Maybe he has name based.
                string collectionAltLink = PathsHelper.GetCollectionPath(request.ResourceAddress);
                token = this.tokenProvider.GetUserAuthorizationToken(
                    collectionAltLink,
                    resourceTypeToSign,
                    HttpConstants.HttpMethods.Get,
                    headers,
                    AuthorizationTokenType.PrimaryMasterKey);
            }

            headers.Set(HttpConstants.HttpHeaders.Authorization, token);

            Uri targetEndpoint = UrlUtility.SetQuery(this.addressEndpoint, UrlUtility.CreateQuery(addressQuery));

            string identifier = GatewayAddressCache.LogAddressResolutionStart(request, targetEndpoint);

            using (HttpResponseMessage httpResponseMessage = await this.httpClient.GetAsync(targetEndpoint, headers))
            {
                using (DocumentServiceResponse documentServiceResponse =
                           await ClientExtensions.ParseResponseAsync(httpResponseMessage))
                {
                    GatewayAddressCache.LogAddressResolutionEnd(request, identifier);

                    return(documentServiceResponse.GetResource <FeedResource <Address> >());
                }
            }
        }
예제 #10
0
        static IDictionary<string, string> QueryString(string url)
        {
            string query = url.Substring(url.IndexOf('?') + 1);

            string[] queryItems = query.Split('&');

            IDictionary<string, string> dic = new StringKeyValueCollection();

            foreach (var qi in queryItems)
            {
                string[] qitem = qi.Split('=');

                if (qitem.Length == 2)
                {
                    dic.Add(qitem[0], qitem[1]);
                }
                else
                {
                    logger.Warning(qi);
                }
            }

            if (dic.Count != queryItems.Length)
            {
                logger.Warning(url);
                logger.Warning(query);
            }

            return dic;
        }