Anmelden

View Full Version : SYSTOOLS / HTTPGETBLOB Verhalten



Seiten : [1] 2

Bratmaxxe
19-12-17, 06:48
Moin zusammen,

ich habe eine Frage bezüglich des Verhaltens eines HTTPGETBLOB - Aufrufs.

Ich habe, je nach Einsatzzweck entweder ein RPG Programm oder eine SQL-UDF erstellt, die Daten von einem Rest-Webservice abrufen und entsprechend dem unterlagerten Systemen bereitstellen.

SQL-UDF-Definition:



CREATE FUNCTION PGM.MYFUNC (
PNR DECIMAL(7, 0) )
RETURNS CHAR(50)
LANGUAGE RPGLE
SPECIFIC PGM.MYFUNC
NOT DETERMINISTIC
READS SQL DATA
RETURNS NULL ON NULL INPUT
EXTERNAL NAME 'PGM/MYFUNC(SQL_FUNC)'
PARAMETER STYLE GENERAL ;



RPG-Programm mit embedded SQL und Serviceprogramm:




DSQL_FUNC PI 50A
D PNR 7 0
*
*š//Initialisierung Work-Felder
D WEB_URL S 255 VARYING
D VALIDITY_DTE S D
D SQLERG S 50A
D ORT S 50A INZ(*BLANKS)

C TIME VALIDITY_DTE
/FREE
CALLP INIT_ENV();

WEB_URL = 'https://user:password@xxx.de/' +
'employee-data-transfer/api/employee/' + %CHAR(PNR) +
'/birthplace?validityDate=' + %CHAR(VALIDITY_DTE);
/END-FREE
*
C/EXEC SQL
C+ SELECT RESULT.* into :SQLERG
C+ FROM XMLTABLE(
C+ '$result'
C+ PASSING
C+ XMLPARSE(DOCUMENT SYSTOOLS.HTTPGETBLOB(:WEB_URL, '')
C+ ) as "result"
C+ COLUMNS birthplace CHAR(50) PATH 'birthplace'
C+ ) AS result
C/END-EXEC
*
C IF SQLCOD = *ZEROS
C EVAL ORT = SQLERG
C ENDIF
*
C RETURN ORT



Im INIT_ENV werden Umgebungsvariablen gesetzt:

CALL QCMDEXC('ADDENVVAR ENVVAR(JAVA_HOME) VALUE(''/QOpenSys/QIBM/ProdData/JavaVM/jdk60/64bit'') REPLACE(*YES)');

CALL QCMDEXC('ADDENVVAR ENVVAR(QIBM_JAVA_PROPERTIES_FILE) VALUE(''/QIBM/userdata/java400/my.properties'') REPLACE(*YES)');


Der Webservice ist so aufgebaut, dass er eine 404 Meldung zurückgibt, wenn keine Daten gefunden wurden (z.B. ungültige Personalnummer als Parameter mitgegeben).

Der Rückgabewert ist dann wie folgt:


- 38000(-443)[IBM][System i Access ODBC Driver]SQL0443 (0,60 secs)


