Пример #1
0
        public void Should_be_able_to_publish_and_receive_response()
        {
            bus.Respond<RpcRequest, RpcResponse>(req => new RpcResponse { Value = req.Value });
            var request = new RpcRequest { Value = 5 };
            var response = bus.Request<RpcRequest, RpcResponse>(request);

            Assert.IsNotNull(response);
            Assert.IsTrue(request.Value == response.Value);
        }
Пример #2
0
        /* 实现思路
         * 1、调取JsonRpc接口获取当前区块高度
         * 2、根据当前区块高度排除数据库中6个以内的区块(因为一定是未确认的)
         * 3、拿出剩余未确认的区块,调取Rpc接口判断区块是否被确认
         * 4、批量更新数据库的确认状态和是否作废状态
         * 5、需要更新RewardList表中的是否作废状态
         *
         * 备注:Rpc接口判断区块是否被确认这个接口需要自己用Rpc写
         * 接口:根据传入的区块Hash判断是否区块是否被确认
         * 接口返回值:返回被确认的区块Hash
         */

        /// <summary>
        /// 更新区块的确认状态和抛弃状态
        /// </summary>
        /// <returns></returns>
        public async Task GetVerifiedHashes()
        {
            //不能直接调用OmniCoin.Bussiness,需要使用JsonRpc调用接口
            //先通过JsonRpc获取当前区块高度
            LogHelper.Debug($"****************begin to sync blocks********************");
            BlocksDac                 dac             = new BlocksDac();
            RewardListDac             rewardDac       = new RewardListDac();
            MinersDac                 minersDac       = new MinersDac();
            AuthenticationHeaderValue authHeaderValue = null;

            LogHelper.Debug($"API_URI is {MiningPoolSetting.API_URI}");
            long responseValue = 0;

            try
            {
                RpcClient   client   = new RpcClient(new Uri(MiningPoolSetting.API_URI), authHeaderValue, null, null, "application/json");
                RpcRequest  request  = RpcRequest.WithNoParameters("GetBlockCount", 1);
                RpcResponse response = await client.SendRequestAsync(request);

                if (response.HasError)
                {
                    throw new ApiCustomException(response.Error.Code, response.Error.Message);
                }

                responseValue = response.GetResult <long>();
                LogHelper.Debug($"responseValue:{responseValue}");
                LogHelper.Debug($"sqlite block hight is {responseValue}");
                if (responseValue - 100 > 0)
                {
                    //根据responseValue获取数据库中高度小于responseValue - 6的所有Hash值
                    List <string> hashes      = dac.GetAppointedHash(responseValue - 100);
                    RpcRequest    requestHash = RpcRequest.WithParameterList("GetVerifiedHashes", new List <object> {
                        hashes
                    }, 1);
                    RpcResponse responseHash = await client.SendRequestAsync(requestHash);

                    if (responseHash.HasError)
                    {
                        throw new ApiCustomException(response.Error.Code, response.Error.Message);
                    }
                    List <Block> list = responseHash.GetResult <List <Block> >();
                    LogHelper.Info($"Verified Hashes count is {list.Count}");

                    /*发送到阿里云消息队列
                     * foreach (Block item in list)
                     * {
                     *  //根据Block获取RewardList
                     *  string tableName = "RewardList" + Time.GetLocalDateTime(item.Timestamp).ToString("yyyyMMdd");
                     *  List<RewardList> rewardList = rewardDac.GetListByHash(tableName, item.Hash);
                     *  string sendBody = Newtonsoft.Json.JsonConvert.SerializeObject(new { item, rewardList });
                     *
                     *  AliMQ.ProducerMessage producer = new AliMQ.ProducerMessage();
                     *  producer.Initialize("MinerReward");
                     *  producer.SendNormalMessage(item.GeneratorId, sendBody, item.Hash);
                     * }
                     */
                    //根据list的值批量更新数据库
                    foreach (var item in list)
                    {
                        LogHelper.Info($"begin update block confirm");
                        UpdateBlockConfirmed(item.Hash, (item.IsVerified ? 1 : 0), (item.IsDiscarded ? 1 : 0));
                        string tableName = "RewardList" + Time.GetLocalDateTime(item.Timestamp).ToString("yyyyMMdd");
                        //如果区块作废就更新RewardList表状态
                        if (item.IsDiscarded)
                        {
                            LogHelper.Info($"begin update discarded blocks");
                            rewardDac.UpdatePaid(tableName, item.Hash, 2, responseValue - 100);
                            //更新Miners表中的未发放UnpaidReward余额
                            minersDac.UpdateDiscardedUnpaidReward(tableName, item.Hash);
                        }
                    }
                    //丢弃那些状态失败的,根据区块高度和confirm=0更新IsDiscard
                    UpdateFailBlock(responseValue - 100);
                    LogHelper.Debug($"****************end to sync blocks********************");
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.Message, ex);
            }
        }
Пример #3
0
 public override Task <T> HandleAsyncWithResult <T>(RpcRequest rpcRequest) => SendRequest <T>(rpcRequest);
Пример #4
0
 public override object HandleSync(RpcRequest rpcRequest) => SendRequest <object>(rpcRequest).ConfigureAwait(false).GetAwaiter().GetResult();
