public void SendResponse(MessageContext context, HttpResponsePacket response )
        {
            if (disposed) throw new ObjectDisposedException("Subscriber has been disposed");
            if (String.IsNullOrEmpty(context.ReplyToQueue)) return;

            if (conn == null)
            {
                //TODO: Log this -- it technically shouldn't happen. Also translate to a HTTP Unreachable because it means StartCallbackQueueConsumer didn't create a connection
                throw new ApplicationException("This is Bad");
            }

            //TODO: Channel Pool this connection
            using (IModel channel = conn.CreateModel())
            {

                BasicProperties basicProperties = new BasicProperties { CorrelationId = context.CorrelationId };

                try
                {
                    channel.BasicPublish(String.Empty,
                                    context.ReplyToQueue,
                                    basicProperties,
                                    response.Serialize());
                }
                catch {
                    //TODO: Log execption
                }
            }
        }
Beispiel #2
0
        private async Task ProcessRequest(MessageContext restbusContext, CancellationToken cancellationToken)
        {
            //NOTE: This method is called on a background thread and must be protected by an outer big-try catch

            //HttpRequestMessage requestMsg;
            HttpResponse responseMsg = null;

            var msg = restbusContext.Request.ToServiceMessage();
            var httpContext = new DefaultHttpContext(msg);

            await appFunc.Invoke(httpContext).ConfigureAwait(false);
            responseMsg = httpContext.Response;

            //if (!restbusContext.Request.TryGetHttpRequestMessage(appVirtualPath ?? (appVirtualPath = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath), out requestMsg))
            //{
            //    responseMsg = new HttpResponseMessage(HttpStatusCode.BadRequest) { ReasonPhrase = "Bad Request" };
            //}

            //TODO: Implement disposed
            //if (disposed)
            //{
            //    responseMsg = requestMsg.CreateErrorResponse(HttpStatusCode.ServiceUnavailable, "The server is no longer available.");
            //}
            //else
            //{
            //    requestHandler.EnsureInitialized();

            //    // Add current synchronization context to request parameter
            //    SynchronizationContext syncContext = SynchronizationContext.Current;
            //    if (syncContext != null)
            //    {
            //        requestMsg.SetSynchronizationContext(syncContext);
            //    }

            //    // Add HttpConfiguration to request parameter
            //    requestMsg.SetConfiguration(config);

            //    // Ensure we have a principal, even if the host didn't give us one
            //    IPrincipal originalPrincipal = Thread.CurrentPrincipal;
            //    if (originalPrincipal == null)
            //    {
            //        Thread.CurrentPrincipal = anonymousPrincipal.Value;
            //    }

            //    // Ensure we have a principal on the request context (if there is a request context).
            //    HttpRequestContext requestContext = requestMsg.GetRequestContext();

            //    if (requestContext == null)
            //    {
            //        requestContext = new RequestBackedHttpRequestContext(requestMsg);

            //        // if the host did not set a request context we will also set it back to the request.
            //        requestMsg.SetRequestContext(requestContext);
            //    }

            //    try
            //    {

            //        try
            //        {
            //            responseMsg = await requestHandler.SendMessageAsync(requestMsg, cancellationToken);
            //        }
            //        catch (HttpResponseException exception)
            //        {
            //            responseMsg = exception.Response;
            //        }
            //        catch (NullReferenceException exception)
            //        {
            //            // There is a bug in older versions of HttpRoutingDispatcher which causes a null reference exception when
            //            // a route could not be found
            //            // This bug can be triggered by sending a request for a url that doesn't have a route
            //            // This commit fixes the bug https://github.com/ASP-NET-MVC/aspnetwebstack/commit/6a0c03f9e549966a7f806f8b696ec4cb2ec272e6#diff-c89c7bee3d225a037a6d04e8e4447460

            //            if (exception.TargetSite != null && exception.TargetSite.DeclaringType != null
            //                && exception.TargetSite.DeclaringType.FullName == "System.Web.Http.Dispatcher.HttpRoutingDispatcher"
            //                && exception.TargetSite.Name == "SendAsync")
            //            {
            //                //This is the bug, so send a 404 instead

            //                const string NoRouteMatchedHttpPropertyKey = "MS_NoRouteMatched";

            //                requestMsg.Properties.Add(NoRouteMatchedHttpPropertyKey, true);
            //                responseMsg = requestMsg.CreateErrorResponse(
            //                    HttpStatusCode.NotFound,
            //                    String.Format("No HTTP resource was found that matches the request URI '{0}'.", requestMsg.RequestUri));

            //            }
            //            else
            //            {
            //                responseMsg = CreateResponseMessageFromException(exception);
            //            }
            //        }
            //        catch (Exception exception)
            //        {
            //            responseMsg = CreateResponseMessageFromException(exception);
            //        }

            //        if (responseMsg == null)
            //        {
            //            //TODO: Not good, Log this
            //            //TODO: derive exception from RestBus.Exceptions class
            //            responseMsg = CreateResponseMessageFromException(new ApplicationException("Unable to get response"));
            //        }

            //    }
            //    finally
            //    {
            //        Thread.CurrentPrincipal = originalPrincipal;
            //    }
            //}


            //Send Response
            try
            {
                //TODO: Why can't the subscriber append the subscriber id itself from within sendresponse
                subscriber.SendResponse(restbusContext, MessageHelpers.ToHttpResponse(responseMsg, msg));
            }
            catch
            {
                //TODO: Log SendResponse error
            }
        }
