Skip to content

Commit

Permalink
Merge pull request #1699 from folio-org/FOLIO-873-improve-docs-271
Browse files Browse the repository at this point in the history
FOLIO-873 improve docs
  • Loading branch information
dcrossleyau authored Jul 16, 2024
2 parents 90468c0 + 0e58219 commit d96fa2b
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 65 deletions.
1 change: 1 addition & 0 deletions _data/remote-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"https://raw.githubusercontent.com/folio-org/rfcs/master/text/0002-kafka-tenant-collection-topics.md",
"https://raw.githubusercontent.com/folio-org/rfcs/master/text/0003-folio-breaking-changes.md",
"https://raw.githubusercontent.com/folio-org/rfcs/master/text/0004-iso-8601.md",
"https://raw.githubusercontent.com/folio-org/rfcs/master/text/0005-application-formalization.md",
"https://raw.githubusercontent.com/folio-org/rfcs/master/text/0006-folio-distributed-vs-centralized-configration.md",
"https://raw.githubusercontent.com/folio-org/stripes-cli/master/doc/dev-guide.md",
"https://raw.githubusercontent.com/folio-org/stripes-cli/master/doc/user-guide.md",
Expand Down
4 changes: 2 additions & 2 deletions _data/repos.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"metadata": {
"generatedDateTime": "2024-07-02T01:07:37.886603+00:00"
"generatedDateTime": "2024-07-15T23:48:55.230975+00:00"
},
"repos": [
{
Expand Down Expand Up @@ -3799,7 +3799,7 @@
"org": "folio-org",
"repoLanguageHint": "node",
"repoType": "stripes",
"snippetIntro": "<p>stripes-testing is a toolkit for building integration tests against Stripes UI modules and platforms. There are no tests in this repository; instead they exist in the platforms they exercise (e.g. platform-core). Tests that operate only a single app (unit tests) should be written with the <a href='https://github.com/folio-org/stripes/blob/master/doc/bigtest.md'>BigTest</a> toolkit instead.</p>",
"snippetIntro": "<p>stripes-testing is a toolkit for building integration tests against Stripes UI modules and platforms. This repository contains:</p>",
"workflows": [
"build-npm-release.yml",
"build-npm.yml"
Expand Down
24 changes: 20 additions & 4 deletions _faqs/how-to-which-module-which-interface-endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,44 @@ Registry queries such as the following will assist investigation ...

### Interfaces provided by module

Confirm that a certain [back-end module](/source-code/map/#backend-mod) implements a certain interface which handles a set of endpoints.
Confirm that a certain [back-end module](/source-code/map/#backend-mod) implements a certain interface which handles a set of [endpoints](/reference/api/endpoints/).
Obtain its ModuleDescriptor from the registry and extract the "provides" section.
For example:

```
curl -s -S -w'\n' \
'https://folio-registry.dev.folio.org/_/proxy/modules?filter=mod-inventory-storage&latest=1&full=true' \
| jq '.[].provides'
| jq -r '.[].provides'
curl -s -S -w'\n' \
'https://folio-registry.dev.folio.org/_/proxy/modules?filter=mod-inventory-storage&latest=1&full=true' \
| jq -r '.[].provides[] | [.id, .version] | @tsv'
```

### Requires an interface

Discover which modules are using a specific interface:

```
curl -s -S -w'\n' \
'https://folio-registry.dev.folio.org/_/proxy/modules?latest=1&require=inventory-record-bulk' \
| jq -r '.[].id'
```

### Requires an old interface

```
curl -s -S -w'\n' \
'https://folio-registry.dev.folio.org/_/proxy/modules?latest=1&require=instance-bulk%3D0.1'
'https://folio-registry.dev.folio.org/_/proxy/modules?latest=1&require=instance-bulk%3D0.1' \
| jq -r '.[].id'
```

### Provides a newer interface

```
curl -s -S -w'\n' \
'https://folio-registry.dev.folio.org/_/proxy/modules?latest=1&provide=inventory-record-bulk'
'https://folio-registry.dev.folio.org/_/proxy/modules?latest=1&provide=inventory-record-bulk' \
| jq -r '.[].id'
```

## UI Developer Settings
Expand Down
4 changes: 3 additions & 1 deletion _remote/raml-module-builder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2521,7 +2521,9 @@ RMB handles all routing, so this is abstracted from the developer. However, ther

#### De-Serializers

At runtime RMB will serialize/deserialize the received JSON in the request body of PUT, PATCH and POST requests into a POJO and pass this on to an implementing function, as well as the POJO returned by the implementing function into JSON. A module can implement its own version of this. For example, the below will register a de-serializer that will tell RMB to set a User to not active if the expiration date has passed. This will be run when a User JSON is passed in as part of a request
At runtime RMB will serialize/deserialize the received JSON in the request body of PUT, PATCH and POST requests into a POJO and pass this on to an implementing function, as well as the POJO returned by the implementing function into JSON. The ObjectMapperTool provides the serializer and de-serializer. Note that `JsonObject.mapFrom` is incompatible, use `ObjectMapperTool.valueAsString` instead.

A module can implement its own version of the de-serializer, for example, the below will register a de-serializer that will tell RMB to set a User to not active if the expiration date has passed. This will be run when a User JSON is passed in as part of a request

```java
ObjectMapperTool.registerDeserializer(User.class, new UserDeserializer());
Expand Down
12 changes: 12 additions & 0 deletions _remote/raml-module-builder/doc/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ These are notes to assist upgrading to newer versions.
See the [NEWS](../NEWS.md) summary of changes for each version.

<!-- ../../okapi/doc/md2toc -l 2 -h 3 upgrading.md -->
* [Version 35.3](#version-353)
* [Version 35.2](#version-352)
* [Version 35.1](#version-351)
* [Version 35.0](#version-350)
Expand All @@ -29,6 +30,12 @@ See the [NEWS](../NEWS.md) summary of changes for each version.
* [Version 25](#version-25)
* [Version 20](#version-20)

## Version 35.3

Don't use `JsonObject.mapFrom` to serialize a Java class instance to JSON,
RMB's database methods automatically do this. When writing custom SQL use
`ObjectMapperTool.valueAsString` to serialize in a way compatible with RMB's deserializer.

## Version 35.2

35.2.\* is the Quesnelia (R1 2024) version.
Expand All @@ -51,6 +58,11 @@ because the
and [artifact name](https://github.com/jakartaee/validation/commit/80f3223c3aa7696e3a732ae802baac8fc529f785)
have changed.

Don't use `JsonObject.mapFrom` to serialize a Java class instance to JSON,
RMB's database methods automatically do this. When writing custom SQL use
`ObjectMapperTool.getMapper().writeValueAsString` to serialize
in a way compatible with RMB's deserializer.

## Version 35.1

35.1.\* is the Poppy (R2 2023) version.
Expand Down
201 changes: 201 additions & 0 deletions _remote/rfcs/text/0005-application-formalization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
---
layout: null
---

* Start Date: 10/09/2023
* Contributors:
* [Craig McNally]([email protected])
* [Vince Bareau]([email protected])
* RFC PRs:
* PRELIMINARY REVIEW: https://github.com/folio-org/rfcs/pull/14
* DRAFT REFINEMENT: https://github.com/folio-org/rfcs/pull/22
* PUBLIC REVIEW: https://github.com/folio-org/rfcs/pull/29
* FINAL REVIEW: https://github.com/folio-org/rfcs/pull/34
* Outcome: ACCEPTED

# Application Formalization

## Summary
It is proposed that an Application be defined as the minimal but complete set of elements which together are intended to deliver a specific solution to Folio. The intention is to group together all the closely related components which will need to evolve together, but independently of other parts (i.e. other applications) of Folio.

## Motivation
The existing Folio project lacks a formal definition of an Application structure. A consequence is that Folio is stuck in a mode of monolithic releases which are ever increasing in size. There have also been repeated complaints that the setup and management of Folio can be difficult due to the number modules involved.

## Scope
* Application composition
* Application versioning
* Application dependencies
* Application definition/descriptors
* Backward compatibility with Folio instances not adopting Applications
* Application management and deployment are ***out of scope***
* Application Stores and Marketplaces are ***out of scope***
* Application-specific UI bundles is ***out of scope***
* How movement of modules between Applications will work is ***out of scope***
* How bounded contexts and cross-module database access could be introduced is ***out of scope***

## Detailed Explanation/Design

### Terminology
* Application: The minimal but complete set of elements which together are intended to deliver a specific solution to Folio.
* Bounded context: The boundary of the microservice. It "owns" the storage for the service.

### Specifics

#### Application Composition
Applications can be thought of as vertical slices of functionality. As such, they're are comprised of a combination of the following:
* Backend Modules
* Edge Modules
* UI Modules
* UI Plugins

Applications will typically be made up of multiple components spanning all or several of these categories. However, that's not a requirement. In fact, in it's simplest form, it's possible for an application to be comprised of a single module from any of the categories listed above.

An important concept introduced by the formalization of Applications, is that Applications become the delivery mechanism for the modules they contain. Therefore, if a new version of a particular module is required, then it follows that the new version of the entire Application must be installed. It then also follows that a given version of a Module must belong to one and only one Application. To do otherwise is possible, but would quickly lead to dependency and version management challenges. This restriction is enforced by the Application Manager and/or Folio Application Registry (FAR), both of which are out of scope for this RFC. It is recognized that there must be accommodations to allow refactoring or consolidation of Applications, which could involve moving of particular Modules from one Application to another.

#### Application Versioning
* Applications must maintain their own versioning which is independent of the versioning of their components. The components which comprise Applications already have their own independent versioning which would still need to remain in effect.
* Applications have versioning separate from interface versioning
* Application compatibility is determined at the Application level
* This allows Applications to have independent development lifecycles.
* The [semantic version](https://semver.org/) system is used for applications.

#### Application Dependencies
Formalizing Applications does not change the underlying module implementations. This means modules which depend on interfaces provided by other modules continue to have those dependencies, and those dependencies may span Application boundaries. However, the Application formalization rolls those interface dependencies up into Application dependencies, or dependencies on specific versions of applications.

Example w/ many version omitted for clarity:
**app-foo-1.0.1**
* requires:
* `app-bar: ^1.0.0`
* modules:
* `ui-foo`
* requires interfaces: `foo`
* `mod-foo`
* provides interfaces: `foo`
* requires interfaces: `foo-storage`, `bar`
* `mod-foo-storage`
* provides interfaces: `foo-storage`
* requires interfaces:

**app-bar-1.0.0**
* requires:
* `app-configuration: ~1.1.1`
* modules:
* `mod-bar`
* provides interfaces: `bar`
* requires interfaces: `configuration`
* `ui-bar`
* requires interfaces: `bar`

**app-configuration-1.1.1**
* requires:
* modules:
* `mod-configuration`
* provides interfaces: `configuration`
* requires interfaces:

In this scenario, in order for `app-foo-1.0.1` to be enabled for a tenant, `app-bar-1.X.X` and `app-configuraturation-1.1.X` would also need to be enabled for the tenant. This is because `app-foo` depends on a compatible version (specified as `^`) of `app-bar-1.X.X`, and `app-bar` depends on an approximately equivalent version (specified as `~`) of `app-configuration-1.1.1`. Exact versions and/or ranges can also be specified. See the [node-semver documentation](https://github.com/npm/node-semver#advanced-range-syntax]) for details.

#### Application Descriptors
Similar to how modules are explicitly defind through module descriptors, applications are defined through application descriptors. The application descriptor references module descriptors

**Application Descriptor Properties**
| Property | Type | Description | Notes |
| ------------------- | ------------ | ------------------------------------------------------------------------------------ | ------------------------ |
| id | String | Identifier for the application conforming to pattern: `{name}-{semantic version}` | e.g. "app-orders-1.0.0" |
| name | String | Name of the application | e.g. "app-orders" |
| version | String | Version of the application | e.g. "1.0.0" |
| description | String | Brief description of the application | e.g. "Application delivering orders functionality" |
| dependencies | Dependency[] | List of dependencies on other applications | See "Dependency Properties" table below |
| modules | ModuleId[] | List of backend/edge modules comprising the application | See "ModuleId Properties" table below |
| uiModules | ModuleId[] | List of UI modules comprising the application | See "ModuleId Properties" table below |
| moduleDescriptors | ModuleDescriptor[] | Module descriptors for the backend/edge modules comprising the application | Read-only. See [ModuleDescriptor Schema](https://github.com/folio-org/okapi/blob/master/okapi-core/src/main/raml/ModuleDescriptor.json) |
| uiModuleDescriptors | ModuleDescriptor[] | Module descriptors for the frontend modules/plugins comprising the application | Read-only. See [ModuleDescriptor Schema](https://github.com/folio-org/okapi/blob/master/okapi-core/src/main/raml/ModuleDescriptor.json) |
| metadata | Metadata | System-generated record metadata | Read-only. See [Metadata Schema] (https://github.com/folio-org/raml/blob/master/schemas/metadata.schema) |

**NOTE**: Module descriptors are not being retired or replaced. As such, there's no need to duplicate all of the information in the module descriptor in the application descriptor. Things like the launchDescriptors sections of module descriptors are not duplicated or moved to the application descriptor.

**Dependency Properties**
| Property | Type | Description | Notes |
| ---------| ------- | -------------------------------------------------------------------- | -------------------------------- |
| id | String | Identifier for the module conforming to pattern: `{name}-{version}` | e.g. "mod-orders-storage-13.5.0" |
| name | String | Name of the module | e.g. "mod-orders" |
| version | String | Version of the module | e.g. "13.5.0" |

**ModuleId Properties**
| Property | Type | Description | Notes |
| -------- | ------- | -------------------------------------------------------------------- | -------------------------------- |
| id | String | Identifier for the module conforming to pattern: `{name}-{version}` | e.g. "mod-orders-storage-13.5.0" |
| name | String | Name of the module | e.g. "mod-orders" |
| version | String | Version of the module | e.g. "13.5.0" |
| url | String | URL pointing to the module descriptor for this module | e.g. "https://folio-registry.dev.folio.org/_/proxy/modules/mod-orders-storage-13.5.0" |

Example:
```
{
"id": "app-gobi-0.0.1",
"name": "app-gobi",
"version": "0.0.1",
"description": "Application facilitating the placement of orders via GOBI and other compatible vendors",
"dependencies": [
{
"id": "app-orders-0.0.1",
"name": "app-orders",
"version": "^0.0.1"
},
{
"id": "app-organizations-0.0.1",
"name": "app-organizations",
"version": "^0.0.1"
}
],
"modules": [
{
"id": "mod-gobi-2.6.0",
"name": "mod-gobi",
"version": "2.6.0",
"url": "https://folio-registry.dev.folio.org/_/proxy/modules/mod-gobi-2.6.0"
}
],
"uiModules": [
{
"id": "folio_gobi-settings-2.0.0",
"name": "folio_gobi-settings",
"version": "2.0.0",
"url": "https://folio-registry.dev.folio.org/_/proxy/modules/folio_gobi-settings-2.0.0"
}
]
}
```
**N.B.** Full module descriptors and metadata have been omitted for readability reasons.

## Benefits
* Application formalization is the necessary first step in being able to create Application-level releases.
* NOTE: How Application releases are packaged into a Folio release is the subject of a future RFC about Platforms.
* The system operator can focus on an Application (which is a "package") rather than the multitude of individual modules it contains. They'd work with the single Application instead of the individual parts of that Application (business logic module, storage module, UI module, plugins, etc.)
* Brings us closer to realizing the idea of having an application store/marketplace
* Application formalization facilitates the adoption of a formalized microservice bounded context (subject of a separate RFC: https://github.com/folio-org/rfcs/pull/20)

## Risks and Drawbacks
* Transition to Applications should be iterative
* First pass is to create larger applications spanning multiple areas in order to satisfy dependencies
* Subsequent passes will further break up these large applications into smaller, applications focused on a single area of functionality
* Since Applications are a vertical slice of functionality, better alignment/coordination between back-end and front-end development team members is required.
* Reorganizing development teams around applications would help
* By latching onto the Application term, there may be confusion about terminology since that term currently means different things to different people.
* It may help to proposed formal names for other things currently referred to as Applications (e.g. the icons that appear in the Folio toolbar)

## Rationale and Alternatives
Alternative approaches include:
* **Status quo** - Don't do anything and deal with monolithic releases, an ever-growing number of modules, and all the problems and challenges associated with those things.
* Releasing of coarser granularity packages of modules; e.g. platform-core, platform-minimal, platform-complete, etc.
* **Independent module release cycles** - Impractical due to how tightly coupled modules are to one another. It also doesn't address the issue of system operators needing to manage an ever growing number of modules.

## Timing
* First in the sequence.
* RFC Submission: Early October '23

## Unresolved Questions
The following unresolved questions are not addressed here, but will be the addressed in other RFCs:
* How will Application management work?
* How will Application Descriptors be developed and maintained?
* How the Stripes UI will be updated as applications are enabled/disabled/upgraded?
Loading

0 comments on commit d96fa2b

Please sign in to comment.