Пример #5
0
        /// <summary>
        /// Finds the matching Rpc method for the current request
        /// </summary>
        /// <param name="route">Rpc route for the current request</param>
        /// <param name="request">Current Rpc request</param>
        /// <param name="parameterList">Paramter list parsed from the request</param>
        /// <param name="serviceProvider">(Optional)IoC Container for rpc method controllers</param>
        /// <param name="jsonSerializerSettings">Json serialization settings that will be used in serialization and deserialization for rpc requests</param>
        /// <returns>The matching Rpc method to the current request</returns>
        private RpcMethod GetMatchingMethod(RpcRoute route, RpcRequest request, out object[] parameterList, IServiceProvider serviceProvider = null, JsonSerializerSettings jsonSerializerSettings = null)
        {
            if (route == null)
            {
                throw new ArgumentNullException(nameof(route));
            }
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            this.logger?.LogDebug($"Attempting to match Rpc request to a method '{request.Method}'");
            List <RpcMethod> methods = DefaultRpcInvoker.GetRpcMethods(route, serviceProvider, jsonSerializerSettings);

            //Case insenstive check for hybrid approach. Will check for case sensitive if there is ambiguity
            methods = methods
                      .Where(m => string.Equals(m.Method, request.Method, StringComparison.OrdinalIgnoreCase))
                      .ToList();

            RpcMethod rpcMethod = null;

            parameterList = null;
            int originalMethodCount = methods.Count;

            if (methods.Count > 0)
            {
                List <RpcMethod> potentialMatches = new List <RpcMethod>();
                foreach (RpcMethod method in methods)
                {
                    bool matchingMethod;
                    if (request.ParameterMap != null)
                    {
                        matchingMethod = method.HasParameterSignature(request.ParameterMap, out parameterList);
                    }
                    else
                    {
                        matchingMethod = method.HasParameterSignature(request.ParameterList);
                        parameterList  = request.ParameterList;
                    }
                    if (matchingMethod)
                    {
                        potentialMatches.Add(method);
                    }
                }

                if (potentialMatches.Count > 1)
                {
                    //Try to remove ambiguity with case sensitive check
                    potentialMatches = potentialMatches
                                       .Where(m => string.Equals(m.Method, request.Method, StringComparison.Ordinal))
                                       .ToList();
                    if (potentialMatches.Count != 1)
                    {
                        this.logger?.LogError("More than one method matched the rpc request. Unable to invoke due to ambiguity.");
                        throw new RpcMethodNotFoundException();
                    }
                }

                if (potentialMatches.Count == 1)
                {
                    rpcMethod = potentialMatches.First();
                }
            }
            if (rpcMethod == null)
            {
                this.logger?.LogError("No methods matched request.");
                throw new RpcMethodNotFoundException();
            }
            this.logger?.LogDebug("Request was matched to a method");
            return(rpcMethod);
        }
Пример #6
0
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            if (message is IByteBuffer buffer)
            {
                var id = 0l;

                /*
                 * skip length field
                 */

                buffer.SkipBytes(4);

                var header = buffer.ReadByte();

                /*
                 * process heart beat
                 */
                if (header == HEARTBEAT_HEADER)
                {
                    if (ensureRegisterd(context))
                    {
                        _checker.UpdateTimeout(context.Channel.Id.AsLongText());
                    }

                    //else ignore
                }
                else if (header == REQUEST)
                {
                    var rpcContext = _pool.Rent();

                    try
                    {
                        /*
                         *  resolve request
                         */
                        var request = new RpcRequest();

                        request.RequestId = buffer.ReadLongLE();

                        id = request.RequestId;

                        var length = buffer.ReadIntLE();

                        var path = buffer.ReadString(length, Encoding.UTF8);

                        parseQuery(request, path);

                        length = buffer.ReadIntLE();

                        request.Body = new byte[length];

                        buffer.ReadBytes(request.Body);

                        /*
                         * login check
                         */
                        if (_validator != null)// configed require  identity validate
                        {
                            try
                            {
                                if (!_checker.IsRegistered(context.Channel.Id.AsLongText()))
                                {
                                    var resposne = _validator.Validate(request.Query["id"], request.Query["password"]) ? RpcResponse.CreateResponse(200, request.RequestId)
                                                                                                                       : RpcResponse.CreateLoginFialedResponse(request.RequestId);

                                    var sendBuffer = _codex.EncodeServerResponse(resposne);

                                    var sendBuffer1 = context.Allocator.Buffer(sendBuffer.Length);

                                    sendBuffer1.WriteBytes(sendBuffer);

                                    context.WriteAndFlushAsync(sendBuffer1);
                                }
                            }
                            catch (Exception ex)
                            {
                                var sendBuffer = _codex.EncodeServerResponse(RpcResponse.CreateErrorResponse(request.RequestId));

                                var sendBuffer1 = context.Allocator.Buffer(sendBuffer.Length);

                                sendBuffer1.WriteBytes(sendBuffer);

                                context.WriteAndFlushAsync(sendBuffer1);

                                return;
                            }
                        }

                        /*
                         *  process request
                         */

                        rpcContext.Init(request, context);

                        _middleWare.ProcessRequest(rpcContext);
                    }
                    catch (Exception ex)
                    {
                        _logger?.Error(ex);

                        context.WriteAndFlushAsync(RpcResponse.CreateErrorResponse(10000));
                    }
                    finally
                    {
                        _pool.Recycle(rpcContext);
                    }
                }
            }
            else
            {
                _logger?.Warn($"unexcepted input {message}");
            }
        }
