Buenas David, ¿has podido revisarlo?. He intentado seguir la documentación https://cedocs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?K... pero no consigo realizar el envio del json. Al volver a compilar la clase (es el codigo del mensaje anterior a este) al re enviar un mensaje tengo este ERROR <Ens>ErrException: <METHOD DOES NOT EXIST>zCopyFrom+2^%Stream.Object.1 *Rewind,EnsLib.HTTP.GenericMessage -- logged as '-' number - @''

Comentaste antes " Creo que el uso del método CopyFrom es correcto pero si te falla es fácil copiar el contenido de un Stream a otro mediante Write y Read. "Pero no he sabido hacerlo.

Saludos

Buenas Alberto,

La documentación la habia leido y no me soluciono el problema. No se como implementarlo en mi codigo. Para mi el problema no es en la transformación de json si no pq una clase no permite dos propiedades iguales(actor). Yo en el tProxy cargo valores, pero la estructura del tProxy es la que define como sera el json, no puedo meter en una clase dos atributos iguales y tengo el problema.

Buenas

El error se produce al intentar realizar el envio, pongo una imagen

Esta es la versión final de codigo:

Class demo.bo.RESTOperation Extends EnsLib.REST.Operation
{ Parameter INVOCATION = "Queue"; Method SendHTTP(pHttpVerb As %String, pURL As %String, Output pHttpResponse As %Net.HttpResponse, pStream As %Stream.GlobalCharacter) As %Status
{
    set httpRequest = ##class(%Net.HttpRequest).%New()
    set httpRequest.ContentType = "application/json"
    set tSC = httpRequest.EntityBody.CopyFrom(pStream)
    set tSC = ..Adapter.SendFormDataURL(pURL,.pHttpResponse,pHttpVerb,httpRequest)
    quit tSC
} Method PostJSON(pURL As %String, Output pHttpResponse As %Net.HttpResponse, pStream As %Stream.GlobalCharacter) As %Status
{
  Return ..SendHTTP("POST",pURL,.pHttpResponse,pStream)
} Method OnPostRequest(pRequest As EnsLib.HTTP.GenericMessage, Output pResponse As EnsLib.HTTP.GenericMessage) As %Status
{
    set tURL=..Adapter.URL_"/demo"
    set tSC=..PostJSON(tURL,.tHttpResponse,pRequest)
    if $$$ISERR(tSC)&&$IsObject(tHttpResponse)&&$IsObject(tHttpResponse.Data)&&tHttpResponse.Data.Size {
        set tSC=$$$ERROR($$$EnsErrGeneral,$$$StatusDisplayString(tSC)_":"_tHttpResponse.Data.Read())
    }
    if $$$ISERR(tSC) quit tSC
    // procesar respuesta
    set pResponse = ##class(%Stream.GlobalCharacter).%New()
    set pResponse.respuesta = ##class(%Stream.GlobalCharacter).%New()
    if tHttpResponse.StatusCode=200 {
        $$$TRACE(tHttpResponse.Data.Read())
        set tSC = pResponse.respuesta.%JSONImport(tHttpResponse.Data)
    else 
        set tSC=$$$ERROR($$$EnsErrGeneral,"HTTP Status:"_tHttpResponse.StatusCode)
    }
    quit tSC
} XData MessageMap
{
<MapItems>
    <MapItem MessageType="EnsLib.HTTP.GenericMessage">
        <Method>OnPostRequest</Method>
    </MapItem>
</MapItems>
} }
 

Pues he dejado el metodo asi:

Method SendHTTP(pHttpVerb As %String, pURL As %String, Output pHttpResponse As %Net.HttpResponse, pStream As %Stream.GlobalCharacter) As %Status
{
    set httpRequest = ##class(%Net.HttpRequest).%New()
    set httpRequest.ContentType = "application/json"
    set tSC httpRequest.EntityBody.CopyFrom(pStream)
    set tSC = ..Adapter.SendFormDataURL(pURL,.pHttpResponse,pHttpVerb,httpRequest)
    quit tSC
}

He tenido que depurar un par de errores que conocia y ahora el error es:

