コード例 #1
0
        private static CosmosHttpClient CreateHelper(
            HttpClient httpClient,
            HttpMessageHandler httpMessageHandler,
            TimeSpan requestTimeout,
            UserAgentContainer userAgentContainer,
            ApiType apiType,
            ICommunicationEventSource eventSource)
        {
            if (httpClient == null)
            {
                throw new ArgumentNullException(nameof(httpClient));
            }

            httpClient.Timeout = requestTimeout > CosmosHttpClientCore.GatewayRequestTimeout
                ? requestTimeout
                : CosmosHttpClientCore.GatewayRequestTimeout;
            httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue {
                NoCache = true
            };

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

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

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

            return(new CosmosHttpClientCore(
                       httpClient,
                       httpMessageHandler,
                       eventSource));
        }
コード例 #2
0
        public GatewayStoreModel(
            GlobalEndpointManager endpointManager,
            ISessionContainer sessionContainer,
            TimeSpan requestTimeout,
            ConsistencyLevel defaultConsistencyLevel,
            DocumentClientEventSource eventSource,
            JsonSerializerSettings serializerSettings,
            UserAgentContainer userAgent,
            ApiType apiType,
            Func <HttpClient> httpClientFactory)
            : this(endpointManager,
                   sessionContainer,
                   defaultConsistencyLevel,
                   eventSource)
        {
            HttpClient httpClient = httpClientFactory();

            if (httpClient == null)
            {
                throw new InvalidOperationException("HttpClientFactory did not produce an HttpClient");
            }

            this.InitializeGatewayStoreClient(
                requestTimeout,
                serializerSettings,
                userAgent,
                apiType,
                httpClient);
        }
コード例 #3
0
        static CosmosDiagnosticsContextCore()
        {
            // Default user agent string does not contain client id or features.
            UserAgentContainer userAgentContainer = new UserAgentContainer();

            CosmosDiagnosticsContextCore.DefaultUserAgentString = userAgentContainer.UserAgent;
        }
コード例 #4
0
        private void InitializeGatewayStoreClient(
            TimeSpan requestTimeout,
            JsonSerializerSettings serializerSettings,
            UserAgentContainer userAgent,
            ApiType apiType,
            HttpClient httpClient)
        {
            // Use max of client specified and our own request timeout value when sending
            // requests to gateway. Otherwise, we will have gateway's transient
            // error hiding retries are of no use.
            httpClient.Timeout = (requestTimeout > this.requestTimeout) ? requestTimeout : this.requestTimeout;
            httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue {
                NoCache = true
            };

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

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

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

            this.gatewayStoreClient = new GatewayStoreClient(
                httpClient,
                this.eventSource,
                serializerSettings);
        }
コード例 #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ConnectionPolicy"/> class to connect to the Azure Cosmos DB service.
 /// </summary>
 public ConnectionPolicy()
 {
     this.connectionProtocol          = Protocol.Https;
     this.RequestTimeout              = TimeSpan.FromSeconds(ConnectionPolicy.defaultRequestTimeout);
     this.MediaRequestTimeout         = TimeSpan.FromSeconds(ConnectionPolicy.defaultMediaRequestTimeout);
     this.ConnectionMode              = ConnectionMode.Gateway;
     this.MaxConcurrentFanoutRequests = defaultMaxConcurrentFanoutRequests;
     this.MediaReadMode              = MediaReadMode.Buffered;
     this.UserAgentContainer         = new UserAgentContainer();
     this.preferredLocations         = new ObservableCollection <string>();
     this.EnableEndpointDiscovery    = true;
     this.MaxConnectionLimit         = defaultMaxConcurrentConnectionLimit;
     this.RetryOptions               = new RetryOptions();
     this.EnableReadRequestsFallback = null;
 }
