private static TraceEventType GetTypeForRpcError( RpcError rpcError )
		{
			if ( 0 < rpcError.ErrorCode || rpcError.ErrorCode == -31 )
			{
				return TraceEventType.Warning;
			}

			switch ( rpcError.ErrorCode % 10 )
			{
				case -2:
				case -4:
				{
					return TraceEventType.Warning;
				}
				case -1:
				case -3:
				{
					return TraceEventType.Critical;
				}
				default:
				{
					return TraceEventType.Error;
				}
			}
		}
Exemple #2
0
 public RpcAnswer(Combinator answer)
 {
     Success = answer.Name != "rpc_error";
     if (Success)
         Combinator = answer;
     else
         Error = new RpcError(answer.Get<int>("error_code"), answer.Get<string>("error_message"));
 }
 public static void Assert(RpcError errorCode)
 {
     if (errorCode != RpcError.RPC_S_OK)
     {
         RpcException ex = new RpcException(errorCode);
         Log.Error("RpcError.{0} - {1}", errorCode, ex.Message);
         throw ex;
     }
 }
		private static int GetIdForRpcError( RpcError rpcError )
		{
			if ( 0 < rpcError.ErrorCode )
			{
				return 20000;
			}
			else
			{
				return 10000 + ( rpcError.ErrorCode * -1 );
			}
		}
 private static int GetIdForRpcError(RpcError rpcError)
 {
     if (0 < rpcError.ErrorCode)
     {
         return(20000);
     }
     else
     {
         return(10000 + (rpcError.ErrorCode * -1));
     }
 }
Exemple #6
0
        public RpcError abortCall(uint exceptionCode)
        {
            if (AsyncContextStatus.InProgress != status)
            {
                throw new InvalidOperationException(String.Format("Invalid operation, the current state = {0}.", status));
            }
            RpcError result = RpcApi.RpcAsyncAbortCall(asyncState, exceptionCode);

            status = AsyncContextStatus.Aborted;
            return(result);
        }
Exemple #7
0
        private static bool ServerUseProtseqEp(RpcProtseq protocol, int maxCalls, string endpoint)
        {
            RpcError errorCode = RpcServerApi.RpcServerUseProtseqEp(protocol.ToString(), maxCalls, endpoint, IntPtr.Zero);

            if (errorCode != RpcError.RPC_S_DUPLICATE_ENDPOINT)
            {
                RpcException.Assert(errorCode);
            }

            return(errorCode == RpcError.RPC_S_OK);
        }
Exemple #8
0
 /// <summary>
 ///		Gets the <see cref="RpcErrorMessage"/> corresponds to the specified <see cref="SocketError"/>.
 /// </summary>
 /// <param name="socketError">The <see cref="SocketError"/>.</param>
 /// <returns>
 ///		The <see cref="RpcErrorMessage"/> corresponds to the specified <see cref="SocketError"/>.
 /// </returns>
 public static RpcErrorMessage ToServerRpcError(this SocketError socketError)
 {
     if (socketError.IsError().GetValueOrDefault())
     {
         RpcError rpcError = socketError.ToRpcError();
         return(new RpcErrorMessage(rpcError, rpcError == RpcError.TransportError ? "Unexpected socket error." : rpcError.DefaultMessageInvariant, new SocketException(( int )socketError).Message));
     }
     else
     {
         return(RpcErrorMessage.Success);
     }
 }
Exemple #9
0
 public RpcAnswer(Combinator answer)
 {
     Success = answer.Name != "rpc_error";
     if (Success)
     {
         Combinator = answer;
     }
     else
     {
         Error = new RpcError(answer.Get <int>("error_code"), answer.Get <string>("error_message"));
     }
 }
