Hola,

$SYSTEM.OBJ.CompileAllNamespaces() -- Compila las clases de TODOS los namespaces

Normalmente es más sencillo ir Namespace por Namespace (si hay varios) y se hace con $SYSTEM.OBJ.CompileAll(). Este método puede recibir "flags" de compilación. Yo suelo usar "ckub":

$SYSTEM.OBJ.CompileAll("ckub")

Para ver los flags de compilación disponibles:

USER>Do $system.OBJ.ShowFlags()

 See $system.OBJ.ShowQualifiers() for comprehensive list of qualifiers as flags have been superseded by qualifiers

    b - Include sub classes.
    c - Compile. Compile the class definition(s) after loading.
    d - Display. This flag is set by default.
    e - Delete extent.
    h - Show hidden classes.
    i - Validate XML export format against schema on Load.
    k - Keep source.  When this flag is set, source code of
        generated routines will be kept.
    l - Lock classes while compiling.  This flag is set by default.
    p - Percent.  Include classes with names of the form %*.
    r - Recursive.  Compile all the classes that are dependency predecessors.
    s - Process system messages or application messages.
    u - Update only.  Skip compilation of classes that are already up-to-date.
    y - Include classes that are related to the current class in the way that
        they either reference to or are referenced by the current class in SQL usage.

These flags are deprecated a, f, g, n, o, q, v
Default flags for this namespace 
You may change the default flags with the SetFlags(flags,system) classmethod.

Puede que me equivoque, pero estoy viendo un 500 Internal Server Error, eso es un error que te devuelve el servicio. Por lo tanto ni siquiera se producen los mensajes. ¿Puedes elevar el nivel de log o meter trazas para saber qué está pasando? Por otro lado veo que el ContentType es "text/plain" y debería ser "application/json"

Para empezar veo que estás creando una clase Adaptador que hereda de Test.BO.Adapter.HTTPOutboundAdapter. Eso no es una Operación. Es un adaptador.

Y la verdad no veo dónde estás metiendo los datos del Body... quizá hay más código

Yo mejor haría una operación que herede de EnsLib.REST.Operation.

Ejemplo:

Class demo.bo.RESTOperation Extends EnsLib.REST.Operation
{

Parameter INVOCATION = "Queue";

Method SendHTTP(pHttpVerb As %String, pURL As %String, Output pHttpResponse As %Net.HttpResponse, jsonObject As %JSON.Adaptor) As %Status
{
    set httpRequest = ##class(%Net.HttpRequest).%New()
    set httpRequest.ContentType = "application/json"
    if $IsObject(jsonObject) {
        set tSC=jsonObject.%JSONExportToStream(httpRequest.EntityBody)
        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, jsonObject As %JSON.Adaptor) As %Status
{
    Return ..SendHTTP("POST",pURL,.pHttpResponse,jsonObject)
} 

Method OnPostRequest(pRequest As demo.PostRequest, Output pResponse As demo.PostResponse) 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(demo.msg.PostResponse).%New()
    set pResponse.respuesta = ##class(demo.msg.Respuesta).%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="demo.PostRequest"> 
        <Method>OnPostRequest</Method>
    </MapItem>
</MapItems>
}

}

Glup, eso no me lo esperaba!!... tendría que mirar desde cuándo está el JSON Adaptor

Pero para tu problema eso va a dar igual, me explico. El parámetro "jsonObject" es el que utiliza esa clase %JSON.Adaptor pero esa clase lo único que hace es ayudarte a manejar objetos JSON. Para resolver tu problema inicial en lugar de usar esa clase utiliza como tu dices un Stream. Por ejemplo el %Stream.GlobalCharacter.

Esta sentencia:

set tSC=..PostJSON(tURL,.tHttpResponse,pRequest.orden)

Lo que hace es pasar la URL, el objeto donde se va a colocar la respuesta a la vuelta (por referencia) y el contenido del mensaje pRequest. En este caso puedes inventarte un objeto tuyo que lleve un Stream con un JSON en texto plano para probar.

En este método:

Method PostJSON(pURL As %String, Output pHttpResponse As %Net.HttpResponse, pStream As %Stream.GlobalCharacter) As %Status 
{
  Return ..SendHTTP("POST",pURL,.pHttpResponse,pStream) 
}

cambia la firma del método para usar el Stream. Y finalmente en este método envía el contenido como Body de la llamada HTTP.

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 
}

No lo he probado. 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.

Espero que te sirva. 

Chicos y chicas aprovechad esta oportunidad para certificarse. Paso 1: REGISTRARSE en el VS2020

Hay tiempo de preparar el examen ya que se puede realizar online en cualquier momento hasta el 31 de Diciembre.

¿Qué os parece si hacemos una serie de webinars explicando los contenidos como preparación para el examen?

Kurro, aunque parezca tonto lo habitual ahí es que llamas a la URL incorrecta y en lugar de invocar el servicio te viene un HTML típico de error entonces el pro y no sabe interpretarlo.

Puedes meter un wireshark o trazas de SOAP para ver exactamente cual es el HTTP que sale y entra.

Genial. Me alegra haber ayudado. Igual te animas y publicas un POST con tu experiencia. Seguro le es útil a alguien que empiece. Y gracias por participar en la comunidad 

Os hemos escuchado y os comunico que vamos a realizar un webinar muy orientado para quien empieza con IRIS el próximo día 23 de marzo.... manteneros en el dial ya que pronto recibiréis más noticias 😜

A qué te refieres con pipeline por PHP????

si quieres conectar una BD MySQL con Caché se puede hacer de varias formas. Por ejemplo mediante tablas vinculadas. De esta forma tablas de una BD externa se ven como tablas propias de Caché.

Pero sigo sin saber muy bien que necesitas 

Lo de pasar los datos “vía PHP” es lo que me suena muy raro. Si quieres migrar los datos de una BD a la otra se me ocurren mil mejores formas que con PHP. Si lo que necesitas es conectarte a Caché para recuperar información a una pantalla de PHP y luego moverla a MySQL. El problema se reduce a conectar PHP a Caché. Mírate este proyecto de código abierto: https://github.com/chrisemunt/mg_php

Evgeny encontró una solución muy útil a su pregunta para convertir el resultado de una SQL a un objeto JSON. Así de Fácil:

s sc=##class(%ZEN.Auxiliary.jsonSQLProvider).%WriteJSONFromSQL("json","SELECT Name FROM Sample.Person")

y con un poco más de magia construyo esta librería para cumplir también con la parte REST

Se puede instalar fácilmente con ZPM:

USER>zpm "install sql-rest"

Hay varias cosas que tener en cuenta aquí. Lo primero es que el VSCode debe estar en la misma máquina que la instancia de IRIS para que puedan compartir procesos de sistema operativo. Lo demás es poder adjuntarse al proceso del BO y luego poder parar en la línea de código.

Echa un ojo a esto si no lo has hecho ya:

https://intersystems-community.github.io/vscode-objectscript/rundebug/

Para adjuntarte a un proceso utiliza esta configuración en el fichero .vscode/launch.json

{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "objectscript",
      "request": "attach",
      "name": "ObjectScript Attach",
      "processId": "${command:PickProcess}",
      "system": true
    }
  ]
}

Ja ja ja ... pues la verdad pensaba que tenía que estar en el mismo “entorno” los procesos de IRIS y el VSCode pero mira si somos buenos que no hace falta 🤣

Si es un cliente el mediaType que te llega debería coincidir con alguno de los mediaType que estableces en el Accept. ¿Has probado a establecer el Accept en la llamada?