コード例 #6
0
        public void GlobalAddressResolverUpdateAsyncSynchronizationTest()
        {
            SynchronizationContext prevContext = SynchronizationContext.Current;

            try
            {
                TestSynchronizationContext syncContext = new TestSynchronizationContext();
                SynchronizationContext.SetSynchronizationContext(syncContext);
                syncContext.Post(_ =>
                {
                    UserAgentContainer container      = new UserAgentContainer(clientId: 0);
                    FakeMessageHandler messageHandler = new FakeMessageHandler();

                    AccountProperties databaseAccount = new AccountProperties();
                    Mock <IDocumentClientInternal> mockDocumentClient = new Mock <IDocumentClientInternal>();
                    mockDocumentClient.Setup(owner => owner.ServiceEndpoint).Returns(new Uri("https://blabla.com/"));
                    mockDocumentClient.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny <Uri>(), It.IsAny <CancellationToken>())).ReturnsAsync(databaseAccount);

                    GlobalEndpointManager globalEndpointManager = new GlobalEndpointManager(mockDocumentClient.Object, new ConnectionPolicy());
                    GlobalPartitionEndpointManager partitionKeyRangeLocationCache = new GlobalPartitionEndpointManagerCore(globalEndpointManager);

                    ConnectionPolicy connectionPolicy = new ConnectionPolicy
                    {
                        RequestTimeout = TimeSpan.FromSeconds(10)
                    };

                    GlobalAddressResolver globalAddressResolver = new GlobalAddressResolver(
                        endpointManager: globalEndpointManager,
                        partitionKeyRangeLocationCache: partitionKeyRangeLocationCache,
                        protocol: Documents.Client.Protocol.Tcp,
                        tokenProvider: this.mockTokenProvider.Object,
                        collectionCache: null,
                        routingMapProvider: null,
                        serviceConfigReader: this.mockServiceConfigReader.Object,
                        connectionPolicy: connectionPolicy,
                        httpClient: MockCosmosUtil.CreateCosmosHttpClient(() => new HttpClient(messageHandler)));

                    ConnectionStateListener connectionStateListener = new ConnectionStateListener(globalAddressResolver);
                    connectionStateListener.OnConnectionEvent(ConnectionEvent.ReadEof, DateTime.Now, new Documents.Rntbd.ServerKey(new Uri("https://endpoint.azure.com:4040/")));
                }, state: null);
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(prevContext);
            }
        }
コード例 #7
0
        public GatewayStoreModel(
            GlobalEndpointManager endpointManager,
            ISessionContainer sessionContainer,
            TimeSpan requestTimeout,
            ConsistencyLevel defaultConsistencyLevel,
            DocumentClientEventSource eventSource,
            JsonSerializerSettings serializerSettings,
            UserAgentContainer userAgent,
            ApiType apiType = ApiType.None,
            HttpMessageHandler messageHandler = null)
        {
            // CookieContainer is not really required, but is helpful in debugging.
            this.cookieJar       = new CookieContainer();
            this.endpointManager = endpointManager;
            HttpClient httpClient = new HttpClient(messageHandler ?? new HttpClientHandler {
                CookieContainer = this.cookieJar
            });

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

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

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

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

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

            this.eventSource        = eventSource;
            this.gatewayStoreClient = new GatewayStoreClient(
                httpClient,
                this.eventSource,
                serializerSettings);
        }
コード例 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ConnectionPolicy"/> class to connect to the Azure Cosmos DB service.
        /// </summary>
        public ConnectionPolicy()
        {
            this.connectionProtocol          = Protocol.Https;
            this.RequestTimeout              = TimeSpan.FromSeconds(ConnectionPolicy.defaultRequestTimeout);
            this.MediaRequestTimeout         = TimeSpan.FromSeconds(ConnectionPolicy.defaultMediaRequestTimeout);
            this.ConnectionMode              = ConnectionMode.Gateway;
            this.MaxConcurrentFanoutRequests = defaultMaxConcurrentFanoutRequests;
            this.MediaReadMode              = MediaReadMode.Buffered;
            this.UserAgentContainer         = new UserAgentContainer(clientId: 0);
            this.preferredLocations         = new ObservableCollection <string>();
            this.EnableEndpointDiscovery    = true;
            this.MaxConnectionLimit         = defaultMaxConcurrentConnectionLimit;
            this.RetryOptions               = new RetryOptions();
            this.EnableReadRequestsFallback = null;
#if PREVIEW
            this.EnableClientTelemetry = ConfigurationManager.GetEnvironmentVariable <bool>(ClientTelemetryOptions.EnvPropsClientTelemetryEnabled, false);
#endif
        }
コード例 #9
0
 public GatewayStoreModel(
     GlobalEndpointManager endpointManager,
     ISessionContainer sessionContainer,
     TimeSpan requestTimeout,
     ConsistencyLevel defaultConsistencyLevel,
     DocumentClientEventSource eventSource,
     JsonSerializerSettings serializerSettings,
     UserAgentContainer userAgent,
     ApiType apiType,
     HttpMessageHandler messageHandler)
     : this(endpointManager,
            sessionContainer,
            defaultConsistencyLevel,
            eventSource)
 {
     this.InitializeGatewayStoreClient(
         requestTimeout,
         serializerSettings,
         userAgent,
         apiType,
         new HttpClient(messageHandler ?? new HttpClientHandler {
         CookieContainer = this.cookieJar
     }));
 }
