public static Task<HttpResponseMessage> SendToServiceAsync(
            this HttpClient instance, Uri serviceInstanceUri, Func<HttpRequestMessage> createRequest,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ServicePartitionClient<HttpCommunicationClient> servicePartitionClient = new ServicePartitionClient<HttpCommunicationClient>(
                clientFactory,
                serviceInstanceUri);

            return MakeHttpRequest(instance, createRequest, cancellationToken, servicePartitionClient);
        }
        public Task<string> Results()
        {
            Uri serviceUri = new ServiceUriBuilder(ChaosTestServiceName).ToUri();

            ServicePartitionClient<HttpCommunicationClient> servicePartitionClient = new ServicePartitionClient<HttpCommunicationClient>(
                this.clientFactory,
                serviceUri);

            return servicePartitionClient.InvokeWithRetryAsync(
                client =>  client.HttpClient.GetStringAsync(new Uri(client.Url, "api/Results")));
        }
        public Task Stop()
        {
            Uri serviceUri = new ServiceUriBuilder(ChaosTestServiceName).ToUri();

            ServicePartitionClient<HttpCommunicationClient> servicePartitionClient = new ServicePartitionClient<HttpCommunicationClient>(
                this.clientFactory,
                serviceUri);

            return servicePartitionClient.InvokeWithRetryAsync(
                client => client.HttpClient.PostAsync(new Uri(client.Url, "api/Stop"), new StringContent(String.Empty)));
        }
        public async Task<HttpResponseMessage> Count()
        {
            // For each partition client, keep track of partition information and the number of words
            ConcurrentDictionary<Int64RangePartitionInformation, long> totals = new ConcurrentDictionary<Int64RangePartitionInformation, long>();
            IList<Task> tasks = new List<Task>();

            foreach (Int64RangePartitionInformation partition in await this.GetServicePartitionKeysAsync())
            {
                try
                {
                    ServicePartitionClient<HttpCommunicationClient> partitionClient
                        = new ServicePartitionClient<HttpCommunicationClient>(communicationFactory, serviceUri, new ServicePartitionKey(partition.LowKey));

                    await partitionClient.InvokeWithRetryAsync(
                        async (client) =>
                        {
                            HttpResponseMessage response = await client.HttpClient.GetAsync(new Uri(client.Url, "Count"));
                            string content = await response.Content.ReadAsStringAsync();
                            totals[partition] = Int64.Parse(content.Trim());
                        });
                }
                catch (Exception ex)
                {
                    // Sample code: print exception
                    ServiceEventSource.Current.OperationFailed(ex.Message, "Count - run web request");
                }
            }

            StringBuilder sb = new StringBuilder();
            sb.Append("<h1> Total:");
            sb.Append(totals.Aggregate<KeyValuePair<Int64RangePartitionInformation, long>, long>(0, (total, next) => next.Value + total));
            sb.Append("</h1>");
            sb.Append("<table><tr><td>Partition ID</td><td>Key Range</td><td>Total</td></tr>");
            foreach (KeyValuePair<Int64RangePartitionInformation, long> partitionData in totals.OrderBy(partitionData => partitionData.Key.LowKey))
            {
                sb.Append("<tr><td>");
                sb.Append(partitionData.Key.Id);
                sb.Append("</td><td>");
                sb.AppendFormat("{0} - {1}", partitionData.Key.LowKey, partitionData.Key.HighKey);
                sb.Append("</td><td>");
                sb.Append(partitionData.Value);
                sb.Append("</td></tr>");
            }

            sb.Append("</table>");

            return new HttpResponseMessage()
            {
                Content = new StringContent(sb.ToString(), Encoding.UTF8, "text/html")
            };
        }
        public async Task Invoke(HttpContext context)
        {
            // create the Service Fabric client (it will resolve the address)
            var client = new ServicePartitionClient<HttpCommunicationClient>(
                _clientFactory,
                new Uri("fabric:/GatewaySample/HttpService"));

            // call your service.
            await client.InvokeWithRetry(async x =>
            {
                HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, "api/values");

                HttpResponseMessage response = await x.HttpClient.SendAsync(req, context.RequestAborted);

                await context.Response.WriteAsync(DateTime.Now + " - Result from API: ");
                await context.Response.WriteAsync("Status: " + response.StatusCode + "; Body: ");
                await response.Content.CopyToAsync(context.Response.Body);
            });
        }
        public async Task <int> GetSummaryAsync(string slot)
        {
            var summary = 0;

            ServicePartitionClient <HttpCommunicationClient> partitionClient
                = new ServicePartitionClient <HttpCommunicationClient>(communicationClientFactory, serviceUri, new ServicePartitionKey());

            await partitionClient.InvokeWithRetryAsync(
                async (client) =>
            {
                HttpResponseMessage httpResponse = await client.HttpClient.GetAsync(new Uri($"{client.Url}api/analysis/summary/{slot}"));
                httpResponse.EnsureSuccessStatusCode();

                string content = await httpResponse.Content.ReadAsStringAsync();
                summary        = int.Parse(content);
            });

            return(summary);
        }
Exemple #7
0
        public async Task <IActionResult> AddNewInventoryItem(InventoryItem newItem)
        {
            var partitionKey    = new ServicePartitionKey((int)newItem.ItemType);
            var partitionClient = new ServicePartitionClient <HttpCommunicationClient>(_clientFactory, _serviceUri, partitionKey);
            var results         = await partitionClient.InvokeWithRetryAsync(async (client) =>
            {
                var newItemContent = new StringContent(JsonConvert.SerializeObject(newItem), Encoding.UTF8, "application/json");
                var response       = await client.HttpClient.PostAsync(new Uri($"{client.BaseUri}/api/inventory"), newItemContent);
                if (!response.IsSuccessStatusCode)
                {
                    throw new InvalidOperationException($"Error - {response.StatusCode}: {response.ReasonPhrase}");
                }

                var responseContent = await response.Content.ReadAsStringAsync();
                return(JsonConvert.DeserializeObject <InventoryItem>(responseContent));
            }, CancellationToken.None);

            return(RedirectToAction("Index", new { SelectedItemType = newItem.ItemType }));
        }
        public async Task Invoke(HttpContext context)
        {
            // create the Service Fabric client (it will resolve the address)
            var client = new ServicePartitionClient <HttpCommunicationClient>(
                _clientFactory,
                new Uri("fabric:/GatewaySample/HttpService"));

            // call your service.
            await client.InvokeWithRetryAsync(async x =>
            {
                HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, "api/values");

                HttpResponseMessage response = await x.HttpClient.SendAsync(req, context.RequestAborted);

                await context.Response.WriteAsync(DateTime.Now + " - Result from API: ");
                await context.Response.WriteAsync("Status: " + response.StatusCode + "; Body: ");
                await response.Content.CopyToAsync(context.Response.Body);
            }, context.RequestAborted);
        }
        public async Task <byte[]> ProcessWsMessageAsync(
            byte[] wsrequest, CancellationToken cancellationToken
            )
        {
            IWsSerializer    mserializer = new ProtobufWsSerializer();
            WsRequestMessage mrequest    = await mserializer.DeserializeAsync <WsRequestMessage>(wsrequest);

            ServicePartitionClient <WsCommunicationClient> serviceClient =
                new ServicePartitionClient <WsCommunicationClient>(
                    this.clientFactory,
                    ConnectionFactory.StockServiceUri,
                    partitionKey: new ServicePartitionKey(mrequest.PartitionKey),
                    listenerName: ServiceConst.ListenerWebsocket);

            return(await serviceClient.InvokeWithRetryAsync(
                       async client => await client.SendReceiveAsync(wsrequest),
                       cancellationToken
                       ));
        }
        public async Task<byte[]> ProcessWsMessageAsync(
            byte[] wsrequest, CancellationToken cancellationToken
            )
        {
            IWsSerializer mserializer = new ProtobufWsSerializer();
            WsRequestMessage mrequest = await mserializer.DeserializeAsync<WsRequestMessage>(wsrequest);

            ServicePartitionClient<WsCommunicationClient> serviceClient =
                new ServicePartitionClient<WsCommunicationClient>(
                    this.clientFactory,
                    ConnectionFactory.StockServiceUri,
                    partitionKey: new ServicePartitionKey(mrequest.PartitionKey),
                    listenerName: ServiceConst.ListenerWebsocket);

            return await serviceClient.InvokeWithRetryAsync(
                async client => await client.SendReceiveAsync(wsrequest),
                cancellationToken
                );
        }
        static void Main(string[] args)
        {

            try
            { }
            finally
            {
                // using service fabric interfaces 
                var factory = new WcfMultiPointCommunicationClientFactory(ServicePartitionResolver.GetDefault());
                //if you are using singlton partition
                //ServicePartitionClient<WcfMultiPointCommunicationClient> partitionClient = new ServicePartitionClient<WcfMultiPointCommunicationClient>(factory, new Uri(FabricServiceName));
                // if you are using partitions (named (string param) range (long param))
                ServicePartitionClient<WcfMultiPointCommunicationClient> partitionClient = new ServicePartitionClient<WcfMultiPointCommunicationClient>(factory, new Uri(FabricServiceName), "P1");

                int MaxRounds = 100;
                int current = 1;
                    while (current <= MaxRounds)
                    {
                        try
                        {
                            //doStuffUsingStandardResolve().Wait();
                            //doStuffUsingICommInterfaces(partitionClient).Wait();
                            CallSvcThatUsesReliableCollection().Wait();
                            Console.WriteLine("*********************************************************");
                            Thread.Sleep(500);
                        }
                        catch(AggregateException ae)
                        {
                            Console.WriteLine(string.Format("call error {0}", ae.Flatten().Message));
                            Thread.Sleep(100);
                        }

                        current++;
                    }
              
            }


            Console.WriteLine("Done!");
            Console.Read();

        }