Пример #7
0
        /// <summary>
        /// Intercepts the specified invocation.
        /// </summary>
        /// <param name="invocation">The invocation.</param>
        public async Task <object> Intercept(Invocation invocation)
        {
            await Task.Yield();

            var correlationId = Guid.NewGuid().ToString();

            var h = new
            {
                name = $"{invocation.Method.DeclaringType?.FullName}.{invocation.Method.Name}",
                args = invocation.Method.GetParameters().Select(a => a.ParameterType.FullName).ToArray(),
                ret  = invocation.Method.ReturnType.FullName
            };

            using (ObjectPool <EventWaitHandle> .PoolObject pooledEvent = _eventPool.Get())
            {
                EventWaitHandle @event  = pooledEvent.Item;
                object          result  = null;
                var             handler = new Func <byte[], WorkerResult>(d =>
                {
                    Type type = invocation.Method.ReturnType;
                    if (type.IsTaskT())
                    {
                        type = invocation.Method.ReturnType.GenericTypeArguments[0];
                    }

                    result = _serializer.Deserialize(type, d);
                    @event.Set();
                    return(WorkerResult.Success);
                });

                if (!_pending.TryAdd(correlationId, handler))
                {
                    return(null);
                }

                var props = new BasicProperties
                {
                    CorrelationId = correlationId,
                    Headers       = new Dictionary <string, object>
                    {
                        { "returnType", h.ret },
                        { "signature", h.name },
                        { "args", h.args }
                    }
                };

                if (invocation.Method.ReturnType != typeof(void))
                {
                    props.ReplyTo = _queue;
                }

                return(await Task.Run(async() =>
                {
                    var req = new RpcRequest {
                        Arguments = invocation.Arguments
                    };
                    _model.BasicPublish(Exchange, string.Empty, props, _serializer.Serialize(req));

                    if (invocation.Method.ReturnType == typeof(void))
                    {
                        _pending.TryRemove(correlationId, out Func <byte[], WorkerResult> _);
                        return null;
                    }

                    await Task.Yield();
                    @event.WaitOne();
                    return result;
                }));
            }
        }
Пример #8
0
 public override async Task <RpcResponse> InterceptSendRequestAsync(
     Func <RpcRequest, string, Task <RpcResponse> > interceptedSendRequestAsync, RpcRequest request,
     string route = null)
 {
     if (request.Method == "eth_sendTransaction")
     {
         var transaction        = (TransactionInput)request.ParameterList[0];
         var privateTransaction = new PrivateTransactionInput(transaction, privateFor.ToArray(), privateFrom);
         request.ParameterList[0] = privateTransaction;
         return(await interceptedSendRequestAsync(request, route).ConfigureAwait(false));
     }
     return(await interceptedSendRequestAsync(request, route).ConfigureAwait(false));
 }
Пример #9
0
        /// <summary>
        /// Detects if list of parameters matches the method signature
        /// </summary>
        /// <param name="parameterList">Array of parameters for the method</param>
        /// <returns>True if the method signature matches the parameterList, otherwise False</returns>
        private bool HasParameterSignature(MethodInfo method, RpcRequest rpcRequest, out RpcMethodInfo rpcMethodInfo)
        {
            JToken[] orignialParameterList;
            if (rpcRequest.Parameters == null)
            {
                orignialParameterList = new JToken[0];
            }
            else
            {
                switch (rpcRequest.Parameters.Type)
                {
                case JTokenType.Object:
                    JsonSerializer jsonSerializer            = this.GetJsonSerializer();
                    Dictionary <string, JToken> parameterMap = rpcRequest.Parameters.ToObject <Dictionary <string, JToken> >(jsonSerializer);
                    bool canParse = this.TryParseParameterList(method, parameterMap, out orignialParameterList);
                    if (!canParse)
                    {
                        rpcMethodInfo = null;
                        return(false);
                    }
                    break;

                case JTokenType.Array:
                    orignialParameterList = rpcRequest.Parameters.ToArray();
                    break;

                default:
                    orignialParameterList = new JToken[0];
                    break;
                }
            }
            ParameterInfo[] parameterInfoList = method.GetParameters();
            if (orignialParameterList.Length > parameterInfoList.Length)
            {
                rpcMethodInfo = null;
                return(false);
            }
            object[] correctedParameterList = new object[parameterInfoList.Length];

            for (int i = 0; i < orignialParameterList.Length; i++)
            {
                ParameterInfo parameterInfo = parameterInfoList[i];
                JToken        parameter     = orignialParameterList[i];
                bool          isMatch       = this.ParameterMatches(parameterInfo, parameter, out object convertedParameter);
                if (!isMatch)
                {
                    rpcMethodInfo = null;
                    return(false);
                }
                correctedParameterList[i] = convertedParameter;
            }

            if (orignialParameterList.Length < parameterInfoList.Length)
            {
                //make a new array at the same length with padded 'missing' parameters (if optional)
                for (int i = orignialParameterList.Length; i < parameterInfoList.Length; i++)
                {
                    if (!parameterInfoList[i].IsOptional)
                    {
                        rpcMethodInfo = null;
                        return(false);
                    }
                    correctedParameterList[i] = Type.Missing;
                }
            }

            rpcMethodInfo = new RpcMethodInfo(method, correctedParameterList, orignialParameterList);
            return(true);
        }