コード例 #10
0
        public StoreClientFactory(
            Protocol protocol,
            int requestTimeoutInSeconds,
            int maxConcurrentConnectionOpenRequests,
            UserAgentContainer userAgent          = null,                                 // optional for both HTTPS and RNTBD
            ICommunicationEventSource eventSource = null,                                 // required for HTTPS, not used for RNTBD
            string overrideHostNameInCertificate  = null,                                 // optional for RNTBD, not used for HTTPS
            int openTimeoutInSeconds          = 0,                                        // optional for RNTBD, not used for HTTPS
            int idleTimeoutInSeconds          = 1800,                                     // optional for both HTTPS and RNTBD
            int timerPoolGranularityInSeconds = 0,                                        // optional for RNTBD, not used for HTTPS
            int maxRntbdChannels                = ushort.MaxValue,                        // RNTBD
            int rntbdPartitionCount             = 1,                                      // RNTBD
            int maxRequestsPerRntbdChannel      = 30,                                     // RNTBD
            int receiveHangDetectionTimeSeconds = 65,                                     // RNTBD
            int sendHangDetectionTimeSeconds    = 10,                                     // RNTBD
            Func <TransportClient, TransportClient> transportClientHandlerFactory = null, // Interceptor factory
            bool enableCpuMonitor = true)
        {
            // <=0 means idle timeout is disabled.
            // valid value: >= 10 minutes
            if (idleTimeoutInSeconds > 0 && idleTimeoutInSeconds < 600)
            {
                throw new ArgumentOutOfRangeException(nameof(idleTimeoutInSeconds));
            }

            if (protocol == Protocol.Https)
            {
                if (eventSource == null)
                {
                    throw new ArgumentOutOfRangeException("eventSource");
                }
                this.transportClient = new HttpTransportClient(requestTimeoutInSeconds, eventSource, userAgent, idleTimeoutInSeconds);
            }
            else if (protocol == Protocol.Tcp)
            {
                if (maxRntbdChannels <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(maxRntbdChannels));
                }
                if ((rntbdPartitionCount < 1) || (rntbdPartitionCount > 8))
                {
                    throw new ArgumentOutOfRangeException(nameof(rntbdPartitionCount));
                }
                if (maxRequestsPerRntbdChannel <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(maxRequestsPerRntbdChannel));
                }
                if (maxRntbdChannels > ushort.MaxValue)
                {
                    DefaultTrace.TraceWarning(
                        "The value of {0} is unreasonably large. Received: {1}. " +
                        "Use {2} to represent \"effectively infinite\".",
                        nameof(maxRntbdChannels),
                        maxRntbdChannels,
                        ushort.MaxValue);
                }
                const int minRecommendedMaxRequestsPerChannel = 10;
                const int maxRecommendedMaxRequestsPerChannel = 10000;
                if (maxRequestsPerRntbdChannel < minRecommendedMaxRequestsPerChannel)
                {
                    DefaultTrace.TraceWarning(
                        "The value of {0} is unreasonably small. Received: {1}. " +
                        "Small values of {0} can cause a large number of RNTBD " +
                        "channels to be opened to the same back-end. Reasonable " +
                        "values are between {2} and {3}",
                        nameof(maxRequestsPerRntbdChannel),
                        maxRequestsPerRntbdChannel,
                        minRecommendedMaxRequestsPerChannel,
                        maxRecommendedMaxRequestsPerChannel);
                }
                if (maxRequestsPerRntbdChannel > maxRecommendedMaxRequestsPerChannel)
                {
                    DefaultTrace.TraceWarning(
                        "The value of {0} is unreasonably large. Received: {1}. " +
                        "Large values of {0} can cause significant head-of-line " +
                        "blocking over RNTBD channels. Reasonable values are between {2} and {3}",
                        nameof(maxRequestsPerRntbdChannel),
                        maxRequestsPerRntbdChannel,
                        minRecommendedMaxRequestsPerChannel,
                        maxRecommendedMaxRequestsPerChannel);
                }
                // Not related to maxRecommendedMaxRequestsPerChannel.
                const int minRequiredSimultaneousRequests = 10000;
                if (checked (maxRntbdChannels * maxRequestsPerRntbdChannel) <
                    minRequiredSimultaneousRequests)
                {
                    DefaultTrace.TraceCritical(
                        "The number of simultaneous requests allowed per backend " +
                        "is unreasonably small. Received {0} = {1}, {2} = {3}. " +
                        "Reasonable values are at least {4}",
                        nameof(maxRntbdChannels), maxRntbdChannels,
                        nameof(maxRequestsPerRntbdChannel), maxRequestsPerRntbdChannel,
                        minRequiredSimultaneousRequests);
                }
                const int minReceiveHangDetectionTimeSeconds = 65;
                const int maxReceiveHangDetectionTimeSeconds = 180;
                if (receiveHangDetectionTimeSeconds < minReceiveHangDetectionTimeSeconds)
                {
                    DefaultTrace.TraceWarning(
                        "The value of {0} is too small. Received {1}. Adjusting to {2}",
                        nameof(receiveHangDetectionTimeSeconds),
                        receiveHangDetectionTimeSeconds,
                        minReceiveHangDetectionTimeSeconds);
                    receiveHangDetectionTimeSeconds = minReceiveHangDetectionTimeSeconds;
                }
                if (receiveHangDetectionTimeSeconds > maxReceiveHangDetectionTimeSeconds)
                {
                    DefaultTrace.TraceWarning(
                        "The value of {0} is too large. Received {1}. Adjusting to {2}",
                        nameof(receiveHangDetectionTimeSeconds),
                        receiveHangDetectionTimeSeconds,
                        maxReceiveHangDetectionTimeSeconds);
                    receiveHangDetectionTimeSeconds = maxReceiveHangDetectionTimeSeconds;
                }
                const int minSendHangDetectionTimeSeconds = 2;
                const int maxSendHangDetectionTimeSeconds = 60;
                if (sendHangDetectionTimeSeconds < minSendHangDetectionTimeSeconds)
                {
                    DefaultTrace.TraceWarning(
                        "The value of {0} is too small. Received {1}. Adjusting to {2}",
                        nameof(sendHangDetectionTimeSeconds),
                        sendHangDetectionTimeSeconds,
                        minSendHangDetectionTimeSeconds);
                    sendHangDetectionTimeSeconds = minSendHangDetectionTimeSeconds;
                }
                if (sendHangDetectionTimeSeconds > maxSendHangDetectionTimeSeconds)
                {
                    DefaultTrace.TraceWarning(
                        "The value of {0} is too large. Received {1}. Adjusting to {2}",
                        nameof(sendHangDetectionTimeSeconds),
                        sendHangDetectionTimeSeconds,
                        maxSendHangDetectionTimeSeconds);
                    sendHangDetectionTimeSeconds = maxSendHangDetectionTimeSeconds;
                }
                this.fallbackClient = new RntbdTransportClient(
                    requestTimeoutInSeconds,
                    maxConcurrentConnectionOpenRequests,
                    userAgent,
                    overrideHostNameInCertificate,
                    openTimeoutInSeconds,
                    idleTimeoutInSeconds,
                    timerPoolGranularityInSeconds);
                this.transportClient = new Rntbd.TransportClient(
                    new Rntbd.TransportClient.Options(TimeSpan.FromSeconds(requestTimeoutInSeconds))
                {
                    MaxChannels              = maxRntbdChannels,
                    PartitionCount           = rntbdPartitionCount,
                    MaxRequestsPerChannel    = maxRequestsPerRntbdChannel,
                    ReceiveHangDetectionTime = TimeSpan.FromSeconds(receiveHangDetectionTimeSeconds),
                    SendHangDetectionTime    = TimeSpan.FromSeconds(sendHangDetectionTimeSeconds),
                    UserAgent = userAgent,
                    CertificateHostNameOverride = overrideHostNameInCertificate,
                    OpenTimeout         = TimeSpan.FromSeconds(openTimeoutInSeconds),
                    TimerPoolResolution = TimeSpan.FromSeconds(timerPoolGranularityInSeconds),
                    IdleTimeout         = TimeSpan.FromSeconds(idleTimeoutInSeconds),
                    EnableCpuMonitor    = enableCpuMonitor
                });
            }
            else
            {
                throw new ArgumentOutOfRangeException("protocol", protocol, "Invalid protocol value");
            }
            this.protocol = protocol;

            if (transportClientHandlerFactory != null)
            {
                this.fallbackClient  = transportClientHandlerFactory(this.fallbackClient);
                this.transportClient = transportClientHandlerFactory(this.transportClient);
            }
        }