Exemple #12
0
        static void Main(string[] args)
        {
            IServicePartitionResolver partitionResolver = new ServicePartitionResolver("localhost:19000");
            var binding = WcfUtility.CreateTcpClientBinding();


            var wcfClientFactory = new WcfCommunicationClientFactory <ICalculatorService>
                                       (clientBinding: binding, servicePartitionResolver: partitionResolver);

            for (int i = 0; i < 10; i++)
            {
                var calculatorServiceCommunicationClient = new ServicePartitionClient <WcfCommunicationClient <ICalculatorService> >(
                    wcfClientFactory,
                    new Uri("fabric:/CalculatorApplication/CalculatorService"));

                var result = calculatorServiceCommunicationClient.InvokeWithRetryAsync(
                    client => client.Channel.Add(2, 3)).Result;
                Console.WriteLine(result);
            }
        }
Exemple #13
0
        /// <summary>
        /// This is the main entry point for your service instance.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service instance.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            long iterations           = 0;
            var  resolver             = ServicePartitionResolver.GetDefault();
            var  serviceUri           = new Uri(FabricRuntime.GetActivationContext().ApplicationName + "/Service");
            var  communicationFactory = new GrpcCommunicationClientFactory <Greeter.GreeterClient>(null, resolver);

            var partitionClient = new ServicePartitionClient <GrpcCommunicationClient <Greeter.GreeterClient> >(communicationFactory, serviceUri, ServicePartitionKey.Singleton);

            while (!cancellationToken.IsCancellationRequested)
            {
                var reply = partitionClient.InvokeWithRetry((communicationClient) => communicationClient.Client.SayHello(new HelloRequest {
                    Name = $"{++iterations}"
                }));

                ServiceEventSource.Current.ServiceMessage(this.Context, "Client Received: {0}", reply.Message);

                await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
            }
        }
        public async Task <HttpResponseMessage> AddWord(string word)
        {
            // Determine the partition key that should handle the request
            var partitionKey = GetPartitionKey(word);

            var partitionClient =
                new ServicePartitionClient <HttpCommunicationClient>(_communicationFactory, _serviceUri, new ServicePartitionKey(partitionKey));

            await
            partitionClient.InvokeWithRetryAsync(
                async client => { await client.HttpClient.PutAsync(new Uri(client.Url, "AddWord/" + word), new StringContent(String.Empty)); });

            return(new HttpResponseMessage()
            {
                Content = new StringContent(
                    $"<h1>{word}</h1> added to partition with key <h2>{partitionKey}</h2>",
                    Encoding.UTF8,
                    "text/html")
            });
        }
        private static Task<HttpResponseMessage> MakeHttpRequest(
            HttpClient instance, Func<HttpRequestMessage> createRequest, CancellationToken cancellationToken,
            ServicePartitionClient<HttpCommunicationClient> servicePartitionClient)
        {
            return servicePartitionClient.InvokeWithRetryAsync(
                async
                    client =>
                    {
                        HttpRequestMessage request = createRequest();

                        Uri newUri = new Uri(client.BaseAddress, request.RequestUri.OriginalString.TrimStart('/'));

                        request.RequestUri = newUri;

                        HttpResponseMessage response = await instance.SendAsync(request, cancellationToken);

                        response.EnsureSuccessStatusCode();

                        return response;
                    });
        }
        public async Task <HttpResponseMessage> ProxyToService(FabricAddress fabricAddress, HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var client = new ServicePartitionClient <HttpCommunicationClient>(this.communicationClientFactory, fabricAddress.Uri, retrySettings: this.operationRetrySettings);

            await request.Content.LoadIntoBufferAsync();

            return(await client.InvokeWithRetryAsync(async c =>
            {
                try
                {
                    var serviceUri = GetServiceUri(c.Url, request.RequestUri);
                    return await ProxyRequest(serviceUri, request, c.HttpClient);
                }
                catch (Exception ex)
                {
                    ex.Data.Add("Resolved Service Uri", c.Url);
                    throw;
                }
            },
                                                     cancellationToken));
        }