Пример #10
0
        /// <summary>
        /// Call the incoming Rpc request method and gives the appropriate response
        /// </summary>
        /// <param name="request">Rpc request</param>
        /// <returns>An Rpc response for the request</returns>
        public async Task <RpcResponse?> InvokeRequestAsync(RpcRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            this.logger.InvokingRequest(request.Id);
            RpcContext       routeContext  = this.contextAccessor.Get();
            RpcInvokeContext?invokeContext = null;

            if (this.serverConfig.Value.OnInvokeStart != null)
            {
                invokeContext = new RpcInvokeContext(routeContext.RequestServices, request, routeContext.Path);
                this.serverConfig.Value.OnInvokeStart(invokeContext);
            }
            RpcResponse rpcResponse;

            try
            {
                IRpcMethodInfo rpcMethod;
                using (var requestSignature = RpcRequestSignature.Create(request))
                {
                    rpcMethod = this.rpcRequestMatcher.GetMatchingMethod(requestSignature);
                }

                bool isAuthorized = await this.authorizationHandler.IsAuthorizedAsync(rpcMethod);

                if (isAuthorized)
                {
                    object[] realParameters = this.ParseParameters(request.Parameters, rpcMethod.Parameters);

                    this.logger.InvokeMethod(request.Method);
                    object?result = await this.InvokeAsync(rpcMethod, realParameters, request, routeContext.RequestServices);

                    this.logger.InvokeMethodComplete(request.Method);

                    if (result is IRpcMethodResult methodResult)
                    {
                        rpcResponse = methodResult.ToRpcResponse(request.Id);
                    }
                    else
                    {
                        rpcResponse = new RpcResponse(request.Id, result);
                    }
                }
                else
                {
                    var authError = new RpcError(RpcErrorCode.InvalidRequest, "Unauthorized");
                    rpcResponse = new RpcResponse(request.Id, authError);
                }
            }
            catch (Exception ex)
            {
                const string errorMessage = "An Rpc error occurred while trying to invoke request.";
                this.logger.LogException(ex, errorMessage);
                RpcError error;
                if (ex is RpcException rpcException)
                {
                    error = rpcException.ToRpcError(this.serverConfig.Value.ShowServerExceptions);
                }
                else
                {
                    error = new RpcError(RpcErrorCode.InternalError, errorMessage, ex);
                }
                rpcResponse = new RpcResponse(request.Id, error);
            }
            if (this.serverConfig.Value.OnInvokeEnd != null)
            {
                if (invokeContext == null)
                {
                    invokeContext = new RpcInvokeContext(routeContext.RequestServices, request, routeContext.Path);
                }
                this.serverConfig.Value.OnInvokeEnd(invokeContext, rpcResponse);
            }
            if (request.Id.HasValue)
            {
                this.logger.FinishedRequest(request.Id.ToString() !);
                //Only give a response if there is an id
                return(rpcResponse);
            }
            //TODO make no id run in a non-blocking way
            this.logger.FinishedRequestNoId();
            return(null);
        }
Пример #11
0
 public abstract Task <RpcResponse> Call(RpcRequest request);
Пример #12
0
        public async Task <ReturnT> InvokeService(MethodBase method, List <string> paramTypes, params object[] parameters)
        {
            var methodName = method.Name.Substring(0, 1).ToLower() + method.Name.Substring(1);
            var request    = new RpcRequest()
            {
                createMillisTime = DateTimeExtensions.CurrentTimeMillis(),
                accessToken      = _executorOption.Value.AccessToken,
                className        = "com.xxl.job.core.biz.AdminBiz",
                methodName       = methodName,
                parameterTypes   = new ArrayList(paramTypes.Select(item => new Class(item)).ToArray()),
                parameters       = new ArrayList(parameters)
            };

            var ms         = new MemoryStream();
            var serializer = new CHessianOutput(ms);

            serializer.WriteObject(request);
            var responseBody = ms.ToArray();

            int triedTimes = 0;

            while (triedTimes++ < _addresses.Count)
            {
                var item = _addresses[_currentAdminIndex];
                _currentAdminIndex = (_currentAdminIndex + 1) % _addresses.Count;
                if (!item.CheckAccessable())
                {
                    continue;
                }

                Stream responseStream;
                try
                {
                    var content = new ByteArrayContent(responseBody);
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                    var responseMessage = await _client.PostAsync(item.RequestUri, content);

                    responseMessage.EnsureSuccessStatusCode();
                    responseStream = await responseMessage.Content.ReadAsStreamAsync();

                    item.Reset();
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "request admin error.");
                    item.SetFail();
                    continue;
                }

                var rpcResponse = (RpcResponse) new CHessianInput(responseStream).ReadObject();
                if (rpcResponse == null)
                {
                    throw new Exception("xxl-rpc response not found.");
                }
                if (rpcResponse.IsError)
                {
                    throw new Exception(rpcResponse.error);
                }
                else
                {
                    return(rpcResponse.result as ReturnT);
                }
            }

            throw new Exception("xxl-rpc server address not accessable.");
        }
Пример #13
0
        public ServiceRequest ConvertParam(RpcRequest rpc)
        {
            var request = rpc.Data.ToObject <ServiceRequest>();

            return(request);
        }
        public string Handle(string requestData)
        {
            RpcRequest  request   = JsonConvert.DeserializeObject <RpcRequest>(requestData);
            string      nameSpace = request.NameSpace;
            RpcResponse response  = new RpcResponse()
            {
                Code = 1, Message = "未知错误"
            };
            bool flag = RpcConatiner.ServiceContainer.TryGetValue(nameSpace, out object obj);

            if (flag)
            {
                List <string> requestParamList     = JsonConvert.DeserializeObject <List <string> >(request.Parameter);
                List <string> requestParamTypeList = JsonConvert.DeserializeObject <List <string> >(request.ParameterType);
                List <Type>   types = new List <Type>();
                try
                {
                    foreach (var paramType in requestParamTypeList)
                    {
                        Type type = GetType(paramType);
                        if (type == null)
                        {
                            response.Code    = 3;
                            response.Message = "未加载目标方法";
                            return(JsonConvert.SerializeObject(response));
                        }
                        types.Add(type);
                    }

                    MethodInfo method = obj.GetType().GetMethod(request.Method, types.ToArray());

                    if (method == null)
                    {
                        response.Code    = 2;
                        response.Message = "请求方法不存在";
                        return(JsonConvert.SerializeObject(response));
                    }

                    List <object>   parameters     = new List <object>();
                    ParameterInfo[] parameterInfos = method.GetParameters();
                    for (int i = 0; i < parameterInfos.Length; i++)
                    {
                        ParameterInfo parameterInfo = parameterInfos[i];
                        Type          type          = parameterInfo.ParameterType;
                        parameters.Add(JsonConvert.DeserializeObject(requestParamList[i], type));
                    }

                    var result = method.Invoke(obj, parameters.ToArray());
                    response.Code     = 0;
                    response.Message  = "成功";
                    response.Response = JsonConvert.SerializeObject(result);
                    return(JsonConvert.SerializeObject(response));
                }
                catch (System.Exception e)
                {
                    response.Code    = -1;
                    response.Message = e.Message;
                    return(JsonConvert.SerializeObject(response));
                }
            }
            response.Message = "未找到远程接口服务";
            return(JsonConvert.SerializeObject(response));
        }
