Docs Italia beta

Documenti pubblici, digitali.

6.1.2. [NONBLOCK_PUSH_SOAP] Not Blocking Push SOAP

Nel caso di implementazione mediante tecnologia SOAP, l’endpoint di callback ed il CorrelationID, vengono inseriti all’interno dell’header SOAP come campi custom. Erogatore e fruitore DEVONO inoltre seguire le seguenti regole:

  • Le specifiche delle interfacce del fruitore e dell’erogatore DEVONO dichiarare tutti i metodi esposti con relativi schemi dei messaggi di richiesta e di ritorno. Inoltre le interfacce devono specificare eventuali header SOAP richiesti;
  • La specifica dell’interfaccia del fruitore DEVE rispettare quanto richiesto dall’erogatore; in particolare si richiede che l’erogatore fornisca un WSDL descrittivo del servizio di callback che il fruitore è tenuto ad implementare;
  • Al passo (1), il fruitore DEVE indicare l’endpoint della callback utilizzando l’header SOAP custom X-ReplyTo;
  • Al passo (2), l’erogatore DEVE fornire insieme all’acknowledgement della richiesta nel body, il CorrelationID utilizzando l’header SOAP custom X-Correlation-ID;
  • Al passo (3), l’erogatore DEVE utilizzare lo stesso CorrelationID fornito al passo (2) sempre utilizzando l’header SOAP custom X-Correlation-ID;
  • Al passo (4), il fruitore DEVE riconoscere tramite un messaggio di acknowledgement il ricevimento della risposta.

6.1.2.1. Regole di processamento

Nel caso di errore il WS-I Basic Profile Version 2.0 richiede l’utilizzo del meccanismo della SOAP fault per descrivere i dettagli dell’errore. In particolare, al ricevimento della richiesta, fruitore ed erogatore:

  • DEVONO verificare la validità sintattica dei dati in ingresso. In caso di dati errati DEVONO restituire HTTP status 500 Internal Server Error fornendo dettagli circa l’errore, utilizzando il meccanismo della SOAP fault;
  • Nel caso in cui qualcuno degli ID nel path o nel body non esista, DEVONO restituire HTTP status 500 Internal Server Error, indicando nel body di risposta quale degli ID è mancante;
  • Se ipotizzano che la richiesta sia malevola POSSONO ritornare HTTP status 400 Bad Request o HTTP status 404 Not Found
  • In caso di errori non dipendenti dal fruitore, DEVE restituire i codici HTTP 5XX rispettando la semantica degli stessi o restituire il codice HTTP status 500 indicando il motivo dell’errore nella SOAP fault;
  • Al momento della ricezione della richiesta, DEVONO restituire un codice 2XX, nel dettaglio:
    • HTTP status 200 OK in caso di presenza della payload SOAP, riempiendo il body di risposta con il risultato relativo alla richiesta.
    • HTTP status 200 OK o HTTP status 202 Accepted in caso di assenza della payload SOAP
  • Nel caso di errore al momento di ricezione della risposta da parte del richiedente (fruitore o erogatore), è possibile definire meccanismi specifici per la ri-trasmettere le richieste.

6.1.2.2. Esempio

Specifica Servizio Erogatore

https://api.ente.example/soap/nome-api/v1?wsdl