Exemple #17
0
        private static Task <HttpResponseMessage> MakeHttpRequest(
            HttpClient instance, Func <HttpRequestMessage> createRequest, CancellationToken cancellationToken,
            ServicePartitionClient <HttpCommunicationClient> servicePartitionClient)
        {
            return(servicePartitionClient.InvokeWithRetryAsync(
                       async
                       client =>
            {
                HttpRequestMessage request = createRequest();

                Uri newUri = new Uri(client.BaseAddress, request.RequestUri.OriginalString.TrimStart('/'));

                request.RequestUri = newUri;

                HttpResponseMessage response = await instance.SendAsync(request, cancellationToken);

                response.EnsureSuccessStatusCode();

                return response;
            }));
        }
        private async void AskForApproval(string employeeName)
        {
            var fabricClient         = new FabricClient();
            var communicationFactory = new HttpCommunicationClientFactory(new ServicePartitionResolver(() => fabricClient));
            var serviceUri           = new Uri(FabricRuntime.GetActivationContext().ApplicationName + "/LineManagerLeaveApprovalService");

            ServicePartitionClient <HttpCommunicationClient> partitionClient =
                new ServicePartitionClient <HttpCommunicationClient>(
                    communicationFactory,
                    serviceUri,
                    new ServicePartitionKey());

            await
            partitionClient.InvokeWithRetryAsync(
                async (client) =>
            {
                await client.HttpClient.PutAsync(
                    new Uri(client.Url, "Employee/" + employeeName),
                    new StringContent(String.Empty));
            });
        }
        public async Task <AddWordResponse> AddWord(string word)
        {
            // Determine the partition key that should handle the request
            long partitionKey = GetPartitionKey(word);

            // Use service partition client to resolve the service and partition key.
            // This determines the endpoint of the replica that should handle the request.
            // Internally, the service partition client handles exceptions and retries appropriately.
            ServicePartitionClient <CommunicationClient> servicePartitionClient = new ServicePartitionClient <CommunicationClient>(
                clientFactory,
                new Uri(WordCountServiceName),
                partitionKey);

            var res = await servicePartitionClient.InvokeWithRetryAsync(
                client =>
            {
                Uri serviceAddress = new Uri(client.BaseAddress, string.Format("AddWord/{0}", word));

                HttpWebRequest request   = WebRequest.CreateHttp(serviceAddress);
                request.Method           = "PUT";
                request.ContentLength    = 0;
                request.Timeout          = (int)client.OperationTimeout.TotalMilliseconds;
                request.ReadWriteTimeout = (int)client.ReadWriteTimeout.TotalMilliseconds;

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        string httpResult = reader.ReadToEnd().Trim();
                    }
                var retVal = new AddWordResponse();

                retVal.PartitionId    = client.ResolvedServicePartition.Info.Id;
                retVal.ServiceAddress = serviceAddress.ToString();
                retVal.Word           = word;

                return(Task.FromResult(retVal));
            });

            return(res);
        }
Exemple #20
0
        public async Task Invoke(HttpContext context)
        {
            byte[] contextRequestBody = null;

            try
            {
                ServicePartitionClient <HttpCommunicationClient> servicePartitionClient = CreateServicePartitionClient(context);

                // Request Body is a forward-only stream so it is read into memory for potential retries.
                // NOTE: This might be an issue for very big requests.
                if (context.Request.ContentLength > 0)
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        context.Request.Body.CopyTo(memoryStream);
                        contextRequestBody = memoryStream.ToArray();
                    }
                }

                HttpResponseMessage response = await servicePartitionClient.InvokeWithRetryAsync(
                    client => ExecuteServiceCallAsync(client, context, contextRequestBody),
                    context.RequestAborted);

                if (response != null)
                {
                    await response.CopyToCurrentContext(context);
                }
                else
                {
                    _logger.LogWarning("No response. RequestAborted: {RequestAborted}", context.RequestAborted);
                }
            }
            catch (HttpResponseException ex)
            {
                // as soon as we get a response from the service, we don't treat it as an error from the gateway.
                // For this reason, we forward faulty responses to the caller 1:1.
                _logger.LogWarning("Service returned non retryable error. Reason: {Reason}", "HTTP " + ex.Response.StatusCode);
                await ex.Response.CopyToCurrentContext(context);
            }
        }
        public async Task <HttpResponseMessage> AddWord(string word)
        {
            // Determine the partition key that should handle the request
            long partitionKey = GetPartitionKey(word);

            //ServiceProxy.Create<IWordCount>(serviceUri, new ServicePartitionKey(partitionKey))

            ServicePartitionClient <HttpCommunicationClient> partitionClient
                = new ServicePartitionClient <HttpCommunicationClient>(communicationFactory, serviceUri, new ServicePartitionKey(partitionKey));

            await
            partitionClient.InvokeWithRetryAsync(
                async (client) => { await client.HttpClient.PutAsync(new Uri(client.Url, "AddWord/" + word), new StringContent(String.Empty)); });

            return(new HttpResponseMessage()
            {
                Content = new StringContent(
                    String.Format("<h1>{0}</h1> added to partition with key <h2>{1}</h2>", word, partitionKey),
                    Encoding.UTF8,
                    "text/html")
            });
        }
        static async Task Main(string[] args)
        {
            var serviceUri = new Uri("fabric:/ECommerce/ECommerce.Api.Orders");
            var binding    = WcfUtility.CreateTcpClientBinding();
            var servicePartitionResolver      = ServicePartitionResolver.GetDefault();
            var wcfCommunicationClientFactory =
                new WcfCommunicationClientFactory <IOrdersService>(binding, null, servicePartitionResolver);
            var servicePartitionClient =
                new ServicePartitionClient <WcfCommunicationClient <IOrdersService> >(wcfCommunicationClientFactory, serviceUri);

            Console.WriteLine($"Please wait...");

            var result = await servicePartitionClient.InvokeWithRetryAsync(client => client.Channel.GetOrdersAsync());

            if (result != null && result.Any())
            {
                foreach (var order in result)
                {
                    Console.WriteLine($"{order.Id} {order.CustomerId} {order.OrderDate} {order.Total}");
                }
            }
        }
Exemple #23
0
        public async Task <VendorModel> Get(Guid vendorId)
        {
            try
            {
                ServicePartitionClient <HttpCommunicationClient> partitionClient = new ServicePartitionClient <HttpCommunicationClient>(communicationFactory, serviceUri);

                return(await partitionClient.InvokeWithRetryAsync(
                           async (client) =>
                {
                    var uri = client.Url.ToString() + "api/vendors/" + vendorId.ToString();

                    HttpResponseMessage response = await client.HttpClient.GetAsync(uri);
                    string content = await response.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject <VendorModel>(content);
                }));
            }
            catch (Exception ex)
            {
                // Sample code: print exception
                //ServiceEventSource.Current.OperationFailed(ex.Message, "Count - run web request");
                throw;
            }
        }
Exemple #24
0
        private async Task uploadTranscript(string fileName, string text, string user)
        {
            string connectionString            = "[Storage Account Connection String]";
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
            CloudBlobClient     blobClient     = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer  container      = blobClient.GetContainerReference("transcripts");
            CloudBlockBlob      blockBlob      = container.GetBlockBlobReference(fileName + "transcript.txt");

            using (var stream = new MemoryStream(Encoding.Default.GetBytes(text), false))
            {
                await blockBlob.UploadFromStreamAsync(stream);
            }

            Binding binding = WcfUtility.CreateTcpClientBinding();
            IServicePartitionResolver partitionResolver = ServicePartitionResolver.GetDefault();
            var wcfClientFactory = new WcfCommunicationClientFactory <IStateAggregator>(
                clientBinding: binding,
                servicePartitionResolver: partitionResolver
                );
            var jobClient = new ServicePartitionClient <WcfCommunicationClient <IStateAggregator> >(
                wcfClientFactory,
                new Uri("fabric:/AudioTranscriptionApp/StateAggregator"));
            await jobClient.InvokeWithRetryAsync(client => client.Channel.ReportCompletion(fileName, blockBlob.Uri.AbsoluteUri, user));
        }
