1. Appendix A: Mock CICD Pipeline

We wanted to be able to test changes to this configuration or to the scripts used by the pipeline without risks to the real master branch, to our docker images or to the documentation. We didn’t find any such "dry-run" options on Travis CI so we decided to create a complete mock pipeline replicating the actual pipeline. This is a short summary of the necessary steps.

This document reflects the steps to create the pipeline on travis-ci.org and might not be completely accurate now that we’ve migrated to travis-ci.com.

1.1. GitHub

  1. Create organization opfab-mock

  2. Create user account opfabtechmock

  3. Invite opfabtechmock to opfab-mock organization as owner (see later if this can/should be restricted)

  4. Fork operatorfabric-core and opfab.github.io repos to opfab-mock organization

1.2. Travis CI

  1. Go to travis-ci.org (not travis-ci.com)

  2. Sign in with GitHub (using opfabtechmock) This redirects to a page offering to grant access to your account to Travis CI for Open Source, click ok.

    Note: This page (github.com/settings/applications) lets you review the apps that have keen granted this kind of access and when it was last used.

  3. Looking at travis-ci.org/account/repositories, the opfab-mock organization didn’t appear even after syncing the account, so click on "review and add your authorized organizations" (this redirects to github.com/settings/connections/applications/f244293c729d5066cf27).

  4. Click "grant" next to the organization.

  5. After that, Travis CI for Open Source is visible here: github.com/organizations/opfab-mock/settings/oauth_application_policy.

    This allowed the opfab-mock organization to appear in the account: travis-ci.org/account/repositories Click on opfab-mock to get to the list of repositories for this organization and toggle "operatorfabric-core" on.

  6. Under the Travis settings for the operatorfabric-core repository, create a Cron Job on branch develop, that runs daily and is always run.

1.3. SonarCloud

  1. Go to SonarCloud.io

  2. Sign in with GitHub

    When switching between accounts (your own and the technical account for example), make sure to log out of SonarCloud when you’re done using an account because otherwise it will keep the existing session (even in a new tab) rather than sign you back in with the account you’re currently using on GitHub.
  3. Authorize SonarCloud by sonarcloud + Create a new organization from the "+" dropdown menu to the left of your profile picture

    Click on "Just testing? You can create manually" on the bottom right, and not "Choose an organization on GitHub".

    This is because the "opfab" SonarCloud organization that we are trying to replicate is not currently linked to its GitHub counterpart (maybe the option didn’t exist at the time), so we’re doing the same here. In the future it might be a good idea to link them (see OC-751)as SonarCloud states that

Binding an organization from SonarCloud with GitHub is an easy way to keep them synchronized. To bind this organization to GitHub, the SonarCloud application will be installed.

And then it warns again that

Manual setup is not recommended, and leads to missing features like appropriate setup of your project or analysis feedback in the Pull Request.

  1. Click "Analyze new project" then "Create manually" (for the same reasons as the organization).

    Project key and display name : org.lfenergy.operatorfabric:operatorfabric-core-mock Then choose "Public" and click "Set Up".

  2. This redirects to the the following message : We initialized your project on SonarCloud, now it’s up to you to launch analyses!

  3. Now we need to make Sonar aware of our different branch types and of the fact that we have develop and not master as our default branch on GitHub. Under branches/administration:

    • Change the "long living branches pattern" to (master|develop)

    • Delete the develop branch if one had been created

    • Rename the main branch from master to develop

  4. Now we need to provide Travis with a token to use to access SonarCloud. To generate a token, go to Account/Security

    There are two options to pass this token to Travis:

    1. Option A: Define a new SONAR_TOKEN environment variable in the repository’s settings in Travis, then use it in the .travis.yml file as follows:

      addons:
        sonarcloud:
          organization: "opfab-mock"
          token:
               secure: ${SONAR_TOKEN}
    2. Option B: Encrypt this token using the travis gem:

      travis encrypt XXXXXXXXXXXXXXXXXXXXXXXXXXXX
      This has to be run at the root of the repository otherwise you get the following error: Can’t figure out GitHub repo name. Ensure you’re in the repo directory, or specify the repo name via the -r option (e.g. travis <command> -r <owner>/<repo>)
      Do not use the --add option (to add the encrypted value directly to the .travis.yml file) as it changes a lot of things in the file (remove comments, change indentation and quotes, etc.).

      Paste the result (YYYY) in the .travis.yml file:

      addons:
        sonarcloud:
          organization: "opfab-mock"
          token:
               secure: "YYYY"

      Option A would be better as it’s not necessary to make a new commit if the token needs to be changed, but it stopped working suddenly, maybe as a result of a travis policy change regarding encryption. OC-752 was created to investigate.