Пример #15
0
 private RpcRequestParseResult(RpcId id, RpcRequest request, RpcError error)
 {
     this.Id      = id;
     this.Request = request;
     this.Error   = error;
 }
Пример #16
0
        public override async Task <object> InterceptSendRequestAsync <T>(Func <RpcRequest, string, Task <T> > interceptedSendRequestAsync, RpcRequest request, string route = null)
        {
            var id = GetId();
            var sw = Stopwatch.StartNew();

            Log($"{id} Sending request:\n{JsonConvert.SerializeObject(request, Formatting.Indented)}");
            var response = await base.InterceptSendRequestAsync(interceptedSendRequestAsync, request, route);

            Log($"{id} {sw.ElapsedMilliseconds} ms: got response:\n{JsonConvert.SerializeObject(response, Formatting.Indented)}");
            return(response);
        }
Пример #17
0
 public static RpcRequestParseResult Success(RpcRequest request)
 {
     return(new RpcRequestParseResult(request.Id, request, null));
 }
Пример #18
0
        /// <summary>
        /// Call the incoming Rpc request method and gives the appropriate response
        /// </summary>
        /// <param name="request">Rpc request</param>
        /// <param name="route">Rpc route that applies to the current request</param>
        /// <param name="httpContext">The context of the current http request</param>
        /// <param name="jsonSerializerSettings">Json serialization settings that will be used in serialization and deserialization for rpc requests</param>
        /// <returns>An Rpc response for the request</returns>
        public async Task <RpcResponse> InvokeRequestAsync(RpcRequest request, RpcRoute route, HttpContext httpContext, JsonSerializerSettings jsonSerializerSettings = null)
        {
            try
            {
                if (request == null)
                {
                    throw new ArgumentNullException(nameof(request));
                }
                if (route == null)
                {
                    throw new ArgumentNullException(nameof(route));
                }
            }
            catch (ArgumentNullException ex)             // Dont want to throw any exceptions when doing async requests
            {
                return(this.GetUnknownExceptionReponse(request, ex));
            }

            this.logger?.LogDebug($"Invoking request with id '{request.Id}'");
            RpcResponse rpcResponse;

            try
            {
                if (!string.Equals(request.JsonRpcVersion, JsonRpcContants.JsonRpcVersion))
                {
                    throw new RpcInvalidRequestException($"Request must be jsonrpc version '{JsonRpcContants.JsonRpcVersion}'");
                }

                object[]  parameterList;
                RpcMethod rpcMethod = this.GetMatchingMethod(route, request, out parameterList, httpContext.RequestServices, jsonSerializerSettings);

                bool isAuthorized = await this.IsAuthorizedAsync(rpcMethod, httpContext);

                if (isAuthorized)
                {
                    this.logger?.LogDebug($"Attempting to invoke method '{request.Method}'");
                    object result = await rpcMethod.InvokeAsync(parameterList);

                    this.logger?.LogDebug($"Finished invoking method '{request.Method}'");

                    JsonSerializer jsonSerializer = JsonSerializer.Create(jsonSerializerSettings);
                    if (result is IRpcMethodResult)
                    {
                        this.logger?.LogTrace($"Result is {nameof(IRpcMethodResult)}.");
                        rpcResponse = ((IRpcMethodResult)result).ToRpcResponse(request.Id, obj => JToken.FromObject(obj, jsonSerializer));
                    }
                    else
                    {
                        this.logger?.LogTrace($"Result is plain object.");
                        JToken resultJToken = result != null?JToken.FromObject(result, jsonSerializer) : null;

                        rpcResponse = new RpcResponse(request.Id, resultJToken);
                    }
                }
                else
                {
                    var authError = new RpcError(RpcErrorCode.InvalidRequest, "Unauthorized");
                    rpcResponse = new RpcResponse(request.Id, authError);
                }
            }
            catch (RpcException ex)
            {
                this.logger?.LogException(ex, "An Rpc error occurred. Returning an Rpc error response");
                RpcError error = new RpcError(ex, this.serverConfig.Value.ShowServerExceptions);
                rpcResponse = new RpcResponse(request.Id, error);
            }
            catch (Exception ex)
            {
                rpcResponse = this.GetUnknownExceptionReponse(request, ex);
            }

            if (request.Id != null)
            {
                this.logger?.LogDebug($"Finished request with id '{request.Id}'");
                //Only give a response if there is an id
                return(rpcResponse);
            }
            this.logger?.LogDebug($"Finished request with no id. Not returning a response");
            return(null);
        }
