Example #1
0
        private async Task SendReplyAsync(
            ulong conversationId, IMessage response, ILayerStack layerStack, RequestMetrics requestMetrics)
        {
            var sendContext = new EpoxySendContext(this, ConnectionMetrics, requestMetrics);

            IBonded layerData;
            Error   layerError = LayerStackUtils.ProcessOnSend(
                layerStack, MessageType.RESPONSE, sendContext, out layerData, logger);

            // If there was a layer error, replace the response with the layer error
            if (layerError != null)
            {
                logger.Site().Error("{0} Sending reply for conversation ID {1} failed due to layer error (Code: {2}, Message: {3}).",
                                    this, conversationId, layerError.error_code, layerError.message);

                // Set layer error as result of this Bond method call, replacing original response.
                // Since this error will be returned to client, cleanse out internal server error details, if any.
                response = Message.FromError(Errors.CleanseInternalServerError(layerError));
            }

            var frame = MessageToFrame(conversationId, null, null, EpoxyMessageType.RESPONSE, response, layerData, logger);

            logger.Site().Debug("{0} Sending reply for conversation ID {1}.", this, conversationId);

            bool wasSent = await SendFrameAsync(frame);

            logger.Site().Debug("{0} Sending reply for conversation ID {1} {2}.",
                                this, conversationId, wasSent ? "succeedeed" : "failed");
        }
Example #2
0
        internal void SendReply(ulong conversationId,
                                IMessage response,
                                TaskCompletionSource <IMessage> taskSource,
                                ILayerStack layerStack,
                                InMemFrameQueue queue)
        {
            var     requestMetrics = Metrics.StartRequestMetrics(connection.ConnectionMetrics);
            var     sendContext    = new SimpleInMemSendContext(connection, connection.ConnectionMetrics, requestMetrics);
            IBonded layerData      = null;

            Error layerError = LayerStackUtils.ProcessOnSend(layerStack, MessageType.RESPONSE, sendContext, out layerData, logger);

            // If there was a layer error, replace the response with the layer error
            if (layerError != null)
            {
                logger.Site().Error("Sending reply for conversation {0} failed due to layer error (Code: {1}, Message: {2}).",
                                    conversationId, layerError.error_code, layerError.message);

                // Set layer error as result of this Bond method call, replacing original response.
                // Since this error will be returned to client, cleanse out internal server error details, if any.
                response = Message.FromError(Errors.CleanseInternalServerError(layerError));
            }

            var payload = Util.NewPayLoad(conversationId, SimpleInMemMessageType.RESPONSE, layerData, response, taskSource);

            queue.Enqueue(payload);
        }
Example #3
0
        private State?DispatchRequest(EpoxyHeaders headers, EpoxyProtocol.MessageData messageData, ArraySegment <byte> layerData)
        {
            Task.Run(async() =>
            {
                var totalTime      = Stopwatch.StartNew();
                var requestMetrics = Metrics.StartRequestMetrics(ConnectionMetrics);
                var receiveContext = new EpoxyReceiveContext(this, ConnectionMetrics, requestMetrics);

                ILayerStack layerStack = null;

                IMessage result;

                if (messageData.IsError)
                {
                    logger.Site().Error("{0} Received request with an error message. Only payload messages are allowed. Conversation ID: {1}",
                                        this, headers.conversation_id);
                    result = Message.FromError(new Error
                    {
                        error_code = (int)ErrorCode.INVALID_INVOCATION,
                        message    = "Received request with an error message"
                    });
                }
                else
                {
                    IMessage request        = Message.FromPayload(Unmarshal.From(messageData.Data));
                    IBonded bondedLayerData = (layerData.Array == null) ? null : Unmarshal.From(layerData);

                    Error layerError = parentTransport.GetLayerStack(requestMetrics.request_id, out layerStack);

                    if (layerError == null)
                    {
                        layerError = LayerStackUtils.ProcessOnReceive(
                            layerStack, MessageType.REQUEST, receiveContext, bondedLayerData, logger);
                    }

                    if (layerError == null)
                    {
                        result = await serviceHost.DispatchRequest(headers.service_name, headers.method_name, receiveContext, request);
                    }
                    else
                    {
                        logger.Site().Error("{0} Receiving request {1}/{2}.{3} failed due to layer error (Code: {4}, Message: {5}).",
                                            this, headers.conversation_id, headers.service_name, headers.method_name,
                                            layerError.error_code, layerError.message);

                        // Set layer error as result of this Bond method call and do not dispatch to method.
                        // Since this error will be returned to client, cleanse out internal server error details, if any.
                        result = Message.FromError(Errors.CleanseInternalServerError(layerError));
                    }
                }

                await SendReplyAsync(headers.conversation_id, result, layerStack, requestMetrics);
                Metrics.FinishRequestMetrics(requestMetrics, totalTime);
                metrics.Emit(requestMetrics);
            });

            // no state change needed
            return(null);
        }
