Muchas gracias Alberto,

Aunque he puesto que envía un email, también el proceso envía una traza a un proceso interno para el control de errores.

Quiero controlar si falla el email, quede registrado a través de la api de trazas, y si falla las trazas, que envíe un email. (si fallan los dos... pues ya veremos)

Por lo que voy a implementar la solución que ha propuesto Julian en la pregunta que he realizado en la comunidad en inglés.

Un saludo,

Kurro Lopez

Investigando un poco mas la documentación de ZEN.Template no resulta complicado implementar nuevos métodos.

Siguiendo los mismos pasos que para el asistente SOAP, incluye la siguiente entrada en la lista de links y tendrás nuevos asistentes.

Installer Wizard

"Installer Wizard": "${serverUrl}/isc/studio/templates/%25Installer.InstallerWizard.cls?Namespace=${namespace}${serverAuth}"
 

DeepSeek PI Wizard

"DeepSeek PI Wizard": "${serverUrl}/isc/studio/templates/%25DeepSee.Template.DeepSeeKPIWizard.cls?Namespace=${namespace}${serverAuth}"

Buenas David,

Desde Visual Code no se han implementado los wizards de la misma forma que están en Studio, muchos de estos asistentes estaban programados en exclusiva para Studio, otros estaban pensados para acceder desde Atelier, a través de su server template, como el asistente de SOAP.

Podrás incorporarlo en Visual studio siguiendo los siguientes pasos

Asistente para cliente SOAP

https://es.community.intersystems.com/post/trucos-y-consejos-de-vscode-a...

Supongo que poco a poco, la comunidad podrá ir aportando algunos trucos para tener lo mismo que en Atelier.

Un saludo,
Kurro

Esto es lo que ha devuelto el log

09/23/2021 16:04:36 *********************
Output from Web client with SOAP action = http://ws.myprovider.org/buscarInfo
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema'>
  <SOAP-ENV:Body><buscarInfo xmlns="http://ws.myProvider.salutic.org/"><idEspecialidad xsi:type="s:string">CT</idEspecialidad><centroSanitario xsi:type="s:string">CG</centroSanitario><infoAdicional xmlns:s01="http://ws.myProvider.salutic.org/" xsi:type="s01:infoAdicionalType"><ambulancia xsi:type="s:boolean">false</ambulancia><urgencia xsi:type="s:boolean">false</urgencia><gravedad xsi:type="s:boolean">false</gravedad><anestesia xsi:type="s:boolean">false</anestesia><claustrofobia xsi:type="s:boolean">false</claustrofobia></infoAdicional></buscarInfo></SOAP-ENV:Body>
</SOAP-ENV:Envelope>

09/23/2021 16:04:36 *********************
Input to Web client with SOAP action = http://ws.myProvider.org/buscarInfo

ERROR #6243: La solicitud HTTP a SOAP WebService ha devuelto una respuesta con CONTENT-TYPE inesperado: application/wsdl+xml.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://ws.myProvider.org/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.myProvider.org/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/">
<wsdl:documentation>Servicio Web para InfoOnline TEST</wsdl:documentation>
  <wsdl:types>
    <xsd:schema>
<xsd:import namespace="http://ws.myProvider.org/" schemaLocation="InfoOnline.xsd"/>
</xsd:schema>
  </wsdl:types>
  <wsdl:message name="buscarInfoSoapOut">
    <wsdl:part name="buscarInfoResult" element="tns:buscarInfoResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="buscarInfoSoapIn">
    <wsdl:part name="parameters" element="tns:buscarInfo">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="InfoOnlineWSSoap">
    <wsdl:operation name="buscarInfo">
<wsdl:documentation>Solicita informacion para un paciente</wsdl:documentation>
      <wsdl:input message="tns:buscarInfoSoapIn">
    </wsdl:input>
      <wsdl:output message="tns:buscarInfoSoapOut">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="InfoOnlineWSSoap" type="tns:InfoOnlineWSSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="buscarInfo">
      <soap:operation soapAction="http://ws.myProvider.org/buscarHueco" style="document"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="InfoOnlineWS">
<wsdl:documentation>Servicio Web Seguro  (Pruebas) para InfoOnline (TEST) </wsdl:documentation>
    <wsdl:port name="InfoOnlineWSSoap" binding="tns:InfoOnlineWSSoap">
      <soap:address location="https://urlprovider.com/services/SIU"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
