Question
· Mar 14, 2023

Creating Http Responses

Hello,

I want to generate and return an http response based on the input of a http GET request. For my first steps I used an EnsLib.Http.GenericService, which uses an EnsLib.HTTP.InboundAdapter to receive requests like http://[my server]:[my-port]/some-path?ID=12345678.

On the inbound side I receive a EnsLib.HTTP.GenericMessage Object which contains the parameters and some other useful information that I can work with. What I would like to do now is to create a simple HTML page, which contains some Information specific for the given parameter values. All my different attempts to return something, which can be parsed by a browser (or at least shown as a http response in postman) failed up to now.

I think this task is normally done by a webapp, but using an interoperability production makes other things a lot easier for me.

Could anyone provide a snippet how to create a valid Response object inside the OnRequest method of an Ens.BusinessProcess to make me understand the priciple? The target is to receive the request from any web browser and return a page, which then is shown inside of the browser as the result of the request.

Thanks and regards,

Martin

Product version: IRIS 2021.1
$ZV: IS for UNIX (SUSE Linux Enterprise Server for x86-64) 2021.1 (Build 215U) Wed Jun 9 2021 09:48:27 EDT
Discussion (5)1
Log in or sign up to continue

Class HS.Local.Example.ProcessBPL Extends Ens.BusinessProcessBPL
{ Storage Default
{
<Type>%Storage.Persistent</Type>
} /// BPL Definition
XData BPL [ XMLNamespace = "http://www.intersystems.com/bpl]
{
<process language='objectscript' request='EnsLib.HTTP.GenericMessage' response='EnsLib.HTTP.GenericMessage' height='2000' width='2000' >
<context>
<property name='SuccessResponse' type='%String' instantiate='0' >
<parameters>
<parameter name='MAXLEN'  value='50' />
</parameters>
</property>
<property name='ConvertedStream' type='Ens.StreamContainer' instantiate='0' />
</context>
<sequence xend='200' yend='1000' >
<code name='ConvertedStream' xpos='200' ypos='250' >
<![CDATA[ If 1=request.%IsA("Ens.StreamContainer") {
   Set context.ConvertedStream = request
 }
 If 1=request.%IsA("EnsLib.HTTP.GenericMessage") {
   Set context.ConvertedStream = ##class(Ens.StreamContainer).%New()
   Set context.ConvertedStream.Stream = ##class(%GlobalCharacterStream).%New()
   Set tSC = context.ConvertedStream.Stream.CopyFrom(request.Stream)
   Set context.ConvertedStream.OriginalFilename = $Piece(request.HTTPHeaders.GetAt("RawParams"),"=",2)
 }
 If 1=request.%IsA("EnsLib.Kafka.Message") {
   Set context.ConvertedStream = ##class(Ens.StreamContainer).%New()
   Set context.ConvertedStream.Stream = ##class(%GlobalCharacterStream).%New()
   Set tSC = context.ConvertedStream.Stream.Write(request.value)
   Set context.ConvertedStream.OriginalFilename = request.key
   Set tSC = context.ConvertedStream.%Save()
 }]]>
</code>
<if name='Check Test Transaction' condition='context.ConvertedStream.OriginalFilename="TEST.txt"' xpos='200' ypos='350' xend='200' yend='700' >
<false>
<code name='Store Document' xpos='335' ypos='500' disabled="false">
<![CDATA[ Set tSC = ##class(HS.Local.VA.eSCM.FMS.Util).StoreStream(context.ConvertedStream,context.ConvertedStream)]]>
</code>
<call name='Call ToIrisMail Operation' target='ToIrisMail' async='0' xpos='335' ypos='600' >
<request type='Ens.StreamContainer>
<assign property="callrequestvalue="context.ConvertedStreamaction="set" />
</request>
<response type='EnsLib.HTTP.GenericMessage/>
</call>
</false>
</if>
<code name='setting of success response' xpos='200' ypos='800' >
<![CDATA[ Set context.SuccessResponse = ""
 If 1=request.%IsA("EnsLib.HTTP.GenericMessage") {
   Set tmp = ##class(%Library.GlobalBinaryStream).%New()
   Set tSC = tmp.Write("File received successfully")
   Set tSC = tmp.%Save()
   Set context.SuccessResponse=##class(EnsLib.HTTP.GenericMessage).%New(tmp,,request.HTTPHeaders)
   Do context.SuccessResponse.HTTPHeaders.SetAt("HTTP/1.1 200 OK","StatusLine")
   Set tSC = context.SuccessResponse.%Save()
 }]]>
</code>
<assign name="send response back" property="responsevalue="context.SuccessResponseaction="set" xpos='200' ypos='900' />
</sequence>
</process>
} }
 

Hi Oliver,

thanks a lot for your help. Your assumption is right, but at the moment I'm following the approach to write some COS Code to solve the task.

Class UKEr.BP.FHIR.HttpContsentRequestProcess Extends Ens.BusinessProcess
{

Method OnRequest(pRequest As Ens.Request, Output pResponse As Ens.Response) As %Status
{
	#dim tSc = $$$OK
	#dim tResponse as %Net.HttpResponse = ##class(%Net.HttpResponse).%New()
	set tResponse.StatusCode = 200
	// Do something to create a valdid response and assing it to pResponse
	Return tSc
}

/// Handle a 'Response'
Method OnResponse(request As %Library.Persistent, ByRef response As %Library.Persistent, callrequest As %Library.Persistent, callresponse As %Library.Persistent, pCompletionKey As %String) As %Status
{
	return $$$OK
}

}

Nevertheless I'll import your example and have a look at the graphical BP as well. At the moment I'd prefer to create a response in code, but I'm quite confident also to be able to translate your example.

Thank you very much, I'll get back here with results (hopefully).

Regards,

Martin

This is how I translated and simplified your example:

Method OnRequest(pRequest As Ens.Request, Output pResponse As Ens.Response) As %Status
{
	#dim tSc = $$$OK
	#dim tConvertedStream as Ens.StreamContainer
	#dim tStream as %Library.GlobalBinaryStream
	if ( pRequest.%IsA("EnsLib.HTTP.GenericMessage") ){
		set tConvertedStream = ##class(Ens.StreamContainer).%New()
		set tConvertedStream.Stream = ##class(%GlobalCharacterStream).%New()
		set tSc = tConvertedStream.Stream.CopyFrom(pRequest.Stream)
		set tConvertedStream.OriginalFilename = $Piece(pRequest.HTTPHeaders.GetAt("RawParams"),"=",2)
		
		set tStream = ##class(%Library.GlobalBinaryStream).%New()
		set tSc = tStream.Write("<html><head><title>Server Response</title></head><body><h1>This is your response</h1></body></html>")
		set tSc = tStream.%Save()
		
		set pResponse = ##class(EnsLib.HTTP.GenericMessage).%New(tStream,,pRequest.HTTPHeaders)
		do pResponse.HTTPHeaders.SetAt("HTTP/1.1 200 OK","StatusLine")
		do pResponse.%Save()
	}
	
	return tSc
}

It works like expected:

that is exactly what I needed to continue.

Thank you very much for your help,

regards,

Martin