- S1000(-4302)[IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL4302 - Die gespeicherte Java-Proz. oder benutzerdef. Funktion SYSTOOLS.HTTPGETBLOB mit dem spezifischen Namen HTTPG00001 wird mit der Ausnahmebed. https://xxx:xxx@xxx.de/employee-data-transfer/api/employee/7777/birthplace?validityDate=2017-11-16 abgebrochen. (0,48 secs)



Ist dieses Verhalten so normal? Kann man das abfangen - auch eine explizite Abfrage des SQLCODES und das Zurückgeben von *BLANKS hilft nicht. Habe ich einen Fehler gemacht?

Ich bin über jede Hilfe dankbar!

Viele Grüße
BM

Fuerchau
19-12-17, 07:17
Dies könnte ggf. am SQL-Threading liegen.
Die Aufrufe von QCMDEXC sind nicht threadsave, da sie in der OPM-ACTGRP laufen.
Ggf. hilft beim Create Function der Parameter "not fenced", der den Aufruf deiner SQL-Prozedur im Mainthread erzwingt.
Aber es ist ja generell ein Problem, JAVA über SQL zusätzlichzu bemühen.
Hier kann vielleicht Dieters (D*B) Lösung AppServer4RPG wesentlich besser sein.

Bratmaxxe
19-12-17, 12:08
Hallo Baldur,

das NOT FENCED hat leider nicht den gewünschten Effekt gebracht :/

Im Joblog steht aber noch ein weiterer Hinweis (siehe Anlagen):

419

420

Zeichenumsetzungsfehler?

Gruß
BM

Fuerchau
19-12-17, 13:08
Aber klar:
Wenn dein Job (wie so häufig) in CCSID(*HEX) läuft, und der GetBlob CCSID 1200 erwartet, dann kannst du nicht erwarten, dass SQL aus *HEX (WEB_URL) CCSID 1200 umwandeln kann.

Ersetze die Definition von WEB_URL mit 255C.
Ggf. bekommst du hier schon einen Laufzeitfehler bei der Umwandlung.

SQL arbeitet i.d.R. nie mit CCSID(*HEX) außer bei explzit binary definierten Felder.
Also entweder machst du einen CHGJOB CCSID(nnn) mit der korrekten CCSID oder du castest im SQL:
cast(: WEB_URL as char(255) ccsid 273)

Jobs ohne gültige CCSID gehören inzwischen verboten.

Bratmaxxe
19-12-17, 13:29
Danke Baldur,

klappt nun mit der CCSID - allerdings sind die Fehler bei einer ungültigen Personalnummer geblieben:

421

422

:/

Liegt es an der JRE (1.6.0) - an dem HTTP, welches 404 zurückgibt oder gar an meinem Programm?
Ich werd daraus nicht schlau...

Viele Grüße
BM

Fuerchau
19-12-17, 15:09
Da musst du dann leider deinen Webservice prüfen, ob deine Parameter korrekt sind.

Bratmaxxe
20-12-17, 07:40
Hallo Baldur,

ich hatte noch ein anderes Beispiel im Web gefunden:




SELECT SYSTOOLS.HTTPGETCLOB(
CAST ('http://api.geonames.org/countryInfo?lang=it&country=DE&username=demo&style=full' AS VARCHAR(255)),
CAST(NULL AS CLOB(1K)))
FROM SYSIBM.SYSDUMMY1;



Kann das evtl. einmal jemand bei sich auf der AS/400 aufrufen, sofern möglich?
Welches Ergebnis erhaltet ihr?

Bei mir kommt ebenfalls der Fehlercode:

S1000(-4302)[IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL4302 - Die gespeicherte Java-Proz. oder benutzerdef. Funktion SYSTOOLS.HTTPGETCLOB mit dem spezifischen Namen HTTPGETCLOBNONXML wird mit der Ausnahmebed. Ein ferner Host antwortete nicht innerhalb des Zeitlimits. abgebrochen. (189,22 secs)

Fehlt da evtl. ein PTF? Mir gehen so langsam die Ideen aus...

Gruß
BM

andreaspr@aon.at
20-12-17, 09:15
Bei mir IBM i 7.3 funktioniert es:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<geonames>
<status message="the daily limit of 30000 credits for demo has been exceeded. Please use an application specific account. Do not use the demo account for your application." value="18"/>
</geonames>

Bratmaxxe
20-12-17, 10:21
Danke für dein Feedback, Andreas. Wir sind immo mit 7.1 unterwegs und ich weiß aktuell nicht, wie ich mit dem PGM weitermachen soll :/

prsbrc
20-12-17, 13:33
Bei mir unter 7.2 ebenfalls.
Ich würde dir hierfür sowieso das HTTPAPI vom Scott Klement empfehlen denn das läuft auch ganz ohne JVM ;-)