There is still a SONAR_TOKEN environment variable defined in the Travis settings (with a dummy value) because there is a test on its presence to decide whether sonar-scanner should be launched or not (in the case of external PRs) (see OC-700 / OC-507).
  1. Finally change the organization in .travis.yml file and the project key in sonar-project.properties (replace the actual values with mock values).

In travis.yml we launch the sonar-scanner command whereas the tutorials mention gradle sonarqube. It looks like we’re following this which says that "The SonarScanner is the scanner to use when there is no specific scanner for your build system." But there is a specific scanner for Gradle:

The SonarScanner for Gradle provides an easy way to start SonarCloud analysis of a Gradle project. The ability to execute the SonarCloud analysis via a regular Gradle task makes it available anywhere Gradle is available (CI service, etc.), without the need to manually download, setup, and maintain a SonarScanner installation. The Gradle build already has much of the information needed for SonarCloud to successfully analyze a project. By configuring the analysis based on that information, the need for manual configuration is reduced significantly.

→ This could make sonar easier to run locally and reduce the need for configuration (see OC-754).

1.4. GitHub (documentation)

  1. Create a personal access token for GitHub (for the documentation). Its name is not important.

    perso access token doc
  2. Create a GH_DOC_TOKEN env variable in Travis settings for the operatorfabric-core repository , making it available to all branches.

    adding gh doc token travis

1.5. DockerHub

  1. Create account opfabtechmock

  2. Create organization lfeoperatorfabricmock

  3. Change organization name in docker config in services.gradle

    docker {
        name "lfeoperatorfabricmock/of-${project.name.toLowerCase()}"
        tags 'latest', dockerVersionTag
        labels (['project':"${project.group}"])
        files( jar.archivePath
            , 'src/main/resources/bootstrap-docker.yml'
            , '../../../src/main/docker/java-config-docker-entrypoint.sh')
        buildArgs(['JAR_FILE'       : "${jar.archiveName}",
                   'http_proxy'     : apk.proxy.uri,
                   'https_proxy'    : apk.proxy.uri,
                   'HTTP_PROXY_AUTH': "basic:*:$apk.proxy.user:$apk.proxy.password"])
        dockerfile file("src/main/docker/Dockerfile")
    }
  4. Add the opfabtechmock dockerhub account credentials as DOCKER_CLOUD_USER / DOCKER_CLOUD_PWD in Travis env variables in settings (see GH_DOC_TOKEN above).

1.6. Updating the fork

To make the mock repositories catch up with the upstream (the real repositories) from time to time, follow this procedure (the command line version), except you should do a rebase instead of a merge: rick.cogley.info/post/update-your-forked-repository-directly-on-github/

2. Appendix B: Publication of the client library jars to Maven Central

This is a summary of the steps that were necessary to initially set up the publication of jars to Maven Central. The process to actually publish the jars for each release is detailed in the release process documentation.

Publication process overview
  1. Building and signing the jars

  2. Publishing them to a staging repository where there are validations (e.g. check that the POM contains the required information, validating the signature against the public key)

  3. If the validations pass, release the jar to Maven Central

2.1. Claiming the org.opfab namespace on Maven Central

This is done by logging an issue on the Sonatype JIRA (create an account first). The namespace needs to match a domain that you own (and this will be verified), which is why we had to rename our packages to org.opfab.XXX.

You can then request other users to be granted rights on the namespace as well.

2.2. Creating a GPG key pair

The key pair is generated with GPG2, keeping the default options and using the opfabtech technical account email as contact. The key is further secured with a passphrase.

gpg2 --full-generate-key

gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 3072
Requested keysize is 3072 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 18m
Key expires at Tue 11 Oct 2022 12:38:13 CEST
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: opfabtech
E-mail address: opfabtech@gmail.com
Comment: technical account for the OperatorFabric project
You selected this USER-ID:
    "opfabtech (technical account for the OperatorFabric project) <opfabtech@gmail.com>"

