Beispiel #1
0
        public Message(string requestId, MessageType type, MessageMethod method, JObject payload = null)
        {
            if (string.IsNullOrEmpty(requestId))
            {
                throw new ArgumentException(Strings.ArgumentCannotBeNullOrEmpty, nameof(requestId));
            }

            if (!Enum.IsDefined(typeof(MessageType), type))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.Plugin_UnrecognizedEnumValue,
                              type),
                          nameof(type));
            }

            if (!Enum.IsDefined(typeof(MessageMethod), method))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.Plugin_UnrecognizedEnumValue,
                              method),
                          nameof(method));
            }

            RequestId = requestId;
            Type      = type;
            Method    = method;
            Payload   = payload;
        }
Beispiel #2
0
        private async Task <TIncoming> DispatchWithNewContextAsync <TOutgoing, TIncoming>(
            IConnection connection,
            MessageType type,
            MessageMethod method,
            TOutgoing payload,
            CancellationToken cancellationToken)
            where TOutgoing : class
            where TIncoming : class
        {
            var message        = CreateMessage(type, method, payload);
            var timeout        = GetRequestTimeout(connection, type, method);
            var isKeepAlive    = GetIsKeepAlive(connection, type, method);
            var requestContext = CreateOutboundRequestContext <TIncoming>(
                message,
                timeout,
                isKeepAlive,
                cancellationToken);

            _outboundRequestContexts.TryAdd(message.RequestId, requestContext);

            switch (type)
            {
            case MessageType.Request:
            case MessageType.Response:
            case MessageType.Fault:
                var removeRequestContext = true;

                try
                {
                    await connection.SendAsync(message, requestContext.CancellationToken);

                    return(await requestContext.CompletionTask);
                }
                catch (OperationCanceledException) when(requestContext.CancellationToken.IsCancellationRequested)
                {
                    // Keep the request context around if cancellation was requested.
                    // A race condition exists where after sending a cancellation request,
                    // we could receive a response (which was in flight) or a cancellation
                    // response.
                    // If a normal response (success/failure) and not a cancellation response
                    // is received after a cancellation request, we need to have an active
                    // request context to avoid a protocol exception.
                    removeRequestContext = false;

                    throw;
                }
                finally
                {
                    if (removeRequestContext)
                    {
                        RemoveOutboundRequestContext(message.RequestId);
                    }
                }

            default:
                break;
            }

            return(null);
        }
Beispiel #3
0
        public void ToString_ReturnsJson()
        {
            const string        requestId = "a";
            const MessageMethod method    = MessageMethod.GetOperationClaims;
            const MessageType   type      = MessageType.Request;
            const TaskState     state     = TaskState.Executing;

            var now = DateTimeOffset.UtcNow;

            var logMessage = new TaskLogMessage(now, requestId, method, type, state);

            var message = VerifyOuterMessageAndReturnInnerMessage(logMessage, now, "task");

            Assert.Equal(5, message.Count);

            var actualRequestId     = message.Value <string>("request ID");
            var actualMethod        = Enum.Parse(typeof(MessageMethod), message.Value <string>("method"));
            var actualType          = Enum.Parse(typeof(MessageType), message.Value <string>("type"));
            var actualState         = Enum.Parse(typeof(TaskState), message.Value <string>("state"));
            var actualCurrentTaskId = message.Value <int>("current task ID");

            Assert.Equal(requestId, actualRequestId);
            Assert.Equal(method, actualMethod);
            Assert.Equal(type, actualType);
            Assert.Equal(state, actualState);
            Assert.Equal(Task.CurrentId, actualCurrentTaskId);
        }
        public void ToString_ReturnsJson()
        {
            const string        requestId = "a";
            const MessageMethod method    = MessageMethod.GetOperationClaims;
            const MessageType   type      = MessageType.Request;
            const MessageState  state     = MessageState.Sent;

            var now = DateTimeOffset.UtcNow;

            var logMessage = new CommunicationLogMessage(now, requestId, method, type, state);

            var message = VerifyOuterMessageAndReturnInnerMessage(logMessage, now, "communication");

            Assert.Equal(4, message.Count);

            var actualRequestId = message.Value <string>("request ID");
            var actualMethod    = Enum.Parse(typeof(MessageMethod), message.Value <string>("method"));
            var actualType      = Enum.Parse(typeof(MessageType), message.Value <string>("type"));
            var actualState     = Enum.Parse(typeof(MessageState), message.Value <string>("state"));

            Assert.Equal(requestId, actualRequestId);
            Assert.Equal(method, actualMethod);
            Assert.Equal(type, actualType);
            Assert.Equal(state, actualState);
        }
 internal CommunicationLogMessage(DateTimeOffset now, string requestId, MessageMethod method, MessageType type, MessageState state)
     : base(now)
 {
     _requestId = requestId;
     _method    = method;
     _type      = type;
     _state     = state;
 }
        private static bool GetIsKeepAlive(IConnection connection, MessageType type, MessageMethod method)
        {
            if (type == MessageType.Request && method == MessageMethod.Handshake)
            {
                return(false);
            }

            return(true);
        }
 internal TaskLogMessage(DateTimeOffset now, string requestId, MessageMethod method, MessageType type, TaskState state)
     : base(now)
 {
     _requestId     = requestId;
     _method        = method;
     _type          = type;
     _state         = state;
     _currentTaskId = Task.CurrentId;
 }