Exemple #25
0
        private static void SendTestMessageToQueue(Uri uri, string queueName, bool serviceSupportsPartitions, bool requireSessions = false)
        {
            //the name of your application and the name of the Service, the default partition resolver and the topic name
            //to create a communication client factory:
            var factory = new ServiceBusQueueCommunicationClientFactory(ServicePartitionResolver.GetDefault(), null);

            ServicePartitionClient <ServiceBusQueueCommunicationClient> servicePartitionClient;

            if (serviceSupportsPartitions)
            {
                //determine the partition and create a communication proxy
                var partitionKey = new ServicePartitionKey(0L);
                servicePartitionClient = new ServicePartitionClient <ServiceBusQueueCommunicationClient>(factory, uri, partitionKey);
            }
            else
            {
                servicePartitionClient = new ServicePartitionClient <ServiceBusQueueCommunicationClient>(factory, uri);
            }

            //use the proxy to send a message to the Service
            servicePartitionClient.InvokeWithRetry(c => c.SendMessage(CreateMessage(requireSessions)));

            Console.WriteLine($"Message sent to queue '{queueName}'");
        }
        private static void SendTestMessageToTopic(Uri uri, string topicName, bool serviceSupportsPartitions)
        {
            //the name of your application and the name of the Service, the default partition resolver and the topic name
            //to create a communication client factory:
            var factory = new ServiceBusTopicCommunicationClientFactory(ServicePartitionResolver.GetDefault(), topicName);

            ServicePartitionClient <ServiceBusTopicCommunicationClient> servicePartitionClient;

            if (serviceSupportsPartitions)
            {
                //determine the partition and create a communication proxy
                long partitionKey = 0L;
                servicePartitionClient = new ServicePartitionClient <ServiceBusTopicCommunicationClient>(factory, uri, partitionKey);
            }
            else
            {
                servicePartitionClient = new ServicePartitionClient <ServiceBusTopicCommunicationClient>(factory, uri);
            }

            //use the proxy to send a message to the Service
            servicePartitionClient.InvokeWithRetry(c => c.SendMessage(CreateMessage()));

            Console.WriteLine("Message sent to topic");
        }
Exemple #27
0
        public async Task <IActionResult> Index(InventoryItemType?selectedItemType)
        {
            // If not item type is selected, just display a blank list
            if (selectedItemType == null)
            {
                return(View(new ItemListViewModel {
                    InventoryItems = new InventoryItem[] { }
                }));
            }

            // An item type has been selected - retrieve its contents.
            var partitionKey    = new ServicePartitionKey((Int64)selectedItemType);
            var partitionClient = new ServicePartitionClient <HttpCommunicationClient>(_clientFactory, _serviceUri, partitionKey);
            var items           = await partitionClient.InvokeWithRetryAsync(async (client) =>
            {
                var response = await client.HttpClient.GetAsync(new Uri($"{client.BaseUri}/api/inventory"));
                if (!response.IsSuccessStatusCode)
                {
                    throw new InvalidOperationException($"Error - {response.StatusCode}: {response.ReasonPhrase}");
                }

                var responseContent = await response.Content.ReadAsStringAsync();
                var resultItems     = JsonConvert.DeserializeObject <IEnumerable <InventoryItem> >(responseContent);

                // Note - filter applied client-side for demo purposes only.
                return(resultItems.Where(x => x.ItemType == selectedItemType));
            }, CancellationToken.None);

            var viewModel = new ItemListViewModel
            {
                InventoryItems   = items,
                SelectedItemType = selectedItemType
            };

            return(View(viewModel));
        }
        /// <summary>
        /// Invokes the middleware logic in the pipeline.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <returns>
        /// A <see cref="Task"/> that can be awaited.
        /// </returns>
        /// <exception cref="ArgumentNullException">The input context is null.</exception>
        public async Task Invoke(HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // NOTE:
            // Some of the code is copied from
            // https://github.com/AspNet/Proxy/blob/dev/src/Microsoft.AspNetCore.Proxy/ProxyMiddleware.cs for prototype
            // purpose.
            // Reviewing the license of the code will be needed if this code is to be used in production.
            var servicePartitionKey = this.options.ServicePartitionKeySelector == null
                                          ? new ServicePartitionKey()
                                          : this.options.ServicePartitionKeySelector.Invoke(context);
            var servicePartitionClient = new ServicePartitionClient <HttpRequestDispatcher>(
                this.dispatcherProvider,
                this.options.ServiceUri,
                servicePartitionKey,
                this.options.TargetReplicaSelector,
                this.options.ListenerName,
                this.options.OperationRetrySettings);

            try
            {
                await servicePartitionClient.InvokeWithRetryAsync(
                    async dispatcher =>
                {
                    await this.InvokeAsync(context, dispatcher);
                });
            }
            catch (Exception exception)
            {
                Log.Error(exception, "Error while handling request for address {url}", context.Request.Path);
            }
        }
        public async Task Invoke(HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            //
            // NOTE:
            // Some of the code is copied from https://github.com/AspNet/Proxy/blob/dev/src/Microsoft.AspNetCore.Proxy/ProxyMiddleware.cs for prototype purpose.
            // Reviewing the license of the code will be needed if this code is to be used in production.
            //
            var servicePartitionClient = new ServicePartitionClient <HttpRequestDispatcher>(_dispatcherProvider,
                                                                                            _options.ServiceUri,
                                                                                            _options.GetServicePartitionKey?.Invoke(context),
                                                                                            _options.TargetReplicaSelector,
                                                                                            _options.ListenerName,
                                                                                            _options.OperationRetrySettings);

            await servicePartitionClient.InvokeWithRetryAsync(async dispatcher =>
            {
                var requestMessage = new HttpRequestMessage();

                //
                // Copy the request method
                //
                requestMessage.Method = new HttpMethod(context.Request.Method);

                //
                // Copy the request content
                //
                if (!StringComparer.OrdinalIgnoreCase.Equals(context.Request.Method, "GET") &&
                    !StringComparer.OrdinalIgnoreCase.Equals(context.Request.Method, "HEAD") &&
                    !StringComparer.OrdinalIgnoreCase.Equals(context.Request.Method, "DELETE") &&
                    !StringComparer.OrdinalIgnoreCase.Equals(context.Request.Method, "TRACE"))
                {
                    requestMessage.Content = new StreamContent(context.Request.Body);
                }

                //
                // Copy the request headers
                //
                foreach (var header in context.Request.Headers)
                {
                    if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) && requestMessage.Content != null)
                    {
                        requestMessage.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
                    }
                }

                //
                // Flow path base through the custom header X-ServiceFabric-PathBase.
                //
                requestMessage.Headers.TryAddWithoutValidation("X-ServiceFabric-PathBase", context.Request.PathBase);

                //
                // Construct the request URL
                //
                var baseAddress  = dispatcher.BaseAddress;
                var pathAndQuery = PathString.FromUriComponent(baseAddress) + context.Request.Path + context.Request.QueryString;

                requestMessage.RequestUri = new Uri($"{baseAddress.Scheme}://{baseAddress.Host}:{baseAddress.Port}{pathAndQuery}", UriKind.Absolute);

                //
                // Set host header
                //
                requestMessage.Headers.Host = baseAddress.Host + ":" + baseAddress.Port;

                //
                // Send request and copy the result back to HttpResponse
                //
                using (var responseMessage = await dispatcher.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted))
                {
                    //
                    // If the service is temporarily unavailable, throw to retry later.
                    //
                    if (responseMessage.StatusCode == HttpStatusCode.ServiceUnavailable)
                    {
                        responseMessage.EnsureSuccessStatusCode();
                    }

                    //
                    // Copy the status code
                    //
                    context.Response.StatusCode = (int)responseMessage.StatusCode;

                    //
                    // Copy the response headers
                    //
                    foreach (var header in responseMessage.Headers)
                    {
                        context.Response.Headers[header.Key] = header.Value.ToArray();
                    }

                    foreach (var header in responseMessage.Content.Headers)
                    {
                        context.Response.Headers[header.Key] = header.Value.ToArray();
                    }

                    // SendAsync removes chunking from the response. This removes the header so it doesn't expect a chunked response.
                    context.Response.Headers.Remove("transfer-encoding");

                    //
                    // Copy the response content
                    //
                    await responseMessage.Content.CopyToAsync(context.Response.Body);
                }
            });
        }
 private static async Task<long> Get(
     ServicePartitionClient<WcfCommunicationClient<IKeyValueStore>> client,
     string key)
 {
     var value = await client.InvokeWithRetryAsync(_ => _.Channel.Get(key));
     return BitConverter.ToInt64(value, 0);
 }
        public async Task<AddWordResponse> AddWord(string word)
        {
            // Determine the partition key that should handle the request
            long partitionKey = GetPartitionKey(word);

            // Use service partition client to resolve the service and partition key.
            // This determines the endpoint of the replica that should handle the request.
            // Internally, the service partition client handles exceptions and retries appropriately.
            ServicePartitionClient<CommunicationClient> servicePartitionClient = new ServicePartitionClient<CommunicationClient>(
                clientFactory,
                new Uri(WordCountServiceName),
                partitionKey);

            var res = await servicePartitionClient.InvokeWithRetryAsync(
                client =>
                {
                    Uri serviceAddress = new Uri(client.BaseAddress, string.Format("AddWord/{0}", word));

                    HttpWebRequest request = WebRequest.CreateHttp(serviceAddress);
                    request.Method = "PUT";
                    request.ContentLength = 0;
                    request.Timeout = (int) client.OperationTimeout.TotalMilliseconds;
                    request.ReadWriteTimeout = (int) client.ReadWriteTimeout.TotalMilliseconds;

                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        string httpResult = reader.ReadToEnd().Trim();
                        
                    }
                    var retVal = new AddWordResponse();

                    retVal.PartitionId = client.ResolvedServicePartition.Info.Id;
                    retVal.ServiceAddress = serviceAddress.ToString();
                    retVal.Word = word;

                    return Task.FromResult(retVal);
                });

            return res;
        }
 private static Task Set(
     ServicePartitionClient<WcfCommunicationClient<IKeyValueStore>> client,
     string key,
     long value)
 {
     return client.InvokeWithRetryAsync(_ => _.Channel.Set(key, BitConverter.GetBytes(value)));
 }