Пример #19
0
        public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, byte[] body)

        {
            var client = new MongoClient("mongodb://*****:*****@cluster0-shard-00-00-bj19b.azure.mongodb.net:27017,cluster0-shard-00-01-bj19b.azure.mongodb.net:27017,cluster0-shard-00-02-bj19b.azure.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true&w=majority");
            var db     = client.GetDatabase("ReservationManagement");
            var coll   = db.GetCollection <BsonDocument>("Reservation");

            Console.WriteLine($"Consuming Message");
            Console.WriteLine(string.Concat("Message received from the exchange ", exchange));
            Console.WriteLine(string.Concat("Consumer tag: ", consumerTag));
            Console.WriteLine(string.Concat("Delivery tag: ", deliveryTag));
            Console.WriteLine(string.Concat("Routing tag: ", routingKey));
            Console.WriteLine(string.Concat("Message: ", Encoding.UTF8.GetString(body)));


            if (exchange.Equals("request.reservation"))
            {
                //MongoConn


                if (routingKey.Equals("reservation.get.by.id"))
                {
                    Console.WriteLine("get ReservationID " + Encoding.UTF8.GetString(body));

                    var filter = Builders <BsonDocument> .Filter.Eq("_id", ObjectId.Parse(Encoding.UTF8.GetString(body)));

                    var reservationSearched = coll.Find(filter).FirstOrDefault();

                    var myReservation = BsonSerializer.Deserialize <Reservation>(reservationSearched);

                    Console.WriteLine("myReservation LocID " + myReservation.LocationID);
                    // Console.WriteLine("myReservation CurrencyID" + myReservation.CurrencyExchangeRate);
                    Console.WriteLine("myReservation StartDate " + myReservation.StartDate);
                    Console.WriteLine("myReservation EndDate " + myReservation.EndDate);
                    Console.WriteLine("myReservation categoryID " + myReservation.CurrencyExchangeRate);

                    //TODO send GW
                }
                else
                {
                    if (routingKey.Equals("reservation.create"))
                    {
                        Reservation reservationConsumed = JsonConvert.DeserializeObject <Reservation>(Encoding.UTF8.GetString(body));

                        //EXAMPLE exchange request
                        //step 1 - create request
                        RpcRequest request = new RpcRequest {
                            fromCCY = "USD", toCCY = "EUR"
                        };
                        //step 2 - send request
                        RpcResponse testResponse = Task.Run(async() => await RpcCurrencyConverter.GetRpcResult(request)).Result;
                        //step 3 - read response
                        double exchangeRate = testResponse.exchangeRate;

                        //ReservationInsert
                        var insert = new BsonDocument
                        {
                            { "CarID", reservationConsumed.CarID },
                            { "CategoryID", reservationConsumed.CategoryID },
                            { "LocationID", reservationConsumed.LocationID },
                            { "CustomerID", reservationConsumed.CustomerID },
                            // TODO get CurrencyExchangeRate from PALOS Microservice
                            { "Price", reservationConsumed.Price *exchangeRate },
                            { "CurrencyID", reservationConsumed.CurrencyID },
                            { "CurrencyExchangeRate", reservationConsumed.CurrencyExchangeRate },
                            { "StartDate", reservationConsumed.StartDate },
                            { "EndDate", reservationConsumed.EndDate }
                        };

                        coll.InsertOneAsync(insert);

                        DirectMessageToGateway ds = new DirectMessageToGateway();
                        ds.SendMessage(insert.ToString());
                        Console.WriteLine("inserted");
                    }
                    else if (routingKey.Equals("reservation.delete"))
                    {
                        string reservationId = JsonConvert.DeserializeObject <string>(Encoding.UTF8.GetString(body));

                        coll.DeleteOneAsync(reservationId);

                        DirectMessageToGateway ds = new DirectMessageToGateway();
                        ds.SendMessage("true");
                        Console.WriteLine("deleted");
                    }
                }
            }
        }
Пример #20
0
 public Task <T> SendRequestAsync <T>(RpcRequest request, string route = null)
 {
     return(ValidMethods.Contains(request.Method) ? _signer.SendRequestAsync <T>(request, route) : _fallback.SendRequestAsync <T>(request, route));
 }
Пример #21
0
        public override async Task InterceptSendRequestAsync(Func <RpcRequest, string, Task> interceptedSendRequestAsync, RpcRequest request, string route = null)
        {
            await State.TimeConstraint;

#if DEBUG
            Logger.WriteLine(Source.Misc, _type + ": " + request.Method);
#endif

            await base.InterceptSendRequestAsync(interceptedSendRequestAsync, request, route);
        }
Пример #22
0
        public override async Task <RpcResponse> InterceptSendRequestAsync(Func <RpcRequest, string, Task <RpcResponse> > interceptedSendRequestAsync, RpcRequest request, string route = null)
        {
            if (request.Method == "eth_accounts")
            {
                return(BuildResponse(new string[] { "hello", "hello2" }, route));
            }

            if (request.Method == "eth_getCode")
            {
                return(BuildResponse("the code", route));
            }
            return(await interceptedSendRequestAsync(request, route));
        }
Пример #23
0
        public override async Task <object> InterceptSendRequestAsync <T>(Func <RpcRequest, string, Task <T> > interceptedSendRequestAsync, RpcRequest request, string route = null)
        {
            await State.TimeConstraint;

            string additional = null;

            if (request.Method == "eth_getLogs")
            {
                await State.TimeConstraintLogs;
            }

            foreach (var requestRawParameter in request.RawParameters)
            {
                if (requestRawParameter is NewFilterInput raw)
                {
                    additional += " " + raw.FromBlock.BlockNumber + " to " + raw.ToBlock.BlockNumber + " on address " + raw.Address.FirstOrDefault();
                }
                else
                {
                }
            }

#if DEBUG
            Logger.WriteLine(Source.Misc, _type + ": " + request.Method + additional);
#endif

            object response;
            bool   hasFailedOnce = false;

start:
            try
            {
                response = await base.InterceptSendRequestAsync(interceptedSendRequestAsync, request, route);
            }
            catch (RpcResponseException ex) when(!hasFailedOnce)
            {
                hasFailedOnce = true;

                if (ex.Message.ToLower().Contains("internal"))
                {
                    await Task.Delay(250);

                    goto start;
                }

                throw;
            }



            return(response);
        }