<?xml version="1.0"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://ente.example/nome-api"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/" 
    name="SOAPCallbackServerService" 
    targetNamespace="http://ente.example/nome-api">
    <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:tns="http://ente.example/nome-api" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://ente.example/nome-api">

            <xs:element name="MRequest" type="tns:MRequest"/>
            <xs:element name="MRequestResponse" type="tns:MRequestResponse"/>

            <xs:element name="ErrorMessageFault" nillable="true" type="tns:errorMessageFault"/>
            <xs:element name="X-ReplyTo" nillable="true" type="xs:string"/>
            <xs:element name="X-Correlation-ID" nillable="true" type="xs:string"/>

            <xs:complexType name="MRequest">
                <xs:sequence>
                    <xs:element minOccurs="0" name="M" type="tns:mType"/>
                </xs:sequence>
            </xs:complexType>

            <xs:complexType name="mType">
                <xs:sequence>
                    <xs:element minOccurs="0" name="o_id" type="xs:int"/>
                    <xs:element minOccurs="0" name="a" type="tns:aComplexType"/>
                    <xs:element minOccurs="0" name="b" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>

            <xs:complexType name="aComplexType">
                <xs:sequence>
                    <xs:element maxOccurs="unbounded" minOccurs="0" name="a1s" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="a2" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>

            <xs:complexType name="MRequestResponse">
                <xs:sequence>
                    <xs:element minOccurs="0" name="return" type="tns:ackMessage"/>
                </xs:sequence>
            </xs:complexType>

            <xs:complexType name="ackMessage">
                <xs:sequence>
                    <xs:element minOccurs="0" name="outcome" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>

            <xs:complexType name="errorMessageFault">
                <xs:sequence>
                    <xs:element minOccurs="0" name="customFaultCode" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:schema>
    </wsdl:types>

    <wsdl:message name="MRequest">
        <wsdl:part element="tns:MRequest" name="parameters"/>
        <wsdl:part element="tns:X-ReplyTo" name="X-ReplyTo"/>
    </wsdl:message>

    <wsdl:message name="MRequestResponse">
        <wsdl:part element="tns:MRequestResponse" name="result"/>
        <wsdl:part element="tns:X-Correlation-ID" name="X-Correlation-ID"/>
    </wsdl:message>

    <wsdl:message name="ErrorMessageException">
        <wsdl:part element="tns:ErrorMessageFault" name="ErrorMessageException"/>
    </wsdl:message>

    <wsdl:portType name="SOAPCallback">
        <wsdl:operation name="MRequest">
            <wsdl:input message="tns:MRequest" name="MRequest"/>
            <wsdl:output message="tns:MRequestResponse" name="MRequestResponse"/>
            <wsdl:fault message="tns:ErrorMessageException" name="ErrorMessageException"/>
        </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="SOAPCallbackServiceSoapBinding" type="tns:SOAPCallback">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="MRequest">
            <soap:operation soapAction="" style="document"/>
            <wsdl:input name="MRequest">
                <soap:header message="tns:MRequest" part="X-ReplyTo" use="literal"/>
                <soap:body parts="parameters" use="literal"/>
            </wsdl:input>
            <wsdl:output name="MRequestResponse">
                <soap:header message="tns:MRequestResponse" part="X-Correlation-ID" use="literal"/>
                <soap:body parts="result" use="literal"/>
            </wsdl:output>
            <wsdl:fault name="ErrorMessageException">
                <soap:fault name="ErrorMessageException" use="literal"/>
            </wsdl:fault>
        </wsdl:operation>
    </wsdl:binding>

    <wsdl:service name="SOAPCallbackService">
        <wsdl:port name="SOAPCallbackPort" binding="tns:SOAPCallbackServiceSoapBinding">
            <soap:address location="https://api.ente.example/soap/nome-api/v1"/>
        </wsdl:port>
    </wsdl:service>

</wsdl:definitions>

Specifica Servizio Fruitore (callback)

https://api.client.example/soap/nome-api/v1?wsdl

