private JsonRpcResponse ReceiveMessage(string message) { JsonRpcResponse response; long messageId = 0; try { JsonRpcMessage jsonRpcMessage = JsonConvert.DeserializeObject <JsonRpcMessage>(message); messageId = jsonRpcMessage.Id; try { response = new JsonRpcResponse(jsonRpcMessage.Id, TryCallMethod(jsonRpcMessage).Result); } catch (Exception e) { throw e.InnerException; } } catch (Exception e) { response = e switch { JsonSerializationException _ => new JsonRpcResponse(messageId, JsonRpcErrors.ParseError), MethodNotFoundException _ => new JsonRpcResponse(messageId, JsonRpcErrors.MethodNotFound), InvalidParametersException _ => new JsonRpcResponse(messageId, JsonRpcErrors.InvalidParams), FormatException _ => new JsonRpcResponse(messageId, JsonRpcErrors.InvalidParams), _ => new JsonRpcResponse(messageId, JsonRpcErrors.InternalError) }; } return(response); }
public void ExecuteNamedParamsTest() { Incubator inc = new Incubator(); inc.Set(new Echo()); string id = "A Value"; JsonRpcRequest request = new JsonRpcRequest(); request.Incubator = inc; string value = "hello there ".RandomLetters(8); request.Params = JToken.Parse("{{'value': '{0}'}}"._Format(value)); request.RpcParams.By.Name = request.Params; request.Method = "Send"; request.Id = id; IHttpContext context = GetPostContextWithInput(request.ToJson()); request = (JsonRpcRequest)JsonRpcMessage.Parse(context); request.Incubator = inc; JsonRpcResponse response = request.Execute(); Expect.IsTrue(response.GetType().Equals(typeof(JsonRpcResponse))); Expect.AreEqual(response.Result, value); Expect.IsNull(response.Error); Expect.AreEqual(request.Id, response.Id); Expect.AreEqual(id, response.Id); }
protected override ValueTask WriteCoreAsync(JsonRpcMessage content, CancellationToken cancellationToken) { var builder = new Sequence <byte>(); this.Formatter.Serialize(builder, content); this.WrittenMessages.Enqueue(builder); return(default);
/// <summary> /// Reads a distinct and complete message from the transport, waiting for one if necessary. /// </summary> /// <param name="cancellationToken">A token to cancel the read request.</param> /// <returns>The received message, or <c>null</c> if the underlying transport ends before beginning another message.</returns> /// <exception cref="InvalidOperationException">Thrown when <see cref="CanRead"/> returns <c>false</c>.</exception> /// <exception cref="System.IO.EndOfStreamException">Thrown if the transport ends while reading a message.</exception> /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken"/> is canceled before a new message is received.</exception> /// <remarks> /// Implementations may assume this method is never called before any async result /// from a prior call to this method has completed. /// </remarks> public async ValueTask <JsonRpcMessage> ReadAsync(CancellationToken cancellationToken) { Verify.Operation(this.CanRead, "No receiving stream."); cancellationToken.ThrowIfCancellationRequested(); Verify.NotDisposed(this); try { JsonRpcMessage result = await this.ReadCoreAsync(cancellationToken).ConfigureAwait(false); return(result); } catch (InvalidOperationException ex) when(cancellationToken.IsCancellationRequested) { // PipeReader.ReadAsync can throw InvalidOperationException in a race where PipeReader.Complete() has been // called but we haven't noticed the CancellationToken was canceled yet. throw new OperationCanceledException("Reading failed during cancellation.", ex, cancellationToken); } catch (ObjectDisposedException) { // If already canceled, throw that instead of ObjectDisposedException. cancellationToken.ThrowIfCancellationRequested(); throw; } }
protected override ValueTask SendAsync(JsonRpcMessage message, CancellationToken cancellationToken) { if (message is JsonRpcRequest request) { Assert.True(request.TrySetTopLevelProperty <int>(MessageOrderPropertyName, this.messageCounter++)); } return(base.SendAsync(message, cancellationToken)); }
private void TryConvertParameters(JsonRpcMessage message, MethodInfo methodInfo, out object[] parameters) { ParameterInfo[] parameterInfos = methodInfo.GetParameters(); parameters = new object[parameterInfos.Length]; for (int i = 0; i < parameterInfos.Length; i++) { parameters[i] = message.Params[i].ToObject(parameterInfos[i].ParameterType); } }
public static string ToJson(this JsonRpcMessage jsonRpcMessage) { return(JsonConvert.SerializeObject(jsonRpcMessage, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, StringEscapeHandling = StringEscapeHandling.Default })); }
public void ParseRequestArrayShouldReturnRpcBatch() { IRequest request = A.Fake <IRequest>(); A.CallTo <string>(() => request.HttpMethod).Returns("POST"); A.CallTo <Stream>(() => request.InputStream).Returns(GetRequestBatch()); IJsonRpcRequest msg = JsonRpcMessage.Parse(request); Expect.IsInstanceOfType <JsonRpcBatch>(msg); }
public void ParseRequestWithoutIdShouldReturnNotification() { IRequest request = A.Fake <IRequest>(); A.CallTo <string>(() => request.HttpMethod).Returns("POST"); A.CallTo <Stream>(() => request.InputStream).Returns(GetNotificationStream()); IJsonRpcRequest msg = JsonRpcMessage.Parse(request); Expect.IsInstanceOfType <JsonRpcNotification>(msg); }
/// <inheritdoc/> protected override void Write(JsonRpcMessage content, CancellationToken cancellationToken) { if (this.prefixingWriter == null) { this.prefixingWriter = new PrefixingBufferWriter <byte>(this.Writer, sizeof(int)); } // Write out the actual message content, counting all written bytes. this.Formatter.Serialize(this.prefixingWriter, content); // Now go back and fill in the header with the actual content length. Utilities.Write(this.prefixingWriter.Prefix.Span, checked ((int)this.prefixingWriter.Length)); this.prefixingWriter.Commit(); }
public async Task Ctor_AcceptsNullReceivingStream() { var handler = new MyStreamMessageHandler(this.sendingStream, null, new MessagePackFormatter()); Assert.False(handler.CanRead); Assert.True(handler.CanWrite); await Assert.ThrowsAsync <InvalidOperationException>(() => handler.ReadAsync(this.TimeoutToken).AsTask()); JsonRpcMessage expected = CreateNotifyMessage(); await handler.WriteAsync(expected, this.TimeoutToken); var actual = await handler.WrittenMessages.DequeueAsync(this.TimeoutToken); Assert.Equal(expected, actual); }
/// <inheritdoc/> public void Serialize(IBufferWriter <byte> contentBuffer, JsonRpcMessage message) { var correctedMessage = ToValidRequest(message); switch (_serializerKind) { case MessagePackSerializerKind.LZ4MessagePackSerializer: LZ4MessagePackSerializer.Serialize(contentBuffer.AsStream(), correctedMessage, _resolver); return; case MessagePackSerializerKind.MessagePackSerializer: MessagePackSerializer.Serialize(contentBuffer.AsStream(), correctedMessage, _resolver); return; default: throw new InvalidOperationException("internal error"); } }
public void ParseRequestWithOrderedParams() { IRequest request = A.Fake <IRequest>(); A.CallTo <string>(() => request.HttpMethod).Returns("POST"); A.CallTo <Stream>(() => request.InputStream).Returns(GetRequestWithOrderedParamsStream()); IJsonRpcRequest msg = JsonRpcMessage.Parse(request); Expect.IsInstanceOfType <JsonRpcRequest>(msg); JsonRpcRequest rpcRequest = (JsonRpcRequest)msg; Expect.IsTrue(rpcRequest.RpcParams.Ordered); Expect.IsTrue(rpcRequest.RpcParams.By.Position != null); Expect.IsFalse(rpcRequest.RpcParams.Named); Expect.IsTrue(rpcRequest.RpcParams.By.Name == null); Expect.IsNotNull(rpcRequest.Params); Expect.IsTrue(rpcRequest.Params.Is <JArray>(), "Params should have been a JArray"); }
/// <inheritdoc/> public void Serialize(IBufferWriter <byte> contentBuffer, JsonRpcMessage message) { if (message is JsonRpcRequest request && request.Arguments != null && request.ArgumentsList == null && !(request.Arguments is IReadOnlyDictionary <string, object>)) { // This request contains named arguments, but not using a standard dictionary. Convert it to a dictionary so that // the parameters can be matched to the method we're invoking. request.Arguments = GetParamsObjectDictionary(request.Arguments); } if (this.compress) { LZ4MessagePackSerializer.Typeless.Serialize(contentBuffer.AsStream(), message); } else { MessagePackSerializer.Typeless.Serialize(contentBuffer.AsStream(), message); } }
protected override async ValueTask <JsonRpcMessage> DispatchRequestAsync(JsonRpcRequest request, TargetMethod targetMethod, CancellationToken cancellationToken) { this.LastRequestDispatched = request; TaskCompletionSource <JsonRpcMessage>?completionTcs = null; if (this.EnableBuffering) { TaskCompletionSource <bool> signalTask = new TaskCompletionSource <bool>(); completionTcs = new TaskCompletionSource <JsonRpcMessage>(); this.requestSignalQueue.TryEnqueue((request, signalTask, completionTcs.Task)); await signalTask.Task; } JsonRpcMessage result = await base.DispatchRequestAsync(request, targetMethod, cancellationToken); completionTcs?.SetResult(result); return(result); }
public void ExecuteOrderedParamsTest() { Incubator inc = new Incubator(); inc.Set(new Echo()); string value = "hello there ".RandomLetters(8); object id = "some value"; string inputString = "{{'jsonrpc': '2.0', 'method': 'Send', 'id': '{0}', 'params': ['{1}']}}"._Format(id, value); IHttpContext context = GetPostContextWithInput(inputString); IJsonRpcRequest parsed = JsonRpcMessage.Parse(context); JsonRpcRequest request = (JsonRpcRequest)parsed; request.Incubator = inc; JsonRpcResponse response = request.Execute(); Expect.IsTrue(response.GetType().Equals(typeof(JsonRpcResponse))); Expect.AreEqual(value, response.Result); Expect.IsNull(response.Error); Expect.AreEqual(id, response.Id); }
/// <inheritdoc/> protected override async ValueTask <JsonRpcMessage> ReadCoreAsync(CancellationToken cancellationToken) { var readResult = await this.ReadAtLeastAsync(4, allowEmpty : true, cancellationToken).ConfigureAwait(false); if (readResult.Buffer.Length == 0) { return(null); } ReadOnlySequence <byte> lengthBuffer = readResult.Buffer.Slice(0, 4); int length = Utilities.ReadInt32BE(lengthBuffer); this.Reader.AdvanceTo(lengthBuffer.End); readResult = await this.ReadAtLeastAsync(length, allowEmpty : false, cancellationToken).ConfigureAwait(false); ReadOnlySequence <byte> content = readResult.Buffer.Slice(0, length); JsonRpcMessage message = this.Formatter.Deserialize(content); this.Reader.AdvanceTo(content.End); return(message); }
/// <summary> /// Writes a message to the transport and flushes. /// </summary> /// <param name="content">The message to write.</param> /// <param name="cancellationToken">A token to cancel the write request.</param> /// <returns>A task that represents the asynchronous operation.</returns> /// <exception cref="InvalidOperationException">Thrown when <see cref="CanWrite"/> returns <c>false</c>.</exception> /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken"/> is canceled before message transmission begins.</exception> /// <remarks> /// Implementations should expect this method to be invoked concurrently /// and use a queue to preserve message order as they are transmitted one at a time. /// </remarks> public async ValueTask WriteAsync(JsonRpcMessage content, CancellationToken cancellationToken) { Requires.NotNull(content, nameof(content)); Verify.Operation(this.CanWrite, "No sending stream."); cancellationToken.ThrowIfCancellationRequested(); Verify.NotDisposed(this); try { using (await this.sendingSemaphore.EnterAsync(cancellationToken).ConfigureAwait(false)) { cancellationToken.ThrowIfCancellationRequested(); await this.WriteCoreAsync(content, cancellationToken).ConfigureAwait(false); await this.FlushAsync(cancellationToken).ConfigureAwait(false); } } catch (ObjectDisposedException) { // If already canceled, throw that instead of ObjectDisposedException. cancellationToken.ThrowIfCancellationRequested(); throw; } }
// If message is a JsonRpcRequest and its Arguments is a paramter object, // converts the parameter object to a valid JSON-RPC parameter structure. private JsonRpcMessage ToValidRequest(JsonRpcMessage message) { if (!(message is JsonRpcRequest request)) { return(message); } if (IsValidParameterStructure(request.Arguments)) { return(message); } else { if (!_allowParameterObject) { throw new NotSupportedException("This JsonRpcMessagePackFormatter is not configured to allow parameter objects."); } // NOTE: How a member of a parameter object is matched against a parameter of an RPC method // is not a concern of serializers, but the concern of the StreamJsonRpc interface, // introduced by the `InvokeWithParameterObjectAsync` contract. // // By using Json.NET, we happen to implement this matching algorithm. During serialization // every object is converted into a JSON object. Thus we can easily obtain // serialized property names using JObject.Properties. // // Shallowly convert the parameter object to a Dictionary<string, object> before serialization. return(new JsonRpcRequest() { Id = request.Id, Method = request.Method, Version = request.Version, NamedArguments = ToParameterStructure(request.Arguments), }); } }
public void Serialize(IBufferWriter <byte> contentBuffer, JsonRpcMessage message) { throw new NotImplementedException(); }
public object GetJsonText(JsonRpcMessage message) { throw new NotImplementedException(); }
protected override ValueTask WriteCoreAsync(JsonRpcMessage message, CancellationToken cancellationToken) { this.WrittenMessages.Enqueue(message); return(default);
/// <summary> /// Writes a message. /// </summary> /// <param name="content">The message to write.</param> /// <param name="cancellationToken">A token to cancel the transmission.</param> /// <returns>A task that represents the asynchronous write operation.</returns> protected abstract ValueTask WriteCoreAsync(JsonRpcMessage content, CancellationToken cancellationToken);
public object GetJsonText(JsonRpcMessage message) { throw new NotSupportedException(); }
protected override ValueTask WriteCoreAsync(JsonRpcMessage content, CancellationToken cancellationToken) { Interlocked.Increment(ref this.WriteCoreCallCount); return(new ValueTask(this.WriteBlock.WaitAsync())); }
public void Serialize(IBufferWriter <byte> bufferWriter, JsonRpcMessage message) { this.formatter.Serialize(bufferWriter, message); }
/// <inheritdoc/> public object GetJsonText(JsonRpcMessage message) => MessagePackSerializer.ToJson <object>(message);
public void Serialize(System.Buffers.IBufferWriter <byte> bufferWriter, JsonRpcMessage message) { throw new NotImplementedException(); }
protected override void Write(JsonRpcMessage content, CancellationToken cancellationToken) { throw new FileNotFoundException(); }
protected override ValueTask WriteCoreAsync(JsonRpcMessage content, CancellationToken cancellationToken) { this.WrittenMessages.Enqueue(this.Formatter.Serialize(content)); return(default);