Exemple #33
0
        /// <summary>
        /// This is the main entry point for your service replica.
        /// This method executes when this replica of your service becomes primary and has write status.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service replica.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            string eventHubConnectionString = "Event hub compatible endpoint - Azure portal -> IoT Hub -> Build-in endpoints ";

            // These Reliable Dictionaries are used to keep track of our position in IoT Hub.
            // If this service fails over, this will allow it to pick up where it left off in the event stream.
            IReliableDictionary <string, string> offsetDictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <string, string> >(OffsetDictionaryName);

            IReliableDictionary <string, long> epochDictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <string, long> >(EpochDictionaryName);

            // Each partition of this service corresponds to a partition in IoT Hub.
            // IoT Hub partitions are numbered 0..n-1, up to n = 32.
            // This service needs to use an identical partitioning scheme.
            // The low key of every partition corresponds to an IoT Hub partition.
            Int64RangePartitionInformation partitionInfo = (Int64RangePartitionInformation)this.Partition.PartitionInfo;
            long servicePartitionKey = partitionInfo.LowKey;

            PartitionReceiver partitionReceiver = null;

            try
            {
                // Get the partition receiver for reading message from specific consumer group and partition
                // Consumer group is set to $Default
                partitionReceiver = await this.ConnectToIoTHubAsync(consumerGroup : PartitionReceiver.DefaultConsumerGroupName,
                                                                    connectionString : eventHubConnectionString,
                                                                    servicePartitionKey : servicePartitionKey,
                                                                    epochDictionary : epochDictionary,
                                                                    offsetDictionary : offsetDictionary);

                int offsetIteration = 0;

                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    try
                    {
                        // Reading event data list from partition receiver with max message count parameter
                        IEnumerable <EventData> eventDataList = await partitionReceiver.ReceiveAsync(MaxMessageCount);

                        if (eventDataList == null)
                        {
                            continue;
                        }

                        using (var eventData = eventDataList.FirstOrDefault())
                        {
                            string deviceId = (string)eventData.SystemProperties["iothub-connection-device-id"];
                            string data     = Encoding.UTF8.GetString(eventData.Body);
                            ServiceEventSource.Current.ServiceMessage(
                                this.Context,
                                "Reading data from device {0} with data {1}",
                                deviceId,
                                data);

                            var message = new Message(eventData.Body.Array);

                            //TODO: Avoid hardcoded values, place in app settings
                            Uri statelessServiceUri             = new Uri("fabric:/ServiceFabric.IoTSample/IoTSample.CalculationStatelessService");
                            var statelessServiceFactory         = new ServiceBusCommunicationClientFactory(ServicePartitionResolver.GetDefault(), "name of the queue");
                            var statelessServicePartitionClient = new ServicePartitionClient <ServiceBusCommunicationClient>(statelessServiceFactory, statelessServiceUri);
                            await statelessServicePartitionClient.InvokeWithRetryAsync(c => c.SendMessageAsync(message));

                            //TODO: Avoid hardcoded values, place in app settings
                            Uri statefulServiceUri             = new Uri("fabric:/ServiceFabric.IoTSample/IoTSample.ProcessingStatefulService");
                            var statefulServiceFactory         = new ServiceBusCommunicationClientFactory(ServicePartitionResolver.GetDefault(), "name of the queue");
                            var partitionKey                   = new ServicePartitionKey(0L);
                            var statefulServicePartitionClient = new ServicePartitionClient <ServiceBusCommunicationClient>(statefulServiceFactory, statefulServiceUri, partitionKey);
                            await statefulServicePartitionClient.InvokeWithRetryAsync(c => c.SendMessageAsync(message.Clone()));


                            if (++offsetIteration % OffsetInterval == 0)
                            {
                                ServiceEventSource.Current.ServiceMessage(
                                    this.Context,
                                    "Saving offset {0}",
                                    eventData.SystemProperties.Offset);

                                using (ITransaction tx = this.StateManager.CreateTransaction())
                                {
                                    await offsetDictionary.SetAsync(tx, "offset", eventData.SystemProperties.Offset);

                                    await tx.CommitAsync();
                                }

                                offsetIteration = 0;
                            }
                        }
                    }
                    catch (TimeoutException te)
                    {
                        // transient error. Retry.
                        ServiceEventSource.Current.ServiceMessage(this.Context, $"TimeoutException in RunAsync: {te.ToString()}");
                    }
                    catch (FabricTransientException fte)
                    {
                        // transient error. Retry.
                        ServiceEventSource.Current.ServiceMessage(this.Context, $"FabricTransientException in RunAsync: {fte.ToString()}");
                    }
                    catch (FabricNotPrimaryException)
                    {
                        // not primary any more, time to quit.
                        return;
                    }
                    catch (Exception ex)
                    {
                        ServiceEventSource.Current.ServiceMessage(this.Context, ex.ToString());

                        throw;
                    }
                }
            }
            finally
            {
                if (partitionReceiver != null)
                {
                    await partitionReceiver.CloseAsync();
                }
            }
        }
        public async Task SendHealthReportToCountyAsync()
        {
            try
            {
                ConditionalValue <DoctorActorState> doctorStateResult = await this.StateManager.TryGetStateAsync <DoctorActorState>("DoctorActorState");

                if (doctorStateResult.HasValue)
                {
                    DoctorActorState state = doctorStateResult.Value;

                    if (state.PersonHealthStatuses.Count > 0)
                    {
                        DoctorStatsViewModel payload = new DoctorStatsViewModel(
                            state.PersonHealthStatuses.Count,
                            state.HealthReportCount,
                            await this.GetAveragePatientHealthInfoAsync(),
                            state.Name);

                        ServicePartitionKey partitionKey = new ServicePartitionKey(state.CountyInfo.CountyId);
                        Guid id = this.Id.GetGuidId();

                        ServicePartitionClient <HttpCommunicationClient> servicePartitionClient =
                            new ServicePartitionClient <HttpCommunicationClient>(
                                this.clientFactory,
                                this.countyServiceInstanceUri,
                                partitionKey);

                        await servicePartitionClient.InvokeWithRetryAsync(
                            client =>
                        {
                            Uri serviceAddress = new Uri(
                                client.BaseAddress,
                                string.Format(
                                    "county/health/{0}/{1}",
                                    partitionKey.Value.ToString(),
                                    id));

                            HttpWebRequest request   = WebRequest.CreateHttp(serviceAddress);
                            request.Method           = "POST";
                            request.ContentType      = "application/json";
                            request.KeepAlive        = false;
                            request.Timeout          = (int)client.OperationTimeout.TotalMilliseconds;
                            request.ReadWriteTimeout = (int)client.ReadWriteTimeout.TotalMilliseconds;

                            using (Stream requestStream = request.GetRequestStream())
                            {
                                using (BufferedStream buffer = new BufferedStream(requestStream))
                                {
                                    using (StreamWriter writer = new StreamWriter(buffer))
                                    {
                                        JsonSerializer serializer = new JsonSerializer();
                                        serializer.Serialize(writer, payload);
                                        buffer.Flush();
                                    }

                                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                                    {
                                        ActorEventSource.Current.Message("Doctor Sent Data to County: {0}", serviceAddress);
                                        return(Task.FromResult(true));
                                    }
                                }
                            }
                        }
                            );
                    }
                }
            }
            catch (Exception e)
            {
                ActorEventSource.Current.Message("DoctorActor failed to send health report to county service Outer Exception: {0}", e.ToString());
            }
        }
        private ServicePartitionClient<HttpCommunicationClient> CreateServicePartitionClient(HttpContext context)
        {
            // these different calls are required because every constructor sets different variables internally.

            var servicePartitionClient = new ServicePartitionClient<HttpCommunicationClient>(
                communicationClientFactory: _httpCommunicationClientFactory,
                serviceUri: _gatewayOptions.ServiceName,
                partitionKey: _gatewayOptions.ServicePartitionKeyResolver?.Invoke(context),
                listenerName: _gatewayOptions.ListenerName);

            return servicePartitionClient;
        }