<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://ente.example/nome-api"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/" 
    name="SOAPCallbackClientInterfaceService" 
    targetNamespace="http://ente.example/nome-api">
    <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:tns="http://ente.example/nome-api" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://ente.example/nome-api">

            <xs:element name="MRequestResponse" type="tns:MRequestResponse"/>

            <xs:element name="MRequestResponseResponse" type="tns:MRequestResponseResponse"/>
            
            <xs:element name="X-Correlation-ID" nillable="true" type="xs:string"/>

            <xs:complexType name="MRequestResponse">
                <xs:sequence>
                    <xs:element minOccurs="0" name="return" type="tns:mResponseType"/>
                </xs:sequence>
            </xs:complexType>

            <xs:complexType name="mResponseType">
                <xs:sequence>
                    <xs:element minOccurs="0" name="c" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>

            <xs:complexType name="MRequestResponseResponse">
                <xs:sequence>
                    <xs:element minOccurs="0" name="return" type="tns:ackMessage"/>
                </xs:sequence>
            </xs:complexType>

            <xs:complexType name="ackMessage">
                <xs:sequence>
                    <xs:element minOccurs="0" name="outcome" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:schema>
    </wsdl:types>

    <wsdl:message name="MRequestResponse">
        <wsdl:part element="tns:MRequestResponse" name="parameters"/>
        <wsdl:part element="tns:X-Correlation-ID" name="X-Correlation-ID"/>
    </wsdl:message>

    <wsdl:message name="MRequestResponseResponse">
        <wsdl:part element="tns:MRequestResponseResponse" name="result"/>
    </wsdl:message>

    <wsdl:portType name="SOAPCallbackClient">
        <wsdl:operation name="MRequestResponse">
            <wsdl:input message="tns:MRequestResponse" name="MRequestResponse"/>
            <wsdl:output message="tns:MRequestResponseResponse" name="MRequestResponseResponse"/>
        </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="SOAPCallbackClientServiceSoapBinding" type="tns:SOAPCallbackClient">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="MRequestResponse">
            <soap:operation soapAction="" style="document"/>
            <wsdl:input name="MRequestResponse">
                <soap:header message="tns:MRequestResponse" part="X-Correlation-ID" use="literal"/>
                <soap:body parts="parameters" use="literal"/>
            </wsdl:input>
            <wsdl:output name="MRequestResponseResponse">
                <soap:body parts="result" use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    
    <wsdl:service name="SOAPCallbackClientService">
        <wsdl:port binding="tns:SOAPCallbackClientServiceSoapBinding" name="SOAPCallbackClientPort">
            <soap:address location="https://api.client.example/soap/nome-api/v1"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

Segue un esempio di chiamata al metodo M in cui l’erogatore conferma di essersi preso carico della richiesta.

Endpoint

https://api.ente.example/soap/nome-api/v1

Method M

  1. Request Body
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
    xmlns:m="http://ente.example/nome-api">
    <soap:Header>
        <m:X-ReplyTo>https://api.client.example/soap/nome-api/v1</m:X-ReplyTo>
    </soap:Header>
    <soap:Body>
        <m:MRequest>
            <M>
                <o_id>1234</o_id>
                <a>
                    <a1s>1</a1s>
                    <a2>prova</a2>
                </a>
                <b>prova</b>
            </M>
        </m:MRequest>
    </soap:Body>
</soap:Envelope>
  1. Response Body
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
    xmlns:m="http://ente.example/nome-api">>
    <soap:Header>
        <m:X-Correlation-ID>b8268033-de67-4fa0-bf06-caebbfa5117a</m:X-Correlation-ID>
    </soap:Header>
    <soap:Body>
        <m:MRequestResponse>
            <return>
                <outcome>ACCEPTED</outcome>
            </return>
        </m:MRequestResponse>
    </soap:Body>
</soap:Envelope>

Di seguito un esempio di richiesta da parte dell’erogatore verso la callback del fruitore.

Endpoint

https://api.client.example/soap/nomeinterfacciaclient/v1Method

MRequestResponse

  1. Request Body
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
    xmlns:m="http://ente.example/nome-api">
    <soap:Header>
        <m:X-Correlation-ID>b8268033-de67-4fa0-bf06-caebbfa5117a</m:X-Correlation-ID>
    </soap:Header>
    <soap:Body>
        <m:MRequestResponse>
            <return>
                <c>OK</c>
            </return>
        </m:MRequestResponse>
    </soap:Body>
</soap:Envelope>
  1. Response Body
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
    xmlns:m="http://ente.example/nome-api">
    <soap:Body>
        <m:MRequestResponseResponse>
            <return>
                <outcome>OK</outcome>
            </return>
        </m:MRequestResponseResponse>
    </soap:Body>
</soap:Envelope>