All pages
Powered by GitBook
1 of 19

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Upgrade Runbook

MOSIP has recently announced the release of its latest version, 1.2.0.1-B4. This new release brings about an architectural upgrade and addresses multiple bugs. To assist users in migrating from the MOSIP version 1.1.5.x to the latest version 1.2.0.1, a detailed Runbook has been provided, offering comprehensive guidance.

To set up the new environment and deploy the upgraded version of MOSIP, carefully follow the procedures outlined below step-by-step.

Points to Consider

  • The migration will only be supported if the latest version deployed is 1.1.5.x (mostly 1.1.5.5-P1 and above). Countries should ensure that MOSIP is updated to version 1.1.5.x before migrating to the newer version.

  • Once the upgrade is completed, all the modules running on the server will be upgraded together.

  • The IDA Database will not have any entries from version 1.1.4.

  • Migration of websub event is not supported for countries transitioning from db-based websub to kafka-based websub.

  • After migration, if a new machine is added for the Registration Client, it must be installed with the latest version of the Registration Client. We will not provide support for the old version.

  • Partners who decrypt data encrypted by the key manager will support decryption with thumbprint support after upgrading to version 1.2.0.1. Therefore, backward support to encrypt without thumbprint is not available.

  • Prior to migration, countries should prioritize packets stuck in between stages using the registration processor and complete the processing.

  • Any third-party subsystems such as Manual adjudication/ABIS will not respond after migration for a request received before migration. Therefore, it is suggested that all subsystems, such as ABIS and manual adjudication, consume all the messages from ActiveMQ, complete the processing, mark all for reprocess, and respond back to registration processor before migration.

  • Default resource allocation (CPU and memory) has been added to all the pods in version 1.2.0.1, so additional nodes may be required after the upgrade.

  • The rollback process during the migration needs to be handled by the respective system integrators (SI).

  • All the server services and registration clients will be running version 1.1.5.x.

  • Registration packets available in MinIO and the landing zone can be version 1.1.4.x / 1.1.5.x.

  • Existing Grafana and Kibana reports from version 1.1.5 are not required to be viewable in the upgraded environment.

  • If there are additional attributes in the data share for manual adjudication, the manual adjudication system will ignore them and not fail.

  • The first global admin user login does not need to be handled during the upgrade.

  • Out of scope for migration:

    • Configuration of correction flow and related changes are not included in this migration.

    • Anonymous profiles for existing data are not handled in this upgrade.

    • Support for the Lost RID/AID search feature for packets synced before the migration is out of scope.

Upgrade Process

This comprehensive upgrade process entails the deployment architecture upgrade from V2 to V3, as well as the MOSIP platform upgrade from version 1.1.5.5-P1 to 1.2.0.1. The various tasks involved in this process are organized into the following categories.

Upgrade of Deployment Architecture from V2 to V3

  1. Installation and configuration of new environment with V3 architecture.

  2. Deployment of external services.

  3. Backup and restoration of external services.

Upgrade of Platform from version 1.1.5.5-P1 to 1.2.0.1

  1. Upgrade of necessary external services.

  2. Migration of properties.

  3. Upgrade of MOSIP services.

  4. Execution of activities once all upgraded services are operational.

Let us go through the processes discussed above in detail.

Handling Duplicate Entries

This document addresses how an error in Database upgrade script can be managed effectively.

Issue

If the below error has been encountered while attempting to execute the upgrade script, this can be resolved by following the steps mentioned in this document.

Error message

The error message states that a unique index, named cert_thumbprint_unique, cannot be created due to a duplicate entry. Specifically, the values for the cert_thumbprint

Carrying out activities after completion of initial round of testing.

Cover

Cover

Cover

and
partner_domain
columns, which are (231bd472ab24ef60ec6*******2cace89c34, AUTH), already exist in the database. This duplicate entry violates the unique constraint defined for the
ca_cert_store
table in the
mosip_keymanager
database.

To address and successfully execute the DB upgrade script, the following steps can be taken:

  1. Identify the duplicate entries in the mosip_keymanager table.

  2. To accomplish this, use the provided SQL query:

    SELECT * 
    FROM keymgr.ca_cert_store 
    WHERE (cert_thumbprint, partner_domain) IN 
          (SELECT cert_thumbprint, partner_domain 
           FROM your_table_name 
           GROUP BY cert_thumbprint, partner_domain 
           HAVING COUNT(*) > 1);

    This query will retrieve the rows of data that contain duplicate entries.

  3. As a precautionary measure, it is advisable to create a backup of all the duplicate values.

  4. Remove the duplicate entries so that only one composite key remains. The aforementioned SQL script can be reused to verify that the duplicates have been successfully deleted. If the result is empty, then all duplicates have been removed.

  5. By following these steps, the problem should be resolved, and the DB upgrade script can be executed without any further issues.

psql:sql/1.1.5.5_to_1.2.0.1-B1_upgrade.sql:13: ERROR: could not create unique index "cert_thumbprint_unique" DETAIL: Key (cert_thumbprint, partner_domain)=(231bd472ab24ef60ec6*******2cace89c34, AUTH) is duplicated. psql:sql/1.1.5.5_to_1.2.0.1-B1_upgrade.sql:13: STATEMENT: ALTER TABLE keymgr.ca_cert_store ADD CONSTRAINT cert_thumbprint_unique UNIQUE (cert_thumbprint,partner_domain);

Platform Upgrade

This document outlines the necessary steps for upgrading the Platform from version 1.1.5.5-P1 to 1.2.0.1.

Step 1: Upgrade of necessary services

  1. Postgres:

  • Check and remove the duplicate thumbprint entries in keymanager ca_cert_store. Refer the to know more.

  • Refer the for DB upgrade scripts to update the DB.

  • Change shareDomain in all the relevant policies to point to latest datashare

    • Change shareDomain's value from datashare-service to datashare.datashare in the policy_file_id column for each partner.

  • Check and rectify the partner name mismatch issue for certificate renewal. To know more, refer .

  • Follow this to check on the validity of the partner certificate and for renewal/ extension if required.

  • Check mvel expression, id schema and document mappings and add the required applicant document mappings. Click to know more.

  1. Keycloak:

  • Follow the steps mentioned to execute upgrade keycloak init with import-init.yaml.

  • Verify all the existing users of admin and update the roles according to the latest role matrix. To know more about the existing users, refer .

  • In Keycloak, it is important to ensure that the VID / UIN of each operator and supervisor is collected and updated in the individualId field. Failure to do so may cause complications during the onboarding or re-onboarding processes to new or existing machines, as well as during the biometrics update process for these users.

  1. Activemq:

  • Clear all the objects along with topics in the activemq or deploy a fresh instance of activemq with no previous data

  1. ABIS:

  • Stop and clear all the inprogress items as it will be reprocessed freshly.

  • Review the queue names and update if required (mosip-to-abis and abis-to-mosip).

  1. Manual adjudication system:

    • Stop and clear all the in-progress items as it will be reprocessed freshly.

    • Review the queue names and update if required (mosip-to-adjudication and adjudication-to-mosip).

Step 2: Migration of Properties

  • Refer this to run the property migration script.

  • Update registration-processor-default.properties reprocess elapse time to a larger time to avoid reprocessing before migration is fully complete (registration.processor.reprocess.elapse.time=315360000).

  • Add the below properties to syncdata-default.properties file if reg-client versions 1.1.5.4 and below are to be supported additionally.

  • Configuration property files required to be updated for language specific deployments. Please follow the below snippet.

Note: Ensure that the transliteration line is not commented out, even for a single language.

  • Take the latest version of the identity-mapping.json file (1.2.0.1) from mosip-config and update the mapping values based on the country's id schema. Please refer for instructions on making the necessary updates.

  • Additionally, make adjustments to the mvel config file for the application type according to each country's specific requirements. For more details on how to modify the mvel config file, please refer .

  • The camel routes need to be modified to accommodate the new workflow commands and ensure proper integration with external subsystems such as manual adjudication and manual verification. To understand the specific changes required, refer

Step 3: Upgrade of MOSIP

  • To begin, set up the Configuration server.

  • Next, configure and setup the Artifactory.

  • Proceed with the installation in the specified sequence. Refer to the provided for the correct order.

  • Execute the salt generation job

Note: Disable the masterdata loader and regproc-reprocessor.

Step 4: Execution of activities once all upgraded services are operational

  • To resend the partner and policy details to IDA, please run the PMS utility job once. You can find the steps to run the job .

  • The UI specs for pre-registration should be published via the MasterData API in version 1.2.0. Previously, in version 1.1.5, the UI specs were saved in the config server. To upgrade the UI specs, please refer .

  • To proceed with the masterdata country specific upgrade scripts, please follow the instructions outlined .

Step 5: Carrying out activities after completion of initial round of testing

  1. Configure the Registration Client upgrade at the server side. Please refer to this for further instructions.

  2. Run the query to identify all the packets stuck between the stages. Use the manual reprocess utility to reprocess all the RIDs found using the above query. Please refer to this to carry out the reprocess.

  3. Initiate the regproc reprocessor.

Optional Steps

  1. Ensure that the datashare property is properly configured in the abis policy for the domain. Please refer to this for more detailed information.

  2. Remove any unnecessary roles for clients and users.

  3. When the admin portal becomes accessible, the admin user should generate the master keys that have been recently added to the key_policy_def table. This can be done using the admin UI master key generation page (Keymanager) for the ADMIN_SERVICES and RESIDENT

Identifying Applicant Type

Location: repository

Applicant-type MVEL script usages in MOSIP modules :

Manually update roles for client IDs that have been added as part of customization. For more information about the changes, please refer here.

