Vor einigen Wochen sah ich mich mit der
Fragestellung konfrontiert, wie man bestimmte Daten aus einer Notesdatenbank
am besten in ein SAP System uebermitteln kann.
Schnell war klar, dass eine Kopplung
der beiden Systeme ueber eine CSV-Datei Schnittstelle eher "oldschool"
ist und nicht in Frage kommt. Wer sich schon einmal eingehend mit 2 Systemen
die Daten ueber eine CSV Schnittstelle austauschen beschaeftigt hat, weiss
wovon ich rede ;)
Und so geisterte schnell das Wort "Web
Service" durch die vom Rauch vieler Koepfe vernebelte Luft und es
war beschlossene Sache: Ein Web Service Consumer musste her.
Nachdem die bereitgestellte WSDL Datei
nach einigen Schwierigkeiten wie zu langen Funktionsnamen ("InternalError_Bic_cfdominoWs1RfcExceptions_n0")
und der Unmoeglichkeit das WSDL im DominoDesigner als Java Webservice einzubinden,
endlich als WebService Consumer bereitstand, konnte die eigentliche Arbeit
beginnen.
Es wurde ein Agent erstellt, der WebService
ueber ein "use" eingebunden und schon lies sich in einem LS Agenten
ein entsprechendes Objekt dimensionieren und ueber die Methode "setcredentials"
sogar mit Login Parametern fuer das SAP System ausstatten. Als naechstes
wurden unzaehlige Dokumente geladen, Werte ausgelesen und hoechst umstaendlich
in den entsprechenden WS Klassen bereitgestellt. Folgendes Beispiel
soll aufzeigen, wie "holprig" so eine WS klassen Definition in
LS daherkommt. Betrachten wir dazu die folgenden drei Basisklassen
Klasse zur Repraesentation eines
einzelnen Datentyps
Class
objDATENTYP1 as
XSD_ANYTYPE
Public
value As String
Sub
NEW
End Sub
end Class
Klasse zur Repraesentation eines
einzelnen Objektes / Datensatzes:
Class objEinzelnesObjekt
as XSD_ANYTYPE
Public
objVariable1
As objDATENTYP1
Sub
New
End
Sub
End Class
Klasse zur Repraesentation einer
Liste der Objekte / Datensaetze:
Class Listenobjekt_n0
As
XSD_ANYTYPE
Public
item()
As objEinzelnesObjekt
Sub
NEW
End Sub
End Class
Die Anzahl an Klassen fuehrt im Programmablauf
dann zu folgender Dimensionierungs und Zuweisungsorgie um einen einzelnen
Wert an den Web Service zu uebergeben:
'//-- Dimensionierung
der Objekte -----------
Dim
objItemList As
New Listenobjekt
Redim
objItemList.item(0) As
objEinzelnesObjekt '//--
bei mehreren Objekten muss hier natuerlich statt der 0 eine groessere Zahl
stehen ;)
Dim
objSingleItem As
New
objEinzelnesObjekt
Dim
objVariable As
New
objDATENTYP1
'// --- Zuweisung der
Werte zum Daten Objekt -------
objVariable.Value = "verify nice
value"
'//-- Zuweisung des Datenobjektes
zum einzelnen Objekt
Set
objSingleItem.objVariable1 = objVariable
'//-- Zuweisung des einzelnen
Objektes zum Listen Objekt
Set
objItemList.item(0) = objSingleItem
Nun bleibt nur noch, dass ganze an den
WS zu uebergeben, was wie folgt geschieht:
Dim
objWSConnect As
New
WSServiceObject_aus_WSDL / (PortTypeBAse)
Call
objWSConnect.Invoke_Function_in_WSDL(objItemList, Fault1)
Hat man bis dahin alles richtig gemacht,
so passiert - nichts. Eine Rueckmeldung ob die Uebergabe der Daten erfolgreich
war, waere schoen gewesen, blieb aber aus. Dafuer erreichten wir immerhin,
dass bei einer falschen Datenstruktur (z.B. String laenger als im WSDL
definiert) sich der Errorhandler regte.
Doch auch hier lies sich lediglich eine
"Es ist ein Fehler aufgetreten. Kontaktieren sie ihren Datenbank Administrator"
Meldung erzeugen. Bei einer entsprechenden Anzahl von Objekten wird es
so unmoeglich, die Fehlerquelle zu lokalisieren und abzustellen - die Routine
ist also fuer einen Regelbetrieb denkbar ungeeignet.
Bei der aufrufenden Funktion faellt
auf, dass ein "Fault1" Objekt vom Typ "WS_Fault" erwartet
bzw. zurueckgeliefert wird. Dieses Objekt wird ueber das WSDL File erzeugt
und stellt sich wie folgt dar.:
Class
Fault1 As
WS_FAULT
Public
Name As
Bic_cfdWs1RfcExceptions_n0
Public
Text As
XSD_STRING
Public
Message As
RfcExceptionMessage_n0
Sub
NEW
End Sub
End Class
Doch auch nach der Initialisierung der
entsprechenden Objekte und Klassen, konnte der Grund fuer den Fehler nicht
ermittelt werden. Das FehlerObjekt blieb hartnaeckig ungefuellt, obwohl
bei dem zum Testen der Verbindungen verwendeten Programm SoapUI der Fehlergrund
und Fehlerstelle eindeutig angezeigt wurde.
Wie nun also dem Fehler auf die Schliche
kommen ?
Wir entschieden uns schweren Herzens,
den Notes Weg zu verlassen und das auch in der von Niklas Heidloff und
Simon O'Doherty erstellten Soap Catcher
Datenbank verwendete COM Objekt Microsoft.XMLHTTP
einzusetzen.
Dim
WSObject As
Variant
Set
WSObject = CreateObject("Microsoft.XMLHTTP")
Dim
strREQUEST As
String
strREQUEST
= {<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:sap-com:document:sap:soap:functions:mc-style">}
strREQUEST
= strREQUEST & "<soapenv:Header/><soapenv:Body><urn:webservice><Data>"
strREQUEST
= strREQUEST & "<item>"
strREQUEST
= strREQUEST & "<Variable1>"
& "verify nice value" & "</Variable1>"
strREQUEST
= strREQUEST & "</item>"
strREQUEST
= strREQUEST & "</Data>"
strREQUEST
= strREQUEST & "</urn:webservice>"
strREQUEST
= strREQUEST & "</soapenv:Body>"
strREQUEST
= strREQUEST & "</soapenv:Envelope>"
WSObject.open
"POST",
endPoint, False,
strUsername, strPassword
WSObject.setRequestHeader
"Content-type",
"text/xml;charset=UTF-8"
WSObject.send(strREQUEST)
Dim
strError As
String
strError
= StrRight(StrLeft(StrRight(httpObject.responseText,"</faultcode>"),"</faultstring>"),">")
Nachdem man mittels .send die Daten
abgeschickt hat, kann ueber die Eigenschaft httpObject.responseText
nun die entsprechende Rueckmeldung (Fehler o. OK) ausgelesen werden.
FAZIT
Bei der hier aufgezeigten Methode die
Soap Meldungen per Microsoft COM Objekt zu laden, bestehen die ueblichen
Einschraenkungen. Allen voran sei erwaehnt, dass die Verwendung auf Microsoft
fremden System eher schwierig ist. Auch unterliegt der hier verwendete
String "strRequest" natuerlich den entsprechenden Groessenbeschraenkungen.
Die Verwendung eines WebServices mit
Domino 8.5.2 Bordmitteln koennte man generell eher als "schwierig"
bezeichnen. Es waere wuenschenswert, dass in den entsprechenden WS_Fault
Objekten o.ae. zumindest die SOAP Antworten zurueckgeliefert werden wuerden,
um diese auszuwerten. Aber vielleicht wird es ja was mit 8.5.5 .