Die Möglichkeit, bestehende, in RPG oder Cobol geschriebene IBM i-Anwendungen mit Webanwendungen zu kombinieren, erlaubt es uns, Kernanwendungen des System i nun auch für Webanwendungen nutzbar zu machen.

Dass RPG-Anwendungen in einfacher Art und Weise als webnutzbare Funktionen implementiert werden können, hat in den letzten Jahren so manchen RPG-Entwickler überrascht – zumal im Regelfall nur wenige Anpassungen erforderlich sind, damit aus einem RPG-Programm ein Funktionsbaustein für eine Webanwendung gemacht werden kann.

IBM hat der IBM i-Gemeinde im Sommer 2015 einige Neuerungen und Erweiterungen im Bereich der WebServices zur Verfügung gestellt, die einen Teil der Einschränkungen beseitigen, die uns in bestimmten Szenarien an der Realisierung von Projekten gehindert oder zumindest dazu geführt haben, dass diese nur mit hohem Aufwand realisiert werden konnten. Einige dieser Neuerungen verbessern in bestimmten Umgebungen die Laufzeit, andere zielen auf Besonderheiten, die auf Seiten der Web-Entwickler bis dato immer wieder für Verwunderung gesorgt haben. Die notwendige Großschreibung von IBM-Komponenten in den WebService-Bereichen (SOAP, REST etc.) oder die willkürliche Reihenfolge von Parametern sind dazu nur zwei Beispiele. Die Anlehnung der IBM i-Welt an den Rest der WebService-Gemeinde ist ein notwendiger Schritt, um noch besser zusammenarbeiten zu können.

Grundlage für die Nutzung der Neuerungen ist die Verwendung von ILE RPG-Code sowie der Einsatz der Betriebssystemversion IBM i 6.1 oder höher. Zudem müssen auf den unterstützen Betriebssystemversionen mindestens die folgenden PTF-Stände installiert sein:

IBM i 6.1 SF99115, mindestens Level 45
IBM I 7.1 SF99368, mindestens Level 35
IBM I 7.2 SF99713, mindestens Level 9

Ein Thema, das auch die Performance von RPG WebService-Anwendungen beeinflussen kann, sind die Arrays. Sie werden in der neuen Form auch dahingehend unterstützt, dass wir neben dem eigentlichen Array und dessen Inhalten auch die Anzahl der Vorkommen in einem WebService nutzen können.

Bisher konnte man mit WebServices natürlich auch Arrays verwenden Diese Arrays, wie gewohnt in RPG als mehrfach vorkommende Datenstruktur geschrieben, liefert die möglichen Werte und Informationen flexibel an das aufrufende Programm zurück.

Das funktioniert auch für WebServices wunderbar. Leider aber bisher so, dass sich der WebService-Entwickler, der den IBM i-WebService konsumiert, darauf achten muss, nur die tatsächlich gefüllten Bereiche zu verarbeiten.

Nehmen wir als Beispiel eine Bestandsabfrage zu einer Artikelnummer, die auf unterschiedlichen Lagerplätzen gelagert werden kann. Die Anzahl der Lagerplätze ist im Vorfeld nicht bekannt. Folglich kann das Ergebnis so aussehen, dass der Artikel auf einem Lagerplatz, auf zweien oder mehreren zu finden ist. Verarbeitet man so ein Ergebnis, dann musste der WebService-Verbraucher bisher manuell dafür Sorge tragen, dass nur die Elemente verarbeitet wurden, die auch tatsächlich gefüllt waren. Zudem stellt die Menge der zurückgelieferten Informationen auch ein Problem in Sachen Performance und Ressourcennutzung dar.

Mit einer Erweiterung, die IBM in diesem Zusammenhang mit SOAP implementiert hat, (und die ansonsten auch im SOAP-Umfeld gängige Praxis ist), können wir nun den von einem WebService zurückgelieferten Datenbestand auf die tatsächlich gefüllten Elemente beschränken. Das bringt die folgenden Vorteile:

  1. mögliche Reduzierung der Laufzeit
  2. Verringerung des Handlings auf Seiten der WebService-Benutzer. Hier muss man sich nicht mehr um die Abfragen kümmern bzw. darum, ob die Elemente noch gefüllt sind.

Damit wir diese Erweiterung der WebServices nutzen können, müssen wir lediglich einige wenige Änderungen am WebService selbst vornehmen. Schauen wir uns das an einem einfachen Beispiel an.

