public BusinessDataPump(
     IDistributedSearchConfiguration demoCredential,
     Func <TBusinessData> createEmptyBusinessData,
     Func <TBusinessData, TBusinessDataUpdate, TBusinessData> applyUpdate,
     BlobContainerClient snapshotContainerClient)
 {
     this.applyUpdate             = applyUpdate;
     this.createEmptyBusinessData = createEmptyBusinessData;
     this.updateMessagingClient   =
         MessagingClients.Updates <TBusinessDataUpdate>(demoCredential: demoCredential);
     this.snapshotContainerClient = snapshotContainerClient;
 }
        private IObservable <RequestResponseMessage <ProviderSearchResponse <T> > > CreateProviderResponsePump <T>(TopicAndPartition topicAndPartition)
        {
            var messagingClient = MessagingClients
                                  .Responses <ProviderSearchResponse <T> >(
                demoCredential: this.demoCredential,
                topicAndPartition: topicAndPartition);

            var connectable = messagingClient
                              .CreateObervable()
                              .Publish();

            connectable.Connect();

            return(connectable.AsObservable());
        }
        private static async Task Main()
        {
            Console.Title = "Sample Provider";

            IDistributedSearchConfiguration demoCredential = new DemoCredential();

            var requestsClient = MessagingClients.Requests <ProviderSearchRequest <FashionSearchRequest> >(demoCredential);

            var cts = new CancellationTokenSource();

            var clients = new Dictionary <TopicAndPartition, IRequestResponseMessageClient <ProviderSearchResponse <FashionItem> > >();

            IRequestResponseMessageClient <ProviderSearchResponse <FashionItem> > getMessageClient(TopicAndPartition tpid)
            {
                lock (clients)
                {
                    if (!clients.ContainsKey(tpid))
                    {
                        var client = MessagingClients.Responses <ProviderSearchResponse <FashionItem> >(
                            demoCredential: demoCredential, topicAndPartition: tpid);

                        clients.Add(tpid, client);
                    }
                }
                return(clients[tpid]);
            }

            requestsClient
            .CreateObervable(cts.Token)
            .Subscribe(
                onNext: async providerSearchRequestMessage =>
            {
                var search    = providerSearchRequestMessage.Payload;
                var requestId = providerSearchRequestMessage.RequestID;

                var responseProducer = getMessageClient(search.ResponseTopic);

                // await Console.Out.WriteLineAsync($"{requestId}: Somebody's looking for {search.SearchRequest.FashionType}");

                var tcs = new TaskCompletionSource <bool>();

                GetResponses()
                .Select(foundFashionItem => new ProviderSearchResponse <FashionItem>(
                            requestID: requestId,
                            response: ListModule.OfArray(new[] { foundFashionItem })))
                .Subscribe(
                    onNext: async(responsePayload) =>
                {
                    await responseProducer.SendRequestResponseMessage(
                        messagePayload: responsePayload,
                        requestId: requestId,
                        cancellationToken: cts.Token);

                    // await Console.Out.WriteLineAsync($"{requestId}: Sending {responsePayload.Response.Head.Description}");
                },
                    onError: ex =>
                {
                    Console.Error.WriteLine($"Error with request {requestId}: {ex.Message}");
                },
                    onCompleted: async() =>
                {
                    await Console.Out.WriteLineAsync($"Finished with request {requestId}");
                    tcs.SetResult(true);
                },
                    token: cts.Token);

                _ = await tcs.Task;         // only leave on onCompleted
            },
                onError: ex => Console.Error.WriteLine($"Error with EventHub: {ex.Message}"),
                onCompleted: () => Console.WriteLine($"Finished with EventHub"),
                token: cts.Token);

            await Console.In.ReadLineAsync();

            cts.Cancel();
        }
        /// <summary>
        /// A function which can asyncronously send out a provider search request.
        /// </summary>
        /// <returns>Returns a function which can asyncronously send out a provider search request.</returns>
        private Func <ProviderSearchRequest <FashionSearchRequest>, Task> SendProviderSearchRequest()
        {
            var requestProducer = MessagingClients.Requests <ProviderSearchRequest <FashionSearchRequest> >(this.demoCredential);

            return(searchRequest => requestProducer.SendRequestResponseMessage(searchRequest, requestId: searchRequest.RequestID));
        }