591 lines
10 KiB
Markdown
591 lines
10 KiB
Markdown
Die RPG-Quellen und Include-Dateien liegen derzeit bewusst in einem
|
||
gemeinsamen Verzeichnis.
|
||
|
||
Serviceprogramm
|
||
|
||
Das Serviceprogramm heißt:
|
||
|
||
MEDDFNSRV
|
||
|
||
Es besteht derzeit aus den Modulen:
|
||
|
||
MEDDFNSRV
|
||
MEDDFNBLD
|
||
|
||
Die öffentlichen Exporte werden über die Binder-Source
|
||
|
||
MEDDFNSRVB
|
||
|
||
definiert.
|
||
|
||
Die öffentlichen Prozeduren sind:
|
||
|
||
MD_CreateMediaDefinition
|
||
MD_DeleteMediaDefinition
|
||
MD_RetrieveMediaDefinition
|
||
Builder
|
||
|
||
Der Builder erzeugt die Daten für eine Media Definition.
|
||
|
||
Aktuell wird das Format
|
||
|
||
TAPE0200
|
||
|
||
unterstützt.
|
||
|
||
Der Builder kann bereits Media Definitions mit:
|
||
|
||
mehreren Devices
|
||
mehreren Media Files
|
||
mehreren Volume Identifiers
|
||
|
||
erzeugen.
|
||
|
||
Parser
|
||
|
||
Der Parser befindet sich in:
|
||
|
||
meddfnprs.rpgle
|
||
|
||
Ziel des Parsers ist es, die von QSRRTVMD gelieferten
|
||
TAPE0200-Daten wieder in eine
|
||
|
||
MD_MediaDefinition_T
|
||
|
||
zu überführen.
|
||
|
||
Die Parserentwicklung erfolgt schrittweise.
|
||
|
||
Testprogramm
|
||
|
||
Das Testprogramm heißt:
|
||
|
||
MEDDFNTSTP
|
||
|
||
Das Testprogramm wird verwendet, um Media Definitions zu erzeugen
|
||
und anschließend deren Inhalt wieder auszulesen.
|
||
|
||
Die bevorzugte Teststrategie ist ein Roundtrip:
|
||
|
||
MD_MediaDefinition_T
|
||
│
|
||
▼
|
||
MD_CreateMediaDefinition
|
||
│
|
||
▼
|
||
*MEDDFN
|
||
│
|
||
▼
|
||
MD_RetrieveMediaDefinition
|
||
│
|
||
▼
|
||
Parser
|
||
│
|
||
▼
|
||
MD_MediaDefinition_T
|
||
|
||
Damit können die vom Parser gelieferten Werte mit den ursprünglich
|
||
erzeugten Werten verglichen werden.
|
||
|
||
Status
|
||
|
||
Der Builder für TAPE0200 ist funktionsfähig.
|
||
|
||
Das Erzeugen einer Media Definition mit mehreren Devices und
|
||
mehreren Volumes wurde erfolgreich getestet.
|
||
|
||
Ein realer paralleler Save auf eine Tape Library mit zwei Drives
|
||
wurde ebenfalls erfolgreich getestet.
|
||
|
||
Die Parser-Implementierung befindet sich derzeit in Entwicklung.
|
||
|
||
|
||
|
||
---
|
||
|
||
|
||
# 2. `DESIGN.md`
|
||
|
||
|
||
```markdown
|
||
# MEDDFN – Design
|
||
|
||
|
||
## 1. Zweck
|
||
|
||
|
||
MEDDFN soll eine wiederverwendbare RPGLE-Schnittstelle für die
|
||
Arbeit mit IBM i Media Definitions (`*MEDDFN`) bereitstellen.
|
||
|
||
|
||
Der aktuelle Schwerpunkt liegt auf dem Format:
|
||
|
||
|
||
```text
|
||
TAPE0200
|
||
|
||
Das Projekt besteht aus einem Builder, einem Parser und einem
|
||
Serviceprogramm.
|
||
|
||
2. Architektur
|
||
MEDDFN
|
||
│
|
||
├── meddfn_h.rpgle
|
||
│ └── Allgemeine Datenstrukturen und Konstanten
|
||
│
|
||
├── meddfnap_h.rpgle
|
||
│ └── Datenstrukturen und Prototypen für IBM i API-Aufrufe
|
||
│
|
||
├── meddfnbld.rpgle
|
||
│ └── Builder
|
||
│
|
||
├── meddfnprs.rpgle
|
||
│ └── Parser
|
||
│
|
||
├── meddfnsrv.rpgle
|
||
│ └── Öffentliche Serviceprogramm-Prozeduren
|
||
│
|
||
├── meddfnsrvb.rpgle
|
||
│ └── Binder-Source
|
||
│
|
||
└── meddfntstp.rpgle
|
||
└── Testprogramm
|
||
3. Öffentliche Schnittstelle
|
||
|
||
Das Serviceprogramm MEDDFNSRV stellt drei öffentliche Prozeduren
|
||
bereit.
|
||
|
||
MD_CreateMediaDefinition
|
||
|
||
Erzeugt eine *MEDDFN-Media-Definition aus einer
|
||
MD_MediaDefinition_T.
|
||
|
||
MD_DeleteMediaDefinition
|
||
|
||
Löscht eine vorhandene Media Definition.
|
||
|
||
MD_RetrieveMediaDefinition
|
||
|
||
Liest eine vorhandene Media Definition über die IBM i API und
|
||
wandelt die zurückgegebenen Daten wieder in eine
|
||
MD_MediaDefinition_T um.
|
||
|
||
4. IBM i APIs
|
||
|
||
Für das Projekt werden unter anderem folgende IBM i APIs verwendet:
|
||
|
||
QSRCRTMD
|
||
QSRRTVMD
|
||
QSRRSLMD
|
||
QMHSNDPM
|
||
|
||
Die API-spezifischen Strukturen und Prototypen befinden sich in:
|
||
|
||
meddfnap_h.rpgle
|
||
|
||
Allgemeine MEDDFN-Datenstrukturen und Konstanten befinden sich in:
|
||
|
||
meddfn_h.rpgle
|
||
5. TAPE0200
|
||
|
||
Der aktuelle Builder erzeugt das Format:
|
||
|
||
TAPE0200
|
||
|
||
Der grundsätzliche Aufbau ist:
|
||
|
||
TAPE0200 Header
|
||
│
|
||
├── Device Definition
|
||
│ │
|
||
│ ├── Media File Definition
|
||
│ │ │
|
||
│ │ └── Volume Identifier Array
|
||
│ │
|
||
│ └── weitere Media Files
|
||
│
|
||
└── weitere Device Definitions
|
||
6. TAPE0200 Header
|
||
|
||
Die RPG-Struktur ist:
|
||
|
||
MD_Tape0200Header_T
|
||
|
||
Sie enthält unter anderem:
|
||
|
||
Maximum parallel device resources
|
||
Minimum parallel device resources
|
||
Offset zur ersten Device Definition
|
||
Anzahl der Device Definitions
|
||
Länge des Headers
|
||
Device Allocation
|
||
Save Format
|
||
7. Device Definition
|
||
|
||
Die RPG-Struktur ist:
|
||
|
||
MD_Tape0200DeviceDefinition_T
|
||
|
||
Eine Device Definition beschreibt ein Gerät bzw. eine Ressource,
|
||
beispielsweise:
|
||
|
||
TAPMLB01
|
||
TAPMLB02
|
||
|
||
Sie enthält unter anderem:
|
||
|
||
Offset zur nächsten Device Definition
|
||
Device Name
|
||
Offset zur ersten Media File Definition
|
||
Anzahl der Media File Definitions
|
||
Länge der Device Definition
|
||
8. Media File Definition
|
||
|
||
Die RPG-Struktur ist:
|
||
|
||
MD_Tape0200MediaFileDefinition_T
|
||
|
||
Sie enthält unter anderem:
|
||
|
||
Offset zur nächsten Media File Definition
|
||
Sequence Number
|
||
Offset zum Volume Identifier Array
|
||
Anzahl der Volume Identifier
|
||
Länge eines Volume Identifiers
|
||
Starting Volume Array Element
|
||
Länge der Media File Definition
|
||
Starting Position in File
|
||
9. Volume Identifier
|
||
|
||
Volume Identifier haben derzeit eine feste Länge von:
|
||
|
||
6 Bytes
|
||
|
||
Die Konstante dafür ist:
|
||
|
||
MD_VOLUME_ID_LENGTH
|
||
|
||
Beispiele:
|
||
|
||
VOL001
|
||
VOL002
|
||
VOL003
|
||
|
||
Die Volume Identifier werden nach der zugehörigen Media File
|
||
Definition im Builder-Buffer abgelegt.
|
||
|
||
10. Alignment
|
||
|
||
Daten werden auf 4-Byte-Grenzen ausgerichtet.
|
||
|
||
Dafür wird verwendet:
|
||
|
||
MD_AlignLength()
|
||
|
||
Beispiele:
|
||
|
||
6 -> 8
|
||
12 -> 12
|
||
13 -> 16
|
||
11. Builder Context
|
||
|
||
Der Builder verwendet:
|
||
|
||
MD_BuilderContext_T
|
||
|
||
Der Builder schreibt die erzeugten Strukturen schrittweise in einen
|
||
gemeinsamen Buffer.
|
||
|
||
Aktuelle Builder-Prozeduren:
|
||
|
||
MD_BuildCreateBuffer
|
||
MD_BuildTape0200Header
|
||
MD_BuildTape0200Device
|
||
MD_BuildTape0200Media
|
||
MD_BuildTape0200VolumeArray
|
||
12. Builder-Reihenfolge
|
||
|
||
Der Aufbau eines TAPE0200 Buffers erfolgt in dieser Reihenfolge:
|
||
|
||
MD_BuildCreateBuffer
|
||
│
|
||
├── MD_BuildTape0200Header
|
||
│
|
||
└── für jedes Device
|
||
│
|
||
└── MD_BuildTape0200Device
|
||
│
|
||
├── MD_BuildTape0200Media
|
||
│
|
||
├── MD_BuildTape0200VolumeArray
|
||
│
|
||
└── weitere Media Files
|
||
13. Offset-Berechnung
|
||
|
||
Die TAPE0200-Strukturen enthalten relative Offsets.
|
||
|
||
Die Offsets werden beim Aufbau des Buffers anhand der aktuellen
|
||
Bufferposition und der Größe der jeweiligen Strukturen berechnet.
|
||
|
||
Besonders wichtig ist die korrekte Behandlung von:
|
||
|
||
Device Definitions
|
||
Media File Definitions
|
||
Volume Identifier Arrays
|
||
4-Byte-Alignment
|
||
14. StartingPositionInFile
|
||
|
||
Derzeit wird:
|
||
|
||
*ALL'0'
|
||
|
||
verwendet.
|
||
|
||
Beispiel:
|
||
|
||
Media0200.StartingPositionInFile = *ALL'0';
|
||
|
||
Die Business-Datenstruktur stellt derzeit noch nicht alle möglichen
|
||
API-Optionen für dieses Feld zur Verfügung.
|
||
|
||
15. Device Allocation
|
||
|
||
Die Konstanten befinden sich in:
|
||
|
||
meddfn_h.rpgle
|
||
|
||
Aktuell:
|
||
|
||
MD_DeviceAllocateAll
|
||
MD_DeviceAllocateOne
|
||
MD_DeviceAllocateMinimum
|
||
16. Save Format
|
||
|
||
Die Konstanten befinden sich ebenfalls in:
|
||
|
||
meddfn_h.rpgle
|
||
|
||
Aktuell:
|
||
|
||
MD_SaveFormatAuto
|
||
MD_SaveFormatSerial
|
||
MD_SaveFormatParallel
|
||
|
||
Für einen parallelen Save wird verwendet:
|
||
|
||
MediaDefinition.SaveFormat =
|
||
MD_SaveFormatParallel;
|
||
17. Fehlerbehandlung
|
||
|
||
API-Fehler werden über:
|
||
|
||
MD_APIError_T
|
||
|
||
behandelt.
|
||
|
||
Die zentrale Prüfung erfolgt über:
|
||
|
||
MD_CheckApiError()
|
||
|
||
Nachrichten werden über:
|
||
|
||
MD_SendMessage()
|
||
MD_SendEscape()
|
||
|
||
an den Aufrufer weitergegeben.
|
||
|
||
MD_SendEscape() verwendet intern MD_SendMessage() mit dem
|
||
Message Type Escape.
|
||
|
||
18. Parser
|
||
|
||
Der Parser befindet sich in:
|
||
|
||
meddfnprs.rpgle
|
||
|
||
Seine Aufgabe ist es, die von QSRRTVMD gelieferten Daten wieder
|
||
in die fachliche Struktur:
|
||
|
||
MD_MediaDefinition_T
|
||
|
||
zu überführen.
|
||
|
||
Der Parser soll die API-Daten anhand ihrer Header, Devices,
|
||
Media Files und Volume Arrays interpretieren.
|
||
|
||
Grundprinzip:
|
||
|
||
QSRRTVMD Receiver Buffer
|
||
│
|
||
▼
|
||
TAPE0200 Header
|
||
│
|
||
▼
|
||
Device Definitions
|
||
│
|
||
▼
|
||
Media File Definitions
|
||
│
|
||
▼
|
||
Volume Identifier Arrays
|
||
│
|
||
▼
|
||
MD_MediaDefinition_T
|
||
19. Parser-Teststrategie
|
||
|
||
Der Parser wird zunächst mit Media Definitions getestet, die durch
|
||
den eigenen Builder erzeugt wurden.
|
||
|
||
Teststufe 1
|
||
1 Device
|
||
└── 1 Media File
|
||
└── 1 Volume
|
||
Teststufe 2
|
||
1 Device
|
||
└── 1 Media File
|
||
├── VOL001
|
||
└── VOL002
|
||
Teststufe 3
|
||
1 Device
|
||
├── Media File 1
|
||
│ ├── VOL001
|
||
│ └── VOL002
|
||
│
|
||
└── Media File 2
|
||
├── VOL003
|
||
└── VOL004
|
||
Teststufe 4
|
||
2 Devices
|
||
|
||
|
||
TAPMLB01
|
||
└── Media File 1
|
||
├── VOL001
|
||
└── VOL002
|
||
|
||
|
||
TAPMLB02
|
||
└── Media File 1
|
||
├── VOL003
|
||
└── VOL004
|
||
Teststufe 5
|
||
|
||
Test mit einer realen Tape Library und mehreren Drives.
|
||
|
||
Ein paralleler Save auf zwei Tapes wurde erfolgreich getestet.
|
||
|
||
Dabei wurde festgestellt, dass ein installierter BRMS Exit Point
|
||
|
||
QIBM_QTA_TAPE_TMS
|
||
|
||
mit dem Exit-Programm
|
||
|
||
Q1ARTMS
|
||
|
||
das Verhalten beeinflussen kann.
|
||
|
||
Nach temporärem Entfernen des Exit Points konnte der parallele Save
|
||
auf zwei Tapes erfolgreich durchgeführt werden.
|
||
|
||
20. Serviceprogramm
|
||
|
||
Das Serviceprogramm heißt:
|
||
|
||
MEDDFNSRV
|
||
|
||
Aktuell werden folgende Module eingebunden:
|
||
|
||
MEDDFNSRV
|
||
MEDDFNBLD
|
||
|
||
Die Binder-Source heißt:
|
||
|
||
MEDDFNSRVB
|
||
|
||
Die Binder-Source exportiert:
|
||
|
||
MD_CreateMediaDefinition
|
||
MD_DeleteMediaDefinition
|
||
MD_RetrieveMediaDefinition
|
||
|
||
Beim Erstellen des Serviceprogramms wird:
|
||
|
||
TGTRLS(*CURRENT)
|
||
|
||
verwendet.
|
||
|
||
21. Entwicklungsumgebung
|
||
|
||
Das Projekt wird aktuell auf PUB400.com entwickelt.
|
||
|
||
Verwendet werden:
|
||
|
||
VS Code
|
||
Code for IBM i
|
||
IFS
|
||
Git
|
||
Gitea
|
||
|
||
Die Quellen liegen im IFS als UTF-8-Dateien vor.
|
||
|
||
Die RPG-Compile-Actions verwenden:
|
||
|
||
TGTCCSID(*JOB)
|
||
|
||
und:
|
||
|
||
TGTRLS(*CURRENT)
|
||
|
||
Die Include-Dateien liegen derzeit im selben Verzeichnis wie die
|
||
RPG-Quellen.
|
||
|
||
Sie werden beispielsweise über:
|
||
|
||
/COPY './meddfn_h.rpgle'
|
||
/COPY './meddfnap_h.rpgle'
|
||
|
||
eingebunden.
|
||
|
||
22. Entwicklungsgrundsätze
|
||
Bestehende Strukturen wiederverwenden
|
||
|
||
Neue Funktionen sollen nach Möglichkeit die vorhandenen
|
||
Datenstrukturen und Prozeduren verwenden.
|
||
|
||
Keine parallelen Varianten derselben Datenstruktur ohne
|
||
Notwendigkeit.
|
||
|
||
Öffentliche Schnittstelle klein halten
|
||
|
||
Das Serviceprogramm stellt nur die benötigten öffentlichen
|
||
Prozeduren bereit.
|
||
|
||
Interne Builder- und Parser-Prozeduren werden nicht unnötig
|
||
exportiert.
|
||
|
||
Builder und Parser getrennt halten
|
||
|
||
Der Builder erzeugt API-Daten.
|
||
|
||
Der Parser interpretiert API-Daten.
|
||
|
||
Beide Komponenten sollen unabhängig voneinander bleiben.
|
||
|
||
API-Strukturen und Business-Strukturen trennen
|
||
|
||
Die API-Strukturen in meddfnap_h.rpgle beschreiben die
|
||
IBM-i-API.
|
||
|
||
Die fachlichen Strukturen in meddfn_h.rpgle beschreiben das
|
||
interne Datenmodell.
|
||
|
||
Diese Trennung soll erhalten bleiben.
|
||
|
||
Git als gemeinsame Quelle
|
||
|
||
Der aktuelle Code im Git-Repository ist die technische Quelle der
|
||
Wahrheit.
|
||
|
||
Architekturentscheidungen und wichtige Besonderheiten werden in
|
||
dieser Datei dokumentiert, damit sie auch bei der Verwendung von
|
||
Codex in VS Code verfügbar sind. |