CodamAIDocs
Themafertig

Was auditiert wird

Welche Modelle eine Historie haben, welche Operationen eine Revision erzeugen und welche Revisionsarten es gibt.

Ausprägungen
auditing: trueADDMODDELnicht auditiertes Modell

Worum es geht

Ein Modell ist entweder auditiert oder nicht. Auditiert heißt: CDMS hebt bei jeder Änderung eines Objekts den neuen Stand auf. So ein gespeicherter Stand heißt Revision. Alle Revisionen eines Objekts zusammen sind seine Historie.

Ob ein Modell auditiert ist, entscheidet ein einziger Schalter am Modell: im Hub „Auditing: ja“, in einer Modelldatei auditing: true. Der Schalter gilt für das ganze Modell. Einzelne Felder kannst du nicht ausnehmen.

Der Zeitstrahl eines Objekts

So sieht die Historie eines Auftrags aus, der angelegt, zweimal geändert, einmal zurückgesetzt und dann gelöscht wird:

flowchart LR
    A["Revision 17 · ADD<br/>POST /create<br/>price 90.8"] --> B["Revision 42 · MOD<br/>PATCH<br/>price 120.5"]
    B --> C["Revision 51 · MOD<br/>PUT<br/>price 99.0"]
    C --> D["Revision 58 · MOD<br/>Rollback auf 17<br/>price 90.8"]
    D --> E["Revision 63 · DEL<br/>DELETE"]

Jede Revision hat eine Art, im JSON revisionType:

ArtBedeutungWas die Revision enthält
ADDdas Objekt wurde angelegtden Stand direkt nach dem Anlegen
MODdas Objekt wurde geändertden Stand direkt nach der Änderung
DELdas Objekt wurde gelöschtnur die id, alle anderen Felder sind leer

Die Nummern steigen, sind aber nicht lückenlos. Dazwischen liegen Revisionen anderer Objekte. Mehr dazu unter Was eine Revision festhält.

Welche Operation welche Revision erzeugt

OperationRevision
POST /createADD
PUT /update/{id}, PATCH /update/{id}MOD, auch wenn sich fachlich nichts ändert, denn _updatedOn wird neu gesetzt
neuer Dateiinhalt bei einem Datei-ModellMOD, weil sich fileVersion, Größe und Typ ändern
POST /{id}/rollback/{revision}MOD mit dem alten Inhalt, siehe Auf einen alten Stand zurücksetzen
DELETE /delete/{id}DEL
Kind wird im selben Request mit angelegt, geändert oder gelöschteine eigene ADD-, MOD- oder DEL-Revision für das Kind, wenn sein Modell auditiert ist
nur eine Liste des Objekts ändert sichMOD für das Objekt mit der Liste
lesen, suchen, Historie lesen, herunterladenkeine Revision

Die Revisionen entstehen erst, wenn die Anfrage erfolgreich zu Ende geht. Scheitert sie, wird mit allem anderen auch die Revision verworfen. Siehe Ein Request, eine Transaktion.

Eine Anfrage, eine Revisionsnummer

Ändert eine Anfrage mehrere Objekte, bekommen alle Änderungen dieselbe Revisionsnummer. Ein Auftrag mit drei neuen Positionen, in einem Request angelegt, ergibt also eine Revision 17, und darin stehen der Auftrag und die drei Positionen, jeweils als ADD.

Das gilt je Datenbank. Berührt eine Anfrage Modelle in der System-Datenbank und in der Mandanten-Datenbank, entsteht in jeder Datenbank eine eigene Revision mit eigener Nummer. Siehe Keine Atomarität über zwei Datenbanken.

Auditiert oder nicht