Beispiel #8
0
        /// <summary>
        /// Attempts to add a request handler for the specified message method.
        /// </summary>
        /// <param name="method">A message method.</param>
        /// <param name="handler">A request handler.</param>
        /// <returns><c>true</c> if added; otherwise, <c>false</c>.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="handler" /> is <c>null</c>.</exception>
        public bool TryAdd(MessageMethod method, IRequestHandler handler)
        {
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }

            return(_handlers.TryAdd(method, handler));
        }
 private Task <T> CreateMessageAndListen <T>(
     MessageMethod method,
     ChaincodeMessage.Types.Type type,
     IMessage payload,
     string channelId,
     string txId
     )
 {
     return(AskPeerAndListen <T>(CreateMessage(type, payload, channelId, txId), method));
 }
        private Task <T> AskPeerAndListen <T>(ChaincodeMessage message, MessageMethod method)
        {
            var taskCompletionSource = new TaskCompletionSource <T>();

            var queueMessage = new QueueMessage <T>(message, method, taskCompletionSource);

            _messageQueue.QueueMessage(queueMessage);

            return(taskCompletionSource.Task);
        }
        /// <summary>
        /// Creates a message.
        /// </summary>
        /// <typeparam name="TPayload">The message payload.</typeparam>
        /// <param name="type">The message type.</param>
        /// <param name="method">The message method.</param>
        /// <param name="payload">The message payload.</param>
        /// <returns>A message.</returns>
        /// <exception cref="ArgumentNullException">Throws if <paramref name="payload" /> is <c>null</c>.</exception>
        public Message CreateMessage <TPayload>(MessageType type, MessageMethod method, TPayload payload)
            where TPayload : class
        {
            if (payload == null)
            {
                throw new ArgumentNullException(nameof(payload));
            }

            var requestId = _idGenerator.GenerateUniqueId();

            return(MessageUtilities.Create(requestId, type, method, payload));
        }
Beispiel #12
0
        /// <summary>
        /// Instantiates a new <see cref="Message" /> class.
        /// </summary>
        /// <param name="requestId">The message request ID.</param>
        /// <param name="type">The message type.</param>
        /// <param name="method">The message method.</param>
        /// <returns>a <see cref="Message" /> instance.</returns>
        /// <exception cref="ArgumentException">Thrown if <paramref name="requestId" />
        /// is either <c>null</c> or an empty string.</exception>
        public static Message Create(
            string requestId,
            MessageType type,
            MessageMethod method)
        {
            if (string.IsNullOrEmpty(requestId))
            {
                throw new ArgumentException(Strings.ArgumentCannotBeNullOrEmpty, nameof(requestId));
            }

            return(new Message(requestId, type, method));
        }
        private IRequestHandler GetInboundRequestHandler(MessageMethod method)
        {
            IRequestHandler handler;

            if (!RequestHandlers.TryGet(method, out handler))
            {
                throw new ProtocolException(
                          string.Format(CultureInfo.CurrentCulture, Strings.Plugin_RequestHandlerDoesNotExist, method));
            }

            return(handler);
        }
