Application Express und Web Services: Integration mit PL/SQL
Web Services verbreiten sich mehr und mehr
in den IT-Landschaften; sie sind
das zentrale Element service-orientierter Architekturen (SOA).
Kern dieser
Architektur ist es, bestimmte, häufig benötigte Funktionalität als Web Service
bereitzustellen, so dass verschiedenste Applikationen darauf zugreifen können,
und zwar unabhängig von der verwendeten Technologie.
Application Express bietet eine sehr gute Unterstützung für Web Services an - in der
letzten Ausgabe wurde diese ausführlich anhand eines
Beispiels vorgestellt.
Application Express und Web Services: Warum reicht das nicht aus?
Die Web Service-Unterstützung in Application Express weist ein entscheidendes
Merkmal auf.
Das Aufrufen eines Web Service ist an ein Application Express-Formular
oder an einen Bericht (oder genauer: An den Seitenprozeß Web Service)
geknüpft. Ein Prozeß Web Service kann nur als Seitenprozeß (onLoad oder onSubmit) hinterlegt werden.
Da der Aufruf eines Web Service stets Netzwerkaktivität bedeutet, kann diese
Kopplung unter Umständen zu Problemen führen:
-
Wenn der Web Service langsam reagiert, wird dadurch der Aufbau
der gesamten Application Express-Seite verzögert. Wird der Web Service nur
genutzt, um (wie im Beispiel der letzten Ausgabe) Wetterdaten oder einen
um 15 Minuten verzögerten Aktienkurs anzuzeigen, so ist eine solche Verzögerung
kaum hinzunehmen.
Eine Abhilfe könnte hier allerdings mit der AJAX-Technologie erfolgen.
-
Wenn die Application Express-Seite sehr stark frequentiert ist,
finden auch entsprechend viele Aufrufe des
Web Service und damit entsprechender Netzwerkverkehr statt - vielfach
(auch bei den Wetterdaten) ist ein solcher Realtime-Aufruf jedoch gar nicht erforderlich: Besser
wäre ein asynchrones Aufrufen des Web Service (als Job) im Hintergrund
und eine "Pufferung" der Daten in einer lokalen Tabelle. Dies ist mit
der Web Service-Unterstützung in Application Express aus oben genannten
Gründen allerdings nicht möglich.
Das Ziel: Integration der Web Services in PL/SQL
Abhilfe würde eine Integration des Web Service-Aufrufs direkt in PL/SQL bringen -
und genau dies ist das Ziel des heutigen Tipps: Sie werden in der Lage sein,
den Web Service in der Datenbank durch ein PL/SQL-Package abzubilden. Aufrufe
auf diesem Paket führen zu Aufrufen des Web Service. Der Code wird komplett
generiert - sie brauchen die Integration nicht selbst zu programmieren.
Die Datenbank muss allerdings vorbereitet werden, damit diese Integration möglich
wird. Dazu benötigen Sie DBA-Privilegien auf der Datenbank und Zugriff auf den
Datenbankserver - Sie müssen also mit dem DBA der Datenbank zusammenarbeiten.
Wie die Kommunikation mit dem Web Service stattfindet, zeigt Abbildung 1. Die eigentliche
"Arbeit" wird durch die Java-Engine in der Datenbank erledigt (aus diesem Grund kann dieser Tipp nicht in einer OracleXE-Datenbank nachvollzogen werden). Mit Hilfe des
WSDL-Dokumentes wird eine Java-Klasse generiert, die mit Hilfe einer
Web Service-Client-Bibliothek den Aufruf durchführt. Der PL/SQL-Wrapper ist für
die "Darstellung" der Funktionalität als PL/SQL-Package verantwortlich.
Abbildung 1: Aufruf von Web Services als PL/SQL-Paket: Funktionsweise
Vorbereitungen
Der erste Schritt ist die Installation der Web Service-Client-Bibliothek in die
Datenbank. Voraussetzung ist, wie schon erläutert, dass die Java-Engine in der
Datenbank vorhanden ist (das ist normalerweise der Fall). Laden Sie also das
Web Service Callout Utility 10.1.3.1 aus dem Oracle Technet
herunter und legen Sie es in ein Verzeichnis auf dem Datenbankserver. Das
ZIP-Archiv enthält die folgenden Dateien und Ordner:
Packen Sie das ZIP-Archiv nun in das $ORACLE_HOME
Ihrer Datenbank aus, so dass die Dateien
sich danach unterhalb von $ORACLE_HOME/sqlj befinden werden.
Zum Laden der Web Service Client-Bibliothek benötigen Sie, wie schon gesagt, DBA-Privilegien.
Setzen Sie dazu als SYS folgendes Kommando ab
(am besten leiten Sie die Ausgabe in eine Datei um):
-
Wenn Sie Oracle10g Release 1 (10.1) verwenden:
-
Wenn Sie Oracle10g Release 2 (10.2) verwenden:
-
Wenn Sie Oracle11g (11.1) verwenden:
Während der Ausführung (die einige Minuten dauern kann) kann es sein, dass ab und zu
folgende Fehlermeldungen auftreten.
Diese Fehlermeldungen
können Sie ignorieren. Die Funktionalität zum Aufrufen des Web Service ist nun
in der Datenbank installiert.
Einrichten des JPub-Werkzeugs
Der nächste Schritt ist die Einrichtung des JPub-Werkzeugs - mit seiner Hilfe
können Sie den Code zum Aufrufen des Web Service anhand des WSDL-Dokumentes
einfach als Java-Klasse (in der Datenbank) und zugehöriges PL/SQL-Paket
generieren lassen. Laden das
JPub Werkzeug (Version 10.2) aus dem Oracle Technet herunter,
legen Sie es in ein Verzeichnis auf dem Datenbankserver ab. Es ist ebenfalls auch
für Oracle11g geeignet und enthält unter anderem
folgende
Dateien:
Packen Sie das ZIP-Archiv wie vorhin das Web Service Callout Utility in das
$ORACLE_HOME
Ihrer Datenbank aus - das führt dazu, dass die Dateien sich wie vorhin unterhalb von
$ORACLE_HOME/sqlj befinden werden - genau dort gehören sie hin.
Setzen Sie nun den Java-CLASSPATH wie folgt;
am besten schreiben Sie sich dafür
ein Shellskript (UNIX/Linux) oder eine Batchdatei (Windows). Die folgenden
Beispiele setzen voraus, dass
die Umgebungsvariable ORACLE_HOME gesetzt ist.
Zunächst das Unix/Linux-Beispiel:
Das Windows-Beispiel:
Achten Sie beim JDBC-Treiber auf die Java-Version. Die Beispielskripte gehen
von Java 1.5 aus (ojdbc5.jar).
Wenn Sie Java 1.4 verwenden, tauschen Sie es gegen
ojdbc14.jar aus und wenn Sie Java6 verwenden,
nehmen Sie ojdbc6.jar. Sie finden die
Java-Version heraus, indem Sie auf der Kommandozeile
"java -version" eingeben.
ACHTUNG: Diese "Wahl" haben Sie nur bei Oracle11g;
mit Oracle10g Release 2 können Sie auch außerhalb der Datenbank maximal
Java 1.4 - mit Oracle10g Release 1 maximal Java 1.3 verwenden.
Testen Sie zusätzlich (ebenfalls auf der Kommandozeile), ob der Java-Compiler
vorhanden ist. Ein Aufruf von javac sollte folgende Ausgabe liefern.
Kopieren Sie nun die Dateien jpub
(bzw. jpub.exe auf Windows) von
$ORACLE_HOME/sqlj/bin
nach $ORACLE_HOME/bin.
Auf Unix/Linux müssen Sie "jpub"
ggfs. noch mit einem "chmod +x jpub"
ausführbar machen.
Vergeben Sie nun als SYS noch folgendes Privileg,
damit "normale"
Datenbankuser mit dem JPub-Werkzeug Web Services einrichten können. Sie
können als GRANTEE entweder gezielt
Datenbanknutzer eintragen oder das
Privileg mit PUBLIC an alle vergeben.
Nun geht es los: Einrichten des Web Service als PL/SQL Paket
Als Beispiel nehmen wir den bereits in der
letzten Ausgabe vorgestellten Web Service
Global Weather. Wiederum
benötigen Sie die URL des WSDL-Dokumentes, welches den Web Service beschreibt. Sie ist
http://www.webservicex.com/globalweather.asmx?WSDL.
Nutzen Sie nun das JPub-Werkzeug und
setzen Sie auf dem Datenbankserver folgendes Kommando ab:
Daraufhin sollten Sie in etwa folgende Ausgabe sehen:
Die Warnungen können Sie ignorieren. Der Code zum Aufrufen des Web Service wurde
generiert und auch gleich
in die Datenbank geladen. Um den tatsächlichen Aufruf (und die damit verbundene
Netzwerkverbindung) tatsächlich tätigen zu können, benötigen Sie wiederum Privilegien;
das dazu nötige Skript hat das JPub-Werkzeug ebenfalls bereits generiert
(plsql_grant.sql).
Lassen Sie es als SYS laufen, dann ist alles fertig.
Den Web Service wie ein PL/SQL-Paket nutzen
Navigieren Sie nun im Application Express SQL Workshop
(oder dem SQL Developer oder SQL*Plus) und
lassen Sie sich das neue PL/SQL-Paket WS_GLOBALWEATHER
beschreiben (desc WS_GLOBALWEATHER). Im SQL*Plus sehen
Sie in etwa folgende Ausgabe.
Mit einem Aufruf von WS_GLOBALWEATHER.GETWEATHER können
Sie den Web Service
testen - denken Sie allerdings daran, zunächst den Proxy-Server mit
WS_GLOBALWEATHER.SETHTTPPROXY einzustellen;
Ihre Datenbank befindet sich sicherlich hinter einer Firewall.
Und auch das strukturierte Auslesen ist nun ganz einfach:
Noch eine Anmerkung für die Experten:
In der letzten Ausgabe machte die Methode
GeoCitiesByCountry (hier abgebildet
durch WS_GLOBALWEATHER.GETCITIESBYCOUNTRY)
bei Ländern mit vielen Städten Probleme - Grund war das 32k-Limit für
VARCHAR2.
Schaut man sich das generierte Paket nochmals genau an, so erkennt man, dass die
Rückgabe auch hier als VARCHAR2 erfolgt - damit
exisitiert das Limit nach wie vor. Dieses Problem kann gelöst werden,
allerdings müsste man dazu den durch das
JPub-Werkzeug generierten Code so anpassen, dass eine Abbildung auf
CLOB erfolgt. Eine detaillierte Beschreibung
dieser Vorgehensweise
würde hier allerdings zu weit führen.
Die Anwendung: Web Service asynchron aufrufen und Ergebnisse puffern
Nun lässt sich ein Puffern der Wetterdaten ganz einfach realisieren. Erzeugen Sie
zunächst eine Tabelle mit den Städten, deren Wetterdaten Sie gerne verwenden würden und
füllen Sie diese mit ein paar Zeilen.
Lassen Sie das folgende Skript in SQL*Plus oder im SQL Workshop laufen.
Erstellen Sie als nächstes eine PL/SQL-Prozedur, die mit Hilfe des neuen
Paketes WS_GLOBALWEATHER die Wetterdaten abruft,
das XML mit der Funktion EXTRACT interpretiert und die
Wetterdaten in eine Tabelle WS_WETTERDATEN_DETAILS ablegt.
Passen Sie vor dem Ausführen des Skripts noch den Aufruf von
WS_GLOBALWEATHER.SETHTTPPROXY noch an Ihre Umgebung an.
Mit einem Aufruf dieser Prozedur LADE_WETTERDATEN können
Sie nun einfach ein
Update der Tabelle auslösen - um alles komplett zu machen, richten
Sie noch mit DBMS_SCHEDULER einen Job ein, der einmal pro Stunde neue Wetterdaten vom
Web Service abruft.
Damit sind im Hintergrund alle Vorbereitungen gemacht. Sie können nun den
Web Service GlobalWeather in Ihrer Datenbank wie ein gewöhnliches PL/SQL-Paket
ansprechen und beliebig verwenden. Die Nutzung in einem Application Express
Prozeß ist ebenso möglich, wie die Ansprache in einem Trigger. Es ist nun
ein Leichtes, die Inhalte der Tabelle WS_WETTERDATEN_DETAILS auf einer
Application Express-Seite als Bericht anzuzeigen.
Abbildung 2: Bericht auf die Tabelle WS_WETTERDATEN_DETAILS
Und das beste daran ist: Sie können die Netzwerkaktivität Ihrer Application
Express-Datenbank ganz exakt vorhersagen: In diesem Beispiel finden genau ein mal
pro Stunde soviele Anfragen statt, wie es Zeilen in der Tabelle
WS_WETTERDATEN gibt. Wenn der Web Service mal
langsam oder gar nicht verfügbar
ist, merken Ihre Endanwender nichts davon - das äußerste ist die Darstellung
veralteter Daten.
Mit den hier vorgestellten Web Service Callout Utility können Sie
Web Services sehr eng mit Ihrer PL/SQL-Logik integrieren. Der größte Vorteil
ist mit Sicherheit die Entkopplung der Web Service-Aufrufe von der Endbenutzeraktivität.
Natürlich können Sie mit dieser Methode nicht nur Daten von Web Services
abrufen, sondern auch Daten an solche übermitteln. Die Anwendungsmöglichkeiten sind
zahlreich - hier sind zwei weitere Beispiele:
Das Beispiel wurde mit Oracle11g getestet - sollte aber auch mit Oracle10g Release 1
oder Oracle10g Release 2 analog laufen. In Oracle9i sind Web Service Callouts
ebenfalls möglich; allerdings muss dann ein anderes Callout Utility installiert werden.
Mehr Informationen dazu enthält das
Web Service Callout Users' Guide im Oracle Technet.
Zurück zur Community-Seite
|