Example #4
0
 public override Error GetLayerStack(string uniqueId, out ILayerStack stack)
 {
     if (layerStackProvider != null)
     {
         return(layerStackProvider.GetLayerStack(uniqueId, out stack));
     }
     stack = null;
     return(null);
 }
Example #5
0
 public override Error GetLayerStack(out ILayerStack stack)
 {
     if (layerStackProvider != null)
     {
         return(layerStackProvider.GetLayerStack(out stack));
     }
     else
     {
         stack = null;
         return(null);
     }
 }
Example #6
0
 public Error GetLayerStack(out ILayerStack layerStack)
 {
     if (failAfterGets == 0)
     {
         layerStack = null;
         return(Errors.MakeInternalServerError(InternalDetails));
     }
     else
     {
         failAfterGets--;
         layerStack = new LayerStack <Dummy>(LoggerTests.BlackHole, new TestLayer_StatefulAppend("foo"));
         return(null);
     }
 }
 public Error GetLayerStack(string uniqueId, out ILayerStack layerStack, Logger logger)
 {
     if (failAfterGets == 0)
     {
         layerStack = null;
         return(Errors.MakeInternalServerError(InternalDetails, uniqueId));
     }
     else
     {
         failAfterGets--;
         layerStack = new LayerStack <Dummy>(new TestLayer_StatefulAppend("foo"));
         return(null);
     }
 }
Example #8
0
        void DispatchResponse(EpoxyHeaders headers, EpoxyProtocol.MessageData messageData, ArraySegment <byte> layerData)
        {
            IMessage response = messageData.IsError
                ? Message.FromError(Unmarshal <Error> .From(messageData.Data))
                : Message.FromPayload(Unmarshal.From(messageData.Data));

            TaskCompletionSource <IMessage> tcs = responseMap.TakeTaskCompletionSource(headers.conversation_id);

            if (tcs == null)
            {
                logger.Site().Error(
                    "{0} Response for unmatched request. Conversation ID: {1}",
                    this,
                    headers.conversation_id);
                return;
            }

            Task.Run(
                () =>
            {
                var totalTime      = Stopwatch.StartNew();
                var requestMetrics = Metrics.StartRequestMetrics(ConnectionMetrics);
                var receiveContext = new RelayEpoxyReceiveContext(this, ConnectionMetrics, requestMetrics);

                IBonded bondedLayerData = (layerData.Array == null) ? null : Unmarshal.From(layerData);

                ILayerStack layerStack = tcs.Task.AsyncState as ILayerStack;

                Error layerError = LayerStackUtils.ProcessOnReceive(layerStack, MessageType.RESPONSE, receiveContext, bondedLayerData, logger);

                if (layerError != null)
                {
                    logger.Site().Error(
                        "{0} Receiving response {1}/{2}.{3} failed due to layer error (Code: {4}, Message: {5}).",
                        this,
                        headers.conversation_id,
                        headers.service_name,
                        headers.method_name,
                        layerError.error_code,
                        layerError.message);
                    response = Message.FromError(layerError);
                }

                tcs.SetResult(response);
                Metrics.FinishRequestMetrics(requestMetrics, totalTime);
                metrics.Emit(requestMetrics);
            });
        }
Example #9
0
        public static Error ProcessOnSend(
            ILayerStack layerStack, MessageType messageType, SendContext sendContext, out IBonded layerData, Logger logger)
        {
            Error error = null;
            layerData = null;

            if (layerStack != null)
            {
                error = layerStack.OnSend(messageType, sendContext, out layerData);
                if (error != null)
                {
                    logger.Site().Warning("Layer error occurred sending message of type {0} (Code: {1} Message: {2}).",
                        messageType, error.error_code, error.message);
                }
            }

            return error;
        }
Example #10
0
        public static Error ProcessOnSend(ILayerStack layerStack, MessageType messageType, SendContext sendContext, out IBonded layerData)
        {
            Error error = null;

            layerData = null;

            if (layerStack != null)
            {
                error = layerStack.OnSend(messageType, sendContext, out layerData);
                if (error != null)
                {
                    Log.Warning("{0}.{1}: Layer error occurred sending message of type {2} (Code: {3} Message: {4}).",
                                nameof(LayerStackUtils), nameof(ProcessOnSend), messageType, error.error_code, error.message);
                }
            }

            return(error);
        }
        public static Error ProcessOnSend(
            ILayerStack layerStack, MessageType messageType, SendContext sendContext, out IBonded layerData, Logger logger)
        {
            Error error = null;

            layerData = null;

            if (layerStack != null)
            {
                error = layerStack.OnSend(messageType, sendContext, out layerData, logger);
                if (error != null)
                {
                    logger.Site().Warning("Layer error occurred sending message of type {0} (Code: {1} Message: {2}).",
                                          messageType, error.error_code, error.message);
                }
            }

            return(error);
        }
