private static string BuildEndpointUri(NamedService service, string endpointName, HttpServiceUriTarget target, ServicePartitionKey partitionKey, string scheme) { if (service == null) { throw new ArgumentNullException(nameof(service)); } if (string.IsNullOrEmpty(scheme)) { throw new ArgumentException(nameof(scheme)); } HttpServiceUriBuilder builder = new HttpServiceUriBuilder(); builder.SetScheme(scheme); builder.SetServiceName(service); builder.SetPartitionKey(partitionKey); builder.SetEndpointName(endpointName); builder.SetTarget(target); return(builder.Build().OriginalString); }
protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // If the request is outside of the Fabric application, just pass through and do nothing if (!StringComparer.OrdinalIgnoreCase.Equals(request.RequestUri.Host, "fabric")) { return(await base.SendAsync(request, cancellationToken)); } ResolvedServicePartition partition = null; HttpServiceUriBuilder uriBuilder = new HttpServiceUriBuilder(request.RequestUri); var servicePartitionResolver = ServicePartitionResolver.GetDefault(); NeedsResolveServiceEndpointException exception = null; int retries = this.maxRetries; int retryDelay = this.initialRetryDelayMs; while (retries-- > 0) { cancellationToken.ThrowIfCancellationRequested(); partition = partition != null ? await servicePartitionResolver.ResolveAsync(partition, cancellationToken) : await servicePartitionResolver.ResolveAsync(uriBuilder.ServiceName, uriBuilder.PartitionKey, cancellationToken); string serviceEndpointJson; switch (uriBuilder.Target) { case HttpServiceUriTarget.Primary: serviceEndpointJson = partition.GetEndpoint().Address; break; case HttpServiceUriTarget.Secondary: serviceEndpointJson = this.GetRandomEndpointAddress(partition.Endpoints, 1); break; case HttpServiceUriTarget.Any: default: serviceEndpointJson = this.GetRandomEndpointAddress(partition.Endpoints, 0); break; } string endpointUrl = JObject.Parse(serviceEndpointJson)["Endpoints"][uriBuilder.EndpointName].Value <string>(); request.RequestUri = new Uri($"{endpointUrl.TrimEnd('/')}/{uriBuilder.ServicePathAndQuery.TrimStart('/')}", UriKind.Absolute); CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(this.requestTimeoutMs).Token, cancellationToken); try { HttpResponseMessage response = await base.SendAsync(request, cts.Token); return(response); } catch (NeedsResolveServiceEndpointException ex) { exception = ex; if (retries == 0) { break; } } await Task.Delay(retryDelay); retryDelay += retryDelay; } if (exception.Response != null) { return(exception.Response); } else { throw exception.InnerException; } }