Dichiarazione CREATE NICKNAME - esempi per il wrapper dei servizi Web

Quando si crea un nickname per accedere a un servizio Web, si crea una colonna di input per ogni valore nel messaggio di input di un'operazione di servizio Web e una colonna di output per ogni valore nel messaggio di output di un'operazione di servizio Web. Le definizioni delle colonne di ingresso e di uscita si controllano con le definizioni delle opzioni della colonna nickname.

L'opzione TEMPLATE column specifica che una colonna è una colonna di input. L'opzione XPATH column specifica che una colonna è una colonna di output. Quando l'opzione TEMPLATE nickname contiene una notazione tra parentesi ([1,1]), la colonna è una colonna di input obbligatoria.

L'opzione nickname NAMESPACES è un elenco separato da virgole di coppie nome-valore che un sistema federato utilizza per risolvere i namespace degli elementi nei documenti XML di input e di output. Gli spazi dei nomi vengono utilizzati nella richiesta di messaggio in modo da definire i prefissi dell'opzione TEMPLATE nickname. L'opzione nickname NAMESPACES risolve i prefissi nelle espressioni XPath con gli URI degli spazi dei nomi definiti nel WSDL o negli schemi XML. Le espressioni XPath vengono applicate al documento XML restituito dal servizio Web.

Esempio 1: Colonne di input richieste

L'esempio seguente mostra un nickname per un servizio Web chiamato getQuote. Il servizio Web legge il simbolo di un titolo e restituisce il prezzo di negoziazione.
CREATE NICKNAME "stockquote.stockquoteport_getquote_nn" ( 
	symbol VARCHAR (48) OPTIONS(TEMPLATE '&column'),
	result VARCHAR (48) OPTIONS(XPATH './Result/text()'))  