Exemple #36
0
 private static Task Set(ServicePartitionClient <WcfCommunicationClient <ITableStoreService> > client, string key, long value)
 {
     return(client.InvokeWithRetryAsync(_ => _.Channel.Insert(key, null, BitConverter.GetBytes(value))));
 }
 public CachePartitionClient(ServicePartitionClient <CacheCommunicationClient> client)
 {
     _partitionClient = client;
 }
		private static void SendTestMessageToQueue(Uri uri, string queueName, bool serviceSupportsPartitions)
		{
			//the name of your application and the name of the Service, the default partition resolver and the topic name
			//to create a communication client factory:
			var factory = new ServiceBusQueueCommunicationClientFactory(ServicePartitionResolver.GetDefault(), queueName);

			ServicePartitionClient<ServiceBusQueueCommunicationClient> servicePartitionClient;

			if (serviceSupportsPartitions)
			{
				//determine the partition and create a communication proxy
				long partitionKey = 0L;
				servicePartitionClient = new ServicePartitionClient<ServiceBusQueueCommunicationClient>(factory, uri, partitionKey);
			}
			else
			{
				servicePartitionClient = new ServicePartitionClient<ServiceBusQueueCommunicationClient>(factory, uri);
			}

			//use the proxy to send a message to the Service
			servicePartitionClient.InvokeWithRetry(c => c.SendMessage(CreateMessage()));

			Console.WriteLine("Message sent to queue");
		}
        private static async Task Run(string[] args)
        {
            // The Fabric URI of the service.
            var serviceName = new Uri("fabric:/DistributedJournalApp/DistributedJournalService");
            var serviceResolver = new ServicePartitionResolver(() => new FabricClient());

            var clientFactory = new WcfCommunicationClientFactory<IKeyValueStore>(
                serviceResolver,
                ServiceBindings.TcpBinding);

            var client = new ServicePartitionClient<WcfCommunicationClient<IKeyValueStore>>(
                clientFactory,
                serviceName,
                partitionKey: 0L);

            Console.WriteLine("Calling set");
            await Set(client, "test", 38);
            Console.WriteLine("Set complete, calling get");
            Console.WriteLine($"Got {await Get(client, "test")}");

            var numTasks = args.Length == 0 ? 1 : int.Parse(args[0]);
            var tasks = new Task[numTasks];
            var iteration = (long)0;

            // Initialize.
            for (var i = 0; i < tasks.Length; ++i)
            {
                await Set(client, i.ToString(), iteration);
            }

            var timer = Stopwatch.StartNew();
            var paused = false;
            while (true)
            {
                var total = iteration * tasks.Length;
                if (!paused)
                {
                    for (var i = 0; i < tasks.Length; ++i)
                    {
                        tasks[i] = CheckAndIncrement(client, i.ToString(), iteration);
                    }

                    await Task.WhenAll(tasks);

                    if (iteration % 8000 == 0 && iteration > 0)
                    {
                        Console.WriteLine();
                    }

                    if (iteration % 100 == 0)
                    {
                        WriteProgress(iteration, timer, total);
                    }
                    
                    iteration++;
                }

                // Process user input.
                if (Console.KeyAvailable || paused)
                {
                    var consoleKey = Console.ReadKey();
                    switch (consoleKey.Key)
                    {
                        case ConsoleKey.Escape:
                            return;
                        case ConsoleKey.D:
                            // Output debug data.
                            var prefix = $"{iteration}_";
                            await client.InvokeWithRetry(_ => _.Channel.DumpDebugData(DebugDumpDirectory, prefix));
                            break;
                        case ConsoleKey.P:
                            // Toggle pause
                            paused = !paused;
                            break;
                        case ConsoleKey.S:
                            WriteProgress(iteration, timer, total);
                            break;

                    }
                }
            }
        }
        private static async Task CheckAndIncrement(
            ServicePartitionClient<WcfCommunicationClient<IKeyValueStore>> client,
            string key,
            long expected)
        {
            var serialized = await client.InvokeWithRetryAsync(_ => _.Channel.Get(key));
            var value = BitConverter.ToInt64(serialized, 0);

            if (value != expected)
            {
                throw new Exception($"[{DateTime.Now}] Expected {expected} but encountered {value}.");
            }

            await client.InvokeWithRetryAsync(_ => _.Channel.Set(key, BitConverter.GetBytes(value + 1)));
        }
        private static async Task Run(string[] args)
        {
            // The Fabric URI of the service.
            var serviceName     = new Uri("fabric:/DistributedJournalApp/DistributedJournalService");
            var serviceResolver = new ServicePartitionResolver(() => new FabricClient());

            var clientFactory = new WcfCommunicationClientFactory <IKeyValueStore>(
                serviceResolver,
                ServiceBindings.TcpBinding);

            var client = new ServicePartitionClient <WcfCommunicationClient <IKeyValueStore> >(
                clientFactory,
                serviceName,
                partitionKey: 0L);

            Console.WriteLine("Calling set");
            await Set(client, "test", 38);

            Console.WriteLine("Set complete, calling get");
            Console.WriteLine($"Got {await Get(client, "test")}");

            var numTasks  = args.Length == 0 ? 1 : int.Parse(args[0]);
            var tasks     = new Task[numTasks];
            var iteration = (long)0;

            // Initialize.
            for (var i = 0; i < tasks.Length; ++i)
            {
                await Set(client, i.ToString(), iteration);
            }

            var timer  = Stopwatch.StartNew();
            var paused = false;

            while (true)
            {
                var total = iteration * tasks.Length;
                if (!paused)
                {
                    for (var i = 0; i < tasks.Length; ++i)
                    {
                        tasks[i] = CheckAndIncrement(client, i.ToString(), iteration);
                    }

                    await Task.WhenAll(tasks);

                    if (iteration % 8000 == 0 && iteration > 0)
                    {
                        Console.WriteLine();
                    }

                    if (iteration % 100 == 0)
                    {
                        WriteProgress(iteration, timer, total);
                    }

                    iteration++;
                }

                // Process user input.
                if (Console.KeyAvailable || paused)
                {
                    var consoleKey = Console.ReadKey();
                    switch (consoleKey.Key)
                    {
                    case ConsoleKey.Escape:
                        return;

                    case ConsoleKey.D:
                        // Output debug data.
                        var prefix = $"{iteration}_";
                        await client.InvokeWithRetry(_ => _.Channel.DumpDebugData(DebugDumpDirectory, prefix));

                        break;

                    case ConsoleKey.P:
                        // Toggle pause
                        paused = !paused;
                        break;

                    case ConsoleKey.S:
                        WriteProgress(iteration, timer, total);
                        break;
                    }
                }
            }
        }
        public async Task<HttpResponseMessage> AddWord(string word)
        {
            // Determine the partition key that should handle the request
            long partitionKey = GetPartitionKey(word);

            // Use service partition client to resolve the service and partition key.
            // This determines the endpoint of the replica that should handle the request.
            // Internally, the service partition client handles exceptions and retries appropriately.
            ServicePartitionClient<CommunicationClient> servicePartitionClient = new ServicePartitionClient<CommunicationClient>(
                clientFactory,
                new Uri(WordCountServiceName),
                partitionKey);

            return await servicePartitionClient.InvokeWithRetryAsync(
                client =>
                {
                    Uri serviceAddress = new Uri(client.BaseAddress, string.Format("AddWord/{0}", word));

                    HttpWebRequest request = WebRequest.CreateHttp(serviceAddress);
                    request.Method = "PUT";
                    request.ContentLength = 0;
                    request.Timeout = (int) client.OperationTimeout.TotalMilliseconds;
                    request.ReadWriteTimeout = (int) client.ReadWriteTimeout.TotalMilliseconds;

                    using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
                    {
                        HttpResponseMessage message = new HttpResponseMessage();
                        message.Content = new StringContent(
                            String.Format("<h1>{0}</h1> added to partition <h2>{1}</h2> at {2}", word, client.ResolvedServicePartition.Info.Id, serviceAddress),
                            Encoding.UTF8,
                            "text/html");
                        return Task.FromResult<HttpResponseMessage>(message);
                    }
                });
        }