Entsteht eine Revision?
Modell auditiert?Anfrage schreibt?Anfrage erfolgreich?Ergebnis
nein––keine Revision, es gibt nur den aktuellen Stand
janein–keine Revision, Lesen wird nicht aufgezeichnet
jajaneinkeine Revision, die Änderung wurde verworfen
jajajaneue Revision ADD, MOD oder DEL
Was der Schalter bewirkt
auditing: true
auditiert
  • jede Änderung wird eine Revision
  • Historie und Rollback sind möglich, wenn die Endpunkte eingetragen sind
  • bei Datei-Modellen bleibt jeder alte Inhalt als Version
  • die Datenbank bekommt zu jeder Tabelle eine Audit-Tabelle
  • hibernate-envers kommt in die POM
auditing: false
nicht auditiert
  • nur der aktuelle Stand
  • keine Historie, kein Rollback, auch wenn die Endpunkte eingetragen sind
  • ein neuer Dateiinhalt überschreibt den alten
  • nach dem Löschen bleibt nichts

Was im Hintergrund passiert

Du musst das nicht wissen, um die API zu benutzen. Es hilft aber, wenn du in die Datenbank schaust:

Vom Schalter zur Revision
  1. 1
    Hub
    Das Modell ist auf „Auditing: ja“ gestellt.
  2. 2
    Build
    Der Generator schreibt @Audited an die Entity-Klasse und nimmt hibernate-envers in die POM auf.
    Envers ist die Bibliothek, die Revisionen schreibt. Siehe Der Projektrahmen.
  3. 3
    Datenbank
    Zu jeder Tabelle des Modells gibt es eine Audit-Tabelle <tabelle>_AUD, dazu einmal je Datenbank die Tabelle revinfo.
  4. 4
    CDMS→Datenbank
    Bei jedem erfolgreichen Schreiben legt Envers eine Zeile in revinfo an und für jedes geänderte Objekt eine Zeile in dessen _AUD-Tabelle.
    Ergebnis: revinfo sagt wer, wann und von wo. Die _AUD-Zeile hält den Stand des Objekts.

Die Endpunkte zum Lesen der Historie und zum Zurücksetzen entstehen nur, wenn das Modell auditiert ist und sie in der Endpunkt-Liste stehen. Siehe Welche Endpunkte ein Modell hat.

Besondere Fälle

Auditing und die Zeit

Wann: Ein Modell mit bestehenden Daten wird auf auditiert gestellt und neu generiert.

Die Historie beginnt mit der ersten Änderung danach. Für ein bestehendes Objekt ist die erste Revision dann ein MOD, ein ADD gibt es nicht. Ältere Stände kennt CDMS nicht, und auf sie kannst du auch nicht zurücksetzen.

Wann: Ein auditiertes Modell wird auf nicht auditiert gestellt.

Neue Änderungen werden nicht mehr aufgezeichnet, und die Endpunkte für Historie und Rollback entfallen. Was bis dahin aufgezeichnet wurde, bleibt in der Datenbank, ist über die API aber nicht mehr erreichbar.

Wann: Ein auditiertes Modell hat eine Beziehung zu einem anderen Modell.

Das Zielmodell muss ebenfalls auditiert sein. Envers weist ein auditiertes Modell ab, das auf ein nicht auditiertes zeigt, und die Anwendung startet dann nicht. Modelle, die miteinander verbunden sind, auditierst du deshalb gemeinsam.

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-generator – EntityProcessor (@Audited(withModifiedFlag = true, targetNotFoundAction = IGNORE) bei auditing), CdmsYamlLoader (auditing, Endpunkte HISTORY_*/HISTORY_ROLLBACK), ApiProcessor/ApiSingletonProcessor (getHistoryMethod, getRollbackMethod: nur isAudited() und Endpunkt)
  • CDMS/cdms-persistence-database – models/AbstractEntityModel (@Audited an der Basisklasse), auditing/AuditRevisionEntity, AuditHistoryReader.queryHistory (RevisionType), EntityClassFilterService (revinfo je Persistenzziel)
  • CDMS/cdms-integrationtest – AbstractAuditTrailTest.createPatchDeleteAreEachRecorded (ADD, MOD, DEL; eine Revision je Transaktion)
  • documentation/50-auditierung/01-auditing-und-historie.md
Suchen