Change (N)ame, (C)omment, (E)-mail or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilise the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 469E7252B8D25328 marked as ultimately trusted
gpg: directory '/home/guironnetale/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/guironnetale/.gnupg/openpgp-revocs.d/FE0D7AFF9C129CFBBDC18A0B469E7252B8D25328.rev'
public and secret key created and signed.

pub   rsa3072 2021-04-19 [SC] [expires: 2022-10-11]
      FE0D7AFF9C129CFBBDC18A0B469E7252B8D25328
uid                      opfabtech (technical account for the OperatorFabric project) <opfabtech@gmail.com>
sub   rsa3072 2021-04-19 [E] [expires: 2022-10-11]
A standard practice is to have the key expire in 18 months, so I set up a calendar reminder for us to renew it.

2.3. Sharing the signing key

For other developers to be able to sign jars, you need to share both the key pair and the passphrase.

  • Export the key pair to a file

gpg2 --export-secret-keys OPFAB_KEY_ID > key_pair.key

2.4. Publishing the public key

The public key needs to be published to (preferably several) key directories so people wanting to use the signed jars can check the signature against the public key. It is also checked as part of the validations performed on the staging repository.

Our public key was initially published to pool.sks-keyservers.net, which became deprecated (causing the publication to fail), so it was then published to the two servers that the sonatype validations seem to rely on.

For OpenPGP you need to export the public key (and not the key pair) to a file and upload it to their web interface.

gpg2 --export OPFAB_KEY_ID > my_key.pub

For Ubuntu you need to export the public key as ascii-armored ascii and paste the result to their web interface

gpg2 --export --armor OPFAB_KEY_ID
The key can be retrieved from both these servers by searching either for opfabtech@gmail.com or for the key ID.

2.5. Setting up the signing and publication in Gradle

You can’t publish a jar with version "SNAPSHOT" to the Maven staging repositories (you would get a 403 BAD REQUEST), that’s why the Gradle publication task is configured so that if the version ends with "SNAPSHOT", the jars should be published to a local directory (repos/snapshots) rather than to the Maven Central staging repository.

3. Migration Guide from release 1.4.0 to release 1.5.0

3.1. Refactoring of configuration management

3.1.1. Motivation for the change

The initial situation was to have a Third concept that was meant to represent third-party applications that publish content (cards) to OperatorFabric. As such, a Businessconfig was both the sender of the message and the unit of configuration for resources for card rendering.

Because of that mix of concerns, naming was not consistent across the different services in the backend and frontend as this object could be referred to using the following terms: * Third * ThirdParty * Bundle * Publisher

But now that we’re aiming for cards to be sent by entities, users (see Free Message feature) or external services, it doesn’t make sense to tie the rendering of the card ("Which configuration bundle should I take the templates and details from?") to its publisher ("Who/What emitted this card and who/where should I reply?").

3.1.2. Changes to the model

To do this, we decided that the publisher of a card would now have the sole meaning of emitter, and that the link to the configuration bundle to use to render a card would now be based on its process field.

3.1.2.1. On the Businessconfig model

We used to have a Businessconfig object which had an array of Process objects as one of its properties. Now, the Process object replaces the Businessconfig object and this new object combines the properties of the old Businessconfig and Process objects (menuEntries, states, etc.).

In particular, this means that while in the past one bundle could "contain" several processes, now there can be only one process by bundle.

The Businessconfig object used to have a name property that was actually its unique identifier (used to retrieve it through the API for example). It also had a i18nLabelKey property that was meant to be the i18n key to determine the display name of the corresponding businessconfig, but so far it was only used to determine the display name of the associated menu in the navbar in case there where several menu entries associated with this businessconfig.

Below is a summary of the changes to the config.json file that all this entails:

Field before Field after Usage

name

id

Unique identifier of the bundle. Used to match the publisher field in associated cards, should now match process

name

I18n key for process display name.

states.mystate.name

I18n key for state display name.

i18nLabelKey

menuLabel

I18n key for menu display name in case there are several menu entries attached to the process

processes array is a root property, states array being a property of a given process

states array is a root property

Here is an example of a simple config.json file:

Before
{
  "name": "TEST",
  "version": "1",
  "defaultLocale": "fr",
  "menuEntries": [
    {"id": "uid test 0","url": "https://opfab.github.io/","label": "menu.first"},
    {"id": "uid test 1","url": "https://www.la-rache.com","label": "menu.second"}
  ],
  "i18nLabelKey": "businessconfig.label",
  "processes": {
    "process": {
      "states": {
        "firstState": {
          "details": [
            {
              "title": {
                "key": "template.title"
              },
              "templateName": "operation"
            }
          ]
        }
      }
    }
  }
}
After
{
  "id": "TEST",
  "version": "1",
  "name": "process.label",
  "defaultLocale": "fr",
  "menuLabel": "menu.label",
  "menuEntries": [
    {"id": "uid test 0","url": "https://opfab.github.io/","label": "menu.first"},
    {"id": "uid test 1","url": "https://www.la-rache.com","label": "menu.second"}
  ],
  "states": {
    "firstState": {
      "name" :"mystate.label",
      "details": [
        {
          "title": {
            "key": "template.title"
          },
          "templateName": "operation"
        }
      ]
    }
  }
}
You should also make sure that the new i18n label keys that you introduce match what is defined in the i18n folder of the bundle.
3.1.2.2. On the Cards model
Field before Field after Usage

publisherVersion

processVersion

Identifies the version of the bundle. It was renamed for consistency now that bundles are linked to processes not publishers

process

process

This field is now required and should match the id field of the process (bundle) to use to render the card.

processId

processInstanceId

This field is just renamed , it represent an id of an instance of the process

These changes impact both current cards from the feed and archived cards.

The id of the card is now build as process.processInstanceId an not anymore publisherID_process.

3.2. Change on the web-ui.json

The parameter navbar.thirdmenus.type has been removed from this file. Starting from this release the related functionality has been moved on bundle basis and it’s not more global. See "Changes on bundle config.json" for more information.

3.3. Changes on bundle config.json

Under menuEntries a new subproperty has been added: linkType. This property replace the old property navbar.thirdmenus.type in web-ui.json, making possible a more fine control of the related behaviour.

3.4. Component name

We also change the component name of third which is now named businessconfig.

3.5. Changes to the endpoints

The /third endpoint becomes /businessconfig/processes.

3.6. Migration steps

This section outlines the necessary steps to migrate existing data.

You need to perform these steps before starting up the OperatorFabric instance because starting up services with the new version while there are still "old" bundles in the businessconfig storage will cause the businessconfig service to crash.
  1. Backup your existing bundles and existing Mongo data.

  2. Edit your bundles as detailed above. In particular, if you had bundles containing several processes, you will need to split them into several bundles. The id of the bundles should match the process field in the corresponding cards.

  3. If you use navbar.thirdmenus.type in web-ui.json, rename it to navbar.businessmenus.type

  4. Run the following scripts in the mongo shell to copy the value of publisherVersion to a new processVersion field and to copy the value of processId to a new processInstanceId field for all cards (current and archived):

    Current cards
    db.cards.updateMany(
    {},
    { $rename: { "publisherVersion": "processVersion", "processId": "processInstanceId" } }
    )
    Archived cards
    db.archivedCards.updateMany(
    {},
    { $rename: { "publisherVersion": "processVersion", "processId": "processInstanceId" } }
    )
  5. Make sure you have no cards without process using the following mongo shell commands:

    db.cards.find({ process: null})
    db.archivedCards.find({ process: null})
  6. If it turns out to be the case, you will need to set a process value for all these cards to finish the migration. You can do it either manually through Compass or using a mongo shell command. For example, to set the process to "SOME_PROCESS" for all cards with an empty process, use:

    db.cards.updateMany(
    { process: null },
    {
    $set: { "process": "SOME_PROCESS"}
    }
    )
    db.archivedCards.updateMany(
    { process: null },
    {
    $set: { "process": "SOME_PROCESS"}
    }
    )
  7. If you have any code or scripts that push bundles, you should update it to point to the new endpoint.

4. Migration Guide from release 1.7.0 to release 1.8.0

4.1. Card detail definition in business configuration

There is no more the need for multiple definitions of card’s detail rendering because of the removal of multi-tab rendering. The rendering of the detail of a card is configured specifying the detail title, template name and the list of styles.