**** SOAP client return error. method=buscarInfo, action=http://ws.myProvider.org/buscarInfo
     ERROR #6243: La solicitud HTTP a SOAP WebService ha devuelto una respuesta con CONTENT-TYPE inesperado: application/wsdl+xml.

Nota: Por motivos de confidencialidad, se ha modificado la dirección del proveedor y algunos detalles mas, pero esta es la respuesta obtenida.

He sobreescrito el método %OnSOAPResponse para ver si obtenía algo, y ya viene con el error

 Method %OnSOAPResponse(mode As %String, client As %SOAP.WebClient, action As %String, oneWay As %Boolean, method As %String, requestStream As %BinaryStream, responseStream As %BinaryStream, sc As %Status)
{
Quit
}

entonces, no debería de ser un problema de la cabecera de salida, sino mas bién las cabeceras de entrada. ¿O es que intenta recuperar el WSDL para hacer la operación y ahí es donde está el problema?

Un saludo,
Kurro

Hola David,

No se donde se establece ese valor.

El Business Operation se creó usando el wizard y lo que se modificó en los métodos, es que antes de hacer el Invoke a cada uno de los métodos del WS, modifica el namespace y el Location según a que proveedor va a realizar la consulta.

Todos los proveedores tienne la misma estructura y métodos iguales, varían el Namespace y la URL.

He probado a incluir la siguiente linea:

Method MiMetodo(pRequest As MyMessageWS.RequestbuscarInfoRequest, Output pResponse As MyMessageWS.RequestbuscarInfoResponse) As %Library.Status
{
    do ..preparaOperacion(pRequest)
    Set tSC = ..Adapter.InvokeMethod("buscarInfo",.info,pRequest.idEspecialidad,pRequest.listaActos,pRequest.centroSanitario,pRequest.infoAdicional)
    Quit:$$$ISERR(tSC) tSC
    Set tSC = pRequest.NewResponse(.pResponse)  Quit:$$$ISERR(tSC) tSC
    Set pResponse.InfoCentro=$get(info)
    Quit $$$OK
}

Method preparaOperacion(pRequest As MyMessageWS.Request.base) As %Status
{
 Set ..Adapter.%Client.Namespace = pRequest.Namespace
 Set ..Adapter.%Client.Location = pRequest.Url
 Set ..Adapter.%Client.ContentType = "application/wsdl+xml"
 Quit $$$OK
}

He invocado al proveedor directamente para que me dé el WSDL y, efectivamente, responde con un fichero wsdl+xml

A ver si con esta explicación puedes ayudar mejor.

Un saludo,
Kurro

(Respuesta de @Eduard Lebedyuk)

Ver enlace original en https://community.intersystems.com/post/how-automatically-test-deepsee-p...

Aquí algunas ideas

  1. Recupera una lista de pivots
  2. Por cada elemento
    • Obtén el MDX
    • Intenta ejecutar el MDX
    • Si falla, guarda el error
  3. Añade/visualiza los errores

Debería de ser factible, DeepSee API tiene todas las funciones necesarias para hacerlo

Hola,

Os comento las respuestas obtenidas en el community en inglés. Adjunto también el enlace a la respuesta original.

Respuesta de @Robert Cemper 
https://community.intersystems.com/post/query-method-class-persistent-us...

#2) El segundo ejemplo no puede funcionar, principalmente porque no pasa un parámetro en la llamada

#1) NO está previsto utilizar propiedades de objeto vomo variables del lengiaje principal en SQL

El código falla en el métode Execute generado

set tResult = tStatement.%Execute($g(pObject.KeyProcess),$g(pObject.CodeSpecialist),$g(pObject.CodeProvider),$g(pObject.CodeCenter),$g(pObject.Date))

El método $GET object-property simplemente no está implementado. Está definido por la clase y siempre está ahí, pero es necesario y tiene sentido para propiedades multidimensionados

Esto es válido para ObjectScript como tal y no está relacionado con SQL.
Es como tener un método $g(NOTHING, pObkect.KeyProcess)... osea, nada

