diff --git a/_data/remote-docs.json b/_data/remote-docs.json index 07fd6541..398724e7 100644 --- a/_data/remote-docs.json +++ b/_data/remote-docs.json @@ -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", diff --git a/_data/repos.json b/_data/repos.json index 534de71d..da3f59cb 100644 --- a/_data/repos.json +++ b/_data/repos.json @@ -1,6 +1,6 @@ { "metadata": { - "generatedDateTime": "2024-07-02T01:07:37.886603+00:00" + "generatedDateTime": "2024-07-15T23:48:55.230975+00:00" }, "repos": [ { @@ -3799,7 +3799,7 @@ "org": "folio-org", "repoLanguageHint": "node", "repoType": "stripes", - "snippetIntro": "

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 BigTest toolkit instead.

", + "snippetIntro": "

stripes-testing is a toolkit for building integration tests against Stripes UI modules and platforms. This repository contains:

", "workflows": [ "build-npm-release.yml", "build-npm.yml" diff --git a/_faqs/how-to-which-module-which-interface-endpoint.md b/_faqs/how-to-which-module-which-interface-endpoint.md index 504669a9..0e936f2b 100644 --- a/_faqs/how-to-which-module-which-interface-endpoint.md +++ b/_faqs/how-to-which-module-which-interface-endpoint.md @@ -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 diff --git a/_remote/raml-module-builder/README.md b/_remote/raml-module-builder/README.md index be6a1ca2..016041ed 100644 --- a/_remote/raml-module-builder/README.md +++ b/_remote/raml-module-builder/README.md @@ -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()); diff --git a/_remote/raml-module-builder/doc/upgrading.md b/_remote/raml-module-builder/doc/upgrading.md index 2f0aa1b5..9959324f 100644 --- a/_remote/raml-module-builder/doc/upgrading.md +++ b/_remote/raml-module-builder/doc/upgrading.md @@ -8,6 +8,7 @@ These are notes to assist upgrading to newer versions. See the [NEWS](../NEWS.md) summary of changes for each version. +* [Version 35.3](#version-353) * [Version 35.2](#version-352) * [Version 35.1](#version-351) * [Version 35.0](#version-350) @@ -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. @@ -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. diff --git a/_remote/rfcs/text/0005-application-formalization.md b/_remote/rfcs/text/0005-application-formalization.md new file mode 100644 index 00000000..72059c2f --- /dev/null +++ b/_remote/rfcs/text/0005-application-formalization.md @@ -0,0 +1,201 @@ +--- +layout: null +--- + +* Start Date: 10/09/2023 +* Contributors: + * [Craig McNally](cmcnally@ebsco.com) + * [Vince Bareau](vbareau@ebsco.com) +* 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? diff --git a/_remote/stripes-testing/README.md b/_remote/stripes-testing/README.md index 673380d3..4b0d5a47 100644 --- a/_remote/stripes-testing/README.md +++ b/_remote/stripes-testing/README.md @@ -4,7 +4,7 @@ layout: null # stripes-testing -Copyright (C) 2017-2020 The Open Library Foundation +Copyright (C) 2017-2024 The Open Library Foundation This software is distributed under the terms of the Apache License, Version 2.0. See the file "[LICENSE](LICENSE)" for more information. @@ -12,74 +12,30 @@ Version 2.0. See the file "[LICENSE](LICENSE)" for more information. ## Introduction 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 [BigTest](https://github.com/folio-org/stripes/blob/master/doc/bigtest.md) -toolkit instead. +UI modules and platforms. This repository contains: + +* `accessibility`: axe helper functions +* `bigtest`: BigTest helper furnctions, compatible with React >= 17 +* `cypress`: end-to-end tests +* `interactors`: interactors provide "hooks" into components as rendered in the DOM, + allowing tests written in BigTest, Cypress, etc. to use the interactor's consistent + API regardless of how the component implementation changes. -- [TL;DR](#tldr-i-just-want-to-run-some-tests) - [Stripes Component Interactors](doc/interactors.md) - [Prerequisites](#prerequisites) -- [Choose the source of UI module tests to run](#choose-the-source-of-ui-module-tests-to-run) -- [Writing tests](#writing-tests) - -## TL;DR I just want to run some tests -To run the tests for a platform, clone the platform and checkout its `snapshot` -branch, install its dependencies with `yarn`, then run the tests. For example, -for platform-core: +## Running -``` -git clone git@github.com:folio-org/platform-core.git -cd platform-core -git checkout snapshot -yarn -yarn prepare -yarn test-int -``` - -This will start stripes at http://localhost:3000, run the platform's tests, and -quit stripes. +First, install dependencies with npm or yarn. +* To run all Cypress tests at the CLI, run `npx cypress run`. +* To run a specific Cypress test at the CLI, run `npx cypress run --spec ./path/to/spec.cy.js` +* To open the Cypress test-runner in a browser, run `npx cypress open`. ## Prerequisites - [Node.js](https://nodejs.org/) with an [active LTS version](https://github.com/nodejs/Release#release-schedule) - [Yarn](https://yarnpkg.com/) JavaScript package manager -## Choose the source of UI module tests to run - -When building the platform, there are three potential sources for an -application module and its tests: - -- FOLIO's continuous integration repository: `npm-folioci` at repository.folio.org. - Modules in this repository reflect the head-of-master, i.e. code that has been - committed but is not yet part of an official release. This is appropriate for - regression tests and continuous integration. This would also suit developers - who are programming test suites or UI modules, and want to test very the latest - developments. - - This is the default source for `platform-core#snapshot`. - -- Folio's release repository: `npm-folio` at repository.folio.org. - Modules in this repository reflect officially released code. - - This is the default source for `platform-core#master`. - -- A local checkout of a module, brought into the platform by building it in - a [workspace](https://github.com/folio-org/stripes-cli/blob/master/doc/user-guide.md). - -Change a platform's source for its modules with the `npm config` command: - -``` -npm config set @folio:registry https://repository.folio.org/repository/npm-folio/ -``` - -## Writing Tests - -- Write [integration tests for a platform](doc/nightmare.md) with Nightmare -- Write [unit tests for an app](https://github.com/folio-org/stripes/blob/master/doc/bigtest.md) with BigTest - ## Additional information See project [UITEST](https://issues.folio.org/browse/UITEST)