Beispiel #14
0
 /// <summary>
 /// Methods that are in the fast processing method list will be handled on a separate thread. Everything else will be queued on the threadpool.
 /// </summary>
 /// <param name="messageMethod"></param>
 /// <param name="task"></param>
 /// <param name="cancellationToken"></param>
 internal void Handle(MessageMethod messageMethod, Func <Task> task, CancellationToken cancellationToken)
 {
     ThrowIfDisposed();
     if (_fastProccessingMethods.Contains(messageMethod))
     {
         _processingThread.Value.Enqueue(task);
     }
     else
     {
         Task.Run(task, cancellationToken);
     }
 }
Beispiel #15
0
        public string Send2(SendType type, string url = "")
        {
            switch (type)
            {
            case SendType.Get:
                return(MessageMethod.doGetRequest(GetFullURL2(url)));   //GetFullURL2拼成了get方式的发送短信的请求

            case SendType.Post:
                return(MessageMethod.doPostRequest(GetURL(), GetData()));

            default:
                return(string.Empty);
            }
        }
Beispiel #16
0
        public string Send(SendType type)
        {
            switch (type)
            {
            case SendType.Get:
                return(MessageMethod.doGetRequest(GetFullURL()));

            case SendType.Post:
                return(MessageMethod.doPostRequest(GetURL(), GetData()));

            default:
                return(string.Empty);
            }
        }
Beispiel #17
0
        internal Task SendAsync <TPayload>(MessageType type, MessageMethod method, TPayload payload)
            where TPayload : class
        {
            var response = new Response()
            {
                Type    = type,
                Method  = method,
                Payload = payload == null ? null : JObject.FromObject(payload)
            };

            _responses.Add(response);

            return(Task.FromResult(0));
        }
Beispiel #18
0
        /// <summary>
        /// Atomically add or update a request handler for the specified message method.
        /// </summary>
        /// <param name="method">A message method.</param>
        /// <param name="addHandlerFunc">An add request handler function.</param>
        /// <param name="updateHandlerFunc">An update request handler function.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="addHandlerFunc" />
        /// is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="updateHandlerFunc" />
        /// is <c>null</c>.</exception>
        public void AddOrUpdate(
            MessageMethod method,
            Func <IRequestHandler> addHandlerFunc,
            Func <IRequestHandler, IRequestHandler> updateHandlerFunc)
        {
            if (addHandlerFunc == null)
            {
                throw new ArgumentNullException(nameof(addHandlerFunc));
            }

            if (updateHandlerFunc == null)
            {
                throw new ArgumentNullException(nameof(updateHandlerFunc));
            }

            _handlers.AddOrUpdate(method, m => addHandlerFunc(), (m, r) => updateHandlerFunc(r));
        }
        CreateValidHandlerWithMessageQueueExpectation(
            MessageMethod messageMethod,
            ChaincodeMessage.Types.Type type
            )
        {
            var messageQueueMock = new Mock <IMessageQueue>();

            messageQueueMock.Setup(m => m.QueueMessage(It.Is(
                                                           (QueueMessage message) => message.Method == messageMethod && message.Message.Type == type
                                                           )));

            var messageQueueFactoryMock = new Mock <IMessageQueueFactory>();

            messageQueueFactoryMock.Setup(m => m.Create(It.IsAny <IHandler>()))
            .Returns(messageQueueMock.Object);

            return(CreateHandlerWithChainsupportClientFactory(messageQueueFactoryMock.Object), messageQueueMock);
        }
        public object ParseResponse(ChaincodeMessage response, MessageMethod messageMethod)
        {
            if (response.Type == ChaincodeMessage.Types.Type.Response)
            {
                _logger.LogInformation(
                    $"[{response.ChannelId}-{response.Txid}] Received {messageMethod} successful response");

                switch (messageMethod)
                {
                case MessageMethod.GetStateByRange:
                case MessageMethod.GetQueryResult:
                    return(new StateQueryIterator(this, response.ChannelId, response.Txid,
                                                  QueryResponse.Parser.ParseFrom(response.Payload)));

                case MessageMethod.GetHistoryForKey:
                    return(new HistoryQueryIterator(this, response.ChannelId, response.Txid,
                                                    QueryResponse.Parser.ParseFrom(response.Payload)));

                case MessageMethod.QueryStateNext:
                case MessageMethod.QueryStateClose:
                    return(QueryResponse.Parser.ParseFrom(response.Payload));

                case MessageMethod.InvokeChaincode:
                    return(ChaincodeMessage.Parser.ParseFrom(response.Payload));

                default:
                    return(response.Payload);
                }
            }

            if (response.Type == ChaincodeMessage.Types.Type.Error)
            {
                _logger.LogInformation(
                    $"[{response.ChannelId}-{response.Txid}] Received {messageMethod} error response");
                throw new Exception(response.Payload.ToStringUtf8());
            }

            var errorMessage = $"[{response.ChannelId}-{response.Txid}] Received incorrect chaincode " +
                               $"in response to the {messageMethod} call: " +
                               $"type={response.Type}, expecting \"RESPONSE\"";

            _logger.LogInformation(errorMessage);
            throw new Exception(errorMessage);
        }