Ich möchte die Bestandsauskunft für einen Artikel auf Lagerplatzebene durchführen und das Ergebnis in einer Datenstruktur darstellen, wie sie der folgende Codeausschnitt zeigt.

Die Artikelnummer (p_Teil) verwende ich als Eingabeparameter und erwarte die Datenstruktur i_PARM zurück. Sie kann maximal 300-fach vorkommen und besteht aus den Einzelfeldern „Lagerort“ (PaLago) und „Bestand“ (PaBest) die wir auch in der Parameterdefinition für den WebService wiederfinden.

Basierend auf diesen Angaben erhalten wir als mögliche Rückgabewerte drei Lagerplätze, die Sie in der nachfolgenden, zum Testclient gehörenden Abbildung sehen.

Das Problem: Es wurden drei Sätze gefunden – drei gefüllte Elemente. 297 der 300 definierten Elemente sind leer, werden hier aber als „Leerwerte“ in der SOAP-Nachricht vom WebService zurückgeliefert.

Das ist natürlich nicht effektiv, weshalb ich meine RPG-Quelle für den WebService anpasse und dort vor der Array-Definition einen Zähler einfüge, den ich genauso nenne wie die Datenstruktur, lediglich erweitert um die Endung „_LENGTH“.

Hier die Prototypdefinition dazu.

Den Zähler befülle ich nun im RPG-Programm für jedes gefundene Element und definiere diesen WebService auf dem WebService-Server.

Beachten Sie die nachfolgende Abbildung:

Der Parameter „Detect length fields“

Hier finden wir den Parameter „Detect length fields“ – und der ist jetzt ausschlaggebend – denn in Verbindung mit unserem Zähler verändert sich der im SOAP zurückgelieferte Bereich entscheidend!

Dieser Parameter lehnt sich eng an die RPG-Spezifika an. Das ist zwar nicht schön, aber anwendbar und bedarf einiger Beachtung auf RPG-Entwickerseite – denn: Mit diesem Parameter veranlassen wir den WebService, dass jeder als integer definierte Parameter mit der Endung _LENGTH, der vor einem Parameter angegeben wurde, als Zähler für diesen Eintrag identifiziert und entsprechend behandelt wird.

Schauen wir uns das Ergebnis an:

Wie Sie sehen: Es werden nur die wirklich gefüllten Elemente zurückgegeben – also deutlich ressourcenfreundlicher als das bisherige Verfahren. Das kann sich in gewissen Umgebungen entsprechend positiv auf das Laufzeitverhalten und auch auf die Ressourceverwendung auswirken.

Eine weitere Neuerung betrifft die Behandlung der PCML-Inhalte und die damit verbundenen Prozesse und nachgelagerten Aktionen. Die System i-Besonderheiten liegen unter anderem in der Anwendung der Groß-/Kleinschreibung der in PCML eingebundenen System i-Angaben. Beispielsweise wird der Name der ILE-Komponente in dem PCML-Dokument grundsätzlich in Großschrift implementiert – angelehnt an die IBM i-eigene Behandlung der Objektnamen – die eben auch groß genutzt werden. Die abgeleiteten Elemente beinhalten dann ebenso die ILE-Namen, und zwar auch in Großbuchstaben. Verantwortlich hierfür ist der sogenannte IBM Translator, der automatisch die Umsetzung für IBM i-Bedürfnisse durchführt.

WebService-Komponenten wie SOAP oder REST müssen diese entsprechend behandeln und implementieren – denn anders als unter IBM i arbeiten wir hier case-sensitiv. Somit ist die strikte Umsetzung bestimmter Komponenten in Großbuchstaben unter IBM i nicht im Sinne einer Standardisierung und kann zum Beispiel auch Programmierrichtlinien widersprechen, die in manchen Unternehmen vorgegeben sind. Diese Besonderheit hat IBM nun entfernt, was uns in Kombination mit einigen Neuerungen im RPG-Umfeld die flexible Nutzung der Schreibweise der Parameterdefinitionen in den WebServices und den RPG-Komponenten erlaubt. Dafür stehen auf IBM i-Seite einige PTFs zur Verfügung:

  • 7.1 SI55340
  • 7.2 SI55442

Diese Erweiterung wird unter anderem auch zusammen mit der zuvor beschriebenen Array-Erweiterung genutzt und dient als Basis für zukünftige Anpassungen im RPG-Umfeld.