Example #12
0
        private void DispatchResponse(EpoxyHeaders headers, ArraySegment <byte> payload, ArraySegment <byte> layerData)
        {
            IMessage response;

            if (headers.error_code != (int)ErrorCode.OK)
            {
                response = Message.FromError(Unmarshal <Error> .From(payload));
            }
            else
            {
                response = Message.FromPayload(Unmarshal.From(payload));
            }

            TaskCompletionSource <IMessage> tcs = responseMap.TakeTaskCompletionSource(headers.conversation_id);

            if (tcs == null)
            {
                logger.Site().Error("{0} Response for unmatched request. Conversation ID: {1}",
                                    this, headers.conversation_id);
                return;
            }

            Task.Run(() =>
            {
                var receiveContext = new EpoxyReceiveContext(this);

                IBonded bondedLayerData = (layerData.Array == null) ? null : Unmarshal.From(layerData);

                ILayerStack layerStack = tcs.Task.AsyncState as ILayerStack;

                Error layerError = LayerStackUtils.ProcessOnReceive(layerStack, MessageType.Response, receiveContext, bondedLayerData, logger);

                if (layerError != null)
                {
                    logger.Site().Error("{0} Receiving response {1}/{2} failed due to layer error (Code: {3}, Message: {4}).",
                                        this, headers.conversation_id, headers.method_name,
                                        layerError.error_code, layerError.message);
                    response = Message.FromError(layerError);
                }

                tcs.SetResult(response);
            });
        }
Example #13
0
        private void DispatchResponse(InMemFrame payload)
        {
            var receiveContext = new SimpleInMemReceiveContext(connection);
            var headers        = payload.headers;
            var layerData      = payload.layerData;
            var message        = payload.message;
            var taskSource     = payload.outstandingRequest;

            ILayerStack layerStack = taskSource.Task.AsyncState as ILayerStack;

            Error layerError = LayerStackUtils.ProcessOnReceive(layerStack, MessageType.Response, receiveContext, layerData, logger);

            if (layerError != null)
            {
                logger.Site().Error("Receiving response {0}/{1} failed due to layer error (Code: {2}, Message: {3}).",
                                    headers.conversation_id, headers.method_name, layerError.error_code, layerError.message);
                message = Message.FromError(layerError);
            }

            payload.outstandingRequest.SetResult(message);
        }
Example #14
0
        public static Error ProcessOnReceive(ILayerStack layerStack, MessageType messageType, ReceiveContext receiveContext, IBonded layerData)
        {
            Error error = null;

            if (layerStack != null)
            {
                if (layerData == null)
                {
                    Log.Warning("{0}.{1}: Layer stack present but no layer data received.", nameof(LayerStackUtils), nameof(ProcessOnReceive));
                }

                error = layerStack.OnReceive(messageType, receiveContext, layerData);

                if (error != null)
                {
                    Log.Warning("{0}.{1}: Layer error occurred receiving message of type {2} (Code: {3} Message: {4}).",
                                nameof(LayerStackUtils), nameof(ProcessOnReceive), messageType, error.error_code, error.message);
                }
            }
            return(error);
        }
        public static Error ProcessOnReceive(
            ILayerStack layerStack, MessageType messageType, ReceiveContext receiveContext, IBonded layerData, Logger logger)
        {
            Error error = null;

            if (layerStack != null)
            {
                if (layerData == null)
                {
                    logger.Site().Warning("Layer stack present but no layer data received.");
                }

                error = layerStack.OnReceive(messageType, receiveContext, layerData, logger);

                if (error != null)
                {
                    logger.Site().Warning("Layer error occurred receiving message of type {0} (Code: {1} Message: {2}).",
                                          messageType, error.error_code, error.message);
                }
            }
            return(error);
        }
Example #16
0
        public static Error ProcessOnReceive(
            ILayerStack layerStack, MessageType messageType, ReceiveContext receiveContext, IBonded layerData, Logger logger)
        {
            Error error = null;

            if (layerStack != null)
            {
                if (layerData == null)
                {
                    logger.Site().Warning("Layer stack present but no layer data received.");
                }

                error = layerStack.OnReceive(messageType, receiveContext, layerData);

                if (error != null)
                {
                    logger.Site().Warning("Layer error occurred receiving message of type {0} (Code: {1} Message: {2}).",
                        messageType, error.error_code, error.message);
                }
            }
            return error;
        }