Alternativas:

  1. Manipular directamente el código generado. No recomendado
  2. Mover las propiedades con una función auxiliar a variables loclaes y ajusta la consulta con esas variables
ClassMethod FillProp(pObject As Kurro.MyClass) As %Boolean [ SqlName = FILLP, SqlProc ]
{
if '$isObject(pObject) set obj=##class(Kurro.MyClass).%OpenId(pObject)
else  set obj=pObject
set %Kurro("kp")=obj.KeyProcess
     ,%Kurro("sp")= obj.CodeSpecialist
     ,%Kurro("pr")= obj.CodeProvider
     ,%Kurro("cs")= obj.CodeCenter
    ,%Kurro("dt")= obj.Date
quit 1
}

Y la invocación sería de esta forma:

Query GetInfoRcc(objid As %Integer) As %SQLQuery(CONTAINID = 0, ROWSPEC = "IdList:%String,IdProcess:%String,Duration:%String")
{
    SELECT IdList, IdProcess, Duration
    FROM Kurro.MyClass
    WHERE KeyProcess = :%Kurro("kp")
    AND CodeSpecialist = :%Kurro("sp")
    AND CodeProvider = :%Kurro("pr")
    AND CodeCenter = :%Kurro("cs")
    AND "Date" = :%Kurro("dt")
   AND FILLP(:objid) = 1
}

Respuesta de @Vitaliy.Serdtsev 
https://community.intersystems.com/post/query-method-class-persistent-us...

Tal y como ha comentado Robert, el problema está en el $GET(), por lo que en lugar de utilizar el método %Library.SqlQuery:Func(), utilizar el PrepareClaseQuery

Query GetInfo(pObject AS Kurro.MyClass) As %SQLQuery(CONTAINID = 1, ROWSPEC = "IdList:%String,IdProcess:%String,Duration:%String") [ SqlProc ]
{
    SELECT IdList, IdProcess, Duration
    FROM Kurro.MyClass
    WHERE KeyProcess = :pObject.KeyProcess
    AND CodeSpecialist = :pObject.CodeSpecialist
    AND CodeProvider = :pObject.CodeProvider
    AND CodeCenter = :pObject.CodeCenter
    AND "Date" = :pObject.Date
}


set obj=##class(Kurro.MyClass).%New()
set obj.KeyProcess="1033004-1#"
set obj.CodeSpecialist = "surgery"
set obj.CodeProvider = "PR002"
set obj.CodeCenter = "CENTER-01"
set obj.Date = $ZDATETIME($ZDATETIMEH("2021-04-30 15:45:00",3,1),3,1)

set st=##class(%SQL.Statement).%New()
set sc=st.%PrepareClassQuery("Kurro.MyClass","GetInfo")
  if $$$ISERR(sc) {write "%PrepareClassQuery failed:" do $System.Status.DisplayError(sc) quit}
set result=st.%Execute(obj)
do result.%Display()

He utilizado la última respuesta para solucionar mi problema y funciona muy bien

Mucha gracias a los dos por estas respuestas.

Un saludo,
Kurro

Usando las trazas:

set ^ISCSOAP("LogFile")="c:\temp\SOAP.log"
set ^ISCSOAP("Log")="ios"

 He visto que la respuesta era la del servidor y es como si no estuviera llegando al servicio.

La configuración que tenía era como esta

Al poner toda la ruta en el campo "Web Service URL" ha empezado a responder correctamente

http://myserver.com/path/service

Tenemos implementados otros WS y han funcionado correctamente indicando el servicio en el otro campo, pero creo que son por lo que son del tipo

http://myserver.com/path/server.asmx

Este servicio está creado en java y está desplegado en JBoss

Gracias por tu ayuda.

Un saludo,
Kurro

Gracias Alberto.

Puede que sea por la versión de Caché, dado que estamos usando la 2017.2.1

$ZV: Cache for Windows (x86-64) 2017.2.1 (Build 801_3U) Thu Apr 12 2018 10:02:23 EDT
Product version: Ensemble 2017.1
 
Hay muchas cosas que están funcionando bien en IRIS, y esperamos que pronto nuestro cliente haga la migración a IRIS, pero por ahora tenemos que hacer "malabarismos" con estas cosas.
 
Al final lo he tenido que mapear a mano una vez recibido los datos.
 
Un saludo,
Kurro