In the Businessconfig model definition the field details has been removed.

The new fields detailTitle, templateName and styles have been added.

Here is an example of a simple config.json file:

Before
{
  "id": "TEST",
  "version": "1",
  "name": "process.label",
  "states": {
    "firstState": {
      "name" :"mystate.label",
      "details": [
        {
          "title": {
            "key": "template.title"
          },
          "templateName": "operation",
          "styles": ["style1","style2"]
        }
      ]
    }
  }
}
After
{
  "id": "TEST",
  "version": "1",
  "name": "process.label",
  "states": {
    "firstState": {
      "name" :"mystate.label",
      "detailTitle": {
        "key": "template.title"
        },
      "templateName": "operation",
      "styles": ["style1","style2"]
    }
  }
}

4.2. Business menu definition

The business menu are not configured anymore in the business definition but in a specific single configuration file called ui-menu.json. You must move your configuration from the config.json to this new file, see documentation .

5. Migration Guide from release 1.8.0 to release 2.0.0

5.1. AcknowledgmentAllowed field in business configuration

In the process state definition the acknowledgementAllowed has been renamed to acknowledgmentAllowed. The acknowledgmentAllowed field in no more a boolean type and can now assume one of the following values:

  • "Never": acknowledgment not allowed (default value)

  • "Always": acknowledgment allowed

  • "OnlyWhenResponseDisabledForUser": acknowledgment allowed only when the response is disabled for the user

Here is an example of a simple config.json file:

{
  "id": "TEST",
  "version": "1",
  "name": "process.label",
  "states": {
    "firstState": {
      "name" :"mystate.label",
      "details": [
        {
          "title": {
            "key": "template.title"
          },
          "templateName": "operation",
          "styles": ["style1","style2"]
        }
      ],
      "acknowledgmentAllowed": "Never"
    }
  }
}

5.2. Response card : templateGateway.applyChild()

For card with responses, it is not necessary to call templateGateway.applyChildCards() in your template on loading anymore, OperatorFabric will do it.

6. Migration Guide from release 2.2.0 to release 2.3.0

6.1. Communication between template and opfab

6.1.1. Getting response data from template

Some renaming has been done in version 2.3.0 :

  • the method to have the response information from template is rename in getUserResponse instead of validyForm.

  • the return object of this method shall now contains the response data in field responseCardData instead of formData

So if you have the following code in your template :

    templateGateway.validyForm = function () {
        const response = document.getElementById('response').value;
        const formData = { response: response };
        return {
            valid: true,
            formData: formData
        };
    }

It must be modify this way :

    templateGateway.getUserResponse = function () {
        const response = document.getElementById('response').value;
        const responseCardData = { response: response };
        return {
            valid: true,
            responseCardData: responseCardData
        };

    }

6.1.2. Getting the information if the user can respond

To know from a template that the user can respond to a card you must now call templateGateway.isUserAllowedToRespond() instead of implementing the method templateGateway.setUserCanRespond()

So if you have the following code in your template :

    templateGateway.setUserCanRespond = function(responseEnabled) {
        if (responseEnabled) {
            // do something
        } else {
            // do something
        }
    }

It must be modify this way :

    if (templateGateway.isUserAllowedToRespond()) {
         // do something
    } else {
        // do something
    }

7. Migration Guide from release 2.3.0 to release 2.4.0

7.1. Send card

The API does not provide an endpoint to send an array of cards anymore.

  • The endpoint cards now accepts only one card

  • The endpoint async/cards no longer exists

So if you used to send several cards as array, you need to modify your code to send hem one by one via endpoint cards.

7.2. Package name change

The name of the packages in the OperatorFabric code has been changed from org.lfenergy.operatorfabric. to org.opfab. in preparation for an upload of the client library to Maven Central. You need to update any code using the client library to reflect this name change.

8. Migration Guide from release 2.4.0 to release 2.5.0

8.1. Send card

The API endpoint to send a card doesn’t return CardCreationReport object anymore. The endPoint cards now returns :

  • status code 201 (Created) in case of success.

  • status code 400 (Bad request) in case of a request with wrong data.

So if you use CardCreationReport object when you send card, you need to modify your code to not use it anymore and to test the status code returned.