Example #17
0
        public Error GetLayerStack(string uniqueId, out ILayerStack stack)
        {
            Error error = null;

            if (cachedLayerStack != null)
            {
                stack = cachedLayerStack;
            }
            else
            {
                var layers = new ILayer <TLayerData> [layerProviders.Length];
                for (int i = 0; i < layerProviders.Length; i++)
                {
                    try
                    {
                        layers[i] = layerProviders[i].GetLayer();
                        if (layers[i] == null)
                        {
                            error = Errors.MakeInternalServerError($"Layer provider {i} produced null layer", uniqueId);
                            logger.Site().Error(error.message);
                            layers = null;
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Site().Error(ex, "Layer provider {0} threw exception", i);
                        error  = Errors.MakeInternalServerError(ex, uniqueId, includeDetails: true);
                        layers = null;
                        break;
                    }
                }

                stack = error == null ? new LayerStack <TLayerData>(logger, layers) : null;
            }

            return(error);
        }
Example #18
0
        public Error GetLayerStack(out ILayerStack stack)
        {
            Error error = null;

            if (cachedLayerStack != null)
            {
                stack = cachedLayerStack;
            }
            else
            {
                ILayer <TLayerData>[] layers;
                error = GetNewLayers(out layers);
                if (error == null)
                {
                    stack = new LayerStack <TLayerData>(logger, layers);
                }
                else
                {
                    stack = null;
                }
            }

            return(error);
        }
Example #19
0
        public static async Task <TestClientServer <TService> > SetupTestClientServer <TService>(ILayerStack serviceLayerStack = null,
                                                                                                 ILayerStack clientLayerStack  = null) where TService : class, IService, new()
        {
            var testService = new TService();

            EpoxyTransport serviceTransport = new EpoxyTransportBuilder()
                                              .SetLayerStack(serviceLayerStack)
                                              .Construct();
            EpoxyListener listener = serviceTransport.MakeListener(new IPEndPoint(IPAddress.Loopback, 0));

            listener.AddService(testService);
            await listener.StartAsync();

            EpoxyTransport clientTransport = new EpoxyTransportBuilder()
                                             // some tests rely on the use of DebugExceptionHandler to assert things about the error message
                                             .SetLayerStack(clientLayerStack)
                                             .Construct();
            EpoxyConnection clientConnection = await clientTransport.ConnectToAsync(listener.ListenEndpoint);

            return(new TestClientServer <TService>
            {
                Service = testService,
                ServiceTransport = serviceTransport,
                Listener = listener,
                ClientConnection = clientConnection,
                ClientTransport = clientTransport
            });
        }
Example #20
0
 /// <summary>
 /// Set the layer stack.
 /// </summary>
 /// <param name="layerStack">The layer stack.</param>
 /// <returns>The builder.</returns>
 /// <remarks>
 /// The layer stack supplies the set of layers to be used
 /// by the built transport. May be null.
 /// </remarks>
 public virtual TransportBuilder <TTransport> SetLayerStack(ILayerStack layerStack)
 {
     LayerStack = layerStack;
     return(this);
 }
Example #21
0
 public EpoxyTransport(ILayerStack layerStack)
 {
     // Layer stack may be null
     this.layerStack = layerStack;
 }
Example #22
0
 /// <summary>
 /// Get a layer stack instance for this transport.
 /// </summary>
 /// <param name="uniqueId">A unique ID identifying the request or connection that triggered this call. Used in
 /// layer-originated errors.</param>
 /// <param name="stack">The layer stack instance. Will be null if an error is returned.</param>
 /// <returns>An error if one occurred, null otherwise.</returns>
 public abstract Error GetLayerStack(string uniqueId, out ILayerStack stack);
Example #23
0
 /// <summary>
 /// Get a layer stack instance for this transport.
 /// </summary>
 /// <param name="stack">The layer stack instance. Will be null if an error is returned.</param>
 /// <returns>An error if one occurred, null otherwise.</returns>
 public abstract Error GetLayerStack(out ILayerStack stack);
Example #24
0
        internal void SendReply(ulong conversationId,
                                IMessage response,
                                TaskCompletionSource<IMessage> taskSource,
                                ILayerStack layerStack,
                                InMemFrameQueue queue)
        {
            var sendContext = new SimpleInMemSendContext(connection);
            IBonded layerData = null;

            Error layerError = LayerStackUtils.ProcessOnSend(layerStack, MessageType.Response, sendContext, out layerData, logger);

            // If there was a layer error, replace the response with the layer error
            if (layerError != null)
            {
                logger.Site().Error("Sending reply for conversation {0} failed due to layer error (Code: {1}, Message: {2}).",
                                 conversationId, layerError.error_code, layerError.message);

                // Set layer error as result of this Bond method call, replacing original response.
                // Since this error will be returned to client, cleanse out internal server error details, if any.
                response = Message.FromError(Errors.CleanseInternalServerError(layerError));
            }

            var payload = Util.NewPayLoad(conversationId, PayloadType.Response, layerData, response, taskSource);
            queue.Enqueue(payload);
        }