Пример #24
0
        private void ProcessFrames(BinaryReader reader, ref int recvBytes, ref RpcFrame frame)
        {
            bool continueRead = false;

            do
            {
                if (frame == null && recvBytes >= 8)
                {
                    // Frame received
                    byte version      = reader.ReadByte();
                    byte reserved     = reader.ReadByte();
                    byte frameId      = reader.ReadByte();
                    byte protocolCode = reader.ReadByte();
                    int  bodyLen      = reader.ReadInt32();

                    if (version == 1 && reserved == 0 && protocolCode == 0)
                    {
                        if (bodyLen >= 0 && bodyLen <= MAX_BODY_SIZE)
                        {
                            frame         = new RpcFrame();
                            frame.FrameId = frameId;
                            frame.BodyLen = bodyLen;
                        }
                        else
                        {
                            // Invalid header
                        }
                    }
                    else
                    {
                        // Invalid header, close the connection
                    }

                    recvBytes   -= 8;
                    continueRead = true;
                }

                if (frame != null)
                {
                    if (frame.BodyLen == 0)
                    {
                        frame        = null; // Start reading of next frame
                        continueRead = true;
                    }
                    else if (recvBytes >= frame.BodyLen)
                    {
                        // Frame body received

                        byte[] frameBody = reader.ReadBytes(frame.BodyLen);

                        MessagePackSerializer <RpcMessage> serializer = _serverContext.SerializationContext.Serializer;
                        RpcRequest request = (RpcRequest)serializer.UnpackSingleObject(frameBody);

                        ChannelRequest channelRequest = new ChannelRequest(this, frame.FrameId, request);

                        _serverContext.RequestDispatcher.DispatchRequest(channelRequest);

                        recvBytes   -= frame.BodyLen;
                        frame        = null; // Start reading of next frame
                        continueRead = true;
                    }
                }
            }while (continueRead);
        }
Пример #25
0
        private async Task <ReturnT> InvokeRpcService(string methodName, List <object> parameterTypes,
                                                      object parameters, bool polling = false)
        {
            var request = new RpcRequest {
                RequestId        = Guid.NewGuid().ToString("N"),
                CreateMillisTime = DateTime.Now.GetTotalMilliseconds(),
                AccessToken      = this._options.AccessToken,
                ClassName        = "com.xxl.job.core.biz.AdminBiz",
                MethodName       = methodName,
                ParameterTypes   = parameterTypes,
                Parameters       = new List <object> {
                    parameters
                }
            };

            byte[] postBuf;
            using (var stream = new MemoryStream())
            {
                HessianSerializer.SerializeRequest(stream, request);

                postBuf = stream.ToArray();
            }

            var triedTimes = 0;
            var retList    = new List <ReturnT>();

            using (var client = this._clientFactory.CreateClient(Constants.DefaultHttpClientName))
            {
                while (triedTimes++ < this._addresses.Count)
                {
                    var address = this._addresses[this._currentIndex];
                    this._currentIndex = (this._currentIndex + 1) % this._addresses.Count;
                    if (!address.CheckAccessible())
                    {
                        continue;
                    }

                    Stream resStream;
                    try
                    {
                        resStream = await DoPost(client, address, postBuf);

                        address.Reset();
                    }
                    catch (Exception ex)
                    {
                        this._logger.LogError(ex, "request admin error.{0}", ex.Message);
                        address.SetFail();
                        continue;
                    }

                    RpcResponse res = null;
                    try
                    {
                        /*
                         * using (StreamReader reader = new StreamReader(resStream))
                         * {
                         * string content  = await reader.ReadToEndAsync();
                         *
                         * this._logger.LogWarning(content);
                         * }
                         */
                        res = HessianSerializer.DeserializeResponse(resStream);
                    }
                    catch (Exception ex)
                    {
                        this._logger.LogError(ex, "DeserializeResponse error:{errorMessage}", ex.Message);
                    }

                    if (res == null)
                    {
                        retList.Add(ReturnT.Failed("response is null"));
                    }
                    else if (res.IsError)
                    {
                        retList.Add(ReturnT.Failed(res.ErrorMsg));
                    }
                    else if (res.Result is ReturnT ret)
                    {
                        retList.Add(ret);
                    }
                    else
                    {
                        retList.Add(ReturnT.Failed("response is null"));
                    }

                    if (!polling)
                    {
                        return(retList[0]);
                    }
                }

                if (retList.Count > 0)
                {
                    return(retList.Last());
                }
            }
            throw new Exception("xxl-rpc server address not accessible.");
        }
Пример #26
0
 public override Task HandleAsync(RpcRequest rpcRequest) => SendRequest <object>(rpcRequest);