8.2. Card recipients

The deprecated card field recipient is now deleted. So you have to use the fields userRecipients, groupRecipients and entityRecipients to send a card.

9. Migration Guide from release 2.5.0 to release 2.6.0

9.1. Inter-service communication - Ribbon

Ribbon was used by our Feign client that lets business services get information on the current user from the Users service.

Ribbon is no longer maintained, so we chose to remove it from our dependencies (mostly because it was blocking any update of the other Spring dependencies).

Instead, the Feign client now relies on an external property to know where the Users service can be reached, and there is no load-balancing for now.

This requires a change to service configuration: the users.ribbon.listOfServers property should be removed and replaced with operatorfabric.servicesUrls.users.

It should be set in the configuration of all business services (except users), or in the common configuration.

Example
operatorfabric:
  servicesUrls:
    users: "http://localhost:2103"

According to the Feign documentation, the property should contain "an absolute URL or resolvable hostname (the protocol is optional)".

This property is mandatory, if it is absent the application won’t start.
While the ribbon property could handle an array of several urls, this new property expects a single url as there is no load-balancing mechanism for now.

10. Migration Guide from release 2.6.0 to release 2.7.0

10.1. Send card

The API endPoint cards will now require authentication by default. It is possible to configure the endpoint to not require authentication by setting the configuration parameter checkAuthenticationForCardSending to false in cards-publication service configuration file.

11. Migration Guide from release 2.7.0 to release 2.8.0

11.1. UI Configuration Management

The web-ui container has two configuration files: web-ui.json and ui-menu.json.

To avoid maintaining separate copies of these files for each run environment (docker, dev, Cypress), the reference configuration will be the one for the docker mode, with the others being created by script, changing only the properties that should be different between environments (e.g. environmentName). Only the docker configuration will be version-controlled. The scripts creating the configuration are launched by the docker-compose.sh and docker-compose-cypress.sh.

As a consequence, the web-ui.json and ui-menu.json files have been moved from config/xxx/ to config/xxx/ui-config. The volumes in the docker-compose.yml files have been updated accordingly.

This new organization will also allow us to run Cypress tests against different versions of the configuration, for example to test the behaviour of a property meant to hide a component. See the Cypress tests README (src/test/cypress/README.adoc) for more information.

All modes (dev, docker, config) now use the PASSWORD authentication flow by default. If you want to test with another authentication flow, you should use the setSecurityAuthFlow.sh script AFTER the containers have been started.
Example to use the CODE flow in dev mode
cd src/test/resources
.setSecurityAuthFlow.sh dev CODE

11.2. Management of visible menus

The visibility of some core OperatorFabric menus (monitoring, logging, feed configuration screen,…​) was so far configurable for a given OperatorFabric instance through various properties in web-ui.json.

As of this version, it has been unified with that of custom menus:

  • It will now be managed in ui-menu.json along with custom menus

  • It is now possible to make these menus visible only for certain groups

The following properties in web-ui.json are no longer supported and should be removed
  • navbar.hidden (array of menus to hide)

  • admin.hidden (boolean)

  • feedConfiguration.hidden (boolean)

  • realTimeUsers.hidden (boolean)

  • settings.nightDayMode (boolean)

New property in ui-menu.json
{
  "coreMenusConfiguration":
  [
    {
      "id": "coreMenuId1",
      "visible": true
    },
    {
      "id": "coreMenuId2",
      "visible": false
    },
    {
      "id": "coreMenuId3",
      "visible": true,
      "showOnlyForGroups": ["ADMIN","SOME_OTHER_GROUP"]
    }
  ]
}

All core menus should be listed under this new coreMenusConfiguration property in ui-menu.json, each with their own visible and (optionally) showOnlyForGroups property.

Necessary actions for the migration:

  • Remove the deprecated properties listed above from your web-ui.json

  • Add a coreMenusConfiguration block to your ui-menu.json (see the documentation for details and a full example)

11.3. Simplification MongoDB Configuration

We are getting rid of our specific MongoDB configuration to let SpringBoot autoconfigure it. As a result, we are removing support for the spring.data.mongodb.uris property in favour of the standard spring.data.mongodb.uri property. Please change the application configuration files for the services accordingly.

This property can only hold a single URI.