Question Martin Staudigel · 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

Comments

Oliver Wilms · Mar 14, 2023

Hi, Martin,

You receive a request via EnsLib.Http.GenericService. I assume you pass the EnsLib.HTTP.GenericMessage request object to a business process. I think you look for an example how to return the response. Let me look for an example ...

0
Oliver Wilms · Mar 14, 2023

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>
}}
 

0
Oliver Wilms · Mar 14, 2023

I provided a BPL example. Does that help?

0
Martin Staudigel  Mar 15, 2023 to Oliver Wilms

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 pResponseReturn 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

0
Martin Staudigel  Mar 15, 2023 to Oliver Wilms

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.GlobalBinaryStreamif ( 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

0