Changes list

DataAuthorComment

 

Raman AuramauAdded sequence diagram and steps-to-be-followed

 

Raman AuramauAdded more details after a talk with Yauheni Kuzmianok

 

Raman AuramauInitial document

Summary

This is a solution design document aimed to provide details, alternatives and decision for FOLIO cross-module access pattern.

Refer to and for tracking.

Problem Statement

Let's consider the following scenario: mod-orders-storage module needs to be populated with some data from mod_finance_storage module. A quick workaround implemented in migration script - https://github.com/folio-org/mod-finance-storage/blob/v6.0.1/src/main/resources/templates/db_scripts/migration/pending_payment_cross_module.ftl - directly accesses mod_invoice_storage database tables.

This violates the module separation approach since the FOLIO architecture mandates that cross-module communication goes through HTTP APIs only. Also in some cases this workaround may fail running of migration script because some deployments use database ROLEs with access restricted to the current schema, so that mod-finance-storage doesn't have any permissions for mod_invoice_storage tables.

Options considered

Currently there is no approach in FOLIO to address the described problem. The general idea is to move the cross-module migration code into some back-end module. Depending on this code location, one can consider these options as possible approaches:

  1. Implementing generic approach for the whole FOLIO platform
    1. this use case can be covered on RMB level though this is a zone of responsibility of a team rather than Thunderjet,
    2. not sure if there are any real use cases known at the moment; in theory, there might be really different and much more complex use cases,
    3. so, this option has no continuation now.
  2. Designing a generic pattern and implementing it locally in the mod-finance-storage
    1. this option can be covered by Thunderjet team by its own without impact or dependencies on others modules / teams,
    2. this implementation - after review and release - can be considered as a pattern in case of similar needs.

Implementing a cross-module access approach in the mod-finance-storage

In general, this option is based on handling data retrieving in Java code. E.g., TenantReferenceAPI.java in mod-finance-storage is to be extended - when upgrading mod-finance-storage

Note that migration process is applicable to *-storage modules only, so that migration logic cannot be implemented on upper level of business modules. Another benefit in this context is that all the migration is executed in the same database transaction which guarantees data consistency after migration completion.

Described flow is also visualized in the following sequence diagram:

Limitations and Assumptions

Steps to apply the implemented logic

The skeleton of this approach has been already created and available via https://github.com/folio-org/mod-finance-storage/pull/199/files

The following steps are to be followed:

private Future<Void> migration(TenantAttributes attributes, String migrationModule, Supplier<Future<Void>> supplier) {
	SemVer moduleTo = moduleVersionToSemVer(migrationModule);
	SemVer currentModuleVersion = moduleVersionToSemVer(attributes.getModuleFrom());
	if (moduleTo.compareTo(currentModuleVersion) > 0){
		return supplier.get();
	}
	return Future.succeededFuture();
}

private static SemVer moduleVersionToSemVer(String version) {
	try {
		return new SemVer(version);
	} catch (IllegalArgumentException ex) {
		return new ModuleId(version).getSemVer();
	}
}
 return Future.succeededFuture()
	// migrationModule value it the same as fromModuleVersion from schema.json
	.compose(v -> migration(attributes, "mod-finance-storage-6.1.0", () -> customizeYourMigrationLogicHere(headers, vertxContext)))
	.compose(v -> migration(attributes, "mod-finance-storage-5.0.0", () -> customizeYourMigrationLogicHere(headers, vertxContext)))
	.compose(v -> Future.future(promise -> tl.perform(attributes, headers, vertx, promise)));