Beispiel #3
0
        public void SendResponse(MessageContext context, HttpResponsePacket response )
        {
            if (disposed) throw new ObjectDisposedException(GetType().FullName);

            var dispatch = context.Dispatch as MessageDispatch;
            if (dispatch != null)
            {
                //Ack request
                if(Settings.AckBehavior != SubscriberAckBehavior.Automatic && dispatch.Consumer.Model.IsOpen)
                {
                    dispatch.Consumer.Model.BasicAck(dispatch.Delivery.DeliveryTag, false);

                    //NOTE: The call above takes place in different threads silmultaneously
                    //In which case multiple threads will be using the same channel at the same time.
                    //It's okay in this case, because transmissions within a channel are synchronized, as seen in:
                    //https://github.com/rabbitmq/rabbitmq-dotnet-client/blob/f16c093f6409e11d9d77115038cb224eb39468ec/projects/client/RabbitMQ.Client/src/client/impl/ModelBase.cs#L459
                    //and
                    //https://github.com/rabbitmq/rabbitmq-dotnet-client/blob/f16c093f6409e11d9d77115038cb224eb39468ec/projects/client/RabbitMQ.Client/src/client/impl/SessionBase.cs#L177
                }
            }

            //Exit method if no replyToQueue was specified.
            if (String.IsNullOrEmpty(context.ReplyToQueue)) return;

            if (_subscriberPool.Connection == null)
            {
                //TODO: Log this -- it technically shouldn't happen. Also translate to a HTTP Unreachable because it means StartCallbackQueueConsumer didn't create a connection
                throw new ApplicationException("This is Bad");
            }

            //Add/Update Subscriber-Id header
            response.Headers[Common.Shared.SUBSCRIBER_ID_HEADER] = subscriberIdHeader;

            //Send response
            var pooler = _subscriberPool;
            AmqpModelContainer model = null;
            try
            {
                model = pooler.GetModel(ChannelFlags.None);
                BasicProperties basicProperties = new BasicProperties { CorrelationId = context.CorrelationId };

                model.Channel.BasicPublish(String.Empty,
                                context.ReplyToQueue,
                                basicProperties,
                                response.Serialize());
            }
            finally
            {
                if(model != null)
                {
                    model.Close();
                }
            }
        }