// Request processing method... public void ProcessRequest(HttpContext context) { string uri = context.Request.RawUrl.ToLower();; Init(uri); Trace.WriteLine(string.Format("HttpReceiveAdapter.ProcessRequest( uri:{0} ) called", uri), "HttpReceive: Info"); HttpReceiveEndpoint ep = base.GetEndpoint(uri) as HttpReceiveEndpoint; if (null == ep) { throw new ApplicationException("BizTalk HTTP receive adapter failed to initialize itself. Possible reasons:\n" + "1) Receive location URL is not created/configured correctly\n" + "2) Receive location is not enabled\n" + "3) HTTP receive adapter is not running under a user that has access to management and message databases\n" + "4) Isolated host instance is not created for HTTP Receive adapter.\n"); } // Determine if the port is one or two and handle accordingly... if (ep.Configuration.PortIsTwoWay) { ProcessRequestResponse(uri, context, ep); } else { ProcessRequest(uri, context, ep); } }
IBaseMessage ConstructMessage(string uri, HttpContext context, HttpReceiveEndpoint ep) { // Create a new message... IBaseMessage msg = this.msgFactory.CreateMessage(); IBaseMessagePart body = this.msgFactory.CreateMessagePart(); msg.AddPart("Body", body, true); // Attach the request stream to the message body part... Stream stream = context.Request.InputStream; if (!stream.CanSeek) { // The stream must be seekable for property error handling! stream = new VirtualStream(stream); } msg.BodyPart.Data = stream; // Determine the charset and content type and stamp on the message context... body.ContentType = context.Request.ContentType; body.Charset = context.Request.ContentEncoding.WebName; // If we have a Windows User, stamp it on the msg ctx... string user = context.User.Identity.Name; if (user.Length > 0) { msg.Context.Write(WindowsUserProperty.Name.Name, WindowsUserProperty.Name.Namespace, user); } // Note: this sample does not handle certificates. If it did it would // stamp the Cert Thumb Print ont he message context property: SignatureCertificate // Promote the InboundTransportLocation and InboundTransportType msg.Context.Promote(InboundTransportLocationProperty.Name.Name, InboundTransportLocationProperty.Name.Namespace, uri); msg.Context.Promote(InboundTransportTypeProperty.Name.Name, InboundTransportTypeProperty.Name.Namespace, protocol); // If Loopback is configured, stamp it on the message context... if (ep.Configuration.LoopBack && ep.Configuration.PortIsTwoWay) { msg.Context.Write(LoopBackProperty.Name.Name, LoopBackProperty.Name.Namespace, true); } return(msg); }
private void ProcessRequest(string uri, HttpContext context, HttpReceiveEndpoint ep) { // Create a new message... IBaseMessage msg = ConstructMessage(uri, context, ep); // Submit the message using the StandardReceiveBatchHandler SyncReceiveSubmitBatch batch = new SyncReceiveSubmitBatch(transportProxy, terminator, 1); // Do one-way-submit batch.SubmitMessage(msg, null); batch.Done(); if (!batch.Wait()) { Trace.WriteLine("HttpReceiveAdapter.ProcessRequest(): Failed to process the Http Request!", "HttpReceive: Error"); throw new HttpException(400, "Failed to process the Http Request"); } context.Response.StatusCode = 202; }
private void ProcessRequestResponse(string uri, HttpContext context, HttpReceiveEndpoint ep) { // Create a new message... IBaseMessage msg = ConstructMessage(uri, context, ep); // Use the request-response handler to send the request message SyncReceiveSubmitBatch batch = new SyncReceiveSubmitBatch(this.transportProxy, terminator, 1); DateTime expDateTime = DateTime.Now.AddSeconds(ep.Configuration.Timeout); HttpResponseHandler responseHandler = new HttpResponseHandler(this.transportProxy); // Do two-way submit operation: EPM should generate a response in this case batch.SubmitRequestMessage(msg, Guid.NewGuid().ToString("D"), true, expDateTime, responseHandler); // Done will call "Enter" on the terminator to ensure proper ref-counting batch.Done(); // Wait for the callback (this should always complete quickly) if (!batch.Wait()) { throw new HttpException(500, "Failed to submit the Http request to BizTalk Server"); } if (batch.FailedMessages.Count != 0) { throw new HttpException(500, "Failed to submit the Http request to BizTalk Server"); } // It's a good idea to have a timeout on the response message IBaseMessage responseMsg = responseHandler.WaitForResponse(ep.Configuration.Timeout); if (responseMsg == null) { // Response did not arrive in time! throw new HttpException(500, "Failed to retrieve the Http response message from BizTalk Server"); } // Copy the data from the response message into the HTTP response stream. Exception transmitException = null; try { using (Stream httpStream = context.Response.OutputStream) { // Set the response content-type (ideally, this should be extracted from message) context.Response.ContentType = ep.Configuration.ReturnContentType; Stream btsStream = responseMsg.BodyPart.GetOriginalDataStream(); // Note, the data is handled in a streaming fashion to // prevent us going out of memory for large messages. int bytesRead = 0; byte[] buff = new byte[IO_BUFFER_SIZE]; while ((bytesRead = btsStream.Read(buff, 0, IO_BUFFER_SIZE)) > 0) { httpStream.Write(buff, 0, bytesRead); } httpStream.Flush(); } } catch (Exception ex) { transmitException = ex; } finally { // After processing the response message successfully, it MUST be deleted // from BizTalk message box (a.k.a. Application Queue). Otherwise, the message // remain in the queue forever causing the system to become unresponsive. responseHandler.ResponseConsumed(transmitException); } }