Esempio n. 1
0
        public Task <IResponseMessage <IResponseData> > SendRequest(PluginClient whoRequested, int id, IRequestMessage <IRequestData> request)
        {
            var pendingRequest = new PendingRequest(id, request, whoRequested);

            _pendingRequests.Update(l => l.Add(pendingRequest));
            _outStream.OnNext(request.ChangeId(id));
            return(pendingRequest.Task);
        }
Esempio n. 2
0
        public void PassRequestToAnImplementor(PluginClient whoRequested, IRequestMessage <IRequestData> request)
        {
            var clientsThatImplementsRequest = _clients.Values.Where(c => c.IsImlementorOf(request.Name));

            foreach (var client in clientsThatImplementsRequest)
            {
                var responseTask = client.SendRequest(whoRequested, Interlocked.Increment(ref _currentGlobalRequestId), request);
                if (!responseTask.Wait(TimeSpan.FromMinutes(1)))
                {
                    continue;
                }

                var response = responseTask.Result;
                if (response.Status == Status.Unhandled)
                {
                    continue;
                }

                whoRequested.SendResponse(response.ChangeId(request.Id));
                return;
            }

            whoRequested.SendResponse(Response.CreateUnhandled(request, new Error(ErrorCode.InvalidRequest, "Did not find an implementor for " + request.Name), (UnresolvedMessagePayload)null));
        }
Esempio n. 3
0
 public PendingRequest(int id, IRequestMessage <IRequestData> request, PluginClient whoRequested)
 {
     Id           = id;
     Request      = request;
     WhoRequested = whoRequested;
 }
Esempio n. 4
0
        void HandleHello(
            HelloRequest helloReq,
            IMessageConnection c,
            ConcurrentStack <IDisposable> disposables,
            RequestReceiver requestReceiver,
            IObservable <IMessage> messagesIn,
            IObserver <IMessage> messagesOut)
        {
            if (helloReq == null)
            {
                throw new FuseRequestErrorException(ErrorCode.InvalidData, "Expected data to not be empty.");
            }

            // TODO: Enforce daemonkey to be present in the future
            if (!string.IsNullOrWhiteSpace(helloReq.DaemonKey) &&
                DaemonKey.Deserialize(helloReq.DaemonKey) != _daemonKey)
            {
                throw new FuseRequestErrorException(
                          ErrorCode.WrongDaemonKey,
                          "Daemon key was not right, maybe because daemon possesses wrong local user.");
            }

#pragma warning disable 0618
            var pluginClient = new PluginClient(
                messagesOut,
                helloReq.Identifier,
                helloReq.Implements,
                helloReq.EventFilter);
#pragma warning restore 0618

            _pluginClients.Add(c, pluginClient);

            _report.Info("Client connected: " + helloReq.Identifier, ReportTo.LogAndUser);
            c.Disconnected.Subscribe(d => _report.Info("Client disconnected: " + helloReq.Identifier, ReportTo.LogAndUser));

            // Broadcast events to clients that wants the events.
            disposables.Push(messagesIn.OfType <IEventMessage <IEventData> >().Subscribe(_broadcastEvents.OnNext));
            disposables.Push(_broadcastEvents
                             .Subscribe(pluginClient.HandleEvent));

            // Handle Subscribe to event request.
            disposables.Push(
                messagesIn
                .OfType <IRequestMessage <UnresolvedMessagePayload> >()
                .Deserialize <SubscribeRequest>(_report)
                .Subscribe(
                    r => disposables.Push(
                        pluginClient.SubscribeToEvent(
                            r,
                            hotMessages: _broadcastEvents,
                            replayMessages: _replayBroadcastEvents))
                    ));

            disposables.Push(
                requestReceiver.SubscribeToRequest <PublishServiceRequest, PublishServiceResponse>(pluginClient.AppendSupportedRequests));

            // Send requests to clients that implements the request.
            disposables.Push(
                messagesIn.OfType <IRequestMessage <IRequestData> >()
                .Where(r => r.Name != "Subscribe" && r.Name != "Fuse.KillDaemon" && r.Name != "PublishService")
                .Subscribe(r => Task.Run(() => _pluginClients.PassRequestToAnImplementor(pluginClient, r))));

            // Handle the response from the one that implemented the request
            disposables.Push(
                messagesIn.OfType <IResponseMessage <IResponseData> >().Subscribe(pluginClient.HandleResponse));
        }
Esempio n. 5
0
 public void Add(IMessageConnection socket, PluginClient client)
 {
     _clients.TryAdd(socket, client);
 }