1. 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.
-
Building and signing the jars
-
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)
-
If the validations pass, release the jar to Maven Central
1.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.
1.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. |
1.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
-
Send the file to the other developers via a secure channel
-
Then, they need to import this file to their keyring (see the documentation for the publishing task for details).
1.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.
|
1.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.
|
2. Migration Guide from release 1.4.0 to release 1.5.0
2.1. Refactoring of configuration management
2.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?").
2.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.
2.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 |
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:
{
"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"
}
]
}
}
}
}
}
{
"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. |
2.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. |
2.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.
2.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.
2.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. |
-
Backup your existing bundles and existing Mongo data.
-
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 theprocess
field in the corresponding cards. -
If you use navbar.thirdmenus.type in web-ui.json, rename it to navbar.businessmenus.type
-
Run the following scripts in the mongo shell to copy the value of
publisherVersion
to a newprocessVersion
field and to copy the value ofprocessId
to a newprocessInstanceId
field for all cards (current and archived):Current cardsdb.cards.updateMany( {}, { $rename: { "publisherVersion": "processVersion", "processId": "processInstanceId" } } )
Archived cardsdb.archivedCards.updateMany( {}, { $rename: { "publisherVersion": "processVersion", "processId": "processInstanceId" } } )
-
Make sure you have no cards without process using the following mongo shell commands:
db.cards.find({ process: null})
db.archivedCards.find({ process: null})
-
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"} } )
-
If you have any code or scripts that push bundles, you should update it to point to the new endpoint.
3. Migration Guide from release 1.7.0 to release 1.8.0
3.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:
{
"id": "TEST",
"version": "1",
"name": "process.label",
"states": {
"firstState": {
"name" :"mystate.label",
"details": [
{
"title": {
"key": "template.title"
},
"templateName": "operation",
"styles": ["style1","style2"]
}
]
}
}
}
{
"id": "TEST",
"version": "1",
"name": "process.label",
"states": {
"firstState": {
"name" :"mystate.label",
"detailTitle": {
"key": "template.title"
},
"templateName": "operation",
"styles": ["style1","style2"]
}
}
}
3.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 .
4. Migration Guide from release 1.8.0 to release 2.0.0
4.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. Migration Guide from release 2.2.0 to release 2.3.0
5.1. Communication between template and opfab
5.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
};
}
5.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
}
6. Migration Guide from release 2.3.0 to release 2.4.0
7. Migration Guide from release 2.4.0 to release 2.5.0
7.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. Migration Guide from release 2.5.0 to release 2.6.0
8.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.
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.7.0 to release 2.8.0
10.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.
|
cd src/test/resources
.setSecurityAuthFlow.sh dev CODE
10.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
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)
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 yourui-menu.json
(see the documentation for details and a full example)
10.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. |
11. Migration Guide from release 2.10.0 to release 2.11.0
11.1. Logging screen : Filter with tags list
As for archives screen, now you have to specify the list of tags you want to see in the filter of logging screen.
You have to set this list in the web-ui.json
file, with the parameter logging.filters.tags.list
. For example :
"logging": {
"filters": {
"tags": {
"list": [
{
"label": "Label for tag 1",
"value": "tag1"
}
]
}
}
}
12. Migration Guide from release 2.11.0 to release 3.0.0
12.1. Changes in configuration due to business translation mechanism removal
In order to remove unnecessary complexity for third-party, we have decided to remove translation for some of business data, this implies the following migration tasks :
12.1.1. Template directory
The template
directory does not contain language repository anymore. There is one template per process/state
and the templates are located directly in this directory. So you have to move your template for your language directly to the template directory
12.1.2. Changes in config.json
In config.json, the fields process.name
, state.name
and state.description
must not contain i18n data anymore, they must only contain string data. These data will be simply displayed on the screen.
12.1.3. New file i18n.json
The bundle shall contain a new i18n.json file in the root directory. The i18n.json file contains internationalization information for title and summary fields. We keep an i18n mechanism for these two fields in order to have the possibility to adapt the title or summary of the card without having to modify the code of the third party tool sending the card (using only one "language" for translation)
Here is an example file :
{ "message":{ "title":"Message", "summary":"Message received" }, "chartDetail" : { "title":"A Chart"}, "chartLine" : { "title":"Electricity consumption forecast"}, "question" : {"title": "⚡ Planned Outage"}, "contingencies": {"title" : "⚠️ Network Contingencies ⚠️","summary":"Contingencies report for French network"}, "processState": { "title":"Process state ({{status}})" } }
12.1.5. Processes groups
There is no possibility anymore to have translation for the process group name. You can just define the name of the group in the uploaded file. Here is an example of this file :
{
"groups": [
{
"id": "processgroup1",
"name": "Process Group 1",
"processes": [
"process1",
"process2"
]
},
{
"id": "processgroup2",
"name": "Process Group 2",
"processes": [
"process3",
"process4"
]
}
]
}
12.1.6. Script to migrate an existing database
Opfab 3.0 needs two new fields in database : titleTranslated
and summaryTranslated
.
In order to add these two new fields to an existing database, you have to pull the image migration-opfab3
,
go to the directory OF_HOME/src/tooling/migration-opfab3
and execute the script docker-compose.sh
, this way :
./docker-compose.sh <containerNameMongoDB> <portMongoDB> <loginMongoDB> <passwordMongoDB> <pathToBundlesDirectory>
The bundles directory is the directory where you store all the "untar" bundles in the new
format with the i18n.json file. It is not the directory where the opfab instance stores the bundles.
|
12.2. Configuration file web-ui.json
Some attributes have been renamed to be more consistent with their meaning. Here are these attributes :
-
settings.infos.description
renamedsettings.infos.hide.description
-
settings.infos.language
renamedsettings.infos.hide.language
-
settings.infos.timezone
renamedsettings.infos.hide.timezone
-
settings.infos.tags
renamedsettings.infos.hide.tags
-
settings.infos.sounds
renamedsettings.infos.hide.sounds
So if you use these fields in web-ui.json
file, you have to rename them.
12.3. Configuration file common-docker.yml
A new parameter named operatorfabric.servicesUrls.businessconfig
has to be added to your configuration file common-docker.yml
(or equivalent)
For example the following configuration:
operatorfabric:
businessLogActivated: true
servicesUrls:
users: "users:8080"
becomes:
operatorfabric:
businessLogActivated: true
servicesUrls:
users: "users:8080"
businessconfig: "businessconfig:8080"
13. Migration Guide from release 3.0.0 to release 3.1.0
13.1. Kafka date format
The signature for sending card dates via Kafka have been changed to better reflect the REST API. Instead of sending the date in seconds since epoch, you can now use the Java Instant object. The following methods are affected:
-
startDate
-
endDate
-
lttd
-
publishDate
-
TimeSpan.setStart
-
TimeSpan.setEnd
For example the following code:
Card card = Card.newBuilder().setStartDate(12345L).build();
becomes:
Card card = Card.newBuilder().setStartDate(Instant.now()).build();
14. Migration Guide from release 3.1.0 to release 3.2.0
14.1. Cache configuration for i18n files
Add the following lines in your nginx.conf to avoid keeping in cache old translation files when migrating opfab
location /ui/assets/i18n/ {
add_header Cache-Control "no-cache";
alias /usr/share/nginx/html/assets/i18n/;
}
see the reference nginx configuration file : github.com/opfab/operatorfabric-core/blob/master/config/docker/nginx.conf
15. Migration Guide from release 3.4.0 to release 3.5.0
15.1. Timezone management removal
The feature to manage timeline inside opfab has been removed. In consequence, you can remove the following parameters in your web-ui.json configuration file:
-
i10n.supported.time-zones
-
settings.infos.hide.timezone
15.2. Kafka card format changes
The Kafka message schema has been changed. The single card used to send messages to and receive from Operator Fabric
has been split into two cards; one for sending to OpFab and one for receiving messages from OpFab. The CardCommand structure now contains a card
(to OpFab) and a responseCard
(from OpFab).
You will need to change the Kafka listener to get the response card.
For example change
@KafkaListener
public void receivedResponseCard(@Payload ConsumerRecord<String, CardCommand> consumerRecord) {
CardCommand cardCommand = consumerRecord.value();
Card = cardCommand.getCard();
to
@KafkaListener
public void receivedResponseCard(@Payload ConsumerRecord<String, CardCommand> consumerRecord) {
CardCommand cardCommand = consumerRecord.value();
ResponseCard = cardCommand.getResponseCard();
15.2.1. Redirect to business application from a card
The templateGateway.redirectToBusinessMenu
function to redirect to business application from a card has changed. The third argument of the function is now a url extension that can contain sub paths and/or parameters instead of only parameters.
You will need to change the call adding a '?' character at the beginning of the third argument.
For example change:
templateGateway.redirectToBusinessMenu('myMenu','myEntry','param1=aParam¶m2=anotherParam')
to
templateGateway.redirectToBusinessMenu('myMenu','myEntry','?param1=aParam¶m2=anotherParam')
16. Migration Guide from release 3.5.0 to release 3.6.0
16.1. Template rendering
Bootstrap library has been migrate to v5.
If you use bootstrap css classes in your templates, it’s strongly recommended checking your template rendering after migration. |
Charts library has been upgraded from version 3.2.1 to 3.7.1
If you use charts in your templates, it’s strongly recommended checking your template rendering after migration. |
16.2. Mongo data migration steps
This section outlines the necessary steps to migrate existing data.
If you use response card feature, you need to perform these steps before starting up the OperatorFabric instance to avoid displaying wrong data in archives page. |
-
Backup your existing Mongo data.
-
Run the following scripts in the mongo shell to update the value of the new field
deletionDate
for archived cards:db.archivedCards.updateMany( {"deletionDate": {"$exists": false}}, {"$set": {"deletionDate": new ISODate("1970-01-01T00:00:00Z")}} )
16.3. About screen
You do not need anymore to precise opfab version in web-ui.json to see it on about screen. So you need to remove the corresponding line. For example :
"operatorfabric": { "name": "OperatorFabric", "rank": 0, "version": "2.5.0.RELEASE" }
16.4. Deprecated feature
16.4.1. Method templateGateway.getSpecificCardInformation()
Implementation of method templateGateway.getSpecificCardInformation() in usercard templates is now deprecated, replace it by usercardTemplateGateway.getSpecificCardInformation(). It is just a naming change, the behavior is the same.
16.4.2. Restrict recipient dropdown list for user
Using "recipientList" in state definition (in config.json) is now deprecated
If you use "recipientList" to restrict the list of recipients shown to user, replace it with code in template as in the following example :
usercardTemplateGateway.setDropdownEntityRecipientList([ {"id": "ENTITY_FR", "levels": [0,1]}, {"id": "IT_SUPERVISOR_ENTITY"} ]);
16.4.3. Set the list of recipients
Using "recipientList" in state definition (in config.json) is now deprecated
If you use "recipientList" to set the list of recipients, provide now the list of recipients when returning the card object in usercardTemplateGateway.getSpecificCardInformation() in the field entityRecipients.
Example:
usercardTemplateGateway.getSpecificCardInformation = function () { const message = document.getElementById('message').value; const card = { summary : {key : "message.summary"}, title : {key : "message.title"}, entityRecipients: ["ENTITY_FR","IT_SUPERVISOR_ENTITY"], data : {message: message} }; if (message.length<1) return { valid:false , errorMsg:'You must provide a message'} return { valid: true, card: card };
17. Migration Guide from release 3.6.0 to release 3.7.0
17.1. Docker images names changed
From version 3.7.0 the docker names of the former "business services" are changed. Here are there old names and the new ones.
Old docker name | New docker name |
---|---|
lfeoperatorfabric/of-cards-consultation-business-service:3.6.0.RELEASE |
lfeoperatorfabric/of-cards-consultation-service:3.7.0.RELEASE |
lfeoperatorfabric/of-cards-publication-business-service:3.6.0.RELEASE |
lfeoperatorfabric/of-cards-publication-service:3.7.0.RELEASE |
lfeoperatorfabric/of-users-business-service:3.6.0.RELEASE |
lfeoperatorfabric/of-users-service:3.7.0.RELEASE |
lfeoperatorfabric/of-businessconfig-business-service:3.6.0.RELEASE |
lfeoperatorfabric/of-businessconfig-service:3.7.0.RELEASE |
You must change your docker-compose files accordingly.
17.2. Third parties configuration
The configuration of the third parties applications as external recipents has changed. It is now possible to configure wether the user token shall be propagated to the third party or not by setting the "propagateUserToken" boolean property.
If you have third parties configured in your 'cards-publication.yml' you should change the configuration as follows:
From:
externalRecipients-url: "{\ third-party1: \"http://thirdparty1/test1\", \ third-party2: \"http://thirdparty2:8090/test2\", \ }"
To
external-recipients: recipients: - id: "third-party1" url: "http://thirdparty1/test1" propagateUserToken: true - id: "third-party2" url: "http://thirdparty2:8090/test2" propagateUserToken: true
17.3. Rename attribute externalDeviceId
It is now possible to have several external device systems, therefore the attribute externalDeviceId is now renamed into externalDeviceIds and is now a list.
17.3.1. In the configuration file
In the configuration file, replace
userConfigurations: - userLogin: operator1_fr externalDeviceId: CDS_1 - userLogin: operator2_fr externalDeviceId: CDS_2 - userLogin: operator3_fr externalDeviceId: CDS_3 - userLogin: operator4_fr externalDeviceId: CDS_1
by
userConfigurations: - userLogin: operator1_fr externalDeviceIds: ["CDS_1"] - userLogin: operator2_fr externalDeviceIds: ["CDS_2"] - userLogin: operator3_fr externalDeviceIds: ["CDS_3"] - userLogin: operator4_fr externalDeviceIds: ["CDS_1"]
17.3.2. Changes in the Mongo data base
17.3.2.1. Before the migration
Before the migration to 3.7.0, one should save its current database, then add the attribute "externalDeviceIds" based on the value of the existing attribute "externalDeviceId". To add this attribute, simply launch the commands :
var collection = db.getCollection("userConfigurations") collection.find().forEach(function(user) {collection.updateOne({_id: user._id}, {$set: {externalDeviceIds: [user.externalDeviceId]}})})
17.3.2.2. Once the migration is done
Once the migration to 3.7.0 is done, the attribute "externalDeviceId" is not used anymore. You can remove it by launching :
var collection = db.getCollection("userConfigurations") collection.find().forEach(function(user) {collection.updateOne({_id: user._id}, {$unset: {"externalDeviceId": 1}})})
17.4. Deprecated feature
17.4.1. Field recurrence
Using "recurrence" field returned by getSpecificCardInformation() method definition is now deprecated.
If you are using the "viewCardInAgenda" and "recurrence" field, use the "timeSpans" field instead when returning the card object in usercardTemplateGateway.getSpecificCardInformation() to configure the visibility of the card in timeline and agenda.
Example:
usercardTemplateGateway.getSpecificCardInformation = function () { const message = document.getElementById('message').value; const card = { summary : {key : "message.summary"}, title : {key : "message.title"}, entityRecipients: ["ENTITY_FR","IT_SUPERVISOR_ENTITY"], data : {message: message} }; const recurrence = { daysOfWeek : [1,2,3], hoursAndMinutes : {hours:10,minutes:44}, durationInMinutes: 15 } const mystartDate = new Date(); const timeSpans = [{ startDate: mystartDate.getTime(), endDate: mystartDate.getTime() + 7 * 24 * 3600000, recurrence: recurrence }] return { valid: true, card: card, timeSpans: timeSpans };
19. Migration Guide from release 3.8.x to release 3.9.0
19.1. web-ui.json
config file
To declare settings parameters, you now need to group all fields under settings: { }
and you must not use a statement like this one : settings.replayInterval: 10
For example:
Replace the following invalid settings config
"settings.replayInterval": 10,
"settings.replayEnabled": true,
"settings": {
"about": {
"keycloak": {
"name": "Keycloak",
"rank": 2,
"version": "6.0.1"
},
}
"locale": "en",
"dateTimeFormat": "HH:mm DD/MM/YYYY",
"dateFormat": "DD/MM/YYYY",
"styleWhenNightDayModeDesactivated": "NIGHT"
},
By this valid one :
"settings": {
"replayInterval": 10,
"replayEnabled": true,
"about": {
"keycloak": {
"name": "Keycloak",
"rank": 2,
"version": "6.0.1"
},
}
"locale": "en",
"dateTimeFormat": "HH:mm DD/MM/YYYY",
"dateFormat": "DD/MM/YYYY",
"styleWhenNightDayModeDesactivated": "NIGHT"
},
20. Migration Guide from release 3.9.x to release 3.10.0
20.1. Card publication with not existent process or state
OperatorFabric will refuse the publication of cards referring a not existent process or state.
To allow the publication of cards with not existent process or state you should set the authorizeToSendCardWithInvalidProcessState
property to true
in cards-publication.yml
configuration file.
20.2. web-ui.json
config file
20.2.1. settings.about
section
The section to configure about
screen has been moved from settings
section to the root level. You need to change the configuration file accordingly.
For example:
Replace the following invalid config
"settings": {
"about": {
"keycloak": {
"name": "Keycloak",
"rank": 2,
"version": "6.0.1"
},
},
"replayInterval": 10,
"replayEnabled": true,
"locale": "en",
"dateTimeFormat": "HH:mm DD/MM/YYYY",
"dateFormat": "DD/MM/YYYY",
"styleWhenNightDayModeDesactivated": "NIGHT"
},
By this valid one :
"settings": {
"replayInterval": 10,
"replayEnabled": true,
"locale": "en",
"dateTimeFormat": "HH:mm DD/MM/YYYY",
"dateFormat": "DD/MM/YYYY",
"styleWhenNightDayModeDesactivated": "NIGHT"
},
"about": {
"keycloak": {
"name": "Keycloak",
"rank": 2,
"version": "6.0.1"
}
}
20.2.2. settings.infos.hide
section
The section to configure hidden fields for the settings screen has been moved from settings.infos.hide
section to
settingsScreen.hiddenSettings
. This new field is an array of string and possible values are : "description",
"language", "remoteLoggingEnabled" and "sounds". So, you need to change the configuration file accordingly.
For example:
Replace the following invalid config
"settings": {
"infos": {
"hide": {
"description": true
}
}
}
By this valid one :
"settingsScreen": {
"hiddenSettings": ["description"]
}
20.2.3. Feed filtering and sorting
In feed configuration the following parameters to hide filtering and sorting options have been removed: feed.card.hideAckFilter
, feed.card.hideReadSort
, feed.card.hideSeveritySort
Instead, it is possible to configure the default behaviour for sorting and acknowledgment filtering by setting the following parameters in web-ui.json
:
-
feed.defaultSorting
: possible values are : "unread", "date", "severity", "startDate", "endDate" -
feed.defaultAcknowledgmentFilter
: possible values are : "notack", "ack", "all"
21. Migration Guide from release 3.10.x to release 3.11.0
21.1. Card publication
OperatorFabric will now check user perimeter when publishing cards via endpoint /cards
(it does not concern user cards
which are always controlled). To disable perimeter validation it is possible to set the configuration parameter
checkPerimeterForCardSending
to false
in cards-publication service configuration file.
21.2. templateGateway onStyleChange()
method
A new onStyleChange()
method has been added to templateGateway.
OpFab will call this method when switching day/night mode.
It may have to be implemented by a template to refresh styles and reload embedded charts when user change day/night
mode, please check your existing templates.
21.3. Nginx configuration
Nginx configuration file has to be modified to allow the forwarding of query parameters to the new 'userActionLogs' API.
You have to modify nginx.conf
file as follows:
Replace
location ~ "^/users/(.*)" { proxy_set_header Host $http_host; proxy_pass http://users:8080/$1; proxy_set_header X-Forwarded-For $remote_addr; }
With
location ~ "^/users/(.*)" { proxy_set_header Host $http_host; proxy_pass http://users:8080/$1$is_args$args; proxy_set_header X-Forwarded-For $remote_addr; }
22. Migration Guide from release 3.11.x to release 3.12.0
22.1. Java 17
OperatorFabric now runs on java 17, which means that the client library is now compiled with java 17. If you are using the client library, you may need to upgrade your application to java 17 or use client 3.11.2 which is compatible with version 3.12.0 and compiled with java 11.
22.2. Expiration date
A new 'expirationDate' field has been added to the card. Cards with an expiration date will be automatically deleted from the card feed after the expiration date is passed.
The expiration date is by default visible in the usercard screen. You can hide the expiration date in the usercard screen by adding the new 'expirationDateVisible' value to your usercard configuration in the config.json of your bundle.
-
Hide expiration date → "expirationDateVisible" : false
"processState": { "name": "Process example ", "description": "Process state", "color": "#0070C0", "userCard" : { "template" : "usercard_process", "lttdVisible" : false, "expirationDateVisible" : false, "recipientList" : [{"id": "ENTITY_FR", "levels": [0,1]}, {"id": "IT_SUPERVISOR_ENTITY"}] },
-
Show expiration date → "expirationDateVisible" : false
"processState": { "name": "Process example ", "description": "Process state", "color": "#0070C0", "userCard" : { "template" : "usercard_process", "lttdVisible" : false, "expirationDateVisible" : true, "recipientList" : [{"id": "ENTITY_FR", "levels": [0,1]}, {"id": "IT_SUPERVISOR_ENTITY"}] },
23. Migration Guide from release 3.12.0 to release 3.13.0
23.1. Trailing slash
When calling an opfab API you cannot use anymore trailing slash on url.
If, for example, one makes a request like opfab/businessconfig/processes/, it must be replace by opfab/businessconfig/processes
24. Migration Guide from release 3.13.0 to release 3.14.0
24.1. Bundles folder
Bundles are not stored directly into the business config storage path defined in configuration anymore (operatorfabric.businessconfig.storage.path) but in a subdirectory named bundles. So in order to migrate, it is needed to move your bundles directories to a subdirectory named bundles.
To help you migrate your production environment you can use the following script : github.com/opfab/operatorfabric-core/tree/develop/src/tooling/migration-opfab3.13/moveBundles.sh
25. Migration Guide from release 3.14.0 to release 3.15.0
25.1. CrossOrigin for GeoJSON
The option feed.geomap.layer.geojson.crossOrigin
, used to set a cross-origin option when downloading GeoJSON, has
been removed.
26. Migration Guide from release 3.15.0 to release 4.0.0
26.1. Management of core menus and custom menus
The structure of the ui-menu.json
file has changed. Fields coreMenusConfiguration
and menus
do not exist anymore.
Now ui-menu.json
file contains 4 fields :
-
navigationBar
: contains the navigation bar mixing core menus and custom menus -
topRightIconMenus
: contains only the two menu iconsagenda
andusercard
on the top right of the screen -
topRightMenus
: contains the core menus you want to see when you click the user, on the top right of the screen -
locales
: contains the translations for the custom menus
With the new structure of the file, it is now possible to mix core menus and custom menus in the navigation bar. |
You can find more information and a full example in the documentation : opfab.github.io/documentation/current/reference_doc/#menu_entries
26.2. UI Configuration
Some fields of the web-ui.json
file have changed and renamed:
-
alertMessageBusinessAutoClose
has been moved to thealerts
section and is now calledmessageBusinessAutoClose
-
alertMessageOnBottomOfTheScreen
has been moved to thealerts
section and is now calledmessageOnBottomOfTheScreen
26.3. OpfabAPI
Use of methods or attributes starting with templateGateway are now deprecated , the following table give you the new methods to use
Deprecated method or attribute | New method |
---|---|
templateGateway.getEntityName(entityId) |
opfab.users.entities.getEntityName(entityId) |
templateGateway.getEntity(entityId) |
opfab.users.entities.getEntity(entityId) |
templateGateway.getAllEntities() |
opfab.users.entities.getAllEntities() |
templateGateway.redirectToBusinessMenu(menuId, menuItemId, urlExtension) |
opfab.navigate.redirectToBusinessMenu(menuId, menuItemId, urlExtension) |
templateGateway.isUserAllowedToRespond() |
opfab.currentCard.isUserAllowedToRespond() |
templateGateway.isUserMemberOfAnEntityRequiredToRespond() |
opfab.currentCard.isUserMemberOfAnEntityRequiredToRespond() |
templateGateway.getEntitiesAllowedToRespond() |
opfab.currentCard.getEntitiesAllowedToRespond() |
templateGateway.getEntityUsedForUserResponse() |
opfab.currentCard.getEntityUsedForUserResponse() |
templateGateway.getDisplayContext() |
opfab.currentCard.getDisplayContext() |
templateGateway.displayLoadingSpinner() |
opfab.currentCard.displayLoadingSpinner() |
templateGateway.hideLoadingSpinner() |
opfab.currentCard.hideLoadingSpinner() |
templateGateway.childCards |
opfab.currentCard.getChildCards() |
templateGateway.isLocked |
opfab.currentCard.isResponseLocked() |
templateGateway.lockAnswer = function () {//do some stuff} |
opfab.currentCard.listenToResponseLock( () ⇒ {//do some stuff} ) |
templateGateway.unlockAnswer = function () {//do some stuff} |
opfab.currentCard.listenToResponseUnlock( () ⇒ {//do some stuff} ) |
templateGateway.setLttdExpired = function () {//do some stuff} |
opfab.currentCard.listenToLttdExpired( () ⇒ {//do some stuff} ) |
templateGateway.onStyleChange = function () {//do some stuff} |
opfab.currentCard.listenToStyleChange( () ⇒ {//do some stuff} ) |
templateGateway.setScreenSize = function () {//do some stuff} |
opfab.currentCard.listenToScreenSize( () ⇒ {//do some stuff} ) |
templateGateway.onTemplateRenderingComplete = function () {//do some stuff} |
opfab.currentCard.listenToTemplateRenderingComplete( () ⇒ {//do some stuff} ) |
templateGateway.getUserResponse = function () {//do some stuff} |
opfab.currentCard.registerFunctionToGetUserResponse( () ⇒ {//do some stuff} ) |
templateGateway.applyChildCards = function () {//do some stuff} |
opfab.currentCard.listenToChildCards( () ⇒ {//do some stuff} ) |
usercardTemplateGateway.getCurrentProcess() |
opfab.currentUserCard.getProcessId() |
usercardTemplateGateway.getEditionMode() |
opfab.currentUserCard.getEditionMode() |
usercardTemplateGateway.getEndDate() |
opfab.currentUserCard.getEndDate() |
usercardTemplateGateway.getExpirationDate() |
opfab.currentUserCard.getExpirationDate() |
usercardTemplateGateway.getLttd() |
opfab.currentUserCard.getLttd() |
usercardTemplateGateway.getSelectedEntityRecipients() |
opfab.currentUserCard.getSelectedEntityRecipients() |
usercardTemplateGateway.getSelectedEntityForInformationRecipients() |
opfab.currentUserCard.getSelectedEntityForInformationRecipients() |
usercardTemplateGateway.getStartDate() |
opfab.currentUserCard.getStartDate() |
usercardTemplateGateway.getCurrentState() |
opfab.currentUserCard.getState() |
usercardTemplateGateway.getUserEntityChildCardFromCurrentCard() |
opfab.currentUserCard.getUserEntityChildCard() |
usercardTemplateGateway.getSpecificCardInformation = function () {//do some stuff} |
opfab.currentUserCard.registerFunctionToGetSpecificCardInformation( () ⇒ {//do some stuff} ) |
usercardTemplateGateway.setDropdownEntityRecipientList(recipients) |
opfab.currentUserCard.setDropdownEntityRecipientList(recipients) |
usercardTemplateGateway.setDropdownEntityRecipientForInformationList(recipients) |
opfab.currentUserCard.setDropdownEntityRecipientForInformationList(recipients) |
userCardTemplateGateway.setEntityUsedForSendingCard = function (entityID) {//do some stuff} |
opfab.currentUserCard.listenToEntityUsedForSendingCard( (entityID) ⇒ {//do some stuff} ) |
usercardTemplateGateway.setInitialEndDate(endDate) |
opfab.currentUserCard.setInitialEndDate(endDate) |
usercardTemplateGateway.setInitialExpirationDate(expirationDate) |
opfab.currentUserCard.setInitialExpirationDate(expirationDate) |
usercardTemplateGateway.setInitialLttd(lttd) |
opfab.currentUserCard.setInitialLttd(lttd) |
usercardTemplateGateway.setInitialSelectedRecipients(recipients) |
opfab.currentUserCard.setInitialSelectedRecipients(recipients) |
usercardTemplateGateway.setInitialSelectedRecipientsForInformation(recipients) |
opfab.currentUserCard.setInitialSelectedRecipientsForInformation(recipients) |
usercardTemplateGateway.setInitialSeverity(initialSeverity) |
opfab.currentUserCard.setInitialSeverity(initialSeverity) |
usercardTemplateGateway.setInitialStartDate(startDate) |
opfab.currentUserCard.setInitialStartDate(startDate) |
26.4. Write right for user (RightsEnum.Write)
The Write
right has been removed. Considering Receive
and ReceiveAndWrite
rights, Write
was useless
and confusing for the code.
Before upgrading to 4.0, you must replace all "Write" rights by "ReceiveAndWrite" rights. If you want to automate it, you can do it directly in the database via the following request :
db.perimeter.updateMany({"stateRights.right": "Write"}, {"$set": {"stateRights.$.right": "ReceiveAndWrite"}});
26.5. Cards reminder
Cards reminder logic has been moved from front-end to back-end. The reminder logic is handled by the new "cards-reminder" service.
After upgrading to 4.0, you must call the /reset
endpoint to populate the reminders database by processing all current cards with reminder set. For example using cURL:
curl http://localhost:2107/reset -H "Authorization:Bearer $token"
26.6. Internal technical account
The new back service for reminder and the new service regarding mail diffusion and supervision introduce the need of an internal account to communicate between opfab back services. Therefore, if you intend to utilize any of these services, it is necessary to create an Opfab technical account with ADMIN permissions and configure it within your shared YAML configuration file, for example :
operatorfabric:
internalAccount:
login: opfab
password: the_password
The services require knowledge of the URL to retrieve the account’s token, and this URL should be configured within operatorfabric.servicesUrls.authToken. A default value, based on OperatorFabric default installation, is set to: "http://web-ui/auth/token".
26.7. Port mapping
In release 4.0, the listening port is not any more 8080 for services in docker, it is now identical to the default port mapping outside the docker.
So you need to modify your port mapping to migrate replacing the 8080 legacy port by the new port :
2100 |
businessconfig |
2102 |
cards-publication |
2103 |
users |
2104 |
cards-consultation |
2105 |
external-devices |
Depending on your production configuration, you may need as well to change the ports in your nginx conf file.
If you want to keep the old port 8080, you can change it via the server.port parameter in the yml config files of the services.
26.8. RabbitMQ
In previous versions, it was necessary to start a RabbitMQ container referencing "rabbitmq:3-management." We now highly recommend that you update your configuration to utilize "lfeoperatorfabric/of-rabbitmq:4.0.0.RELEASE" instead. This adjustment ensures that you have a qualified version that is fully compatible with OpFab.
When migrating your production environment you may be unable to start rabbitMQ with the following error in log :
2023-09-14 13:57:00.803114+00:00 [error] <0.230.0> Feature flags: `maintenance_mode_status`: required feature flag not enabled! It must be enabled before upgrading RabbitMQ.
2023-09-14 13:57:00.955976+00:00 [error] <0.230.0> Failed to initialize feature flags registry:{disabled_required_feature_flag,
2023-09-14 13:57:00.955976+00:00 [error] <0.230.0> maintenance_mode_status}
BOOT
FAILED
===========
Error during startup: {error,failed_to_initialize_feature_flags_registry}
2023-09-14 13:57:01.022987+00:00 [error] <0.230.0>
2023-09-14 13:57:01.022987+00:00 [error] <0.230.0> BOOT FAILED
2023-09-14 13:57:01.022987+00:00 [error] <0.230.0> ===========
2023-09-14 13:57:01.022987+00:00 [error] <0.230.0> Error during startup: {error,failed_to_initialize_feature_flags_registry}
This issue arises because the persisted data (RabbitMQ queues) generated by the previous version of RabbitMQ is incompatible with the current RabbitMQ version. To address this problem, it is necessary to remove the persisted data before launching OpFab, which can be found at the path mapping /var/lib/rabbitmq/mnesia/ within the Docker container.
If you have configured RabbitMQ persistence, we recommend implementing this as a preventive measure to avoid service unavailability in production.
26.9. Configuration
The configuration has been simplified, you have now default parameters you do not need to set anymore in the back configuration:
-
in all yml file you do not need to set anymore spring.application.name
-
a default kafka configuration is provided, you only have to add "kafka.consumer.group-id : opfab-command" to enable kafka
-
a default rabbit configuration is provided
-
default value are provided for "operatorfabric.servicesUrls.users" and "operatorfabric.servicesUrls.businessconfig"
-
"spring.data.mongodb.database" is not to be set anymore
-
you still need to set "management.endpoints.web.exposure.include: '*'" if you want to monitor opfab via prometheus
-
operatorfabric.businessconfig.storage.path is set by default to "/businessconfig-storage"
The nginx configuration has been simplified as well, the best is to redefine your actual nginx based on the example /config/docker/nginx.conf. The main modification is the removal of the following endpoints declaration :
-
/archives
-
/ui
-
/ui/assets/i18n
-
/config/web-ui.json
-
/config/menu-ui.json
We have also implemented data compression for the information supplied by the "businessconfig" service within the "nginx.conf" reference file. This is done by adding in the location /businessconfig :
gzip on;
gzip_types application/json;
The nginx conf is not loaded anymore in /usr/share/nginx/html/opfab in the docker but in /usr/share/nginx/html/config. You need to modify your volume configuration . For example in docker compose :
volumes:
- "./ui-config:/usr/share/nginx/html/opfab"
becomes :
volumes:
- "./ui-config:/usr/share/nginx/html/config"
In the web-ui.json file, you do not need anymore to set : - security.jwt.expire-claim - security.oauth2.flow.provider - security.oauth2.provider-realm - security.oauth2.provider-url
26.10. Normalization of some configuration parameters
Some configuration parameters have been renamed, so you have to check your config files and adapt them. Here are the concerned parameters (old name → new name):
-
daysBeforeLogExpiration → operatorfabric.users.daysBeforeLogExpiration
-
checkAuthenticationForCardSending → operatorfabric.cards-publication.checkAuthenticationForCardSending
-
authorizeToSendCardWithInvalidProcessState → operatorfabric.cards-publication.authorizeToSendCardWithInvalidProcessState
-
checkPerimeterForCardSending → operatorfabric.cards-publication.checkPerimeterForCardSending
-
external-recipients.* → operatorfabric.cards-publication.external-recipients.*
-
opfab.kafka.topics.card.topicname → operatorfabric.cards-publication.kafka.topics.card.topicname
-
opfab.kafka.topics.response-card.topicname → operatorfabric.cards-publication.kafka.topics.response-card.topicname
-
opfab.kafka.schema.registry.url → operatorfabric.cards-publication.kafka.schema.registry.url
-
delayForDeleteExpiredCardsScheduling → operatorfabric.cards-publication.delayForDeleteExpiredCardsScheduling
-
checkIfUserIsAlreadyConnected → operatorfabric.checkIfUserIsAlreadyConnected
-
spring.data.mongodb.uri -→ operatorfabric.mongodb.uri
-
spring.rabbitmq.* -→ operatorfabric.rabbitmq.*
-
spring.security.oauth2.resourceserver.jwt.jwk-set-uri -→ operatorfabric.security.oauth2.resourceserver.jwt.jwk-set-uri
26.11. Mongodb uri
The option "authMode=scram-sha1" has to be removed from mongodb uri as SCRAM authentication is enabled by default and "authMode" option is not supported by node.js mongodb driver. For example you should change :
mongodb:
uri: mongodb://root:password@mongodb:27017/operator-fabric?authSource=admin&authMode=scram-sha1
to
mongodb:
uri: mongodb://root:password@mongodb:27017/operator-fabric?authSource=admin
26.12. Rate limiter for card sendings
External publishers are now monitored by a new module which limits how many cards they can send
cardSendingLimitCardCount
in a period of time
cardSendingLimitPeriod
.
This is to avoid potential overloading due to external apps stuck in a card sending loop.
Default value is set to 1000 cards per hour. It can be disabled / enabled with
activateCardSendingLimiter
27. Migration Guide from release 4.0.0 to release 4.1.0
27.1. Optimizing Nginx Configuration for Latency Reduction
An optimization has been introduced in the Nginx configuration to reduce latency. To implement this optimization in your nginx.conf
you need to add in location /cards/
the directive proxy_buffering off
For example :
location /cards/ {
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_pass http://cards-consultation:2104/;
proxy_set_header X-Forwarded-For $remote_addr;
}
27.2. Updating the file size limit
The limit of maximum file size has been updated to 100 MB. To implement this limit in your nginx.conf
you need to add in location /businessconfig/
the directive client_max_body_size 100M;
For example :
location /businessconfig {
proxy_set_header Host $http_host;
proxy_pass http://${MY_DOCKER_HOST}:2100;
proxy_set_header X-Forwarded-For $remote_addr;
client_max_body_size 100M;
}
27.3. Nginx Configuration for entity supervision administration
The new 'Supervised Entities' admin page requires interaction with the supervisor API via Nginx. To enable access to the supervisor API, please incorporate the following configuration into your nginx.conf
file:
location ~ "^/supervisor/(.*)" {
set $supervisor http://supervisor:2108;
proxy_set_header Host $http_host;
proxy_pass $supervisor/$1;
proxy_set_header X-Forwarded-For $remote_addr;
}
27.4. Supervisor configuration change
The configuration of 'supervisor.defaultConfig.entitiesToSupervise' parameter has changed. The supervised entity field id
has been renamed to entityId
. You should modify your configuration accordingly.
For example:
supervisor:
defaultConfig:
entitiesToSupervise:
- id: ENTITY1_FR
supervisors:
- ENTITY2_FR
- id: ENTITY2_FR
supervisors:
- ENTITY1_FR
should be changed to:
supervisor:
defaultConfig:
entitiesToSupervise:
- entityId: ENTITY1_FR
supervisors:
- ENTITY2_FR
- entityId: ENTITY2_FR
supervisors:
- ENTITY1_FR
28. Migration Guide from release 4.1.0 to release 4.2.0
28.1. Deletion of parameter displayConnectionCirclesInPreview
The parameter displayConnectionCirclesInPreview
has been deleted. Now, in the usercard preview, users will see
which recipients entities are connected or not via badges : a blue badge if connected and a gray one if not.
This feature is provided for all users.
So you have to remove this parameter from the configuration file web-ui.json
.
28.2. Configuration files of the realtime users screen
Previously, to configure this screen, the json file had to fit the following structure :
{
"realTimeScreens": [
{
"screenName": <Name of the screen>,
"screenColumns": [
{
"entitiesGroups": [
{
"name": <Name of a group of entities>,
"entities": [
<entity1 id>,
<entity2 id>
]
},
{
"name": <Name of another group of entities>,
"entities": [
<entity3 id>,
<entity4 id>
]
}
]
}
]
}
]
}
Now entities shouldn’t be grouped in the configuration file anymore. Instead entities are grouped by a shared parent entity. The configuration file needs to be changed to the following structure:
{
"realTimeScreens": [
{
"screenName": <Name of the screen>,
"screenColumns": [
{
"entitiesGroups": ["<parent entity 1 id>","<parent entity 2 id>"]
}
]
}
]
}
With this parent entity 1 and parent entity 2 need to be declared and the name of the parent entities will be the name of the groups.
28.3. Updating the entity roles in the database
In this release the "roles" attribute has been added to the entity object. It defines the utility of an entity. It absorbs and broaden the logic of the attribute "entityAllowedToSendCard" which becomes deprecated.
To update the entities in your mongo database, you can execute the following script located in OF_HOME/src/tooling/migration-entity-roles
:
./launchMigration.sh <IP or DNSNameMongoDB> <portMongoDB> <loginMongoDB> <passwordMongoDB>
This script will assign the roles "ACTIVITY_AREA", "CARD_RECEIVER" and "CARD_SENDER" to all the entities that have "entityAllowedToSendCard = true" and the role "CARD_RECEIVER" to the others. Please refer to the documentation to see the other possible roles and their effect.
After successful execution of the previous script you should execute the following script to cleanup the database removing the deprecated attribute "entityAllowedToSendCard":
./cleanMongoAfterMigration.sh <IP or DNSNameMongoDB> <portMongoDB> <loginMongoDB> <passwordMongoDB>
28.4. Deletion of deprecated functions in templateGateway/usercardTemplateGateway
Functions in templateGateway/usercardTemplateGateway do not exist anymore, you can refer to the migration documentation to opfab 4.0 to know which functions you have to use.
28.5. Card keepChildCards
The card field keepChildCards
is now deprecated, use the new actions
field (string array) including "KEEP_CHILD_CARDS" action instead.
28.6. Feed process and state filter
New filters have been added to feed filters to allow filtering by card process and state.
It is possible to hide the process filter by setting feed.card.hideProcessFilter
to true
in web-ui.json
config file. When process filter is hidden than also state filter is hidden.
It is possible to hide just the the state filter by setting feed.card.hideStateFilter
to true
in web-ui.json
config file.