Exemple #10
0
        private void btnPing_Click(object sender, EventArgs e)
        {
            IProtocol protocol = new TcpProtocol(tbOtherPeerUrl.Text, tbOtherPeerPort.Text.to_i());
            RpcError  err      = protocol.Ping(dht.Contact);

            if (err.HasError)
            {
                MessageBox.Show("Peer error: " + err.PeerErrorMessage + "\r\n" +
                                "Protocol error: " + err.ProtocolErrorMessage + "\r\n" +
                                "Timeout: " + err.TimeoutError, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private static bool ServerUseProtseqEp(RpcProtseq protocol, int maxCalls, String endpoint)
        {
            Log.Verbose("ServerUseProtseqEp({0})", protocol);
            RpcError err = RpcServerUseProtseqEp(protocol.ToString(), maxCalls, endpoint, IntPtr.Zero);

            if (err != RpcError.RPC_S_DUPLICATE_ENDPOINT)
            {
                RpcException.Assert(err);
            }

            return(err == RpcError.RPC_S_OK);
        }
        private static bool ServerRegisterAuthInfo(RpcAuthentication auth, string serverPrincName)
        {
            Log.Verbose("ServerRegisterAuthInfo({0})", auth);
            RpcError response = RpcServerRegisterAuthInfo(serverPrincName, (uint)auth, IntPtr.Zero, IntPtr.Zero);

            if (response != RpcError.RPC_S_OK)
            {
                Log.Warning("ServerRegisterAuthInfo - unable to register authentication type {0}", auth);
                return(false);
            }
            return(true);
        }
        private static void ServerListen(int maxCalls)
        {
            Log.Verbose("Begin Server Listening");
            RpcError result = RpcServerListen(1, maxCalls, 1);

            if (result == RpcError.RPC_S_ALREADY_LISTENING)
            {
                result = RpcError.RPC_S_OK;
            }
            RpcException.Assert(result);
            Log.Verbose("Server Ready");
        }
Exemple #14
0
        /// <summary>
        /// Add a contact if possible, based on the algorithm described
        /// in sections 2.2, 2.4 and 4.2
        /// </summary>
        public void AddContact(Contact contact)
        {
            Validate.IsFalse<OurNodeCannotBeAContactException>(ourID == contact.ID, "Cannot add ourselves as a contact!");
            contact.Touch();            // Update the LastSeen to now.

            lock (this)
            {
                KBucket kbucket = GetKBucket(contact.ID);

                if (kbucket.Contains(contact.ID))
                {
                    // Replace the existing contact, updating the network info and LastSeen timestamp.
                    kbucket.UpdateContactInfo(contact);
                }
                else if (kbucket.IsBucketFull)
                {
                    if (CanSplit(kbucket))
                    {
                        // Split the bucket and try again.
                        (KBucket k1, KBucket k2) = kbucket.Split();
                        int idx = GetKBucketIndex(contact.ID);
                        buckets[idx] = k1;
                        buckets.Insert(idx + 1, k2);
                        buckets[idx].Touch();
                        buckets[idx + 1].Touch();
                        AddContact(contact);
                    }
                    else
                    {
                        Contact lastSeenContact = kbucket.Contacts.OrderBy(c => c.LastSeen).First();
                        RpcError error = lastSeenContact.Protocol.Ping(ourContact);

                        if (error.HasError)
                        {
                            // Null continuation is used because unit tests may not initialize a DHT.
                            dht?.DelayEviction(lastSeenContact, contact);
                        }
                        else
                        {
                            // Still can't add the contact, so put it into the pending list.
                            dht?.AddToPending(contact);
                        }
                    }
                }
                else
                {
                    // Bucket isn't full, so just add the contact.
                    kbucket.AddContact(contact);
                    dht?.ContactAddedToBucket(kbucket, contact);
                }
            }
        }
        void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string topic   = e.Topic;
            string message = Encoding.UTF8.GetString(e.Message, 0, e.Message.Length);

            string[] splitTopic  = topic.Split('/');
            int      rpcActionId = int.Parse(splitTopic[splitTopic.Length - 1]);

            Hashtable deserializedObject = JsonSerializer.DeserializeString(message) as Hashtable;

            if (topic.StartsWith(RPC_REQUEST_TOPIC))
            {
                TBRpcRequest rpcRequest = new TBRpcRequest((string)deserializedObject["method"], deserializedObject["params"], rpcActionId);

                if (OnRpcRequestTopic != null)
                {
                    OnRpcRequestTopic(this, new RpcEventArgs(rpcRequest));
                }
            }
            else if (topic.StartsWith(RPC_RESPONSE_TOPIC))
            {
                string error = (string)deserializedObject["error"];


                if (error != null)
                {
                    RpcError rpcError = new RpcError(error, rpcActionId);

                    if (OnRpcError != null)
                    {
                        OnRpcError(this, new RpcEventArgs(rpcError));
                    }
                }
                else if (OnRpcResponseTopic != null)
                {
                    TBRpcResponse rpcResponse = new TBRpcResponse(rpcActionId);
                    OnRpcResponseTopic(this, new RpcEventArgs(rpcResponse));
                }
            }

            else if (topic == ATTRIBUTES_TOPIC)
            {
            }
            else if (topic.StartsWith(ATTRIBUTES_TOPIC_RESPONSE))
            {
                TBAttributesResponse tBAttributesResponse = new TBAttributesResponse(deserializedObject["client"], deserializedObject["shared"], rpcActionId);
                if (OnAttributesResponseTopic != null)
                {
                    OnAttributesResponseTopic(this, new RpcEventArgs(tBAttributesResponse));
                }
            }
        }
Exemple #16
0
        /// <summary>
        /// Put contact with an error into a collection and increment the number of times it has timed out.
        /// If it has timed out a certain amount, remove it from the bucket and replace it with the most
        /// recent pending contact that are queued for that bucket.
        /// </summary>
        public void HandleAnyError(RpcError error, Contact contact)
        {
            if (error.HasError)
            {
                // For all errors:
                int count = AddContactToEvict(contact.ID.Value);

                if (count == Constants.EVICTION_LIMIT)
                {
                    ReplaceContact(contact);
                }
            }
        }
Exemple #17
0
        // ======= ======= ======= ======= =======

        /// <summary>
        /// Someone is pinging us.  Register the contact and respond.
        /// </summary>
        public Contact Ping(Contact sender)
        {
            Validate.IsFalse <SendingQueryToSelfException>(sender.ID == ourContact.ID, "Sender should not be ourself!");
            // Not in spec...ping the sender to verify sender.
            RpcError err = sender.Protocol.PingBack(ourContact);

            if (!err.HasError)
            {
                SendKeyValuesIfNewContact(sender);
                bucketList.AddContact(sender);
            }

            return(ourContact);
        }
Exemple #18
0
        /// <summary>
        /// Converts an unknown caught exception into a Rpc response
        /// </summary>
        /// <param name="request">Current Rpc request</param>
        /// <param name="ex">Unknown exception</param>
        /// <returns>Rpc error response from the exception</returns>
        private RpcResponse GetUnknownExceptionReponse(RpcRequest request, Exception ex)
        {
            this.logger?.LogException(ex, "An unknown error occurred. Returning an Rpc error response");

            RpcUnknownException exception = new RpcUnknownException("An internal server error has occurred", ex);
            RpcError            error     = new RpcError(exception, this.serverConfig.Value.ShowServerExceptions);

            if (request?.Id == null)
            {
                return(null);
            }
            RpcResponse rpcResponse = new RpcResponse(request.Id, error);

            return(rpcResponse);
        }
        private static void ServerStopListening()
        {
            Log.Verbose("Stop Server Listening");
            RpcError result = RpcMgmtStopServerListening(IntPtr.Zero);

            if (result != RpcError.RPC_S_OK)
            {
                Log.Warning("RpcMgmtStopServerListening result = {0}", result);
            }
            result = RpcMgmtWaitServerListen();
            if (result != RpcError.RPC_S_OK)
            {
                Log.Warning("RpcMgmtWaitServerListen result = {0}", result);
            }
        }
Exemple #20
0
        private void WriteTranslatedError(RpcException ex)
        {
            RpcError errorCode = (RpcError)ex.ErrorCode;

            if (errorCode == RpcError.ServerUnavailable)
            {
                base.WriteError(new ServerUnavailableException(), ErrorCategory.ReadError, null);
                return;
            }
            if (errorCode != RpcError.EndpointNotRegistered)
            {
                base.WriteError(new Win32Exception(ex.ErrorCode), ErrorCategory.NotSpecified, null);
                return;
            }
            base.WriteError(new EndPointNotRegisteredException(), ErrorCategory.ReadError, null);
        }
Exemple #21
0
        public (bool found, List <Contact> contacts, string val) FindValue(ID key)
        {
            TouchBucketWithKey(key);

            string         ourVal;
            List <Contact> contactsQueried = new List <Contact>();

            (bool found, List <Contact> contacts, string val)ret = (false, null, null);

            if (originatorStorage.TryGetValue(key, out ourVal))
            {
                // Sort of odd that we are using the key-value store to find something the key-value that we originate.
                ret = (true, null, ourVal);
            }
            else if (republishStorage.TryGetValue(key, out ourVal))
            {
                // If we have it from another peer.
                ret = (true, null, ourVal);
            }
            else if (cacheStorage.TryGetValue(key, out ourVal))
            {
                // If we have it because it was cached.
                ret = (true, null, ourVal);
            }
            else
            {
                var lookup = router.Lookup(key, router.RpcFindValue);

                if (lookup.found)
                {
                    ret = (true, null, lookup.val);
                    // Find the first close contact (other than the one the value was found by) in which to *cache* the key-value.
                    var storeTo = lookup.contacts.Where(c => c != lookup.foundBy).OrderBy(c => c.ID ^ key).FirstOrDefault();

                    if (storeTo != null)
                    {
                        int      separatingNodes = GetSeparatingNodesCount(ourContact, storeTo);
                        int      expTimeSec      = (int)(Constants.EXPIRATION_TIME_SECONDS / Math.Pow(2, separatingNodes));
                        RpcError error           = storeTo.Protocol.Store(node.OurContact, key, lookup.val, true, expTimeSec);
                        HandleError(error, storeTo);
                    }
                }
            }

            return(ret);
        }
        private RpcResponseBase GetUnknownExceptionReponse(RpcRequest request, Exception ex)
        {
            this.Logger?.LogError("An unknown error occurred. Returning an Rpc error response", ex);
#if DEBUG
            string message = ex.Message;
#else
            string message = "An internal server error has occurred";
#endif
            RpcUnknownException exception = new RpcUnknownException(message);
            RpcError            error     = new RpcError(exception);
            if (request?.Id == null)
            {
                return(null);
            }
            RpcResponseBase rpcResponse = new RpcErrorResponse(request.Id, error);
            return(rpcResponse);
        }
Exemple #23
0
        /// <summary>
        ///		Initializes a new instance of the <see cref="RpcMethodInvocationException"/> class with a specified error message and a reference to the inner exception that is the cause of this exception.
        /// </summary>
        /// <param name="rpcError">
        ///		Metadata of error. If you specify null, <see cref="RpcError.CallError"/> is used.
        ///	</param>
        ///	<param name="methodName">
        ///		Name of method which is related to this error.
        ///	</param>
        /// <param name="message">
        ///		Error message to desribe condition. Note that this message should not include security related information.
        ///	</param>
        /// <param name="debugInformation">
        ///		Debug information of error.
        ///		This value can be null for security reason, and its contents are for developers, not end users.
        /// </param>
        /// <param name="inner">
        ///		Exception which caused this error.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///		<paramref name="methodName"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///		<paramref name="methodName"/> is empty or blank.
        /// </exception>
        /// <remarks>
        ///		<para>
        ///			For example, if some exception is occurred in server application,
        ///			the value of <see cref="Exception.ToString()"/> should specify for <paramref name="debugInformation"/>.
        ///			And then, user-friendly, safe message should be specified to <paramref name="message"/> like 'Internal Error."
        ///		</para>
        ///		<para>
        ///			MessagePack-RPC for CLI runtime does not propagate <see cref="RpcException.DebugInformation"/> for remote endpoint.
        ///			So you should specify some error handler to instrument it (e.g. logging handler).
        ///		</para>
        /// </remarks>
        public RpcMethodInvocationException(RpcError rpcError, string methodName, string message, string debugInformation, Exception inner)
            : base(rpcError ?? RpcError.CallError, message, debugInformation, inner)
        {
            if (methodName == null)
            {
                throw new ArgumentNullException(nameof(methodName));
            }

            if (string.IsNullOrWhiteSpace(methodName))
            {
                throw new ArgumentException("'methodName' cannot be empty nor blank.", nameof(methodName));
            }

            Contract.EndContractBlock();

            _methodName = methodName;
        }
Exemple #24
0
        private static String StringBindingCompose(RpcProtseq ProtSeq, String NetworkAddr, String Endpoint,
                                                   String Options)
        {
            IntPtr   lpBindingString;
            RpcError result = RpcStringBindingCompose(null, ProtSeq.ToString(), NetworkAddr, Endpoint, Options,
                                                      out lpBindingString);

            RpcException.Assert(result);

            try
            {
                return(Marshal.PtrToStringUni(lpBindingString));
            }
            finally
            {
                RpcException.Assert(RpcStringFree(ref lpBindingString));
            }
        }
        public async Task ShouldSerializeErrors()
        {
            var pipe = new Pipe(new PipeOptions());

            using var handler = NewHandler(pipe.Writer);

            var value = new RpcError(1, new ErrorMessage(1, "something", "data"));

            handler.Send(value);
            await handler.WriteAndFlush();

            using var reader = new StreamReader(pipe.Reader.AsStream());
            var received = await reader.ReadToEndAsync();

            const string send =
                "Content-Length: 76\r\n\r\n{\"seq\":1,\"type\":\"response\",\"request_seq\":1,\"success\":false,\"message\":\"data\"}";

            received.Should().Be(send);
        }
Exemple #26
0
        protected void OriginatorRepublishElapsed(object sender, ElapsedEventArgs e)
        {
            DateTime now = DateTime.Now;

            originatorStorage.Keys.Where(k => (now - originatorStorage.GetTimeStamp(k)).TotalMilliseconds >= Constants.ORIGINATOR_REPUBLISH_INTERVAL).ForEach(k =>
            {
                ID key = new ID(k);
                // Just use close contacts, don't do a lookup.
                var contacts = node.BucketList.GetCloseContacts(key, node.OurContact.ID);

                contacts.ForEach(c =>
                {
                    RpcError error = c.Protocol.Store(ourContact, key, originatorStorage.Get(key));
                    HandleError(error, c);
                });

                originatorStorage.Touch(k);
            });
        }
Exemple #27
0
        public RpcError completeCall(byte[] value, uint exceptionCode)
        {
            if (AsyncContextStatus.InProgress != status)
            {
                throw new InvalidOperationException(String.Format("Invalid operation, the current state = {0}.", status));
            }

            if (null != value)
            {
                // write output payload
                putOutput(value);
            }

            var      rt     = (IntPtr)exceptionCode;
            RpcError result = RpcApi.RpcAsyncCompleteCall(asyncState, ref rt);

            status = AsyncContextStatus.Completed;
            return(result);
        }
        public async Task ShouldSerializeErrors()
        {
            var pipe = new Pipe(new PipeOptions());

            using var handler = NewHandler(pipe.Writer);

            var value = new RpcError(1, new ErrorMessage(1, "something", new object()));


            handler.Send(value);
            await handler.WriteAndFlush();

            using var reader = new StreamReader(pipe.Reader.AsStream());
            var received = await reader.ReadToEndAsync();

            const string send =
                "Content-Length: 75\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":1,\"data\":{},\"message\":\"something\"}}";

            received.Should().Be(send);
        }
Exemple #29
0
 private void HandleExeption(Exception ex, RpcCallContext call)
 {
     if (ex is JsonRpcException)
     {
         call.Error = RpcError.FromException((JsonRpcException)ex);
     }
     else
     {
         if (this.exceptionHandlers.ContainsKey(ex.GetType()))
         {
             var handler = this.exceptionHandlers[ex.GetType()];
             call.Error = handler(ex);
         }
         else
         {
             this.logger.LogError(0, ex, ex.Message);
             call.Error = RpcError.FromException(new JsonRpcInternalErrorException(ex));
         }
     }
 }
Exemple #30
0
        private StartResults TryStartSyncNow()
        {
            int num = 3;

            while (num-- > 0)
            {
                try
                {
                    return(this.client.StartSyncNow(this.targetServer, this.forceFullSync, this.forceUpdateCookie));
                }
                catch (RpcException ex)
                {
                    RpcError errorCode = (RpcError)ex.ErrorCode;
                    if ((errorCode != RpcError.EndpointNotRegistered && errorCode != RpcError.RemoteDidNotExecute) || num == 0)
                    {
                        throw;
                    }
                }
            }
            return(StartResults.ErrorOnStart);
        }
        public void UnresponsiveNodeTest()
        {
            TcpSubnetProtocol p1 = new TcpSubnetProtocol(localIP, port, 1);
            TcpSubnetProtocol p2 = new TcpSubnetProtocol(localIP, port, 2);

            p2.Responds = false;
            ID      ourID = ID.RandomID;
            Contact c1    = new Contact(p1, ourID);
            Node    n1    = new Node(c1, new VirtualStorage());
            Node    n2    = new Node(new Contact(p2, ID.RandomID), new VirtualStorage());

            server.RegisterProtocol(p1.Subnet, n1);
            server.RegisterProtocol(p2.Subnet, n2);
            server.Start();

            ID       testID    = ID.RandomID;
            string   testValue = "Test";
            RpcError error     = p2.Store(c1, testID, testValue);

            Assert.IsTrue(error.TimeoutError, "Expected timeout.");
        }
        static RpcResult HandleRpcResult(BinaryReader br)
        {
            EnsureTypeNumber(br, RpcResultTypeNumber);
            var reqMsgId  = br.ReadInt64();
            var innerCode = PeekTypeNumber(br);

            switch (innerCode)
            {
            case RpcError.TypeNumber:
                EnsureTypeNumber(br, RpcError.TypeNumber);
                return(RpcError.DeserializeTag(br)
                       .Apply(RpcResultErrorHandler.ToException)
                       .Apply(exc => RpcResult.OfFail(reqMsgId, exc)));

            case GZipPackedTypeNumber:
                return(ReadGZipPacked(br).Apply(msgBr => RpcResult.OfSuccess(reqMsgId, msgBr)));

            default:
                return(RpcResult.OfSuccess(reqMsgId, br));
            }
        }
Exemple #33
0
        /// <summary>
        /// Perform a lookup if the bucket containing the key has not been refreshed,
        /// otherwise just get the contacts the k closest contacts we know about.
        /// </summary>
        protected void StoreOnCloserContacts(ID key, string val)
        {
            DateTime now = DateTime.Now;

            KBucket        kbucket = node.BucketList.GetKBucket(key);
            List <Contact> contacts;

            if ((now - kbucket.TimeStamp).TotalMilliseconds < Constants.BUCKET_REFRESH_INTERVAL)
            {
                // Bucket has been refreshed recently, so don't do a lookup as we have the k closes contacts.
                contacts = node.BucketList.GetCloseContacts(key, node.OurContact.ID);
            }
            else
            {
                contacts = router.Lookup(key, router.RpcFindNodes).contacts;
            }

            contacts.ForEach(c =>
            {
                RpcError error = c.Protocol.Store(node.OurContact, key, val);
                HandleError(error, c);
            });
        }
        static TraceEventType GetTypeForRpcError(RpcError rpcError)
        {
            if (0 < rpcError.ErrorCode || rpcError.ErrorCode == -31)
            {
                return(TraceEventType.Warning);
            }

            switch (rpcError.ErrorCode % 10)
            {
            case -2:
            case -4: {
                return(TraceEventType.Warning);
            }

            case -1:
            case -3: {
                return(TraceEventType.Critical);
            }

            default: {
                return(TraceEventType.Error);
            }
            }
        }
 /// <summary>
 ///		Initialize new sintance with unpacked data.
 /// </summary>
 /// <param name="rpcError">
 ///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
 ///	</param>
 /// <param name="message">
 ///		Exception data from remote MessagePack-RPC server.
 ///	</param>
 /// <exception cref="SerializationException">
 ///		Cannot deserialize instance from <paramref name="message"/>.
 /// </exception>
 internal RpcTransportException( RpcError rpcError, MessagePackObject message )
     : base(rpcError, message)
 {
 }
Exemple #36
0
 public RpcAnswer(RpcError error)
 {
     Success = false;
     Error = error;
 }
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcMethodInvocationException"/> class with the default error message.
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.CallError"/> is used.
		///	</param>
		///	<param name="methodName">
		///		Name of method which is related to this error.
		///	</param>
		/// <exception cref="ArgumentNullException">
		///		<paramref name="methodName"/> is null.
		/// </exception>
		/// <exception cref="ArgumentException">
		///		<paramref name="methodName"/> is empty or blank.
		/// </exception>
		public RpcMethodInvocationException( RpcError rpcError, string methodName ) : this( rpcError, methodName, null, null, null ) { }
Exemple #38
0
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcProtocolException"/> with unpacked data.
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
		///	</param>
		/// <param name="unpackedException">
		///		Exception data from remote MessagePack-RPC server.
		///	</param>
		/// <exception cref="SerializationException">
		///		Cannot deserialize instance from <paramref name="unpackedException"/>.
		/// </exception>
		internal RpcProtocolException( RpcError rpcError, MessagePackObject unpackedException ) : base( rpcError, unpackedException ) { }
 /// <summary>
 ///		Initialize new sintance with unpacked data.
 /// </summary>
 /// <param name="rpcError">
 ///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
 ///	</param>
 /// <param name="unpackedException">
 ///		Exception data from remote MessagePack-RPC server.
 ///	</param>
 /// <exception cref="SerializationException">
 ///		Cannot deserialize instance from <paramref name="unpackedException"/>.
 /// </exception>
 protected internal RpcMethodInvocationException( RpcError rpcError, MessagePackObject unpackedException )
     : base(rpcError, unpackedException)
 {
     MessagePackObjectDictionary.TryGetString( unpackedException, _methodNameKeyUtf8, message => new SerializationException( message ), out this._methodName );
 }
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcMethodInvocationException"/> class with a specified error message.
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.CallError"/> is used.
		///	</param>
		///	<param name="methodName">
		///		Name of method which is related to this error.
		///	</param>
		/// <param name="message">
		///		Error message to desribe condition. Note that this message should not include security related information.
		///	</param>
		/// <param name="debugInformation">
		///		Debug information of error.
		///		This value can be null for security reason, and its contents are for developers, not end users.
		/// </param>
		/// <exception cref="ArgumentNullException">
		///		<paramref name="methodName"/> is null.
		/// </exception>
		/// <exception cref="ArgumentException">
		///		<paramref name="methodName"/> is empty or blank.
		/// </exception>
		/// <remarks>
		///		<para>
		///			For example, if some exception is occurred in server application,
		///			the value of <see cref="Exception.ToString()"/> should specify for <paramref name="debugInformation"/>.
		///			And then, user-friendly, safe message should be specified to <paramref name="message"/> like 'Internal Error."
		///		</para>
		///		<para>
		///			MessagePack-RPC for CLI runtime does not propagate <see cref="RpcException.DebugInformation"/> for remote endpoint.
		///			So you should specify some error handler to instrument it (e.g. logging handler).
		///		</para>
		/// </remarks>
		public RpcMethodInvocationException( RpcError rpcError, string methodName, string message, string debugInformation )
			: this( rpcError, methodName, message, debugInformation, null ) { }
Exemple #41
0
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcTransportException"/> class with a specified error message and a reference to the inner exception that is the cause of this exception. 
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.TransportError"/> is used.
		///	</param>
		/// <param name="message">
		///		Error message to desribe condition. Note that this message should not include security related information.
		///	</param>
		/// <param name="debugInformation">
		///		Debug information of error.
		///		This value can be null for security reason, and its contents are for developers, not end users.
		/// </param>
		/// <param name="inner">
		///		Exception which caused this error.
		/// </param>
		/// <remarks>
		///		<para>
		///			For example, if some exception is occurred in server application,
		///			the value of <see cref="Exception.ToString()"/> should specify for <paramref name="debugInformation"/>.
		///			And then, user-friendly, safe message should be specified to <paramref name="message"/> like 'Internal Error."
		///		</para>
		///		<para>
		///			MessagePack-RPC for CLI runtime does not propagate <see cref="RpcException.DebugInformation"/> for remote endpoint.
		///			So you should specify some error handler to instrument it (e.g. logging handler).
		///		</para>
		/// </remarks>
		public RpcTransportException( RpcError rpcError, string message, string debugInformation, Exception inner ) : base( rpcError ?? RpcError.TransportError, message, debugInformation, inner ) { }
Exemple #42
0
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcProtocolException"/> class with a specified error message and a reference to the inner exception that is the cause of this exception. 
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
		///	</param>
		/// <param name="message">
		///		Error message to desribe condition. Note that this message should not include security related information.
		///	</param>
		/// <param name="debugInformation">
		///		Debug information of error.
		///		This value can be null for security reason, and its contents are for developers, not end users.
		/// </param>
		/// <param name="inner">
		///		Exception which caused this error.
		/// </param>
		/// <remarks>
		///		<para>
		///			For example, if some exception is occurred in server application,
		///			the value of <see cref="Exception.ToString()"/> should specify for <paramref name="debugInformation"/>.
		///			And then, user-friendly, safe message should be specified to <paramref name="message"/> like 'Internal Error."
		///		</para>
		///		<para>
		///			MessagePack-RPC for CLI runtime does not propagate <see cref="RpcException.DebugInformation"/> for remote endpoint.
		///			So you should specify some error handler to instrument it (e.g. logging handler).
		///		</para>
		/// </remarks>
		public RpcProtocolException( RpcError rpcError, string message, string debugInformation, Exception inner ) : base( rpcError, message, debugInformation, inner ) { }
Exemple #43
0
		/// <summary>
		/// Converts an unknown caught exception into a Rpc response
		/// </summary>
		/// <param name="request">Current Rpc request</param>
		/// <param name="ex">Unknown exception</param>
		/// <returns>Rpc error response from the exception</returns>
		private RpcResponse GetUnknownExceptionReponse(RpcRequest request, Exception ex)
		{
			this.logger?.LogException(ex, "An unknown error occurred. Returning an Rpc error response");

			RpcUnknownException exception = new RpcUnknownException("An internal server error has occurred", ex);
			RpcError error = new RpcError(exception, this.serverConfig.Value.ShowServerExceptions);
			if (request?.Id == null)
			{
				return null;
			}
			RpcResponse rpcResponse = new RpcResponse(request.Id, error);
			return rpcResponse;
		}
 /// <summary>
 ///		Initialize new instance which represents specified error.
 /// </summary>
 /// <param name="rpcError">
 ///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
 ///	</param>
 ///	<param name="methodName">
 ///		Name of method which is related to this error.
 ///	</param>
 /// <exception cref="ArgumentNullException">
 ///		<paramref name="methodName"/> is null.
 /// </exception>
 /// <exception cref="ArgumentException">
 ///		<paramref name="methodName"/> is empty or blank.
 /// </exception>
 public RpcMethodInvocationException( RpcError rpcError, string methodName )
     : this(rpcError, methodName, "Failed to call specified method.", null)
 {
 }
 /// <summary>
 ///		Initialize new instance which represents specified error.
 /// </summary>
 /// <param name="rpcError">
 ///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
 ///	</param>
 public RpcProtocolException( RpcError rpcError )
     : this(rpcError, "Some protocol violation is occurred in MessagePack-RPC communication.", null)
 {
 }
Exemple #46
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;
		}
		/// <summary>
		///		Initialize new instance with unpacked data.
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="MsgPack.Rpc.RpcError.RemoteRuntimeError"/> is used.
		///	</param>
		/// <param name="unpackedException">
		///		Exception data from remote MessagePack-RPC server.
		///	</param>
		/// <exception cref="SerializationException">
		///		Cannot deserialize instance from <paramref name="unpackedException"/>.
		/// </exception>
		protected internal RpcMethodInvocationException( RpcError rpcError, MessagePackObject unpackedException )
			: base( rpcError, unpackedException )
		{
			this._methodName = unpackedException.GetString( MethodNameKeyUtf8 );
			Contract.Assume( this._methodName != null, "Unpacked data does not have MethodName." );
		}
			public void OnConnectError( RpcError rpcError, Exception exception, bool completedSynchronously, object asyncState )
			{
				Contract.Assume( exception != null );

				var lastError = new RpcProtocolException( rpcError, exception.Message, null, exception );
				if ( completedSynchronously )
				{
					throw lastError;
				}
				else
				{
					var pool = asyncState as ConnectionPool;
					// TODO: trace
					try { }
					finally
					{
						if ( !pool._statusTable.TryUpdate( this._context, LeaseStatus.Error, LeaseStatus.Initializing ) )
						{
							throw new InvalidOperationException( "ConectionPool is in inconsistent state. Initialized socket is not ininitializing." );
						}

						if ( !pool._connectErrors.TryAdd( this._context, lastError ) )
						{
							throw new InvalidOperationException( "ConectionPool is in inconsistent state. Initialized socket is already in error." );
						}

						Interlocked.Decrement( ref pool._initializingSocketCount );
					}
				}

			}
 /// <summary>
 ///		Initialize new instance which represents specified error.
 /// </summary>
 /// <param name="rpcError">
 ///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
 ///	</param>
 public RpcTransportException( RpcError rpcError )
     : this(rpcError, "Some network error is occurred in MessagePack-RPC communication.", null)
 {
 }
Exemple #50
0
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcProtocolException"/> class with a specified error message.
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
		///	</param>
		/// <param name="message">
		///		Error message to desribe condition. Note that this message should not include security related information.
		///	</param>
		/// <param name="debugInformation">
		///		Debug information of error.
		///		This value can be null for security reason, and its contents are for developers, not end users.
		/// </param>
		/// <remarks>
		///		<para>
		///			For example, if some exception is occurred in server application,
		///			the value of <see cref="Exception.ToString()"/> should specify for <paramref name="debugInformation"/>.
		///			And then, user-friendly, safe message should be specified to <paramref name="message"/> like 'Internal Error."
		///		</para>
		///		<para>
		///			MessagePack-RPC for CLI runtime does not propagate <see cref="RpcException.DebugInformation"/> for remote endpoint.
		///			So you should specify some error handler to instrument it (e.g. logging handler).
		///		</para>
		/// </remarks>		
		public RpcProtocolException( RpcError rpcError, string message, string debugInformation ) : this( rpcError, message, debugInformation, null ) { }
 /// <summary>
 ///		Initialize new instance which represents specified error.
 /// </summary>
 /// <param name="rpcError">
 ///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
 ///	</param>
 /// <param name="message">
 ///		Error message to desribe condition. Note that this message should not include security related information.
 ///	</param>
 /// <param name="debugInformation">
 ///		Debug information of error.
 ///		This value can be null for security reason, and its contents are for developers, not end users.
 /// </param>
 /// <remarks>
 ///		<para>
 ///			For example, if some exception is occurred in server application,
 ///			the value of <see cref="Exception.ToString()"/> should specify for <paramref name="debugInformation"/>.
 ///			And then, user-friendly, safe message should be specified to <paramref name="message"/> like 'Internal Error."
 ///		</para>
 ///		<para>
 ///			MessagePack-RPC for CLI runtime does not propagate <see cref="RpcException.DebugInformation"/> for remote endpoint.
 ///			So you should specify some error handler to instrument it (e.g. logging handler).
 ///		</para>
 /// </remarks>		
 public RpcTransportException( RpcError rpcError, string message, string debugInformation )
     : base(rpcError, message, debugInformation)
 {
 }
 /// <summary>
 /// Exception class: RpcException : System.ComponentModel.Win32Exception
 /// Unspecified rpc error
 /// </summary>
 public RpcException(RpcError errorCode)
     : base(unchecked((int) errorCode))
 {
 }
		internal static void TraceRpcError( RpcError rpcError, string format, params object[] args )
		{
			_source.TraceEvent( GetTypeForRpcError( rpcError ), GetIdForRpcError( rpcError ), format, args );
		}
Exemple #54
0
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcTransportException"/> class with a specified error message.
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.TransportError"/> is used.
		///	</param>
		/// <param name="message">
		///		Error message to desribe condition. Note that this message should not include security related information.
		///	</param>
		/// <param name="debugInformation">
		///		Debug information of error.
		///		This value can be null for security reason, and its contents are for developers, not end users.
		/// </param>
		/// <remarks>
		///		<para>
		///			For example, if some exception is occurred in server application,
		///			the value of <see cref="Exception.ToString()"/> should specify for <paramref name="debugInformation"/>.
		///			And then, user-friendly, safe message should be specified to <paramref name="message"/> like 'Internal Error."
		///		</para>
		///		<para>
		///			MessagePack-RPC for CLI runtime does not propagate <see cref="RpcException.DebugInformation"/> for remote endpoint.
		///			So you should specify some error handler to instrument it (e.g. logging handler).
		///		</para>
		/// </remarks>		
		public RpcTransportException( RpcError rpcError, string message, string debugInformation ) : this( rpcError, message, debugInformation, null ) { }
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcMethodInvocationException"/> class with a specified error message and a reference to the inner exception that is the cause of this exception. 
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.CallError"/> is used.
		///	</param>
		///	<param name="methodName">
		///		Name of method which is related to this error.
		///	</param>
		/// <param name="message">
		///		Error message to desribe condition. Note that this message should not include security related information.
		///	</param>
		/// <param name="debugInformation">
		///		Debug information of error.
		///		This value can be null for security reason, and its contents are for developers, not end users.
		/// </param>
		/// <param name="inner">
		///		Exception which caused this error.
		/// </param>
		/// <exception cref="ArgumentNullException">
		///		<paramref name="methodName"/> is null.
		/// </exception>
		/// <exception cref="ArgumentException">
		///		<paramref name="methodName"/> is empty or blank.
		/// </exception>
		/// <remarks>
		///		<para>
		///			For example, if some exception is occurred in server application,
		///			the value of <see cref="Exception.ToString()"/> should specify for <paramref name="debugInformation"/>.
		///			And then, user-friendly, safe message should be specified to <paramref name="message"/> like 'Internal Error."
		///		</para>
		///		<para>
		///			MessagePack-RPC for CLI runtime does not propagate <see cref="RpcException.DebugInformation"/> for remote endpoint.
		///			So you should specify some error handler to instrument it (e.g. logging handler).
		///		</para>
		/// </remarks>
		public RpcMethodInvocationException( RpcError rpcError, string methodName, string message, string debugInformation, Exception inner )
			: base( rpcError ?? RpcError.CallError, message, debugInformation, inner )
		{
			if ( methodName == null )
			{
				throw new ArgumentNullException( "methodName" );
			}

			if ( String.IsNullOrWhiteSpace( methodName ) )
			{
				throw new ArgumentException( "'methodName' cannot be empty nor blank.", "methodName" );
			}

			Contract.EndContractBlock();

			this._methodName = methodName;
		}
 /// <summary>
 /// Turns result data into a rpc response
 /// </summary>
 /// <param name="id">Rpc request id</param>
 /// <param name="serializer">Json serializer function to use for objects for the response</param>
 /// <returns>Rpc response for request</returns>
 public RpcResponse ToRpcResponse(object id, Func<object, JToken> serializer)
 {
     JToken data = this.Data == null ? null : serializer(this.Data);
     RpcError error = new RpcError(this.ErrorCode, this.Message, data);
     return new RpcResponse(id, error);
 }
Exemple #57
0
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcTransportException"/> class with the default error message.
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.TransportError"/> is used.
		///	</param>
		public RpcTransportException( RpcError rpcError ) : this( rpcError, null, null, null ) { }
Exemple #58
0
		/// <summary>
		///		Initializes a new instance of the <see cref="RpcProtocolException"/> class with the default error message.
		/// </summary>
		/// <param name="rpcError">
		///		Metadata of error. If you specify null, <see cref="RpcError.RemoteRuntimeError"/> is used.
		///	</param>
		public RpcProtocolException( RpcError rpcError ) : this( rpcError, null, null, null ) { }