Exemple #43
0
        private async Task <HttpResponseMessage> RedirectRequest(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request.RequestUri.Segments.Length < 3)
            {
                return(new HttpResponseMessage(HttpStatusCode.BadRequest));
            }

            // resolve http(s)://<Cluster FQDN | internal IP>:Port/<ServiceInstanceName>/<Suffix path>?PartitionKey=<key>&PartitionKind=<partitionkind>&Timeout=<timeout_in_seconds>
            string servicePath;
            string suffixPath;

            ProxyHandlerHelper.BuildFabricPath(request.RequestUri, out servicePath, out suffixPath);

            // parse query string
            var queryCollection = request.RequestUri.ParseQueryString();

            string query = ProxyHandlerHelper.BuildQuery(queryCollection);

            string partitionKind;

            if (!ProxyHandlerHelper.TryGetQueryValue(queryCollection, ProxyHandlerHelper.QueryKey.PartitionKind, out partitionKind))
            {
                partitionKind = null;
            }

            string partitionKey;

            if (!ProxyHandlerHelper.TryGetQueryValue(queryCollection, ProxyHandlerHelper.QueryKey.PartitionKey, out partitionKey))
            {
                partitionKey = null;
            }

            int timeout;

            if (!ProxyHandlerHelper.TryGetQueryValue(queryCollection, ProxyHandlerHelper.QueryKey.Timeout, out timeout))
            {
                timeout = 60;
            }

            // Get partition key
            ServicePartitionKey servicePartitionKey = null;

            if (partitionKind != null && partitionKey != null)
            {
                servicePartitionKey = ProxyHandlerHelper.GetServicePartitionKey(partitionKind, partitionKey);
            }

            // Setup cancellation tokens
            var cts = new CancellationTokenSource();

            cts.CancelAfter(TimeSpan.FromSeconds(timeout));

            var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cts.Token);

            SplitTesting.ServiceExtensions.TryGetValue(servicePath, out ProxyItem proxy);
            servicePath += proxy?.Extension;

            try
            {
                var partitionClient = new ServicePartitionClient <HttpCommunicationClient>(communicationFactory, new Uri(servicePath), servicePartitionKey);

                return(await partitionClient.InvokeWithRetryAsync(async (client) =>
                {
                    var clonedRequest = await HttpRequestMessageExtensions.CloneHttpRequestMessageAsync(request);
                    clonedRequest.RequestUri = new Uri(client.Url, suffixPath + query);

                    var upstreamResponse = await client.HttpClient.SendAsync(clonedRequest, HttpCompletionOption.ResponseHeadersRead, linkedCts.Token);

                    IEnumerable <string> serviceFabricHeader;
                    if (upstreamResponse.StatusCode == HttpStatusCode.NotFound &&
                        (!upstreamResponse.Headers.TryGetValues("X-ServiceFabric", out serviceFabricHeader) || !serviceFabricHeader.Contains("ResourceNotFound")))
                    {
                        throw new FabricServiceNotFoundException();
                    }

                    return upstreamResponse;
                }, linkedCts.Token));
            }
            catch (FabricServiceNotFoundException)
            {
                var response = new HttpResponseMessage(HttpStatusCode.NotFound);
                response.AddServiceFabricHeader();

                return(response);
            }
            catch (TaskCanceledException)
            {
                return(new HttpResponseMessage(HttpStatusCode.GatewayTimeout));
            }
            catch (Exception)
            {
                return(new HttpResponseMessage(HttpStatusCode.InternalServerError));
            }
        }