ERROR <Ens>ErrException: <NOLINE>^demo.bo.RESTOperation.1 -- logged as '-' number - @' ;demo.bo.RESTOperation.1'

 

Gracias Nancy no lo vi.

Realizo el cambio en el MessageMap dejandolo asi:

<MapItems>
    <MapItem MessageType="EnsLib.HTTP.GenericMessage">
        <Method>OnPostRequest</Method>
    </MapItem>
</MapItems>
}

Ahora me da este error

ERROR <Ens>ErrException: <PROPERTY DOES NOT EXIST>zOnPostRequest+2^demo.bo.RESTOperation.1 *orden,EnsLib.HTTP.GenericMessage -- logged as '-' number - @' set tSC=..PostJSON(tURL,.tHttpResponse,pRequest.orden)'

Quito el orden del pRequest y ahora me da este error:

ERROR <Ens>ErrException: <UNDEFINED>zSendHTTP+3^demo.bo.RESTOperation.1 *jsonObject -- logged as '-' number - @' if $IsObject(jsonObject) {'

Gracias David, pero vuelvo a la Carga

He implementado la clase de la siguiente manera:

Class demo.bo.RESTOperation Extends EnsLib.REST.Operation
{ Parameter INVOCATION = "Queue"; Method SendHTTP(pHttpVerb As %String, pURL As %String, Output pHttpResponse As %Net.HttpResponse, pStream As %Stream.GlobalCharacter) As %Status
{
    set httpRequest = ##class(%Net.HttpRequest).%New()
    set httpRequest.ContentType = "application/json"
    if $IsObject(jsonObject) {
        set tSC=httpRequest.EntityBody.CopyFrom(pStream)
        if $$$ISERR(tSC) quit tSC
    }  
    set tSC = ..Adapter.SendFormDataURL(pURL,.pHttpResponse,pHttpVerb,httpRequest)
    quit tSC
} Method PostJSON(pURL As %String, Output pHttpResponse As %Net.HttpResponse, pStream As %Stream.GlobalCharacter) As %Status
{
  Return ..SendHTTP("POST",pURL,.pHttpResponse,pStream)
} Method OnPostRequest(pRequest As %Stream.GlobalCharacter, Output pResponse As %Stream.GlobalCharacter) As %Status
{
    set tURL=..Adapter.URL_"/demo"
    set tSC=..PostJSON(tURL,.tHttpResponse,pRequest.orden)
    if $$$ISERR(tSC)&&$IsObject(tHttpResponse)&&$IsObject(tHttpResponse.Data)&&tHttpResponse.Data.Size {
        set tSC=$$$ERROR($$$EnsErrGeneral,$$$StatusDisplayString(tSC)_":"_tHttpResponse.Data.Read())
    }
    if $$$ISERR(tSC) quit tSC
    // procesar respuesta
    set pResponse = ##class(%Stream.GlobalCharacter).%New()
    set pResponse.respuesta = ##class(%Stream.GlobalCharacter).%New()
    if tHttpResponse.StatusCode=200 {
        $$$TRACE(tHttpResponse.Data.Read())
        set tSC = pResponse.respuesta.%JSONImport(tHttpResponse.Data)
    else 
        set tSC=$$$ERROR($$$EnsErrGeneral,"HTTP Status:"_tHttpResponse.StatusCode)
    }
    quit tSC
} XData MessageMap
{
<MapItems>
    <MapItem MessageType="%Stream.GlobalCharacter">
        <Method>OnPostRequest</Method>
    </MapItem>
</MapItems>
} }
 

Y al enviar a mi puerto local tengo el siguiente error, y no llega hasta su destino

 

ERROR <Ens>ErrRequestNotHandled: Request message '5@EnsLib.HTTP.GenericMessage' not handled

El EnsLib.HTTP.GenericMessage lo genero al crear el json desde un  Ens.BusinessProcessBPL que lo envia al adaptador que ahora tiene la clase demo.bo.RESTOperation.

<call name='LLamada' target='FHIR out x2' async='1' xpos='335' ypos='850' >
<request type='EnsLib.HTTP.GenericMessage>
<assign property="callrequest.Streamvalue="context.RequestFHIRaction="set" />
</request>
<response type='EnsLib.HTTP.GenericMessage/>
</call>