Manual verification system:
  • Stop and clear all in-progress items as it will be reprocessed freshly.

  • Review the queue names and update if required (mosip-to-verification and verification-to-mosip).

  • Run the data movement to the necessary three tables using the provided script. Afterward, run the migration script to re-encrypt the data and perform the movement of data from the bucket to the folder (This step is only necessary if the pre-registration has been upgraded from version 1.1.3.x). Please consult the provided document for detailed instructions on how to carry out the data movement process.

  • .
  • Please ensure that the mosip.regproc.packet.classifier.tagging.agegroup.ranges property is aligned with the camel route.xml file.

  • to generate salts for the newly created table in the regproc.
  • Run the key generation job to ensure that all new module keys comply with the key_policy_def table.

  • Please create all the required applicant type details according to the applicanttype.mvel file created in the property migration section. For more information, please refer to the document here.

  • Starting from version 1.2.0.1, it is mandatory to prepend the thumbprint for all encryptions. Therefore, we need to ensure that the certificate thumbprint for a particular partner exactly matches in both the keymanager and IDA key_alias tables. To learn how to check thumbprints and for further steps, please refer here.

  • Please check and rectify any mixed case user names in the user details and zone mapping. For more information, refer here.

  • Finally, restart all the services to take care of old data caching.

  • In case packets continue to fail due to performance issues, follow the steps mentioned in the document to process packets from the beginning.
  • Perform the ID Repository tasks. Run the archival script and reprocess SQL script on the credential transaction table as specified in the document.

  • Backup and delete any unnecessary tables and databases.

  • Manually remove the "mosip_regdevice" and "mosip_authdevice" databases, as they have been moved to "mosip_pms".

  • Delete all tables ending with "<table_name>_to_be_deleted" and "<table_name>_migr_bkp".

  • roles. Only proceed with this step if the corresponding entries are not already available in the
    key_alias
    table of keymanager. For more detailed instructions, please consult the provided
    .
  • During the pre-registration upgrade process, if the encryption key is REGISTRATION, which is an old key, it must be updated. To update the encryption key, please refer to the migration utility process by clicking here.

  • document
    link
    here
    link
    here
    here
    here
    document
    here
    here
    link
    here
    here
    here
    link
    link
    link
    here
    document
    #Properties needed for 1.1.5.4 and previous version reg-client compatibility (Tag mismatch error)
    mosip.kernel.client.crypto.iv-length=16
    mosip.kernel.client.crypto.aad-length=12
    ## Transliteration
    mosip.kernel.transliteration.arabic-language-code=ara
    mosip.kernel.transliteration.english-language-code=eng
    # Added this property for backward compatibility as it is misspelled in <1.2.0 versions of kernel-transliteration library
    mosip.kernel.transliteration.franch-language-code=fra

    This MVEL script is used to determine the type of applicant based on the captured demographic data during the registration process.

    → Set of rules to determine the type of applicant is written as an MVEL script.

    → Applicant Data required for the evaluation passed as “identity” map to the MVEL context.

    → def getApplicantType() method MUST be defined in the script. The string returned from this method should be a valid applicant type code or error code (KER-MSD-151, KER-MSD-147)

    applicant_type_code - Must be one of the values in the apptyp_code column in “master.applicant_valid_document" table.

    "KER-MSD-147" - returned when any of the demographics that are required for the script to return a code are empty (As per default script, it throws this exception if gender or residenceStatus or age is not filled / empty).

    "KER-MSD-151" - returned when the DOB exceeds the current date.

    → Data in the “identity” map are key-value pairs. The Key is the field id in the id-schema.

    → For the fields which are based on dynamic field values. For Ex: gender

    “identity” map will have 2 mappings, genderCode, and gender. where the

    identity.genderCode = “FLE”

    identity.gender = “Female”

    → Age group configuration is also passed in the MVEL context as below

    { “ageGroups” : {'INFANT':'0-5','MINOR':'6-17','ADULT':'18-200'} } and will be accessible as below in the script.

    ageGroups.INFANT = “0-5”

    ageGroups.MINOR = “6-17”

    ageGroups.ADULT = “18-200”

    Sample MVEL script is defined here https://github.com/mosip/mosip-config/blob/master/applicanttype.mvel

    Note: In Pre-registration and Registration-Client, applicant-type code is used to control the list of documents to be collected during the registration process.

    The applicant_type_code returned from this mvel script will be then used to fetch the required documents from master.applicant_valid_document table.

    For example, if the script returns applicant_type_code as “001”, all those entries in the applicant_valid_document table with app_typ_code as “001” will be picked and shown in the respective document dropdowns.

    Attaching the sample csv file below which lists down the required entries for master.applicant_valid_document table.

    We can upload this default data from Admin Portal through Bulk Upload feature.

    The steps to be followed are mentioned below:

    1. Login to Admin Portal.

    2. Navigate to Bulk Upload → Master Data.

    3. Select the Insert operation, select the table name (ApplicantValidDocument) from the dropdown and upload the csv file.

    4. Click on Upload, which saves the uploaded data to the server DB.

    Attaching screenshot for reference:

    Module Name

    Before LTS

    LTS

    Pre-registration

    Yes

    Yes

    Registration Client

    No

    mosip-config

    No

    10KB
    applicant_valid_document.xlsx
    Open

    Deployment Architecture Upgrade

    This document outlines the steps required for migrating the deployment architecture from V2 to V3.

    Step 1: New environment setup with V3 Architecture

    This is required for migration from V2 to V3 architecture

    1. Make sure to have all the pre-requisites ready as per the details present in the section

    INVALID_QUERY_EXCEPTION("KER-MSD-147", "Invalid query passed for applicant type"),	INVALID_DATE_DOB_EXCEED_EXCEPTION("KER-MSD-151", "DOB cannot exceed current date");

    New Datashare Properties

    If a country desires to designate specific data sharing to be transmitted on HTTP or HTTPS endpoints, they should accomplish this by including the Domain URL of the data sharing in the policy field itself. This will have priority over any other settings.

    Furthermore, two new fields have been incorporated into the policy:

    • shareDomainUrlWrite: This field should be employed by individual modules when calling the data sharing functionality to write data.

    • shareDomainUrlRead: This field should be used by the data sharing functionality when generating a URL to share with modules for reading data.

    Note: It is important to note that these fields are compatible with previous versions and are not obligatory to include in all policies. They can be utilized only if a country sees a need for the new features.

  • Setup Wireguard Bastion host

  • Setup wireguard client in your local and complete the configuration

  • Setup Observation K8 cluster

  • Configure Observation k8 cluster

  • Observation cluster’s nginx setup

  • Observation cluster applications setup

  • Observation cluster keycloak-rancher integration

  • Setup new MOSIP k8 cluster

  • MOSIP k8 cluster configuration

  • MOSIP cluster nginx setup

  • Setting up Monitoring for MOSIP cluster

  • Setting up Alerting for MOSIP cluster

  • Setting up Logging for MOSIP cluster

  • Step 2: Deployment of external services

    (Required for V2 to V3 architecture migration)

    1. Setup postgres server

      Note:

      i. Deploy postgres server in a seperate node.

      ii. Make sure postgres initialisation is not done (only install postgres).

    2. Setup Keycloak server

      Note: Make sure keycloak initialisation is not done (only install keycloak).

    3. Setup

    4. Setup

    5. Setup

    6. Setup

    7. Setup

    8. Setup docker if you are using private dockers.

      Note: These instructions are only applicable if you need to access Private Docker Registries. You may disregard them if all of your Docker containers are downloaded from the public Docker Hub.

    9. Setup for the required domains.

    10. Setup for new MOSIP cluster.

    Step 3: Backup and restoration of external services

    This step is required for V2 to V3 architecture migration.

    1. Softhsm (only required if softhsm is used instead of real HSM)

      i. Backup keys

      ii. Restore old key

      iii. Update softhsm ida and softhsm kernel security pin

    2. Postgres

      i. Export

      ii. Import

      iii. secret creation

      iv. Increase postgres max_connections to 1000

    3. Keycloak

      i.

      ii.

    4. Minio

      i. Export the existing Minio as directory

      ii.

    5. Kafka

      i. setup external minio for backup.

      ii. backup kafka

      iii. restore kafka

    6. Conf-secrets

    Update the secrets in existing secrets in conf-secrets namspace.

    1. Packets in landing to be copied from old environment to the upgraded environment or same NFS folder can be mounted to regproc packet server and group 1 stage groups. Refer here for more details.

    • dmz-sc.yaml

    • dmz-pkt-pv.yaml

    • dmz-pkt-pvc.yaml

    • dmz-landing-pv.yaml

    • dmz-landing-pvc.yaml

    pre-requisites

    Additional Information

    Introduction

    Modular Open Source Identity Platform (MOSIP) integrates a suite of Mock Services designed to emulate key functionalities of MOSIP services within the framework. In the development, testing, and demonstration phases, Mock Services will make available a controlled environment to evaluate MOSIP features.

    This document details each of the mock services and explains its significance within the MOSIP architecture.

    Below are the current set of Mock Services available in MOSIP, the services are subject to modifications, as may be planned, in future releases. Please refer to the latest available version of the document.

    • Simulates device services for testing, authentication and delete registration functionalities.

    • Allows developers to interact with a device-service environment without a physical device.

    1. Mock MV (Manual Verification)

    • Reproduces the manual verification process for testing and validation purposes.

    • Enables the testing of manual verification workflows without human intervention.

    • Simulates the functionality of the Automated Biometric Identification System (ABIS).

    • Facilitates testing of biometric matching, search, and integration with ABIS without accessing production data.

    • Maintains resident biometric uniqueness through de-duplication.

    • Interfaces with MOSIP via message queues in JSON format.

    • Replicates MOSIP's Biometric Software Development Kit (SDK) for testing and debugging purposes.

    • Allows developers to integrate biometric functionalities into applications without connecting to physical device.

    • Used for 1:N match, quality, extraction, etc.

    • Simulation is available as Mock BioSDK, installed in the MOSIP sandbox.

    1. Mock SMTP (Simple Mail Transfer Protocol)

    Handling Non-Recoverable Packets

    After running the reprocess utility and regproc reprocessor, it is possible that a few packets may end up in the FAILED status. This can occur due to various reasons such as environment instability or high parallel processing of packets. The following steps will help in identifying if such packets exist and how to handle them.

    To handle these packets, please follow the below steps:

    1. Use the sample query below to find out if there are packets in a non-recoverable state:

    Here, cr_Dtimes should be less than the time of upgrade completion and the processing of the first packet. latest_trn_Dtimes should be greater than the time of upgrade completion and the processing of the first packet. If there are no packets in this status, no further action is required. If any packets are found with the above status, proceed to step 2.

    Handling Partner Organization Name Mismatch Issue

    This document helps in addressing an error related to partner organization name mismatch.

    How do we handle this error?

    During the partner certificate renewal process, users may encounter an error message while uploading the partner certificate.

    The error code KER-PCM-008 indicates a partner organization name mismatch.

    This error suggests that the organization name on the partner's certificate is different from the one originally registered with.

    To resolve this issue, users need to manually update the name column in the partner table of the mosip_pms database with the new organization name from the fresh certificates.

    Softhsm
    Minio server
    ClamAV
    ActiveMQ
    Message Gateway
    registry secrets
    Captcha
    Landing page
    Export
    Import
    Clone Minio

    Supports 1:N de-duplication and adheres to ABIS API Specifications.

    Exposes REST APIs for 1:1 match and quality check at the MOSIP backend.

    Mock MDS (MOSIP Device Services)
    Mock ABIS (Automated Biometric Identification System)
    Mock SDK (Software Development Kit)
    After successfully uploading the partner certificate, it is important to restart the partner-management-service pod.

    <<>

    KER-PCM-008 
    Partner Organization Name not Matched.
  • Before running the reprocess utility to process the packet from the beginning as per the APPROACH 1 in document, update the DEFAULT QUERY in the config.py file as per the requirements to process non-recoverable records.

  • The sample query is as follows:

    Here, the status code should be set to FAILED. cr_Dtimes should be less than the time of upgrade completion and the processing of the first packet. latest_trn_Dtimes should be greater than the time of upgrade completion and the processing of the first packet.

    After changing the query in config.py, please refer to the documentation on how to set up and run the reprocessor script.

    To reprocess packets, use the following command:

    SELECT * FROM registration WHERE status_code='FAILED' AND latest_trn_Dtimes > '2023-10-10 10:00:00.000000' AND cr_Dtimes < '2023-08-25 00:00:00.000000';
    SELECT reg_id, process, workflow_instance_id, iteration FROM registration WHERE status_code='FAILED' AND latest_trn_Dtimes > '2023-10-10 10:00:00.000000' AND cr_Dtimes < '2023-08-25 00:00:00.000000' LIMIT 1000;
    $ ./reprocess.py --db

    Adapting Changes in Administration Roles

    Below is the list of admin roles:

    • GLOBAL_ADMIN

    • ZONAL_ADMIN

    • REGISTRATION_ADMIN

    • MASTERDATA_ADMIN

    • KEY_MAKER

    GLOBAL_ADMIN
    ZONAL_ADMIN
    REGISTRATION_ADMIN
    MASTERDATA_ADMIN
    KEY_MAKER

    Here:

    Green- colored represent persisted roles.

    Blue- colored cells represent newly added roles.

    Red- colored cells represent removed roles.

    How to adjust the role accessibilities for existing users after upgrading to 1.2.0.1-x from 1.1.5.5-P1?

    For a user having GLOBAL_ADMIN role:

    • If a GLOBAL_ADMIN user is performing Certificate related operations then KEY_MAKER role need to be added to that user.

    • If a GLOBAL_ADMIN user is performing Packet Bulk Upload then REGISTRATION_ADMIN role need to be added to that user.

    For a user having ZONAL_ADMIN role:

    • If a ZONAL_ADMIN user is performing Certificate related operations then KEY_MAKER role need to be added to that user.

    • If a ZONAL_ADMIN user is performing Packet Bulk Upload then REGISTRATION_ADMIN role need to be added to that user.

    For a user having REGISTRATION_ADMIN role:

    • If a REGISTRATION_ADMIN user is performing Certificate related operations then KEY_MAKER role need to be added to that user.

    For a user having MASTERDATA_ADMIN role:

    • If a MASTERDATA_ADMIN user is performing GenerateCSR then KEY_MAKER role need to be added to that user.

    • If a MASTERDATA _ADMIN user is performing Packet Bulk Upload then REGISTRATION_ADMIN role need to be added to that user.

    Note: A few new permissions were added to MASTERDATA_ADMIN and KEY_MAKER roles, please refer to the above role matrix table and if there is any inconsistency in the accessibility or roles of existing user, please reassign the roles to the user accordingly.

    Handling Case Insensitive Duplicated User Details

    In the registration processor, there was an issue where packets were failing at the supervisor validation stage when the username of the supervisor was entered in a different case than it appeared in the database. To resolve this issue, a case insensitive search will be implemented to retrieve the username of the supervisor during the validation stage.

    In order for this fix to work properly, it is necessary for the user_id column of the user_details table in the master database to not contain any case insensitive duplicates.

    If there are any duplicates in this table, packets will fail at the supervisor validation stage once again. Therefore, it is important to deactivate or delete these case insensitive duplicates. It should be noted that this action will not have any impact on other areas, as the mapping between keycloak users and the user_id of the user_details table is one-to-one and case insensitive.

    GenerateCSR

    All Master Data

    Machines

    Retrieve Lost RID

    All Master Data

    GetCertificate

    Masterdata Bulk Upload

    User Zone Mapping

    Packet Bulk Upload

    Masterdata Bulk Upload

    UploadCertificate

    Packet Bulk Upload

    User Center Mapping

    UploadCertificate

    GenerateCSR

    UploadOtherDomainCertificate

    GenerateCSR

    All Master Data

    Upload OtherDomainCertificate

    Devices

    GetCertificate

    Masterdata Bulk Upload

    Machines

    UploadCertificate

    GenerateCSR

    Upload OtherDomainCertificate

    UploadCertificate

    Upload OtherDomainCertificate

    Packet Bulk Upload

    Centers

    Centers

    Packet Status

    Devices

    GenerateMasterKey

    User Zone Mapping

    Devices

    Pause/ Resume RID

    Machines

    How can we identify case-insensitive duplicates in the user_id column of the user_details table?

    Follow these steps:

    1. Log in to the master schema of the mosip_master database.

    2. Open a query tool.

    3. Execute the following SQL command in the query tool:

      Make sure to copy the output to a text file to manage the duplicate data effectively.

    How to deactivate/delete the case insensitive duplicates?

    1. Login in to the admin portal with a user having ZONAL_ADMIN role.

    2. On the left pane, click on Resources in the side-menu.

    3. Select User Center Mapping under Resources in the side-menu.

    4. Click Filter on the User Center Mapping page.

    5. Enter the user_id that was retrieved from the database and copied into the text file. After entering the user_id, click on the Apply button.

      • Now, on the User Center Mapping page, case insensitive duplicates of user_id would be displayed.

    6. Select the appropriate action (Delete/ Deactivate) on that entry.

    Managing Unequal Certificates

    First, we will compare the thumbprints in the key_alias tables' thumbprint column of the mentioned IDA and Keymanager DB.

    To check if the thumbprints are the same in both databases, we can follow these steps. For demonstration purposes, we will use 'mpartner-default-auth' as an example.

    Check through SQL commands

    In the results of the above query, if it is found that the thumbprints do not match, the next objective is to take the MOSIP signed certificate from keymanager and store it in IDA manually, so that they match.

    Here is a simple method to accomplish that task.

    SELECT lowerid, cnt from (SELECT count(*) as cnt,LOWER(id) as lowerid FROM master.user_detail group by lowerid) t1 where cnt>1 ;

    Based on the Center, choose the entry that can be deactivated/deleted.

  • Now click on the ellipsis of the selected entry.

  • A. Perform the required authentication at authmanager portal using the below swagger URL

    Sample request body:

    B. Get the certificate using following swagger URL

    In the app_id field use : PARTNER , in the ref_id field use : name of the partner whose cert thumbprints are mismatching such as mpartner-default-auth.

    Sample response:

    C. Now, reauthenticate in the same authmanager URL (note the different clientId , appId and corresponding secret key changes )

    https://api-internal.dev.mosip.net/v1/authmanager/swagger-ui/index.html?configUrl=/v1/authmanager/v3/api-docs/swagger-config#/authmanager/clientIdSecretKey

    Sample Request

    D. After getting the certificate through step B mentioned above, copy it and use it in the following POST request in the below swagger URL:

    https://api-internal.dev.mosip.net/idauthentication/v1/internal/swagger-ui/index.html?configUrl=/idauthentication/v1/internal/v3/api-docs/swagger-config#/keymanager/uploadCertificate

    In applicationId field use IDA and in the referenceId field use name of the partner whose cert thumbprints are mismatching such as mpartner-default-auth.

    Sample request

    After successfully completing this final step, we can proceed to the SQL cmd check mentioned at the beginning of this document and ensure that the thumbprints now match.

    Basic Troubleshooting

    1. Always ensure that you are using the correct base-url for your environment. In our case, it is dev.mosip.net and this should be used in all swagger links. Make sure to change it according to your requirement.

    2. If you encounter an error code such as "errorCode": "500", "message": "401 Unauthorized", please re-authenticate using the authmanager token provided and ensure that you are using the proper credentials.

    3. If you receive a 400 Bad request error, please resend your request with the correct time format and verify that your request JSON is in the specified format.

    4. If you encounter any other issues, please remember to post your queries on the .

    -- SQL commands to find the entry in both Keymanager  and IDA databases respectively. The cert_thumbprint column to be compared between both the entries.
    select * from key_alias where app_id='PARTNER' and ref_id = 'mpartner-default-auth' order by key_expire_dtimes desc limit 1;
    select * from key_alias where app_id='IDA' and ref_id = 'mpartner-default-auth' order by key_expire_dtimes desc limit 1;
    
    {
      {
      "id": "string",
      "version": "string",
      "requesttime": "2023-08-31T12:42:06.436Z",
      "metadata": {},
      "request": {
       "clientId": "mosip-regproc-client",
        "secretKey": "****************",
        "appId": "regproc"
      }
    }
    {
      "id": null,
      "version": null,
      "responsetime": "2023-08-31T12:44:28.804Z",
      "metadata": null,
      "response": {
        "certificate": "-----BEGIN CERTIFICATE-----\nMIIDjCCAqagAwgKoZIhvcNAQELBQAwdjELMAkGA1UE\nBhMCSU4xCzAJBgNVBAgMAktBMRIwEAYDVQQHDAlCQU5HQUxPUkUxDTALBgNVBAoM\nBElJVEIxIDAeBgNVBAsMF01PU0lQLVRFQ0gtQ0VOVEVSIChQTVMpMRUwEwYDVQQD\nDAx3d3cubW9zaXAuaW8wHhcNMjMwNzE4MDgwNDA4WhcNMjQwNzE3MDgwNDA4WjCB\ngzELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMRIwEAYDVQQHDAlCQU5HQUxPUkUx\nDTALBgNVBAoMBElJVEIxIDAeBgNVBAsMF01PU0lQLVRFQ0gtQ0VOVEVSIChJREEp\nMSIwIAYDVQQDDBlJREEtbXBhcnRuZXItZGVmYXVsdC1hdXRoMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtcHF46xabZVp3WtvULbMT/5BBDtzO5pR00nb\nhg+lJ/Tjxtdk6XnMWV7uDD3vsAAhyBw/DxD0DApb02o6Ocf8yMl5NSWIPzJPFSGw\nL6fMhJUuocE/Ng9fVQ4cO9gC/QLxVKTRncpGJeXh0WE6zcZO5t8Vkvy8hq5IIS44\nOECp9ynhx6OIhvEZaJmETmnVQoYZ6KhcPVNgb7otXimSOmuZ4XDhYSJXxE7CT7V+\n8Q/pZvQ4apjmPhqCB5dypEwkuFvDk1fkRJhyHgZhd8adsuj3mbRlK9O7tHFV0hV2\nYo93csKu7AqqU7H+H788CDkjmOX6LqaHk5LxPufsKOWp8DfhqQIDAQABo0IwQDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRDUl0RAF5gjF8Kqn0SQW8oTpWgcTAO\nBgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQELBQADggEBAA7dj1TqEHjZFMju9wt8\nDRI4sUMbf4YtPQQ65ACZ5K+mSBsKWwNQHXna8wn7JMOAFZFxNmz8TKFXAFBbVfYg\neqd2LPsgVpUTy35E3BwjTU90X0viS6o/2bNT0UAo5u1s9PG9YY7p/AUfr1x3kVow\nkplctHOwFmEF1S+Gzq2F1q7sFV41sePYNf5ZEDByc37M9Mdm7D4nddcnYFEbSOdT\nOOCVjt9yM50rE7OinFdBMlkkRiWazuxoXmR2ysumIf0szfNLuCsvJUZw68MUWY8g\nNuPEOUxOo3Es7uNkPTWbLPN5p2tMGNJ3LC4cp86e1aSCzNRFYeDcPbuvf966CY4M\n7X8=\n-----END CERTIFICATE-----\n",
        "certSignRequest": null,
        "issuedAt": "2023-07-18T08:04:08.000Z",
        "expiryAt": "2024-07-17T08:04:08.000Z",
        "timestamp": "2023-08-31T12:44:28.855Z"
      },
      "errors": null
    }
    {
      {
      "id": "string",
      "version": "string",
      "requesttime": "2023-08-31T12:42:06.436Z",
      "metadata": {},
      "request": {
        "clientId": "mosip-ida-client",
        "secretKey": "************",
        "appId": "ida"
      }
    }
    {
      "id": "string",
      "version": "string",
      "requesttime": "2023-08-31T12:46:55.317Z",
      "metadata": {},
      "request": {
        "applicationId": "IDA",
        "referenceId": "mpartner-default-auth",
        "certificateData": "certificate from step-B"
      }
    }
    MOSIP Community

    Registration Client Upgrade

    The Registration Client Docker serves as a registration client zip downloader and upgrade server. The Nginx server within the Registration Client Docker container provides all necessary artifacts and resources during the upgrade process.

    Patch updates:

    • When the registration client is launched, it downloads the manifest file from the upgrade server if the machine is online. Otherwise, it uses the local manifest file.

    • The client compares the checksum of each JAR file in the lib directory with the checksum stored in the manifest file. If there's a mismatch, the client considers the file invalid and deletes it before downloading it from the client upgrade server.

    • A checksum mismatch may be intentional for the rollout of hotfixes in the libraries used by the registration client or in the registration-client and registration-service module.

    • Patch updates do not support the upgrade of local Derby DB.

    Assumption:

    • No major or minor version changes should occur for registration-client and registration-services modules.

    • Registration clients must be online to receive patch updates.

    To roll out patches:

    • Rebuild the Registration Client Dockerfile and publish it with the same version.

    • Restart the registration client pod in Rancher.

    For slow connections or connection failures:

    • If the client fails to download the manifest file when the machine is online, the registration client application will exit and report a build status check failure in the pre-loader screen.

    • If the latest manifest file is successfully downloaded but fails to download all the patches, the registration client application will exit and report a patch download failure.

    • In both cases, the operator/supervisor must restart the registration client application with a stable network connection. Upon restart, the client application will repeat the check from the server and continue the patch update.

    Patch updates can include updates to existing libraries and the addition of new files. However, they are only applied to files in the lib directory.

    Note: Deleting the registration-client.jar or registration-services.jar is not recoverable.

    Version upgrade

    This procedure entails upgrading from one version of the software to the next iteration.

    Additionally, this may involve upgrading local derby databases.

    Upon each launch of the registration client, the client retrieves the maven-metadata.xml file from the client upgrade server. The version specified in the local manifest file is then compared to the initial version element found in the maven-metadata.xml.

    Should the version values differ, the client recognizes it as an available upgrade to a new version.

    Above is the sample content of maven-metadata.xml.

    The version upgrades are not performed automatically and must be initiated by the operator or supervisors. The process for the version upgrade can be outlined as follows:

    1. Backup the database, libraries, binary, and manifest files and folders.

    2. Download the latest JAR files and manifest files from the upgrade server to the local machine.

    3. Prompt the operator/supervisor to restart the registration client with the upgraded JAR files.

    4. Upon restart, the application executes the database upgrade scripts.

    From version 1.1.5.5 and above, the registration client now has the ability to upgrade directly from one version to another without going through the versions in between.

    To enable this upgrade process, a new configuration has been introduced. This configuration is required for the upgrade to any higher version. The configuration key that needs to be set is mosip.registration.verion.upgrade.version-mappings.

    The version-mappings configuration specifies the list of released versions of the registration client, their respective release order, and the database scripts folder name.

    For example, to upgrade from version 1.1.4 to version 1.1.5.5, the configuration should be specified as follows:

    This configuration needs to be specified in the spring.properties file of the registration-services.

    During the registration client upgrade process, the application retrieves the above configuration and initiates the database upgrade based on the specified list of versions.

    The upgrade progresses according to the releaseOrder and executes the necessary database scripts based on the dbVersion value.

    How to roll out version upgrades?

    In rancher,

    • Delete the existing version helm deployment of the registration client.

    • Deploy the new version of the registration client helm chart.

    Example:

    Let us assume that the registration-client version 1.1.5.5 is currently running, and we have to upgrade to version 1.2.0.1 version.

    What happens after deploying the 1.2.0.1 version registration client in rancher?

    Registration clients downloading the maven-metadata.xml from the upgrade server will be aware of the new version availability.

    content:

    Based on the first version available in the maven-metadata.xml, registration client will next download the MANIFEST.MF.

    After the successful download of the manifest file, the registration client will start the download of all the new files, updates the existing file if the hash is mismatched, and deletes the unused files from the lib directory.

    After completing the download, operator/supervisor will be prompted to restart the registration client.

    Next restart, will start the registration client as version 1.2.0.1 and starts the DB upgrade script execution if present based on the version-mappings configuration available.

    The status of the DB script execution is printed on the preloader screen and also logged into registration.log.

    Backups and rollbacks

    During the version upgrade process, we create backups of the manifest, db, lib, and bin folders in the designated backup directory. Once the upgrade is completed successfully, the backups are cleared. However, if the upgrade fails, we only roll back the changes made to the database.

    In the event that the registration client application gets stuck during the upgrade due to errors or failures in the background, it is necessary for the operator or supervisor to manually roll back to the previous version of the registration client.

    Below are the steps for manually rolling back:

    1.1.4.* to 1.1.5.5 / 1.1.4.* to 1.2.0.*

    1. Close the registration client application.

    2. Delete the db and .mosipkeys folders in the reg-client working directory.

    3. Navigate to the designated backup directory, where you will find a folder named after the previous version and the timestamp when it was created. For example, "1.1.4.4_2023-05-30 13-00-27.238Z".

    1.1.5.5 to 1.2.0.*

    1. Close the registration client application.

    2. Delete the db folder, if it exists, in the registration client working directory.

    3. Navigate to the designated backup directory, where you will find a folder named after the previous version and the timestamp when it was created. For example, "1.1.5.5_2023-05-30 13-00-27.238Z".

    By following these steps, the registration client application will be successfully rolled back to its previous version.

    Guide to Reprocess Packets Manually

    This document provides instructions on manually reprocessing all packets from the beginning after migration. The 1.2.0.1 release introduces multiple new stages and a new tagging mechanism. All packets that have not been processed before migration will be reprocessed to ensure they go through the new stages.

    To facilitate packet reprocessing, MOSIP provides a Python script. This approach involves fetching all RIDs from the database using a query and processing them from the beginning. Please consult the documentation for instructions on setting up and running the reprocessing script. The query can be found in the config.py file.

    Note: This script is highly customizable, and each country can modify it according to their specific requirements. This document outlines the general approach for reprocessing packets. If a country has special needs, the query will need to be adjusted accordingly.

    The following command should be used to reprocess packets:

    $ ./reprocess.py --db

    It is important to first reprocess just one packet after migration to ensure that all stages are functioning correctly. This can be accomplished by setting the limit to 1. Please refer to the explanation below for instructions on changing the limit.

    APPROACH 1

    DEFAULT QUERY

    The default query reprocesses all packets that were not "PROCESSED" or "REJECTED" before migration. The query uses a limit of 1000 packets and a 1-second delay between each packet. This means that when the script is executed, it will reprocess 1000 packets one by one with a 1-second interval. These settings can be adjusted if necessary in the file:

    This query also selects packets that are one day old (latest_trn_dtimes < (SELECT NOW() - INTERVAL '1 DAY')). This ensures that the script does not reprocess the same packets repeatedly. The time frame should be adjusted according to the system downtime caused by migration.

    A country can determine the number of packets to be reprocessed in each batch and set the limit accordingly. The script should be executed the necessary number of times. For example, if there are 10000 pending packets and the limit is set to 1000, the script should be run 10 times.

    APPROACH 2

    This approach is designed for countries where packets are not directly routed from the securezone. In cases where the country has disabled routing from the securezone by setting the below property to false, the securezone notification stage should be disregarded. This is because any packets that have not moved beyond the securezone will be taken care of by the automated reprocessor.

    Property: securezone.routing.enabled=false

    This approach is similar to APPROACH 1 with one key difference. It utilizes the latest_trn_type_code in the query to specifically target packets that are stuck in these stages for reprocessing. It will disregard packets stuck in other stages.

    Note: If any custom stage is introduced by the country, the latest_trn_type_code should be added to the query.

    Query:

    query="SELECT reg_id, process, workflow_instance_id FROM registration WHERE latest_trn_status_code IN ('SUCCESS', 'REPROCESS', 'IN_PROGRESS') AND reg_process_retry_count <= 500 AND latest_trn_dtimes < (SELECT NOW() - INTERVAL '1 DAY') AND status_code NOT IN ('PROCESSED', 'FAILED', 'REJECTED') LIMIT 1000"
    config.py
    LIMIT 1000 # Can be changed as needed.
    latest_trn_dtimes < (SELECT NOW() - INTERVAL '1 DAY') # Can be changed based on the time difference during migration.
    delay = 1 # Seconds
    query="select reg_id,process,workflow_instance_id from registration where latest_trn_status_code in ('SUCCESS', 'REPROCESS', 'IN_PROGRESS') and reg_process_retry_count<=500 and latest_trn_dtimes < (SELECT NOW() - INTERVAL '1 DAY') and status_code NOT IN ('PROCESSED', 'FAILED', 'REJECTED')
    and latest_trn_type_code in ('UPLOAD_PACKET', 'VALIDATE_PACKET', 'QUALITY_CHECK', 'OSI_VALIDATE', 'BIOMETRIC_AUTHENTICATION', 'DEMOGRAPHIC_VERIFICATION', 'BIOGRAPHIC_VERIFICATION', 'MANUAL_VERIFICATION', 'UIN_GENERATOR') LIMIT 1000"
     

    If the execution of the upgrade scripts is successful, the registration client starts and the version upgrade process is considered complete.

  • In the event of failure, rollback scripts for the database are executed and the registration client application exits. The operator/supervisor must rerun the registration client to initiate the execution of the upgrade database scripts.

  • Once the version upgrade process is successfully completed, the backup folder is removed and the registration client is fully functional for use.

  • Copy all the files and folders (lib, bin, MANIFEST.MF) from the backup to the registration client working directory, except for the .mosipkeys folder.

  • Copy the .mosipkeys folder from the backup to the home directory of the current user.

  • Launch the registration client application again.

  • Copy all the files and folders (lib, bin, MANIFEST.MF) from the backup to the registration client working directory.
  • Launch the registration client application again.

  • On patch download, the pre-loader screen displays Restart required
    Successful restart of the Registration Client application
    <metadata>
    <groupId>io.mosip.registration</groupId>
    <artifactId>registration-services</artifactId>
    <versioning>
    <versions>
    <version>1.2.0.1</version>
    </versions>
    <lastUpdated>20200729125958</lastUpdated>
    </versioning>
    </metadata>
    mosip.registration.verion.upgrade.version-mappings={ "1.1.4":{ "dbVersion":"1.1.4", "releaseOrder":1}, "1.1.5":{ "dbVersion":"1.1.5", "releaseOrder":2}, "1.1.5.5":{ "dbVersion":"1.1.5.5", "releaseOrder":3} }
    <metadata>
    <groupId>io.mosip.registration</groupId>
    <artifactId>registration-services</artifactId>
    <versioning>
    <versions>
    <version>1.2.0.1</version>
    </versions>
    <lastUpdated>20200729125958</lastUpdated>
    </versioning>
    </metadata>

    Changes in Role Management based on Client IDs

    Partner Management Services

    In previous versions (1.1.5.x) of our system, we utilized the mosip-partner-client for Partner Management Services (PMS). However, starting from version 1.2.0.1 onwards, we have implemented the use of mosip-pms-client instead. This transition has led to updates in service account roles, client scopes, and client configurations.

    Please find below the details of the changes made to service account roles and client scopes.

    Service account roles for Partner-Management-Services

    mosip-partner-client (1.1.5.x)
    mosip-pms-client (1.2.0.1)

    Client Scopes for Partner-Management-Services:

    mosip-partner-client (1.1.5.x)
    mosip-pms-client (1.2.0.1)

    Admin-Services

    In version 1.1.5.x, the mosip-admin-client was utilized for administrative services. We are also continuing to utilize the same client in version 1.2.0.1. While there have been modifications to the service account roles, the Client scopes have remained unchanged. Please find below the updated service account role adjustments. Additionally, it is worth noting that MOSIP Commons is also utilizing this client.

    Service account roles for Admin-Services:

    mosip-admin-client (1.1.5.x)
    mosip-admin-client (1.2.0.1)

    Client scopes are the same for mosip-admin-client in 1.2.0.1 & 1.1.5.1

    • email

    • profile

    • roles

    • web-origins

    Pre-registration

    In version 1.1.5.x, we utilized the 'mosip-prereg-client' for Pre-Registration. This client is also utilized in version 1.2.0.1. There have been modifications in the service account roles, while the client scopes have remained unchanged. Please find below the updated service account roles.

    Service account roles for Pre-Registration:

    mosip-prereg-client in 1.1.5.x
    mosip-prereg-client in 1.2.0.1

    Note: Prior to proceeding with the upgrade, please ensure that the INDIVIDUAL role has been removed.

    Client scopes are the same for mosip-prereg-client in 1.2.0.1 & 1.1.5.1

    • email

    • profile

    • roles

    • web-origins

    ID Authentication

    In the previous version 1.1.5.x, the mosip-ida-client module was responsible for handling ID authentication. However, starting from version 1.2.0.1, we have switched to using mpartner-default-auth for this purpose. This transition has brought about several changes, including modifications to service account roles, client scopes, and client configurations. Below is an overview of the changes in service account roles and client scopes.

    Service account roles for id-authentication:

    mosip-ida-client in (1.1.5.x)
    mpartner-default-auth (1.2.0.1)

    Client Scopes for id-authentication:

    mosip-ida-client (1.1.5.x)
    mpartner-default-auth (1.2.0.1)

    Digital-card-service

    In the previous version, 1.1.5.x, we did not employ any clients for our digital card service. However, in the latest version, 1.2.0.1, we have implemented the use of the mpartner-default-digitalcard client. Please find below the service account roles and client scopes associated with the mpartner-default-digitalcard client.

    Service account roles assigned to _mpartner-default-digitalcard_** in 1.2.0.1**

    • CREATE_SHARE

    • CREDENTIAL_REQUEST

    • default_roles_mosip

    • PRINT_PARTNER

    Client scopes assigned to _mpartner-default-digitalcard_** in 1.2.0.1**

    • email

    • profile

    • roles

    • web-origins

    Print

    In version 1.1.5.x, we do not employ any clients for printing. However, beginning from version 1.2.0.1, we utilize the mpartner-default-print client. Please find below the service account roles and client scopes associated with the mpartner-default-print client.

    Service account roles assigned to _mpartner-default-print_** in 1.2.0.1**

    • CREATE_SHARE

    • default_roles_mosip

    • PUBLISH_CREDENTIAL_STATUS_UPDTAE_GENERAL

    • SUBSCRIBE_ CREDENTIAL_ISSUED_INDIVIDUAL

    Client scopes assigned to _mpartner-default-print_** in 1.2.0.1**

    • email

    • profile

    • roles

    • web-origins

    ID Repository

    In version 1.1.5.x, we utilized the mosip-regproc-client for id-repository. Starting from version 1.2.0.1, we have transitioned to using mosip-idrepo-client. This switch has led to modifications in service account roles, client scopes, and client settings. Below are the details of the changes in service account roles and client scopes.

    Client Scopes for id-repository:

    mosip-regproc-client (1.1.5.x)
    mosip-idrepo-client (1.2.0.1)

    Service account roles for id-repository:

    mosip-regproc-client (1.1.5.x)
    mosip-idrepo-client (1.2.0.1)

    Resident Services

    In version 1.1.5.x, we utilized the mosip-resident-client for Resident Services. This client is also employed in version 1.2.0.1. Although there were modifications in service account roles, the client scopes remain unchanged. Below the details of the alterations made in service account roles.

    Service account roles for Resident-Services:

    mosip-resident-client (1.1.5.x)
    mosip-resident-client (1.2.0.1)

    Client Scopes for Resident-Services:

    mosip-resident -client (1.1.5.x)
    mosip- resident -client (1.2.0.1)

    Compliance-Tool-Kit

    In previous iterations (1.1.5.x) of our system, we did not employ any clients for the compliance toolkit. However, beginning with version 1.2.0.1, we have implemented the use of mosip_toolkit_client. The following information outlines the service account roles and client scopes associated with mosip_toolkit_client.

    Service account roles assigned to _mosip_toolkit_client_** in 1.2.0.1**

    • default_roles_mosip

    Client scopes assigned to _mosip_toolkit_client_** in 1.2.0.1**

    • email

    • profile

    • roles

    • web-origins

    Changes in Camel Route

    This document outlines the changes made to the camel route file following the migration.

    1. In the 1.2.0.1 release, there is a default camel route file for each registration type, without any differentiation between the dmz and mz concepts. This is due to the transition from V2 to V3 deployment, which is mandatory.

    1. Workflow commands are implemented to handle the isValid and internal error, with the primary purpose of making important decisions regarding the overall workflow state. Previously, these decisions were made within each individual stage, but now we are transferring them to the camel route, allowing for easier customization by different countries. This change grants more flexibility in controlling the workflow and reduces the reliance on specific stages for decision-making. It is mandatory for the registration table to be updated with packet processing results in each stage, whether successful or failed, excluding the status code. The example below demonstrates one of the workflow commands utilized in routes.

    PMS_ADMIN

    PMS_USER

    PUBLISH_APIKEY_APPROVED_GENERAL

    PUBLISH_APIKEY_UPDATED _GENERAL

    PUBLISH_CA_CERTIFICATE_UPLOADED_GENERAL

    PUBLISH_MISP_LICENSE_GENERATED_GENERAL

    PUBLISH_MISP_LICENSE_UPDATED_GENERAL

    PUBLISH_OIDC_CLIENT_CREATED_GENERAL

    PUBLISH_OIDC_CLIENT_UPDATED _GENERAL

    PUBLISH_PARTNER _UPDATED _GENERAL

    PUBLISH_POLICY_UPDATED _GENERAL

    REGISTRATION_PROCESSOR

    SUBSCRIBE_CA_CERTIFICATE_UPLOADED_GENERAL

    ZONAL_ADMIN

    send_binding_otp

    update_oidc_client

    uploaded_certificate

    wallet_binding

    web_origins

    PUBLISH_MOSIP_HOTLIST_GENERAL

    uma_authorization

    PUBLISH_CREDENTIAL_STATUS_UPDATE_GENERAL

  • SUBSCRIBE_ CREDENTIAL_ISSUED_INDIVIDUAL

  • SUBSCRIBE_IDENTITY_CREATED_GENERAL

  • SUBSCRIBE_IDENTITY_UPDATED _GENERAL

  • offline access

    CREATE_SHARE

    REGISTRATION_PROCESSOR

    default_roles_mosip

    uma_authorization

    DEVICE_PROVIDER

    PARTNER

    PARTNER_ADMIN

    email

    add_oidc_client

    profile

    email

    roles

    get_certificate

    web-origins

    profile

    roles

    MASTERDATA_ADMIN

    Default-roles-mosip

    offline_access

    ZONAL_ADMIN

    uma_authorization

    offline-access

    PUBLISH_MASTERDATA_IDAUTHENTICATION_TEMPLATES_GENERAL

    PUBLISH_MASTERDATA_TITLES_GENERAL

    • INDIVIDUAL

    • offline_access

    • PRE_REGISTRATION_ADMIN

    • PREREG

    • REGISTRATION_PROCESSOR

    • uma_authorization

    • default_roles_mosip

    • PRE_REGISTRATION_ADMIN

    • PREREG

    • REGISTRATION_PROCESSOR

    • AUTH

    • AUTH_PARTNER

    • ID_AUTHENTICATION

    • offline_access

    • uma_authorization

    • CREDENTIAL_REQUEST

    • default_roles_mosip

    • ID_AUTHENTICATION

    • offline_access

    • PUBLISH_ANONYMOUS_PROFILE_GENERAL

    • PUBLISH_AUTH_TYPE_STATUS_UPDATE_ACK_GENERAL

    • PUBLISH_AUTHENTICATION_TRANSACTION_STATUS_GENERAL

    • PUBLISH_CREDENTIAL_STATUS_UPDATE_GENERAL

    • PUBLISH_IDA_FRAUD_ANALYTICS_GENERAL

    • SUBSCRIBE_ACTIVATE_ID_INDIVIDUAL

    • SUBSCRIBE_APIKEY _APPROVED_GENERAL

    • SUBSCRIBE_APIKEY _UPDATED _GENERAL

    • SUBSCRIBE_AUTH_TYPE_STATUS_UPDATE_ACK_GENERAL

    • SUBSCRIBE_AUTH_TYPE_STATUS_UPDATE_INDIVIDUAL

    • SUBSCRIBE_CA_CERTIFICATE_UPLOADED_GENERAL

    • SUBSCRIBE_CREDENTIAL_ISSUED_INDIVIDUAL

    • SUBSCRIBE_DEACTIVATE_ID_INDIVIDUAL

    • SUBSCRIBE_MASTERDATA_IDAUTHENTICATION_TEMPLATES_GENERAL

    • SUBSCRIBE_MASTERDATA_TITLES_GENERAL

    • SUBSCRIBE_MISP_LICENSE_GENERATED_GENERAL

    • SUBSCRIBE_MISP_LICENSE_UPDATED_GENERAL

    • SUBSCRIBE_MOSIP_HOTLIST_GENERAL

    • SUBSCRIBE_OIDC_CLIENT_CREATED_GENERAL

    • SUBSCRIBE_OIDC_CLIENT_UPDATED_GENERAL

    • SUBSCRIBE_PARTNER_UPDATED_GENERAL

    • SUBSCRIBE_POLICY _UPDATED_GENERAL

    • SUBSCRIBE_REMOVE _ID_INDIVIDUAL

    • uma_authorization

    • email

    • profile

    • roles

    • web-origins

    • add_oidc_client

    • email

    • profile

    • roles

    • update_oidc_client

    • web-origins

    • email

    • profile

    • roles

    • web-origins

    • email

    • profile

    • roles

    • web-origins

    • ABIS_PARTNER

    • CENTRAL_ADMIN

    • CENTRAL_APPROVER

    • CREDENTIAL_INSURANCE

    • CREDETIAL_PARTNER

    • Default

    • DEVICE_PROVIDER

    • DIGITAL_CARD

    • FTM_PROVIDER

    • GLOBAL_ADMIN

    • INDIVIDUAL

    • KEY_MAKER

    • MASTERDATA_ADMIN

    • MISP

    • MISP_PARTNER

    • ONLINE_VERIFICATION_PARTNER

    • POLICYMANAGER

    • PRE_REGISTRATION

    • PRE_REGISTRATION_ADMIN

    • PREREG

    • REGISTRATION_ADMIN

    • REGISTRATION_OFFICER

    • REGISTRATION_OPERATOR

    • REGISTRATION_SUPERVISOR

    • ZONAL_ADMIN

    • ZONAL_APPROVER

    • default_roles_mosip

    • ID_REPOSITORY

    • offline_access

    • PUBLISH_ACTIVATE_ID_ALL_INDIVIDUAL

    • PUBLISH_AUTH_TYPE_STATUS_UPDATE_ALL_INDIVIDUAL

    • PUBLISH_AUTHENTICATION_TRANSACTION_STATUS_GENERAL

    • PUBLISH_DEACTIVATE_ID_ALL_INDIVIDUAL

    • PUBLISH_IDENTITY_CREATED_GENERAL

    • PUBLISH_IDENTITY_UPDATED _GENERAL

    • PUBLISH_REMOVE _ID_ALL_INDIVIDUAL

    • PUBLISH_VID_CRED_STATUS_UPDATE_GENERAL

    • SUBSCRIBE_VID_CRED_STATUS_UPDATE_GENERAL

    • uma_authorization

    • CREDENTIAL_ISSUANCE

    • CREDENTIAL_REQUEST

    • offline_access

    • RESIDENT

    • uma_authorization

    • CREDENTIAL_REQUEST

    • default_roles_mosip

    • offline_access

    • RESIDENT

    • SUBSCRIBE_AUTH_TYPE_STATUS_UPDATE_ACK_GENERAL

    • SUBSCRIBE_AUTHENTICATION_TRANSACTION_STATUS_GENERAL

    • SUBSCRIBE_CREDENTIAL_STATUS_UPDATE_GENERAL

    • uma_authorization

    • email

    • profile

    • roles

    • web-origins

    • email

    • ida_token

    • individual_id

    • profile

    • roles

    • web-origins

    <to uri="workflow-cmd://complete-as-failed" />

    Below are the workflow commands:

    Commands
    Usage

    workflow-cmd://complete-as-processed

    The status code will be updated to "PROCESSED" and a websub event will be sent to the notification service for notification purposes. Additionally, it will check if there is an additional request ID present. If so, a tag will be created with a specific registration type and flow status set as "PROCESSED". Furthermore, the latest transaction status code of the main flow will be updated to "REPROCESS" in order to resume processing. Lastly, notifications will be added for failed, rejected, processed, and pause-and-request-additional-info records within the workflow.

    workflow-cmd://complete-as-rejected

    The status code will be updated to "REJECTED" and a websub event will be sent to the notification service for notification. Additionally, it will verify if there are any additional request IDs present. If so, a tag will be created for the specific registration type with a flow status of "REJECTED", and the processing of the main flow will be resumed.

    workflow-cmd://complete-as-failed

    The status code will be updated to FAILED, and a websub event will be sent to the notification service for notifying relevant parties. Additionally, if there is an additional request ID present, a tag will be created with the corresponding registration type and flow status as FAILED. Following this, the processing of the main flow will resume.

    workflow-cmd://mark-as-reprocess

    It will update status code to REPROCESS. It will create tag with particular reg type with flow status as FAILED

    workflow-cmd://anonymous-profile

    To store packet details in anonymous profile table

    1. The OSI validator stage is divided into four stages: operator-validator stage, supervisor-validator stage, introducer-validator stage, and cmd-validator stage. If a packet is determined to be valid, it will be directed from the packet classifier to the cmd-validator stage. This step is mandatory.

    1.1.5.5

    1.2.0.1

    1. Tags will be created in the packet classifier stage. Depending on the tags, the packet will be transferred from the command validator stage to either the supervisor or operator stage. In order to introduce validation and check tags, packets will be moved accordingly. The availability of tags allows us to modify camel routes. (Mandatory)

    1. The quality checker stage has been updated to the quality classifier stage. Packets are now transferred from the supervisor, operator, and introducer stages to the quality classifier stage, depending on the designated route. This change is mandatory.

    2. Instead of manual verification in section 1.1.5.5, it is now replaced with manual adjudication in section 1.2.0.1. Additionally, a new route has been specified from the manual adjudication stage to the UIN generator stage in the XML route. In cases where duplicates are identified, the manual adjudication stage is added to the route after the demo dedupe and bio dedupe processes. This change is mandatory.

    1.1.5.5

    1.2.0.1

    1. New route has been added from UIN generator stage to biometric-extraction stage. This stage fetches biometric extraction policy from PMS and sends to ID Repository (mandatory).

      1. New route has been added from biometric-extraction stage to Finalization stage. This stage publishes draft version to ID Repository DB (Mandatory).

    2. New route has been added from Finalization stage to Printing stage. This stage creates Credential Request for printing systems (mandatory).

    1. Based on Tags related to quality score, the packets will move form quality classifier to workflow-cmd://pause-and-request-additional-info or demodedupe (optional).

    1.1.5.5

    1.2.0.1

    1. We can use JSON path also and update the conditions. If we want to update route based on isValid and internalError then follow the below syntax (optional)

    If we wish to use check condition based on address, then follow the below syntax (optional) ,

    If we wish to use the check condition based on Tags, then follow as below (optional):

    If we want to set the property in camel route, then follow the steps as below. .

    This property is used for PAUSE and RESUME feature. We cant set application properties here (optional)

    1. As a part of the 1.2.0.1 update, if no biometric data is available, the system will proceed to the verification stage. This stage is only relevant in cases where the required biometrics are missing from the packet. The system will send the applicant's demographic and biometric information to the external Verification System (VS) through a queue and Datashare. Upon receiving the decision from the VS, the system will proceed accordingly and forward the packets. In case of rejection, the applicant will be notified (optional).

    New route is specified from verification to UIN generator stage route.xml

    1. Now securezone-notification stage can consume from securezone-notification-bus-in address which is from packet receiver stage. We can even use, http://regproc-group2.regproc/registrationprocessor/v1/securezone/notification instead of http://mz.ingress:30080/registrationprocessor/v1/securezone/notification (optional)

      1.1.5.5

      1.2.0.1

    ~~~

    13KB
    registration-processor-camel-routes-new-mz.xml
    Open
    1KB
    registration-processor-camel-routes-new-dmz (1).xml
    Open
    26KB
    registration-processor-camel-routes-new-default (1).xml
    Open
    <route id="operator-validator-->supervisor-validator new route">
       <from uri="eventbus://operator-validator-new-bus-out" />
       <log message="operator-validator-->supervisor-validator/introducer-validator/demo-dedupe new route ${bodyAs(String)}" />
       <choice>
          <when>
             <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == true)]</jsonpath>
             <to uri="workflow-cmd://complete-as-failed" />
             <to uri="workflow-cmd://anonymous-profile" />
          </when>
          <when>
             <jsonpath>$.[?(@['isValid'] == true &amp;&amp; @['internalError'] == true)]</jsonpath>
             <to uri="workflow-cmd://mark-as-reprocess" />
          </when>
          <when>
             <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == false)]</jsonpath>
             <to uri="workflow-cmd://complete-as-failed" />
             <to uri="workflow-cmd://anonymous-profile" />
          </when>
          <when>
             <jsonpath suppressExceptions="true">$.[?(@['tags']['META_INFO-OPERATIONS_DATA-supervisorId'] != '' &amp;&amp; @['tags']['META_INFO-OPERATIONS_DATA-supervisorId'] != '--TAG_VALUE_NOT_AVAILABLE--')]</jsonpath>
             <to uri="eventbus://supervisor-validator-bus-in" />
          </when>
          <when>
             <jsonpath suppressExceptions="true">$.[?(@['tags']['AGE_GROUP'] == 'INFANT' || @['tags']['AGE_GROUP'] == 'MINOR' || @['tags']['INTRODUCER_AVAILABILITY'] == 'true')]</jsonpath>
             <to uri="eventbus://introducer-validator-bus-in" />
          </when>
          <otherwise>
             <to uri="eventbus://quality-classifier-bus-in" />
          </otherwise>
       </choice>
    </route>
     <route id="uin-generation route-->biometric-extraction-stage new route">
       <from uri="eventbus://uin-generator-new-bus-out" />
       <log message="uin-generation-->biometric-extraction-stage route ${bodyAs(String)}" />
       <choice>
          <when>
             <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == true)]</jsonpath>
             <to uri="workflow-cmd://complete-as-failed" />
             <to uri="workflow-cmd://anonymous-profile" />
          </when>
          <when>
             <jsonpath>$.[?(@['isValid'] == true &amp;&amp; @['internalError'] == true)]</jsonpath>
             <to uri="workflow-cmd://mark-as-reprocess" />
          </when>
          <when>
             <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == false)]</jsonpath>
             <to uri="workflow-cmd://complete-as-failed" />
             <to uri="workflow-cmd://anonymous-profile" />
          </when>
          <otherwise>
             <to uri="eventbus://biometric-extraction-bus-in" />
             <to uri="workflow-cmd://anonymous-profile" />
          </otherwise>
       </choice>
    </route>
    
    <route id="biometric-extraction route-->finalization-stage new route">
       <from uri="eventbus://biometric-extraction-new-bus-out" />
       <log message="biometric-extraction-->finalization-stage route ${bodyAs(String)}" />
       <choice>
          <when>
             <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == true)]</jsonpath>
             <to uri="workflow-cmd://complete-as-failed" />
             <to uri="workflow-cmd://anonymous-profile" />
          </when>
          <when>
             <jsonpath>$.[?(@['isValid'] == true &amp;&amp; @['internalError'] == true)]</jsonpath>
             <to uri="workflow-cmd://mark-as-reprocess" />
          </when>
          <when>
             <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == false)]</jsonpath>
             <to uri="workflow-cmd://complete-as-failed" />
             <to uri="workflow-cmd://anonymous-profile" />
          </when>
          <otherwise>
             <to uri="eventbus://finalization-bus-in" />
          </otherwise>
       </choice>
    </route>
    <route id="packet-reciever-->securezone-notification new route">
        <from uri="eventbus:packet-receiver-new-bus-out" />
        <log
            message="packet-reciever-->packet-uploader new ${bodyAs(String)}" />
        <choice>
            <when>
                <simple>${bodyAs(String)} contains '"isValid":true'</simple>
                <process ref="tokenGenerationProcessor"/>
                <setHeader headerName="CamelHttpMethod">
                    <constant>POST</constant>
                </setHeader>
                <setHeader headerName="Content-Type">
                    <constant>application/json</constant>
                </setHeader>
                <setHeader headerName="Cookie">
                    <simple>${header.Cookie}</simple>
                </setHeader>
                <setBody>
                    <simple>${bodyAs(String)}</simple>
                </setBody>
                <to uri="http://mz.ingress:30080/registrationprocessor/v1/securezone/notification" />
            </when>
            <when>
                <simple>${bodyAs(String)} contains '"internalError":true'</simple>
                <to uri="eventbus:retry-bus-in" />
            </when>
            <otherwise>
                <to uri="eventbus:error-bus-in" />
            </otherwise>
        </choice>
    </route>
    <route id="packet-receiver-->securezone-notification new route">
      <from uri="eventbus://packet-receiver-new-bus-out" />
      <log message="packet-receiver-->securezone-notification new ${bodyAs(String)}" />
      <choice>
         <when>
            <jsonpath>$.[?(@['isValid'] == false && @['internalError'] == true)]</jsonpath>
            <to uri="workflow-cmd://complete-as-failed" />
         </when>
         <when>
            <jsonpath>$.[?(@['isValid'] == true && @['internalError'] == true)]</jsonpath>
            <to uri="workflow-cmd://mark-as-reprocess" />
         </when>
         <when>
            <jsonpath>$.[?(@['isValid'] == false && @['internalError'] == false)]</jsonpath>
            <to uri="workflow-cmd://complete-as-failed" />
         </when>
         <otherwise>
            <to uri="eventbus://securezone-notification-bus-in" />
         </otherwise>
      </choice>
    <route id="packet-classifier-->quality-checker new route">
            <from uri="eventbus:packet-classifier-new-bus-out" />
            <log
                message="packet-classifier-->quality-checker new route ${bodyAs(String)}" />
            <choice>
                <when>
                    <simple>${bodyAs(String)} contains '"isValid":true'</simple>
                    <to uri="eventbus:quality-checker-bus-in" />
                </when>
                <when>
                    <simple>${bodyAs(String)} contains '"isValid":false' and ${bodyAs(String)} contains '"internalError":false'</simple>
                    <to uri="eventbus:message-sender-bus-in" />
                </when>
                <when>
                    <simple>${bodyAs(String)} contains '"internalError":true'</simple>
                    <to uri="eventbus:retry-bus-in" />
                </when>
                <otherwise>
                    <to uri="eventbus:error-bus-in" />
                </otherwise>
            </choice>
        </route>
    <route id="packet-classifier-->cmd-validator new route">
         <from uri="eventbus://packet-classifier-new-bus-out" />
         <log message="packet-classifier-->quality-classifier new route ${bodyAs(String)}" />
         <choice>
            <when>
               <jsonpath>$.[?(@['isValid'] == false && @['internalError'] == true)]</jsonpath>
               <to uri="workflow-cmd://complete-as-failed" />
               <to uri="workflow-cmd://anonymous-profile" />
            </when>
            <when>
               <jsonpath>$.[?(@['isValid'] == true && @['internalError'] == true)]</jsonpath>
               <to uri="workflow-cmd://mark-as-reprocess" />
            </when>
            <when>
               <jsonpath>$.[?(@['isValid'] == false && @['internalError'] == false)]</jsonpath>
               <to uri="workflow-cmd://complete-as-failed" />
               <to uri="workflow-cmd://anonymous-profile" />
            </when>
            <otherwise>
               <to uri="eventbus://c-m-d-validator-bus-in" />
            </otherwise>
         </choice>
      </route>
          <route id="cmd-validator-->operator-validator new route">
          <from uri="eventbus://c-m-d-validator-new-bus-out" />
          <log message="cmd-validator-->operator-validator/supervisor-validator new route ${bodyAs(String)}" />
          <choice>
             <when>
                <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == true &amp;&amp; @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://mark-as-reprocess" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == false)]</jsonpath>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <when>
                <jsonpath suppressExceptions="true">$.[?(@['tags']['META_INFO-OPERATIONS_DATA-officerId'] != '' &amp;&amp; @['tags']['META_INFO-OPERATIONS_DATA-officerId'] != '--TAG_VALUE_NOT_AVAILABLE--')]</jsonpath>
                <to uri="eventbus://operator-validator-bus-in" />
             </when>
             <when>
                <jsonpath suppressExceptions="true">$.[?(@['tags']['META_INFO-OPERATIONS_DATA-supervisorId'] != '' &amp;&amp; @['tags']['META_INFO-OPERATIONS_DATA-supervisorId'] != '--TAG_VALUE_NOT_AVAILABLE--')]</jsonpath>
                <to uri="eventbus://supervisor-validator-bus-in" />
             </when>
             <otherwise>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </otherwise>
          </choice>
       </route>
    <route id="manual-verification-->uin-generation new route">
            <from uri="eventbus:manual-verification-new-bus-out" />
            <log
                message="manual-verification-->uin-generation new route ${bodyAs(String)}" />
            <choice>
                <when>
                    <simple>${bodyAs(String)} contains '"isValid":true'</simple>
                    <to uri="eventbus:uin-generator-bus-in" />
                </when>
                <when>
                    <simple>${bodyAs(String)} contains '"isValid":false' and ${bodyAs(String)} contains '"internalError":false'</simple>
                    <to uri="eventbus:message-sender-bus-in" />
                </when>
                <when>
                    <simple>${bodyAs(String)} contains '"internalError":true'</simple>
                    <to uri="eventbus:retry-bus-in" />
                </when>
                <otherwise>
                    <to uri="eventbus:error-bus-in" />
                </otherwise>
            </choice>
        </route>
    <route id="manual-adjudication-->uin-generation new route">
          <from uri="eventbus://manual-adjudication-new-bus-out" />
          <log message="manual-adjudication-->uin-generation new route ${bodyAs(String)}" />
          <choice>
             <when>
                <jsonpath>$.[?(@['isValid'] == false && @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == true && @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://mark-as-reprocess" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == false && @['internalError'] == false)]</jsonpath>
                <to uri="workflow-cmd://complete-as-rejected" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <otherwise>
                <to uri="eventbus://uin-generator-bus-in" />
             </otherwise>
          </choice>
       </route>
     <route id="finalization route-->printing-stage new route">
          <from uri="eventbus://finalization-new-bus-out" />
          <log message="finalization-->printing-stage route ${bodyAs(String)}" />
          <choice>
             <when>
                <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == true &amp;&amp; @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://mark-as-reprocess" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == false)]</jsonpath>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <otherwise>
                <to uri="eventbus://printing-bus-in" />
             </otherwise>
          </choice>
       </route>
    <route id="quality-checker-->osi-validator new route">
            <from uri="eventbus:quality-checker-new-bus-out" />
            <log
                message="quality-checker-->osi-validator new route ${bodyAs(String)}" />
            <choice>
                <when>
                    <simple>${bodyAs(String)} contains '"isValid":true'</simple>
                    <to uri="eventbus:o-s-i-validator-bus-in" />
                </when>
                <when>
                    <simple>${bodyAs(String)} contains '"isValid":false' and ${bodyAs(String)} contains '"internalError":false'</simple>
                    <to uri="eventbus:message-sender-bus-in" />
                </when>
                <when>
                    <simple>${bodyAs(String)} contains '"internalError":true'</simple>
                    <to uri="eventbus:retry-bus-in" />
                </when>
                <otherwise>
                    <to uri="eventbus:error-bus-in" />
                </otherwise>
            </choice>
        </route>
    
    <route id="quality-classifier-->demo-dedupe new route">
          <from uri="eventbus://quality-classifier-new-bus-out" />
          <log message="quality-classifier-->demo-dedupe new route ${bodyAs(String)}" />
          <choice>
             <when>
                <jsonpath>$.[?(@['isValid'] == false && @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == true && @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://mark-as-reprocess" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == false && @['internalError'] == false)]</jsonpath>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <when>
                <jsonpath suppressExceptions="true">$.[?(@['tags']['BIOMETRIC_CORRECTION_FLOW_STATUS'] in ['FAILED'] || @['tags']['BIOMETRIC_CORRECTION_FLOW_STATUS'] in ['REJECTED'])]</jsonpath>
                <setProperty propertyName="ADDITIONAL_INFO_PROCESS"><constant>BIOMETRIC_CORRECTION</constant></setProperty>
                <setProperty propertyName="PAUSE_FOR"><constant>1296000</constant></setProperty>
                <to uri="workflow-cmd://pause-and-request-additional-info" />
             </when>
             <when>
                <jsonpath suppressExceptions="true">$.[?(@['tags']['Biometric_Quality-Iris'] in ['Average', 'Good','--Biometrics-Not-Available--'] && @['tags']['Biometric_Quality-Finger'] in ['Average', 'Good', '--Biometrics-Not-Available--'] && @['tags']['Biometric_Quality-Face'] in ['Average', 'Good', '--Biometrics-Not-Available--'])]</jsonpath>
                <to uri="eventbus://demo-dedupe-bus-in" />
             </when>
             <when>
                <jsonpath suppressExceptions="true">$.[?(@['tags']['Biometric_Quality-Iris'] in ['Poor'] || @['tags']['Biometric_Quality-Finger'] in ['Poor'] || @['tags']['Biometric_Quality-Face'] in ['Poor'])]</jsonpath>
                <setProperty propertyName="ADDITIONAL_INFO_PROCESS"><constant>BIOMETRIC_CORRECTION</constant></setProperty>
                <!-- PAUSE_FOR is in seconds -->
                <setProperty propertyName="PAUSE_FOR"><constant>1296000</constant></setProperty>
                <to uri="workflow-cmd://pause-and-request-additional-info" />
             </when>
             <otherwise>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </otherwise>
          </choice>
       </route>
    <jsonpath>$.[?(@['isValid'] == true && @['internalError'] == true)]</jsonpath>
    <jsonpath suppressExceptions="true">$.[?(@['messageBusAddress']['address'] == 'verification-bus-in')]</jsonpath>
    <jsonpath suppressExceptions="true">$.[?(@['tags']['AGE_GROUP'] == 'INFANT' || @['tags']['AGE_GROUP'] == 'MINOR' || @['tags']['INTRODUCER_AVAILABILITY'] == 'true')]</jsonpath>
    <setProperty propertyName="PAUSE_FOR"><constant>1296000</constant></setProperty>
    
     <route id="verification route-->uin-generator new route">
          <from uri="eventbus://verification-new-bus-out" />
          <log message="verification route-->uin-generator new route ${bodyAs(String)}" />
          <choice>
             <when>
                <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == true &amp;&amp; @['internalError'] == true)]</jsonpath>
                <to uri="workflow-cmd://mark-as-reprocess" />
             </when>
             <when>
                <jsonpath>$.[?(@['isValid'] == false &amp;&amp; @['internalError'] == false)]</jsonpath>
                <to uri="workflow-cmd://complete-as-failed" />
                <to uri="workflow-cmd://anonymous-profile" />
             </when>
             <otherwise>
                <to uri="eventbus://uin-generator-bus-in" />
             </otherwise>
          </choice>
       </route>

    workflow-cmd://pause-and-request-additional-info

    It will verify if there is an additional request ID. If there is, it will update the status code to "FAILED" and the latest transaction status code of the main workflow to "REPROCESS" in order to resume processing of the main workflow. If there is no additional request ID, it will update the status code to "PAUSED_FOR_ADDITIONAL_INFO" and create the additional request ID. It will then send a web sub-event to the notification service to trigger a notification.

    Update Identity Mapping file in Configuration

    As part of the migration process, we will be updating the latest version of the identity-mapping.json file (1.2.0.1) from the mosip-config. This update involves modifying the mapping values to align with the id schema of the respective country.

    To guide you through the updating process, please refer to the following information:

    In the provided sample identity-mapping.json, the focus will be solely on modifying the mapper values to match the id schema of the country.

    According to the identity-mapping.json file mentioned above, we need to verify if a value is present in the country's ID schema. If the value exists, we can retain it as is. Otherwise, we should update the value in the identity-mapping.json file.

    To illustrate, let's consider a few examples:

    • The fullName field is not included in the ID schema. Instead, it consists of firstName, middleName, and lastName. Therefore, we should replace the fullName with firstName, middleName, and lastName in the identity-mapping.json file.

    • Similarly, the introducerUIN field is not present in the schema, but instead, it has introducerCredentialID. Hence, we need to substitute introducerUIN with introducerCredentialID in the mapping.json file.

    • Additionally, since addressLine1 is not part of the schema, we should replace its value with presentAddressLine1, which is present.

    Sample Country’s ID schema

    {
       "identity":{
          "IDSchemaVersion":{
             "value":"IDSchemaVersion"
          },
          "name":{
             "value":"fullName"
          },
          "gender":{
             "value":"gender"
          },
          "dob":{
             "value":"dateOfBirth"
          },
          "age":{
             "value":"age"
          },
          "introducerRID":{
             "value":"introducerRID"
          },
          "introducerUIN":{
             "value":"introducerUIN"
          },
          "introducerVID":{
             "value":"introducerVID"
          },
          "introducerName":{
             "value":"introducerName"
          },
          "phone":{
             "value":"phone"
          },
          "phoneNumber":{
             "value":"phone"
          },
          "email":{
             "value":"email"
          },
          "emailId":{
             "value":"email"
          },
          "uin":{
             "value":"UIN"
          },
          "vid":{
             "value":"VID"
          },
          "individualBiometrics":{
             "value":"individualBiometrics"
          },
          "introducerBiometrics":{
             "value":"introducerBiometrics"
          },
          "individualAuthBiometrics":{
             "value":"individualAuthBiometrics"
          },
          "officerBiometricFileName":{
             "value":"officerBiometricFileName"
          },
          "supervisorBiometricFileName":{
             "value":"supervisorBiometricFileName"
          },
          "residenceStatus":{
             "value":"residenceStatus"
          },
          "preferredLanguage":{
             "value":"preferredLang"
          },
          "locationHierarchyForProfiling":{
             "value":"zone,postalCode"
          },
          "addressLine1":{
             "value":"addressLine1"
          },
          "addressLine2":{
             "value":"addressLine2"
          },
          "addressLine3":{
             "value":"addressLine3"
          },
          "location1":{
             "value":"city"
          },
          "location2":{
             "value":"region"
          },
          "location3":{
             "value":"province"
          },
          "postalCode":{
             "value":"postalCode"
          },
          "location4":{
             "value":"zone"
          },
          "fullAddress":{
             "value":"addressLine1,addressLine2,addressLine3,city,region,province,postalCode"
          },
          "bestTwoFingers":{
             "value":"bestTwoFingers"
          },
          "birthdate":{
             "value":"dateOfBirth"
          },
          "picture":{
             "value":"face"
          },
          "phone_number":{
             "value":"phone"
          },
          "address":{
             "value":"addressLine1,addressLine2,addressLine3,city,region,province,postalCode"
          },
          "individual_id":{
             "value":"individual_id"
          },
          "street_address":{
             "value":"addressLine1,addressLine2,addressLine3"
          },
          "locality":{
             "value":"city"
          },
          "region":{
             "value":"region"
          },
          "postal_code":{
             "value":"postalCode"
          },
          "country":{
             "value":"province"
          }
       },
       "metaInfo":{
          "value":"metaInfo"
       },
       "audits":{
          "value":"audits"
       },
       "documents":{
          "poa":{
             "value":"proofOfAddress"
          },
          "poi":{
             "value":"proofOfIdentity"
          },
          "por":{
             "value":"proofOfRelationship"
          },
          "pob":{
             "value":"proofOfDateOfBirth"
          },
          "poe":{
             "value":"proofOfException"
          }
       },
       "attributeUpdateCountLimit":{
          "fullName":2,
          "gender":1,
          "dob":1,
          "age":1
       }
    }
    Lastly, the phone field is not found in the schema, but mobileno is present. Thus, we need to replace phone with mobileno in the mapping.json file.
  • Our task is to compare each field value in the identity-mapping.json file with the ID schema and update it with the appropriate value based on the schema.

  • {
       "$schema":"http://json-schema.org/draft-07/schema#",
       "description":"string",
       "additionalProperties":false,
       "title":"string",
       "type":"object",
       "definitions":{
          "simpleType":{
             "uniqueItems":true,
             "additionalItems":false,
             "type":"array",
             "items":{
                "additionalProperties":false,
                "type":"object",
                "required":[
                   "language",
                   "value"
                ],
                "properties":{
                   "language":{
                      "type":"string"
                   },
                   "value":{
                      "type":"string"
                   }
                }
             }
          },
          "documentType":{
             "additionalProperties":false,
             "type":"object",
             "required":[
                "format",
                "type",
                "value"
             ],
             "properties":{
                "refNumber":{
                   "type":"string"
                },
                "format":{
                   "type":"string"
                },
                "type":{
                   "type":"string"
                },
                "value":{
                   "type":"string"
                }
             }
          },
          "biometricsType":{
             "additionalProperties":false,
             "type":"object",
             "properties":{
                "format":{
                   "type":"string"
                },
                "version":{
                   "type":"number",
                   "minimum":0
                },
                "value":{
                   "type":"string"
                }
             }
          }
       },
       "properties":{
          "identity":{
             "additionalProperties":false,
             "type":"object",
             "required":[
                "IDSchemaVersion",
                "firstName",
                "dateOfBirth",
                "pobCountry",
                "pobProvince",
                "pobCity",
                "gender",
                "residenceStatus",
                "bloodType",
                "permanentCountry",
                "permanentAddressLine1",
                "addressCopy",
                "presentCountry",
                "presentAddressLine1",
                "modeOfClaim",
                "proofOfAddress",
                "individualBiometrics"
             ],
             "properties":{
                "presentProvince":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,50}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "pobCountry":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,50}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "pobProvince":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,50}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "permanentBarangay":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "mobileno":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "type":"string",
                   "fieldType":"default"
                },
                "suffix":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{1,3}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "proofOfDateOfBirth":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/documentType"
                },
                "introducerSuffix":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{1,3}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "introducerMiddleName":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"(?=(?:^\\w|Ñ|Ü|ü|ñ))([A-Z0-9a-zñÑ -.‘_ Üü]+)(?<=[^ ])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "presentCity":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,50}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "firstName":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"(?=(?:^\\w|Ñ|Ü|ü|ñ))([A-Z0-9a-zñÑ -.‘_ Üü]+)(?<=[^ ])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "IDSchemaVersion":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"none",
                   "format":"none",
                   "type":"number",
                   "fieldType":"default",
                   "minimum":0
                },
                "proofOfException":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/documentType"
                },
                "registrationType":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"dynamic",
                   "$ref":"#/definitions/simpleType"
                },
                "permanentCountry":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,50}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "presentCountry":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,50}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "permanentProvince":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,50}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "proofOfRelationship":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/documentType"
                },
                "UIN":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"none",
                   "format":"none",
                   "type":"string",
                   "fieldType":"default"
                },
                "maritalStatus":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"dynamic",
                   "$ref":"#/definitions/simpleType"
                },
                "presentAddressLine1":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,255}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "presentZipcode":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "lastName":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"(?=(?:^\\w|Ñ|Ü|ü|ñ))([A-Z0-9a-zñÑ -.‘_ Üü]+)(?<=[^ ])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "presentAddressLine2":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,255}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "presentAddressLine3":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,255}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "guardianFirstName":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"(?=(?:^\\w|Ñ|Ü|ü|ñ))([A-Z0-9a-zñÑ -.‘_ Üü]+)(?<=[^ ])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "presentAddressLine4":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,255}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "proofOfAddress":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/documentType"
                },
                "gender":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"",
                   "fieldType":"dynamic",
                   "$ref":"#/definitions/simpleType"
                },
                "modeOfClaim":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"dynamic",
                   "$ref":"#/definitions/simpleType"
                },
                "proofOfConsent":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/documentType"
                },
                "guardianSuffix":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{1,3}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "bloodType":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"",
                   "fieldType":"dynamic",
                   "$ref":"#/definitions/simpleType"
                },
                "introducerFirstName":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"(?=(?:^\\w|Ñ|Ü|ü|ñ))([A-Z0-9a-zñÑ -.‘_ Üü]+)(?<=[^ ])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "guardianLastName":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"(?=(?:^\\w|Ñ|Ü|ü|ñ))([A-Z0-9a-zñÑ -.‘_ Üü]+)(?<=[^ ])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "individualBiometrics":{
                   "bioAttributes":[
                      "leftEye",
                      "rightEye",
                      "rightIndex",
                      "rightLittle",
                      "rightRing",
                      "rightMiddle",
                      "leftIndex",
                      "leftLittle",
                      "leftRing",
                      "leftMiddle",
                      "leftThumb",
                      "rightThumb",
                      "face"
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/biometricsType"
                },
                "presentBarangay":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "residenceStatus":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"kyc",
                   "format":"none",
                   "fieldType":"dynamic",
                   "$ref":"#/definitions/simpleType"
                },
                "email":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^[A-Za-z0-9_\\-]+(\\.[A-Za-z0-9_]+)*@[A-Za-z0-9_-]+(\\.[A-Za-z0-9_]+)*(\\.[a-zA-Z]{2,})$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "type":"string",
                   "fieldType":"default"
                },
                "guardianMiddleName":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"(?=(?:^\\w|Ñ|Ü|ü|ñ))([A-Z0-9a-zñÑ -.‘_ Üü]+)(?<=[^ ])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "parentOrGuardianRID":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "type":"string",
                   "fieldType":"default"
                },
                "permanentZipcode":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "pobCity":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,50}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "addressCopy":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^[YN]$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "type":"string",
                   "fieldType":"default"
                },
                "dateOfBirth":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(1869|18[7-9][0-9]|19[0-9][0-9]|20[0-9][0-9])/([0][1-9]|1[0-2])/([0][1-9]|[1-2][0-9]|3[01])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "type":"string",
                   "fieldType":"default"
                },
                "individualAuthBiometrics":{
                   "bioAttributes":[
                      "leftEye",
                      "rightEye",
                      "rightIndex",
                      "rightLittle",
                      "rightRing",
                      "rightMiddle",
                      "leftIndex",
                      "leftLittle",
                      "leftRing",
                      "leftMiddle",
                      "leftThumb",
                      "rightThumb",
                      "face"
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/biometricsType"
                },
                "proofOfIdentity":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/documentType"
                },
                "introducerCredentialID":{
                   "bioAttributes":[
                      
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "type":"string",
                   "fieldType":"default"
                },
                "permanentAddressLine1":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,255}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "guardianBiometrics":{
                   "bioAttributes":[
                      "leftEye",
                      "rightEye",
                      "rightIndex",
                      "rightLittle",
                      "rightRing",
                      "rightMiddle",
                      "leftIndex",
                      "leftLittle",
                      "leftRing",
                      "leftMiddle",
                      "leftThumb",
                      "rightThumb",
                      "face"
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/biometricsType"
                },
                "middleName":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"(?=(?:^\\w|Ñ|Ü|ü|ñ))([A-Z0-9a-zñÑ -.‘_ Üü]+)(?<=[^ ])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "permanentCity":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,50}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "permanentAddressLine2":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,255}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "permanentAddressLine3":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,255}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "introducerLastName":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"(?=(?:^\\w|Ñ|Ü|ü|ñ))([A-Z0-9a-zñÑ -.‘_ Üü]+)(?<=[^ ])$",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"evidence",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                },
                "permanentAddressLine4":{
                   "bioAttributes":[
                      
                   ],
                   "validators":[
                      {
                         "langCode":null,
                         "validator":"^(?=.{0,255}$).*",
                         "arguments":[
                            
                         ],
                         "type":"regex"
                      }
                   ],
                   "fieldCategory":"pvt",
                   "format":"none",
                   "fieldType":"default",
                   "$ref":"#/definitions/simpleType"
                }
             }
          }
       }
    }

    Partners' Certificate Expired

    Here's how to fix it!.

    The key point to note here is that MOSIP only accepts partners whose client certificates have a minimum of 1 year of validity remaining. MOSIP re-signs the client certificate with a 1-year validity. The respective partner must renew their certificate before the MOSIP-signed certificate expires in order to continue communication with MOSIP.

    However, if this renewal is not done, the certificates will expire.

    Here is a three-step process to address this scenario:

    a. How to check the validity of your partner's certificate?

    To check the validity, the user must have access to the database.

    The user can access the mosip_keymanager database and open two tables: ca_cert_store and partner_cert_store.

    The ca_cert_store table stores the CA and SUBCA/Intermediate CA certificates, while the partner_cert_store table stores the PARTNER/CLIENT certificates. In both of these tables, there are columns named cert_not_before and cert_not_after which provide details about the validity of the partner's certificate.

    b. How to extend the validity of the partner's certificate?

    There are two categories of partners: MOSIP Internal partners (e.g., IDA) and External partners (e.g., Device Partners, MISP partners).

    1. For MOSIP Internal partners, if the validity of their certificate needs to be increased, the onboarder script can be run again for that specific partner. The onboarder will create fresh certificates and upload them to extend the validity.

    2. For External Partners, they will need to obtain fresh certificates from their CA and upload them to extend their validity.

    c. Troubleshooting common errors:

    KER-ATH-401 Authentication Failed

    If the user encounters this error code, it means that the user is not authenticated. The user should authenticate first before using the API.

    KER-PCM-005 Root CA Certificate not found.

    If the user encounters this error code, it means that there is an issue with either the CA or SUBCA certificate. The user must resolve the CA/SUBCA issue first.

    Pre-Registration UI Upgrade

    The Pre-Registration UI-spec file pre-registration-demographic.json was previously included in the mosip-config repository in version 1.1.5.*, but starting from version 1.2.0, it should be manually published using the master data UI-spec API.

    How to define and publish UI specifications?

    1. Go to Swagger clientIdSecretKey to get the Authentication token:

    2. Go to Swagger defineUISpec to define the new UI Specifications

    1. Go to publishUISpec to Publish the newly defined UI Spec

    1. Once done, check the master.ui_spec table.

    Changes in UI Specifications

    The document provides details about all UI spec attributes. This document can be referred to in order to identify the changes between versions 1.1.5 and 1.2.0.1.

    The following new attributes have been added:

    • subType (optional - for dynamic dropdowns)

    • transliteration (mandatory to enable transliteration)

    • locationHierarchyLevel (mandatory to be added in each location dropdown to indicate the location hierarchy level)

    • parentLocCode (mandatory to be added in the topmost dropdown in the location hierarchy to indicate the parent for it. It can also be omitted, in which case the mosip.country.code property will be used)

    UI Specifications of 1.1.5 and 1.2.0

    1.1.5

    1.2.0

  • gender Attribute should be mandatory, and the parameter required should be true

  • The control type for the date of birth should be changed to ageDate

  • The labelName should be provided with the "languageCode" as the "key" and the label as the "value". Example: {"labelName": { "eng": "Date Of Birth", "ara": "تاريخ الولادة", "fra": "Date de naissance" }}

  • visibleCondition (optional)

  • requiredCondition (optional)

  • alignmentGroup (optional)

  • containerStyle (optional)

  • headerStyle (optional)

  • changeAction (optional)

  • Pre-registration UI Specifications
    {env_url}/v1/authmanager/swagger-ui/index.html?configUrl=/v1/authmanager/v3/api-docs/swagger-config#/authmanager/clientIdSecretKey
    
    "request": {
      "clientId": "mosip-reg-client",
      "secretKey": {secret_key},
      "appId": "admin"
    } 
    {env_url}/v1/masterdata/swagger-ui/index.html?configUrl=/v1/masterdata/v3/api-docs/swagger-config#/ui-spec-controller/defineUISpec"
    
    request": {
        "identitySchemaId": {id of latest identity schema},
        "domain": "pre-registration",
        "type": "schema",
        "title": "Pre-registration UI Specification",
        "description": "Pre-registration UI Specification",
        "jsonspec": {Add New UI Spec}
     }
      {env_url}/v1/masterdata/swagger-ui/index.html?configUrl=/v1/masterdata/v3/api-docs/swagger-config#/ui-spec-controller/publishUISpec
    
      get the id from the defineUISpec response and add it in request
    
      "request": {
          "id": "{}",
        "effectiveFrom": "2022-07-28T08:42:07.706Z"
        }  
    {
    
                  "identity": [{
    
                                               "id": "IDSchemaVersion",
    
                                               "description": "ID Schema Version",
    
                                               "type": "number",
    
                                               "controlType": null,
    
                                               "fieldType": "default",
    
                                               "inputRequired": false,
    
                                               "validators": [],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "fullName",
    
                                               "description": "Enter Full Name",
    
                                               "labelName": {
    
                                                              "eng": "Full Name",
    
                                                              "ara": "الاسم الكامل",
    
                                                              "fra": "Nom complet"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "dateOfBirth",
    
                                               "description": "Enter DOB",
    
                                               "labelName": {
    
                                                              "eng": "Date Of Birth",
    
                                                              "ara": "تاريخ الولادة",
    
                                                              "fra": "Date de naissance"
    
                                               },
    
                                               "controlType": "date",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "string",
    
                                               "validators": [],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "gender",
    
                                               "description": "Enter Gender",
    
                                               "labelName": {
    
                                                              "eng": "Gender",
    
                                                              "ara": "جنس",
    
                                                              "fra": "Le genre"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "dynamic",
    
                                               "type": "simpleType",
    
                                               "validators": [
    
     
    
                                               ],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "residenceStatus",
    
                                               "description": "Residence status",
    
                                               "labelName": {
    
                                                              "eng": "Residence Status",
    
                                                              "ara": "حالة الإقامة",
    
                                                              "fra": "Statut de résidence"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "dynamic",
    
                                               "type": "simpleType",
    
                                               "validators": [
    
     
    
                                               ],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "addressLine1",
    
                                               "description": "addressLine1",
    
                                               "labelName": {
    
                                                              "eng": "Address Line1",
    
                                                              "ara": "العنوان السطر 1",
    
                                                              "fra": "Adresse 1"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "addressLine2",
    
                                               "description": "addressLine2",
    
                                               "labelName": {
    
                                                              "eng": "Address Line2",
    
                                                              "ara": "العنوان السطر 2",
    
                                                              "fra": "Adresse 2"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": false
    
                                 },
    
                                 {
    
                                               "id": "addressLine3",
    
                                               "description": "addressLine3",
    
                                               "labelName": {
    
                                                              "eng": "Address Line3",
    
                                                              "ara": "العنوان السطر 3",
    
                                                              "fra": "Adresse 3"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": false
    
                                 },
    
                                 {
    
                                               "id": "region",
    
                                               "description": "region",
    
                                               "labelName": {
    
                                                              "eng": "Region",
    
                                                              "ara": "منطقة",
    
                                                              "fra": "Région"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "province",
    
                                               "description": "province",
    
                                               "labelName": {
    
                                                              "eng": "Province",
    
                                                              "ara": "المحافظة",
    
                                                              "fra": "Province"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "city",
    
                                               "description": "city",
    
                                               "labelName": {
    
                                                              "eng": "City",
    
                                                              "ara": "مدينة",
    
                                                              "fra": "Ville"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "zone",
    
                                               "description": "zone",
    
                                               "labelName": {
    
                                                              "eng": "Zone",
    
                                                              "ara": "منطقة",
    
                                                              "fra": "Zone"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [
    
     
    
                                               ],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "postalCode",
    
                                               "description": "postalCode",
    
                                               "labelName": {
    
                                                              "eng": "Postal Code",
    
                                                              "ara": "الكود البريدى",
    
                                                              "fra": "code postal"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "string",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^[(?i)A-Z0-9]{5}$|^NA$",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "phone",
    
                                               "description": "phone",
    
                                               "labelName": {
    
                                                              "eng": "Phone",
    
                                                              "ara": "هاتف",
    
                                                              "fra": "Téléphone"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "string",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^([6-9]{1})([0-9]{9})$",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "email",
    
                                               "description": "email",
    
                                               "labelName": {
    
                                                              "eng": "Email",
    
                                                              "ara": "البريد الإلكتروني",
    
                                                              "fra": "Email"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "string",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^[\\w-\\+]+(\\.[\\w]+)*@[\\w-]+(\\.[\\w]+)*(\\.[a-zA-Z]{2,})$",
    
                                                              "arguments": [
    
     
    
                                                              ]
    
                                               }],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "proofOfAddress",
    
                                               "description": "proofOfAddress",
    
                                               "labelName": [{
    
                                                              "value": "Address Proof",
    
                                                              "language": "eng"
    
                                               }],
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [
    
     
    
                                               ],
    
                                               "required": false
    
                                 },
    
                                 {
    
                                               "id": "proofOfIdentity",
    
                                               "description": "proofOfIdentity",
    
                                               "labelName": [{
    
                                                              "value": "Identity Proof",
    
                                                              "language": "eng"
                                               }],
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [
    
                                               ],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "proofOfRelationship",
    
                                               "description": "proofOfRelationship",
    
                                               "labelName": [{
    
                                                              "value": "Relationship Proof",
    
                                                              "language": "eng"
                                               }],
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [
    
                                               ],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "proofOfDateOfBirth",
    
                                               "description": "proofOfDateOfBirth",
    
                                               "labelName": [{
    
                                                              "value": "DOB Proof",
    
                                                              "language": "eng"
    
                                               }],
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [
    
                                                ],
    
                                               "required": true
    
                                 },
    
                                 {
    
                                               "id": "proofOfException",
    
                                               "description": "proofOfException",
    
                                               "labelName": [{
    
                                                              "value": "Exception Proof",
    
                                                              "language": "eng"
    
                                               }],
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [
    
                                               ],
    
                                               "required": true
                                 }
    
                  ],
    
                  "locationHierarchy": ["region", "province", "city", "zone", "postalCode"]
    }
    {
    
                  "identity": {
    
                                 "identity": [{
    
                                               "id": "IDSchemaVersion",
    
                                               "description": "ID Schema Version",
    
                                               "type": "number",
    
                                               "controlType": null,
    
                                               "fieldType": "default",
    
                                               "inputRequired": false,
    
                                               "validators": [],
    
                                               "required": true
    
                                 }, {
    
                                               "id": "fullName",
    
                                               "description": "Enter Full Name",
    
                                               "labelName": {
    
                                                              "eng": "Full Name",
    
                                                              "ara": "الاسم الكامل",
    
                                                              "fra": "Nom complet"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": []
    
                                               }],
    
                                               "required": true,
    
                                               "transliteration": true
    
                                 }, {
    
                                               "id": "dateOfBirth",
    
                                               "description": "Enter DOB",
    
                                               "labelName": {
    
                                                              "eng": "Date Of Birth",
    
                                                              "ara": "تاريخ الولادة",
    
                                                              "fra": "Date de naissance"
    
                                               },
    
                                               "controlType": "ageDate",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "string",
    
                                               "validators": [],
    
                                               "required": true
    
                                 }, {
    
                                               "id": "gender",
    
                                               "description": "Enter Gender",
    
                                               "labelName": {
    
                                                              "eng": "Gender",
    
                                                              "ara": "جنس",
    
                                                              "fra": "Le genre"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "dynamic",
    
                                               "subType": "gender",
    
                                               "type": "simpleType",
    
                                               "validators": [],
    
                                               "required": true
    
                                 }, {
    
                                               "id": "residenceStatus",
    
                                               "description": "Residence status",
    
                                               "labelName": {
    
                                                              "eng": "Residence Status",
    
                                                              "ara": "حالة الإقامة",
    
                                                              "fra": "Statut de résidence"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "dynamic",
    
                                               "subType": "residenceStatus",
    
                                               "type": "simpleType",
    
                                               "validators": [],
    
                                               "required": true
    
                                 }, {
    
                                               "id": "addressLine1",
    
                                               "description": "addressLine1",
    
                                               "labelName": {
    
                                                              "eng": "Address Line1",
    
                                                              "ara": "العنوان السطر 1",
    
                                                              "fra": "Adresse 1"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": []
    
                                               }],
    
                                               "required": true,
    
                                               "transliteration": true
    
                                 }, {
    
                                               "id": "addressLine2",
    
                                               "description": "addressLine2",
    
                                               "labelName": {
    
                                                              "eng": "Address Line2",
    
                                                              "ara": "العنوان السطر 2",
    
                                                              "fra": "Adresse 2"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": []
    
                                               }],
    
                                               "required": false,
    
                                               "transliteration": true
    
                                 }, {
    
                                               "id": "addressLine3",
    
                                               "description": "addressLine3",
    
                                               "labelName": {
    
                                                              "eng": "Address Line3",
    
                                                              "ara": "العنوان السطر 3",
    
                                                              "fra": "Adresse 3"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": []
    
                                               }],
    
                                               "required": false,
    
                                               "transliteration": true
    
                                 }, {
    
                                               "id": "region",
    
                                               "description": "region",
    
                                               "labelName": {
    
                                                              "eng": "Region",
    
                                                              "ara": "منطقة",
    
                                                              "fra": "Région"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": []
    
                                               }],
    
                                               "parentLocCode": "MOR",
    
                                               "locationHierarchyLevel": 1,
    
                                               "required": true
    
                                 }, {
    
                                               "id": "province",
    
                                               "description": "province",
    
                                               "labelName": {
    
                                                              "eng": "Province",
    
                                                              "ara": "المحافظة",
    
                                                              "fra": "Province"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": []
    
                                               }],
    
                                               "locationHierarchyLevel": 2,
    
                                               "required": true
    
                                 }, {
    
                                               "id": "city",
    
                                               "description": "city",
    
                                               "labelName": {
    
                                                              "eng": "City",
    
                                                              "ara": "مدينة",
    
                                                              "fra": "Ville"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^(?=.{0,50}$).*",
    
                                                              "arguments": []
    
                                               }],
    
                                               "locationHierarchyLevel": 3,
    
                                               "required": true
    
                                 }, {
    
                                               "id": "zone",
    
                                               "description": "zone",
    
                                               "labelName": {
    
                                                              "eng": "Zone",
    
                                                              "ara": "منطقة",
    
                                                              "fra": "Zone"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "simpleType",
    
                                               "validators": [],
    
                                               "locationHierarchyLevel": 4,
    
                                               "required": true
    
                                 }, {
    
                                               "id": "postalCode",
    
                                               "description": "postalCode",
    
                                               "labelName": {
    
                                                              "eng": "Postal Code",
    
                                                              "ara": "الكود البريدى",
    
                                                              "fra": "code postal"
    
                                               },
    
                                               "controlType": "dropdown",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "string",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^[(?i)A-Z0-9]{5}$|^NA$",
    
                                                              "arguments": []
    
                                               }],
    
                                               "locationHierarchyLevel": 5,
    
                                               "required": true
    
                                 }, {
    
                                               "id": "phone",
    
                                               "description": "phone",
    
                                               "labelName": {
    
                                                              "eng": "Phone",
    
                                                              "ara": "هاتف",
    
                                                              "fra": "Téléphone"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "string",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^([6-9]{1})([0-9]{9})$",
    
                                                              "arguments": []
    
                                               }],
    
                                               "required": true
    
                                 }, {
    
                                               "id": "email",
    
                                               "description": "email",
    
                                               "labelName": {
    
                                                              "eng": "Email",
    
                                                              "ara": "البريد الإلكتروني",
    
                                                              "fra": "Email"
    
                                               },
    
                                               "controlType": "textbox",
    
                                               "inputRequired": true,
    
                                               "fieldType": "default",
    
                                               "type": "string",
    
                                               "validators": [{
    
                                                              "type": "regex",
    
                                                              "validator": "^[\\w-\\+]+(\\.[\\w]+)*@[\\w-]+(\\.[\\w]+)*(\\.[a-zA-Z]{2,})$",
    
                                                              "arguments": []
    
                                               }],
    
                                               "required": true
    
                                 }, {
    
                                               "id": "proofOfAddress",
    
                                               "description": "proofOfAddress",
    
                                               "labelName": {
    
                                                              "ara": "إثبات العنوان",
    
                                                              "fra": "Address Proof",
    
                                                              "eng": "Address Proof"
    
                                               },
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [],
    
                                               "subType": "POA",
    
                                               "required": false
    
                                 }, {
    
                                               "id": "proofOfIdentity",
    
                                               "description": "proofOfIdentity",
    
                                               "labelName": {
    
                                                              "ara": "إثبات الهوية",
    
                                                              "fra": "Identity Proof",
    
                                                              "eng": "Identity Proof"
    
                                               },
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [],
    
                                               "subType": "POI",
    
                                               "required": true
    
                                 }, {
    
                                               "id": "proofOfRelationship",
    
                                               "description": "proofOfRelationship",
    
                                               "labelName": {
    
                                                              "ara": "إثبات العلاقة",
    
                                                              "fra": "Relationship Proof",
    
                                                              "eng": "Relationship Proof"
    
                                               },
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [],
    
                                               "subType": "POR",
    
                                               "required": true
    
                                 }, {
    
                                               "id": "proofOfDateOfBirth",
    
                                               "description": "proofOfDateOfBirth",
    
                                               "labelName": {
    
                                                              "ara": "دليل DOB",
    
                                                              "fra": "DOB Proof",
    
                                                              "eng": "DOB Proof"
    
                                               },
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [],
    
                                               "subType": "POB",
    
                                               "required": true
    
                                 }, {
    
                                               "id": "proofOfException",
    
                                               "description": "proofOfException",
    
                                               "labelName": {
    
                                                              "ara": "إثبات الاستثناء",
    
                                                              "fra": "Exception Proof",
    
                                                              "eng": "Exception Proof"
    
                                               },
    
                                               "controlType": "fileupload",
    
                                               "inputRequired": true,
    
                                               "validators": [],
    
                                               "subType": "POE",
    
                                               "required": true
    
                                 }],
    
                                 "locationHierarchy": ["region", "province", "city", "zone", "postalCode"]
    
                  }
    
    }