SDK-CART Versione 1.1 20/04/2008
Indice dei Contenuti 1 INTRODUZIONE...2 2 L USO DEL COMPONENTE DI INTEGRAZIONE DELLA PORTA DI DOMINIO... 2 2.1 Modalità d'uso trasparente dei Servizi...3 2.2 Uso del Servizio IntegrationManager... 4 2.2.1 Invocazione di una porta delegata tramite Integration Manager...7 2.2.2 Accesso ai messaggi ricevuti tramite Integration Manager...7 3 CONTENUTI DELLE RISPOSTE APPLICATIVE...9 4 LA GESTIONE DEGLI ERRORI NELL'INTERAZIONE TRA SERVIZIO APPLICATIVO E PORTA DELEGATA...10 5 ASPETTI DI INTEGRAZIONE NEI PROFILI ASINCRONI...13 6 INTERSCAMBIO DI INFORMAZIONI TRA SIL E PDD...15 6.1 Integrazione tramite QUERY_STRING...16 6.2 Integrazione tramite l uso dell Header SOAP etoscana... 17 7 USO DEL MECCAMISMO DEI FILTRI NELL HEADER SOAP FCA...19 Impostazione delle proprietà da parte del SIL Pubblicatore...19 ALLEGATO A: INTERFACCIA WSDL DEL SERVIZIO DI INTEGRATIONMANAGER...22 ALLEGATO B : HEADER SOAP ETOSCANA...32 DOMANDE FREQUENTI...33 gestione degli allegati...33 2 di 36
1 INTRODUZIONE Nella specifica SPCoop, un dominio è definito come il confine di responsabilità di un ente o soggetto amministrativo e racchiude al suo interno tutte le applicazioni da esso gestite. Il confine applicativo del Dominio è rappresentato dalla Porta di Dominio (PdD), attraverso la quale devono transitare tutte le comunicazioni da e verso il dominio. Le Porte di Dominio si parlano tra di loro scambiandosi richieste e risposte in un formato parte della specifica SPCoop, denominato busta egov. Tuttavia il formato della busta non è parlato nativamente dalle applicazioni, pertanto la Porta di Dominio deve anche occuparsi di convertire le richieste applicative nel formato busta egov. Facendo riferimento a questa problematica, i compiti della Porta di Dominio vengono solitamente classificati in due componenti: il componente di cooperazione, che riguarda la comunicazione tra le Porte di Dominio e quello di integrazione, che riguarda la comunicazione tra i Servizi Applicativi dell Ente e la Porta di Dominio. Il componente di integrazione si differenzia a sua volta in due diversi moduli: la porta delegata e la porta applicativa. In particolare la porta delegata è utilizzata come proxy per l accesso al servizio destinazione, mentre la porta applicativa deve essere in grado di gestire la consegna dei contenuti delle buste egov ricevute al corrispondente servizio applicativo interno al dominio destinazione. Differentemente da quanto avviene per il componente di cooperazione (busta egov), per il componente di integrazione la specifica SPCoop si limita a presentare un esempio di massima di una sua possibile realizzazione. Al fine di uniformare le interfacce del livello applicativo verso l infrastruttura CARTE, in questo documento vengono quindi presentate le interfacce esposte dalle Porte di Dominio verso i Servizi Applicativi. 2 L USO DEL COMPONENTE DI INTEGRAZIONE DELLA PORTA DI DOMINIO Le interazioni tra i servizi applicativi e le porte delegate e applicative delle Porte di Dominio che li ospitano devono avvenire tramite richieste SOAP 1.1 su protocollo https. Ogni richiesta del Servizio Applicativo deve essere autenticata dalla Porta tramite certificati X.509. In alcuni casi particolari potrà essere permessa anche l utenticazione basic/http. In generale le interazioni tra i servizi applicativi e la porta di dominio possono avvenire in due modi: 1. modalità trasparente: prevede che il servizio applicativo utilizzi (in caso di porta delegata) o esponga (in caso di porta applicativa) le 3 di 36
interfacce applicative native dei servizi, esattamente come registrate negli accordi di servizio; in tal caso la Porta di Dominio agisce come un proxy trasparente con funzionalità di imbustamento e sbustamento egov dei messaggi applicativi; utilizzando questa modalità, gli applicativi potranno continuare ad operare esattamente come se stessero interagendo direttamente con il servizio applicativo dell'altro Ente; 2. uso del Servizio Integration Manager della PdD: prevede di utilizzare le interfacce di un apposito web service di Integrazione, messo a disposizione dalla Porta di Dominio per la spedizione e/o la ricezione di messaggi applicativi da parte dei servizi applicativi del proprio Dominio di Servizi. 2.1 MODALITÀ D'USO TRASPARENTE DEI SERVIZI Questa modalità prevede che il servizio applicativo utilizzi (in caso di porta delegata) o esponga (in caso di porta applicativa) le interfacce applicative native dei servizi, così come registrate negli accordi di servizio; in tal caso la Porta di Dominio agisce come un proxy SOAP trasparente con funzionalità di imbustamento e sbustamento egov dei messaggi applicativi; utilizzando questa modalità, gli applicativi potranno quindi continuare ad operare esattamente come se stessero interagendo direttamente con il servizio applicativo dell'altro Ente. L'invocazione della porta delegata in modalità trasparente può essere realizzata tramite gli strumenti del linguaggio di programmazione nativo del servizio applicativo, utilizzando ad esempio stub creati tramite il proprio ambiente di sviluppo Web Services (ad esempio wsdl2java in Axis), facendo riferimento direttamente al WSDL del servizio da utilizzare, così come registrato nell'accordo di servizio. In questo caso la principale modifica rispetto all'invocazione dell'effettivo servizio destinazione sarà la URL utilizzata per l'invocazione http, che dovrà essere quella corrispondente alla porta delegata del servizio esposta dalla PdD. Il codice che segue mostra un esempio, usando Axis 1.4, di invocazione di una porta delegata usando gli stub del servizio. try { HelloWSServiceLocator locator = new HelloWSServiceLocator(); Locator.setHelloWorldEndpointAddress("http://nal/cart/PD/HelloWorld "); HelloWS port = locator.gethelloworld(); 4 di 36
String msg = port.sayhello(); } catch (AxisFault e) { } Come si può notare, è sufficiente settare l endpoint del servizio alla URL della Porta Delegata da indirizzare, senza ulteriori modifiche al codice applicativo. Ovviamente non è obbligatorio utilizzare degli stub per l invocazione del servizio, ma si può utilizzare qualunque altra modalità supportata dal proprio ambiente di lavoro per la programmazione di web services. 2.2 USO DEL SERVIZIO INTEGRATIONMANAGER Prevede di utilizzare le interfacce di un apposito web service di Integrazione, messo a disposizione dalla Porta di Dominio per la spedizione e/o la ricezione di messaggi applicativi da parte dei servizi applicativi del proprio Dominio di Servizi. L'interfaccia WSDL completa dell'integration manager è disponibile in allegato A. A titolo descrittivo si mostra di seguito l'interfaccia esposta dal Web Service, espressa in linguaggio java: interface IntegrationManager { SPCoopMessage invocaportadelegata( String portadelegata, SPCoopMessage msg) SPCoopMessage sendrispostaasincronasimmetrica( String portadelegata,spcoopmessage msg) String[] getallmessagesid() String[] getallmessagesidbyservice( String tiposervizio, String servizio, String azione) String[] getnextmessagesid(int n) String[] getnextmessagesidbyservice( int n, String tiposervizio, String servizio, String azione) 5 di 36
SPCoopMessage getmessage(string idegov) SPCoopMessage getmessagebyreference(string riferimentomsg) void deletemessage(string idegov) void deletemessagebyreference(string riferimentomsg) public void deleteallmessages() } L'oggetto di base su cui lavorano le varie operazioni supportate dall IntegrationManager è l SPCoopMessage, che contiene varie informazioni relative al messaggio e un array di byte corrispondente al messaggio SOAP vero e proprio. La struttura della classe SPCoopMessage è mostrata a titolo descrittivo in linguaggio java nel riquadro seguente. public class SPCoopMessage implements java.io.serializable { public void setmessage(byte [] m) public byte[] getmessage() public boolean getimbustamento() public void setimbustamento(boolean imbustamento) public String getidapplicativo() public void setidapplicativo(string applicativo) public String getservizioapplicativo() public void setservizioapplicativo(string servizioapplicativo) public SPCoopHeaderInfo getspcoopheaderinfo() 6 di 36
public void setspcoopheaderinfo(spcoopheaderinfo spcoopheaderinfo) } Come risulta dalla struttura della classe mostrata nel riquadro precedente, l oggetto SPCoopMessage riferisce un ulteriore oggetto di tipo SPCoopHeaderInfo che raccoglie tutte le informazioni relative all header SPCoop della busta egov accessibili dai servizi applicativi. La struttura della classe SPCoopHeaderInfo è mostrata a titolo descrittivo in linguaggio java nel riquadro seguente. public class SPCoopHeaderInfo implements java.io.serializable { public String gettipomittente() public void settipomittente(string type ) public String getmittente() public void setmittente(string m ) public String gettipodestinatario() public void settipodestinatario(string type ) public String getdestinatario() public void setdestinatario(string s ) public String getservizio() public void setservizio(string s ) public String gettiposervizio() public void settiposervizio(string type ) public String getazione() 7 di 36
public void setazione(string a ) public String getid() public void setid(string id ) public String getriferimentomessaggio() public void setriferimentomessaggio(string rif ) public String getidcollaborazione() public void setidcollaborazione(string idcollaborazione) } 2.2.1 INVOCAZIONE DI UNA PORTA DELEGATA TRAMITE INTEGRATION MANAGER Il codice che segue mostra un esempio, in Axis 1.4, di invocazione di una porta delegata usando il servizio di IntegrationManager. IntegrationManagerServiceLocator locator = new IntegrationManagerServiceLocator(); locator.setintegrationmanagerendpointaddress(imurl); port = locator.getintegrationmanager(username,password); // Costruzione Messaggio SPCoop msg = new SPCoopMessage(); // soapmessagetosend è il messaggio SOAP da spedire // espresso come array di byte msg.setmessage(soapmessagetosend); try { 8 di 36
SPCoopMessage msgresponse = port.invocaportadelegata(locationpd,msg); } catch(exception e){ } System.out.println("ClientError: "+e.getmessage()); 2.2.2 ACCESSO AI MESSAGGI RICEVUTI TRAMITE INTEGRATION MANAGER Il codice che segue mostra un esempio, in axis 1.4, di accesso ai messaggi ricevuti su una porta applicativa usando il servizio di IntegrationManager. IntegrationManagerServiceLocator locator = new IntegrationManagerServiceLocator(); locator.setintegrationmanagerendpointaddress(integrationmanagerurl); port = locator.getintegrationmanager(username,password); String []ids = port.getallmessagesid(); for (int i=0; i<ids.length; i++ ) { SPCoopMessage msg = port.getmessage(ids[i]); // processa il messaggio ricevuto come byte array... processmessage(msg.getmessage()); } deletemessage(ids[i]); Nell esempio precedente viene prima utilizzata l operazione getallmessagesid per accedere all elenco dei messaggi ricevuti e quindi l operazione di getmessage per prelevare i singoli messaggi. Dopo il processamento di un messaggio, si procede alla sua rimozione. Oltre a questi due metodi di base, il servizio di IntegrationManager fornisce ulteriori interfacce per gestire in vario modo i messaggi in arrivo per un SIL. 9 di 36
Nel riquadro successivo vengono elencate le varie interfacce utili per l accesso ai messaggi. String[] getallmessagesid() // restituisce gli identificatori di tutti i messaggi disponibili // in coda per il SIL richiedente String[] getallmessagesidbyservice( String tiposervizio, String servizio, String azione) // restituisce gli identificatori di tutti i messaggi disponibili in // coda per il SIL corrispondente al servizio ed all azione // indicati in input String[] getnextmessagesid(int n) // restituisce i primi n identificatori di messaggi disponibili // in coda per il SIL String[] getnextmessagesidbyservice( int n, String tiposervizio, String servizio, String azione) // restituisce i primi n identificatori di messaggi disponibili // in coda per il SIL corrispondenti al servizio ed all azione // indicati in input SPCoopMessage getmessage(string idegov) // restituisce il messaggio identificato dall identificatore in input SPCoopMessage getmessagebyreference(string riferimentomsg) // restituisce il messaggio identificato dall identificatore 10 di 36
// di riferimentomessaggio in input void deletemessage(string idegov) // cancella il messaggio identificato dall id in input void deletemessagebyreference(string riferimentomsg) // cancella il messaggio identificato dall id di riferimentomessaggio // in input public void deleteallmessages() // cancella tutti i messaggi in coda per il SIL richiedente 3 CONTENUTI DELLE RISPOSTE APPLICATIVE Nel caso del profilo Sincrono, le risposte (ricevute dalla PdD nel caso di invocazioni della porta delegata o inviate dalla PdD nel caso di invocazioni dei Servizi Applicativi abbinati alle Porte Applicative), sono direttamente generate dai Servizi Applicativi erogatori e trasparentemente restituiti dalla PdD ai servizi fruitori. La stessa cosa succede per i profili Asincroni Simmetrico e Asimmetrico, che corrispondono concettualmente ad una coppia di interazioni sincrone correlate tra loro. Per questo motivo, l Integration Manager non può essere usato per l accesso ai messaggi ricevuti dai servizi applicativi con profili Sincroni ed Asincroni. Infatti questi messaggi non possono essere tenuti dalla Porta di Dominio in attesa di una successiva richiesta del SIL, ma devono essere immediatamente girati al servizio applicativo per poter ottenere la risposta da girare al richiedente. Nel caso del profilo Oneway, invece, la PdD mittente restituisce la risposta al servizio fruitore immediatamente, senza attendere di ricevere una risposta dal servizio applicativo erogatore del servizio. In questo caso il servizio fruitore riceverà quindi una risposta creata dalla PdD con SOAP body vuoto. 11 di 36
4 LA GESTIONE DEGLI ERRORI NELL'INTERAZIONE TRA SERVIZIO APPLICATIVO E PORTA DELEGATA In funzione del fatto che si usi la modalità di invocazione trasparente o i servizi dell'integrationmanager per l invocazione di una porta delegata della Porta di Dominio, cambia il modo in cui le condizioni di errore vengono gestite dal servizio applicativo. Nel caso in cui si usino i servizi dell'integrationmanager eventuali condizioni di errore generate dalla Porta di Dominio saranno restituite all'interno di un eccezione gestita dal servizio IntegrationManager, il cui formato è rappresentato di seguito in linguaggio java. public class SPCoopException { public java.lang.string getcodiceeccezione(); public void setcodiceeccezione(java.lang.string codiceeccezione); public java.lang.string getdescrizioneeccezione(); public void setdescrizioneeccezione(java.lang.string descrizioneeccezione); public java.lang.string getidentificativofunzione(); public void setidentificativofunzione(java.lang.string identificativofunzione); public java.lang.string getidentificativoporta(); public void setidentificativoporta(java.lang.string identificativoporta); public java.lang.string getoraregistrazione(); public void setoraregistrazione(java.lang.string oraregistrazione); } public java.lang.string gettipoeccezione(); public void settipoeccezione(java.lang.string tipoeccezione); 12 di 36
Le eventuali eccezioni generate dal Servizio Applicativo originale saranno invece trasportate come SOAPFault all interno del campo messaggio dell oggetto SPCoopMessage. Nel caso in cui si utilizzi la modalità trasparente, sarà invece possibile, in caso di eccezione SOAPFault, testare il campo FaultActor per riconoscere e gestire i casi di errore dovuti all'interazione con la porta di dominio (valore "it.toscana.regione.cart.pdd") da quelli puramente applicativi. Nel frammento di codice seguente vediamo, a titolo di esempio, come gestire questa situzione nel caso specifico del linguaggio java usando Axis 1.4 come webservices engine. try { HelloWSServiceLocator locator = new HelloWSServiceLocator(); locator.sethelloworldendpointaddress("http://nal/carte/pd/getdate"); HelloWS port = locator.gethelloworld(); String msg = port.sayhello(); } catch (AxisFault e) { if("it.toscana.regione.cart.pdd".equals(e.getfaultactor())){ System.out.println("Ricevuto Messaggio di Errore PdD[" + e.getfaultcode() + "]:"); System.out.println(e.getFaultString()); }else{ System.out.println("Ricevuto SOAPFault applicativo"); System.out.println("Actor: "+e.getfaultactor()); System.out.println("Code: "+e.getfaultcode()); System.out.println("String: "+e.getfaultstring()); } } catch (Exception e) { 13 di 36
System.out.println("ClientError: "+e.getmessage()); e.printstacktrace(); } Come evidenziato nell'esempio, il particolare codice di eccezione generato dalla Porta di Dominio potrà essere ottenuto tramite il campo FaultCode del messaggio di Fault. In entrambi gli approcci, in caso di errore, la Porta di Dominio restituirà gli stessi codici di errore, elencati nella tabella seguente. FaultCode FaultString CART_500 Porta di Dominio Temporaneamente non Disponibile CART_401 Porta Delegata Inesistente CART_402 Autenticazione Fallita CART_403 Pattern Ricerca Porta Delegata Non Valido CART_404 Autorizzazione Fallita CART_405 Servizio SPCoop abbinato alla Porta Delegata Inesistente CART_406 Nessun Messaggio disponibile per il Servizio Applicativo CART_407 Messaggio Richiesto Inesistente CART_4XX Generico errore client I servizi applicativi sono tenuti a gestire tutti gli errori generati dalla PdD, trattenendo i messaggi che hanno generato errore per una successiva rispedizione. In particolare, in caso di errore CART_500, il servizio applicativo è tenuto a sospendere temporaneamente per un tempo calcolato in maniera random, la spedizione di messaggi, in modo da favorire il decongestionamento dell infrastruttura. 5 ASPETTI DI INTEGRAZIONE NEI PROFILI ASINCRONI I profili di collaborazione Asincroni, sia Simmetrici che Asimmetrici, al contrario degli altri profili previsti in SPCoop (Oneway e Sincrono) richiedono due interazioni, una richiesta di servizio ed una risposta del servizio che viene ritornata tramite una nuova interazione. Le buste egov prodotte sono quindi quattro (due per ogni interazione) e vengono correlate tra di loro 14 di 36
attraverso l identificativo egov. Pertanto i servizi applicativi devono necessariamente scambiare con la porta di dominio l informazione relativa all'id egov utilizzato per la correlazione tra la richiesta e la successiva risposta. Nel caso si usi il servizio di IntegrationManager della Porta di Dominio è possibile utilizzare le interfacce di questo servizio per lo scambio dell id egov necessario per la correlazione. Nel caso in cui si utilizzi la modalità trasparente per l invocazione dei servizi Asincroni, sarà invece possibile utilizzare header del trasporto http, dovendo l'interfaccia applicativa rimanere quella originale del servizio applicativo invocato. Il codice che segue mostra un esempio di transazione asincrona asimmetrica tramite IntegrationManager. SPCoopMessage msg1 = new SPCoopMessage(); msg1.setmessage(soapmessagerichiesta); // invio richiesta asincrona e prelievo dell id di correlazione SPCoopMessage msg1response = port.invocaportadelegata( portadelegatarichiesta,msg1); idegovrichiesta = msg1response.getid(); // Costruzione SPCoopHeaderInfo SPCoopHeaderInfo spcoopheaderinfo = new SPCoopHeaderInfo(); spcoopheaderinfo.setriferimentomessaggio(riferimentomessaggio); msg.setidapplicativo(idcorrelazioneapplicativa); ioapplicativo); msg.setservizioapplicativo(nomeserviz... // settaggio dell id di correlazione ed invio richiesta stato SPCoopMessage msg2 = new SPCoopMessage(); 15 di 36
msg2.setmessage(soapmessagerichiestastato); SPCoopHeaderInfo spcoopheaderinfo2 = new SPCoopHeaderInfo(); spcoopheaderinfo2.setriferimentomessaggio(idegovrichiesta); msg2.setspcoopheaderinfo(spcoopheaderinfo2); SPCoopMessage msg2response = port.invocaportadelegata(portadelegatarichiestastato, msg2); Come evidenziato nell esempio, la correlazione della richiesta con la risposta, avviene prelevando l IDEgov della prima richiesta tramite il metodo getid, e settandolo come riferimentomessaggio della seconda richiesta tramite il metodo setriferimentomessaggio. Nel caso in cui si usi la modalità trasparente, le informazioni di correlazione potranno essere gestite tramite le proprietà SPCoopID ed SPCoopRiferimentoMessaggio, accessibili come mostrato nella successiva sezione 6 Interscambio di Informazioni tra SIL e PdD. Il codice che segue mostra un esempio di utilizzo della modalità trasparente usando gli header del protocollo http come modalità di interscambio delle informazioni tra SIL e PdD. URL url = new URL(UrlPortaDelegataRichiesta); HttpURLConnection httpcon1 = (HttpURLConnection)url.openConnection();... OutputStream out = httpcon1.getoutputstream(); out.write(soapmessagerichiesta); out.close();... String idegov = httpcon1.getheaderfields().get("spcoopid");... url = new URL(UrlPortaDelegataRichiestaStato); HttpURLConnection httpcon2 = (HttpURLConnection)url.openConnection();... 16 di 36
httpcon2.setrequestproperty("spcoopriferimentomessaggio", idegov); OutputStream out = httpcon2.getoutputstream(); out.write(soapmessagerichiestastato); out.close();... 6 INTERSCAMBIO DI INFORMAZIONI TRA SIL E PDD Alcune delle informazioni parte dell header SPCoop della busta egov possono essere scambiate tra il SIL e la PdD al momento dell invocazione di una porta delegata o tra la PdD ed il SIL al momento dell invocazione di una porta applicativa. In particolare le informazioni in questione variano in funzione delle specifiche precipuità degli Accordi di Servizio a cui la busta si riferisce e sono identificate tramite le seguenti keyword: SpCoopID SPCoopTipoMittente SPCoopMittente SPCoopTipoDestinatario SPCoopDestinatario SPCoopTipoServizio SPCoopServizio SPCoopAzione SPCoopRiferimentoMessaggio SPCoopIdCollaborazione Nel caso di uso dell IntegrationManager, tali informazioni sono accessibili tramite le interfacce di get/set della classe SPCoopHeaderInfo, già mostrata in precedenza. Nel caso di uso della modalità trasparente, tali informazioni sono invece accessibili tramite tre diverse modalità: 1. come header del trasporto http: in questo caso i nomi degli header saranno uguali alle informazioni sopra elencate; 2. come proprietà della QUERY_STRING della URL http invocata: in questo caso il nome della proprietà saranno uguali alle informazioni sopra elencate; 17 di 36
3. come informazioni interne all header SOAP etoscana, appositamente definito per l interscambio di tali informazioni nel CART; in questo caso le informazioni saranno rappresentate in accordo all xsd dell header etoscana riportato in appendice B. Va notato che la PdD del CART accetta in input e produce in output le informazioni necessarie usando contemporaneamente tutti le 3 modalità appena elencate. E quindi possibile, per il programmatore dei servizi applicativi, usare indifferentemente uno qualunque di tali modalità. Abbiamo già mostrato un esempio d uso dell interscambio di informazioni tra SIL e PdD sia tramite l uso dell Integration Manager che tramite l uso di header http nella modalità trasparente, nella precedente sezione 5 Aspetti di integrazione nei Profili Asincroni. Nel seguito vedremo un analogo esempio di codice, utilizzando le modalità alternative di integrazione tramite QUERY_STRING e tramite Header SOAP etoscana. 6.1 INTEGRAZIONE TRAMITE QUERY_STRING URL url = new URL(UrlPortaDelegataRichiesta); HttpURLConnection httpcon1 = (HttpURLConnection)url.openConnection();... OutputStream out = httpcon1.getoutputstream(); out.write(soapmessagerichiesta); out.close();... String idegov = httpcon1.getheaderfields().get("spcoopid");... url = new URL( UrlPortaDelegataRichiestaStato + "?SPCoopRiferimentoMessaggio=" + idegov ); HttpURLConnection httpcon2 = (HttpURLConnection)url.openConnection();... OutputStream out = httpcon2.getoutputstream(); out.write(soapmessagerichiestastato); out.close(); 18 di 36
... Nel codice appena mostrato si può notare come il parametro SPCoopRiferimentoMessaggio venga passato aggiungendo un parametro della QUERY_STRING alla URL della porta delegata invocata, anziché usando il setting degli header http. 6.2 INTEGRAZIONE TRAMITE L USO DELL HEADER SOAP ETOSCANA URL url = new URL(UrlPortaDelegataRichiesta); HttpURLConnection httpcon1 = (HttpURLConnection)url.openConnection();... OutputStream out1 = httpcon1.getoutputstream(); out1.write(soapmessagerichiesta); out1.close();... InputStream responsestream = httpcon1.getinputstream(); Message response = new Message(responseStream); responsestream.close();... SOAPHeaderElement headeretoscana = null; java.util.iterator<?> iter = response.getsoapheader().examineallheaderelements(); while( iter.hasnext() ) { SOAPHeaderElement headerelement = (SOAPHeaderElement) iter.next(); //Controllo Actor if(headerelement.getactor().equals( "http://it.regione.toscana.cart.pdd/etoscana") ) { headeretoscana = headerelement; break; 19 di 36
} } String idegov = headeretoscana.getattribute("id-egov");... // Preparazione dell'header SOAP etoscana Name name = new PrefixedQName( "http://it.regione.toscana.cart.pdd/etoscana", "etoscana", "cart"); SOAPHeaderElement header = new org.apache.axis.message.soapheaderelement(name); header.setactor("http://it.regione.toscana.cart.pdd/etoscana"); header.addnamespacedeclaration("soap_env", "http://schemas.xmlsoap.org/soap/envelope/"); // Settaggio riferimentomessaggio per la correlazione asincrona header.setattribute("spcoopriferimentomessaggio", idegov); // Aggiunta header al messaggio Soap. Si assume che il Messaggio Axis // da spedire sia disponibile nella variabile axismsgrichiestastato axismsgrichiestastato.getsoapenvelope().getheader().addchildelement(header) ; URL urlconnection = new URL(...todo...); HttpURLConnection httpconn = 20 di 36
(HttpURLConnection) urlconnection.openconnection(); OutputStream out = httpconn.getoutputstream(); axismsgrichiestastato.writeto(out); out.close();... 7 USO DEL MECCAMISMO DEI FILTRI NELL HEADER SOAP FCA Il CART permette di abilitare dei filtri in sottoscrizione, quando si usa JMS come modalità di trasporto tra le Porte di Dominio. In tal caso il SIL pubblicatore dovrà comunicare alla Porta di Dominio i valori delle proprietà usate come filtri, nella forma di una sequenza di triple del tipo: <nome proprietà, valore proprietà, operatore> dove l operatore può assumere uno dei seguenti valori: =,<,>,<>,<=,>=,LIKE. ATTENZIONE: quando viene utilizzato l operatore LIKE, il valore della proprietà dovrà contenere esclusivamente caratteri alfanumerici o il carattere #. Il matching, in caso di uso dell operatore LIKE, avverrà se il valore della proprietà risulta essere una sottostringa del valore inserito dal pubblicatore per quella proprietà. IMPOSTAZIONE DELLE PROPRIETÀ DA PARTE DEL SIL PUBBLICATORE L impostazione delle proprietà da parte dei SIL pubblicatori può avvenire usando l'api dell'fca Sun, in particolare tramite la feature delle msgrules prevista dall'fca oppure, nel caso di applicazioni che non usino l'fca, inserendo nel messaggio SOAP da spedire un header analogo a quello usato dall'emulatore FCA, che contiene la specifica dei filtri come nel formato xml seguente: <Intestazione soapenv:actor="http://it.regione.toscana.cart.pdd/fca" soapenv:mustunderstand="1" > <IntestazioneMessaggio> <Filters> 21 di 36
<Filter> <Key>Chiave1</Key> <Value>Value12</Value> </Filter> <Filter> <Key>Chiave2</Key> <Value>Value2</Value> </Filter> <Filter> </Filter> </Filters> </IntestazioneMessaggio> </Intestazione> Nel frammento di codice seguente vediamo un esempio di codice per il setting dei filtri nel caso specifico del linguaggio java, usando Axis 1.4 come web-services engine. L esempio completo, implementato tramite l uso dell Integration Manager è incluso nella directory esempi/filtrijms del Kit Sviluppatore CART. // Costruzione Messaggio Axis Message m = new Message(new ByteArrayInputStream(b),imbustamento); Name name = new PrefixedQName( http://it.regione.toscana.cart.pdd/fca/busta, Intestazione, fcaheader ); // Costruzione FCA Header org.apache.axis.message.soapheaderelement header = new org.apache.axis.message.soapheaderelement( Intestazione ); header.setactor( http://it.regione.toscana.cart.pdd/fca ); 22 di 36
header.addnamespacedeclaration("soap_env", "http://schemas.xmlsoap.org/soap/envelope/"); SOAPElement soapelement = header.addchildelement("intestazionemessaggio"); SOAPElement soapelementfilters = soapelement.addchildelement("filters"); SOAPElement soapelement1 = soapelementfilters.addchildelement("filter"); // setting dei filtri, si assume che siano stati predisposti negli array key, operator e value for(int i=0; i<key.length;i++){ soapelement1.addchildelement("key").addtextnode(key[i]); soapelement1.addchildelement("operator").addtextnode(operator[i]); soapelement1.addchildelement("value").addtextnode(value[i]); } SOAPHeader headersoap = null; if(m.getsoapheader()==null){ headersoap = m.getsoapenvelope().addheader(); } else{ headersoap = m.getsoapenvelope().getheader(); } headersoap.addchildelement(header); } 23 di 36
24 di 36
ALLEGATO A: INTERFACCIA WSDL DEL SERVIZIO DI INTEGRATIONMANAGER <?xml version="1.0" encoding="utf-8"?> <wsdl:definitions targetnamespace="http://services.pdd.openspcoop.org" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://services.pdd.openspcoop.org" xmlns:intf="http://services.pdd.openspcoop.org" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/xmlschema"> <wsdl:types> <schema elementformdefault="qualified" targetnamespace="http://services.pdd.openspcoop.org" xmlns="http://www.w3.org/2001/xmlschema"> <element name="getmessage"> <element name="idegov" type="xsd:string"/> <element name="getmessageresponse"> <element name="getmessagereturn" type="impl:spcoopmessage"/> <complextype name="spcoopheaderinfo"> <element name="id" nillable="true" type="xsd:string"/> <element name="azione" nillable="true" type="xsd:string"/> <element name="destinatario" nillable="true" type="xsd:string"/> <element name="idcollaborazione" nillable="true" type="xsd:string"/> <element name="mittente" nillable="true" type="xsd:string"/> <element name="riferimentomessaggio" nillable="true" type="xsd:string"/> <element name="servizio" nillable="true" type="xsd:string"/> <element name="tipodestinatario" nillable="true" type="xsd:string"/> <element name="tipomittente" nillable="true" type="xsd:string"/> <element name="tiposervizio" nillable="true" type="xsd:string"/> <complextype name="spcoopmessage"> <element name="idapplicativo" nillable="true" type="xsd:string"/> <element name="imbustamento" type="xsd:boolean"/> <element name="message" nillable="true" type="xsd:base64binary"/> <element name="servizioapplicativo" nillable="true" type="xsd:string"/> <element name="spcoopheaderinfo" nillable="true" type="impl:spcoopheaderinfo"/> <complextype name="spcoopexception"> <element name="codiceeccezione" nillable="true" type="xsd:string"/> <element name="descrizioneeccezione" nillable="true" type="xsd:string"/> 25 di 36
<element name="identificativofunzione" nillable="true" type="xsd:string"/> <element name="identificativoporta" nillable="true" type="xsd:string"/> <element name="oraregistrazione" nillable="true" type="xsd:string"/> <element name="tipoeccezione" nillable="true" type="xsd:string"/> <element name="fault" type="impl:spcoopexception"/> <element name="deletemessage"> <element name="idegov" type="xsd:string"/> <element name="deletemessageresponse"> <complextype/> <element name="getallmessagesid"> <complextype/> <element name="getallmessagesidresponse"> <element maxoccurs="unbounded" name="getallmessagesidreturn" type="xsd:string"/> <element name="getallmessagesidbyservice"> <element name="tiposervizio" type="xsd:string"/> <element name="servizio" type="xsd:string"/> <element name="azione" type="xsd:string"/> <element name="getallmessagesidbyserviceresponse"> <element maxoccurs="unbounded" name="getallmessagesidbyservicereturn" type="xsd:string"/> <element name="getnextmessagesid"> <element name="counter" type="xsd:int"/> <element name="getnextmessagesidresponse"> <element maxoccurs="unbounded" name="getnextmessagesidreturn" type="xsd:string"/> 26 di 36
<element name="getnextmessagesidbyservice"> <element name="counter" type="xsd:int"/> <element name="tiposervizio" type="xsd:string"/> <element name="servizio" type="xsd:string"/> <element name="azione" type="xsd:string"/> <element name="getnextmessagesidbyserviceresponse"> <element maxoccurs="unbounded" name="getnextmessagesidbyservicereturn" type="xsd:string"/> <element name="getmessagebyreference"> <element name="riferimentomsg" type="xsd:string"/> <element name="getmessagebyreferenceresponse"> <element name="getmessagebyreferencereturn" type="impl:spcoopmessage"/> <element name="deletemessagebyreference"> <element name="riferimentomsg" type="xsd:string"/> <element name="deletemessagebyreferenceresponse"> <complextype/> <element name="deleteallmessages"> <complextype/> <element name="deleteallmessagesresponse"> <complextype/> <element name="invocaportadelegata"> <element name="portadelegata" type="xsd:string"/> <element name="msg" type="impl:spcoopmessage"/> <element name="invocaportadelegataresponse"> 27 di 36
<element name="invocaportadelegatareturn" type="impl:spcoopmessage"/> <element name="invocaportadelegataperriferimento"> <element name="portadelegata" type="xsd:string"/> <element name="msg" type="impl:spcoopmessage"/> <element name="riferimentomessaggio" type="xsd:string"/> <element name="invocaportadelegataperriferimentoresponse"> <element name="invocaportadelegataperriferimentoreturn" type="impl:spcoopmessage"/> <element name="sendrispostaasincronasimmetrica"> <element name="portadelegata" type="xsd:string"/> <element name="msg" type="impl:spcoopmessage"/> <element name="sendrispostaasincronasimmetricaresponse"> <element name="sendrispostaasincronasimmetricareturn" type="impl:spcoopmessage"/> <element name="sendrichiestastatoasincronaasimmetrica"> <element name="portadelegata" type="xsd:string"/> <element name="msg" type="impl:spcoopmessage"/> <element name="sendrichiestastatoasincronaasimmetricaresponse"> <element name="sendrichiestastatoasincronaasimmetricareturn" type="impl:spcoopmessage"/> </schema> </wsdl:types> <wsdl:message name="invocaportadelegataperriferimentoresponse"> <wsdl:part element="impl:invocaportadelegataperriferimentoresponse" name="parameters"/> 28 di 36
<wsdl:message name="getnextmessagesidbyservicerequest"> <wsdl:part element="impl:getnextmessagesidbyservice" name="parameters"/> <wsdl:message name="getmessagerequest"> <wsdl:part element="impl:getmessage" name="parameters"/> <wsdl:message name="invocaportadelegataperriferimentorequest"> <wsdl:part element="impl:invocaportadelegataperriferimento" name="parameters"/> <wsdl:message name="invocaportadelegatarequest"> <wsdl:part element="impl:invocaportadelegata" name="parameters"/> <wsdl:message name="getnextmessagesidrequest"> <wsdl:part element="impl:getnextmessagesid" name="parameters"/> <wsdl:message name="deleteallmessagesresponse"> <wsdl:part element="impl:deleteallmessagesresponse" name="parameters"/> <wsdl:message name="getallmessagesidbyservicerequest"> <wsdl:part element="impl:getallmessagesidbyservice" name="parameters"/> <wsdl:message name="getallmessagesidbyserviceresponse"> <wsdl:part element="impl:getallmessagesidbyserviceresponse" name="parameters"/> <wsdl:message name="getmessageresponse"> <wsdl:part element="impl:getmessageresponse" name="parameters"/> <wsdl:message name="sendrispostaasincronasimmetricaresponse"> <wsdl:part element="impl:sendrispostaasincronasimmetricaresponse" name="parameters"/> <wsdl:message name="sendrichiestastatoasincronaasimmetricaresponse"> <wsdl:part element="impl:sendrichiestastatoasincronaasimmetricaresponse" name="parameters"/> <wsdl:message name="deletemessagebyreferencerequest"> <wsdl:part element="impl:deletemessagebyreference" name="parameters"/> <wsdl:message name="invocaportadelegataresponse"> <wsdl:part element="impl:invocaportadelegataresponse" name="parameters"/> <wsdl:message name="getnextmessagesidbyserviceresponse"> <wsdl:part element="impl:getnextmessagesidbyserviceresponse" name="parameters"/> <wsdl:message name="sendrichiestastatoasincronaasimmetricarequest"> <wsdl:part element="impl:sendrichiestastatoasincronaasimmetrica" name="parameters"/> <wsdl:message name="deletemessagerequest"> <wsdl:part element="impl:deletemessage" name="parameters"/> <wsdl:message name="getallmessagesidresponse"> <wsdl:part element="impl:getallmessagesidresponse" name="parameters"/> 29 di 36
<wsdl:message name="getnextmessagesidresponse"> <wsdl:part element="impl:getnextmessagesidresponse" name="parameters"/> <wsdl:message name="spcoopexception"> <wsdl:part element="impl:fault" name="fault"/> <wsdl:message name="deleteallmessagesrequest"> <wsdl:part element="impl:deleteallmessages" name="parameters"/> <wsdl:message name="deletemessagebyreferenceresponse"> <wsdl:part element="impl:deletemessagebyreferenceresponse" name="parameters"/> <wsdl:message name="deletemessageresponse"> <wsdl:part element="impl:deletemessageresponse" name="parameters"/> <wsdl:message name="getmessagebyreferenceresponse"> <wsdl:part element="impl:getmessagebyreferenceresponse" name="parameters"/> <wsdl:message name="getallmessagesidrequest"> <wsdl:part element="impl:getallmessagesid" name="parameters"/> <wsdl:message name="getmessagebyreferencerequest"> <wsdl:part element="impl:getmessagebyreference" name="parameters"/> <wsdl:message name="sendrispostaasincronasimmetricarequest"> <wsdl:part element="impl:sendrispostaasincronasimmetrica" name="parameters"/> <wsdl:porttype name="integrationmanager"> <wsdl:operation name="getmessage"> <wsdl:input message="impl:getmessagerequest" name="getmessagerequest"/> <wsdl:output message="impl:getmessageresponse" name="getmessageresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="deletemessage"> <wsdl:input message="impl:deletemessagerequest" name="deletemessagerequest"/> <wsdl:output message="impl:deletemessageresponse" name="deletemessageresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="getallmessagesid"> <wsdl:input message="impl:getallmessagesidrequest" name="getallmessagesidrequest"/> <wsdl:output message="impl:getallmessagesidresponse" name="getallmessagesidresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="getallmessagesidbyservice"> <wsdl:input message="impl:getallmessagesidbyservicerequest" name="getallmessagesidbyservicerequest"/> <wsdl:output message="impl:getallmessagesidbyserviceresponse" name="getallmessagesidbyserviceresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="getnextmessagesid"> 30 di 36
<wsdl:input message="impl:getnextmessagesidrequest" name="getnextmessagesidrequest"/> <wsdl:output message="impl:getnextmessagesidresponse" name="getnextmessagesidresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="getnextmessagesidbyservice"> <wsdl:input message="impl:getnextmessagesidbyservicerequest" name="getnextmessagesidbyservicerequest"/> <wsdl:output message="impl:getnextmessagesidbyserviceresponse" name="getnextmessagesidbyserviceresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="getmessagebyreference"> <wsdl:input message="impl:getmessagebyreferencerequest" name="getmessagebyreferencerequest"/> <wsdl:output message="impl:getmessagebyreferenceresponse" name="getmessagebyreferenceresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="deletemessagebyreference"> <wsdl:input message="impl:deletemessagebyreferencerequest" name="deletemessagebyreferencerequest"/> <wsdl:output message="impl:deletemessagebyreferenceresponse" name="deletemessagebyreferenceresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="deleteallmessages"> <wsdl:input message="impl:deleteallmessagesrequest" name="deleteallmessagesrequest"/> <wsdl:output message="impl:deleteallmessagesresponse" name="deleteallmessagesresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="invocaportadelegata"> <wsdl:input message="impl:invocaportadelegatarequest" name="invocaportadelegatarequest"/> <wsdl:output message="impl:invocaportadelegataresponse" name="invocaportadelegataresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="invocaportadelegataperriferimento"> <wsdl:input message="impl:invocaportadelegataperriferimentorequest" name="invocaportadelegataperriferimentorequest"/> <wsdl:output message="impl:invocaportadelegataperriferimentoresponse" name="invocaportadelegataperriferimentoresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="sendrispostaasincronasimmetrica"> <wsdl:input message="impl:sendrispostaasincronasimmetricarequest" name="sendrispostaasincronasimmetricarequest"/> <wsdl:output message="impl:sendrispostaasincronasimmetricaresponse" name="sendrispostaasincronasimmetricaresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> <wsdl:operation name="sendrichiestastatoasincronaasimmetrica"> <wsdl:input message="impl:sendrichiestastatoasincronaasimmetricarequest" name="sendrichiestastatoasincronaasimmetricarequest"/> 31 di 36
<wsdl:output message="impl:sendrichiestastatoasincronaasimmetricaresponse" name="sendrichiestastatoasincronaasimmetricaresponse"/> <wsdl:fault message="impl:spcoopexception" name="spcoopexception"/> </wsdl:porttype> <wsdl:binding name="integrationmanagersoapbinding" type="impl:integrationmanager"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="getmessage"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="getmessagerequest"> </wsdl:input> <wsdl:output name="getmessageresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="deletemessage"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="deletemessagerequest"> </wsdl:input> <wsdl:output name="deletemessageresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="getallmessagesid"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="getallmessagesidrequest"> </wsdl:input> <wsdl:output name="getallmessagesidresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="getallmessagesidbyservice"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="getallmessagesidbyservicerequest"> </wsdl:input> <wsdl:output name="getallmessagesidbyserviceresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="getnextmessagesid"> <wsdlsoap:operation soapaction=""/> 32 di 36
<wsdl:input name="getnextmessagesidrequest"> </wsdl:input> <wsdl:output name="getnextmessagesidresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="getnextmessagesidbyservice"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="getnextmessagesidbyservicerequest"> </wsdl:input> <wsdl:output name="getnextmessagesidbyserviceresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="getmessagebyreference"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="getmessagebyreferencerequest"> </wsdl:input> <wsdl:output name="getmessagebyreferenceresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="deletemessagebyreference"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="deletemessagebyreferencerequest"> </wsdl:input> <wsdl:output name="deletemessagebyreferenceresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="deleteallmessages"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="deleteallmessagesrequest"> </wsdl:input> <wsdl:output name="deleteallmessagesresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="invocaportadelegata"> <wsdlsoap:operation soapaction=""/> 33 di 36
<wsdl:input name="invocaportadelegatarequest"> </wsdl:input> <wsdl:output name="invocaportadelegataresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="invocaportadelegataperriferimento"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="invocaportadelegataperriferimentorequest"> </wsdl:input> <wsdl:output name="invocaportadelegataperriferimentoresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="sendrispostaasincronasimmetrica"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="sendrispostaasincronasimmetricarequest"> </wsdl:input> <wsdl:output name="sendrispostaasincronasimmetricaresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> <wsdl:operation name="sendrichiestastatoasincronaasimmetrica"> <wsdlsoap:operation soapaction=""/> <wsdl:input name="sendrichiestastatoasincronaasimmetricarequest"> </wsdl:input> <wsdl:output name="sendrichiestastatoasincronaasimmetricaresponse"> </wsdl:output> <wsdl:fault name="spcoopexception"> <wsdlsoap:fault name="spcoopexception" use="literal"/> </wsdl:fault> </wsdl:binding> <wsdl:service name="integrationmanagerservice"> <wsdl:port binding="impl:integrationmanagersoapbinding" name="integrationmanager"> <wsdlsoap:address location="http://pdd/cart/integrationmanager"/> </wsdl:port> </wsdl:service> </wsdl:definitions> 34 di 36
ALLEGATO B : HEADER SOAP ETOSCANA <?xml version="1.0" encoding="utf-8"?> <xsd:schema xmlns="http://it.regione.toscana.cart.pdd/etoscana" targetnamespace="http://it.regione.toscana.cart.pdd/etoscana" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap_env="http://schemas.xmlsoap.org/soap/envelope/" elementformdefault="qualified" attributeformdefault="unqualified"> <! Utilizzato per le comunicazioni tra servizio applicativo e porta di dominio --> <xsd:element name="etoscana"> <xsd:complextype> <xsd:attribute name="spcooptipomittente" type="xsd:string" /> <xsd:attribute name="spcoopmittente" type="xsd:string" /> <xsd:attribute name="spcooptipodestinatario" type="xsd:string" /> <xsd:attribute name="spcoopdestinatario" type="xsd:string" /> <xsd:attribute name="spcooptiposervizio" type="xsd:string" /> <xsd:attribute name="spcoopservizio" type="xsd:string" /> <xsd:attribute name="spcoopazione" type="xsd:string" /> <xsd:attribute name="spcoopid" type="xsd:string" /> <xsd:attribute name="spcoopriferimentomessaggio" type="xsd:string" /> <xsd:attribute name="spcoopcollaborazione" type="xsd:string" /> <xsd:attribute name="spcoopidapplicativo" type="xsd:string" /> <xsd:attribute name="spcoopservizioapplicativo" type="xsd:string" /> <!-- SOAPHeader Element --> <xsd:attribute ref="soap_env:actor" use="required" fixed="http://it.regione.toscana.cart.pdd/etoscana"/> <xsd:attribute ref="soap_env:mustunderstand" use="required" fixed="0"/> </xsd:complextype> </xsd:element> </xsd:schema> 35 di 36
DOMANDE FREQUENTI GESTIONE DEGLI ALLEGATI La gestione degli attachment è trasparente rispetto alla Porta di Dominio, essendo l'attachment parte del messaggio SOAP (in questo caso SOAP with Attachment). Quindi l'attachment può essere inviato senza ulteriori complicazioni, sia tramite l'uso dell'interfaccia trasparente, che tramite l'uso del servizio di Integration Manager. Le Porte di Dominio poi si occuperanno di gestire i manifest così come previsto nella specifica SPCoop. 36 di 36