FOR SERVER "xmethods_server"  OPTIONS(
	URL 'http://66.28.98.121:9090/soap' , 
	SOAPACTION 'urn:xmethods-delayed-quotes#getQuote' , 
	TEMPLATE '<soapenv:Envelope>
                   <soapenv:Body>
                    <ns2:getQuote>
                      <symbol>&symbol[1,1]</symbol>
                    </ns2:getQuote>
                   </soapenv:Body>
                  </soapenv:Envelope>',
   XPATH '/soapenv:Envelope/soapenv:Body/*' , 
   NAMESPACES 'ns2="urn:xmethods-delayed-quotes" ,  
              ns1="http://www.example.com/wsdl/
                  net.xmethods.services.stockquote.StockQuote/" ,  
                  soapenv="http://schemas.xmlsoap.org/soap/envelope/" ');
L'opzione nickname TEMPLATE specifica la colonna SYMBOL come colonna di input obbligatoria, poiché la colonna contiene la designazione [1,1]. Nell'opzione nickname TEMPLATE, viene specificata la busta SOAP completa per il servizio Web. Il valore di input di getQuote è contenuto negli elementi envelope e body di SOAP. L'opzione XPATH nickname contiene le informazioni per trovare il valore del prezzo di negoziazione attraverso la busta SOAP e i tag body.
Utilizzare il nickname stockquote.stockquoteport_getquote_nn per accedere al servizio Web, come nella seguente query:
SELECT * FROM "stockquote.stockquoteport_getquote_nn" 
  WHERE symbol='IBM';
È necessario utilizzare il predicato symbol='IBM' in questa istruzione perché symbol è una colonna di input obbligatoria. Il predicato di uguaglianza è l'unico predicato valido sulle colonne di input. Ciascuno dei predicati di uguaglianza imposta un valore nel messaggio di input. Se la colonna di input è opzionale, non è necessario un predicato di uguaglianza su tale colonna. Se la colonna di input è obbligatoria, è necessario eseguire la query con un predicato di uguaglianza. È possibile utilizzare un valore letterale come IBM in un'espressione di uguaglianza o un valore da una tabella unita o un nickname.

Esempio 2: Elementi ripetuti e nickname figlio

L'esempio seguente utilizza un servizio Web denominato getZooReport che produce un report per gli zoo. Il valore di ingresso è un identificatore di zoo. Il valore di uscita è un report descritto dal seguente schema:
Figura 1. Servizio Web getZooReport
<wsdl:definitions name="Name"
    targetNamespace="http://myzoo.com"
...
<wsdl:types>
 <xsd:schema elementFormDefault="qualified" targetNamespace="http://myzoo.com"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <xsd:element name="Animal">
      <xsd:complexType>
         <xsd:sequence>
          <xsd:element ref="tns:Name"/>
          <xsd:element ref="tns:Species"/>
          <xsd:element ref="tns:Lot"/>
         </xsd:sequence>
      </xsd:complexType>
  </xsd:element>
  <xsd:element name="AnimalCareList">
     <xsd:complexType>
       <xsd:sequence>
         <xsd:element maxOccurs="unbounded" minOccurs="1" ref="tns:Animal"/>
       </xsd:sequence>
     </xsd:complexType>
  </xsd:element>
  <xsd:element name="Count" type="xsd:string"/>
  <xsd:element name="LastModified" type="xsd:string"/>
  <xsd:element name="Lot" type="xsd:string"/>
  <xsd:element name="Name" type="xsd:string"/>
  <xsd:element name="NumberOfCages" type="xsd:string"/>
  <xsd:element name="Species" type="xsd:string"/>
  <xsd:element name="Zoo">
     <xsd:complexType>
       <xsd:sequence>
         <xsd:element ref="tns:ZooName"/>
         <xsd:element ref="tns:Count"/>
         <xsd:element ref="tns:LastModified"/>
         <xsd:element maxOccurs="unbounded" minOccurs="0" ref="tns:Zookeeper"/>
       </xsd:sequence>
       <xsd:attribute name="id" type="xsd:string" use="optional"/>
      </xsd:complexType>
 </xsd:element>
 <xsd:element name="ZooName" type="xsd:string"/>
 <xsd:element name="Zookeeper">
     <xsd:complexType>
       <xsd:sequence>
         <xsd:element ref="tns:Name"/>
         <xsd:element ref="tns:NumberOfCages"/>
         <xsd:element ref="tns:AnimalCareList"/>
       </xsd:sequence>
      <xsd:attribute name="id" type="xsd:string" use="optional"/>
    </xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
...

La seguente istruzione DDL si basa sul WSDL che contiene lo schema:
Figura 2. Nickname del genitore - zooport_getzooreport_nn
CREATE NICKNAME zooport_getzooreport_nn ( 
	zooid VARCHAR (48) OPTIONS(TEMPLATE '&column'),
	zoo_id VARCHAR (48) OPTIONS(XPATH './ns1:Zoo/@ns1:id'),
	report_zooname VARCHAR (48) OPTIONS(XPATH './ns1:Zoo/ns1:ZooName/text()'),
	report_count VARCHAR (48) OPTIONS(XPATH './ns1:Zoo/ns1:Count/text()'),
	report_lastmodified VARCHAR (48) 
       OPTIONS(XPATH './ns1:Zoo/ns1:LastModified/text()'),
	zooport_getzooreport_pkey VARCHAR (16) FOR BIT DATA NOT NULL 
       OPTIONS(PRIMARY_KEY 'YES'))  
FOR SERVER "zooserver"  OPTIONS(
	URL 'http://localhost:9080/MaelstromTest/services/ZooPort' , 
	SOAPACTION 'http://myzoo.com/getZooReport' , 
	TEMPLATE '<soapenv:Envelope>
              <soapenv:Body>
                <zooId>&zooId[1,1]</zooId>
              </soapenv:Body>
             </soapenv:Envelope>' , 
	XPATH '/soapenv:Envelope/soapenv:Body' , 
     NAMESPACES ' soapenv="http://schemas.xmlsoap.org/soap/envelope/" ,  
                  ns1="http://myzoo.com " ');
Figura 3 Figlio del nickname zooport_getzooreport_nn
CREATE NICKNAME zooport_getzooreport_report_nn ( 
	zooport_getzooreport_fkey VARCHAR (16) 
        FOR BIT DATA NOT NULL 
           OPTIONS(FOREIGN_KEY 'ZOOPORT_GETZOOREPORT_NN'),
   zookeeper_id VARCHAR (48) OPTIONS(XPATH './ns1:Zookeeper/@ns1:id'),
   report_name VARCHAR (48) OPTIONS(XPATH './ns1:Zookeeper/ns1:Name/text()'),
   report_numberofcages VARCHAR (48) 
           OPTIONS(XPATH './ns1:Zookeeper/ns1:NumberOfCages/text()'),
   zooport_getzooreport_pkey VARCHAR (16) 
           FOR BIT DATA NOT NULL OPTIONS(PRIMARY_KEY 'YES'))  
  FOR SERVER "zooserver"  OPTIONS(
        XPATH './ns1:Zoo' , 
        NAMESPACES ' soapenv="http://schemas.xmlsoap.org/soap/envelope/" ,  
               ns1="http://myzoo.com" ');
Figura 4. Figlio di zooport_getzooreport_report_nn
CREATE NICKNAME zooport_getzooreport_report_report_nn ( 
        zooport_getzooreport_fkey VARCHAR (16) FOR BIT DATA NOT NULL 
             OPTIONS(FOREIGN_KEY 'zooport_getzooreport_report_nn'),
        report_name VARCHAR (48) 
             OPTIONS(XPATH './ns1:Animal/ns1:Name/text()'),
        report_species VARCHAR (48) 
             OPTIONS(XPATH './ns1:Animal/ns1:Species/text()'),
        report_lot VARCHAR (48) OPTIONS(XPATH './ns1:Animal/ns1:Lot/text()'))  
 FOR SERVER "zooserver"  OPTIONS(
        XPATH './ns1:Zookeeper/ns1:AnimalCareList' , 
        NAMESPACES ' soapenv="http://schemas.xmlsoap.org/soap/envelope/" ,  
                  ns1="http://myzoo.com" ');
Lo schema include alcuni elementi che si ripetono, noti come elementi di sequenza. Questi elementi ripetuti diventano nickname figli del nickname genitore, come mostrato nella Figura 2, Figura 3 e Figura 4. Ad esempio, zooname, count, lastmodified e zookeeper sono tutti elementi di zoo. L'elemento zoo contiene 0 o più elementi zookeeper. Il nickname principale, zoo, contiene le colonne zooname, count e lastmodified. Viene creato un soprannome figlio, zookeeper, per descrivere gli elementi ripetuti di zookeeper. Anche il terzo elemento della colonna zookeeper, animalcarelist, contiene 0 o più elementi e quindi diventa un nickname figlio, zooport_getzooreport_report_nn. La figura seguente mostra la gerarchia dei nickname:
Figura 5. Genitore -> Figlio -> gerarchie di nickname
Soprannome radice: zooport_getzooreport_nn
Zoo (genitore):
  • ZooName
  • Conteggio
  • LastModified
  • ZooKeeper (ci sono 0 o più elementi ZooKeeper )
    Soprannome del bambino: zooport_getzooreport_report_nn
    Elementi di ZooKeeper
    • Nome
    • NumberOfCages
    • AnimalCareList (ci sono 0 o più elementi Animal)
      Soprannome del bambino: zooport_getzooreport_report_nn
      Animale
      • Nome
      • Specie
      • Lotto
L'istruzione seguente è una tipica query che si potrebbe eseguire sui nickname per accedere al servizio Web zoo report. Quando si emette questa istruzione, si recuperano le informazioni dal report zoo in base a un identificatore specifico e alla corrispondenza tra le chiavi primarie e le chiavi esterne dei report zoo nickname figlio.
SELECT * FROM zooport_getzooreport_nn , 
        zooport_getzooreport_report_nn zk ,          
        zooport_getzooreport_report__report__nn a     
    WHERE zooid='1'AND zooport_getzooreport_pkey=zk.zooport_getzooreport_fkey
    and zk.zooport_getzooreport_pkey=a.zooport_getzooreport_fkey;

Esempio 3: Legame tardivo

L'esempio seguente mostra come utilizzare l'opzione di binding tardivo. Se si definiscono le opzioni URL e SOAPACTION del nickname e si abilitano le opzioni URLCOLUMN e SOAPACTIONCOLUMN della colonna quando si crea un nickname, si utilizzano le funzioni di binding tardive.

L'esempio seguente riguarda un servizio Web che fornisce preventivi per i pezzi di ricambio, implementato da tutti i fornitori di un'azienda. Ecco l'istruzione CREATE NICKNAME che include le definizioni di URLCOLUMN e SOAPACTIONCOLUMN:
CREATE NICKNAME GetPartQuote(
  partnumber INTEGER OPTIONS (TEMPLATE'&column'),
  price FLOAT OPTIONS (XPATH './price')),
  urlcol VARCHAR(100) OPTIONS (URLCOLUMN 'Y'),
  soapactioncol VARCHAR(100) OPTIONS (SOAPACTIONCOLUMN 'Y'),
 FOR SERVER myServer
  OPTIONS (
  ... 
  SOAPACTION 'http://example.com/GetPartPrice' ,
  URL 'http://mycompany.com:9080/GetPartPrice'',
  ...
   )
Per ottenere le quotazioni di tutti i fornitori con un'unica query, sono necessari i valori che ciascun fornitore utilizza per le opzioni delle colonne SOAPACTION e URL. La query si presenta come segue:
SELECT * FROM supplier_endpoints p, 
    GetPartQuote q
 WHERE partnumber=1234 AND 
       p.url=q.urlcol AND 
       p.soapaction=q.soapactioncol;

La tabella locale supplier_endpoints contiene tutti gli URL e gli indirizzi SOAP con cui è possibile chiamare il servizio Web. È possibile includere una clausola ORDER BY price per determinare il fornitore meno costoso per questo pezzo.

Esempio 4: opzione di colonna ESCAPE_INPUT

È possibile includere frammenti XML come valori di input nella query. Quando si registra un nickname, includere l'opzione di colonna ESCAPE_INPUT=N. Questa opzione mantiene i caratteri speciali, come le parentesi angolari (< e >) nei frammenti XML nei valori di input.

Quando uno schema contiene valori di input ripetuti che richiedono l'invio di XML come parte del messaggio SOAP, è possibile usare l'opzione di colonna ESCAPE_INPUT per costruire il messaggio di output con l'XML corretto.

Ad esempio, il servizio Web zoo include un'operazione per aggiungere un nuovo guardiano dello zoo e gli animali associati a tale guardiano. Nello schema di questo esempio, un AnimalCareList può avere più animali.
CREATE NICKNAME add_zookeeper(
	zookeeper_id VARCHAR(48)  OPTIONS(TEMPLATE '...'),
	name VARCHAR(48) OPTIONS(TEMPLATE '...'),
	numberofcages VARCHAR(48) OPTIONS(TEMPLATE '...'),
	animals VARCHAR(3000) OPTIONS( TEMPLATE '...' , ESCAPE_INPUT 'N')
...
Per aggiungere un nuovo guardiano dello zoo con due animali, si deve eseguire una query come quella dell'esempio seguente:
SELECT * FROM add_zookeeper 
  WHERE zookeeper_ID='37' AND 
        name='Amit Kapoor' AND 
        numberofcages='3'  AND 
        animals='<AnimalCareList xmlns="http://myzoo.com">
                  <Animal>
                    <Name>Larry</Name>
                    <Species>Gorilla</Species>
                    <Lot>7</Lot>
                  </Animal>
                  <Animal>
                    <Name>Bill</Name>
                    <Species>Chimpanzee</Species>
                    <Lot>8H</Lot>
                  </Animal>
                 </AnimalCareList>';

Il nickname add_zookeeper è un'operazione del servizio Web che può modificare lo stato del servizio Web o aggiornare le informazioni. Anche se i wrapper non relazionali non possono essere aggiornati, l'istruzione SELECT di questo esempio aggiorna le informazioni sullo zoo per aggiungere un nuovo guardiano.

Si può anche usare l'opzione di colonna ESCAPE_INPUT per uno schema con un elemento come xsd:anyType. In questo caso, il tipo di elemento è sconosciuto. È possibile utilizzare l'opzione di colonna ESCAPE_INPUT sulla colonna di input per quell'elemento, in modo da poter specificare frammenti XML arbitrari per l'input.