Beispiel #21
0
        /// <summary>
        /// Instantiates a new <see cref="Message" /> class.
        /// </summary>
        /// <typeparam name="TPayload">The message payload type.</typeparam>
        /// <param name="requestId">The message request ID.</param>
        /// <param name="type">The message type.</param>
        /// <param name="method">The message method.</param>
        /// <param name="payload">The message payload.</param>
        /// <returns>a <see cref="Message" /> instance.</returns>
        /// <exception cref="ArgumentException">Thrown if <paramref name="requestId" />
        /// is either <c>null</c> or an empty string.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="payload" /> is <c>null</c>.</exception>
        public static Message Create <TPayload>(
            string requestId,
            MessageType type,
            MessageMethod method,
            TPayload payload)
            where TPayload : class
        {
            if (string.IsNullOrEmpty(requestId))
            {
                throw new ArgumentException(Strings.ArgumentCannotBeNullOrEmpty, nameof(requestId));
            }

            if (payload == null)
            {
                throw new ArgumentNullException(nameof(payload));
            }

            var jsonPayload = JsonSerializationUtilities.FromObject(payload);

            return(new Message(requestId, type, method, jsonPayload));
        }
Beispiel #22
0
        public static async Task <StunMessage> ParseAsync(
            Stream stream,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var header = new byte[20];
            await stream.ReadAsync(header, 0, 20, cancellationToken);

            MessageMethod method = ParseMethod(header[0], header[1]);
            MessageClass  @class = ParseClass(header[0], header[1]);

            var length = new byte[2];

            System.Array.Copy(header, 2, length, 0, 2);

            var transactionId = new byte[12];

            System.Array.Copy(header, 8, transactionId, 0, 12);

            var body = new byte[length.ToUShort()];
            await stream.ReadAsync(body, 0, body.Length, cancellationToken);

            IEnumerable <Attribute> attributes = ParseAttributes(
                body,
                transactionId
                );

            StunMessage rv = null;

            rv = @class switch
            {
                MessageClass.SuccessResponse => method switch
                {
                    MessageMethod.Allocate => new AllocateSuccessResponse(),
                    MessageMethod.Connect => new ConnectSuccessResponse(),
                    MessageMethod.ConnectionBind => new ConnectionBindSuccessResponse(),
                    MessageMethod.Binding => new BindingSuccessResponse(),
                    MessageMethod.CreatePermission => new CreatePermissionSuccessResponse(),
                    MessageMethod.Refresh => new RefreshSuccessResponse(),
                    _ => rv,
                },
Beispiel #23
0
        /// <summary>
        /// Asynchronously sends a message to the remote target and receives the target's response.
        /// </summary>
        /// <typeparam name="TOutbound">The outbound payload type.</typeparam>
        /// <typeparam name="TInbound">The inbound payload type.</typeparam>
        /// <param name="method">The outbound message method.</param>
        /// <param name="payload">The outbound message payload.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A task that represents the asynchronous operation.
        /// The task result (<see cref="Task{TResult}.Result" />) returns a <typeparamref name="TInbound" />
        /// from the target.</returns>
        /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" />
        /// is cancelled.</exception>
        /// <exception cref="InvalidOperationException">Thrown if not connected.</exception>
        public Task <TInbound> SendRequestAndReceiveResponseAsync <TOutbound, TInbound>(
            MessageMethod method,
            TOutbound payload,
            CancellationToken cancellationToken)
            where TOutbound : class
            where TInbound : class
        {
            if (State == ConnectionState.Closing ||
                State == ConnectionState.Closed)
            {
                return(Task.FromResult <TInbound>(null));
            }

            if (_state < (int)ConnectionState.Connecting)
            {
                throw new InvalidOperationException(Strings.Plugin_NotConnected);
            }

            cancellationToken.ThrowIfCancellationRequested();

            return(MessageDispatcher.DispatchRequestAsync <TOutbound, TInbound>(method, payload, cancellationToken));
        }
        /// <summary>
        /// Asynchronously dispatches a request.
        /// </summary>
        /// <typeparam name="TOutbound">The request payload type.</typeparam>
        /// <typeparam name="TInbound">The expected response payload type.</typeparam>
        /// <param name="method">The request method.</param>
        /// <param name="payload">The request payload.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A task that represents the asynchronous operation.
        /// The task result (<see cref="Task{TResult}.Result" />) returns a <typeparamref name="TInbound" />
        /// from the target.</returns>
        /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" />
        /// is cancelled.</exception>
        public Task <TInbound> DispatchRequestAsync <TOutbound, TInbound>(
            MessageMethod method,
            TOutbound payload,
            CancellationToken cancellationToken)
            where TOutbound : class
            where TInbound : class
        {
            cancellationToken.ThrowIfCancellationRequested();

            // Capture _connection as SetConnection(...) could null it out later.
            var connection = _connection;

            if (connection == null)
            {
                return(Task.FromResult <TInbound>(null));
            }

            return(DispatchWithNewContextAsync <TOutbound, TInbound>(
                       connection,
                       MessageType.Request,
                       method,
                       payload,
                       cancellationToken));
        }
Beispiel #25
0
        /// <summary>
        /// Attempts to remove a request handler for the specified message method.
        /// </summary>
        /// <param name="method">A message method.</param>
        /// <returns><c>true</c> if a request handler was removed; otherwise, <c>false</c>.</returns>
        public bool TryRemove(MessageMethod method)
        {
            IRequestHandler handler;

            return(_handlers.TryRemove(method, out handler));
        }
Beispiel #26
0
 /// <summary>
 /// Attempts to get a request handler for the specified message method.
 /// </summary>
 /// <param name="method">A message method.</param>
 /// <param name="handler">An existing request handler.</param>
 /// <returns><c>true</c> if the request handler exists; otherwise, <c>false</c>.</returns>
 public bool TryGet(MessageMethod method, out IRequestHandler handler)
 {
     return(_handlers.TryGetValue(method, out handler));
 }
 public QueueMessage(ChaincodeMessage message, MessageMethod method)
 {
     Message = message;
     Method  = method;
 }
Beispiel #28
0
 public Task <TInbound> SendRequestAndReceiveResponseAsync <TOutbound, TInbound>(MessageMethod method, TOutbound payload, CancellationToken cancellationToken)
     where TOutbound : class
     where TInbound : class
 {
     throw new NotImplementedException();
 }
        private static TimeSpan GetRequestTimeout(IConnection connection, MessageType type, MessageMethod method)
        {
            if (type == MessageType.Request && method == MessageMethod.Handshake)
            {
                return(connection.Options.HandshakeTimeout);
            }

            return(connection.Options.RequestTimeout);
        }
        /// <summary>
        /// Creates a message.
        /// </summary>
        /// <param name="type">The message type.</param>
        /// <param name="method">The message method.</param>
        /// <returns>A message.</returns>
        public Message CreateMessage(MessageType type, MessageMethod method)
        {
            var requestId = _idGenerator.GenerateUniqueId();

            return(MessageUtilities.Create(requestId, type, method));
        }