He probado ha poner diversas clases en el request y en el response sin exito.

Despues he modificado el metodo para ponerle el EnsLib.HTTP.GenericMessege quedando asi: Method OnPostRequest(pRequest As EnsLib.HTTP.GenericMessage, Output pResponse As EnsLib.HTTP.GenericMessage) As %Status

Pero el error persiste:

ERROR <Ens>ErrRequestNotHandled: Request message '5@EnsLib.HTTP.GenericMessage' not handled

Un Saludo

Cierto tienes razon, lo mire demasiado rapido.

He creado las siguientes clases:

  • demo.PostRequest
  • demo.msg.PostResponse
  • demo.msg.Respuesta
  • demo.PostResponse

¿Podria haber usado en su lugar  %Stream.GlobalCharacter en su lugar? ¿Las clases que valores deben tener? No tengo muy claro que propiedades debe tener la clase que contenga el mensaje JSON.

Aun asi me dice que debo crear la clase %JSON.Adaptador, entiendo que es una clase de sistema, yo no la tengo. Mi versión es cliente 2018.2 version 309.

Ando muy permido en este asunto.

Buenas David,

Estaba enfocando el error en el servicio (EnsLib.HTTP.GenericOperation) mas que en en el adaptador (Test.BO.Adapter.HTTPOutboundAdapter). Ya que lo tengo enviando por post a un servicio rest con otra ip, y me esta funcionando. Voy a revisar el codigo que me pasas e implementarlo. Al crear la clase (tal cual) me da el siguiente error:

¿sabes por que puede ser?

Buenas

He configurado los logs del servicio y no deja rastros.

Realice algunos cambios y configure el servicio con la clase de caracteres JSON

Cuando veo el mensaje en el servicio veo lo siguiente

<HTTPMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://www.w3.org/2001/XMLSchema">

<Type>GC</Type>

<HTTPHeaders>

<HTTPHeadersItem HTTPHeadersKey="CharEncoding">@JSON</HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="EnsConfigName">HTTPWorkBench</HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="HTTPVersion">1.1</HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="HttpRequest">POST</HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="IParams">0</HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="RawParams" xsi:nil="true"></HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="TranslationTable">JSON</HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="URL">/</HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="content-length">0</HTTPHeadersItem>

<HTTPHeadersItem HTTPHeadersKey="host">localhost:9980</HTTPHeadersItem></HTTPHeaders>

</HTTPMessage>

Si veo en la operación la respuesta al JSON veo lo siguiente.

<Stream></Stream>

<Type>BG</Type>

<HTTPHeaders><HTTPHeadersItem HTTPHeadersKey="CONTENT-LENGTH">0</HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="CONTENT-TYPE">text/plain; charset="UTF-8"</HTTPHeadersItem><HTTPHeadersItem HTTPHeadersKey="StatusLine">HTTP/1.1 500 Internal Server Error</HTTPHeadersItem></HTTPHeaders>

</HTTPMessage>

El codigo de la operacion que envio es el siguiente:

Class Test.BO.Adapter.HTTPOutboundAdapter Extends EnsLib.HTTP.OutboundAdapter
{ 
/// Send a POST to the configured Server, Port and URL, sending form data to the named form variables.
Method Post(Output pHttpResponse As %Net.HttpResponse, pFormVarNames As %String, pData...) As %Status
{     quit ..SendFormDataArray(.pHttpResponse, "POST", ..GetRequest(), .pFormVarNames, .pData)
}

ClassMethod GetRequest() As %Net.HttpRequest
{
    set request = ##class(%Net.HttpRequest).%New()
    set request.ContentType = "application/json"
    quit request
}
}

El adaptador que esta recibiendo es un EnsLib.REST.GenericService, deberia crear una clase que heredara de la anterior, ¿para poner los log que me indicas?¿Como los pondría para ver si recibo algún valor cuando el stream esta vacio?

He revisado en BBDD la tabla EnsLib_HTTP.GenericMessage  y en streamBG veo 

3485%Stream.GlobalBinary^CacheStream

No hay logica aun, ya que no tengo claro que este recibiendo el json, y por tanto es logico el error 500.

Un Saludo