Exemple #44
0
        private static async Task <long> Get(ServicePartitionClient <WcfCommunicationClient <ITableStoreService> > client, string key)
        {
            var value = await client.InvokeWithRetryAsync(_ => _.Channel.Get(key, null));

            return(BitConverter.ToInt64(value, 0));
        }
        public async Task<HttpResponseMessage> AddWord(string word)
        {
            // Determine the partition key that should handle the request
            long partitionKey = GetPartitionKey(word);

            ServicePartitionClient<HttpCommunicationClient> partitionClient
                = new ServicePartitionClient<HttpCommunicationClient>(communicationFactory, serviceUri, new ServicePartitionKey(partitionKey));

            await
                partitionClient.InvokeWithRetryAsync(
                    async (client) => { await client.HttpClient.PutAsync(new Uri(client.Url, "AddWord/" + word), new StringContent(String.Empty)); });

            return new HttpResponseMessage()
            {
                Content = new StringContent(
                    String.Format("<h1>{0}</h1> added to partition with key <h2>{1}</h2>", word, partitionKey),
                    Encoding.UTF8,
                    "text/html")
            };
        }
Exemple #46
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            ConfigurationPackage configPackage = this.Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");

            this.UpdateConfigSettings(configPackage.Settings);

            this.Context.CodePackageActivationContext.ConfigurationPackageModifiedEvent
                += this.CodePackageActivationContext_ConfigurationPackageModifiedEvent;

            this.indexCalculator = new HealthIndexCalculator(this.Context);

            ServicePrimer primer = new ServicePrimer();
            await primer.WaitForStatefulService(this.nationalServiceInstanceUri);

            IReliableDictionary <int, string> countyNamesDictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <int, string> >(CountyNameDictionaryName);

            ServiceEventSource.Current.ServiceMessage(this, "CountyService starting data processing.");
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    //every ten seconds, grab the counties and send them to national
                    await Task.Delay(this.interval, cancellationToken);

                    ServicePartitionClient <HttpCommunicationClient> servicePartitionClient =
                        new ServicePartitionClient <HttpCommunicationClient>(
                            this.clientFactory,
                            this.nationalServiceInstanceUri);

                    IList <KeyValuePair <int, string> > countyNames = new List <KeyValuePair <int, string> >();

                    using (ITransaction tx = this.StateManager.CreateTransaction())
                    {
                        IAsyncEnumerator <KeyValuePair <int, string> > enumerator = (await countyNamesDictionary.CreateEnumerableAsync(tx)).GetAsyncEnumerator();

                        while (await enumerator.MoveNextAsync(cancellationToken))
                        {
                            countyNames.Add(enumerator.Current);
                        }
                    }

                    foreach (KeyValuePair <int, string> county in countyNames)
                    {
                        IReliableDictionary <Guid, CountyDoctorStats> countyHealth =
                            await
                            this.StateManager.GetOrAddAsync <IReliableDictionary <Guid, CountyDoctorStats> >(
                                string.Format(CountyHealthDictionaryName, county.Key));

                        int totalDoctorCount       = 0;
                        int totalPatientCount      = 0;
                        int totalHealthReportCount = 0;
                        int avgHealth = 0;

                        using (ITransaction tx = this.StateManager.CreateTransaction())
                        {
                            IAsyncEnumerable <KeyValuePair <Guid, CountyDoctorStats> > healthRecords = await countyHealth.CreateEnumerableAsync(tx);

                            IAsyncEnumerator <KeyValuePair <Guid, CountyDoctorStats> > enumerator = healthRecords.GetAsyncEnumerator();

                            IList <KeyValuePair <Guid, CountyDoctorStats> > records = new List <KeyValuePair <Guid, CountyDoctorStats> >();

                            while (await enumerator.MoveNextAsync(cancellationToken))
                            {
                                records.Add(enumerator.Current);
                            }

                            avgHealth = this.indexCalculator.ComputeAverageIndex(records.Select(x => x.Value.AverageHealthIndex));

                            foreach (KeyValuePair <Guid, CountyDoctorStats> item in records)
                            {
                                totalDoctorCount++;
                                totalPatientCount      += item.Value.PatientCount;
                                totalHealthReportCount += item.Value.HealthReportCount;
                            }
                        }

                        CountyStatsViewModel payload = new CountyStatsViewModel(totalDoctorCount, totalPatientCount, totalHealthReportCount, avgHealth);

                        await servicePartitionClient.InvokeWithRetryAsync(
                            client =>
                        {
                            Uri serviceAddress = new Uri(client.BaseAddress, string.Format("national/health/{0}", county.Key));

                            HttpWebRequest request   = WebRequest.CreateHttp(serviceAddress);
                            request.Method           = "POST";
                            request.ContentType      = "application/json";
                            request.Timeout          = (int)client.OperationTimeout.TotalMilliseconds;
                            request.ReadWriteTimeout = (int)client.ReadWriteTimeout.TotalMilliseconds;

                            using (Stream requestStream = request.GetRequestStream())
                            {
                                using (BufferedStream buffer = new BufferedStream(requestStream))
                                {
                                    using (StreamWriter writer = new StreamWriter(buffer))
                                    {
                                        JsonSerializer serializer = new JsonSerializer();
                                        serializer.Serialize(writer, payload);
                                        buffer.Flush();
                                    }

                                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                                    {
                                        ServiceEventSource.Current.ServiceMessage(this, "County Data Sent {0}", serviceAddress);
                                        return(Task.FromResult(true));
                                    }
                                }
                            }
                        },
                            cancellationToken);
                    }
                }
                catch (TaskCanceledException)
                {
                    throw;
                }
                catch (Exception exception)
                {
                    ServiceEventSource.Current.ServiceMessage(
                        this,
                        "CountyService encountered an exception trying to send data to National Service: {0}",
                        exception.ToString());
                    continue;
                }
            }
        }
            static async Task doStuffUsingICommInterfaces(ServicePartitionClient<WcfMultiPointCommunicationClient> partitionClient)
        {

            // the client needs those to know which interface is wired to wich host. 

            var PointDef = new PointDefinition()
            {
                HostTitle = "host1",
                Binding = new NetTcpBinding(),    
                Interfaces = new List<Type>() { typeof(SvcInterface1), typeof(SvcInterface2) }
            };


          
            var defs = new PointDefinition[1] { PointDef }; ;
        
            await partitionClient.InvokeWithRetryAsync(client => {

                if (client.ConnectionStatus == ClientConnectionStatus.NotConnected)
                    client.PointDefinition = defs;



                foreach (var def in defs) // hosts
                {
                    Console.WriteLine(string.Format("working on {0} host", def.HostTitle));
                    string result = string.Empty;
                    // our listner has wired the same 2 interfaces per host


                    var Channel1= client.GetChannel<SvcInterface1>(def,  typeof(SvcInterface1));
                    
                    result = Channel1.SvcInterface1Op1(parameter);
                    Console.WriteLine(string.Format("opeartion {0} on interface {1} called with {2} returned {3}", "SvcInterface1Op1", "SvcInterface1", parameter, result));


                    result = Channel1.SvcInterface1Op2(parameter);
                    Console.WriteLine(string.Format("opeartion {0} on interface {1} called with {2} returned {3}", "SvcInterface1Op2", "SvcInterface1", parameter, result));

                    var Channel2 = client.GetChannel<SvcInterface2>(def, typeof(SvcInterface2));


                    result = Channel2.SvcInterface2Op1(parameter);
                    Console.WriteLine(string.Format("opeartion {0} on interface {1} called with {2} returned {3}", "SvcInterface2Op1", "SvcInterface2", parameter, result));

                    result = Channel2.SvcInterface2Op2(parameter);
                    Console.WriteLine(string.Format("opeartion {0} on interface {1} called with {2} returned {3}", "SimSessionOp2", "SvcInterface2Op2", parameter, result));


                }
                return Task.Delay(0);
            });
            
        }