What this is about
Embedded, CRMS has no cold start of its own. It comes up with the start of the CDMS application, in the same process and in the same order as CDMS and CIAS. As a service of its own it has its own start, which looks the same, only without the CDMS models next to it.
How CDMS and CIAS start as a whole is under Cold start of an installation. This page shows what CRMS adds to it.
The timeline
flowchart LR
A["1 Placement<br/>property against classpath"] --> B["2 Context<br/>mandatory settings, keys, bucket"]
B --> C["3 Tables<br/>system and tenant DB"]
C --> D["4 Templates<br/>seed shipped ones"]
D --> E["5 Timers<br/>anchoring, retention"]
E --> F(["ready for the first report"])
classDef stufe fill:#ffc107,stroke:#b38600,color:#1f1a00
classDef ziel fill:#4d7c0f,stroke:#4d7c0f,color:#fff
class A,B,C,D,E stufe
class F ziel
Stage 3 is not a fixed point in time. The tables of a database come about when it is needed for the first time, as with CDMS. For the system database that is at the latest when the templates are seeded.
The five stages
-
1CRMS1 Placement. Does
codamai.crms.placementmatch the classpath?localrequires the embedded CRMS,remoterequirescrms-clientand forbids the CRMS renderer and the CRMS HTTP interface. This check runs before anything else of CRMS. A wrongly assembled application fails here, before any module asks for its keys. -
2CRMS2 Context. Spring builds the objects of CRMS. Every mandatory setting is checked nowThe timestamping key, the platform administrator roles, the formats, and with stored documents the key, retention and bucket. Plus the building blocks the host has to provide: the caller and the tenant list from CIAS, the database layer of CDMS.
-
3CRMS→Database3 Tables. The
crms_…tables come about in the system database and in every tenant databaseCRMS registers its entities for both levels with the database layer. Hibernate builds the tables from them as soon as a database is needed for the first time. -
4Application→CRMS4 Templates. If the application ships templates, it seeds them as soon as it is readyAs a platform administrator in the scope
SYSTEM, through the normal path of draft and submit. The templates land in the system database. -
5CRMS5 Timers. One minute after the start, the anchoring pass and the retention pass beginResult: The application accepts render requests. The first anchor comes about in the first anchoring pass.
Stage 2: what fails the start
| Setting | If it is missing or wrong |
|---|---|
codamai.crms.placement is missing or does not match the classpath | the start fails, the message names the missing or surplus jar |
CODAMAI_CRMS_TSA_KEYSTORE is missing, is not PKCS#12, or the certificate has expired | the start fails. Without this key CRMS cannot anchor its journals |
| the timestamping certificate expires in less than 60 days | no start failure, a warning in the log with the expiry date |
the scope SYSTEM is admitted, but CIAS names no platform administrator role | the start fails. Nobody could write system templates |
a format in CODAMAI_CRMS_FORMATS without an installed format module | the start fails |
| documents are stored, but document key, retention, bucket or S3 access are missing | the start fails, the message names the variable |
| the bucket has no Object Lock | the start fails as long as CODAMAI_CRMS_STORAGE_ALLOW_UNLOCKED is off |
| an interval of the timers is zero or negative | the start fails |
remote: CODAMAI_CRMS_CLIENT_URL is missing or not an http or https address | the start fails. This is the only obligation of a client |
The list of all variables and when each is mandatory is under Environment variables. The timestamping key is explained in Timestamps and anchors.
Stage 3: where the CRMS tables land
CRMS has no database path of its own. It uses the shared CodamAI persistence layer, the same one as CDMS, and registers its entities there twice: once for the system database, once for every tenant database. So every database gets the same crms_… tables. Which row goes where is decided by whom it belongs to.
| Database | What CRMS keeps there |
|---|---|
| System database | system templates, the system journal, the anchors |
Tenant database, such as nordbau | templates of the tenant and its persons, the journal of nordbau, its final documents, the proof path of its journal |
In SINGLE that is one database. The files of the final documents are not in the database but in the S3 bucket.
Unlike CIAS, there is no migration run of its own for this. The tables come about the same way as those of the CDMS models, on the first access to the database in question. So after an update, a tenant database too is raised only when this tenant works or a timer visits it. Details under The database and Databases and schemas.
Stage 4: seeding shipped templates
CRMS does not read a template folder by itself. If an application ships templates in its build, the application seeds them. The hub backend does this for its project documents as soon as it reports itself ready:
-
1Applicationacts as a platform administrator: the roles from CIAS, no tenant, the identifier
hub-backendas author -
2Application→CRMScreates missing editions and language variants in the scope
SYSTEM -
3ApplicationIs the source equal to the published revision?
-
4Application→CRMSonly if not: save a draft and submit it with a reason
-
5CRMSthe approval chain of the scope
SYSTEMdecidesResult: Without approval stages the template is published immediately. An unchanged build changes nothing.
If seeding fails, that is in the log, and the start goes on. Everything else in the application works without the templates. A report that needs them answers with template-not-found until the next successful seeding. The whole path is shown in Templates shipped with a build.
Stage 5: the first anchoring pass
Anchoring means: CRMS has the latest state of every journal confirmed with a timestamp. That way nothing can be rewritten unnoticed later.
-
1CRMS→CIASasks for all tenants, page by pageSuspended and closed ones too. Their journal has to stay anchored, and their retention periods keep running. Embedded CIAS answers by method call, standalone CIAS over HTTP.
-
2CRMS→Databasereads the head of the system journal and the head of the journal of every tenantFor every tenant, CRMS enters its context through CIAS. The tenant gate also admits tenants that are not served, but refuses unknown ones. The context has no roles.
-
3CRMSbuilds a tree from all heads, has its root stamped and puts the anchor into the system database
-
4CRMS→Databaseputs each tenant's proof path into its own databaseResult: If a tenant cannot be reached, it is left out and picked up in the next pass. A pass that fails as a whole is in the log; the next one is the retry.
The first pass begins one minute after the start, then every CODAMAI_CRMS_ANCHOR_INTERVAL (hourly). The retention pass, which removes expired documents, follows the same pattern with an interval of 24 hours. Both are on as soon as CRMS is embedded. With CIAS it is the other way round: its timers are off until somebody switches them on. The reason is that anchoring and retention are obligations, not maintenance.
With several instances of the same application, you leave the timers on in exactly one (CODAMAI_CRMS_SCHEDULING_ENABLED). How an anchor is built is under Timestamps and anchors.
CRMS registers its roles
In stage 4 of the cold start, CIAS reads the declarations of the modules, that is, the lists of their roles and attributes, and creates roles in Keycloak from them. An embedded CRMS is in this list as module crms, next to cias and cdms. Its declaration is the bean crmsIdentityRegistry, and the project frame lists it.
It follows that:
- What is not used is not added. A scope the installation does not admit and documents it does not store register no role. The hub admits system templates only and stores no documents, so its list is empty.
- The reconciliation creates the roles as client roles on the application’s client, like CDMS’s. You grant them like any other role.
- A new name replaces the old one. If the installation renames a role, CRMS registers the new name. The reconciliation retires the old one instead of deleting it. See Modules register roles and attributes.
- CRMS never registers platform roles. System templates are written by the platform administrators that CIAS names for the installation. See The platform’s realm roles.
- A CRMS service of its own registers nothing. Its roles belong to the client of the CRMS service. You create them there yourself.
Where you set the role names is under The roles.
The variants
When: Everything runs in one process, as in the hub backend.
One start for all three. The CRMS tables sit next to those of CDMS and CIAS in the system database and next to the tenant models in every tenant database. The tenant list for the anchoring pass is a method call.
Result: When the process is up, it can produce reports.
When: CRMS sits in the CDMS application, CIAS is a service of its own.
The start of the application checks the same as above. The anchoring pass asks the CIAS service for the tenants over HTTP, with the application's service token. For that, CIAS has to publish its tenant list, and the service account needs the role from codamai.cias.tenancy.directory-roles there.
Result: If CIAS cannot be reached during the first pass, only that pass fails. The start is not affected.
When: The CRMS module sits in a runtime without a CDMS application.
The CRMS service has its own start and its own database with only the CRMS tables. It needs the same mandatory settings, plus bucket and S3 access always. It asks CIAS over HTTP, for the tenant gate and for the tenant list.
Result: The timers run in the CRMS service, not in the applications that call it.
When: The application calls a CRMS service through crms-client.
The application checks only the placement and the address of the service. It has no CRMS tables, no keys, no templates to seed and no timers. All of that belongs to the service.
Result: If the CRMS service is not running yet, the application still starts. Reports then answer with crms-unavailable.