Worum es geht
CRMS läuft auf zwei Arten, genau wie CIAS:
- eingebettet (
local): CRMS läuft im selben Prozess wie eine CDMS-Anwendung. Die Anwendung ruft die Ports als Java-Methoden auf. - als eigener Dienst (
remote): CRMS läuft als eigenes Programm. Andere Anwendungen rufen es über HTTP auf, mitcrms-client.
Fachlich verhält sich CRMS in beiden Fällen gleich: dieselben Ports, dieselben Antworten, dieselben Fehlerschlüssel.
Die zwei Betriebsarten
| local | remote | |
|---|---|---|
| Eigenschaft | codamai.crms.placement=local | codamai.crms.placement=remote |
| Auf dem Klassenpfad | Starter, das eingebettete CRMS (bringt Vorlagenverwaltung, Renderer und Nachweis mit), die gewählten Formatmodule, die HTTP-Schnittstelle von CRMS und, solange endgültige Dokumente gespeichert werden, der S3-Speicher von CRMS | Starter und crms-client, sonst nichts von CRMS |
| Aufruf | Methodenaufruf im selben Prozess | HTTP an den CRMS-Dienst |
| Datenbank | die Datenbank der CDMS-Anwendung | die eigene Datenbank des Dienstes |
| Zeitgesteuerte Läufe | laufen in der Anwendung: Verankerung und Aufbewahrung | laufen im CRMS-Dienst, nicht in der Anwendung |
| Vorlagen bearbeiten | über /crms/** der Anwendung | direkt über die Routen des CRMS-Dienstes |
Die HTTP-Schnittstelle von CRMS gehört zur eingebetteten Art. Eine Anwendung, die CRMS einbettet, stellt damit /crms/** bereit, und andere Anwendungen können sie als CRMS-Dienst nutzen. Eine Anwendung mit remote darf diese Schnittstelle nicht haben. Sie würde sonst den Dienst über eigene Routen weiterreichen, hinter ihrer eigenen Sicherheit.
CIAS kennt dieselben zwei Bauformen, siehe CIAS eingebettet (eine Einheit).
Was beim Start geprüft wird
Der Starter prüft die Eigenschaft gegen den Klassenpfad, bevor irgendein anderer Teil von CRMS entsteht. Passt etwas nicht, startet die Anwendung nicht, und die Meldung sagt, welches jar fehlt oder zu viel ist.
| Renderer von CRMS und crms-client zusammen? | codamai.crms.placement | Klassenpfad | Start |
|---|---|---|---|
| ja | – | – | scheitert: einbetten oder aufrufen, nie beides |
| nein | fehlt oder leer | – | scheitert: die Eigenschaft ist Pflicht |
| nein | weder local noch remote | – | scheitert |
| nein | local | eingebettetes CRMS fehlt | scheitert |
| nein | remote | crms-client fehlt | scheitert |
| nein | remote | HTTP-Schnittstelle von CRMS vorhanden | scheitert |
| nein | local | eingebettetes CRMS vorhanden | CRMS eingebettet |
| nein | remote | crms-client vorhanden | CRMS über HTTP |
Die Eigenschaft hat keinen Standardwert. Ein Projektrahmen, der sie vergessen hat, liefe sonst still mit der falschen Art.
In einem Native Image steht der Klassenpfad schon beim Bauen fest, die Eigenschaft wird erst beim Start gelesen. Das ist Absicht: Ein Native Image hat einen festen Klassenpfad, läuft aber in verschiedenen Umgebungen. Die Umgebungsvariable dazu heißt CODAMAI_CRMS_PLACEMENT.
Der Hub entscheidet
Ein Projekt im Hub hat höchstens ein CRMS-Modul. Wo du dieses Modul hinlegst, also in welche Laufzeit (das Programm, das später läuft), entscheidet über die Betriebsart jeder CDMS-Anwendung des Projekts. Es gibt kein Feld, in dem du local oder remote einträgst.
| Hat das Projekt ein CRMS-Modul? | Meldet sich die CDMS-Anwendung über CIAS an? | Wo liegt das CRMS-Modul? | Die CDMS-Anwendung |
|---|---|---|---|
| nein | – | – | ohne CRMS |
| ja | nein | nicht in ihrer eigenen Laufzeit | ohne CRMS |
| ja | nein | in ihrer eigenen Laufzeit | Build abgelehnt: CRMS braucht CIAS |
| ja | ja | in keiner Laufzeit | Build abgelehnt: das CRMS-Modul muss in eine Laufzeit |
| ja | ja | in ihrer eigenen Laufzeit | local: CRMS eingebettet |
| ja | ja | in einer anderen Laufzeit | remote: Client des CRMS dort |
„In einer anderen Laufzeit“ heißt entweder ein eigener CRMS-Dienst oder eine andere CDMS-Anwendung des Projekts, in die CRMS eingebettet ist. Liegt das CRMS-Modul in einer Laufzeit ohne CDMS-Anwendung, entsteht daraus ein eigener CRMS-Dienst.
Der Build setzt dann die passenden Abhängigkeiten in die POM. Bei local kommen nur die Formatmodule der Formate hinein, die das CRMS-Modul gewählt hat. Bei remote kommt kein Formatmodul hinein, denn gerendert wird im Dienst.
Ein Aufruf über HTTP
Bei remote gilt eine Regel: Der Aufruf trägt die Person, nicht den Dienst. crms-client reicht das Zugriffstoken der Anfrage weiter, die die Anwendung gerade beantwortet. Ein eigenes Dienst-Token schickt es nie. So nennt jede Revision, jede Freigabe und jedes endgültige Dokument die Person, die es ausgelöst hat.
-
1Benutzer→Clientklickt auf „Bericht erzeugen“
-
2Client→CDMSAnfrage mit Token:
Authorization: Bearer … -
3CDMSbaut die Payload und ruft
ReportRenderPort.render(…)auf -
4CDMSläuft gerade eine Anfrage mit Token?
-
5CDMSkein Token, etwa in einem Hintergrundjob →
crms-authentication-required, es wird nichts gesendet -
6CDMS→CRMS
crms-clientschicktPOST /crms/rendermit demselben Token -
7CRMS→Keycloaktauscht das Token gegen sein eigenes, mit den Rollen, die CRMS für diese Person kennt
-
8CRMSrendert wie eingebettet
-
9CRMS→CDMSantwortet mit dem Dokument
-
10CDMS→Clientreicht das Ergebnis weiterErgebnis: Dasselbe
RenderedDocumentoder dieselbeCrmsExceptionwie eingebettet
crms-client übersetzt die Antwort zurück in dieselben Objekte und Fehler, die die eingebettete Art liefert. Ist der Dienst nicht erreichbar, läuft die Zeit ab oder kommt eine Antwort, die nicht von CRMS stammt, wird daraus crms-unavailable, nie ein halbes Ergebnis. Die Adresse des Dienstes steht in CODAMAI_CRMS_CLIENT_URL. Mehr unter Der Client.