Пример #27
0
        /// <summary>
        /// Finds the matching Rpc method for the current request
        /// </summary>
        /// <param name="path">Rpc route for the current request</param>
        /// <param name="request">Current Rpc request</param>
        /// <param name="parameterList">Parameter list parsed from the request</param>
        /// <param name="serviceProvider">(Optional)IoC Container for rpc method controllers</param>
        /// <returns>The matching Rpc method to the current request</returns>
        private RpcMethodInfo GetMatchingMethod(RpcPath path, RpcRequest request, IRpcRouteProvider routeProvider, IServiceProvider serviceProvider)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            this.logger?.LogDebug($"Attempting to match Rpc request to a method '{request.Method}'");
            List <MethodInfo> allMethods = this.GetRpcMethods(path, routeProvider);

            //Case insenstive check for hybrid approach. Will check for case sensitive if there is ambiguity
            var requestMethodName = this.convertSnakeCaseToCamelCase ? this.ConvertSnakeCaseToCamelCase(request.Method) : request.Method;
            List <MethodInfo> methodsWithSameName = allMethods
                                                    .Where(m => string.Equals(m.Name, requestMethodName, StringComparison.OrdinalIgnoreCase))
                                                    .ToList();

            var potentialMatches = new List <RpcMethodInfo>();

            foreach (MethodInfo method in methodsWithSameName)
            {
                (bool isMatch, RpcMethodInfo methodInfo) = this.HasParameterSignature(method, request);
                if (isMatch)
                {
                    potentialMatches.Add(methodInfo);
                }
            }

            if (potentialMatches.Count > 1)
            {
                //Try to remove ambiguity with 'perfect matching' (usually optional params and types)
                List <RpcMethodInfo> exactMatches = potentialMatches
                                                    .Where(p => p.HasExactParameterMatch())
                                                    .ToList();
                if (exactMatches.Any())
                {
                    potentialMatches = exactMatches;
                }
                if (potentialMatches.Count > 1)
                {
                    //Try to remove ambiguity with case sensitive check
                    potentialMatches = potentialMatches
                                       .Where(m => string.Equals(m.Method.Name, requestMethodName, StringComparison.Ordinal))
                                       .ToList();
                    if (potentialMatches.Count != 1)
                    {
                        this.logger?.LogError("More than one method matched the rpc request. Unable to invoke due to ambiguity.");
                        throw new RpcMethodNotFoundException();
                    }
                }
            }

            RpcMethodInfo rpcMethod = null;

            if (potentialMatches.Count == 1)
            {
                rpcMethod = potentialMatches.First();
            }

            if (rpcMethod == null)
            {
                //Log diagnostics
                string methodsString = string.Join(", ", allMethods.Select(m => m.Name));
                this.logger?.LogTrace("Methods in route: " + methodsString);

                var methodInfoList = new List <string>();
                foreach (MethodInfo matchedMethod in methodsWithSameName)
                {
                    var parameterTypeList = new List <string>();
                    foreach (ParameterInfo parameterInfo in matchedMethod.GetParameters())
                    {
                        string parameterType = parameterInfo.Name + ": " + parameterInfo.ParameterType.Name;
                        if (parameterInfo.IsOptional)
                        {
                            parameterType += "(Optional)";
                        }
                        parameterTypeList.Add(parameterType);
                    }
                    string parameterString = string.Join(", ", parameterTypeList);
                    methodInfoList.Add($"{{Name: '{matchedMethod.Name}', Parameters: [{parameterString}]}}");
                }
                this.logger?.LogTrace("Methods that matched the same name: " + string.Join(", ", methodInfoList));
                this.logger?.LogError("No methods matched request.");
                throw new RpcMethodNotFoundException();
            }
            this.logger?.LogDebug("Request was matched to a method");
            return(rpcMethod);
        }
Пример #28
0
 public void doFilter(RpcRequest req)
 {
     //...限流逻辑...
 }
Пример #29
0
        /// <summary>
        /// Detects if list of parameters matches the method signature
        /// </summary>
        /// <param name="parameterList">Array of parameters for the method</param>
        /// <returns>True if the method signature matches the parameterList, otherwise False</returns>
        private (bool Matches, RpcMethodInfo MethodInfo) HasParameterSignature(MethodInfo method, RpcRequest rpcRequest)
        {
            object[] orignialParameterList;
            if (!rpcRequest.Parameters.HasValue)
            {
                orignialParameterList = new object[0];
            }
            else
            {
                switch (rpcRequest.Parameters.Type)
                {
                case RpcParametersType.Dictionary:
                    Dictionary <string, object> parameterMap = rpcRequest.Parameters.DictionaryValue;
                    bool canParse = this.TryParseParameterList(method, parameterMap, out orignialParameterList);
                    if (!canParse)
                    {
                        return(false, null);
                    }
                    break;

                case RpcParametersType.Array:
                    orignialParameterList = rpcRequest.Parameters.ArrayValue;
                    break;

                default:
                    orignialParameterList = new JToken[0];
                    break;
                }
            }
            ParameterInfo[] parameterInfoList = method.GetParameters();
            if (orignialParameterList.Length > parameterInfoList.Length)
            {
                return(false, null);
            }
            object[] correctedParameterList = new object[parameterInfoList.Length];

            for (int i = 0; i < orignialParameterList.Length; i++)
            {
                ParameterInfo parameterInfo = parameterInfoList[i];
                object        parameter     = orignialParameterList[i];
                bool          isMatch       = this.ParameterMatches(parameterInfo, parameter, out object convertedParameter);
                if (!isMatch)
                {
                    return(false, null);
                }
                correctedParameterList[i] = convertedParameter;
            }

            if (orignialParameterList.Length < parameterInfoList.Length)
            {
                //make a new array at the same length with padded 'missing' parameters (if optional)
                for (int i = orignialParameterList.Length; i < parameterInfoList.Length; i++)
                {
                    if (!parameterInfoList[i].IsOptional)
                    {
                        return(false, null);
                    }
                    correctedParameterList[i] = Type.Missing;
                }
            }

            var rpcMethodInfo = new RpcMethodInfo(method, correctedParameterList, orignialParameterList);

            return(true, rpcMethodInfo);
        }
Пример #30
0
 public override async Task <object> InterceptSendRequestAsync <TResponse>(
     Func <RpcRequest, string, Task <TResponse> > interceptedSendRequestAsync, RpcRequest request,
     string route = null)
 {
     if (request.Method == "eth_sendTransaction")
     {
         var transaction = (TransactionInput)request.RawParameters[0];
         return(await SignAndSendTransaction(transaction).ConfigureAwait(false));
     }
     return(await base.InterceptSendRequestAsync(interceptedSendRequestAsync, request, route).ConfigureAwait(false));
 }
Пример #31
0
        public override async Task <T> HandleAsyncWithResult <T>(RpcRequest rpcRequest)
        {
            var result = await SendRequest(rpcRequest).ConfigureAwait(false);

            return((T)result);
        }