Hola Alberto, gracias por responder porque nos apoya y orienta lo que nos explicas, en concreto el ejemplo de la documentación y las dos indicaciones a implementar
Hemos escrito el siguiente WebService:
Class WSCLIENTE.HistoriaClinica.FicheroVacuServiceSOAP Extends %SOAP.WebClient [ ProcedureBlock ]
{
// Parameter LOCATION = "https://regvacube.sns.gob.es/regvacu/ws/FicheroVacuService";
/// This is the URL used to access the web service.
/// This is the namespace used by the Service
Parameter NAMESPACE = "http://ws.regvacuWs.ms.es/regvacu/ws/FicheroVacuService";
/// 20/09/21 Cambiamos a 0, con el objetivo de quitar el xsi:type
Parameter OUTPUTTYPEATTRIBUTE = 0;
/// Determines handling of Security header.
Parameter SECURITYIN = "ALLOW";
/// This is the name of the Service
Parameter SERVICENAME = "FicheroVacuService";
// Parameter SOAPVERSION = 1.2;
Parameter SOAPVERSION = 1.1;
/// This is the SOAP version supported by the service.
Parameter MTOMREQUIRED = 1;
// Method cargarFichero(fichero As %xsd.base64Binary(REQUIRED=1), ccaaId As EsquemasDatos.HistoriaClinica.tns.CCAAIdType(REQUIRED=1), tipoFichero As EsquemasDatos.HistoriaClinica.tns.TipoFicheroType(REQUIRED=1)) As EsquemasDatos.HistoriaClinica.tns.InfoFicheroType(XMLNAME="responseFichero") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
// Method cargarFichero(fichero As %GlobalBinaryStream, ccaaId As EsquemasDatos.HistoriaClinica.tns.CCAAIdType(REQUIRED=1), tipoFichero As EsquemasDatos.HistoriaClinica.tns.TipoFicheroType(REQUIRED=1)) As EsquemasDatos.HistoriaClinica.tns.InfoFicheroType(XMLNAME="responseFichero") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
/// 15 10 21 Edu explica que el fichero, el .zip con un .csv necesitamos enviarlo SIN CODIFICAR
/// quitamos %GlobalBinaryStream y ponemos %GlobalCharacterStream
///
Method cargarFichero(fichero As %GlobalCharacterStream, ccaaId As EsquemasDatos.HistoriaClinica.tns.CCAAIdType(REQUIRED=1), tipoFichero As EsquemasDatos.HistoriaClinica.tns.TipoFicheroType(REQUIRED=1)) As EsquemasDatos.HistoriaClinica.tns.InfoFicheroType(XMLNAME="responseFichero") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
//Header - Addresing
set addressing = ..crearAddressing()
set addressing.Action = "cargarFichero"
set ..AddressingOut = addressing
set ..AddressingOut.mustUnderstand = "1"
//Firma el XML (mensaje SOAP)
//do ..crearSignature()
set ..MTOMRequired=1
//24 09 21 para añadir parametro name en cabecera content type
//set ..ContentType="application/octet-stream; name=nombre"
//28 09 21 probamos a ajustarlo
//set ..ContentType="application/octet-stream; charset=latin1"
set ..ContentType="application/xhtml+xml; charset=latin1"
/*
27 09 21 con el objetivo de poner parametro name en cabecera content type
Genera excepcion: ERROR #5001: <INVALID OREF>zcargarFichero+16^WSCLIENTE.HistoriaClinica.FicheroVacuServiceSOAP.1
*/
//set ..HttpRequest.ContentType="application/octet-stream; name=nombre"
//do ..HttpRequest.SetHeader("name","nombre")
Quit ..WebMethod("cargarFichero","CargarFicheroVacuRequest").Invoke($this,"http://ws.regvacuWs.ms.es/FicheroVacu/cargarFichero",.fichero,.ccaaId,.tipoFichero)
}
Method infoFichero(ccaaId As EsquemasDatos.HistoriaClinica.tns.CCAAIdType(REQUIRED=1), infoFichero As EsquemasDatos.HistoriaClinica.tns.InfoFicheroType(REQUIRED=1), Output estado As EsquemasDatos.HistoriaClinica.tns.EstadoFicheroType(REQUIRED=1)) As %xsd.base64Binary(XMLNAME="fichero") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
set ..MTOMRequired=1
Quit ..WebMethod("infoFichero","InfoFicheroVacuRequest").Invoke($this,"http://ws.regvacuWs.ms.es/FicheroVacu/infoFichero",.ccaaId,.infoFichero,.estado)
}
Method crearAddressing() As %SOAP.Addressing.Properties
{
set IPRedSanitaria = ##class(Util.TablasMaestras).getValorMaestra("PARAMETROS","IPRedSanitaria")
set puertoRespuestas = ##class(Util.TablasMaestras).getValorMaestra("PARAMETROS","PuertoRespuestasSSL")
set ReplyTo = ##class(%SOAP.Addressing.EndpointReference).%New()
set ReplyTo.Address = "http://www.w3.org/2005/08/addressing/anonymous"
//set ReplyTo.Address = "https://"_IPRedSanitaria_":"_puertoRespuestas_"/csp/SNS/Servicios.ProgramasAsistenciales.SIFCOv02r00.cls"
set MessageId = ##class(Util.FuncionesComunes).getUID()
set addressing = ##class(%SOAP.Addressing.Properties).%New()
set addressing.MessageId = MessageId
set addressing.Destination = ..Location
set addressing.ReplyEndpoint = ReplyTo
Quit addressing
}
Method crearSignature() As %XML.Security.Signature
{
//Generamos el Binary Security Token a partir del mcertificado
set x509alias = ##class(Util.TablasMaestras).getValorMaestra("PARAMETROS","aliasCertMSSSI")
set pwd = ##class(Util.TablasMaestras).getValorMaestra("PARAMETROS","pwdCertMSSSI")
set cred = ##class(%SYS.X509Credentials).GetByAlias(x509alias,pwd)
set token = ##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(cred)
//Creamos la firma
//set sig1=##class(%XML.Security.Signature).CreateX509(token,,$$$KeyInfoX509IssuerSerial)
//set sig2=##class(%XML.Security.Signature).CreateX509(token,$$$SOAPWSIncludeSoapBody,$$$SOAPWSReferenceDirect)
set sig2=##class(%XML.Security.Signature).CreateX509(token,$$$SOAPWSIncludeDefault,$$$SOAPWSReferenceDirect)
//do sig1.SetSignatureMethod($$$SOAPWSrsasha1)
do sig2.SetSignatureMethod($$$SOAPWSrsasha1)
//do sig1.SetDigestMethod($$$SOAPWSsha1)
do sig2.SetDigestMethod($$$SOAPWSsha1)
//Creamos la referencia al id del token generado a partir de la firma
//set algorithm=$$$SOAPWSEnvelopedSignature_","_$$$SOAPWSc14n
set reference=##class(%XML.Security.Reference).Create(token.Id)
do sig2.AddReference(reference)
//Crear TimeStamp
Set timestamp=##class(%SOAP.Security.Timestamp).Create()
//Se une
//do ..SecurityOut.AddElement(sig1)
do ..SecurityOut.AddToken(token)
do ..SecurityOut.AddElement(sig2)
Do ..SecurityOut.AddToken(timestamp)
}
}El sistema destino, nos pide por favor, que implementemos un WebService con MTOM y que envie los zip con csv de la siguiente forma:
.png)
Al importar el WSDL del sistema destino, se nos generó la cabecera del método "cargarFichero" con "fichero" como un "%xsd.base64Binary"
Siguiendo tus indicaciones, hemos cambiado fichero por "%GlobalCharacterStream"
De esta forma se envía el fichero, el csv, sin codificar, dentro de un CDATA
.png)
Siendo la respuesta del sistema destino:
10/15/2021 08:57:24 *********************
Input to Web client with SOAP action = http://ws.regvacuWs.ms.es/FicheroVacu/cargarFichero
--MIME_Boundary
Content-ID: <root.message@cxf.apache.org>
Content-Type: application/xop+xml; type="text/xml"; charset=utf-8
Content-Transfer-Encoding: 8bit
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Name must not be null</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
--MIME_Boundary--
---------------
Validate Security header: action=http://ws.regvacuWs.ms.es/FicheroVacu/cargarFichero, MethodName=cargarFichero
**** SOAP client return error. method=cargarFichero, action=http://ws.regvacuWs.ms.es/FicheroVacu/cargarFichero
ERROR #6248: La respuesta de SOAP es un error de SOAP: faultcode=Server
faultstring=Name must not be null
faultactor=
detail=Sin embargo, como observamos en la primera imagen, el sistema destino necesitaría, requeriría, que le enviemos el fichero codificado en binario, ya que pone:
Content-Transfer-Encoding: binary
Cuando adaptamos el fichero para que sea "%GlobalBinaryStream" vemos la siguiente traza, donde sí se codifica en binario:
.png)
Al enviar codificado en binario, el sistema destino también responde:
09/28/2021 16:56:43 *********************
Input to Web client with SOAP action = http://ws.regvacuWs.ms.es/FicheroVacu/cargarFichero
--MIME_Boundary
Content-ID: <root.message@cxf.apache.org>
Content-Type: application/xop+xml; type="text/xml"; charset=utf-8
Content-Transfer-Encoding: 8bit
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Name must not be null</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
--MIME_Boundary--
---------------
Validate Security header: action=http://ws.regvacuWs.ms.es/FicheroVacu/cargarFichero, MethodName=cargarFichero
**** SOAP client return error. method=cargarFichero, action=http://ws.regvacuWs.ms.es/FicheroVacu/cargarFichero
ERROR #6248: La respuesta de SOAP es un error de SOAP: faultcode=Server
faultstring=Name must not be null
faultactor=
detail=En resumen, el sistema destino necesita de nosotros: "añadir el parámetro “name” dentro de la cabecera “Content-Type” al adjuntar el archivo. Vuestro cliente debería generar dicho parámetro para no obtener dicho error."
Siendo la comparativa completa entre lo enviado por ensemble (sin el parámetro "name", por lo tanto es incorrecto) a la izquierda; y lo generado por el SoapUI (con el parámetro name, correcto), a la derecha:

Por favor, ustedes ¿podrían indicarnos ejemplos, documentación, proyectos, código, que nos sirva de referencia para indagar, investigar y completar el desarrollo?
Además hemos investigado las siguientes respuestas:
https://community.intersystems.com/post/add-parameter-name-inside-conte…
Muchas gracias por su tiempo, leyendo y respondiendo, gracias
- Inicie sesión para enviar comentarios
.png)
.png)

.png)
.png)

.png)
.png)











.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
