# What is cQube & what does it solve

Details out the technical architecture of cQube

cQube is envisioned as a ready-to-use / pre-packaged, configurable, and extendable DPG solution to enable observability and action towards effective policy implementation in education and other sectors, involving various stakeholders across govt, society, and private sectors.


# Business case

### Problem Statement

There are several challenges that government program owners face while leveraging technology for monitoring public programs:

* Program administrators face challenges in defining actionable insights and relevant indicators for tracking
* Data ingestion, processing & visualisation available as disaggregated products, not packaged into a solution
* Governments are unable to hire expert technical staff (architects, engineers) to smartly leverage a combination of available products together for end-to-end monitoring
* Governments have budget and digital infrastructure (server) limitations

### **cQube as a Solution**

cQube offers two core differential value propositions for monitoring programs:

* A domain-agnostic product packaging of ingestion, processing and visualisation layer in a manner that is:
  * Easy to deploy with minimal engineering staff
  * Lite deployment (minimal infrastructure requirements optimised to program needs)
  * Built for scale (to be scale tested with \~500k users)
  * Leverages reference schemas and spec-compliant API based implementation
  * Brownfield ready with modular components interoperable with existing systems
* Domain-specific configuration layer allowing out-of-the-box contextualisation of indicators, insights, role based nudges and actions


# cQube ed

**Need**

Vidya Samiksha Kendra was initiated by Ministry of Education as a [program](https://pib.gov.in/PressReleaseIframePage.aspx?PRID=1843168) with the following objectives:

* Improve monitoring of schemes / programs in education
* Effectively collect, monitor, correlate and analyze data to take timely decisions
* Envisioned as state-level systems to monitor schemes / programs and build accountability in field-staff
* To drive a big leap in learning outcomes through meaningful data based action

There are several challenges that government program owners face while leveraging technology for monitoring public programs:

* Data ingestion, processing & visualization available as disaggregated products, not packaged into a solution
* Lack of visibility at the granular level in the system & thus face challenges in defining actionable insights and relevant indicators for tracking
* Limitation on hiring expert technical staff (architects, engineers) to smartly leverage a combination of available products together for end-to-end monitoring
* Constraints related to budgets lead to limitations on building extensive digital infrastructure capabilities

### Solution

cQube Ed is a pre-packaged solution for education with 120+ pre-defined actionable

indicators & insights like attendance, assessment etc. It acts as an accelerator for states

in fast tracking their Vidya Samiksha Kendra journeys.


# Design Principles

cQube Ed is based on the following design principles:

1. **Solution:** cQube is neither a tool nor a platform. It is a ready-to-use/pre-packaged, configurable, and extendable solution to enable observability and action towards effective policy implementation in education and other sectors, involving various stakeholders across govt, society, and private sectors.
2. **Education-specific:** A pre-packaged solution of cQube for education, *cQube Ed*, comes with a set of predefined actionable indicators and insights which are specific to education. For eg: the metrics could be related to attendance, enrolment, assessments etc. The schema for data ingestion will also be defined for edu-specific indicators.
3. **Based in Indian Context:** cQube is based in the Indian context, implying that the jurisdictions and hierarchies will be defined accordingly. For eg: The hierarchy for cQube Ed will be as follows - State > District > Block > Cluster > School > Class.


# cQube adoptions

Coming soon...


# Discuss more about cQube

Lets discuss here- [Link](https://github.com/orgs/Sunbird-cQube/discussions/792)


# cQube on Gitpod

Developers can try out cQube installation and ingestion on Gitpod.

1. Login to your github account.
2. Open sunbird cqube-devops repository and fork the repo into your personal github
3. Checkout to gitpod-branch
4. Update readme.md file as follows

<figure><img src="https://lh6.googleusercontent.com/munUgcsrqtru6ODPk_UZe1ttQ5_Y3rimzo4qSvzpwlO2VB5y5x7Hol3C3I3ZItFWtOb1_pzr3JbkJurlHStaX9r1vwBQGFdPIyMPBFOPobxhteslQnL7NNC6UQgVpEIRU4CZaTqHfTZwY9vppZvsrE8" alt=""><figcaption></figcaption></figure>

Replace \<github\_username> with your actual github username

**Note:**&#x20;

* By default JH is selected as a state code.
* If you want to change the state code, you can navigate to cqube-devops/config\_files/config.yml
* Change the state code and commit the changes.

5. Commit the changes.
6. Click on Open in Gitpod
7. If you are a new user to gitpod, complete the signup process&#x20;
8. Once the registration is done then the configuration page gets displayed. Click on continue

<figure><img src="https://lh6.googleusercontent.com/m7yBxE-tustLRBevJdX_Pi2L95UOn4eFvfxaQvsDaQBFF67Nc1xI_uuNHnSDeR-l9J2bhfxwZCMaboY6ZFMBNxZgcvOV4a4z1HghwxB1R87tYexKKsBVqMHWIrRy0HhWg6_BjIr_eMZ7IP7do9GHyCE" alt=""><figcaption></figcaption></figure>

9. Automatically it sets a VM and start the cqube deployment.
10. Once the config file is generated, type no and hit enter

<figure><img src="https://lh6.googleusercontent.com/UffbSAfbylpQVsUbbJSmcxWtMB61Vj3Fb-s7kAUc_1VOnfLgVR0XkUcAibNFwsyAt3qqVv0P-Ig6pN-7H99qhR87zTWT3RYWlOEL5qkJKkHFwotQonBolzvCOegKeOYNn_c4XWc834eo46FW6kyUuQQ" alt=""><figcaption></figcaption></figure>

<br>

11. Select the default config file by typing no

<figure><img src="https://lh3.googleusercontent.com/hUQyxNEXvjqxcw8uyIp7MMjs1iqA-0i0kXitxOJ6fVcBJ9L97dS3EDOvQ4pHRGL1DEDbuYk2SjPfsQ58sYZQ31bUkkklKUQlRDIlYAoe-Vq0RXGFXlA-Dt66dGnV6ZED4s-1zC0P_2aypLZF0lyQXj8" alt=""><figcaption></figcaption></figure>

12. Wait unit the installation is done.
13. Once installation is completed, you will be able to see the url to access the dashboard

<figure><img src="https://lh6.googleusercontent.com/uflMJ0hmljQ3SL7X9zRJABF3399VDOJnLBPg8iWqxlq-dKAzoCKLF_Ilk_ptphYYB1op8gghDGKo81Rr3h8Gyo-UrRxq2OzfNvf9S0VRkDSvx5ku9ZtNi6Q4cZ3sRzJHwDLNwMe8_CB0m1YJkLwz_kY" alt=""><figcaption></figcaption></figure>

14. Access the dashboard using the url in your browser.

<figure><img src="https://lh5.googleusercontent.com/7O5gmZ0ChR6m5qS3ZD23zhq6zppbfpWImTcBBveZtbqgDjt2OU_vUunsFnFGxs7J6Y0zwYN-Z3KMLGXfSLEkUJbckVfDMvdCyn24PAZCWqb9zVkjqOVMkmmJHhLNAyNVTb73KvvctD-5VDfYHO39XPU" alt=""><figcaption></figcaption></figure>

15. Use keycloak credentials from config.yml file to login

<figure><img src="https://lh6.googleusercontent.com/JKg0nh85iepiglGJF4De4ESK7STn5_PsmNGZQgvI7Z-VhRIXM7Bwk3vxPf_0ZS_WgkBqHHfEhMbWRivfunp-6NTznzJ94ZBcgofbdf23TmsqapdTEG4nNK5Zmv2Ae2kBh1aFVbv9pl-qlxIFXRzhC3U" alt=""><figcaption></figcaption></figure>

16. Follow the [ingestion and processing ](https://cqube.sunbird.org/use-cqube/ingesting-the-data)steps to ingest the data. Once done you will be able to see the data in the dashboard.

<figure><img src="https://lh4.googleusercontent.com/0F75GP-aOCyolzj_584Nvymu6Dy6y8KfwOHN3S81p4n4vvFD5_RIbbM-24TUbq6iWpjkMwagj7ue48fWKfb2tWHVts1QiOrKbA6cgLSMEGRI3wt_kKkDiSqElWjEbTP9YZxRkhXP8uxXWTxsQ8gQmg8" alt=""><figcaption></figcaption></figure>

Cqube deployment in gitpod video link:&#x20;

[gitpod\_recording.zip](https://drive.google.com/file/d/1lc6whjXGbxuPDpDqnyJs-n4Ev6GkXmdk/view?usp=sharing)

Ingestion and processing video link:

<https://drive.google.com/file/d/1GLYfQMPJHWMfDseLiaZg1G46Zfu2Ie--/view?usp=sharing>

<br>


# cQube Roadmap

### **How to read:**

1. The planned items are available on the JIRA board for cQube - [Link](https://project-sunbird.atlassian.net/jira/software/c/projects/CQ/boards/115/backlog?issueLimit=100)
2. For the items on the community discussions, we expect interested community users to go to the github discussion to suggest changes on existing items or add new items which will be added to the roadmap.

{% embed url="<https://www.figma.com/file/AeWbJFKH64HNu6XbtYF3Ra/cQube-roadmap?node-id=0:1&t=vxHi7TfjJ22XRHLi-1&type=whiteboard>" %}

<br>


# Architecture

Details out the technical architecture of cQube

cQube is envisioned as a ready-to-use / pre-packaged, configurable, and extendable DPG solution to enable observability and action towards effective policy implementation in education and other sectors, involving various stakeholders across govt, society, and private sectors.

The architecture of cQube has been revised to enable flexibility in configuration:

* Spec-based architecture has been created for cQube Ed with API-first design
* There are 5 blocks: Installation > Ingestion > Processing > Visualisation > Actions
* All the blocks can be used individually and as an end-to-end solution by cQube adopters

The terminologies used in the architecture can be found [here](https://project-sunbird.atlassian.net/wiki/spaces/CQUB/pages/3258024044/cQube+Design+Document+Nov+2022#1.-Terminologies).

<figure><img src="/files/iHzvvcDAY4vYA1CsQbA1" alt=""><figcaption></figcaption></figure>

High-level architecture design can be found [here](https://project-sunbird.atlassian.net/wiki/spaces/CQUB/pages/3258024044/cQube+Design+Document+Nov+2022).

Low-level architecture design can be found [here](https://project-sunbird.atlassian.net/wiki/spaces/CQUB/pages/3266740614/cQube+LLD+-+v12Dec2022).


# Design Principles

* **Low Tech/Minimal Coding:** Leverage existing tools and provide configuration options to minimize the need for coding.
* **API First:** Design APIs for all functionality and blocks to enable independent evolution and integration.
* **Progressive Enhancement:** Allow for module changes and tiered improvements in the user experience.
* **Modularity:** Design modular blocks that can be selected and integrated based on specific needs.
* **Integrations:** Enable integration of higher-order capabilities through clear boundaries and APIs.
* **Ease of Deployment/Management:** Provide easy deployment options and support on commodity hardware or cloud platforms.
* **Scalable:**
  * **Ingestion:** Design scalable ingestion processes for real-time data updates.
  * **SLA Driven:** Strive for a 30-minute SLA between data ingestion and insight generation.
* **Performance:** Prioritize stable performance within specified hardware limitations.
* **Data Privacy:** Store only aggregated data and insights, ensuring no personally identifiable information is stored.
* **Accessibility:** Ensure accessibility on mobile and desktop devices.
* **Data Security:** Implement specific measures to safeguard data (further details required).

These design considerations aim to create a configurable, scalable, and user-friendly solution for effective data-driven governance in the education sector.

The detailed design principles of cQube, according to the architecture, can be found [here](https://project-sunbird.atlassian.net/wiki/spaces/CQUB/pages/3258024044/cQube+Design+Document+Nov+2022#3.-Design-Considerations).


# Key Components

This page outlines the key components of cQube

* **Installation:** The installation block enables easy deployment and setup of the cQube platform. It provides a streamlined process for getting cQube up and running quickly.
* **Ingestion:** The ingestion block handles the collection and validation of data from various sources. It ensures that the data is accurately captured and standardized for further processing.
* **Processing:** The processing block involves data transformation, cleansing, aggregation, and advanced analytics. It leverages the collected data to derive meaningful insights, identify patterns, and generate actionable intelligence.
* **Visualization:** The visualization block focuses on presenting the analyzed data in a visually appealing and intuitive manner. It includes interactive dashboards, charts, graphs, and reports that allow users to explore and understand the data easily.
* **Actions:** The actions block enables stakeholders to take informed actions based on the insights gained from the data. It supports evidence-based decision-making and provides a platform for implementing targeted interventions and policies.


# Details of microservices

* **Ingestion-ms:** The ingestion-ms is used to upload the data of the events, datasets, dimensions, transformers and pipeline. All these apis will be to ingesting the data into the cQube.
* **Spec-ms:** The spec-ms is used to import schema of the events, datasets, dimensions. All these specs will be defined by the cQube platform prior to ingesting the data into the cQube. These specifications are derived by considering the KPIs as the Indicator.
* **Generator-ms:** The generator-ms is used to create the adapters for converting the older input data format to newer format for VSK & NVSK programs.
* **Nifi-ms:** Apache NiFi is used as a real-time integrated data logistics and simple event processing platform
* **Postgres-ms:** Postgres microservice contains the schema and tables
* **Nginx-ms:** It is commonly used as a reverse proxy and load balancer to manage incoming traffic and distribute it to slower upstream servers
* **Kong-ms:** It is a lightweight API Gateway that secures, manages, and extends APIs and microservices.
* **Dashboard-ms:** It consists of an angular app, it is used to visualize the datasets present in postgres-ms in the form of charts. On run time it requests query-builder to fetch data from postgres-ms and load it into the client side(Browser)
* **Query\_builder-ms:** It consists of backend API, which consists of JWT,METRICS,QUERY apis

**JWT** - it will generate a jwt token to restrict the other apis.

**METRICS -** it consists of menus for the navigation bar and dashboard cards.

**QUERY** - this api used for executing the SQL queries which integrated with Dashboard-ms.

**LASTMODIFIED -** this api will use for the last modified data in the s3,azure and minio


# Suggested Team Structure

Shows you a list of things to help you get started with cQube V 5.0:

cQube v5.0, the latest version of cQube, enables monitoring of 9 out-of-the-box state and national education programs for performance improvement. All of these programs will be tailored to the user role and jurisdiction. Any new program can also be added by the state for monitoring purposes.

To get started with cQube, the following team composition is suggested:

| Type              | Language / Skills                     | Experience | Full-time people |
| ----------------- | ------------------------------------- | ---------- | ---------------- |
| Backend Developer | TypeScript, NestJS                    | 3+ years   | 1                |
| DevOps            | Docker, Ansible                       | 3+ years   | 1                |
| QA                | UAT                                   | 3+ years   | 1                |
| Tech Lead         | All of the above, & management skills | 5+ years   | 1                |

To enable any customizations/add new programs, following members are suggested in addition to the above:

| Type               | Language / Skills          | Experience | Full-time people |
| ------------------ | -------------------------- | ---------- | ---------------- |
| Backend Developer  | Nest.js, Python, NiFi, SQL | 4+ years   | 1                |
| Frontend Developer | Angular                    | 3+ years   | 1                |

\
The detailed skill sets required for each phase of the setting up process are mentioned below:

<table data-header-hidden><thead><tr><th width="191"></th><th></th></tr></thead><tbody><tr><td>Configure</td><td><ul><li>Knowledge of defining the grammars (dimensions, event) and verifying CSVs (data files for dimensions and events)</li><li>Basic knowledge of Pandas + Python to clean data if needed.</li></ul></td></tr><tr><td>Deploy</td><td><ul><li>Shell scripting, AWS, Ansible, Docker (build, deploy, update containers; Verify from logs connections)</li><li>Nginx, Networking, Ubuntu.</li></ul></td></tr><tr><td>Monitor</td><td><ul><li>Knowledge of defining the grammars (dimensions, event) and verifying CSVs (data files for dimensions and events) and KPI and their definitions</li><li>Basic of Database to verify SQL queries or construct new ones if needed</li><li>Ability to use GitHub to raise tickets, issues.</li></ul></td></tr><tr><td>Maintain</td><td><ul><li>Ansible, Docker (build, deploy, update containers; Verify from logs connections), Nginx, Networking, Ubuntu</li></ul></td></tr><tr><td>Enhance &#x26; contribute (Frontend)</td><td><ul><li>Angular 14</li><li>Good understanding of MVC</li><li>Understanding of javascript and typescript</li><li>Debugging skills; Basics of Dockerfile</li></ul></td></tr><tr><td>Enhance &#x26; contribute (Backend)</td><td><ul><li>Basic knowledge of Database to verify SQL queries or construct efficient new ones if needed</li><li>Knowledge of how datasets are created in cQube</li><li>NestJS, Typescript, Postgres</li></ul></td></tr><tr><td>Enhance &#x26; contribute (Ingestion)</td><td><ul><li>Should only be done by the core team</li></ul></td></tr><tr><td>Enhance &#x26; contribute (DevOps)</td><td><ul><li>Ansible, Docker, Nginx, Networking, Ubuntu</li><li>Worked previously on an IaC codebase (<a href="https://www.redhat.com/en/topics/automation/what-is-infrastructure-as-code-iac">https://www.redhat.com/en/topics/automation/what-is-infrastructure-as-code-iac</a>)</li></ul></td></tr></tbody></table>

## Supported Servers & Clouds

1. AWS - The steps to deploy cQube v5.0 on AWS have been mentioned [here](/deployment-process/aws-deployment)
2. On premise (State Data Centre, Local) - The steps to deploy cQube v5.0 on 'On premise' (State Data Centre, Local) have been mentioned [here](/deployment-process/sdc-deployment)


# Hardware Requirements

List of hardware requirements as pre-requisites for cQube V 5.0

### For  AWS :

Create an AWS EC2 instance with the following configurations:

* Ubuntu  22.04 (supported)
* 16 GB of System RAM (minimum requirement)
* 4 core CPU for AWS(minimum requirement)
* 250GB HDD
* S3 Storage

Other Requirements:

* Create a domain name
* Configure cname of AWS ec2  to the domain name
* Create a SSL certificate for the domain name.(which is applicable to configure with nginx )

**For  Azure :**&#x20;

Create an AzureEC2 instance with the following configurations:

* Ubuntu  22.04 (supported)
* 16 GB of System RAM (minimum requirement)
* 4 core CPU for Azure(minimum requirement)
* 250GB HDD
* Blob storage

Other Requirements:

* Create a domain name
* Configure cname of Azure ec2  to the domain name
* Create a SSL certificate for the domain name.(which is applicable to configure with nginx )

**For  Oracle :**&#x20;

Create an Oracle EC2 instance with the following configurations:

* Ubuntu  22.04 (supported)
* 16 GB of System RAM (minimum requirement)
* 4 core CPU for  2 OCPU for Oracle (minimum requirement)
* 250GB HDD
* Cloud Storage

Other Requirements:

* Create a domain name
* Configure cname of Oracle  ec2  to the domain name
* Create a SSL certificate for the domain name.(which is applicable to configure with nginx )

### For On-Premise (State Data Centre, Local):

One server is required with the following configurations:

* Ubuntu 22.04 (supported) \[[Link to install Ubuntu](https://ubuntu.com/tutorials/install-ubuntu-desktop#1-overview)]
* 16 GB of System RAM (minimum requirement)
* 4 core CPU (minimum requirement)
* 250GB HDD
* Minio Storage&#x20;

Other Requirements:

* Create a domain name
* Configure CNAME or A record of AWS ec2 to the domain name
* Create a SSL certificate for the domain name.(which is applicable to configure with nginx)


# Prerequisites Checklist

| Item                                                                          | Description                                                     | Automatic check/ manual check | Feedback to the user                                                                                                                                                                                                                                                                                                                                                                                                              |
| ----------------------------------------------------------------------------- | --------------------------------------------------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| OS                                                                            | Check if the os is ubuntu 22.04                                 | Automatic                     | Please use ubuntu 22.04 or above for the best experience                                                                                                                                                                                                                                                                                                                                                                          |
| RAM                                                                           | Check if the RAM is at least 16GB                               | Automatic                     | Highly  recommended to maintain minimum of 16GB RAM                                                                                                                                                                                                                                                                                                                                                                               |
| CPU                                                                           | Check if CPU is 4 core                                          | Automatic                     | 2 core CPU might work but we suggest to use 4 core to avoid any server hangs                                                                                                                                                                                                                                                                                                                                                      |
| Storage                                                                       | Check if storage is minimum 250GB                               | Automatic                     | Please ensure that the storage is at least 250GB & is an SSD                                                                                                                                                                                                                                                                                                                                                                      |
| Domain Name test                                                              | Validate if the domain name is valid                            | Automatic                     | <p><br></p>                                                                                                                                                                                                                                                                                                                                                                                                                       |
| SSL certs                                                                     | Check if the user has provided the certs                        | Automatic                     | Certificates which are compatible with nginx                                                                                                                                                                                                                                                                                                                                                                                      |
| Check ports ( 80,443,9000,9001,8000,4200,3000,3001,3002,3003,8096,5432,8080 ) | Check if the specified ports and running                        | Automatic                     | <p>Please kill the port by following the instructions below.<br><strong>sudo netstat -ntlp</strong><br><strong>Sudo kill -15 \<PID></strong></p>                                                                                                                                                                                                                                                                                  |
| Check for dimension files                                                     | Check if the required csv files are present in dimension folder | Automatic                     | Please upload the required dimension files                                                                                                                                                                                                                                                                                                                                                                                        |
| SSL certificate verification                                                  | Check if the SSL certificates are valid                         | Manual                        | Make sure the certificate has a full chain of certificates to avoid handshake issues of SSL.                                                                                                                                                                                                                                                                                                                                      |
| SSL certificates upload                                                       | Copy the certificates into the server                           | Manual                        | <p>If you are opting for public mode of installation, Make sure to copy certificates to the server.<strong>(</strong>Navigate to the directory cqube-devops/ansible/ssl\_certificates.</p><p><strong>Copy the certificate and private key inside this cqube-                   devops/ansible/ssl\_certificates folder )</strong></p>                                                                                             |
| Dimension files upload                                                        | Copy the dimension files to the server                          | Manual                        | <p>If you are opting for VSK and If you are willing to pull the data from NVSK, Then this step is required. <strong>( Navigate to the directory cqube-devops/ansible/ssl\_certificates.cp state-dimension.data.csv grade-dimension.data.csv subject-dimension.data.csv etc../home/ubuntu/cqube-devops/ansible.dimension\_files</strong></p><p>                 <strong>Path: cqube-devops/ansible/dimension\_files.)</strong></p> |


# Checking pre existing ports

Make sure the following ports are not running. If running please stop the service or kill the port

Security Group Configuration:

* Port 80 inbound from 0.0.0.0/0
* Port 443 inbound from 0.0.0.0/0
* Port 3005 inbound from 0.0.0.0/0
* 5432 inbound to the particular ip which needs access

Kong Configurations: ( already configured using one step deployment )

* 3000 will get routed to /api/ingestion
* 3001 will get routed to /api/spec
* 3002 will get routed to /api/queryBuilder
* 3003 will get routed to /api/generator
* 443 ( nginx is configured in cqube )

**Note:** we can check for the ports using the command **sudo netstat -ntlp** and can kill the particular port using its port id by command **sudo kill -15 \<PID>**

<br>


# Instance Creation

Here the links for how to Create the instance in Azure , AWS and Oracle&#x20;

1. [Azure ](https://learn.microsoft.com/en-us/azure/virtual-machines/linux/quick-create-portal?tabs=ubuntu)
2. [AWS ](https://www.techtarget.com/searchcloudcomputing/tutorial/How-to-create-an-EC2-instance-from-AWS-Console)
3. [Oracle](https://docs.oracle.com/en/cloud/cloud-at-customer/occ-get-started/create-oracle-linux-instance.html#GUID-77D03EFA-ABAA-4ED5-ABC8-9CA756B9D6BF)


# Copying SSL Certificate

Below are the steps to copy SSL certificates from a local source to Ubuntu and from Windows to Ubuntu.

**From Local to Ubuntu:**

1. Please find the below command  to copying ssl keys from local ubuntu to ubuntu server&#x20;

&#x20;               sudo scp -i poc\_key.pem \<Name of the SSL keys > ubuntu@\<IP>:\~/

2. After copying the files from local to server then we need to move the SSL keys (.crt and.key) to the mentioned path.

&#x20;              Path: cqube-devops/ansible/ssl\_certificates

&#x20;              cp \<ssl certificates> /home/ubuntu/cqube-devops/ansible/ssl\_certificates

**From Windows to Ubuntu:**

1. Please find the below link  to copying ssl keys from windows machine to ubuntu server(winscp,filezilla)

&#x20;             <https://www.hostgator.com/help/article/how-to-transfer-files-with-winscp>

2. After copying the files from windows to server then we need to move the SSL keys (.crt and.key) to the mentioned path.

&#x20;            Path: cqube-devops/ansible/ssl\_certificates

&#x20;             cp \<ssl certificates> /home/ubuntu/cqube-devops/ansible/ssl\_certificates


# How can I install cQube?

Under this topic we will get some understanding about High level Understanding of deployment.&#x20;

How to set the instance:

1. [Oracle  Installation ](https://cqube.sunbird.org/use-cqube/getting-started/oracle-instance-setup)
2. [AWS Installation](https://cqube.sunbird.org/use-cqube/getting-started/aws-installation)
3. [SDC Installation ](https://cqube.sunbird.org/use-cqube/getting-started/sdc-installation)
4. [Azure Installation ](https://cqube.sunbird.org/use-cqube/getting-started/azure-installation)


# High level understanding of deployment

<figure><img src="https://lh6.googleusercontent.com/jU-BLw2SrNI4sly0I3FGLJGDzdUazW575-pjxVHp7LdGwKoC8QrRZBe1bPmxORILBd2m59mfyqt07IlSwiohjh6T99Fw3UTfP0vawhdmFec5qiAd9zmScX_5GEcn2rB2SC0a5ZvdMXGpwmfTlhGvcYg" alt=""><figcaption></figcaption></figure>


# Oracle Installation

Instance Setup in Oracle Cloud:

**Step 1:** Create an instance with Ubuntu 22.04(Oracle Linux ) image, 2 core OCPU, and 16GB RAM

<figure><img src="https://lh7-us.googleusercontent.com/txzf_6TL9dajtvyVB_ctLclivrhHamVdVtR--XUqSy34FR8Pjgi9261dPSVMuSSudFJs7el5KRnf49Oi6TPEJr-CnBOCCS3NtzC2NLgfXCAVslSPFTFfVicCTLL3VOB-nqf2kzqnmqUrdeyX2MXHa9s" alt=""><figcaption></figcaption></figure>

**Step 2:** Download the private key file associated with the instance.

<figure><img src="https://lh7-us.googleusercontent.com/rumaDQ75o8ycg8M-7MZx9QGIjKe2UDzUhKOblKWKbgBjV9NUbnJiq_YtBf9VgYxVN1Yb1pnhc6_fRVg82I0JLGmCkuqFZYClAWgYT2gTvSwPv5EWMxrO6yRSlsX7-8P2O2IFUHK193KzE3TwGqyGwWg" alt=""><figcaption></figcaption></figure>

**Step 3:** Create a Storage Bucket

Go to the Oracle Cloud console and create a bucket with default configurations.

<figure><img src="https://lh7-us.googleusercontent.com/NNIOHuVaRTkKwK3aIju19DK6e_W6iTM14-9vUogiuLn0i3fq1jnBLjqGyBizl84Q0S429bon7WHHcH7WyZZ6M617tLm-FT_Z4fcxjDU24DzRtVoERNEybsDJcd6uT2znUUDNZrKRu-7q5GU-DceRsTQ" alt=""><figcaption></figcaption></figure>

**Step 4:** Generate Config File in Oracle Cloud

Login to the Oracle Cloud account and navigate to the profile section

<figure><img src="https://lh7-us.googleusercontent.com/t69xbC99kuUkrTGbCeFzFu8-HDKbos0wqnLaA-mR6q_5P4D2OsT3h2IWlK70tAMETTsCWb5X6ern8tdgFUTofuGHubXh5ibsV7CGaKjxPIuAG3wpHgEmy6_g9PUCipbb_jPfibHgaQXiqUxb-0vDIN8" alt=""><figcaption></figcaption></figure>

Generate a new key pair in the API keys section and download the private key file

<figure><img src="https://lh7-us.googleusercontent.com/czRkrDc0W3jXJwLMTJrHa9O_68ajQJxb0F5eRP4tHC2e0sqV1-brMOjDyyFCVxUd2WGehfGqJb5vOvgNCCV4uAVOE638HyW4S-8Qp-g3Wcaccgm9TnFx1YGGJp86m9l7p2mVdgOQ34abutwxEobOioI" alt=""><figcaption></figcaption></figure>

Copy the content of the configuration file for future use<br>

<figure><img src="https://lh7-us.googleusercontent.com/mMxrmYwcg15Q7ho7u2ouN4MBfSY11B8cAv0rWOzuMulfgFnxy2OFIMR4zMyu0kgvzQSfMzXcXpoj2s4UdZ97WA_XDqyqCa9yu6NTp8HreYs_KYmXhFHjcCBDp3mMVlu7IWjQJkaWH0VjzFSt0dILkd8" alt=""><figcaption></figcaption></figure>

**Upload the API Key File to the cQube Server:**

* Connect to the cQube server using SSH.
* Copy the Oracle API private key file to the server using the command:

&#x20;                    scp -i \<pem\_file\_of\_server> \<private\_key\_of\_oracle\_api> ubuntu@\<ip>:\~/

* Switch to the root user:

&#x20;                     sudo su

* Move the private key file to the .oci directory:

&#x20;                     mkdir /root/.oci && cd /root/.oci&#x20;

&#x20;                     mv /home/\<system\_user\_name>/\<private\_key\_of\_oracle\_api> .

* Verify the presence of the file in the current directory:

&#x20;                      ls -ltr

* Exit from the root user and continue with the cQube installation.

**Instructions to fill the Oracle config variables during installation:**

* Copy the config file to the desired location (/root/.oci/config).
* Open the config file and replace the following placeholders with actual values from the API key config file:

&#x20;                   User OCID

&#x20;                   Tenancy OCID

&#x20;                   Region (by index or name)

* Decide whether to generate a new API Signing RSA key pair.

&#x20;                 If declining, provide the path to an existing key.

* Specify the location for the API Signing private key file               (/root/.oci/\<private\_key\_of\_oracle\_api>).

**(Note: Bucket should be created manually before installation process starts)**

**Oracle bucket policy creation steps**

**(Note : These policies are applicable for NVSK data pull)**

**Step 1:** Initially, log in to the Oracle Cloud using the credentials, as illustrated in the screenshot below.

<figure><img src="https://lh7-us.googleusercontent.com/pLOZPIB7B-_mrlY4hKyq_j5CPNET_mU4HB6lR2DzIxQaekGa7i3nYZqHPF4fPD4NWN5wa_Z6APzaObRo8O7afYaCYN-IvnpM5H4yLgmbLSgFjWZuagFP_7aJLX7iVKs70FXASALEZAS2S0NUnNvmGsA" alt=""><figcaption></figcaption></figure>

**Step 2**: Following the guidance from the above screenshot, please type “policies” into the search bar, as depicted in the screenshot below.

<figure><img src="https://lh7-us.googleusercontent.com/z-pPcXYBmSjwTtBoisq1fVBDkb4Ya1sIAC3D77bfP_kVoGtNLSX1uN60skrfHwJWfF3w-zwoWs7EFSC7UPs_eRc-KIaBbpgR-qE1pMFmSUQTJ0yp_YaIzkyFymAo9glMcKOGNEZTmPqBcMbDfjMXXGc" alt=""><figcaption></figcaption></figure>

**Step 3:** Simply click on the policies option and proceed to create new policies, as shown in the screenshot below.

<figure><img src="https://lh7-us.googleusercontent.com/r9wWCuwMUlLzlBEPW96QKEGD7owjweup28rCUzGRa37rpryx0Hrf8PVCZDz2Ehdnst5bI6-yNptx5tLpxdQuCJ2q6WxMMJRluH5PXal-KEqLrLBWZYMWuBVX95WqSpgjoT9WsDJwS8Lm2XAnYG7r56o" alt=""><figcaption></figcaption></figure>

**Step 4**: We already have some existing policies. Please refer to the attached screenshot for more details.

<figure><img src="https://lh7-us.googleusercontent.com/91MFvpfGfJ4VJnUTbkvFrWuSaIpNZfJY7525zxw1JyRlWOSkKiCzJhvEMmvIf-_Oa5FQxh1Z-jXc00A-Ck6NyvFaJbsyAAHHbo35bY1eDL3c8JkGfe_oLpy00qZYaDXFC3j2Yo-VSXX42w0oiP_h0wc" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh7-us.googleusercontent.com/Ma81_AZH3l2_W-U8mIwhex7ds9w9bIBDGAXR4uj8OJXZfDt6taemGHfKEKEIvmxNUvL8_f9EZmf-pXhSlUykt_BekLdovEguGt9qmlSNmn3iVg-kOheH_oMw7ix0NW_XuGZGf1ZJ1X8iYFQXVcbn1JM" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh7-us.googleusercontent.com/uZg7WiAdSNROf6EluWwqe6zF3Yt4dir__UVsIK_slXfp0BJ0a-D8mCRGw0SXOfHskd2AtS3VRa8c-yW-1PrYhhxqe2pR5MWoUpcOu17navDh7PMpiAJqsjbRjfIttl33BCzsVVL2ucCG5Dox5Iu1Q8g" alt=""><figcaption></figcaption></figure>

**Primary Steps:**

**Step  1:** A SSL certificate must be uploaded if you are opting for the public mode of installation where you want to access cQube using a public API endpoint.&#x20;

**Note :** You can ignore the above step if you are opting for localhost installation (single desktop).

Connect to the cqube Oracle instance

&#x20;       ssh -i \<path\_to\_the\_pem\_file> \<user\_name>@\<public\_ip\_of\_the\_instance>

&#x20;       Ex: ssh -i poc\_key.pem -o ServerAliveInterval=60 ubuntu\@13.200.12.31&#x20;

**Step 2:** Clone the cqube-devops repository using following command

&#x20;                **git clone** [**https://github.com/Sunbird-cQube/cqube-devops.git**](https://github.com/Sunbird-cQube/cqube-devops.git)    &#x20;

<br>

<figure><img src="/files/Tfcvl3xMU1z8X3lfNu5C" alt=""><figcaption></figcaption></figure>

**Step 3:** Navigate to the directory where cQube is cloned or downloaded and checkout to the desired branch

&#x20;                       **cd cqube-devops/**&#x20;

&#x20;                        **git checkout release-v5.0.5(latest release branch)**

<figure><img src="/files/cHI8ldwsBRM8iOinMbhG" alt=""><figcaption></figcaption></figure>

**Step 4:** Navigate to the directory cqube-devops/ansible/ssl\_certificates.

&#x20;                     **Copy the certificate and private key inside this cqube-                   devops/ansible/ssl\_certificates folder.**

<figure><img src="/files/RUSmhiPucZZilPo5uXmr" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/NphLIq2eVwOHR4myIZBm" alt=""><figcaption></figcaption></figure>

**Step 5 :** If you are opting to pull the data from the NVSK instance, then make sure to upload the dimension files. If you do not want to pull the data, then you can ignore this step. (Applicable if you choose access type VSK).

If you are opting to pull data from an NVSK instance, then make sure to copy the dimension files inside cqube-devops/ansible/dimension\_files

<figure><img src="/files/KRpGvKejJXeKnGLQh5XM" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/iPLSsqMJuEOzzBp7xj8t" alt=""><figcaption></figcaption></figure>

Once all the primary steps of uploading SSL certificates and dimensions are done, we can check prerequisites using the script.

**Navigate back to cqube-devops directory**

**Step 6**: Give the following permissions to the pre\_requisites.sh file

&#x20;          **sudo chmod u+x shell\_scripts/pre\_requisites.sh**

**Step 7:** Run the pre\_requisites script with non root user with sudo privileges

&#x20;                 **sudo ./shell\_scripts/pre\_requisites.sh**

<figure><img src="/files/ZpuGQh7p2qZqkyDcz4J4" alt=""><figcaption></figcaption></figure>

**Step 8 :** When steps 6 and 7 are done, you will see the feedback from status checks.

**Step 9:** Go through the feedback provided, and if you find any issues in red resolve them by following the hints provided. If everything is good then proceed with cqube deployment.

**Deployment  Process:**&#x20;

**Step 1:**&#x52;efer to the prerequisites checklist section before starting the cqube deployment.-[ Link ](https://app.gitbook.com/o/-Mi9QwJlsfb7xuxTBc0J/s/-Miy6UN-HyTKGo2Sjcky/~/changes/326/get-started-on-cqube/prerequisites-checklist)

**Step 2:** Navigate to cqube-devops directory and give the executable permissions to the install.sh file

&#x20;                         **sudo chmod u+x install.sh**

**Step 3:** Install cQube with non root user with sudo privileges

&#x20;                     **sudo ./install.sh**

<figure><img src="/files/Y5P7nDp6WaPeONFcHcNg" alt=""><figcaption></figcaption></figure>

Install.sh file contains a shell script where it will run shell scripts and ansible-playbook to setup the cQube

**Step 4:** Generation of domain specific configuration file - Please refer to the Hints provided and enter the values accordingly.

* access\_type: Enter VSK, NVSK, or others.

&#x20;           a) VSK: To set up VSK for a state

&#x20;            b) NVSK: To establish a nationwide cQube deployment

&#x20;                   c) Others: To set up cQube for other purposes.

* state\_name: Enter the required state code by referring to the state list provided (this variable needs to be filled if you are opting for access\_type as VSK; otherwise, it will get filled as NA by default).
* loginpage\_status: Enter true if you want to enable the login screen for the CQUBE instance. Otherwise, enter false.
* data\_pull\_status: Enter true if you want to pull data from an NVSK instance, or else enter false. (You need to fill this variable if you have selected access\_type as VSK; otherwise,  it will get auto-filled with NA.)
* nvsk\_api\_endpoint: Enter the NVSK instance api endpoint if you selected true for data\_pull\_status; otherwise,  it will get autofilled with NA.

Once all the above variables are filled, you get prompted with a preview of the domain-specific config file. Review the entered variables. If everything is correct, then type ‘no’ and proceed further, or else enter ‘yes’ and re-enter the variables correctly.

<figure><img src="https://lh7-us.googleusercontent.com/MDlCBoqU-lr2GHTIzCZ1xVfcTgDFgE7JUhyQcnZXofCDeawg2c0sW9dhLDj-AU_v3-P1hYYykt1UzggBu5Fahksjq61Fc6jptbmodTxPqy-70Xtyy5vTbkY_yj5LAdTCQ8RXqsXESc6n_zd0aq8mTLM" alt=""><figcaption></figcaption></figure>

**Step 5:** Generation of a generic config file: refer to the hints provided and enter the config file accordingly.

* mode\_of\_installation: Enter public as you have opted for setting up cqube in AWS. (Possible values are public and localhost.)
* storage\_type: Enter storage type as oracle. (Possible values are aws, azure, oracle, and local.)
* api\_end\_point: Enter the url in which the clock is to be configured.
* nginx\_cert\_file: Enter the name of the SSL certificate file that you uploaded in the SSL\_certificates folder.
* nginx\_key\_file: Enter the name of the private key file that you uploaded in the ssl\_certificates folder.

  * Db\_credentials: You will be prompted with default database credentials. If you want to continue with the same, enter no; otherwise, enter yes and proceed to enter your database credentials.

    db\_user\_name ( Enter the postgres database username )&#x20;

    db\_name ( Enter the postgres database name )

    db\_password ( Enter the postgres password )

    <figure><img src="https://lh7-us.googleusercontent.com/RHH2JTaOxXFWkSxPeqCHe25m5LjrdZd6otIttzZQNC97yA90ayMhDfEZLI-hvH9H2LueYbRSrnzM0s9EaSs4SZmvFERw8yufdYyP8KKvIWkEkE0wD7X0LTY0XM4Ku29P_VMq9AjBGgHH5Qgkz8wsl14" alt=""><figcaption></figcaption></figure>

    <figure><img src="/files/vBD1tsssBiK7iH0YgypF" alt=""><figcaption></figcaption></figure>

    * Readonly\_db\_credentials: You will be prompted with default read-only database credentials. If you want to continue with the same, enter no; otherwise, enter yes and proceed to enter your read-only database credentials.

      &#x20;      read\_only\_db\_user\_name ( Enter the postgres database username )&#x20;

      &#x20;      read\_only\_db\_password ( Enter the postgres password )

    <figure><img src="/files/9H4YhLHOc7bQIuEflpxp" alt=""><figcaption></figcaption></figure>

    * Keycloak\_credentials: You will be prompted with the default keycloak admin dashboard credentials. If you want to continue with the same, enter no; otherwise, enter yes and proceed to enter your keycloak credentials.

    &#x20;          Keycloak\_adm\_name (Enter the keycloak admin name eg: admin)

    &#x20;          Keycloak\_adm\_password (enter the keycloak admin password eg: Admin\@123)

  <figure><img src="/files/SfAV8sVElOqQMEKD3Q4Y" alt=""><figcaption></figcaption></figure>

  **Step 6:** Once the config file is generated, a preview of the config file is displayed, followed by a question where the user gets the option to re-enter the configuration values by choosing ‘yes’. If option ‘no’ is selected, then the install.sh moves to the next section.

<figure><img src="https://lh7-us.googleusercontent.com/qPp5Y-L2b-bkFSUVBWkODbMlOdlz2k0dhHjZ7EcqLccLqcnG0tuuJYrwLNbzZNA0pl03or2zGU5_opJuEAq8rdvtDdTBvQVXYcQgES8NZ0ZChNKs4kWy4AP04yjbzj1gHiDSQtiX24Br7CqtfJhRysA" alt=""><figcaption></figcaption></figure>

* Enter a location for your config \[/home/basha/.oci/config]: /root/.oci/config (enter)
* Enter a user OCID
* Enter a tenancy OCID
* Enter a region by index or name: ap-mumbai-1
* Do you want to generate a new API Signing RSA key pair? (If you decline you will be asked to supply the path to an existing key.) \[Y/n] : \<Click n> n
* Enter the location of your API Signing private key file

Ex: /root/.oci/itadmin\@tibilsolutions.com\_2023-04-18T10\_08\_35.916Z.pem

<figure><img src="https://lh7-us.googleusercontent.com/BzRt1ckZGYT2PYW0URtRGPHD1yyiXmb4HG6xwlA7-DiTHnm3sYvmLCvsEI4E4Qq5sgBc5ztb4efERKJd2Jjw5aIbhGwptfOcv_tm2iF9jiGDPr_bNMu8PQY3bQf2pxTmZKvoj4iHIuTrOLhpCjuP14U" alt=""><figcaption></figcaption></figure>

**Step 7:**  A preview of the program\_selector.yml file is displayed, followed by a question where the user gets an option to enable or disable the programs by choosing 'yes'. If option 'no' is selected, then the install.sh moves to the next section.

&#x20;1\.   If access\_type is selected as VSK, the following programs will be displayed: by default, all programs are selected, and the programs are publicly visible.

<figure><img src="/files/gg8cz7sPcl2ICrPZeV1h" alt=""><figcaption></figcaption></figure>

**Note:** If you are willing to select the programs, type yes, select the programs you want, and enter public or private for each program to enable or disable the login screen for programs (follow the hints provided).

2. If access\_type is selected as NVSK, the following programs will be displayed: By default, all programs are selected, and the programs are publicly visible.

<figure><img src="/files/nJ8KumBl7QGTc1eFTp0f" alt=""><figcaption></figcaption></figure>

**Note:** If you are willing to select the programs, type yes, select the programs you want, and enter public or private for each program to enable or disable the login screen for programs (follow the hints provided).

**Step 8:** Once all the configuration files are generated, the script moves further to clone the cQube microservice repositories and deploy cQube

**Step 9:** If you selected data\_pull\_status as true, then you will see the data pulling APIs where the data gets pulled from the NVSK instance and processed in the VSK cQube Once installation is done, we need to wait 20 minutes to visualize the data on the cQube dashboard.

**Step 10:** Once the installation is completed, you will be prompted with the following messages and required reference urls:

**(Note: The installation process is expected to take approximately 30-40 minutes.)**

**cQube Installed Successfully**

<figure><img src="/files/0RwTzP2WH6tcNj18OiVC" alt=""><figcaption></figcaption></figure>

<br>

<br>


# AWS Installation

IAM user and Role creation for S3 connectivity (AWS)

An AWS Identity and Access Management (IAM) user is an entity that is created in AWS to represent the person or application that uses it to interact with AWS. A user in AWS contains a name and credentials. An IAM user with administrator permissions is different from the AWS account root user. One has to create an IAM user with a supported role to provide the connectivity between EC2 and S3. The role should have list, read, and write permissions.

**Primary Steps:**

**Step  1:** A SSL certificate must be uploaded if you are opting for the public mode of installation where you want to access cQube using a public API endpoint.&#x20;

**Note :** You can ignore the above step if you are opting for localhost installation (single desktop).

**Step 2:** Clone the cqube-devops repository using following command

&#x20;                **git clone** [**https://github.com/Sunbird-cQube/cqube-devops.git**](https://github.com/Sunbird-cQube/cqube-devops.git)    &#x20;

<figure><img src="https://lh5.googleusercontent.com/UjoUhbupTuK24BEdYb_SXBRsE-rLCtD5f7uk9dg33z-REsD-teRvFTK--lV-UVnM_YtHhnFqEljUAhfC2fH2Htx6u213g_mcnV6X0HcXm_UapobOFOwwgOPj1BLDfAO_ugB0JGd3n1vxGfkjvpIwgmc" alt=""><figcaption></figcaption></figure>

**Step 3:** Navigate to the directory where cQube is cloned or downloaded and checkout to the desired branch

&#x20;                       **cd cqube-devops/**&#x20;

&#x20;                        **git checkout release-v5.0.5(latest release branch)**

<figure><img src="https://lh5.googleusercontent.com/E_OgyUFO8XlcHce_ewm--W_fs3kEi8pACeSncu30SlO09NG7G3yrfU8LiGjMieVCHsQAUuRDxtrPlrXXyocoJ4hwNBYKYX3U1Zwr994d6znC2rOt6neOX3VicuFB16R21NKSG7s2iBQBloiYTqF4MWo" alt=""><figcaption></figcaption></figure>

**Step 4:** Navigate to the directory cqube-devops/ansible/ssl\_certificates.

&#x20;                     **Copy the certificate and private key inside this cqube-                   devops/ansible/ssl\_certificates folder.**

<figure><img src="https://lh4.googleusercontent.com/Wr-sri7bGZATnpBooUYO6vDQJdLZQh8pi3mDhhm9lQzAkacsn_FLBwAa1_8oiVG0BRq81msG3QsBRa79l_KL7BN-Vs8S-JgKItFAcTN4H7_V9rdieto5B4AQPXdtqdtInbZ212f7uyNS_7TBQYUo5Ss" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh3.googleusercontent.com/EVMpEfmKC-N3SyOIP-F0-HkJaoo2an1hA-8Nq-UKguuR5C19k-dwqz8WdFE3YwGVjvDI6WvhZmS25O0vE1XxLjTiIJheMVL3LhXePgLmalVQWViV6Nfp6tdT85-33K3NzIV0sQngPp1-GDLgqV19044" alt=""><figcaption></figcaption></figure>

**Step 5 :** If you are opting to pull the data from the NVSK instance, then make sure to upload the dimension files. If you do not want to pull the data, then you can ignore this step. (Applicable if you choose access type VSK).

If you are opting to pull data from an NVSK instance, then make sure to copy the dimension files inside cqube-devops/ansible/dimension\_files

<figure><img src="https://lh5.googleusercontent.com/ZCuFEZA2V1fU9pdBSa2-6tLaGYTpebXzmepl3yYMOtOKLnYDXAYX6bGa0bkrTrZQacyc9Ir8QDd6gZ7-RE6tf_4cYdiLDavdskNfYZK4mXJPV69Z51hQ-68mNUqVo87L4kvjQ--QNryFwRpmAGJX8qQ" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh6.googleusercontent.com/TiNfl0zmceZ2BXtfHPo1KqZPcwaNjo_4aIqZjoOuZkFRoIO-DlAUnFrKGWosGtoFLLI9gd0U_aSPs16JbGUBkymm0keQKORBnL3GHrkeVOzEOhRg8JIm9QcMUh_3Gign_g6G4ojoI-3eCj8bIvW4N64" alt=""><figcaption></figcaption></figure>

Once all the primary steps of uploading SSL certificates and dimensions are done, we can check prerequisites using the script.

**Navigate back to cqube-devops directory**

**Step 6**: Give the following permissions to the pre\_requisites.sh file

&#x20;          **sudo chmod u+x shell\_scripts/pre\_requisites.sh**

**Step 7:** Run the pre\_requisites script with non root user with sudo privileges

&#x20;                 **sudo ./shell\_scripts/pre\_requisites.sh**

<figure><img src="https://lh6.googleusercontent.com/UZrSv7qjKeHyKyH9c3q6qB-LhvQ_FhlV2um3kzPLwsRYF_-UHbSRdqHtJHNf77BWIYad5nI2pDiv2-_96aGv6EjXDHFkUWW-dy7y4BVCcTnPO_k6bm_XqBCdRNOpMGoVSICk7t5TTbNleobiPsPqDTQ" alt=""><figcaption></figcaption></figure>

**Step 8 :** When steps 6 and 7 are done, you will see the feedback from status checks.

**Step 9:** Go through the feedback provided, and if you find any issues in red resolve them by following the hints provided. If everything is good then proceed with cqube deployment.

#### Deployment Process

**Step 1:** Connect to the cqube AWS ec2 instance

**For linux and macOS:**

* Download the .pem file which is generated while creating the EC2 instance
* Open the terminal and navigate to the folder where .pem file has been downloaded
* Then give the read permission to the .pem file using following command

&#x20;                       **sudo chmod 400 \<aws.pem>**

* Use the following command to connect to the instance

**ssh -i \<path\_to\_the\_pem\_file>  \<user\_name>@\<public\_ip\_of\_the\_instance>**

**For windows:**

* Download the .pem file which is generated while creating the EC2 instance
* Use puttygen to connect to the instance.
* Refer following link to use puttyGen for connecting.

  <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html>

**Step 2:** Refer to the prerequisites checklist section before starting the cqube deployment.-[ Link ](https://app.gitbook.com/o/-Mi9QwJlsfb7xuxTBc0J/s/-Miy6UN-HyTKGo2Sjcky/~/changes/326/get-started-on-cqube/prerequisites-checklist)

**Step 3:** Navigate to cqube-devops directory and give the executable permissions to the install.sh file

&#x20;                         **sudo chmod u+x install.sh**

**Step 4:** Install cQube with non root user with sudo privileges

&#x20;                     **sudo ./install.sh**

<figure><img src="https://lh3.googleusercontent.com/vooad-dKteZvHc2BAzhdpUKpbtQPVwhSkwsM44nkMQo8eb13orfphwl1NCQ87lG1ojxKjBclOlLQA9qjQUHhBFMyEYRGK96XdGnkniIvbz6SticcwZAM7M_f1wfHZ7luA7C0OYKn3zCQdFWwNdHF6P8" alt=""><figcaption></figcaption></figure>

Install.sh file contains a shell script where it will run shell scripts and ansible-playbook to setup the cQube

**Step 5:** Generation of domain specific configuration file - Please refer to the Hints provided and enter the values accordingly.

* access\_type: Enter VSK, NVSK, or others.

&#x20;           a) VSK: To set up VSK for a state

&#x20;            b) NVSK: To establish a nationwide cQube deployment

&#x20;            c) Others: To set up cQube for other purposes.

* state\_name: Enter the required state code by referring to the state list provided (this variable needs to be filled if you are opting for access\_type as VSK; otherwise, it will get filled as NA by default).
* loginpage\_status: Enter true if you want to enable the login screen for the CQUBE instance. Otherwise, enter false.
* data\_pull\_status: Enter true if you want to pull data from an NVSK instance, or else enter false. (You need to fill this variable if you have selected access\_type as VSK; otherwise,  it will get auto-filled with NA.)
* nvsk\_api\_endpoint: Enter the NVSK instance api endpoint if you selected true for data\_pull\_status; otherwise,  it will get autofilled with NA.

Once all the above variables are filled, you get prompted with a preview of the domain-specific config file. Review the entered variables. If everything is correct, then type ‘no’ and proceed further, or else enter ‘yes’ and re-enter the variables correctly.

<figure><img src="https://lh5.googleusercontent.com/pryTY65YLkTnovHGmfeSD-R7kI9iJ1i_HR-nsOlhNXbT0JGYB8jmcn4Xj-kyddvK0jj3xBV0Ydie8HVkzzuyGgxAxOI2g8MRzgRRBTwrDeHod45HSW_HpYGsurANuYOkrJ56gbJjRI4Uvn-oTgYtMqU" alt=""><figcaption></figcaption></figure>

**Step 6**: Generation of a generic config file: refer to the hints provided and enter the config file accordingly.

* mode\_of\_installation: Enter public as you have opted for setting up cqube in AWS. (Possible values are public and localhost.)
* storage\_type: Enter storage type as AWS. (Possible values are aws, azure, oracle, and local.)
* api\_end\_point: Enter the url in which the clock is to be configured.
* nginx\_cert\_file: Enter the name of the SSL certificate file that you uploaded in the SSL\_certificates folder.
* nginx\_key\_file: Enter the name of the private key file that you uploaded in the ssl\_certificates folder.
* Db\_credentials: You will be prompted with default database credentials. If you want to continue with the same, enter no; otherwise, enter yes and proceed to enter your database credentials.
  * db\_user\_name ( Enter the postgres database username )&#x20;
  * db\_name ( Enter the postgres database name )
  * db\_password ( Enter the postgres password )

<figure><img src="https://lh3.googleusercontent.com/dzP6FFmWaLIz8QwOHtXZy9LYg7ZR7afq33HJIQq7wLJDoRiScABiV8IvKX4Ewih_X3X_iLBrUYCle62zEW-D2pN23Fvj3nSaHX83D-5f-cqKjrJ-geV_4jNxGNqozNrGxNXkPVIa2A0cLB46_KX91Rk" alt=""><figcaption></figcaption></figure>

* Readonly\_db\_credentials: You will be prompted with default read-only database credentials. If you want to continue with the same, enter no; otherwise, enter yes and proceed to enter your read-only database credentials.

1. read\_only\_db\_user\_name ( Enter the postgres database username )&#x20;
2. read\_only\_db\_password ( Enter the postgres password )

<figure><img src="https://lh6.googleusercontent.com/bSMlVxvQRvTqsw2UbFRIOb28Ckk4eTN1_eMgqcXW-asrT5ChbL3Gy61PYQqEWYumIHv0mbkK-ERe-TxpivLHJeH_-2VIsy_dMa2goGWUTqr1f6fd8oUZWxnjefAY9cw5FrQH4e1lBt5AWbRzOlyKEkA" alt=""><figcaption></figcaption></figure>

* Keycloak\_credentials: You will be prompted with the default keycloak admin dashboard credentials. If you want to continue with the same, enter no; otherwise, enter yes and proceed to enter your keycloak credentials.

1. Keycloak\_adm\_name (Enter the keycloak admin name eg: admin)
2. Keycloak\_adm\_password (enter the keycloak admin password eg: Admin\@123)

<figure><img src="https://lh5.googleusercontent.com/-XIpmDt1ddcx42pw-uQFjkPhJBlWW-GJfxRAmnwAtNK1-PNuHW3_hPbUDz_2LPdLzXk5-2gDAFD5uZhQejSKJTfg3rnG9l99UZecMvmFZx4JYZfNTtC5sYWME3XwhmY52r1NvWS5z043ILqwOK5BUHo" alt=""><figcaption></figcaption></figure>

**Step 7:** Once the config file is generated, a preview of the config file is displayed, followed by a question where the user gets the option to re-enter the configuration values by choosing ‘yes’. If option ‘no’ is selected, then the install.sh moves to the next section.

<figure><img src="https://lh6.googleusercontent.com/0FhGW3sUZR1vXIx9wjz5bCislTL6J8nHe0q9v8oVeLFXs_ppZEwmAo7ABlwyCI7mcsOCMvZnjJQNsfIH4C8Y_psT-ZGuCM904kQT4U16vBIwQjkTRP9QdLQ-Mc-ERXmozrcZA_573dkCQPOLSUQw7W4" alt=""><figcaption></figcaption></figure>

**Step 8:** Generation of storage config file: Refer to the hints provided below and enter the config file accordingly.

* aws\_access\_key: Enter the aws s3 access key to access the s3 bucket.
* aws\_secret\_key: Enter the aws s3 secret key to access the s3 bucket.
* s3\_bucket: By default, an s3 bucket is selected. If you get an error because the bucket already exists, type a unique bucket name and proceed further.

**Step 9:**  A preview of the program\_selector.yml file is displayed, followed by a question where the user gets an option to enable or disable the programs by choosing 'yes'. If option 'no' is selected, then the install.sh moves to the next section.

1. &#x20;If access\_type is selected as VSK, the following programs will be displayed: by default, all programs are selected, and the programs are publicly visible.

<figure><img src="https://lh3.googleusercontent.com/-zZmhvyhBxS-jAPpN14zsnMsSsdWsz-6aBIO1Tfr3lu-QIVy4pTbCo-b6Bt4CJ77r8JpY4XERl2glridREEto6FUyT5RgJO381SVrUQ-bLnYuXNWfykALSrGbwfWavyNLSWQquWnMa0oisuurynepN4" alt=""><figcaption></figcaption></figure>

**Note:** If you are willing to select the programs, type yes, select the programs you want, and enter public or private for each program to enable or disable the login screen for programs (follow the hints provided).

2. If access\_type is selected as NVSK, the following programs will be displayed: By default, all programs are selected, and the programs are publicly visible.

<figure><img src="https://lh3.googleusercontent.com/7vvQny2i_KaBOYET4imE9Xjuclhbg_ckqFiX7zY3soM9SmvWmMahSaIV5CyiLlD-AcIIwPWu4aojqkBeRt9pMiQL8i0_jb5-FgzwYIHK8DrbU8SdWfJQwMm3EbO5Ujq0rLq7xuaRHmUUKSostQ5tRUA" alt=""><figcaption></figcaption></figure>

**Note:** If you are willing to select the programs, type yes, select the programs you want, and enter public or private for each program to enable or disable the login screen for programs (follow the hints provided).

**Step 10:** Once all the configuration files are generated, the script moves further to clone the cQube microservice repositories and deploy cQube

**Step 11:** If you selected data\_pull\_status as true, then you will see the data pulling APIs where the data gets pulled from the NVSK instance and processed in the VSK cQube Once installation is done, we need to wait 20 minutes to visualize the data on the cQube dashboard.

**Step 12:** Once the installation is completed, you will be prompted with the following messages and required reference urls:

**(Note: The installation process is expected to take approximately 30-40 minutes.)**

**cQube Installed Successfully**

<figure><img src="https://lh6.googleusercontent.com/LCFZH9xuBbl55esbiqJXn-uvnFec2JcAobp3lzAezKHaJzgTxkP2zDgnd8iDysdqO1Z5aog7kCD14B4uOpFo3bSW9OxLDFsa2Dl0BiZyOuT-16tEW3GEHIpsYAIrprC_6hDQwfe1Ci1eVjPQT57faKU" alt=""><figcaption></figcaption></figure>

<br>

\ <br>


# SDC Installation

**Step 1:** Use the following command to connect to the On-premise instance

&#x20;     **ssh -i \<path\_to\_the\_pem\_file> \<user\_name>@\<public\_ip\_of\_the\_instance>**

&#x20;      **Ex: ssh -i poc\_key.pem -o ServerAliveInterval=60 ubuntu\@13.200.12.31**&#x20;

**Step 2:** Clone the cqube-devops repository using following command

&#x20;        **git clone** [**https://github.com/Sunbird-cQube/cqube-devops.git**](https://github.com/Sunbird-cQube/cqube-devops.git)    &#x20;

<figure><img src="https://lh4.googleusercontent.com/LVrcmhInvNGnFXBZ2ZRHWZMqBGRqCX9DKsXteWhbRmV6X6EPDDo7TDOnwyDKjgahfIVWnnqsrXZ31AXnc5HOpDgcZEKdaBQN64bli_8wbM4xHZxmICUKdKIsXIkfqYGiXvE70Ryxtvnv0sttt0KbQnQ" alt=""><figcaption></figcaption></figure>

**Step 3:** Navigate to the directory where cqube is cloned or downloaded and checkout to the desired branch(Release Branch)

&#x20;                  **cd cqube-devops/**&#x20;

&#x20;                    **git checkout release-v5.0.5(latest release branch)**

<figure><img src="https://lh4.googleusercontent.com/qGnkWolEPHARu8cx0EFfpfyErug71YUFL6BzcboIVFdeKbZcrnnGtPJX3K4bRWTOJ9z3_LqR7LG5UWaVd3FkBcAuQA4Op8v_SW7DhsKL3Mk06TrIHX3zR0hRfgUTOKqUtSag5H01zkoK7kTIRMJ-ZPo" alt=""><figcaption></figcaption></figure>

**Step 4:** Give the following permissions to the install.sh file

&#x20;                 **sudo chmod u+x install.sh**

**Step 5**: Install cqube with non root user with sudo privileges

&#x20;                **sudo ./install.sh**

<figure><img src="https://lh3.googleusercontent.com/8-TCjndfNmhcIz0VcBUThl0Tt7D0eabbgLg6BFNZBLP1PDysbYUIjQXbkE7S2COFUfCg-qrD7MkZIzGITkzEQcYrzqSmrHudpWKKLFU62AdAKOiP_of_DII9H4keBrEZKyRYY-ihPNf2KA1Dcmm-d_Y" alt=""><figcaption></figcaption></figure>

Install.sh file contains a shell script where it will run shell scripts and ansible-playbook to setup the cQube

**Step 6:** User Input Variables - These are the variables which need to be entered by the user by following the Hint provided

* state\_name ( Enter the required state code by referring to the state list provided )
* api\_end\_point ( Enter the url in which cqube to be configured )
* Storage\_type : Local
* Mode\_of\_installation:Public

<figure><img src="https://lh7-us.googleusercontent.com/gnwQZz6PuxXxfl0x78YpgyLcpcfnqrDaiWdP0Xg0PH-FHvZQ8YSNJeFoFw6aen46d7bw6L4kZ7ScyDxac0izcwG85HTWB-sWpncqFYtiTnXTzwI4lOAD-Re3AQlgzgf_E2Dwe8QkU5fowLxYSF4zL6A" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh7-us.googleusercontent.com/X4cUgnfrkKYEr050YuD-gDpaa7F-XrtcRGdWR3aDoPTXs2UqWnsIaP6lLRCQ3dxz0-_KHwUb9wCYPf42Wlu3N908tHPxwYVLwjwsJRVA4HAaus3TW3wiWhLIAt5HSYkHH5Ngk9N3Zp5LP7WJCHeqNk4" alt=""><figcaption></figcaption></figure>

**Step 7:** Optional\_variables- Database credentials contain default values. If the user wishes to enter their own credentials then the user should opt for yes to enter their credentials otherwise can opt for no when the question pops up

* db\_user\_name ( Enter the postgres database username )&#x20;
* db\_name ( Enter the postgres database name )
* db\_password ( Enter the postgres password )

<figure><img src="https://lh5.googleusercontent.com/PQSTfzWT0BPjtTe72EuCIiDxpO10S6XPn7Mv66t30yyuerrjWb4B9oUMtojPUjyeAwakZgOxQLpnY0VkHJN4i1g7BOWjYBh3C5EZXafu16YSZtbdUnTfh4mbdpCna0JuWBpbVPJUUU_Y_dtL6Bf6xUY" alt=""><figcaption></figcaption></figure>

**Step 8:** Once the config file is generated, A preview of the config file is displayed followed by a question where the user gets an option to re enter the configuration values on choosing yes. If option no is selected then the install.sh moves to the next section.

<figure><img src="https://lh4.googleusercontent.com/xIyf4G-HwzWAB0L9y-sFwH1s7jfXnoQB9G0oSRbVjlUNvzLh2QdlKY9W6dgeKcRocoL4koqk1nLBEwU7OGQV4ui1mpK6_l-9xDtk85UuL6Md6cRmiogUjfeJW02FF5abNuKvUwYqSLydl7uVeFXgXa0" alt=""><figcaption></figcaption></figure>

**Step 9:**  A preview of the program\_selector.yml file is displayed followed by a question where the user gets an option to enable or disable the programs on choosing yes. If option no is selected then the install.sh moves to the next section.

<figure><img src="https://lh5.googleusercontent.com/84BynE9o-c4gHYwC5w_2GjkzCI1KxO1IrgVCK5cz_x6px4cweNM5kpFvGk9NC2Hca1lXUh9lmiedor9d8uCs6Np9VDAIPhOcU6bet29Cd6aCjh_jNNU7P9_aAOcAUcHV8Ua9rmrcwSuGF065hW6Ei2U" alt=""><figcaption></figcaption></figure>

**Step 10:** Once the installation is completed, You will be prompted with the following messages and required reference urls.

&#x20;              **cQube Installed Successfully**

**(Note: The installation process is expected to take approximately 30-40 minutes.)**

cQube ingestion api can be accessible using \<domain\_name>

<figure><img src="https://lh4.googleusercontent.com/1u8Ey9_9IWWC4yycnYp1T5jrekIJxNIxy9yrvlx4vChVHIvHa97W1Em_dKuLb4yN9pQfA_Rd77oBO1HoEdq171JY7EoByfA2kESaifZG5dPtA_bgTHkcatjSiPp9lvruGSDrpVHBCzrm_FrlzPw3N4U" alt=""><figcaption></figcaption></figure>

<br>


# Azure  Installation

IAM user and Role creation for AZURE Storage Blob Container connectivity

An AZURE Identity and Access Management (IAM) user is an entity that is created in AZURE to represent the person or application that uses it to interact with AZURE. A user in Azure contains a name and credentials. An IAM user with administrator permissions is different from the AWS account root user. One has to create an IAM user with a supported role to provide the connectivity between azure VM and blob container. The role should have list, read and write permissions.

**Primary Steps:**

**Step  1:** A SSL certificate must be uploaded if you are opting for the public mode of installation where you want to access cQube using a public API endpoint.&#x20;

**Note :** You can ignore the above step if you are opting for localhost installation (single desktop).

**Step 2:** Clone the cqube-devops repository using following command

&#x20;                **git clone** [**https://github.com/Sunbird-cQube/cqube-devops.git**](https://github.com/Sunbird-cQube/cqube-devops.git)    &#x20;

<figure><img src="/files/7teuPFsnyC688hMuSwY0" alt=""><figcaption></figcaption></figure>

**Step 3:** Navigate to the directory where cQube is cloned or downloaded and checkout to the desired branch

&#x20;                       **cd cqube-devops/**&#x20;

&#x20;                        **git checkout release-v5.0.5(latest release branch)**

<figure><img src="/files/QgFwntVXodWNE49UEAIT" alt=""><figcaption></figcaption></figure>

**Step 4:** Navigate to the directory cqube-devops/ansible/ssl\_certificates.

&#x20;                     **Copy the certificate and private key inside this cqube-                   devops/ansible/ssl\_certificates folder.**

<figure><img src="/files/J7l5EyhIZm0eFpNHLVLK" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/shmFW53P7YHLUUVTAgws" alt=""><figcaption></figcaption></figure>

**Step 5 :** If you are opting to pull the data from the NVSK instance, then make sure to upload the dimension files. If you do not want to pull the data, then you can ignore this step. (Applicable if you choose access type VSK).

If you are opting to pull data from an NVSK instance, then make sure to copy the dimension files inside cqube-devops/ansible/dimension\_files

<figure><img src="/files/Q4UF7QR9S6ywOSkhF0gi" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/tadkkePPmaujVpAVi6fB" alt=""><figcaption></figcaption></figure>

Once all the primary steps of uploading SSL certificates and dimensions are done, we can check prerequisites using the script.

**Navigate back to cqube-devops directory**

**Step 6**: Give the following permissions to the pre\_requisites.sh file

&#x20;          **sudo chmod u+x shell\_scripts/pre\_requisites.sh**

**Step 7:** Run the pre\_requisites script with non root user with sudo privileges

&#x20;                 **sudo ./shell\_scripts/pre\_requisites.sh**

<figure><img src="/files/RP3K6JqRSRdLBg291A4I" alt=""><figcaption></figcaption></figure>

**Step 8 :** When steps 6 and 7 are done, you will see the feedback from status checks.

**Step 9:** Go through the feedback provided, and if you find any issues in red resolve them by following the hints provided. If everything is good then proceed with cqube deployment.

#### Deployment Process

**Step 1:** Connect to the cqube Azure ec2 instance

**For linux and macOS:**

* Download the .pem file which is generated while creating the EC2 instance
* Open the terminal and navigate to the folder where .pem file has been downloaded
* Then give the read permission to the .pem file using following command

&#x20;                       **sudo chmod 400 \<aws.pem>**

* Use the following command to connect to the instance

**ssh -i \<path\_to\_the\_pem\_file>  \<user\_name>@\<public\_ip\_of\_the\_instance>**

**Ex:** ssh -i poc\_key.pem -o ServerAliveInterval=60 ubuntu\@13.200.12.31

**For windows:**

* Download the .pem file which is generated while creating the EC2 instance
* Use puttygen to connect to the instance.
* Refer following link to use puttyGen for connecting.

**Step 2:** Refer to the prerequisites checklist section before starting the cqube deployment.-[ Link ](https://app.gitbook.com/o/-Mi9QwJlsfb7xuxTBc0J/s/-Miy6UN-HyTKGo2Sjcky/~/changes/326/get-started-on-cqube/prerequisites-checklist)

**Step 3:** Navigate to cqube-devops directory and give the executable permissions to the install.sh file

&#x20;                      **sudo chmod u+x install.sh**

**Step 4:** Install cQube with non root user with sudo privileges

&#x20;                     **sudo ./install.sh**

<figure><img src="https://lh7-us.googleusercontent.com/B5xQFKfEHA_Qk0tXqgJRS7aRd0CJPo24wIf64SLosEEX8l_TDkjEEGJzgLThOxJ4JuZynMZNiNJUvYXzkTKApwg8AfcKWiJD-NK0jhkh4RrRN0UrornptmmOW8h7mlA10gyFe9Vq6EWbn0CdHdZh5yA" alt=""><figcaption></figcaption></figure>

Install.sh file contains a shell script where it will run shell scripts and ansible-playbook to setup the cQube

**Step 5:** Generation of domain specific configuration file - Please refer to the Hints provided and enter the values accordingly.

* access\_type: Enter VSK, NVSK, or others.

&#x20;           a) VSK: To set up VSK for a state

&#x20;            b) NVSK: To establish a nationwide cQube deployment

&#x20;            c) Others: To set up cQube for other purposes.

* state\_name: Enter the required state code by referring to the state list provided (this variable needs to be filled if you are opting for access\_type as VSK; otherwise, it will get filled as NA by default).
* loginpage\_status: Enter true if you want to enable the login screen for the CQUBE instance. Otherwise, enter false.
* data\_pull\_status: Enter true if you want to pull data from an NVSK instance, or else enter false. (You need to fill this variable if you have selected access\_type as VSK; otherwise,  it will get auto-filled with NA.)
* nvsk\_api\_endpoint: Enter the NVSK instance api endpoint if you selected true for data\_pull\_status; otherwise,  it will get autofilled with NA.

Once all the above variables are filled, you get prompted with a preview of the domain-specific config file. Review the entered variables. If everything is correct, then type ‘no’ and proceed further, or else enter ‘yes’ and re-enter the variables correctly.

<figure><img src="/files/WUdCB3a38f7Jkpvwyotq" alt=""><figcaption></figcaption></figure>

**Step 6**: Generation of a generic config file: refer to the hints provided and enter the config file accordingly.

* mode\_of\_installation: Enter public as you have opted for setting up cqube in AWS. (Possible values are public and localhost.)
* storage\_type: Enter storage type as AWS. (Possible values are aws, azure, oracle, and local.)
* api\_end\_point: Enter the url in which the clock is to be configured.
* nginx\_cert\_file: Enter the name of the SSL certificate file that you uploaded in the SSL\_certificates folder.
* nginx\_key\_file: Enter the name of the private key file that you uploaded in the ssl\_certificates folder.

<figure><img src="https://lh7-us.googleusercontent.com/PZ2SYsWY8Q3SxJsGdExR5yC2sT3hqGy74XKylutJzEFGx1o6OKhQ4Z8ut1wvRnBIzt0RiOMSwp3fy2P3GrEG2vpD6JpokMu6UrkBB9rmpeDLRi0qSUBab812KDlVxvhoK4HPK9Lvm9Hcfn-fgfeBdqw" alt=""><figcaption></figcaption></figure>

* Db\_credentials: You will be prompted with default database credentials. If you want to continue with the same, enter no; otherwise, enter yes and proceed to enter your database credentials.
  * db\_user\_name ( Enter the postgres database username )&#x20;
  * db\_name ( Enter the postgres database name )
  * db\_password ( Enter the postgres password )

<figure><img src="https://lh3.googleusercontent.com/dzP6FFmWaLIz8QwOHtXZy9LYg7ZR7afq33HJIQq7wLJDoRiScABiV8IvKX4Ewih_X3X_iLBrUYCle62zEW-D2pN23Fvj3nSaHX83D-5f-cqKjrJ-geV_4jNxGNqozNrGxNXkPVIa2A0cLB46_KX91Rk" alt=""><figcaption></figcaption></figure>

* &#x20;Readonly\_db\_credentials: You will be prompted with default read-only database credentials. If you want to continue with the same, enter no; otherwise, enter yes and proceed to enter your read-only database credentials.

1. read\_only\_db\_user\_name ( Enter the postgres database username )&#x20;
2. read\_only\_db\_password ( Enter the postgres password )

<figure><img src="/files/dNcupMP5ppsQLPTqUw4x" alt=""><figcaption></figcaption></figure>

* Keycloak\_credentials: You will be prompted with the default keycloak admin dashboard credentials. If you want to continue with the same, enter no; otherwise, enter yes and proceed to enter your keycloak credentials.

1. Keycloak\_adm\_name (Enter the keycloak admin name eg: admin)
2. Keycloak\_adm\_password (enter the keycloak admin password eg: Admin\@123)

<figure><img src="/files/KcX06bfYVfG4BICbwX3N" alt=""><figcaption></figcaption></figure>

**Step 7:** Once the config file is generated, a preview of the config file is displayed, followed by a question where the user gets the option to re-enter the configuration values by choosing ‘yes’. If option ‘no’ is selected, then the install.sh moves to the next section.

**Step 8:** Generation of storage config file: Refer to the hints provided below and enter the config file accordingly.

* Azure Container String: Enter the container string&#x20;
* azure\_account\_key: Enter the azure account key to access the bucket.
* azure\_account-name: Enter the azure account name to access the bucket.
* azure blob container name : Enter unique azure blob container name.

**Step 9:**  A preview of the program\_selector.yml file is displayed, followed by a question where the user gets an option to enable or disable the programs by choosing 'yes'. If option 'no' is selected, then the install.sh moves to the next section.

1. &#x20;If access\_type is selected as VSK, the following programs will be displayed: by default, all programs are selected, and the programs are publicly visible.

<figure><img src="/files/OaLL2KhCp1IL3m9MMcKN" alt=""><figcaption></figcaption></figure>

**Note:** If you are willing to select the programs, type yes, select the programs you want, and enter public or private for each program to enable or disable the login screen for programs (follow the hints provided).

2. If access\_type is selected as NVSK, the following programs will be displayed: By default, all programs are selected, and the programs are publicly visible.

<figure><img src="/files/3WOBmUpdfDgzVg3eTqQ0" alt=""><figcaption></figcaption></figure>

**Note:** If you are willing to select the programs, type yes, select the programs you want, and enter public or private for each program to enable or disable the login screen for programs (follow the hints provided).

**Step 10:** Once all the configuration files are generated, the script moves further to clone the cQube microservice repositories and deploy cQube

**Step 11:** If you selected data\_pull\_status as true, then you will see the data pulling APIs where the data gets pulled from the NVSK instance and processed in the VSK cQube. Once installation is done, we need to wait 20 minutes to visualize the data on the cQube dashboard.

**Step 12:** Once the installation is completed, you will be prompted with the following messages and required reference urls:

**(Note: The installation process is expected to take approximately 30-40 minutes.)**

**cQube Installed Successfully**

<figure><img src="/files/ufgPEm6gABEUZdZ78h2k" alt=""><figcaption></figcaption></figure>


# How to prepare the data

The steps given in the next few sections need to be followed as it is and in the same sequence

* Defining dimensions & ingesting them
* Defining event files & ingesting them

**The ingestion will NOT be successful if event files are ingested before the dimension files.**


# Schema

The schema in cQube is a json object which needs to be defined in a specific format. cQube expects a schema to validate the data file provided by the state team. The current cQube schema should be defined as follows.&#x20;

{​​&#x20;

&#x20;   "program": "string",&#x20;

&#x20;   "input": {​​&#x20;

&#x20;       "type": "object",&#x20;

&#x20;       "properties": {​​&#x20;

&#x20;           "column\_name": {​​&#x20;

&#x20;               "type": "string || number",&#x20;

&#x20;               "shouldnotnull": true&#x20;

&#x20;           }&#x20;

&#x20;       },&#x20;

&#x20;       "required": \[&#x20;

&#x20;           "column\_name"&#x20;

&#x20;       ]&#x20;

&#x20;   }&#x20;

}&#x20;

&#x20;<br>

The properties consist of the column names present in the data file. We can specify the type of the column. It currently supports two types: string and number. The shouldnotnull property indicates that null values are not allowed. The required key indicates that the column names specified inside an array are mandatory and should be present in the data file.&#x20;


# How to prepare schemas for  dimension files

Dimensions are the columns that describe events. The dimensions are those values which do not change frequently and remain constant. Example: State name

**CQube adopts the Dimension Specification as defined below**

<pre><code>"program": "school",//Name of the dimension
<strong>  "input": {
</strong>    "type": "object",
    "properties": {
      "school_id": {
        "type": "string",
        "shouldNotNull": true
      },
      "udise_code": {
        "type": "string",
        "shouldNotNull": true
      },
      "school_name": {
        "type": "string",
        "shouldNotNull": true
      },
      "schoolcategory_id": {
        "type": "string",
        "shouldNotNull": false
      },
      "schoolmanagement_id": {
        "type": "string",
        "shouldNotNull": false
      },
      "school_statecategory_id": {
        "type": "string",
        "shouldNotNull": false
      },
      "cluster_id": {
        "type": "string",
        "shouldNotNull": true
      },
      "cluster_name": {
        "type": "string",
        "shouldNotNull": true
      },
      "block_id": {
        "type": "string",
        "shouldNotNull": true
      },
      "block_name": {
        "type": "string",
        "shouldNotNull": true
      },
      "district_id": {
        "type": "string",
        "shouldNotNull": true
      },
      "district_name": {
        "type": "string",
        "shouldNotNull": true
      },
      "latitude": {
        "type": "number",
        "shouldNotNull": false
      },
      "longitude": {
        "type": "number",
        "shouldNotNull": false
      }
    },
    "required": [
      "school_id",
      "udise_code",
      "school_name",
      "cluster_id",
      "cluster_name",
      "block_id",
      "block_name",
      "district_id",
      "district_name",
      "latitude",
      "longitude"
    ]
  }
}
</code></pre>


# How to prepare schemas for event files

An event is a data structure that records an occurrence at a particular time for an entity (eg: school, etc). It is a combination of simple data types (eg: integer, varchar, etc.). An event should always contain a column/set of columns that helps you calculate the Indicator. A table with a timestamp doesn’t necessarily mean that it is an event; it should contribute to either aggregation or filtering of the dataset.

```
{
    “program”: “string”, // Name of the event
    “input”: {
        "type": "object",
        "properties": {
             <COLUMN NAME>: {
"type": "string || number",
             "shouldnotnull": true,
	“format”?: “date”
         }
    }
}

Example: school-attendance

  "program": "teacher-attendance",
  "input": {
    "type": "object",
    "properties": {
      "date": {
        "type": "string",
        "shouldNotNull": true,
        "format": "date"
      },
      "school_id": {
        "type": "string",
        "shouldNotNull": true
      },
      "grade": {
        "type": "string",
        "shouldNotNull": true
      },
      "district_id": {
        "type": "string",
        "shouldNotNull": true
      },
      "block_id": {
        "type": "string",
        "shouldNotNull": true
      },
      "cluster_id": {
        "type": "string",
        "shouldNotNull": true
      },
      "schoolcategory_id": {
        "type": "string",
        "shouldNotNull": true
      },
      "total_teachers": {
        "type": "string",
        "shouldNotNull": true
      }
    },
    "required": [
      "date",
      "school_id",
      "grade",
      "district_id",
      "cluster_id",
      "block_id",
      "schoolcategory_id",
      "total_teachers"
    ]
  }
}
```


# Examples of dimension & event files

This page gives an example of cQube Dimension & Event schema for better understanding

### **Dimension Schema**

**Ex : School Dimension**

This is the data for all schools, clusters, blocks and districts in the state.

**If CSV is being ingested, the file name should be -> school-dimension.data.csv**

| #  | Column               | Data type | Description                                         | Validation  |
| -- | -------------------- | --------- | --------------------------------------------------- | ----------- |
| 1  | district\_id         | string    | Unique ID in the district                           | NA          |
| 2  | district\_name       | string    | Name of the district                                | NA          |
| 3  | block\_id            | string    | Unique ID in the block                              | NA          |
| 4  | block\_name          | string    | Name of the block                                   | NA          |
| 5  | cluster\_id          | string    | Unique ID in the cluster                            | NA          |
| 6  | cluster\_name        | string    | Name of the cluster                                 | NA          |
| 7  | school\_id           | string    | Unique ID in the school                             | NA          |
| 8  | school\_name         | string    | Name of the school                                  | NA          |
| 9  | schoolcategory\_name | string    | ID of the school category for the respective school | NA          |
| 10 | grade                | string    | ID of the grade present in the school               | NA          |
| 11 | latitude             | string    | Latitude of the school                              | NA          |
| 12 | longitude            | string    | Longitude of the school                             | NA          |
| 13 | udise\_code          | string    | Unique ID                                           | <p><br></p> |

### Event Schemas:

**Ex : Teacher Attendance**

This program entails indicators to monitor compliance and performance of teacher attendance. Following are the reports within this program:

* **Teacher Attendance Compliance:** This report shows the compliance of attendance being marked by teachers.
* **Teacher Attendance Summary:** This report shows the summary of teachers being present in the school (out of the ones marking their attendance).

Following schema will be required to enable the teacher attendance program:

**If CSV is being ingested, the file name should be -> teachersattendance-event.data.csv**

#### **Note: The name for grammar file & event file should be same. e.g: teachersattendance-event.data.csv , teachersattendance-event.grammar.csv**

| #  | Column Name                  | Data Type | Description                                                            | Validation                              |
| -- | ---------------------------- | --------- | ---------------------------------------------------------------------- | --------------------------------------- |
| 1  | date                         | string    | Date when the data was recorded                                        | <p>DD/MM/YY</p><p>format to be used</p> |
| 2  | district\_id                 | string    | Unique ID of the district as per the dimension table                   | NA                                      |
| 3  | block\_id                    | string    | Unique ID of the block as per the dimension table                      | NA                                      |
| 4  | cluster\_id                  | string    | Unique ID of the cluster as per the dimension table                    | NA                                      |
| 5  | school\_id                   | string    | Unique ID of the school as per the dimension table                     | NA                                      |
| 6  | schoolcategory\_name         | string    | Category\_id which the school ID belongs to as per the dimension table | NA                                      |
| 7  | grade                        | string    | Grade for which the data is being entered                              | NA                                      |
| 8  | total\_teachers              | string    | Total number of teachers                                               | NA                                      |
| 9  | teachers\_attendance\_marked | string    | Total number of teachers whose attendance was marked                   | NA                                      |
| 10 | teachers\_marked\_present    | string    | Total number of teachers who were present                              | NA                                      |

#### NOTE :  Each metric should be part of a separate event table.&#x20;

E.g. In teacher attendance event file, we will have 3 tables: one for total\_teachers, one for teachers\_attendance\_marked & one for teachers\_marked\_present


# All cQube schemas used for VSK

Please check [here](https://docs.google.com/spreadsheets/u/0/d/10yWmivrqtxdRLiJpX_ytzxbvoGG0WNWEI-7RLV8zelM/edit) for all the schema.


# Ingesting the data


# High-level understanding of ingestion

The diagram that explains the ingestion process.

<figure><img src="/files/LC8PAeqs33JnoBAiWBsV" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/OOHHtUDt8ahhcsoyulVy" alt=""><figcaption></figcaption></figure>


# Steps to ingest schema

## **Note:**&#x20;

To see the API documentation please go to this link <https://editor.swagger.io/> and paste the contents of the github links provided below. The example data provided in the request body is for understanding purposes and  it is not the actual data.

The API endpoint specified in the below document is for public mode of installation.

## Steps to add the schema for events&#x20;

### &#x20;Step 1:&#x20;

Create a postman request and add details

**API Endpoint:** \<domain\_name> /api/spec/event&#x20;

**HTTP Method:** POST

<figure><img src="https://lh6.googleusercontent.com/faVudKEqjMTYCjiDPpWIHCF8OqtnDrrZHYoWj-uWAtbN7S_Q747w3Kpt-dpZbvjvxKYE5afpGfgXZbOl9jVrAKDqd1Uhha6ZE1DBqDMugO8jl1qfkpNYdjeAevHp50uxKuC52HIkyQykIjziimINz5U" alt=""><figcaption></figcaption></figure>

### **Step 2:** &#x20;

Build the request body with reference to YAML file. The request body for the above API is attached here for yaml:[ ](https://github.com/Sunbird-cQube/spec-ms/blob/march-release/spec.yaml)<https://github.com/Sunbird-cQube/spec-ms/blob/dev/spec.yaml> Provide valid input details for the parameters shown below.

<figure><img src="https://lh6.googleusercontent.com/Da49GbryaKw33EF1MfP7CGHcBi61wNMG8B6UhjhBu29oXl8KWBveEyFqAC1sI6qNtsJhLthtAwck7uuG9BBQifM1SU7zE-S2RlExrV_ViWEThJMMfHL-AKbmHBxEmVkUcr4DcvpbDuDhly0YvW_50d0" alt=""><figcaption></figcaption></figure>

### **Step 3:**  &#x20;

Click on the send button for request and if the request is successful the user should see a response message. Please refer to the below screenshot.

<figure><img src="https://lh3.googleusercontent.com/r62qXfcINgzPCDMasadG90znjEUKOdUzBTdSsKy8li6fcls1U854Zml8-R-0oQhk2ilGQGZtokNiqhACjRN3i5kz3vRqfFtRJgo8-PLwI1HL9_EvatgoDJ9Tmddl3AjpLdkeMVx77jVRkwP-7Wfi72s" alt=""><figcaption></figcaption></figure>

Once the API response is successful then the schema is stored in the spec.”EventGrammar” table.

## Steps to add the schema for dimensions

### &#x20;Step 1:&#x20;

Create a postman request and add details

**API Endpoint:** \<domain\_name> /api/spec/dimension&#x20;

**HTTP Method:** POST

<br>

<figure><img src="https://lh4.googleusercontent.com/ucPn9qM4H122SF8sZfTQfr6G6lh21xv25yqqTuHCRa4fk4y0xspy1XLXlYdWPuz-5vuDz35ONzAihLzjtbQlC3NowmVO97JkVX3v48IS4LSLsSUuTEvBsuygLyhACU13NrUo5PGz6x7-Sx6lIXI_VCk" alt=""><figcaption></figcaption></figure>

**Step 2:** &#x20;

Build the request body with reference to YAML file. The request body for the above API is attached here for yaml:[ ](https://github.com/Sunbird-cQube/spec-ms/blob/march-release/spec.yaml)<https://github.com/Sunbird-cQube/spec-ms/blob/dev/spec.yaml> Provide valid input details for the parameters shown below.

<figure><img src="https://lh6.googleusercontent.com/qKDqFmHtdsNHEHrl18DymaBLbTUD9SNtp2fR7_Riy_vL3-MaOoWv_0iiSjXAMxK_4fLZwi-S5gvfvsCLN5KcG3KZ24ZHDZDyfiAKUTr8Pqkypr88HwVGtTRduuGGoN29r41EWiwzQ52LJbTygyGOZKE" alt=""><figcaption></figcaption></figure>

### Step 3:&#x20;

Click on the send button for request and if the request is successful the user should see a response message. Please refer to the below screenshot. Once the API response is successful then the schema is stored in the spec.”DimensionGrammar” table.

<figure><img src="https://lh6.googleusercontent.com/AM13aDosp284LtloR_Sk2CVcW9uWDlXT0fMdHVLCa15-bVzpf7ckpHJ-K3GB9VrZ_Wv-a9Adv52tj2q-moG5yaUe6OLB_bLRE1F2nezfaP1W-txqn6gf8vHHP8JknMAiNlY2lXUH8p-PRGzJ5ol1k5c" alt=""><figcaption></figcaption></figure>

<br>


# Steps to ingest data files

**Difference between State Specific programs and National programs API**

| State Specific Programs API                                                                                                                             | National Programs API                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| <ol><li>Accepts file in .csv format</li></ol>                                                                                                           | <ol><li>Accepts file in .zip format</li></ol>                                                                         |
| <ol start="2"><li>It is mainly used when the state team  wants to onboard new programs apart from the starter pack.</li></ol>                           | 2. This API can be used for starter pack             programs of VSK and NVSK                                         |
| <ol start="3"><li>The uploaded file will be present in the process\_input folder in cloud storage given that there are no errors in the data.</li></ol> | 3. The uploaded file will be present in the emission folder in cloud storage given if there are no errors in the data |

### **Note:**&#x20;

The ingestion API’s have prerequisites to work. Whenever any file is uploaded it should have the specified schema stored in the DB. This can be done by making use of spec API’s.

## Generate JWT token API

### Step 1:&#x20;

Create a postman request & add details.

**API Endpoint:** \<domain\_name>/api/ingestion/generatejwt

**HTTP Method:** GET

<figure><img src="https://lh4.googleusercontent.com/mvKxXnKs2Ec2v9gCYXUq8fhsC2hOt6GVU30JLYg1ukgj_sQ9ImQUI0ApO_6DYOW6ziNbyy9c75xKFKO37IE-d5qSDx7yEV3p0_U3Yz55A8Yv6DPgfA_lU16-7jikEtGQ7b7yhAVtiCvWBUm_Uk280ZQ" alt=""><figcaption></figcaption></figure>

### Step 2:

Click on the send button for request and if the request is successful the user should see      a jwt token generated. Please refer to the below screenshot.

<figure><img src="https://lh6.googleusercontent.com/r1WVmOHtC-g_6DArNJVl6m7YvHMh2lfkzGA7Sqd3g_moKxQWUX_ZaELhAEVUdBD0-VW-kxFltDkIK9w5sXSvGpNhBsghwlAR3IUWYcxuMglPsQVoUjk5-MdewyPirXzC6JffIVOiUuJta9Bcv9l0HPs" alt=""><figcaption></figcaption></figure>

## **Note:**&#x20;

The token generated using the above API is passed in Authorization headers in all the ingestion API’s. If the token is not passed then the API will not work. To pass the token in postman go to the Authorization tab in postman and select the bearer token option from the drop down present on the left menu. On the right side paste the jwt token generated through API. Please refer to the below screenshot.

<figure><img src="https://lh4.googleusercontent.com/Di1Qb5hSfcVRulri86DyeGRdWLBJDU4Q_wvbx7kNz9bRv0uhtEqb53ZGKtizVKqP1cLjpHrOMBxED-8GEr4SLUs-uCWngwU_YhQSQSS2sp0eHVOQrh0f4bsWgk88y1gjx3QRTYnJo1sjqnC_RSaxg3Q" alt=""><figcaption></figcaption></figure>

##


# Upload the .csv data file for state specific programs using ingestion API

Events, Dimensions  can be uploaded  into respective cloud storage  via the ingestion APIs. The event upload is done for only state programs using this API.

The jwt token has to be passed in the API headers.

**Step 1**: create a postman request and add details.

API Endpoint: \<domain\_name>/api/ingestion/new\_programs

HTTP Method: POST

<br>

<figure><img src="https://lh5.googleusercontent.com/MaPHj49DDiYoBuI0G5glMvm4ucxnr8jY9xMAKEHf4pt1V_r0D-F5fz659CbHMTkXrxSKzbEA-EeDKa1pEfaBKGVvYuF4NdxP_LYp6-PW-9aRkqvEvFebTQDwfXvitxflOv2Ne_wyTRzWImH0cKEZQtg" alt=""><figcaption></figcaption></figure>

This API will import the dimension csv and upload it into the process\_input folder in the cloud if there are no errors.&#x20;

**Step 2:** Build the request body with reference to YAML file. The request body for the above API is attached here for yaml:[ ](https://github.com/Sunbird-cQube/spec-ms/blob/march-release/spec.yaml)<https://github.com/Sunbird-cQube/spec-ms/blob/dev/spec.yaml> Provide valid input details for the parameters shown below.

* file : Attach the CSV file for the importing
* ingestion\_type : Specify the type of ingestion (value should be event when uploading the event data file. If it is a dimension data file it should be dimension)
* ingestion\_name : Name of the event or dimension&#x20;
* program\_name: Name of the state program (This key is required only for ingestion\_type = ‘event’)

Note: The value for the key program\_name should be the same name as the folder name present inside ingest->VSK or NVSK->programs folder in processing-ms.

Example: <https://github.com/Sunbird-cQube/processing-ms/blob/dev/impl/c-qube/ingest/VSK/config.json>

The above link has a list of programs array.

&#x20;**Example:** For a school attendance program the folder name is school-attendance so the same name should be given while passing the value for program\_name.

&#x20;"files": "./ingest/VSK/programs/school-attendance" => The folder name can be identified as school-attendance.

<figure><img src="https://lh5.googleusercontent.com/zMTxWtC_vlt6V5ZmUV92cWSPQ7LjlGVGPtcvGK5JraDALW4ZzE2kjLTC6oidv3nihdalb7nGDzCkAwmGLqdpSaltNwJRgZM0f0uDJOeoX98EnU0ixKckqlYnhw3ZM_WkjdQBz7ESXmZsdaoGUEeafys" alt=""><figcaption></figcaption></figure>

### Step 3:&#x20;

Click on the send button for request and if the request is successful the user should see a response message. Please refer to the below screenshot.

<figure><img src="https://lh5.googleusercontent.com/IU5Zb0WByjHEYpg2Vq2-dttEcHNafU091uAX5CR_1yxALTS1ZVmy0tmGSI1t8FChA7a-ctq2zO6gsN8LPWOcN_BUNcGKNqc4q02SE3ks2a88DuexpWu_c9e9Z0RGFgGsDr1SBpwvHZdVTzHqEHJwFXQ" alt=""><figcaption></figcaption></figure>

After successful execution of the csv import api we get the response and we can see the file status indicating if the file is uploaded or not using GET file status API. If the file is successfully uploaded we will get the response as uploaded and if there are any errors it will send us the response indicating there was an error in the file.

<br>


# API to upload starter pack data files for NVSK programs

This focuses on ingestion of programs like UDISE, PGI, NISHTHA, DIKSHA, NAS, PM-POSHAN. The jwt token has to be passed in the API headers.

**Note:** There could be some common errors in the files which could lead to unsuccessful data ingestion into cQube. Look at these errors here and resolve them before ingesting data into cQube.

The already existing files will need to be ingested into cQube via the following process:

This API accepts the data in a zip file format and adds it to the emission folder in the respective cloud storage / SDC.

<br>

&#x20;**National Programs API:**

### Step 1: &#x20;

Open the specified request & add the details

**API Endpoint:** \<domain\_name>/api/ingestion/national\_programs

**HTTP Method:** GET&#x20;

<figure><img src="https://lh4.googleusercontent.com/FxBb2naDMzrSwyVBQqO-icyzVjsZXAOUwAJS4_iZQUAEOG8d4eaASjtmHjXsDydBgFc6MzzXzWZjIu6kr20Sb7rakoanaIN609omZPk28cIgDFl43xQxaWpWZ7JbcGD0VCvuF2Qb9e22DQucpueddRY" alt=""><figcaption></figcaption></figure>

### Step 2:&#x20;

Send the query parameters with reference to the YAML file. The query parameters for the above api is attached in  Link for yaml:  [ ](https://github.com/Sunbird-cQube/spec-ms/blob/dev/spec.yaml)[<img src="https://lh6.googleusercontent.com/vz1PVdRSVzygs-DlegHLT1KDUWzJ5y6WDQD3V5CE-Szl9udxKtyL3yuPSqPy3tpkwN2UbYDE43uFQV-qzU1yjCeV6ESNlJD5xkmTSZds-4yEy3NWIt10Fs-D3UfRV6IZg-mNQD-HBg78jlreb_eY_q8" alt="" data-size="line">](https://github.com/Sunbird-cQube/spec-ms/blob/dev/spec.yaml)[spec-ms/spec.yaml at dev · Sunbird-cQube/spec-ms](https://github.com/Sunbird-cQube/spec-ms/blob/dev/spec.yaml)

Provide the valid input details for the parameters shown below.

<figure><img src="https://lh5.googleusercontent.com/dYFL3X-Vkq1W9HHJv2XInIso2b5nofh7yaHVDzWjJkHUKbwgIe8EIBtpJP1uzkaDHe0mT9ceX2m3yiCWn7r6CWbdA4lIBMwUpXM2AVcq26GOJWdExaXPsHb5UsBSeEvzHgvjPFKp4NEfcbzNebzSBxA" alt=""><figcaption></figcaption></figure>

### Step 3:&#x20;

Click on the send button for the request and if the request is successful the user should see a response message which contains the status of the file.

<figure><img src="https://lh4.googleusercontent.com/ZYvquzK3X_OlYqpX6LucWKlOywN07ulIUh7qvxGUAzi2H9KAZiPXkgCv7PIgEMCHr_tiPLMKY1UmBRse3ug75SCkKKlJJ3IgSXDxc6XmXPYvG1SMcyoB1Uvu9kAAvf0QNaqwgUJxUlzwcQ4qLyG7lGU" alt=""><figcaption></figcaption></figure>


# Get file status API

#### Here are the steps for the get file status API

**Step 1:**  Open the specified request & add the details

API Endpoint: \<domain\_name>/ingestion/file-status

HTTP Method: GET&#x20;

<figure><img src="https://lh6.googleusercontent.com/2mo-a6hRB01iXeJERI76ZtsT1Vw5SK1gT9BJ8P4oFp_a0ahdOJY0N6X-xyBizr6SUxsfF3XlkHYoGhy17GHhLzinHp-_oTCqTg0YQAgevh6noSBK15zhYyWhNgJCdjPDZ-ZOx6hFGMcoldE7drudMv4" alt=""><figcaption></figcaption></figure>

**Step 2:** Send the query parameters with reference to the YAML file. The query parameters for the above api is attached in  Link for yaml:  [ spec-ms/spec.yaml at dev · Sunbird-cQube/spec-ms](https://github.com/Sunbird-cQube/ingestion-ms/blob/dev/spec.yaml)

Provide the valid input details for the parameters shown below.

<figure><img src="https://lh4.googleusercontent.com/TgsJXYCXs1XmNr3lBHZklJCukt0HoGTpADliB9stGX_HGPVkS05cuYD1ZeyaWP4Y1_oGqvrKQtc1iz5zTJxkHwZA3T0PV-8cB2Hlyj8iR-04HVnLWEJIN9LbA8G2zVGC75EIeCaO5f4Ek2ldErey-sE" alt=""><figcaption></figcaption></figure>

**Step 3:** Click on the send button for the request and if the request is successful the user should see a response message which contains the status of the file.

<figure><img src="https://lh6.googleusercontent.com/JtKc_052YB5zo2WNvIr-HEF0iUH3UD370b2wEENX3NSHORfdRWyfjzTcV57WMkHu0N6e6Kh29CRTDg_sPNQbHSdlNwCUYJmkbj9YEjVg-XFR8ZHA3CbIF5Gv1VvS_qxYMhghuHZXMhBb-Kn_O45uerA" alt=""><figcaption></figcaption></figure>

If the csv files are too large in size, the upload process of those files will take more time which will make users wait for longer duration to receive the response from the API. As a result, the upload process will be running asynchronously and we have developed this api to know the status of the file at any particular time.<br>


# Scheduled API

This API helps to schedule the processor group at any particular time.

**Step 1:** Open the specified request & add the details

API Endpoint: \<domain\_name>/api/spec/schedule

HTTP Method: POST

<figure><img src="https://lh7-us.googleusercontent.com/ipFrpZJtvnhpGkeGWVaY4WOOTnLCWEbn7T2JMr3C2USEgA541-sMhnxZxkGW-L9ED9WbOqJZOxwgXC1g8Seo5_qorIMGq_a0jlUFHsyXijrJaNwDAkYIWoovmgPSj44EaOemDcNQH8X5TdezMYqfi1w" alt=""><figcaption></figcaption></figure>

&#x20;**Step 2:** Build the request body with reference to YAML file. The request body for the above api is attached in Link for yaml:[ <img src="https://lh6.googleusercontent.com/6iHBv7-J6xyy-5gQJP5LFct6CCSQtWwle7mfLmderwHe8v6_YMtGn_fu6PStM26dCx9TCW2Cqczakl5bTHifrH-LWpnUHrCyJbcIUcY6qKS2tvJqc4eOxtgSbk6-cw_i_XznwisTSBuwldWvQFP1WLU" alt="" data-size="line">spec-ms/spec.yaml at dev · Sunbird-cQube/spec-ms](https://github.com/Sunbird-cQube/spec-ms/blob/dev/spec.yaml)   . Provide the valid input details for the Parameters shown below.&#x20;

<figure><img src="https://lh4.googleusercontent.com/jRI10tM1uT30UwtTaCoFaADJ_Ye_F5eASi_PU3nTA9OhJ1vT1Ct_ahXYLuCn8mmPUTdBxlp2QGQN6gvhto7G1SH_Et8RbOFD0fUGr10pYCyamczk5DGimoOO5todVMI0JB-hHnBhpWAqA5v6OtuG-NQ" alt=""><figcaption></figcaption></figure>

### Step 3:&#x20;

Click on the send button for the request and if the request is successful the user should see a response message. The schedule time will be updated in the processor group.

<figure><img src="https://lh5.googleusercontent.com/FcloJ0J3uWjLSAzzPJG5UyOSJnVKHiJ7rzbZGvafXUfRkYL3c-wxwsaQM4Xp2qbEZydGexoi23ndSVFzAVQSAIkjVB0-B6BEM-iMRQZl77Dcj0Q3o5Dm2Q9cugPCRRQo9tskb6dioeBVMBpm_LEjGAw" alt=""><figcaption></figcaption></figure>

The schedule api helps to run the processor group in Nifi at a scheduled time. The schedule time can be updated by changing the cron expression for scheduled\_at property in the request body.

**Processor Group state Change API:**

This API helps to change the state of a processor group in Nifi. It will provide the functionality to start the processor group or stop the processor group.

**Step 1:** Create  a specified request in postman  and add the details.

<figure><img src="https://lh7-us.googleusercontent.com/DUbTnb-ysYYg0xEfdQ9PUfOjlgHQtqOUBWfPYeP2V0vvIZCDZiSBKLOzVAsCMXNCHqa1U4A1hQNERHuRFuLeTMsOg9YgsR6w7TjbBRNQ9GdXVdluF5sZ0azvaPdl8OOEQkENCQHXZxtjd5doubzt8hg" alt=""><figcaption></figcaption></figure>

**Step 2:** Step 2: Build the request body with reference to YAML file. The request body for the above api is attached in Link for yaml:[ <img src="https://lh7-us.googleusercontent.com/qMa3emhWmrFwRvUTkiQ2q6CTtXbsK8PIdipItYpsUr3HhNR-_V6qiNWE0GQVt-cd48WOMBVEkeIc2XS0nCO4evRngYks1dhVYwi2bvNlAT9EtDmrzzMr0Q6lzbrG_ErLLGnrFSthZpYXrf0NgJ4d6B4" alt="" data-size="line">spec-ms/spec.yaml at dev · Sunbird-cQube/spec-ms](https://github.com/Sunbird-cQube/spec-ms/blob/dev/spec.yaml)   . Provide the valid input details for the Parameters shown below.<br>

<figure><img src="https://lh7-us.googleusercontent.com/4muG8rfsdrBueNhcp8CUeBf-4JHyIO7-K-_dY7un7aqgkv4v-DplFXNt9OvPWEBwYelLjXM_A4ezqnOKDnuQScav6OtjYZWN6HdZxtt0t7v34NAFh1P3rldBLZA34YNL17uUyapT1xAtl-2Y5A3OzCI" alt=""><figcaption></figcaption></figure>

&#x20;**Step 3:** Click on the send button for the request and if the request is successful the user should see a response message.&#x20;

<figure><img src="https://lh7-us.googleusercontent.com/8jDYjaK9n0OCK9DSbiObVMael4Yjg53hopfSQan9mdPDDgDuVhrA3RH9x2ixFCqJwVaI5F7igNXBDWZ79xRL4CbYJVcICtFSJgPZTlXnLUmBKUjzaEkoE-9YL6Rk3BFjGHCKsBEu9wa02rwcPWm3KRY" alt=""><figcaption></figcaption></figure>

In the above example as you can see the processor group onestep\_dataingestion\_aws is changed to running state.\
Note:

1\. This API is only used to change the state of a processor group. If you want to change the schedule time you will have to use the Schedule API.

2\. It is suggested to stop the processor groups once the data is ingested for all the programs using the above API

\ <br>


# Error during ingestion

Errors may occur due to state code mismatches, the inclusion of special characters, variations in column names between grammar and event files, etc.

| ID | State / UT Name                      |
| -- | ------------------------------------ |
| 1  | Andaman and Nicobar Islands          |
| 2  | Andhra Pradesh                       |
| 3  | Arunachal Pradesh                    |
| 4  | Assam                                |
| 5  | Bihar                                |
| 6  | Chandigarh                           |
| 7  | Chhattisgarh                         |
| 8  | Dadra & Nagar Haveli and Daman & Diu |
| 9  | Delhi                                |
| 10 | Goa                                  |
| 11 | Gujarat                              |
| 12 | Haryana                              |
| 13 | Himachal Pradesh                     |
| 14 | Jammu and Kashmir                    |
| 15 | Jharkhand                            |
| 16 | Karnataka                            |
| 17 | Kerala                               |
| 18 | Ladakh                               |
| 19 | Lakshadweep                          |
| 20 | Madhya Pradesh                       |
| 21 | Maharashtra                          |
| 22 | Manipur                              |
| 23 | Meghalaya                            |
| 24 | Mizoram                              |
| 25 | Nagaland                             |
| 26 | Odisha                               |
| 27 | Puducherry                           |
| 28 | Punjab                               |
| 29 | Rajasthan                            |
| 30 | Sikkim                               |
| 31 | Tamil Nadu                           |
| 32 | Telangana                            |
| 33 | Tripura                              |
| 34 | Uttar Pradesh                        |
| 35 | Uttarakhand                          |
| 36 | West Bengal                          |
| 37 | CBSE                                 |
| 38 | CISCE                                |
| 39 | NCERT                                |

###

##

##


# Error Monitoring

The error file captures all error records during the ingestion process and is uploaded to the relevant cloud storage. Users can log in to the respective cloud storage platform, navigate to the designated bucket created during installation, and follow these steps to access the error file:

1. For the new\_program API: a) Error files are stored in the "ingestion\_error" folder within the bucket. b) Within "ingestion\_error," there are folders for each program (named after the program\_name). Inside these program folders, there is a sub-folder with the current date as its name. c) Users can access the current date folder, review the error files within, and download them to examine CSV errors.
2. For the national\_programs API: a) Error files are stored in the "emission\_error" folder within the bucket. b) Inside "emission\_error," a folder is created with today's date, containing the error files.

After identifying and rectifying errors, users should re-upload the entire file. Screenshots illustrating how to access error files are provided below for reference.

<figure><img src="https://lh7-us.googleusercontent.com/QnTX6IoTuCGCcumCKqS0KuItQNSv2bQO3PbP9785jzP5oS62D6hTyXEGvK_nfoT7R22IAlKJ2fcm9QvhpuvmZ6fUubdZ8U4fq7gm-kX2qfkBSaOlT4O_jpvWR1gJQzJVpA4AvoXwlyadpvMhD0P-P0Q" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh7-us.googleusercontent.com/8jmipM9DFgiXIVMBDAtuqwzAvCI1Jv0Siw33vk_Xph11PAYuz3DmAXZGz7340s9DQrTalis5RF-c0xIgji3frDmO3zCVB_G2qb4JfwSaoTw397D4A3mNQiLS54ySCNCwu88FA22VbFSy-h5bjtSuRGM" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh7-us.googleusercontent.com/mG-FJpanjok4LQIj4QzXVI8vgmcpmKfvVG09bgcdD8_nvCE5CG2GDbkkNrhSU14cr6aYxbuS5XOyBpMRk2G4NM3gOChuuIYZJm54ydzvCsrg-HH-Sh-vwBPARbANme-2SKEfzoOjVyKfz5e49NGh70Q" alt=""><figcaption></figcaption></figure>

To get the count of processed records and error records GET /ingestion/file-status API can be used.

<br>


# Common errors in data files during ingestion

### Single Master of Districts, Blocks, Clusters and Schools within a state to be referenced:

* State and national programs on cQube will require data for districts, blocks, clusters and schools to enable decentralised observability. Dimension masters for district, block, cluster and school will need to be created having a unique ID and name of the jurisdiction. A single master file for each jurisdiction should be created and that should be referenced for data of both - state as well as national programs. Any discrepancy will lead to unsuccessful data ingestion.
* For example: If a state has 30 districts, a district dimension master will have data in[ this](https://cqube.sunbird.org/data-ingestion-and-processing/cqube-schemas#district-dimension) format. The table will contain IDs from 1 to 30 with names of the district against each ID. Each district will be mapped to the state ID as per the 1st point. Same process will be followed for dimension masters for blocks, clusters and schools.

### Individual values for grade, subject and medium instead of arrays:

* State and national programs in cQube will require data for grade, subject and medium being followed in the state. Generally the states share values of subject in arrays like \['Political Science/Civics', 'Social Science']. This is an incorrect format.
* The subjects should have individual values and different subjects should be in different rows. For example: Political Science / Civics will be Row 1 with relevant data in the event file and Social Science will be Row 2 with relevant data in the event file. Dimension for subject in the specified format linked here will also have 2 rows with unique IDs - Political Science / Civics and Social Science.

### No quotes - single (') or double (“) should be present in the data being ingested

* In all the files being ingested, single or double quotes should not be present at all


# Processor group name

The programs are  individually  scheduled by using scheduled API please run the following program name space.

1. nishtha
2. pgi
3. pm\_poshan
4. diksha
5. nas
6. udise
7. sch\_att
8. ncf
9. micro\_improvements
10. nipun\_bharat
11. ncert\_quiz
12. pm\_shri


# Adapter details

**Overview**

**Metric:** A metric is a column in an event data file on which the aggregations are done to derive the insights.

CQube adapter is an ETL (Extract, Transform and Load) pipeline with processes used to move data from the adapter database to multiple CSVs after making the required transformations. A cQube adapter is needed because cQube expects data in a specific format and the output CSVs of the adapter can be ingested directly into cQube to get the programs, reports and indicators.

## Working of an Adapter  \[Currently working for National Programs]

1. The adapter makes a connection with the  state data source (ex: azure container/aws s3 bucket/oracle file system /minio bucket).Read the zipped data file from the emission folder emission/\<date>/\<file\_name>.csv.
2. It then reads the raw data files from the datasource.It performs the transformation to generate the Dimension and Event (Fact) CSV files. The desired format and output columns list in the dimension and event file for each program can be found here.
3. &#x20;Select the required column from the report(zip file).&#x20;
4. Split the files according to the number of metrics in report
5. Output Event CSV files will be stored inside AWS S3 Bucket / Minio / Azure in the input-bucket process\_input/program/\<date>/\<event\_name>-event.data.csv. process\_input/program/\<date>/\<event\_name>-dimension.data.csv Format.&#x20;
6. NiFi will run This adapter ETL pipeline will run at a specific frequency so that the output CSV data can be refreshed and the latest data will be ingested into the system.  &#x20;

Example for illustration:&#x20;

1. **Initial file**

<table data-header-hidden data-full-width="true"><thead><tr><th></th><th></th><th></th><th></th><th></th><th></th><th></th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td>date</td><td>district_id</td><td>block_id</td><td>cluster_id</td><td>school_id</td><td>schoolcategory_name</td><td>grade</td><td>gender</td><td>KPI-1</td><td>KPI-2</td><td>KPI-3</td></tr><tr><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td></tr></tbody></table>

2. **Final files**

| date | district\_id | block\_id | cluster\_id | school\_id | schoolcategory\_name | grade | gender | KPI-1 |
| ---- | ------------ | --------- | ----------- | ---------- | -------------------- | ----- | ------ | ----- |
|      |              |           |             |            |                      |       |        |       |

<table data-header-hidden><thead><tr><th></th><th width="609"></th><th></th><th></th><th></th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td>date</td><td>district_id</td><td>block_id</td><td>cluster_id</td><td>school_id</td><td>schoolcategory_name</td><td>grade</td><td>gender</td><td>KPI-2</td></tr><tr><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td></tr></tbody></table>

| date        | district\_id | block\_id   | cluster\_id | school\_id  | schoolcategory\_name | grade       | gender      | KPI-3       |
| ----------- | ------------ | ----------- | ----------- | ----------- | -------------------- | ----------- | ----------- | ----------- |
| <p><br></p> | <p><br></p>  | <p><br></p> | <p><br></p> | <p><br></p> | <p><br></p>          | <p><br></p> | <p><br></p> | <p><br></p> |

## Architecture

<figure><img src="https://lh7-us.googleusercontent.com/qA-zynQlsoN_H1GLNISWUcQpcsT4EPgzVSHeklQ34a9J5QXbGJj2ROntJo_SEiMCDrO72tzjr0gUKeWu-zMe6pQ_npkH2kOFNgtzNtZwLZy1oxChy2adbaef4gdvgWlr6tf2Q3hlDD4O7mNkTByNWUE" alt=""><figcaption></figcaption></figure>

## Technology Used

cQube adapter can use any system, programming language or ETL tool to develop the cQube adapter.&#x20;

For example:

* Python scripts can be used to extract data from the source / state database, transform it and finally export the CSV files inside the AWS S3 bucket or cloud storage which is being used. Apache Airflow can be used to scheduling the python scripts.
* Or, Apache NiFi can be used to create the end-to-end ETL Pipeline.
* The only requirement is that the adapter-generated CSV files should have the same column names and the data format as per schema\
  \
  Refer this [link](https://docs.google.com/document/d/1F9ho_1y3sWDCzynPAzLScYT18VmuS4K-1dNOWs1z6rE/edit#heading=h.y16u3gcmp1l8) for detailed explanation


# Postman details

## Setting up Postman

* [Download](https://www.postman.com/downloads/) the postman application and import the collection.
* Select the import option in postman to import the collection. Please refer to the screenshot.

<figure><img src="/files/9bfeh9SwgJpZiQklgG9B" alt=""><figcaption></figcaption></figure>

## Postman collection files

{% file src="/files/EcMHOLzrSyli3j8XNAPa" %}

{% file src="/files/6L9pok5teROmunR5TvPl" %}


# Processing of data

The Following sections covered in this topic:

Nifi data

API details for Nifi-Rest


# Data Processing using CLI command

&#x20;  **Ingestion of Dimensions:**

&#x20;         For the ingestion of dimension, we have to make sure, we have grammar and data files present in the below directory inside the server.

`/ingest/<program_type>/dimensions`

Run the below command from the /ingest/ folder to upload the dimensions in the database.

&#x20;   `yarn cli ingest`

* It will read the config.json file of a specific program type present inside the ingest folder.
* Then it will process all the dimension grammar present in the dimensions folder.
* The dimension grammars are stored in the “spec.dimensionGrammar” table and the dimensions tables are created in the dimensions schema.
* It will also look for data files respective to each dimension grammar file name and ingest all the dimension data to the respective tables.
* After the dimensions are ingested the programs array present in config.json is read and the event grammars are processed from the corresponding \<program-name> folder. The event grammars are stored in the spec.”EventGrammars” table.
* The dataset grammars are also stored in the spec.”datasetGrammars” table and the dataset tables are created based on the combination of timeDimension, dimension and metric present in the event grammars.
* In addition to the above combination of datasets created the user can also specify the combination of datasets that can be created in the whitelist array.

&#x20;    The below screenshot shows the final output of the yarn cli ingest command when all the dimension,event and dataset grammars are processed. The dimension data is also ingested in this process.

<figure><img src="https://lh3.googleusercontent.com/s0otTPD7cD9TYoghGwoUf2BsRopUpsb7hTVUuzfNa3xm_e1i26tdv99zb1TqP15dkPDXahRVs4RFz1pD0oGIGffqBCV3z6FkOWDU_xvmTuADFf59_YEYJYif31a5DJyxg9gYq_frCHPyGorjNbhSRAA" alt=""><figcaption></figcaption></figure>

**Note:** When you ingest dimensions everything gets deleted and re ingested. So to update the dimensions data, you should reupload the full dimensions data file and run the command (yarn cli ingest) to ingest dimensions

&#x20;       **Ingestion of Program Data**

For the ingestion of events data, we have to make sure, we have grammar and data files present in the below directory respective to each program inside the server.

`/ingest/<program_type>/programs`

The value for program type is read from the .env file and it can have two values VSK or NVSK.

&#x20;`yarn cli ingest-data`

This command will ingest the data to the dataset tables for all the programs. It also provides an option to ingest the data for the particular program

yarn cli ingest-data ---filter=\<program\_name>.

&#x20;The program name passed should be the same as the namespace specified in the config file.

* It will read all the programs present in the config.json file.
* It will check for the data files inside the programs folder and process the data.
* Then the process dataset update request is created.
* The transformer processes the request and updates the data to the dataset tables created. These datasets are used for visualization in the UI.

Below command can be used to upload the data for PGI program. Here in the filter we are passing pgi.

`yarn cli ingest-data --filter='pgi’`

<figure><img src="https://lh3.googleusercontent.com/ecHW9kEiJgPuOkCh9QwZQXphF6Qld7XfI3cpTUqCb-WKl0XJCV70oLtIpvIp7t2bfqEFMHI_Tf0imt-QKP5hkLu4A1T51LEKiPIX-DLhEiwg5sSfWf9a_bQ-75cZKRfpn0AxAetATZmnzxEXzcBHkn0" alt=""><figcaption></figcaption></figure>

The above figure shows the ingestion of data for the program PGI. The data ingested can then be used by the visualization to derive statistical data.

&#x20;      **Delete the data in the database**

`yarn cli nuke-db`: This command will delete all the data present in the database.


# API Details for Nifi-Rest

[Nifi-Rest-api’s code](https://github.com/Sunbird-cQube/generator-ms/blob/dev/static_processor_group/add_nifi_template.py)


# Nifi section

&#x20;Nifi in cQube is used to create a data flow and automate the processing of data with the help of processor groups. These processor groups are responsible for accessing the data files from the cloud storage and moving it into the processing-ms codebase. Once the data files are moved the commands will be executed which will ingest the data into the database.&#x20;

Here we have different processor groups to process the data(Nifi canvas).\
1\. To run adapters.

2\. To run all programs.

3\. To run program wise.

The Processor groups in nifi can be scheduled using API called [scheduled API ](https://cqube.sunbird.org/use-cqube/ingesting-the-data/steps-to-ingest-data-files/scheduled-api)

<figure><img src="https://lh7-us.googleusercontent.com/RTAA79E4m4LW4kNxJ-x9lqS7LHwui1rMc-m-w4Pjx4UwURcFH9xhzn0xW6H4_CJDE_eyxI-RZNJIYcVLeJzsCOiroK2PXlI8Cdpoq5sDKdW3j6V5KxXoARgNBTzwA72tYx6M4FIr4i1CzhtAkDLn6cw" alt=""><figcaption></figcaption></figure>

**1. To run adapters:** This processor group is used to run the adapters shell script code.

<figure><img src="https://lh7-us.googleusercontent.com/vYOhhEZhqKmGv3WYCUQaPsnNHsHu4JuHhK5IRCXxrNf_O8-KfidyQElnuQb6BJizTMXo0moKHTwQ5KxMWSVGYnuJaLP_ATOw4wNBlhMTCdsz-ufJs-jyJr2QpwxENzKssec2EdeqRZGBHRQof4GRUdM" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh7-us.googleusercontent.com/1-B6z29UGf5kF5HNL6k9EQxJOJokP2IKIpIbmI6M-m9ERkP4xS1IZ9DtjNd1ccleV5Ig9QawB1oqUjIFfEOeACVQVGuTH4U-9270jHkTm0GsxwLZaB75u76P77-ulwre6OYiOMXKslcu2rE-WPZDdPY" alt=""><figcaption></figcaption></figure>

**2. To run all programs:** This processor group is used to move files from process\_input folder to processing\_ms folder according to folder structures. .i.e., (dimensions/,programs/). Then it will run yarn cli ingest(where it will ingest all schemas and grammars to the database) and yarn cli ingest-data (where it will ingest all data files to the database) commands.

<figure><img src="https://lh7-us.googleusercontent.com/F-AkuAxqcUxj4Lko-3lnAficTq2tDQh_x_GXKCdPsqy4ZJUvozqRMRS3fCtFplDC-R8qDtwdcvJ19phlJGY77UqIZ75cB0gi_DiuSYCvtIu8oH6lwTbO0K2O6UlcXbYM8MDEJ4SZg09S0dGBkbwuxbs" alt=""><figcaption></figcaption></figure>

**3.To run program wise:** This processor group is used to move particular program files from process\_input folder to processing\_ms folder. Then it will run yarn cli ingest and yarn cli ingest-data --filter=’program\_name’.(where it will ingest particular program data files).

<figure><img src="https://lh7-us.googleusercontent.com/WLJMhDjsBMTveEgWHBrLVTNqb62DdiRsrxyh2K_TRdnxWVb29xnKDv5r2fnKkV3bfAa9ekyK4kR-vLIRtPQXpNOtxdDEer7prp24KTK3NKkt-vMYn8Tu0EiBPivT_tjnsV63iKYHhZQ_2YsOXd5VKsQ" alt=""><figcaption></figcaption></figure>

\
In order to automate these processor groups we have written REST-APIs. Please look into the below link to understand th Nifi codebase.

\
[Nifi-Rest-api’s code](https://github.com/Sunbird-cQube/generator-ms/blob/dev/static_processor_group/add_nifi_template.py)

<br>


# Visualizing the data


# High level understanding of how visualizations work in cQube

<figure><img src="/files/4LyMBPfaaoXJ7zgpgJhE" alt=""><figcaption></figcaption></figure>


# Programs and reports out-of-the-box

Details out the indicators in each report and program available in cQube Ed V 5.0

There are a total of 9 programs available in cQube v5.0:

1. [Student Attendance](#1.-student-attendance)
2. [NISHTHA](#2.-nishtha)
3. [DIKSHA](#3.-diksha)
4. [PM POSHAN](#4.-pm-poshan)
5. [NAS](#5.-nas)
6. [UDISE](#6.-udise)
7. [PGI](#7.-pgi)

### 1. Student Attendance

This program entails indicators to monitor compliance and performance of student attendance. Following are the reports within this program.

* **Schools Reporting Student Attendance:** This report shows the % of schools that report attendance within the selected time duration for more than 50% enrolled students on average. This report will have the Date Range filter. Other Filters like District, Block, Cluster, School will be picked up from RBAC. Following indicators will be available for specific roles as part of this report:

For a State Officer:

<table data-full-width="true"><thead><tr><th>Indicator</th><th>Chart Type</th><th>Applicable Filters</th></tr></thead><tbody><tr><td>Average % Schools Reporting Student Attendance</td><td>Big Number</td><td>Date Range</td></tr><tr><td>District-wise % Schools Reporting Student Attendance</td><td>Table</td><td>Date Range</td></tr></tbody></table>

For a District Officer:

<table><thead><tr><th>Indicator</th><th width="133.66666666666666">Chart Type</th><th>Applicable Filters</th></tr></thead><tbody><tr><td>Average % Schools Reporting Student Attendance</td><td>Big Number</td><td>District, Date Range</td></tr><tr><td>Block-wise % Schools Reporting Student Attendance</td><td>Table</td><td>District, Date Range</td></tr><tr><td>District-wise Rank in % Schools Reporting Student Attendance</td><td>Table</td><td>Date Range</td></tr></tbody></table>

For a Block Officer:

| Indicator                                                 | Chart Type | Applicable Filters          |
| --------------------------------------------------------- | ---------- | --------------------------- |
| Average % Schools Reporting Student Attendance            | Big Number | District, Block, Date Range |
| Cluster-wise % Schools Reporting Student Attendance       | Table      | District, Block, Date Range |
| Block-wise Rank in % Schools Reporting Student Attendance | Table      | District, Date Range        |

For a Cluster Officer:

| Indicator                                                   | Chart Type | Applicable Filters                   |
| ----------------------------------------------------------- | ---------- | ------------------------------------ |
| Average % Schools Reporting Student Attendance              | Big Number | District, Block, Cluster, Date Range |
| School-wise % Student attendance being reported             | Table      | District, Block, Cluster, Date Range |
| Cluster-wise Rank in % Schools Reporting Student Attendance | Table      | District, Block, Date Range          |

For a School Principal:

| Indicator                                               | Chart Type | Applicable Filters                           |
| ------------------------------------------------------- | ---------- | -------------------------------------------- |
| Average % Student attendance being reported             | Big Number | District, Block, Cluster, School, Date Range |
| Grade-wise % Student attendance being reported          | Table      | District, Block, Cluster, School, Date Range |
| School-wise Rank in % Student attendance being reported | Table      | District, Block, Cluster, Date Range         |

* **Average Students Present:** This report shows the % of students present (out of the ones for whom attendance is being reported) within the selected time duration on an average. This report will have the Date Range filter. Other Filters like District, Block, Cluster, School will be picked up from RBAC. Following indicators will be available for specific roles as part of this report:

For a State Officer:

<table><thead><tr><th width="252.66666666666666">Indicator</th><th>Chart Type</th><th>Applicable Filters</th></tr></thead><tbody><tr><td>Average % Students Present</td><td>Big Number</td><td>Date Range</td></tr><tr><td>District-wise % Students Present</td><td>Table</td><td>Date Range</td></tr><tr><td>Gender-wise % Students Present</td><td>Bar Chart</td><td>Date Range</td></tr><tr><td>Grade-wise % Students Present</td><td>Bar Chart</td><td>Date Range</td></tr></tbody></table>

For a District Officer:

| Indicator                                | Chart Type | Applicable Filters   |
| ---------------------------------------- | ---------- | -------------------- |
| Average % Students Present               | Big Number | District, Date Range |
| Block-wise % Students Present            | Table      | District, Date Range |
| District-wise Rank in % Students Present | Table      | Date Range           |
| Gender-wise % Students Present           | Bar Chart  | District, Date Range |
| Grade-wise % Students Present            | Bar Chart  | District, Date Range |

For a Block Officer:

| Indicator                             | Chart Type | Applicable Filters          |
| ------------------------------------- | ---------- | --------------------------- |
| Average % Students Present            | Big Number | District, Block, Date Range |
| Cluster-wise % Students Present       | Table      | District, Block, Date Range |
| Block-wise Rank in % Students Present | Table      | District, Date Range        |
| Gender-wise % Students Present        | Bar Chart  | District, Block, Date Range |
| Grade-wise % Students Present         | Bar Chart  | District, Block, Date Range |

For a Cluster Officer:

| Indicator                               | Chart Type | Applicable Filters                   |
| --------------------------------------- | ---------- | ------------------------------------ |
| Average % Students Present              | Big Number | District, Block, Cluster, Date Range |
| School-wise % Students Present          | Table      | District, Block, Cluster, Date Range |
| Cluster-wise Rank in % Students Present | Table      | District, Block, Date Range          |
| Gender-wise % Students Present          | Bar Chart  | District, Block, Cluster, Date Range |
| Grade-wise % Students Present           | Bar Chart  | District, Block, Cluster, Date Range |

For a School Principal:

| Indicator                      | Chart Type | Applicable Filters                           |
| ------------------------------ | ---------- | -------------------------------------------- |
| Average % Students Present     | Big Number | District, Block, Cluster, School, Date Range |
| Grade-wise % Students Present  | Table      | District, Block, Cluster, School, Date Range |
| School-wise % Students Present | Table      | District, Block, Cluster, Date Range         |
| Gender-wise % Students Present | Bar Chart  | District, Block, Cluster, School, Date Range |

For a Class Teacher:

| Indicator                             | Chart Type | Applicable Filters                                  |
| ------------------------------------- | ---------- | --------------------------------------------------- |
| % Students Present                    | Big Number | District, Block, Cluster, School, Grade, Date Range |
| Grade-wise Rank in % Students Present | Table      | District, Block, Cluster, School, Date Range        |
| Gender-wise % Students Present        | Bar Chart  | District, Block, Cluster, School, Grade, Date Range |

* **Average Students Present:** This report shows the % of students present (out of the ones for whom attendance is being reported) within the selected time duration on an average. This report will have the Date Range filter. Other Filters like District, Block, Cluster, School will be picked up from RBAC. Following indicators will be available for specific roles as part of this report:

For a State Officer:

<table><thead><tr><th width="252.66666666666666">Indicator</th><th>Chart Type</th><th>Applicable Filters</th></tr></thead><tbody><tr><td>Average % Students Present</td><td>Big Number</td><td>Date Range</td></tr><tr><td>District-wise % Students Present</td><td>Table</td><td>Date Range</td></tr><tr><td>Gender-wise % Students Present</td><td>Bar Chart</td><td>Date Range</td></tr><tr><td>Grade-wise % Students Present</td><td>Bar Chart</td><td>Date Range</td></tr></tbody></table>

For a District Officer:

| Indicator                                | Chart Type | Applicable Filters   |
| ---------------------------------------- | ---------- | -------------------- |
| Average % Students Present               | Big Number | District, Date Range |
| Block-wise % Students Present            | Table      | District, Date Range |
| District-wise Rank in % Students Present | Table      | Date Range           |
| Gender-wise % Students Present           | Bar Chart  | District, Date Range |
| Grade-wise % Students Present            | Bar Chart  | District, Date Range |

For a Block Officer:

| Indicator                             | Chart Type | Applicable Filters          |
| ------------------------------------- | ---------- | --------------------------- |
| Average % Students Present            | Big Number | District, Block, Date Range |
| Cluster-wise % Students Present       | Table      | District, Block, Date Range |
| Block-wise Rank in % Students Present | Table      | District, Date Range        |
| Gender-wise % Students Present        | Bar Chart  | District, Block, Date Range |
| Grade-wise % Students Present         | Bar Chart  | District, Block, Date Range |

For a Cluster Officer:

| Indicator                               | Chart Type | Applicable Filters                   |
| --------------------------------------- | ---------- | ------------------------------------ |
| Average % Students Present              | Big Number | District, Block, Cluster, Date Range |
| School-wise % Students Present          | Table      | District, Block, Cluster, Date Range |
| Cluster-wise Rank in % Students Present | Table      | District, Block, Date Range          |
| Gender-wise % Students Present          | Bar Chart  | District, Block, Cluster, Date Range |
| Grade-wise % Students Present           | Bar Chart  | District, Block, Cluster, Date Range |

For a School Principal:

| Indicator                      | Chart Type | Applicable Filters                           |
| ------------------------------ | ---------- | -------------------------------------------- |
| Average % Students Present     | Big Number | District, Block, Cluster, School, Date Range |
| Grade-wise % Students Present  | Table      | District, Block, Cluster, School, Date Range |
| School-wise % Students Present | Table      | District, Block, Cluster, Date Range         |
| Gender-wise % Students Present | Bar Chart  | District, Block, Cluster, School, Date Range |

For a Class Teacher:

| Indicator                             | Chart Type | Applicable Filters                                  |
| ------------------------------------- | ---------- | --------------------------------------------------- |
| % Students Present                    | Big Number | District, Block, Cluster, School, Grade, Date Range |
| Grade-wise Rank in % Students Present | Table      | District, Block, Cluster, School, Date Range        |
| Gender-wise % Students Present        | Bar Chart  | District, Block, Cluster, School, Grade, Date Range |

### 2. NISHTHA

NISHTHA is a capacity building program for "Improving Quality of School Education through Integrated Teacher Training". It aims to build competencies among all the teachers and school principals at the elementary stage. NISHTHA is the world's largest teachers' training program. Following reports are available in this program:

1. Implementation Status
2. Courses and Medium status
3. % against Potential Base
4. District wise Status
5. Course wise Status

### **3. DIKSHA:**

The Digital Infrastructure for Knowledge Sharing is an initiative of the National Council of Educational Research and Training (Ministry of Education, Govt. of India). This platform enables implementation of two key programs- NISHTHA and Energized Textbooks. Following reports are available in this program:

1. ETB Coverage Status
2. Content Coverage on QR
3. Learning Sessions on Potential Users

### **4. PM POSHAN:**

Pradhan Mantri Poshan Shakti Nirman (PM POSHAN) earlier known as the National Programme of Mid-Day Meal in Schools is one of the foremost rights based Centrally Sponsored Schemes under the National Food Security Act, 2013 (NFSA). The primary objective of the scheme is to improve the nutritional status of children studying in classes I-VIII in eligible schools. Following report is available in this program:

1. Progress Status

### **5. NAS:**

The National Achievement Survey (NAS) is a nationally representative large-scale survey of students' learning undertaken by the Ministry of Education, Government of India. Following reports are available in this program:

1. District Wise Performance
2. Grade & Subject performance

### **6. UDISE:**

The Unified District Information System for Education (UDISE) is an educational management information system collected by school administrators on a yearly basis. Following reports are available in this program:

1. District Wise Performance
2. Correlation

### **7. PGI:**

The Performance Grading Index (PGI) is a tool to provide insights on the status of school education in States and Union territories including key levers that drive their performance and critical areas for improvement. Following report is available in this program:

1. District Wise Performance


# Enhance /Customize cQube


# Available customizations

Describes how customizations on the login (UI) layer of cQube Ed can be made

cQube V 5.0 offers customizations on the UI layer of the login page. Post making these customizations, the UI layer of cQube will need to be redeployed. Please see the nested pages to view the available customizations in cQube UI


# Changing Dashboard Logos and Headers

There are 5 configurations enabled here for the dashboard pages.

All of these configurations will be done in the UI configuration file, which can be found in the dashboard-ms micro service. You can access this file in this manner: dashboard-ms > src > assets > config > ui\_config.json.

There are certain keys specified for each configuration to be changed as mentioned below. If there is a need to change any of these configurations, the users need to go to specified location directory (in ui\_config.json) as shown below and make the changes:

<figure><img src="https://lh4.googleusercontent.com/xdRUItkSTTvKU1fwvnFZBW8S2owj97FNOf4TFAmKziHMyTgGPlPWfRzTt5SyT7sEQ61M4NWkyf5OqTAZaH80i1dyaUXp-yF2VXGt6unT2is1Ic60e9XHaOlTorWN_AUZnx39E_rEf_D4zJUcQzW7p6A" alt=""><figcaption></figcaption></figure>

&#x20;**dashboard\_header1\_title** : This key is used to change the title of the cQube dashboard page mentioned at the top. It is depicted in the image below:

<figure><img src="https://lh3.googleusercontent.com/ZtGMBVCu7VQd1sCWWWKEJxYET86DPp6IHrIR4fX_axCHpa2LgKD9MqSOJX07BD4HHLL9I6dNdR-72oAumB8Xki0tbPOy-HIRUdTUHl0kPuNTL0Yr4E2dDywq9TBlFS8Img0BXZjjtpfg7V7g9Cs79V0" alt=""><figcaption></figcaption></figure>

**dashboard\_header1\_image** : This key is used to change the image of the cQube dashboard page present at the top. The size of the image should be 32px \* 32px. It is depicted in the image below:

<figure><img src="https://lh6.googleusercontent.com/k3bBGSRqUENx7BamyiI34iyzPqEozqlBSmR6OaQz-trP-uHXi-uEe3Sv6EmzVQCHtzuJCV5TcJC-g8CuUXR89IT2EYcsVce1PkQnEyF8lJx7J6jNcqiCAxXKtjnGp6i6xKzriC-ki3eHXXAI3gUVG88" alt=""><figcaption></figcaption></figure>

dashboard\_header1\_image

The user needs to upload the image into the specified directory: dashboard-ms > src > assets > images

\
**dashboard\_header2\_title** : This key is used to change the state name in the title of the cQube dashboard. It is depicted in the image below:

<figure><img src="https://lh5.googleusercontent.com/tY6b_hG_faCC3BpzMCeMk3alzSWg12lJ4ULJWGUA3G2exIAdbpR9uxYoMAL6MuiK3Gkp2w-q7Y1T1I-A0-lwkJlSnY-n1X8JBokhzo_QuWZUUMkRsCy8jCGw5TNt36udpe87yp8bBvi3HZcDowWLLY8" alt=""><figcaption></figcaption></figure>

dashboard\_header2\_title

**dashboard\_header2\_image1** : This key is used to change the first image next to the title of the cQube dashboard. The size of the image should be 45px \* \<Any>. It is depicted in the image below:

<figure><img src="https://lh4.googleusercontent.com/PQhJ47xNC8u-QGEdxcy6k6bmoR_L5-dXqPMxj0RoqWPiIO-NeYORCSjwP_IpnmfRwLPU_ElfPvunglLY452vMsZAYZidEJ3jYTCI04KF-B1jAY2Ln66IicbwIMbaIdX2-BkEDepIjvpPhh1JoeS206E" alt=""><figcaption></figcaption></figure>

dashboard\_header2\_image1

The user needs to upload the image into the specified directory: dashboard-ms > src > assets > images

dashboard\_header2\_image2 : This key is used to change the second image next to the title of the cQube dashboard. The size of the image should be 45px \* 45px. It is depicted in the image below:

<figure><img src="https://lh3.googleusercontent.com/KCElwHVWXGDPGPoJypbnv_R2_GKmHdEHyhlv9pOict0OdtwIHraja0XgowlDEh_M3LtjKic2JxFsQWpZ1Ilm5flO1-A3H7Caw-LUxI_EuOAGsNUN7Ukt8vtXjr7lsZGmM6EvLr_kGebFgtBqsdzLrLo" alt=""><figcaption></figcaption></figure>

dashboard\_header2\_image2

The user needs to upload the image into the specified directory: dashboard-ms > src > assets > images

Post making the changes, the user needs to redeploy the code again as explained below.

### Steps for redeploying cQube UI post changes

Run the commands below in the given order to redeploy the UI config file changes for them to be reflected in the visualization layer:

`sudo docker stop dashboard_app`

`sudo docker rm dashboard_app`

`sudo docker rmi dashboard_ms:1`

`cd cqube-devops/microservices/dashboard-ms`

`sudo git pull`&#x20;

`sudo docker build -t dashboard_ms:1 .`

`sudo docker run -d -p 4200:80 --network cqube_net --name dashboard_app dashboard_ms:1`


# Changing Program Name, Icon and Side Menu Sequence

The name of the programs, icons and sequence of the side menubar can be changed as explained below.

<figure><img src="https://lh3.googleusercontent.com/iipFUbCzEi05qxyMu_gEtR-dGWuKURVMOuTHZKZG84wq4Gzj0EafQ5OsYrHOmYMGAx14bg2mffe7ae4XBn2ZrmS7jkjtvy8hreKtina4e7FafJMwd7gzqvryst4iA6iWolas-No52E-4GpRBxPrP-es" alt=""><figcaption></figcaption></figure>

This can be changed in the menu configuration file present in the query-builder micro service (query-builder > menus.csv).

<figure><img src="https://lh6.googleusercontent.com/L0u8bVkegAyF0vMcPltdTQBdZX8qQVMPAtEwWvvz9MmXHA-8Kh0Yndpgj1PbjxlgWr31-_OgHcdJbUo5KUH-qZ80ySGSJp1etiW0g_G1Emr0FyyHQglD8z0gbYiREHsD7XG8583PlgIbnclG510YURY" alt=""><figcaption></figcaption></figure>

The users can change the menu sequence and program name in this file. They need to add the required details mentioned in the CSV to add a new program in the menu bar. If they add / change any icon for the menu, they need to upload the icon images into the following directory dashboard-ms > src > assets > images

The sample CSV filled is shown below:

<figure><img src="https://lh4.googleusercontent.com/FUKQ_lmnIovRIrBVem4okG00Ws_5RlDSBVIWA4L5TqhVmAWUq12DKY6HCue_H7mhtJsUULfvQVmXR2CWRyrOGm7xU2RkErxkl2zMBk-gp3HEfYmhl19RLH4D45D0MxMoRzIRy8N9HuVaV6G3RGM_q4k" alt=""><figcaption></figcaption></figure>

Post making the changes, the user needs to redeploy the code again as explained below.

### Steps for redeploying cQube UI post changes

Run the commands below in the given order to redeploy the menus.csv file changes for them to be reflected in the visualization layer:

`sudo docker stop querybuilder_app`

`sudo docker rm querybuilder_app`

`sudo docker querybuilder_ms:1`

`cd cqube-devops/microservices/querybuilder-ms`

`sudo git pull`

`sudo docker build -t querybuilder_ms:1`

`sudo docker run -d -p 3002:3002 --network cqube_net --name querybuilder_app querybuilder_ms:1`

\ <br>


# Adding a new KPI

A shared BigNumber component is available in the below path

src/app/shared/components/big-number

* Create a new angular Component inside a Program following the below folder structure.

<figure><img src="https://lh4.googleusercontent.com/CYWSKPpFe7_sMf1mI8RkMa6zyMTW18vLCk0bAvnN6c6TWlPN8x9XQtsa033DOg7_oPOY8w5CGg7symzujEhU7bRq-J8S4VUmpzliQpGvSdd_s-RnO62Lbfymf-K3_J4pn6rgjevrxlmoCBxEaQm59hw" alt=""><figcaption></figcaption></figure>

* Add the common component in the html file.
* In the component typescript file add the getReportData Function which fetches the queries according to the configurations. For reference follow this file&#x20;

src/app/views/teacher-attendance/pages/teacher-attendance-summary/reports/tas-average-attendance-bignumber/tas-average-attendance-bignumber.component.ts

* Add the configuration to the program config files found in the config folder.

<figure><img src="https://lh5.googleusercontent.com/xxj07p2Wvd9ijrSu0UaGU6VeVgZowbTNnAKPgEI78e_rVBS_UT72i0SiNiNpK4rI39TGeqSBnlPqf2I70HQRtxnXYqfDbV2ivx2yVHaP_FiVH5iTR5XES65wBKfDDrix3vIcUwOtP1OEUQUK_3tI6AU" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh3.googleusercontent.com/COsiUlSOKpqTWPEmrE0oQ0CZEf3hqvBYVy8OBbwOXphJMAHvP6mtV8mxJkMXTK1PEf7zCEnEOwd2nXCAIkjMbcjAZ5oQWtyow_-9BZaFq-5s96UJnzqzyNGJNysNO3shKd1jhuwJmqSmkY7jMkxrGb8" alt=""><figcaption></figcaption></figure>

<br>

* label is the tab/report name the current kpi belongs to
* filter is an array of objects, where each object corresponds to the rbac level containing specific details for each levels

1. hierarchyLevel is the mapping of the current level to the logged in Level.
2. timeSeriesQueries hold key/object pairs where key is the chart type and value is the query for fetching the data for that chart. They are fetched when date time filter is involved
3. Similar to timeSeriesQueries queries hold the queries for non-date time filter scenarios
4. level inside the actions just specifies the name of next level in the given hierarchy.
5. The bigNumber object inside options contains extra options to be sent to that specific chart type.
6. title is the bigNumber titles to be displayed
7. valueSuffix is the suffix to the bigNumber Value to be displayed

property is the column name/ property name in the output of the query to be displayed as the BigNumber.


# Adding a Map KPI into dashboard ms

A shared map component using leaflet is available in the below path

`src/app/shared/components/maps/leaflet-map`<br>

* Create a new report component and add the above shared component in the html files with any additional elements if needed

\
For reference follow the below file:

src/app/views/teacher-attendance/pages/teacher-attendance-summary/reports/teacher-attendance-map/teacher-attendance-map.component.html

* In the component ts file add the required functions (ex: get reportData, apply criteria, drilldown) respective to each feature.

**For reference follow the below file:**

src/app/views/teacher-attendance/pages/teacher-attendance-summary/reports/teacher-attendance-map/teacher-attendance-map.component.ts

* Options available in the configuration:&#x20;
* indicatorType specifies whether the kpi is of type percent or any general value type.
* indicator represents the property name of the kpi on which map has to be based on. (property name is nothing but alias name in the query)
* title specifies the title to be displayed in the legend
* tooltipMetrics  is an array of objects which is used to construct tooltip.It contains a property name/value which if present in the data will be added along with its prefix and suffixes to the tooltip element.&#x20;

&#x20;

<figure><img src="https://lh5.googleusercontent.com/1LbZAtbo9SZXvTZtAKNCSMTmPrW1ra3oKQQnB89ZX5ZyaPDbR1TW3b2Dxt8x9MWs-kayg6Cez6-hdmAuBZSJG8Zj__oq1k1KmhehU-_RJfUTP9hyVXP--Z4qu3Hb9oILcRLCZ1W8fWWOWPI7HzmTmV0" alt=""><figcaption></figcaption></figure>

Above options are applicable for certain scenarios where metric filter is not needed.

In a case where a metric filter is needed few extra options are available in the configuration.

* metricFilterNeeded is a flag which can be set true if a metric filter is involved in the map report.
* groupByColumn is a property by which the data from the queries can be grouped on a given level.
* metricValueProp specifies the value property to identify the value of a given metric option.
* metricLabelProp specifies the label of the metric option.

Example for the above scenario can be found below:

<figure><img src="https://lh4.googleusercontent.com/bNBtB-x9HiHy_8TUfQdy8Azq_13KNRWFg42hgqIYsWPfObJpHue7wGRpXYCvILPD9i3P5_vN2KaONA1tzZZxdMLW3lURdYpVC9-vw7XfNlsnX_W4x0ZZ9c9qSFC2EaQSxohIwa70HlxI_NPwBOkV8Gc" alt=""><figcaption></figcaption></figure>

Group by is used to group all metrics for a given district/block/cluster into a single row.<br>

**Before Group By:**

<figure><img src="https://lh5.googleusercontent.com/GCZoJzfw_WOdnu2XbYzZ890X4pusvwl62zgsP4O7EtSMIY6er5ziVt2feyxRZsGNSyFZnxjewVvkuKGw0YCoPDP7c_kkawg7s9fqO6pUuyg7C2ZNjuHLwMip7GgLFOr4Zch33u39Y5nx8ap4wij5j1k" alt=""><figcaption></figcaption></figure>

\
**After Group By:**&#x20;

<figure><img src="https://lh5.googleusercontent.com/BAf9YYYfdr8n86sMGcVt-PXlshBbvBrK3GgWu3TBp2-yNb0Ms3Ihd_4IuvPqRpmvlEN3NCof4uuBFFk9GoHiZup4n3_Sw5uX7hY9ypmG1kEiwS6bfEoY3Y4UeYZEBvMSVyU5oBnizhB48Ig7VV0f6wU" alt=""><figcaption></figcaption></figure>

To add drill down features just follow the steps in the table i.e to subscribe to the drilldown service in the map report component .

For reference follow below report:

src/app/views/teacher-attendance/pages/teacher-attendance-summary/reports/teacher-attendance-map/teacher-attendance-map.component.ts

\ <br>


# Table Drill Down Customization

A service named report-drill down-service  has been created to maintain the state of the drilldown in a given program, which can be found in the below path of the dashboard ms codebase:&#x20;

`src/app/core/services/report-drilldown/report-drilldown.service.ts`

In order to implement the drill down feature in a given table report, subscribe to the above service in the ngOnInit lifecycle function as shown below.

<figure><img src="https://lh3.googleusercontent.com/lz121e77GyjMoxNAz_S-lbDSbHsT0L5RsCWr6KLIFqiOLDgpG3HvTUm4tBDYxmsClwmboFP_bE1PsnAE7tAKZ0zBoqJRObzpd3DOF-srqRNxmZFNJH8M2oxeR7aLsfg1zOAj03iNvX-cPWT2ggnBIF8" alt=""><figcaption></figcaption></figure>

Add the drilldown function to the table report component file. (In future this function will be placed in the service itself). For reference the function can be found in the below file: src/app/views/teacher-attendance/pages/teacher-attendance-summary/reports/tas-average-attendance/tas-average-attendance.component.ts

To enable clickable level columns in the table add the below configuration into the column object of the table report configuration.<br>

<figure><img src="https://lh5.googleusercontent.com/fknytDWBEgeu7h8l-v4p7Tvb6QQBM_0XT20as1NRYGnL_xrClpD7Pizw94hhesDdVDkowRPV87B8FGT9GDNzDS9ThvnAe2y-JgMz8K8_w4dSOxNxwT6CfnERkIrJQRIdsY93IBrxX39Ahv242--U1gQ" alt=""><figcaption></figcaption></figure>

Here are the steps:

* dataProps is to specify what property name the column be and alias name of that property.
* hierarchyLevel specifies which level the current column is in.
* linkedReports represents which other reports will be affected by the drilldown of this table.
* allowedLevels restricts the drill down to specified levels in the array

To Link a report to drill down features of another report, subscribe to the service like above and add the drilldown function to the report component file.<br>

For reference follow the implementation in the below file&#x20;

src/app/views/teacher-attendance/pages/teacher-attendance-summary/reports/average-attendance-school-table/average-attendance-school-table.component.ts

<br>


# Adding a Scatter Plot KPI into dashboard ms

A sunbird dashlet library is being used to plot scatter charts across the application.

* Create a new report component and add the above library selector in the html files with any (additional elements if needed)

**For reference follow the below file:**

src/app/views/udise/pages/correlation-tab/reports/correlation/correlation.component.html

* In the component ts file add the required functions (ex: get reportData, apply criteria, drilldown) respective to each feature.

**For reference follow the below file:**

src/app/views/udise/pages/correlation-tab/reports/correlation/correlation.component.ts

A common function getScatterChartReportData() is used to get the data based on the configuration which will be then passed to the dashlet library. The chart configurations present are based on the chartJS requirements which is used within the sb-dashlet library.

**The above function can be found in the below file:**

src/app/core/services/data.service.ts

\
**Options available in the specifically for the scatter plot configuration:**

* groupByNeeded specifies whether the group by is needed upon the data received from the query
* groupByLabel specifies property name on which group by will be done
* metricLabelProp specifies the property which will be converted as key after group by
* metricValueProp specifies the property which will be converted as value after group by
* valueSuffix is a suffix string which can be attached after the value in the tooltip, EX: %
* tooltipMetrics is the configuration required to develop custom tooltips. It is an array of objects, in which each object represents a line in the tooltip (except the x-axis and y-axis values).

**Each object consists of 3 properties as follows:**

* valuePrefix is the prefix string before the value.
* value is the property name of the value in the query result
* valueSuffix is the suffix string after the value.

<figure><img src="https://lh3.googleusercontent.com/qrne5homn7GelBxJOFQdv8sxiqwjFEX8VzWrBAMP_4R9nJuy0V9hqaWxZ_2BQRZPWjGDbe3ROQrnyxJu4BIAB-wKPtp0hh4lJkJwjCoDdozPkSfuEaGW_9-2IYcY68_hXOORkL5Uf2-3qAIXNH2bFpo" alt=""><figcaption></figcaption></figure>

* Filters for the Scatter Plot (X-axis and Y-axis) can be configured as shown below.

<figure><img src="https://lh6.googleusercontent.com/ytZQZA5j9Ua_YcdXpmO2T30xk3z6PyVn3iyvsjD0ggVWFwochcc0YdZZyyJ4VAp7k2OlpqqwdRO-RZGQ506Ai2i6hUKEMgLkjc3HSlJtZSzwFWCCVLZ1KYoLUgoLybdXD3vVwlznog1cNMCo7ibTkXM" alt=""><figcaption></figcaption></figure>

**Options for filter configuration:**

* label is the tab name under which the filter will be included
* name is the placeholder name that will be displayed above the filter in the UI.
* labelProp specifies the property in the query result for dropdown names.
* valueProp specifies the property which will be mapped with the dropdown values.
* id is just an identifier for each filter.
* axis specifies which axis (out of x and y) this filter corresponds to.
* query as the name suggests, holds the query which fetches the filter data.


# Configure default date range across app/specific report

Currently In cQube dashboard default date range is set to 7 days across app.&#x20;

If needed one can change the number of days for default selection across the app as shown below.

<figure><img src="https://lh6.googleusercontent.com/sVD1XlZOq0a3Hmn-7Y7xw0pr2g20v0-DlILAypWmgKA02q76c7pixg3jnK1kGzXzLzSgQAyW6GMyYjqrGAKosBbN63_TXRamgXTcTg1XbQczpdACR9-FGFC1mzINVxLBb-uOZuXsMhsTNpOt6Z77w0I" alt=""><figcaption></figcaption></figure>

The above defaultSelectedDays can be set in the time-series-filter-panel in the shared folder.

However if one wants to override and have custom default range for a specific report they can follow the below steps:

<figure><img src="https://lh5.googleusercontent.com/6meWCho4-TnXE7AVo8oYmVWXlDFgGCC-S4dSe3KNPLjaPUiIpDXC2XMaL4s6FNgHWzRqtNt8ogEpeCvBRaXVgMj8vj8Np6zllfrn49beHqudCfrw-R1LirUYHHsCrmQdbCym7-AmsWQyEG4T0QafsTo" alt=""><figcaption></figcaption></figure>

One can pass an input as shown above to the time-series-filter-panel html selector in a specific report html file.

<br>


# How to add a New Indicator

Note: These steps are for adding a new indicator to an existing program

1. Navigate to the component created for the given report and into the "reports" folder.
2. Create a child component using the following CLI command: `ng g c <indicator-name>`.
3. Once the component is created, fill the HTML and TypeScript files with references to previous indicators or with Angular/implementation knowledge.
4. Later, in the configuration file of that program, add an object with a unique key for that indicator.
5. Fill the configurations according to the reference again with the older indicators and fill the queries using the datasets ingested for this indicator for every level that this indicator is required for.

<figure><img src="/files/pvzQOlvnNvFsdx1Ua6fb" alt=""><figcaption></figcaption></figure>

6. Based on the chart type, you can also provide options in the same configurations, such as titles, color of the columns, legend of the map report, etc.

<figure><img src="/files/CZszZMFNyMOoTrCiFwrn" alt=""><figcaption></figcaption></figure>


# How to add a new report in an existing program

Note: These steps are for adding a new report to an existing program

1. Navigate to the respective program in the client-side code base where the report has to be added.
2. Inside the "pages" folder, create an Angular component named after the report using the following CLI command: `ng g c <report-name>`

<figure><img src="/files/7racJF4jKXX2HXgp9ALM" alt=""><figcaption></figcaption></figure>

3. Once the component is created, it will contain four files - `ts`, `spec-ts`, `html`, and `css`.
4. Fill the TypeScript and HTML files with the reference of other programs. You may need to have knowledge about Angular and how functions have been designed.
5. Include this component in the program HTML file to be rendered.
6. Under the same program name, there will be a config folder that contains a configuration file for the entire program (a JSON file).
7. If any filters are required for the specific report, add an object under the "filter" key in the above configuration file which specifies the filter and its values required for the report. You may need Angular knowledge to fill the object with the appropriate structure.

<figure><img src="/files/t9JtNEYXOdy3s7WOdIgO" alt=""><figcaption></figcaption></figure>

<br>


# How to add a  new program (end to end)

Note: These steps are for adding a new program

### Create event and dimension Grammar files:

Design the event and dimension grammar files for your program. This grammar defines the structure and relationships between different data elements, such as event attributes and dimensions.

* Event grammar: The event grammar defines the structure of the events to be ingested into the system. It includes information such as the event name, its attributes (e.g. event timestamp, user ID, etc.), and data types.
* Dimension grammar: The dimension grammar defines the dimensions, or attributes, that will be used to group and filter events. It includes information such as the dimension name, its attributes (e.g. dimension value, category, etc.), and data types.

### Create a Config.json

Config.json provides directive to processing engine on how to process the grammar and data files, where they are stored, etc. it should be placed in /ingest/\<VSK or NVSK>/

globals : global settings

dimensions : It includes, file format, location and namespace

programs : program specific settings like namespace, description, input location, output location, dimensions which should be considered etc.

\
Only programs mentioned under config.json will be considered for ingestion.

<figure><img src="https://lh4.googleusercontent.com/94rz7Ht5A0rWOEcm6PWJ6U5RWObR2oMCSJXg0OrwbO8U4DLsUakBg8EZK5VBO01NjKajQrNl-OAa9jzWJ1hNW0OyMzvVQuuKKAYAlQLkR4avrqF_dnmxcNG2Pki_ZFZ_KVtvaPkTvI3aoT8H0z0I_Cg" alt=""><figcaption></figcaption></figure>

### 15.3 Upload the event and dimension grammar spec:

* Convert the Event and Dimension Grammar to JSON format as given in the below example

Example: if there is a event with two columns

school\_id and school\_name

Below would be the JSON object

{

&#x20;    "program": "school-attendance",

&#x20;    "input": {

&#x20;        "type": "object",

&#x20;         "properties": {

&#x20;                        "school\_id": {

&#x20;                                                 "type": "string",

&#x20;                                                 "shouldNotNull": true

&#x20;            },

&#x20;           "school\_name": {

&#x20;                                                   "type": "string",

&#x20;                                                   "shouldNotNull": true

&#x20;            }

}

}

* Dimension grammar : Use the /spec/dimension API to upload the dimension grammar
* Place the dimension grammar file as -dimension.grammar.csv in processing-ms/impl/c-qube/ingest/VSK or NVSK/dimensions/ folder as seen below or as per the config.json settings

<figure><img src="https://lh3.googleusercontent.com/kY4bfdcuNteynNJrD_NsHvdcg8pnobTwhfLB9I_gJkeA9dHrbyrh_P6HtRGT_mF6bVYKyNUFSZ7-gLJ7NYJuH4t0wxJ0LhjDjMTqMdVzU0cv2klQflcQL--llS8Zxu3lgX91Nr9tuS0KW90CpE-PIqI" alt=""><figcaption></figcaption></figure>

**Contents of the district-dimension.grammar.csv**

<figure><img src="https://lh5.googleusercontent.com/aMDK7TGW7ONHajVCISgCURej1h_VirtHq_N_R232ViM-0AKANXGQZ3AmnVAsxp-9BsA9zCN0psm-u1B7Cf1RaWqiASH5txS_Hsh2ZksTO1exiSyGncUYdLQaNhjv-ZWVx5yFsay5gZeMP_it52Sd5Pg" alt=""><figcaption></figcaption></figure>

* Event schema can be ingested in 2 ways:
  * Though API Method

**Event spec API: spec/event**

<figure><img src="https://lh3.googleusercontent.com/DrupXNPiAW9-ZyqMUYteKKKhzhXhSaT3lVJEYxT-LH5ynRqX1SuJQTRTcs_Sgra5fMyv_EAHhm2BMdY1SXgfgDHLRbsiipCBW6r-h1sU5Q8urwgGtE6t2phHbNmqtOa9j_lhf4piljvmuAAnFHW9tl0" alt=""><figcaption></figcaption></figure>

* Through YARN CLI

YARN CLI INGEST

This command is used to ingest Event and Dimension Spec and Dimension Data based on the configuration we have

* Create a \<new-program> folder in processing-ms/impl/c-qube/ingest/\<state\_code>/programs\\
* Place the event grammar file as \<xyz>-event.grammar.csv in processing-ms/impl/c-qube/ingest/\<state\_code>/programs/\<new-program> folder as seen below (example for diksha program)

This would be based on default config.json or else it should be as per config.json

<figure><img src="https://lh4.googleusercontent.com/MXwUFOjitgjvhYpoAzjZIgIVYTYtfcTr_JJ5UK3HIh_v3kM9hYLMx43dXgTn4B5s_FfOUQ-boHcHI8eWWqGtZrRf6bbOcu0ZysRsNnJJGEKxswX4pJ__3Q69vJ0EQxciWl-Vz63N9PTWFou6Df_efrE" alt=""><figcaption></figcaption></figure>

Contents of the district-dimension.grammar.csv

<figure><img src="https://lh4.googleusercontent.com/74XJs0gO8v9HCRYFtj6UYcFqDzXKzk-h-HVnPKh5lMUdE69I6XUtpR7xkQUdM9w39dnwY6pQmwltmUJh_CZxXh0EZeWiZ56ecYHBCvh29embc2s0T8uR0TVXU-XMT28R3z-J3j6QpxyjPBkYtVD3TVg" alt=""><figcaption></figcaption></figure>

### Data Ingestion:

This process may involve uploading the CSV file or connecting to the database directly. Following links will provide more details on the process.

* [Uploading through CSV](https://github.com/Sunbird-cQube/community/blob/master/ui-configurations/broken-reference/README.md)
* [Connecting to Database](https://github.com/Sunbird-cQube/community/blob/master/ui-configurations/broken-reference/README.md)

**Add event data on a regular frequency:** To keep your program up-to-date, continuously add new event data to the platform. Determine an appropriate frequency for updating the data, such as daily, weekly, or monthly.w Ensure that the new data is compatible with the existing event and dimension schema.

### UI Program Addition

* Create a new module manually or using cli common ng g m \<module-name> in the below folder in the angular code base: src/app/views
* Add the folders config and pages, where config holds a configuration file for the reports in this program and pages contains the code of all the tabs/reports.
* Add the routing to the program component in the app-routing module using lazy-loading

<figure><img src="https://lh5.googleusercontent.com/5jp9HOEX24O3pU1qomvK1K-TUm5Tje1cqODomTY9kxwSqgK5paqkyLTaJeVt96H2tqjoMwsu_IPk6LdzgtYuhXJdXiIO2Lp0PbEm_Gx4tQ8_35LdxOL2zcQ5to94LBl9miclCtpV98IU-coMYD4giPw" alt=""><figcaption></figcaption></figure>

* Add the configuration of this program to the main\_matric.csv present in the root folder of query builder.( To add this program to side nav and summary statistics) as shown below.

<figure><img src="https://lh5.googleusercontent.com/C5MX471pQ3wkaeUMxk2b6m-DESKg5eR6DZ98TebG70dJKwe6i6y7GbtP2UWU0xrLRjL62S0iHJQLsDhSadRENe-hxakPhapeLSEcgB88O0r9qOb0Lit2X6hNHrvcD59yZWn7dXw-QWhdlKm6k13b8L4" alt=""><figcaption></figcaption></figure>

* Next add the programId filled in the above file to another file Program Selector in the query Builder root folder itself. The Program Selector file takes input from the ansible during installation to update which programs to be visible in the dashboard. If a new program is added after installation manually fill the programId and set the status true for that program to be visible in the dashboard.

<figure><img src="https://lh3.googleusercontent.com/ZmR3QT4W0BoD2xFvnxxFrBuoP2HlAoyyekf3i7HeG6ixAXUanwUnAA7v3joZvNvX0D2VtAgJqLDS9wZEh1E0dwejin8E83YSCFPhzaPhZpl9A390ABQWlkuAI3kIKMmldBnDdjdao4y2B2sObX6VeA4" alt=""><figcaption></figcaption></figure>

* Configuration file of the newly added program should be added to the below file:

src/app/core/config/configMapping.ts

All the configuration files are mapped at a place for easy access , This object will be used to map each row in main\_metric with program wise configuration files with the respective programIds.

<figure><img src="https://lh5.googleusercontent.com/hzRqczmIjAsrQz6MpSGPmnh6hIVO5_Iq8Hut922WAqTZgh495fPLdnozAsUUynvcZWly-PWhZtL_mFR3560MNxJVCCgtomPa6U0-9x2qTFOAgdqy02cJxra_LIoyGzaGNh9oQQpZR1Shi2QW--_jqSk" alt=""><figcaption></figcaption></figure>

Later one can add the desired KPI to the above program created following the below steps


# Additional Features

Here we can see some of the additional  features of the cQube


# Public/Private dashboards

During the installation, based on the inputs of the installer, access to the access for the program will be set to either public or private.

Public Access indicates that the program can be accessed via a public dashboard with a login as a user.

Private Access indicates that the program can be accessed only via a private dashboard, which is once any private or admin user is logged in.

Keycloak Admin can override the access from the keycloak admin console by following the below steps.

1. Navigate to the roles tab. Select whichever role admin wants to modify the program access to.

<figure><img src="https://lh6.googleusercontent.com/nxeAOQ03qRS2oGlD3YgiFbDPsQfutto5Cug0wASsbWKTO_icgZoMogZKdZ-DRLZSC4G_XtEKxtHqQ4jNcJFipjFpQ4VBpU_IhK52KwjqkuolDoc41DQugs22NbbHnscKgvC9dfaq86sVhjaFUUeBkQQ" alt=""><figcaption></figcaption></figure>

2. Once on the selected role page, select the attributes tab.

<figure><img src="https://lh6.googleusercontent.com/nxeAOQ03qRS2oGlD3YgiFbDPsQfutto5Cug0wASsbWKTO_icgZoMogZKdZ-DRLZSC4G_XtEKxtHqQ4jNcJFipjFpQ4VBpU_IhK52KwjqkuolDoc41DQugs22NbbHnscKgvC9dfaq86sVhjaFUUeBkQQ" alt=""><figcaption></figcaption></figure>

3. Modify the value of the attribute named key, which is a string consisting of comma separated program Ids and save to apply the changes.

<figure><img src="https://lh4.googleusercontent.com/KjOot73rZdxGmYJhtVVVVSXhm9vaBgTMKHLAg2SnhJLJSQAPGixhNgKEwH0Li4B8tlNOXBylN95_3bE9R4YUmwK0na02N9nk_twQE0ntcVObHmAPlO3NMMEAiY1Qkw1PlwPtUw12c4r_5Fu0XewQsdw" alt=""><figcaption></figcaption></figure>

4. Any role to be added can be appended to that string with a comma between each programId, or any program ID removed will no longer be accessible to the selected role.
5. Currently configured Program ID’s can be found in a table of spec schema: **spec.DatasetGrammar.**

Also following are the IDs that are currently available and configured program IDs within cQube:

&#x20;

* nishtha
* pm\_poshan
* nas
* diksha
* pgi
* udise
* sch\_att
* nipun\_bharat
* ncert\_quiz
* micro\_improvements
* telemetry


# Role based access control

During the installation of cQube, three roles will be created within keycloak.

1. Private\_user
2. Guest (Default)
3. Admin

Any roles created will be associated with guest roles by default.

For accessing any private programs, users should be assigned private\_user.

Any user who needs access to the admin panel as well as the telemetry dashboard will have to be assigned the admin role. One can be assigned both private, guest, and admin roles, through which he will have access to every program within the dashboard.

During the installation, two users, one guest and an admin—will be created and assigned appropriate roles.

Any user once created can navigate to the role mapping tab, select the required role from the available roles list, and add it so it will be associated with the user.

<figure><img src="https://lh4.googleusercontent.com/z6XCSisn1IjfNV-gQVBvibYXT9J57LZV5uxR0hnXUq0P3liNkSBGyqRLIKNbGdILjyRZgysInmEOTcfit828tHlaM1S9NGk2BCryoYuOYkrHcMD7AUFKlAjhfwqGRZ-P8RccRTNVLT2UIkiccVH4_Y4" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh5.googleusercontent.com/Z_04Kpe_VxOkA_jMkyaQuhSWnN1K3b3L85jDKFn3Orwx7P8MAcAxC6psEaFTCYuzsUBkq21y1WR0k8SadivE1cIB6UFNZ7CgNZ7DRNFS3ASK8QdIL81de8Rlr-ShZqjuA2Tp6qYEW6J8KuvuLJz_xYk" alt=""><figcaption></figcaption></figure>


# Saving geographical preferences

Any private user can have their priorities and preferences set for the first time, and whenever he logs into the dashboard, preferences will be automatically selected and the respective dashboards associated with the previously selected role will be shown.

&#x20;

Any user who wants his preference to be saved for the next login can check the save my preferences checkbox before submitting the role and level details.

<figure><img src="https://lh3.googleusercontent.com/Dkl1i41B-M79eZaW9ZtNHZaZQitWlMpTwbp9UruTAav33v1fzE4ARNm4w5NpFjqfmoRxZdtlH4a_7ipltDL3hJEA2EasOLYp7Ahk0hCH1gCI1NyDvIgHjUGcWoNcdCtKogomLhxCZnBzhwt-_Ij4ytI" alt=""><figcaption></figcaption></figure>

Once selected, the options for a particular role will be assigned to the user, and when the same user logs in again, they will be redirected directly to the dashboard with preselected values saved with the user.

&#x20;

If any user wants to override the preference, they can click on the home button and reselect the options that will be saved for the next login.


# Admin Panel

It is a web application that allows gives user essential and important tools for managing& using cQube

Features of the admin console include the following:

1. System Monitoring
2. Data debugger
3. Schema creator

It is accessible for an admin user only through a separate URL( Ex: https\://\<domain name>/admin).

\ <br>


# Data Debugger

It analyzes the data and reports the user about the errored records in the raw data file of an event or dimension. User has to select an event or dimension schema which is needed to validate the records of uploaded events or dimension files. After that debugger will analyze the uploaded data against the selected schema and it reports back to the user with the errored records. This feature helps the user to analyze the data before ingesting the data for data processing.

Data Debugger analyzes the fed data and reports and identifies the errors in them, if any, in an event or dimension files.&#x20;

**How it works:**

To validate the raw data of either dimension or an event, first:

1. Upload the grammar file for the dimension or event that you want to validate.
2. Validate the grammar file.
3. Validate the raw data against the uploaded grammar file.

**Steps to validate the Raw Data file:**&#x20;

(Please note - The raw data file should be in CSV format.)

1. Check 'Dimension Grammar' is present in the dropdown menu.
2. Upload the dimension file.
3. Click on the 'Validate Grammar' Tab.

Now, the system will show errors if any, in the screen for the uploaded file. If the file does not contain any errors, the user will be directed to the next screen.&#x20;

Here are more information about each step above.&#x20;

1. **Upload the grammar file for the dimension or event that you want to validate.**

The grammar file is a CSV file that defines the structure of the data that you want to validate. It contains information about the different fields in the data, such as the field name, data type, and constraints.

Following  screenshot of validate grammar of data debugger

<figure><img src="https://lh7-us.googleusercontent.com/-mkkkFxHJgnam06-Hf4xB1BTIPZX8JwXnVev-kyfbXOXUQP8zW7mfVs8C9wpoBURWmkS5RDgZm_vavsnQH6noi9pzlMrzU9QUcUpmAXQ_RG-u2obigDwboaaQtNyaQ0oH_mAbTLftzXgiZquyJRD-ZM" alt=""><figcaption></figcaption></figure>

Following is the sample grammar file block dimension:

<figure><img src="https://lh4.googleusercontent.com/E7XutNio5PHiOX1SsgOdA-6hM3kOMMjGN-8CzepJPcDtlS1N8HVB0vVsb86uCtcbFm_8MCngRAXi88P_0obkuNJ47UASe8wpJF5jA3jVrjqKyeXhxUgIkORPhRCq3Dvs2VyZq2FR_plfzY4ijmUmD3U" alt=""><figcaption></figcaption></figure>

**Note**: Include primary key if it is a dimension grammar file.

2. **Validate the grammar file.**

Once you have uploaded the grammar file, you need to validate it to make sure that it is correct. The validation process will check for errors in the grammar file, such as missing fields or invalid data types.

Here is a sample screenshot of a table that might be displayed to the user:

<figure><img src="https://lh3.googleusercontent.com/FIW-TicihbEBaXCx_zthE6ix4lLlC5522rZAjg1yA0CLMwj2YEIsO7S3u9UbExgmV3vxuclYq53ZTHnd_c9RZoMSRtHIyKpWAbkTDRg7duCnoqZxioLuVkzXG7nUlmM6FtdaNbF0sGI-E8M_ktaA8l8" alt=""><figcaption></figcaption></figure>

If the uploaded grammar file is valid, then a Validate Data button will be enabled for the user. Using the Validate Data button, the user can go into the validation step.

Following screenshot will be displayed to the user

<figure><img src="https://lh7-us.googleusercontent.com/sH3nVYHfOpopGhRZ03lBCbn-vAXoCyK7Y_Qz4wlx_NlKKJBjRleu_bIBM6nh086H-GFnuLONTAZJ7nD8ZZarynPEobKqTccOE1zYv8SxDDL5kTnklXJA636f5M5n5Q-vo5omoJd0uLmV0-8NwOWYluw" alt=""><figcaption></figcaption></figure>

3. **Validate the raw data against the uploaded grammar file.**

Once the grammar file has been validated, you can validate the raw data against it. The validation process will check for errors in the raw data, such as missing fields or invalid values.

If there are no errors in the raw data file, then the validation will be successful. Otherwise, the validation will fail, and you will be given a report of the errors.

Following screenshot for validate the data

<figure><img src="https://lh7-us.googleusercontent.com/8Qh_qyyzxBs-56hFhH6S4D3KqRG_54tojwBvf1EM7XgVgV0cDOEYS_bnJ9BPsWE2eQ-WQQkQEouo7tnN4SXLOt5lBfdYlKAbfr2TNUL18lWrPkam873ycP_mYmVoUZvfCOtOGnkd9D4G7hC0f4CtoYM" alt=""><figcaption></figcaption></figure>

If there are any errors in the uploaded data, then the errors will be reported to the user in the form of a table. Following is a screenshot of the error screen.

<figure><img src="https://lh7-us.googleusercontent.com/ZglCSoRa-h3u-5Y8Ejqenilfj0FJHCYkAoBqz8PKJUg3GbaqpWXlgoLfUkYn2lrjcdW6qu5nZa3Qa0B0xBTaXDbNG-p7csPi3ZH6jWjREYBTrfakgA-LQHSZT5jNaEQ2zGEpMyYkylvy8l4CEaFba9U" alt=""><figcaption></figcaption></figure>

\
If the file is valid, then a alert message  will be displayed to the user, which means that the data is ready to be ingested. Following is the screenshot:

<figure><img src="https://lh7-us.googleusercontent.com/jDZtQHs2PIanm81-8_hqjNw6SbtZ1e2duniZcQACNDpzJkqBI-m6Oi7axqNw--9EENKja2hy35KAjw-ux0NI9s6VkTUSvaKnyzw4HJypTzkYOeplKYZSksvapXd5zjEtvl2QktKTqIMhVZjng77GZsE" alt=""><figcaption></figcaption></figure>

<br>

**Steps:**

* **Grammar Validation**

The user must first choose the grammar file type to validate, either dimension or event. Then, the user must upload the grammar file. After uploading the file, the debugger analyzes the grammar and reports any errors to the user. If there are no errors, the debugger shows a message indicating that the schema is valid.

* **Data Validation**

The user must first choose the data file type to validate, either dimension or event. Then, the user must upload the raw data file. After uploading the file, the debugger analyzes the data against the grammar uploaded in the previous step and reports any errors to the user. If there are no errors, the debugger shows a message indicating that the schema is valid.<br>


# Schema Generator

Schema generator is a tool that can generate a schema for given set of data. This schema can then be used to validate the data and to generate code to work with the data.

In the context of  raw event data, the schema generator can be used to generate a grammar file and a dimension file. The grammar file defines the structure of the event data, while the dimension file defines the different dimensions of the event data.

These files could then be used to validate the event raw data and to generate code to work with the data. For example, the grammar file could be used to validate the event data against a schema. The dimension file could be used to generate a database schema or to generate code to load the event data into a data warehouse.

Here is an example of how a schema generator could be used to generate a grammar file and a dimension file for event raw data:

1. The user provides the schema generator with a sample of the event raw data.
2. The schema generator analyzes the data and generates a schema.
3. The user reviews the schema and makes any necessary changes.
4. The user generates the grammar file and the dimension file.
5. The user validates the event raw data against the grammar file.
6. The user generates code to load the event data into a data warehouse using the dimension file.

Schema generators are a valuable tool for working with event raw data. They can help to ensure that the data is well-structured and easy to use.

Steps :&#x20;

1. Upload the sample event data CSV file. This file will be used by the schema generator to extract the schema and derive the dimensions.
2. Review the schema list of fields and field types. The schema generator will display a list of fields and their types as either dimensions or metrics. You can update the field types if needed.
3. Click the update button to generate the grammar and dimensions for the given event.

Once the schema and dimensions have been generated, you can download them in a zip file. This file will contain two files: a grammar file and a dimension file.

The grammar file defines the structure of the event data. The dimensions file defines the different dimensions of the event data.

You can then use these files to validate your event raw data and generate code to work with the data. For example, you could use the grammar file to validate your event data against a schema. You could use the dimensions file to generate a database schema or to generate code to load your event data into a data warehouse.

Here are some additional tips for using a schema generator:

* Make sure that the sample event data file that you upload is representative of the entire event data set. This will help to ensure that the schema and dimensions that are generated are accurate.
* Review the schema list of fields and field types carefully before clicking the update button. This will help to ensure that the schema and dimensions are generated correctly.
* Once you have generated the schema and dimensions, test them with a small sample of your event raw data to make sure that they are working correctly.

&#x20;**Example:**

1. Upload the sample event data CSV file. This file will be used by the schema generator to extract the schema and derive the dimensions.

Following  screenshot of the schema generator.

<figure><img src="https://lh7-us.googleusercontent.com/R6NULK18Gu7HLMjUDGqW3XRRWeCQa80WACcnLXSTMIJgzFFMoJuRSHUAmNDK3WrO1AUQdny6kRvbgq6TV2OXitWI9iXgqUyZOJvhLOPUGfgYZ3dxt770Wtadn-puewihWu8tOSiiT6hnx0_Ccn40Fhc" alt=""><figcaption></figcaption></figure>

Following is the sample data for the ETB coverage status data of the DIKSHA program.

<figure><img src="https://lh6.googleusercontent.com/Ar7ZqUCH7uC5Jr_Y2JpuplaEenmJx0P0uIDeamXSeeDKBO5QgXLjLFEXbqMp_l82bsGyFbMOKEjyEOL2P4cU_oyi9NEfbI7mvLddMlkZBTwf1_R5zl3ZT10nKHIGor89B-2lffdoTLdsEOAjg6gnOcw" alt=""><figcaption></figcaption></figure>

Once the user uploads the file, the extracted schema will be shown to the user in the format of the table. The following screenshot represents the sample screen.

<figure><img src="https://lh7-us.googleusercontent.com/inrPqECLI2vJFEXWPX_nX9-nwgIfFRoJdxA_wXbj-ZPBeDlh3DADHORKoR_HjJTVCoUsid29WOdFs34JC8pUne78-SP6gnTRLn0bNh6TYvZFR852QQsCC1DWHRAdmAV8G55BXdO_MM-8Kf8CDQ0Sd_0" alt=""><figcaption></figcaption></figure>

The user needs to be able to enter a program name and description, and choose whether the field should be treated as a metric or not. The field types are also shown in the table for every field. Users can edit the name of the field if they want and those field names are editable in the table.

Along with the above, users are also able to select dimensions as well. Here’s the screenshot of another part of the screen that contains adding Dimensions.

Note: Automatically date time fields are considered as time dimensions.

<figure><img src="https://lh7-us.googleusercontent.com/wQAkHh_-cmIhtbvs1i-UwBP6VgSmJJ3ckkBSEhnG3yf6CZCqPHMUYRWcu-eVTgYrRFFwKH1n8wVTnHCnu90Xkeg8s9OO7lPxqn4zAJNaCDFgGEwQNUjNWUm4SraVtp-UxVWH_MxBlfMaDqytb7FJ7o4" alt=""><figcaption></figcaption></figure>

Users will be able to add Dimensions as shown in the above screenshot. By clicking on the “Add Dimension” button, users can add a new dimension for the event. After adding the dimension, the user needs to add at least one field from the event to the dimension. If the user adds more than one field to the dimension, then the user has to define at least one field as “Index”. Indexes are useful in removing the duplicates from the records while generating the dimension files.

Note: If the user only selects one field for the dimension, then no need to define the Index field as the selected field would be considered as the Index for that dimension.

After providing the required inputs, users can be able to generate dimensions and events by clicking on the above “Update” button.

<br>

2. After generating the dimension and event grammars for the provided file, the following screen will be displayed to the user.

<figure><img src="https://lh3.googleusercontent.com/nENtiN36DVUufT1K_qaTHAwComQ66pnqNjdtNpqHRlfBfXoUKIlOFolN4Tw2ySDP5Du_nKcUkTJwe-xVwI_UsPk07h9oJ3Rvkfa4V6Yl49MY5GHBwNCFYPyAX_YyAYGz6d0ARJ_2JTP65lWSesV3Jzk" alt=""><figcaption></figcaption></figure>

The screen has navigation buttons at the top that the user can use to switch between the dimensions and events tabs. The list tab contains information about the dimensions and metrics list.

The dimensions tab contains a drop-down menu that the user can use to select the dimension they want to see.

<figure><img src="https://lh4.googleusercontent.com/lB9KURorRu__hfQuDeNuIueAwBXyuOHASjs3Qow9WdGCiE9xFDOWDzVrJwSOu0aV_hgjB6L0iJYknQePow_vYlZWfxUxgeCie19wCtLdNQS_d8uidBC8m_FwLxZIvCqWpR0a4xyx5cLA7ktIBiUH6MQ" alt=""><figcaption></figcaption></figure>

The events tab contains a dropdown menu that the user can use to select the event they want to see.

<figure><img src="https://lh7-us.googleusercontent.com/Gq1MNe1uw0Myi0jM9SUhQoxQFIqKffkA9d-6tJ7CdwjvDu0Xcy_N8fdx2Z-qhw5VMMIDpwI30WaDpJRL6QJ4rmAKgY9L_SqbpQWkH2ojUwMlx__FIl-xOFs2OKA-YVIet12k0o18Tt_sszZ3hauFuJc" alt=""><figcaption></figcaption></figure>

The user will be able to download all the generated files in zip format by using the “Download Ingest” button.


# System Monitoring

System monitoring contains information about the system resource consumption and status about docker container services of cQube.

* Once the user is logged in to the admin panel. Click on monitoring, It redirects to another window where you will be able to see the grafana dashboard.

  <figure><img src="https://lh7-us.googleusercontent.com/sFQuePVF4oaTVHt-8yW6KZYnrNMbcEGxC7oppHV5fHQOiWFlBqr915cpUDJJYCiCVKE-wx9S5Ve6Axi3D379iCJL0Lood8qdQkdee3tKNpu3GTBS0JMM1s5FVrEcVadwRmC-gddQPYonATluOyqz0_0" alt=""><figcaption></figcaption></figure>

  * By default the username and password will be the following

  Username: admin

  Password: admin

  * Click on login and the change the password as prompted

  <figure><img src="https://lh7-us.googleusercontent.com/d1UfOGVO4a37D8dedJe8gynFbYOIhtqvyRoyZE9xRLD5yajiLKUAPOvDWFlsWNJCpM6BHpBApb4s8zHOsK9Eh9utZPsd6_OoamzZToLErMW5zJAPF5caeYSJqoEyUeGsKvYfAZJHNkoYLgfyebY6ev0" alt=""><figcaption></figcaption></figure>

  * Login to the grafana dashboard and click on the Toggle Menu bar and then click on Dashboard

  <figure><img src="https://lh7-us.googleusercontent.com/t33P6WCZRf_SCu7uogWqU-PlPyhQca2oHcm3_BMCa1txBJ9U_rl224Ryx5_ZZw2vo7yDqnFQ-g2K4mZWcLk3PE9R4-ViSFvftYt9P-YIQEJ9vy1FLw6ooZ6ubnPDeqeCLZ52OnvCjx_HM5Wx2bmKryM" alt=""><figcaption></figcaption></figure>

  * Once you click on dashboards, you will be able to see the dashboards. Click on General to expand the dashboard.

  <figure><img src="https://lh7-us.googleusercontent.com/4p-PqLW2NHqXecScpPJ--bLB4TNn1KvJBW2hy306o1-fdrzzFbYG0NemIWTdgQ01xzPJWZ1WfnYwJg13TWithGDWgIty0m0pDeloEHgXv-ZHSysEXUJYinsOesG4k7bFsLVTkvsf4jEL5jSv86yV5rc" alt=""><figcaption></figcaption></figure>

  * **Docker containers:** This dashboard contains the general statistics about the docker container performances.

  <figure><img src="https://lh7-us.googleusercontent.com/jMHu30TEmvttPBS9uWtvgigFj3A-N-kgLEdvg7UnJUxBzDpeOO12DBwH4y_cNx4werMBQramPqlKCJWbEEAh7xi3nwaXI2aEoQM7UdcHCYNqANMvqz3mwyhsjGe29MDMT0XCAhYBVFs1YLCAy4hCcEI" alt=""><figcaption></figcaption></figure>

  CPU used: This module gives you the total number of CPU used by the containers

  CPU cores: This module gives the information about the number of cpu cores the VM is running on

  Memory Load: It gives the total percentage of memory load by the docker containers

  Used Memory: It gives the information about the total GB of memory in use by the docker containers

  Storage Load: It gives the total percentage of storage load by the docker containers

  Used Storage: It gives the information about the total GB of storage in use by the docker containers

  Running Containers: It shows the total number of containers which are up and running

  Container CPU Usage: It shows the usage of CPU consumed by each container

  Container Memory Usage: It shows the usage of memory consumed by each container
* Infra Metrics: This dashboard contains the general statistics about the docker infrastructure

  <br>

  <figure><img src="https://lh7-us.googleusercontent.com/RRKwLw1QrTck2vk2jwRkqhCur0I-mnSF69bMUDKuEM9sm0UapStB5vfbutwRyCoWzgd2R2VTI1GfKP7uaxmver98ZMUxGVo7UpE8AMKTATM-sP_YKzxuCo-OiqIelOIXQUiX0GN_SyxRy0ryz03YOjc" alt=""><figcaption></figcaption></figure>

  Uptime: It shows the total uptime of the server from the last shutdown.

  CPU idle: It shows the percentage of CPU idle at that particular time

  CPU cores: It shows the number of cpu cores the VM is running on

  Available Memory: It shows the total GB of free RAM in the VM

  Free Storage: It shows the total number of free storage available

  CPU Usage: It shows the usage cycle of cpu

  Memory Usage: It shows the usage cycle of RAM

  Network Usage: It shows the usage of input/output network usage
* **Monitor Services:** This dashboard contains the statistics about the monitoring services.

  <br>

  <figure><img src="https://lh7-us.googleusercontent.com/zbg2NLQJoUncVF36YAH5hHnEecKmzLGm76Geva6kmbJgR8hF-JUedt2WnPLCexDx11Xi2fDP_zTzrgEPq3xpdDHrL8RZwi5_ui532bumUzaKWUMCFv-V_0RgWlvYTAKRXU-b29gw7-TFgiv2dPuI7w0" alt=""><figcaption></figcaption></figure>

  Prometheus uptime: It shows the number of minutes prometheus is up and running

  Memory Usage: It shows the memory usage of monitoring containers

  Container CPU usage: It shows the percentage of cpu used by monitoring containers

  Container memory usage: It shows the percentage of memory used by monitoring containers.&#x20;

  <br>


# Adding Users

There are 2 ways to add users to cQube V 5.0 via Keycloak:

1. Adding individual users
2. Adding bulk users


# Adding  an individual user

**Step 1 :** Post configuring Keycloak as explained here, navigate to the Users tab.

**Step 2 :** Click on the add User button.

<figure><img src="https://lh6.googleusercontent.com/9_gt-INUgN3uRi38bpffr2NG-zGSzJUutgjzE24oZCWPEit-ItlIOPQupVxXrkqkKnPZEYoZIZmGs8sEThlnLKcQx-frhFe9QQwOmwSUBW7keBvYJ06xY62GRiIRXSF7_4Sp7CdKv4r9YNe8d3-h-lk" alt=""><figcaption></figcaption></figure>

**Step 3 :** Enter the username for the user being created and save.

<br>

<figure><img src="https://lh4.googleusercontent.com/jxokXbfNzN7GM-GKJfff10w3nWc-F8gCuhnay5YI7-t6P0vO3xsf6jSNfzPmEOh8cK2vZl3oPt_1tsz-ZY86yC2ET0ldegayY2fbMQZq0hj6bwo_9Q6DMZAkEljZg8Wf-gbrpY8iCkNUWDY8SBkjA9o" alt=""><figcaption></figcaption></figure>

**Step 4 :** Once the user is created, navigate to the Credentials tab and enter the required password. Turn off the temporary password option and click on 'Set Password'.

<figure><img src="https://lh6.googleusercontent.com/FTObnD0Tike047IKtWyf1pb7JKbjyf6u0v3xaQRPTeZPZKGuN-msk5VNcUskJ2hNi-99C2Ws-fJyuxSE77k4zzZsl9DOxz1RkXb144Ndqf98zwizx2KZAXIoxnI_4aWaHgJ0L5HBgRBsjr7-akrPazk" alt=""><figcaption></figcaption></figure>

Step 5: Navigate to the Role-Mapping, under Realm-roles select private\_user and click on ‘Add selected’ button. This will assign the private\_user role to the created user.

<br>

<figure><img src="https://lh6.googleusercontent.com/WU7R49zl1M-KKoO1AK17BbzUU_uVcBrOYeBzbwz_TKWo8R9xuYzvX6EdnRfCtZk3p3HION3sJmkwAaCh0ziaqVMdVhAjVdTEdPHOa5xF5KpkVd-1KsSxO3d9Sj4Icn_nbXv8KPwx9I1ei5VY1FiKkBo" alt=""><figcaption></figcaption></figure>

✅ The required user has been added successfully!

**Steps to manually enable the flag to store Role-Info**

**Step 1 :** Navigate client scopes on the left hand navigation.&#x20;

**Step 2 :** Select roles under the client scopes in the table.

<br>

<figure><img src="https://lh5.googleusercontent.com/w9NGiRzpF2-7yBjdSjh_8vNp8MhpHBIk2T7QQ4BEfBaWKxNbWWapNEKo-6I9bhc1ZpY-6rlWevKna3RInTbHYj3Jk3Da4i3j7g8q7_-2LS9yDA4ExzhPDAydmCoS_ioJBWRwbl-fs6l2s1f7ZUu7gC8" alt=""><figcaption></figcaption></figure>

**Step 3 :** Navigate to the Mappers tab on the top and select realm roles.

<br>

<figure><img src="https://lh4.googleusercontent.com/yYgd2l533KKBJQyHDUjr3gqIw3vVu6Fs0TIgHfU1KqKWWKpiLVSammtnNYTMr_L8XAtCiLQTYho2rok9mrdSOd11u6VOmpLQpVdSivShYl48sPU1jlxwO5DDsoSlHcPIvchfJDkIvSKBpXHv3fOXT-E" alt=""><figcaption></figcaption></figure>

**Step 4 :** Toggle Add to UserInfo button and save.

<br>

<figure><img src="https://lh5.googleusercontent.com/UbFCVNB98nQSJ1I2zx-wBsP1ZX-zaqrWZ8S7vXVN5QcQqXT49ibn6rSHVjrZB2zlmFoW1QuRqYnUgDMq_1pf9PY0QKokIsZx1z1Nw7kxapBKEvyIGzo-V8lK37Js8jgDZ8x5QGb6qBmNJkqgNfRv-hM" alt=""><figcaption></figcaption></figure>

<br>

#### &#x20;

<br>

\
\
\ <br>


# Adding bulk users

**Step 1 :** Navigate to 'Import' tab in the 'Manage' section.

<figure><img src="https://lh5.googleusercontent.com/JnzuT_4qD3rnHXoehyc1yq7QA0txxC-81ph_6cW88TkaqzRdr0UOhinM87FYSqXOBUIoY-SqBYx2q5D_PtqmYJPJJSuMZhMTPlnbyVnre1PZdftA17011MS0qKRF6qp4mF3QgZohk2PDvsGCQlfbjSU" alt=""><figcaption></figcaption></figure>

**Step 2 :** Click on 'Select file' and upload the .json file containing information of users to be added. (.json file should be in the format as shown below)

<figure><img src="https://lh4.googleusercontent.com/LnoooF3quq4z28k8lj43QGQ6A1lwH4V9ab-ZMh3jp9W8u9qb4HYaGLVFoi5qr_BqUfA6-0gglhWsYbqtofBuPzdU6HvqInliby1xahkpiNMrSAfMxEMbLTbC9TMJYzG4dtIae7xpDpfZrUJyA8XchaM" alt=""><figcaption></figcaption></figure>

**Step 3 :** After selecting the.json file, turn the import users option on. Then, in the dropdown, select 'Overwrite' if you wish to overwrite existing users with the same information, or select 'Skip' if you want to skip them. If you select 'Fail', the process will fail in case there are users with duplicate information.

<br>

<figure><img src="https://lh5.googleusercontent.com/W7Peh1cGpMiFzVuXgYIFELW8eg--SSJjENv7H9OmQC7TWSzbSo8KVgRK3pZa2hvFIo1Xwjme8MgFkxlQXBj50kfjBVRMLX2hfA5ADFxXTlmFoTw9Gx9ToCi5Xrp0M5yKG45_Xa2JpYiIH8bTIPhlNhs" alt=""><figcaption></figcaption></figure>

**Step 4 :** Post selecting the dropdown, click on 'Import'.

<figure><img src="https://lh3.googleusercontent.com/xZHpOd1Uxe6PWmRByK6571G0hWtXlJhfH0JAr706cBRW76O6TW7LWtI5eIsYTOoMoo2yTH4BNw5M_k5X9aR93EKp-2Vfs1WwmH6gqxfbF2IwH-Qe5uQFXvLY_eGZmIzN6uARsNeY3WivgYlqxIk0EL4" alt=""><figcaption></figcaption></figure>

✅ The bulk users have been added successfully and will be able to login to the application using respective credentials!


# Infra health monitoring

* This dashboard contains the general statistics about the docker infrastructure

<figure><img src="https://lh5.googleusercontent.com/AfOlO9320UfGK2mYDEL-T0eK1rapVdpVdPr9PIAfhUwdkHT5E3yTGuwPPZsdGlbu0hmo0AdCRRBZBJrLIH7GfGUSP39ST6uUGFLhO0klaPBE_BR-9W2-k8daSDDYWPBcmAZgqyP5aS4khBiATV6I1-s" alt=""><figcaption></figcaption></figure>

| Metrics          | Description                                                     |
| ---------------- | --------------------------------------------------------------- |
| Uptime           | It shows the total uptime of the server from the last shutdown. |
| CPU idle         | It shows the percentage of CPU idle at that particular time     |
| CPU cores        | It shows the number of cpu cores the VM is running on           |
| Available Memory | It shows the total GB of free RAM in the VM                     |
| Free Storage     | It shows the total number of free storage available             |
| CPU Usage        | It shows the usage cycle of cpu                                 |
| Memory Usage     | It shows the usage cycle of RAM                                 |
| Network Usage    | It shows the usage of input/output network usage                |

<br>


# Usage monitoring

**Telemetry Process**

Telemetry is a database which provides the website traffic information to the users.  This tool provides datapoints like number of visitors, their access style (devices) and the report type they have accessed, etc.&#x20;

1. KPIs/Metrics captured:&#x20;

&#x20;            a. Most Visited Landing Pages

&#x20;            b. Users Count

&#x20;            c. Average time spent on each page

&#x20;            d. Unique Users across Browser & Device Types

&#x20;            e. Roll-Up of users using (Daily, Weekly)

&#x20;            f.  Click, Select, Download

2. Define Events, Dimensions & Schema

eventName : telemetry-event.data

<table data-header-hidden><thead><tr><th></th><th width="165"></th><th></th><th></th><th></th><th></th><th></th><th></th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td>date</td><td>timestamp</td><td>userId</td><td>pageName</td><td>pageEvent</td><td>pageEventName</td><td>deviceType</td><td>userLocation</td><td>browserType</td><td>timeSpent</td><td>timeIn</td><td>timeOut</td></tr><tr><td>24/04/23</td><td>13:00:11</td><td>cf797e0a-b857-47f1-b0d7-10bd83231421</td><td>teacher-attendance</td><td>click</td><td>download</td><td>web</td><td>Bengaluru</td><td>chrome</td><td><br></td><td><br></td><td><br></td></tr><tr><td>24/04/23</td><td>13:00:11</td><td>cf797e0a-b857-47f1-b0d7-10bd83231421</td><td>teacher-attendance</td><td>onload</td><td>pageLoad</td><td>mobile</td><td>Bengaluru</td><td>firefox</td><td>3213</td><td>13:10:02</td><td>13:13:02</td></tr><tr><td>24/04/23</td><td>13:00:11</td><td>cf797e0a-b857-47f1-b0d7-10bd83231421</td><td>pgi</td><td>click</td><td>apply</td><td>web</td><td>Bengaluru</td><td>chrome</td><td><br></td><td><br></td><td><br></td></tr><tr><td>24/04/23</td><td>13:00:11</td><td>cf797e0a-b857-47f1-b0d7-10bd83231421</td><td>teacher-attendance</td><td>click</td><td>cancel</td><td>mobile</td><td>Bengaluru</td><td>chrome</td><td><br></td><td><br></td><td><br></td></tr><tr><td>24/04/23</td><td>13:00:11</td><td>cf797e0a-b857-47f1-b0d7-10bd83231421</td><td>login</td><td>login</td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td><td><br></td></tr></tbody></table>

<figure><img src="/files/p0ZOpvzq6aFJHQeC5yvH" alt=""><figcaption></figcaption></figure>

3\. Workflow

&#x20;                The diagram explains about the flow of the telemetry works.&#x20;

<figure><img src="/files/bfUddZbUHkbFssXAECQB" alt=""><figcaption></figcaption></figure>

4. Visualize the reports.
5. Steps done for enabling telemetry

&#x20;           a. Create a python script for splitting up multi metrics into single metric (<https://github.com/Sunbird-cQube/generator-ms/blob/release-v5.0.5/adapter/telemetry.py>).

&#x20;            b. Add the telemetry details in config.json file (<https://github.com/Sunbird-cQube/processing-ms/blob/release-v5.0.5/impl/c-qube/ingest/VSK/config.json>).

&#x20;            c. Create nifi processor group to schedule for moving data and processing

&#x20;            d. Add new UI report

&#x20;            e. Add the logics in UI to capture the events

&#x20;            f. Create the grammars&#x20;


# Testing approaches & activities

Two types of testing approaches are followed in cQube:

1. &#x20;**Functional Testing:**&#x20;
   * Smoke Testing
   * Regression Testing&#x20;
   * System E2E Testing&#x20;
2. **Non Functional Testing:**&#x20;
   * Performance Testing

Testing activities of cQube are divided into 3 phases:&#x20;

1. **Installation Testing** - AWS  SDC (On-premise)  , Oracle&#x20;
2. **API’s Testing** - Spec , Ingestion ,Dimension and Scheduler
3. **Visualization** - UI Application Testing


# Manual & Automated testing

**Testing activities mentioned below are done manually:**

* **Installation of cQube** - AWS&#x20;
* **Installation of cQube** - SDC / On-premise ( localhost and Public )
* **Installation of cQube** - Oracle

**Testing activities mentioned below are automated:**

* **Using Karate Framework** - CuCumber with BDD approach automated all the event/spec, Ingestion/, /dimensions, /scheduler, etc., covered with all the required validations to the API responses.
* **For Visualization** - Using Selenium with a Python programming language and Pytest framework for running the automation test suites - almost 80% of the UI application can be automated, and the rest of other test cases are executed as a manual process


# Functional Testing


# Smoke Testing

When the build is ready for QA then, we will take up the release build version code and start testing the major features of the application to ensure that all the functionality is working as expected or not by following the phases&#x20;

* One-step Installation - Positive Scenarios to be executed
* API karate Framework - Calling Spec , dimension , Ingestion, and Schedule APIs for each program wise to verify able to add schemas to db , input files to buckets, and verify the ability to schedule the Nifi processor and validate the processing of the ingested input files&#x20;
* Verify the after Nifi Processing of the files whether datasets of all the programs have been created tables or not in the database&#x20;
* Verifying the Visualization&#x20;
* Login Page&#x20;
* Dashboard - Summary Statistics&#x20;
* All Program Dashboard - Data is showing up or not, and each web feature functionality is working as expected or not


# Functional tests

When Smoke Testing is completed with 0 Blockers and 0 Majors, then we proceed with functional testing by following the phases&#x20;

* One-step Installation - Positive and Negative Scenarios to be executed
* API Karate Framework - Validation of spec , Ingestion , Dimension , and Schedule API, both positive and negative scenarios using karate.&#x20;
* Verify the after Nifi Processing of the input files whether datasets of all the programs have been created tables or not in the database&#x20;
* Verifying the Visualization.&#x20;
* Login Page&#x20;
* Dashboard - Summary Statistics&#x20;
* All Program Dashboard - Data is showing up or not, and each web feature functionality is working as expected or not


# Regression Testing

This kind of testing activity can be followed up when new features or new enhancements are made to the existing UI - Visualization report. Then we will go through the Completed end to end regression testing of the Application, which includes&#x20;

* Login Page
* Dashboard Screen&#x20;
* Summary Statistics - All Navigations&#x20;
* Each Program Dashboard and tab, along with web features to be tested&#x20;
* Session Out and Resolutions testing ( 2K & 4K ) with Chrome and Firefox compatibility browsers


# System Testing

This can be done when there is no blocker and major defects are on the defect list. Then it would be the final round of testing activity before moving to production/sign-off from Quality Assurance of the Application&#x20;

* One-Step Installation - AWS , SDC/On-premise , Oracle&#x20;
* API Testing - Spec , Ingestion , Dimension , Scheduler&#x20;
* Nifi Processing Validation of ingested program files&#x20;
* Database validation - verification of all the programs datasets are created or not&#x20;
* Visualization Testing - Login Page , Dashboard Page , Program Dashboards and their each tab functionalities to be tested&#x20;
* Verification of Logout , Release date , Release version and Resolutions tests


# Non Functional Testing


# Performance Testing

The practice of evaluating how a system performs in terms of responsiveness and stability under a particular workload&#x20;

1. Load Testing&#x20;
2. Volume Testing


# Load Testing

It is a type of Performance Testing that determines the performance of a system, software product, or software application under real-life based load conditions. Basically, load testing determines the behavior of the application when multiple users use it at the same time&#x20;

Example: Scenarios are covered with minimum and maximum number of concurrent users are accessing the application on same time to verify that how the application can handle the pressure and responding to the user request


# Volume Testing

It is a type of software testing which is carried out to test a software application with a certain amount of data. The amount used in volume testing could be a database size or it could also be the size of an interface file that is the subject of volume&#x20;

Exmple: In cQube application we have ingestion of program wise input file which is in the csv file format here we are tested the sending the larger amount of data from 10L to 3M of records with csv file size approximately 1.5GB through the API to bucket&#x20;

<br>


# Performance testing results

Please access the link [here](https://docs.google.com/spreadsheets/d/1ec7CrZ07BP0lc8DbYkyMJHa5oHJii3GorGhCa0qMUHk/edit#gid=159280127)


# Test for One-Step Installation

Executing all the prepared manual test cases of one-step installation by manual by providing positive and negative inputs while doing installation and capturing the errors/defects, and updating into Jira board along with reproducible steps and screenshots for the understanding defect smoothly and avoid difficulty to understanding the defect to developers.


# Test for Ingestion

* By using Karate Framework - developed the cucumber scripts to read the schemes provided by the DB developers and based on the ingestion data to be generated according to predefined columns and data types of each file&#x20;
* Running the karate scripts to verify whether the ingestion process is working as expected or not&#x20;


# Test for nifi processing

* Once all the Ingestion and Dimensions files are uploaded to the process\_input folder, then we will schedule the Nifi processor group to continue further processing of uploaded input files and store the final result in the database by creating datasets.
* Verifying whether each program-level dataset is created or not in the database.


# Test for UI Application

* For Visualization - Automated the scripts using selenium python using pytest framework that has covered all the UI automation up to 80%. Most of the features are to be automated with both positive and negative validation in the automation scripts and will run the scripts once Nifi processing is completed&#x20;
* Rest other, like 20% of manual test cases like alignments , tooltip information, and resolution testing ,can be covered in the manual testing


# Test for KPIs

By using Pytest Framework : we followed to get the output data from the database and implemented the business logic, and verifying the final result matched to the expected outcome&#x20;

Step 1: Prepare input JSON files for each program(student\_attendance, teacher\_attendance, etc..) which have all the dimensions needed for a particular program along with its values and along with its metric with min and max values.

Step 2:  Use the grammar file required for the program (student\_attendance, teacher\_attendance, etc..) in order to extract the time dimension, dimensions, and metrics.

Step 3: Get the required time dimension and dimensions from the grammar file

Step 4: Get the required metrics from the config file

Step 5: For each metric in the program, generate the test data along with the required dimension columns specified in the config file.

<figure><img src="https://lh5.googleusercontent.com/-slTNSHx-QA_PWsjzA3_BXfqQFPKSwOZ6e0CTzJ9wTJOYXgtAUdRdYHhjjspu2tmREf9sRzXblyaFa1pYqa4-uthkuOBsnzafbvccOvDhdjzzKvYbmXtD9r-S11o_43Zwg4poPngB3Fm1ruSFVBZan0" alt=""><figcaption></figcaption></figure>

Step 6: Split the generated test data of each metric according to different time\_lines (daily, weekly, monthly, yearly) for each dimension key-metric aggregate value combination, to use it as the expected data (which should be filled up through manual calculation).

<figure><img src="https://lh5.googleusercontent.com/lmscir8PsMhD_3WlQKqoGoAH5OIHCqvwpCmK5uLZ-LDrsOPlDI_lTsgSZryPsxXCA1rwMluabhS_9fLh-3bXZnVH0iRSOnd9ahUuyDcIc7eTYU0aQtRnl3RnfwbHqm1Np4hQlkOKiT4Osxpt6Gfos_Q" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh6.googleusercontent.com/kjWe5RjYbeEufHIWa9OBHICYnoGVx-yVxDnAFVj52UJR8wPGzD31eve9hngsFnPjDgFAfYuokcj_VzGu5gI8b-8PG14u5VobeicAz9DuaB1jSEJ-tyiYkfjP_NaX6jDuENSGDlIUlFaZ0_KHCz8l1fA" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh3.googleusercontent.com/fo_JJXH2dbsX9AIzMeq2z5g2iKDs0xeAjq9Y2Wlpf5-OISIc7nZr7u3MN6fwo6CJwu8pyIhXWmAnEvXQTH35dQAucT6S0z2gcagiIEpuL1mMOorJUT_AMKyKPMTQkTSvwu2oTCn7VSdO8eSjqk4J4SA" alt=""><figcaption></figcaption></figure>

Step 7: Ingest the test data into the cube server and get the processed data in the database, which is the actual data file.

Step 8: Fill in the aggregate values for expected data manually.

Step 9: Compare the actual data with the expected data and generate the HTML test results.


# State List

Here the list of state name and state code

| State Code | State name                  |
| ---------- | --------------------------- |
| AN         | Andaman and Nicobar Islands |
| AP         | Andhra Pradesh              |
| AR         | Arunachal Pradesh           |
| AS         | Assam                       |
| BR         | Bihar                       |
| CH         | Chandigarh                  |
| CT         | Chhattisgarh                |
| DN         | Dadra and Nagar Haveli      |
| DD         | Daman and Diu               |
| DL         | Delhi                       |
| GA         | Goa                         |
| GJ         | Gujarat                     |
| HR         | Haryana                     |
| HP         | Himachal Pradesh            |
| JK         | Jammu and Kashmir           |
| JH         | Jharkhand                   |
| KA         | Karnataka                   |
| KL         | Kerala                      |
| LD         | Lakshadweep                 |
| MP         | Madhya Pradesh              |
| MH         | Maharashtra                 |
| MN         | Manipur                     |
| ML         | Meghalaya                   |
| MZ         | Mizoram                     |
| NL         | Nagaland                    |
| OR         | Odisha                      |
| PY         | Puducherry                  |
| PB         | Punjab                      |
| RJ         | Rajasthan                   |
| SK         | Sikkim                      |
| TN         | Tamil Nadu                  |
| TG         | Telangana                   |
| TR         | Tripura                     |
| UP         | Uttar Pradesh               |
| UT         | Uttarakhand                 |
| WB         | West Bengal                 |


# AWS Deployment

&#x20;Here the details for the complete deployment process

**Prerequisites to install cQube on AWS machine**

* Ubuntu 22.04 (supported)&#x20;
* &#x20;16 GB of System RAM (minimum requirement)
* &#x20;4 core CPU (minimum requirement)
* &#x20;Domain name ex: <https://cqube-demo-cert.tibilprojects.com>
* SSl certificate keys ex: certificate.crt and private.key
* AWS access\_key and secret\_key
* &#x20;250 GB Storage

**Step 1:** Use the following command to connect to the AWS instance

&#x20;              ssh -i \<path\_to\_the\_pem\_file> \<user\_name>@\<public\_ip\_of\_the\_instance>

&#x20;             **Ex: ssh -i poc\_key.pem -o ServerAliveInterval=60 ubuntu\@13.200.12.31**&#x20;

**Step 2**: Clone the cqube-devops repository using following command

&#x20;               git clone <https://github.com/Sunbird-cQube/cqube-devops.git>  &#x20;

<figure><img src="https://lh4.googleusercontent.com/24la-c3z7usSWqXH9eQmv5wTynOWYuUoC35pobDgLzBk2-T08oQdygbOnbKPzsas_9WwUGoo4pIAjjR-BYdt7Kanf4FQek-3PYf5fSUX7UqHZc7LOEbuv9q8HM0ciNDbb1SH2abWQI7VJ0N3jBA-f88" alt=""><figcaption></figcaption></figure>

**Step 3:** Navigate to the directory where cqube is cloned or downloaded and checkout to the desired branch(Release Branch)

&#x20;                                cd cqube-devops/&#x20;

&#x20;                                git checkout release-v5.0.5(latest release branch)

<figure><img src="https://lh5.googleusercontent.com/SNlt2aYh61rk83eTmD-4P2vuSPP_vq-JbgZ9kBmBFRJzbzBFL_XPsE2IdRxICbu90oiWPDvI5lIHYG5un3TH3a5zgFTx0QC6gZd3eHNNU01kxGBEkYDmO0GsRu742Do6DEW58KX4355SO4Nrk0NytpM" alt=""><figcaption></figcaption></figure>

**Step 4:** After checkout of the latest branch, we need to move the SSL keys (.crt and.key) to the mentioned path, as shown in the below screenshot.

&#x20;                       Path: cqube-devops/ansible/ssl\_certificates

**Command for moving ssl keys:**

&#x20;                       cp certificate.crt  private.key /home/ubuntu/cqube-devops/ansible/ssl\_certificates

<figure><img src="https://lh5.googleusercontent.com/JEAnluvA_6GJZu4RdQAm8_hC5kpmXauxfzaqzErltZTc-igVIlhtOFqsSdEsfY_gYR_9aJ9d_Nj3pq1d3p-GGUvvgQQtS8TCG11o1zorFz1f9Nuf4YZyAtMTkVFeRYCytwv0U6uiz1GgrFgvLple-8U" alt=""><figcaption></figcaption></figure>

**Step 5:** After copying the ssl keys similarly, we can move the VSK dimension to (state,district,grade,subject,medium) below the mentioned path, as shown in the screenshot below.

**Command for moving dimensions:**

**(Note: This Step 5  is applicable for pulling the data from NVSK )**

&#x20;                      cp state-dimension.data.csv grade-dimension.data.csv subject-dimension.data.csv etc../home/ubuntu/cqube-devops/ansible.dimension\_files

&#x20;                      Path: cqube-devops/ansible/dimension\_files.

<figure><img src="https://lh5.googleusercontent.com/DhCvqRvrO-7MVBgzcH3sueBGZ6g1Du-af-w-TXQBjcyNNYyllvIr4qBKmV-3DwwZr2CJGNDWsY4LoWmEbeG1PSpUZY_4Wa_XYtpoljiqdGQ7Gy0mEJP_onYlQlg2ZIGyH47EAesWXYDCiPGeV5L1G5o" alt=""><figcaption></figcaption></figure>

**Step 6:** Give the following permissions to the install.sh file

&#x20;                      sudo chmod u+x install.sh

**Step 7:** Install cqube with non root user with sudo privileges

&#x20;                       sudo ./install.sh

<figure><img src="https://lh4.googleusercontent.com/6Ceax5QyiqtNR0guJamDCA_CNpvX587dUQOzgyPKry5dkmVRt3ByNY3O44fPUyesD6Pes0WwtaScw0eYT8-X9jBD3KLtkW82DRAhu8MtKTO8jnhbfBsDjZkv6-qHqOJj6Ut-bS_Fr8W5wL914ogJgLk" alt=""><figcaption></figcaption></figure>

* Access\_type(Enter NVSK or VSK or Others)
* state\_code ( Enter the required state code by referring to the state list provided )
* Do want to enable login screen for cqube instance(Enter true or false)
* Do you want to pull the data from the NVSK server?(Enter true or false)
* Please enter the end point to pull the data (Ex: cqube-demo-nvsk.tibilprojects.com)

**Step 8:** User Input Variables - These are the variables which need to be entered by the user by following the Hint provided

Install.sh file contains a shell script where it will run shell scripts and ansible-playbook to setup the cQube

<figure><img src="https://lh5.googleusercontent.com/Z16--MibQujgoKCEUx1F4DDrcup27nG6AmrQXkKn_chgucEl9g1CEuFnTCtYy09nMvnc0wl9rczZxZ5-eX2azcuDKv4TZPER8YlWOaEuVBidlMdPQOCStq1Xf936xIf0B1sI2i2y0HrrOjZLhqhcgkM" alt=""><figcaption></figcaption></figure>

* Mode of installation: Public
* Storage\_type : aws
* API\_Endpoint(Enter the domain name :  (ex: cqube-demo-cert.tibilprojects.com)
* Please enter the name of cert file: ( ex:certificate.crt)
* Please enter the name of key file:  (ex: private.key)

**Step 9:** Once you enter the above user input it will create one config file.please preview the config file and confirm if everything is correct.if it is correct type “no” and proceed and else type “yes” then correct it.

<figure><img src="https://lh3.googleusercontent.com/Obgxo291qAm0nXG3UZUKvM7mdiVyGhuzZJwydnHcewD3lzv8AiZB3AF7Y-KYPJgRIlefjIMmDJmfmZwAixUwRNX1mSk8VQuhCsZgSjvga8hQfrGrewlXRr9edhMBb5ql_jDrZV15dqSNtwQX2mDVgrY" alt=""><figcaption></figcaption></figure>

* db\_user\_name ( Enter the postgres database username )&#x20;
* db\_name ( Enter the postgres database name )
* db\_password ( Enter the postgres password )
* &#x20;read\_only\_db\_user( Enter the read only db user)
* read\_only\_db\_password( Enter the read only db password)
* keycloak\_adm\_name( Enter the keycloak admin name)
* &#x20;keycloak\_adm\_password( Enter the keycloak password)

**Step 10:** Optional\_variables- Database credentials contain default values. If the user wishes to enter their own credentials then the user should opt for ‘yes’ to enter their credentials otherwise can opt for ‘no’ when the question pops up

<figure><img src="https://lh5.googleusercontent.com/F0AOBp-ue8AvmbIbAfP7957Soc--_5PUwF5Rshc_oeYTj5pgEcV5oseX4TMnqRjK5WSUfQbNzmDqDH3Je_HMS3w3PTOnliPkIYneVVaGAGe-RT4o8K3JArXKvsWW4pZWHSty_jlcNliI0K3uEvfx8xQ" alt=""><figcaption></figcaption></figure>

**Step 11:** Once the config file is generated, A preview of the config file is displayed followed by a question where the user gets an option to re enter the configuration values on choosing yes. If option no is selected then the install.sh moves to the next section.

<figure><img src="https://lh4.googleusercontent.com/Yz1NMCBiU-JR9s8Z3y0A84mcP7HYU32QsK9ZSX_ZHD_zQgGkbzmScWGAWGMFFmrKfPKTn-f43WJ5q3q_5pPqnjQQ3wQPOuify-C_8NAporlQWPeNP9QhINC_lGW8btb_l_f2BbQzhpqfusRjuDf7IGs" alt=""><figcaption></figcaption></figure>

**Step 12:** A preview of the program\_selector.yml file is displayed followed by a question where the user gets an option to enable or disable the programs on choosing ‘yes’. If option ‘no’ is selected then the install.sh moves to the next section.

<figure><img src="https://lh4.googleusercontent.com/L8Wl3Hnptsqa0kYfp4ZqeHxmpQIo29FsQlJbI7P3kXBBLjMamUN2H0iEm3vA6Z538kPC7fqhrKngqc471QWrGZTOfC6jIW1zKKdtifnlOZRAeeAs5N9K-ESI8x7E-wB5b62dCEOjGEBQ7_na6JFTF5M" alt=""><figcaption></figcaption></figure>

**Step 13:** Once the installation is completed, You will be prompted with the following messages and required reference urls.

**cQube Installed Successfully**

cQube ingestion api can be accessible using \<domain\_name>

<figure><img src="https://lh4.googleusercontent.com/oGmKJZ2-5wSwVhQdrhLe5GIShERwX3pK8AKs8G6XjMWnb2-U2ZZbQJcwrS5HCYdAMgaXCkSaSKbpYae0r0YKZdDNxL1ElOoz4YuRzICjEzFAgkyetM7e973WlMhfHQo0Hv_xdW3x68vX9aXUw0PWSZg" alt=""><figcaption></figcaption></figure>

* After installation check the docker containers are up or not
* Sudo docker ps -a

<figure><img src="https://lh7-us.googleusercontent.com/xE38bQFwin4f7fznyjUjUQCUQ550m0fjEnWdRhLTmxwrbtraCfdEGZWS6w63rx7kHuMvQ_wF2vvcO0g0d_HDpPwpvEUZ4u7-iDt-s7pIBGGvSulTIMT7Et5j5sohOrc1pa_JOipYu8i7Wbrv7Mq5SpU" alt=""><figcaption></figcaption></figure>

**Ingestion Flow:**

**Setting up Postman:**

* [Download](https://www.postman.com/downloads/) the postman application and import the collection.
* Select the import option in the postman then select the upload files to import the collection. Please refer to the below screenshot.

<figure><img src="https://lh4.googleusercontent.com/G8g6Ic0gcMJNScE_SdgRwr7APJo7JUEhqWvSlXYdufHhfkQgh1a32IQrESxhgDwGmGmZPoYoLUbH6neyeY9Bj29tASrG43zNx4oNod8TehZdNloDOiq_yrxj0ARuAOUdiNuSqVJdGLnY99OtBmGulIU" alt=""><figcaption></figcaption></figure>

<br>

* Upload the cQube\_latest.postman\_collection .json file and VSK\_Schema.postman\_collection.json,

<https://drive.google.com/drive/u/0/folders/12Wn7UIHgUhq6U3GzlRN-zdrJMnj1hrPO>

* After installations first need to create the jwt token in postman as shown below screenshot.

API\_Endpoint: <https://cqube-ssl-test.tibilprojects.com/api/ingestion/generatejwt>

<figure><img src="https://lh7-us.googleusercontent.com/vJtPWO34t8f2HAmlYyNpe2kg1_Nnsk4a_uyMV-LFoENJav8r9SddvO2o5KCVOOdG-9aoAgtzSYy2XUrTnfOQLF6k1Byv81hdXP7VbtXNRBST6FIGl94voh_zTKGrn2xmZ4R3eqwxWCZV_4VU9PNNC7Y" alt=""><figcaption></figcaption></figure>

* After creating the JWT token then upload the vsk\_schema and dimension schema as shown below screenshot

&#x20;API Endpoint:[ ](https://cqube-ssl-test.tibilprojects.com/api/ingestion/national_programs)[htpps://cqube-ssl-test.tibilprojects.com/api/spec/event](https://cqube-apr27-demo.tibilprojects.com/api/spec/event)

<figure><img src="https://lh7-us.googleusercontent.com/qpNEnirkXm7J3tSf9unLHFynC1Cj6ebmqxkjqG5wgG_EyZiE3DbAkMhncRCfamZNcfllxPRgSuiSxNe6KqmkT8wSqy5tdFNXQ8DmdB5LXmAxfKDAOL5yiuik-YEUsHcskiEokviRHvSfN5-wljOHCWw" alt=""><figcaption></figcaption></figure>

Run the both schema at a time (click on 3 dots and select Run collection)

* After uploading the grammar files,Just copy the generate token and add into national\_programs and new programs
* Go to authorization and select Bearer token, then paste the token&#x20;
* Then I need to upload the VSK data(NCERT) as shown in the below screenshot.

&#x20;           API Endpoint:[ ](<https://cqube-ssl-test.tibilprojects.com/api/ingestion/national_programs&#xD;&#xA;>)[https://cqube-ssl-test.tibilprojects.com/api/ingestion/national\_programs <br>](<https://cqube-ssl-test.tibilprojects.com/api/ingestion/national_programs&#xD;&#xA;>)

<figure><img src="https://lh7-us.googleusercontent.com/yi4ruRGMYzZmwQl3uuHuaR1vDYyoNHTOel2CeYCVAZv0QxD6NJfx-yPQC-FxVFiQ_AO4lPrZBC3CcTzDtsWCjNfISDtyqyebEYhGhveoJlHywqkIOmAdDurYSuVZHH4XZAFFW6WGDLRuhjzb96GrlEE" alt=""><figcaption></figcaption></figure>

* We need to ingest only three programs (pgi,diksha,nishtha)data through API. The other three programs automatically pull the data from the NVSK server.
* For above point we need to upload (PGI, DIKSHA, NISHTHA) three programs schema and ingest the raw files to the aws emission bucket.
* Then we can schedule the below mentioned processor groups one by one by using schedule API as shown in the below screenshot
  * &#x20;Run\_adapters
  * data\_moving\_aws

<br>

<figure><img src="https://lh7-us.googleusercontent.com/zapTPsHQg6EefoQCqQXBlq_60teMoNJUUVxic0Eid-e0ZyDkiwCEybVxuYxkfGzLcHryQUn_ym-j4luaFtClIt2ltyM-WZg3JHbZYxawTH8IZe5wGFQzbRvhuxoKgfpXG_A_y7cPorHtcMTNw7f_qX8" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/mtbqIntvsbWE5Gp4vX2w" alt=""><figcaption></figcaption></figure>

* After the schedule, the programs should one by one by using schedule API as mentioned in the below screenshot.

  Bbody:

  {

  &#x20;   "processor\_group\_name": "ingest\_data",

  &#x20;   "scheduled\_at": "0 31 14 \* \* ?",

  &#x20;   "program\_name": "nishtha"

  }

<figure><img src="https://lh7-us.googleusercontent.com/Ypr5SVcSJ3AuGVFhCvt_gGT98ocMPawzN8BqbG7VUJ2eamsy4lyTNPJscBz8zIv_fJYB7UpfWEUMxgDpbQRbyosTfT1nyluht3bgkhQ1Zdw0gzAz74-hATVpBIChPVLrGRRzORaVPOri8hXxvooyWhA" alt=""><figcaption></figcaption></figure>

<br>

* Check the visualization in the UI dashboard. As shown in the below screenshot.

<figure><img src="https://lh4.googleusercontent.com/U6iWqfNUVi6nrnCRoqO0DjUABoeF-RzkFXW5Ytblqvgc8GFkasQ7JqfyDKtkq1NeU8EJmAZRzDgimrRlAG5MS9x0TJqm1hBpQejedmZAIenPnbUBZEnKyvrRO-WqOoaHs_NvC1w-dw1jXtYZDPpugz8" alt=""><figcaption></figcaption></figure>

\
\
\
\ <br>

\
\ <br>


# SDC Deployment

**Prerequisites to install cQube on local machine**

* Ubuntu 22.04 (supported)&#x20;
* &#x20;16 GB of System RAM (minimum requirement)
* &#x20;4 core CPU (minimum requirement)
* &#x20;Domain name (with SSL), ex: <https://vsk.scertchd.edu.in/>
* &#x20;250 GB Storage

**Step 1:** Use the following command to connect to the On-premise instance

&#x20;            ssh -i \<path\_to\_the\_pem\_file> \<user\_name>@\<public\_ip\_of\_the\_instance>

&#x20;            **Ex: ssh -i poc\_key.pem -o ServerAliveInterval=60 ubuntu\@13.200.12.31**&#x20;

**Step 2:** Clone the cqube-devops repository using following command

&#x20;            git clone <https://github.com/Sunbird-cQube/cqube-devops.git>    &#x20;

<figure><img src="https://lh4.googleusercontent.com/X52JlR-8CHhXM6tS3-6VdVoNvx1kFYrYp1iOH-3BDb1MQet3e52fuaWz73lmq7lTv7VA8S504QtwuRYT2KP9GOli5pBgqg_uybfnB2WXrl0MylbIABtMbA5Rj7m2CInqDrKsESBMFs7k3HMyZj3FZUQ" alt=""><figcaption></figcaption></figure>

**Step 3:** Navigate to the directory where cqube is cloned or downloaded and checkout to the desired branch(Release Branch)

&#x20;             cd cqube-devops/&#x20;

&#x20;            git checkout release-v5.0.5(Latest release branch )

<figure><img src="https://lh6.googleusercontent.com/qrWu_KUQD_INTnbYVwdmkf0wTOp-8JU_Px7HG7mF9L0wXoYSFIV3rLuqUZHOXIXC3szTIeHfWJR78lJ6TJ-7IfeSL3XVprq1iKrXQBoHzSsblc8dyVNheewBHALLrUWNoOcMV9YOh6TMvVpcxjGzdzs" alt=""><figcaption></figcaption></figure>

**Step  4:** After checkout of the latest branch, we need to move the SSL keys (.crt and.key) to the mentioned path, as shown in the below screenshot.

**Command for moving ssl keys:**

&#x20;             cp certificate.crt  private.key /home/ubuntu/cqube-devops/ansible/ssl\_certificates

&#x20;             Path: cqube-devops/ansible/ssl\_certificates

<figure><img src="https://lh7-us.googleusercontent.com/GO-OzWIj5zPLqxHlywifxxtnkSgtmpZN9davkg5eRWRLu-hRPw11o_BU0cDUvpVVH9DaTcd3hLY1Ne5nErMUtlouXq-0M2vkkrChkGexGtO3TJrZujJo_uaIiLu5nR_yS1PT49QnofyAWfwGQdAaM2k" alt=""><figcaption></figcaption></figure>

**Step 5:** After copying the ssl keys similarly, we can move the VSK dimension to (state,district,grade,subject,medium) below the mentioned path, as shown in the screenshot below.

**Command for moving dimensions:**

**(Note: This Step 5  is applicable for pulling the data from NVSK )**

&#x20;                  cp state-dimension.data.csv grade-dimension.data.csv subject-dimension.data.csv etc../home/ubuntu/cqube-devops/ansible.dimension\_files

&#x20;                Path: cqube-devops/ansible/dimension\_files.

<figure><img src="https://lh7-us.googleusercontent.com/b87hfG-Kzb5nfNIYFY_25W17c6P139n8k23IZ6Sq7bWqfLPcjeg_vltTZ6BpZ6oqKS6W9e2fLNWFZ6yr6c5keHFtdv6La1sn_uqraTCj8_qbL0PvFJgM3GloCcS6W4TTQrc6mM0D2m2b6UWqGzVCPNo" alt=""><figcaption></figcaption></figure>

**Step 6:** Give the following permissions to the install.sh file

&#x20;               sudo chmod u+x install.sh

**Step 7:** Install cqube with non root user with sudo privileges

&#x20;              sudo ./install.sh

<figure><img src="https://lh7-us.googleusercontent.com/iQ8cuU7RyZdlyS--G3meu66JvXIHoXfYw0uoH0te1dbXl6QvXc7NRK0VjhHI_opO4gMloybAvGTAq4y_k5fTT7VF9aSzcgc9w5J9lgHE8A3oY1kNlP4Pd4tu3QXDhBCsVTSArihkE5JklMFQuuvd0lA" alt=""><figcaption></figcaption></figure>

Install.sh file contains a shell script where it will run shell scripts and ansible-playbook to setup the cqube

**Step 8:** User Input Variables - These are the variables which need to be entered by the user by following the Hint provided

* Access\_type(Enter NVSK or VSK or Others)
* state\_code ( Enter the required state code by referring to the state list provided )
* Do want to enable login screen for cqube instance(Enter true or false)
* Do you want to pull the data from the NVSK server?(Enter true or false)
* Please enter the end point to pull the data (Ex: cqube-demo-nvsk.tibilprojects.com)

<figure><img src="https://lh7-us.googleusercontent.com/XYWbpWBHCNfPxu7tfp7BdhroPsEOyRNZQ-Skit_18voAAVWXBt3suf5TNaqDOHUT0KIblA4xwLLGynJt4-Z0X8RNPZtSGc4XRelikjxUzN86j4sBPfX7dfQHGlYAZ802lrm8al1HXjXFmZSqOD7wKFM" alt=""><figcaption></figcaption></figure>

**Step 9:** Once you enter the above user input it will create one config file.please preview the config file and confirm if everything is correct.if it is correct type “no” and proceed and else type “yes” then correct it.

* Mode of installation: Public
* Storage\_type : local
* API\_Endpoint(Enter the domain name ex: cqube-demo-cert.tibilprojects.com)
* Please enter the name of cert file( ex:certificate.crt)
* Please enter the name of key file (ex: private.key)

<figure><img src="/files/EA8yl0xOjUHE4Z3nvJ4Q" alt=""><figcaption></figcaption></figure>

**Step 10:** Optional\_variables- Database credentials contain default values. If the user wishes to enter their own credentials then the user should opt for ‘yes’ to enter their credentials otherwise can opt for ‘no’ when the question pops up

* db\_user\_name ( Enter the postgres database username )&#x20;
* db\_name ( Enter the postgres database name )
* db\_password ( Enter the postgres password )
* &#x20;read\_only\_db\_user( Enter the read only db user)
* read\_only\_db\_password( Enter the read only db password)
* keycloak\_adm\_name( Enter the keycloak admin name)
* &#x20;keycloak\_adm\_password( Enter the keycloak password)

<figure><img src="https://lh7-us.googleusercontent.com/mY6HBXHfzd-lkr3cNvdsiuU5lRY1f8u5CdmS-P8l1_LhcOdZWHbFn4mFQZ6x8q6D3o6W_hL82nQjcOvu3MJRwwMWBRRXswHE7RUMwFRnpjt_xWKVEnjsuxbeqvpLS-fO5NeNeQMaNZwG2nhKOuvO8GU" alt=""><figcaption></figcaption></figure>

**Step 11:** Once the config file is generated, A preview of the config file is displayed followed by a question where the user gets an option to re enter the configuration values on choosing yes. If option no is selected then the install.sh moves to the next section.

<figure><img src="https://lh7-us.googleusercontent.com/ZxNFPaMU0SAWxonVDO6cTBYHbHnjxxHT2uMKyWUyB6d7jGXGny46GUfZMu1f_h8F55pmBmKeeN8iZE0fCLn_Ok8TNpSouPvMM9DsMzdworouWhd81d-xk_XFb5qpPtvipgysSOENhKvWkwAPI3x94Qg" alt=""><figcaption></figcaption></figure>

**Step 12:**  A preview of the program\_selector.yml file is displayed followed by a question where the user gets an option to enable or disable the programs on choosing ‘yes’. If option ‘no’ is selected then the install.sh moves to the next section.

<figure><img src="https://lh7-us.googleusercontent.com/tSEjvNGTkIC4gZ3wVLe_qu7KQG3F93M1-PZOI_S6XKjn2LwKAhAkmUxh50AtqpGPpfObMSMNs3GQ980jAEXAozhPMkTEIEJWMmlXjFZ8Xovetv72RA1rPQ1cEbqDEsbxw9YKS7x3L1q3FTHbBHWkTNA" alt=""><figcaption></figcaption></figure>

**Step 13:** Once the installation is completed, You will be prompted with the following messages and required reference urls.

**cQube Installed Successfully**

cQube ingestion api can be accessible using \<domain\_name>

<figure><img src="https://lh7-us.googleusercontent.com/d4R92pktsFD2vGBLKBFzF0MI3NhcG3xv20iKlZ-d3gSIgne77QlHTclJPKfIalSRgYB_qIW1BC5mjdhOInjvKr_X2GlMEG2zUzp-m1r1iwz8nhlJ2knhXKtYtDyUmWsHwZU86DCePg2V0PDd5lrfWUg" alt=""><figcaption></figcaption></figure>

* After installation check the docker containers are up or not
* Sudo docker ps -a

<figure><img src="https://lh7-us.googleusercontent.com/xE38bQFwin4f7fznyjUjUQCUQ550m0fjEnWdRhLTmxwrbtraCfdEGZWS6w63rx7kHuMvQ_wF2vvcO0g0d_HDpPwpvEUZ4u7-iDt-s7pIBGGvSulTIMT7Et5j5sohOrc1pa_JOipYu8i7Wbrv7Mq5SpU" alt=""><figcaption></figcaption></figure>

<br>

**Ingestion Flow:**

Setting up Postman:

* [Download](https://www.postman.com/downloads/) the postman application and import the collection.
* Select the import option in the postman then select the upload files to import the collection. Please refer to the below screenshot.

<figure><img src="https://lh7-us.googleusercontent.com/fEgzfIPm9GTUFu7G-FXvM26084n2WZpZpLqKqIkCiG0OqGkFadHjCHoe5gpI7zMd1fg6uCz2s3MYQuX-v6qTY9M250rCQCxGAtANDJtdfWZWYQXfKK7qKwDmzF9mCny4brszZG464DVG-OgqrheJYEc" alt=""><figcaption></figcaption></figure>

<br>

* Upload the cQube\_latest.postman\_collection .json file and VSK\_Schema.postman\_collection.json,

<https://drive.google.com/drive/u/0/folders/12Wn7UIHgUhq6U3GzlRN-zdrJMnj1hrPO>

* After installations first need to create the jwt token in postman as shown below screenshot.

API\_Endpoint: [https://cqube-ssl-test.tibilprojects.com/api/ingestion/generatejwt](http://vsk.ap.gov.in/api/ingestion/generatejwt)

<figure><img src="https://lh7-us.googleusercontent.com/vJtPWO34t8f2HAmlYyNpe2kg1_Nnsk4a_uyMV-LFoENJav8r9SddvO2o5KCVOOdG-9aoAgtzSYy2XUrTnfOQLF6k1Byv81hdXP7VbtXNRBST6FIGl94voh_zTKGrn2xmZ4R3eqwxWCZV_4VU9PNNC7Y" alt=""><figcaption></figcaption></figure>

* After creating the JWT token then upload the vsk\_chema and dimension schema as shown below screenshot

&#x20;API Endpoint: [htpps://cqube-ssl-test.tibilprojects.com/api/spec/event](https://cqube-apr27-demo.tibilprojects.com/api/spec/event)

<br>

<figure><img src="https://lh7-us.googleusercontent.com/qpNEnirkXm7J3tSf9unLHFynC1Cj6ebmqxkjqG5wgG_EyZiE3DbAkMhncRCfamZNcfllxPRgSuiSxNe6KqmkT8wSqy5tdFNXQ8DmdB5LXmAxfKDAOL5yiuik-YEUsHcskiEokviRHvSfN5-wljOHCWw" alt=""><figcaption></figcaption></figure>

Run the both schema at a time (click on 3 dots and select Run collection)

* After uploading the grammar files,Just copy the generate token and add into national\_programs and new programs api
* Go to authorization and select Bearer token, then paste the token&#x20;
* Then I need to upload the VSK data(NCERT) as shown in the below screenshot.ii

&#x20;           API Endpoint: [https://cqube-ssl-test.tibilprojects.com/api/ingestion/national\_programs](https://ap.vsk.gov.in/api/ingestion/national_programs)

<figure><img src="https://lh7-us.googleusercontent.com/yi4ruRGMYzZmwQl3uuHuaR1vDYyoNHTOel2CeYCVAZv0QxD6NJfx-yPQC-FxVFiQ_AO4lPrZBC3CcTzDtsWCjNfISDtyqyebEYhGhveoJlHywqkIOmAdDurYSuVZHH4XZAFFW6WGDLRuhjzb96GrlEE" alt=""><figcaption></figcaption></figure>

* We need to ingest only three programs (pgi,diksha,nishtha)data through API. The other three programs automatically pull the data from the NVSK server.
* For above point we need to upload (PGI, DIKSHA, NISHTHA) three programs schema and ingest the raw files to the aws emission bucket.
* Then we can schedule the below mentioned processor groups one by one by using schedule API as shown in the below screenshot
  * &#x20;Run\_adapters
  * data\_moving\_local

<figure><img src="https://lh7-us.googleusercontent.com/zapTPsHQg6EefoQCqQXBlq_60teMoNJUUVxic0Eid-e0ZyDkiwCEybVxuYxkfGzLcHryQUn_ym-j4luaFtClIt2ltyM-WZg3JHbZYxawTH8IZe5wGFQzbRvhuxoKgfpXG_A_y7cPorHtcMTNw7f_qX8" alt=""><figcaption></figcaption></figure>

<br>

<figure><img src="https://lh7-us.googleusercontent.com/yt1gP3Hth9oGdUXh5axcg4O7eADAa8QawRoOSkqWrZOL_ABqZrdD4rPUlVjYOae8CfJfHear74qVIglwBIDkgUYTRMDyvM3UOnf79p5DfTFlTubYzlloCtKsVSbwkWVK4ORGv2cDFDawUgm6n7lggQQ" alt=""><figcaption></figcaption></figure>

* After that you can schedule the one by one program by using schedule API as mentioned in the below screenshot.

&#x20;      Body:

&#x20;             {

&#x20;                "processor\_group\_name": "ingest\_data",

&#x20;                 "scheduled\_at": "0 31 14 \* \* ?",

&#x20;                 "program\_name": "nishtha"

&#x20;              }

<br>

<figure><img src="https://lh7-us.googleusercontent.com/Ypr5SVcSJ3AuGVFhCvt_gGT98ocMPawzN8BqbG7VUJ2eamsy4lyTNPJscBz8zIv_fJYB7UpfWEUMxgDpbQRbyosTfT1nyluht3bgkhQ1Zdw0gzAz74-hATVpBIChPVLrGRRzORaVPOri8hXxvooyWhA" alt=""><figcaption></figcaption></figure>

* Check the visualization in the UI dashboard. As shown in the below screenshot.

<figure><img src="https://lh7-us.googleusercontent.com/HeOpzhfh3wX3H-ptYtWDKTD3HzY3DIRmZMCxJLts9eSFCBdYsOeaeqYcnLwd3OgGodMXxb4xJA-r-FsqpDdP3bOtf2IJpnNqoy40zOthR8j5FJPNkRZ4V122_8HO7tJnu6kOKogETyhB7NHrA57cbMs" alt=""><figcaption></figcaption></figure>

<br>


# Adapter Details During the Processing

we can schedule processor groups one by one by using schedule API for the different storage types.

* data\_moving\_local
* data\_moving\_aws
* data\_moving\_azure
* data\_moving\_oracle


# How can I upgrade cQube to the latest release

**AWS**

Connect to the cQube AWS EC2 Instance

For Linux and macOS:

1. Download the .pem file generated during EC2 instance creation.
2. Open the terminal and navigate to the folder where the .pem file is downloaded.
3. Provide read permission to the .pem file: sudo chmod 400 \<aws.pem>

Connect to the instance using the following command:

4. ssh -i \<path\_to\_the\_pem\_file> \<user\_name>@\<public\_ip\_of\_the\_instance>

For Windows:

1. Download the .pem file generated during EC2 instance creation.

Use Puttygen to connect to the instance. Refer to this link for instructions:[ PuttyGen Instructions](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html)


# Deployment & ingestion related issues & their solutions

## Deployment  Issues

* **Process lock issue**

When starting the deployment we might face an issue which states “Waiting for cache&#x20;

Lock: Could not get lock /var/lib/dpkg/lock-frontend”

**Resolution:**

Check for the process which is using sudo and stop the process using process id or wait till the sudo gets de-locked and restart the deployment process

* **Redeployment of dashboard-ms**

sudo docker stop dashboard\_app

sudo docker rm dashboard\_app

sudo docker dashboard\_ms:1

cd cqube-devops/microservices/dashboard-ms

sudo git pull sudo docker build -t dashboard\_ms:1 .

sudo docker run -d -p 4200:80 --network cqube\_net --name         &#x20;

dashboard\_app dashboard\_ms:1

* **Redeployment of Querybuilder-ms**

sudo docker stop querybuilder\_app

sudo docker rm querybuilder\_app

sudo docker querybuilder\_ms:1

cqube-devops/microservices/querybuilder-ms

sudo git pull

sudo docker build -t querybuilder\_ms:1

sudo docker run -d -p 3002:3002 --network cqube\_net --name querybuilder\_app

querybuilder\_ms:1

* **Port in use error while running docker-compose**

If this error arises, please check for the port which is affecting the deployment and kill the\
the port using the port ID.                        &#x20;

sudo netstat -ntlp | grep \<PORT>

sudo kill -15 \<PID>\
&#x20;                        &#x20;

Once the port is killed follow the installation script. &#x20;

## Related to ingestion

* **Single Master of Districts, Blocks, Clusters, and Schools**:

To enable decentralized observability, a single master file should be created for each jurisdiction (district, block, cluster, and school) with a unique ID and name.

Both state and national programs on cQube will reference these masters.

Any discrepancy in the master data will result in unsuccessful data ingestion.

* **Individual Values for Grade, Subject, and Medium:**

Grade, subject, and medium data should have individual values in separate rows, instead of being stored as arrays.

Each subject should have a unique ID, and different subjects should be in different rows.

* **Change in Column Name for NISHTHA Program:**

In the diksha\_nishtha\_percentage-enrollment-certification.zip file for the NISHTHA program, the first "State" column (Column B) should be renamed to "State Name\_Correct" to avoid duplication.

* **No Quotes in the Data:**

Quotes, whether single (') or double (“), should not be present in the data being ingested.

* **Numerical Values instead of Strings:**

Certain files (udise\_program-started.zip, nas\_program-started.zip, diksha\_nishtha\_program-started.zip) should use numerical values (1 and 0) instead of strings (Yes and No) in relevant columns.

* **No Commas in Large Numerical Values:**

Large numerical values in CSVs should not have commas (,) in between the digits.

These guidelines ensure data consistency, proper formatting, and accurate ingestion in the cQube system.

<br>


# Reporting a Bug

Describes the process of reporting a bug to the cQube Product Team

There is a bug if something for the user isn’t working as intended. The cQube Product Team will be responsible to fix the bug that has been reported in the DPG.

### Communication Tool

All the bugs and need for support should be posted as issues on the cQube Community on GitHub - [Link](https://github.com/Sunbird-cQube/community/issues).

### Reporting a Bug

A new issue should be created in the GitHub Community of cQube **only** if any similar issue doesn't already exist or has been resolved by the cQube Product Team. The reported issues for cQube can be seen [here](https://github.com/Sunbird-cQube/community/issues?q=is%3Aopen+is%3Aissue) and the resolved issues can be seen [here](https://github.com/Sunbird-cQube/community/issues?q=is%3Aissue+is%3Aclosed).

**Process to report a bug:**

1. Go to the issues tab of cQube Community on Github - <https://github.com/Sunbird-cQube/community/issues>

<figure><img src="/files/IqMj8AM9SPOQAGuOoc6l" alt=""><figcaption></figcaption></figure>

2. Click on 'New Issue'. Then select 'Get Started' in front of 'Bug report'.

<figure><img src="/files/JGdN8HrCyl62fO0DcQX4" alt=""><figcaption></figcaption></figure>

3. Detail out the bug that you are facing with a title, description, steps to reproduce, expected behaviour, relevant screenshots and desktop / mobile configurations.

<figure><img src="/files/rvsuY8rkaiytjcNe3ZzS" alt=""><figcaption></figcaption></figure>

4. Attach relevant label(s) to the bug being reported.

<figure><img src="/files/1d7QYN8iG89IOOf7YBp8" alt=""><figcaption></figcaption></figure>

5. Click on 'Submit new issue'.

### Response from the cQube Product Team

The cQube Product Team will respond within 2-3 working days post the issue has been submitted with a timeline by when the bug can be fixed. It will be included in the cQube roadmap. The adopter who has raised the issue will be able to track the bug on a JIRA ticket.

Ideally, P0 bugs will be prioritised and taken up in the ongoing sprint and P1 bugs will be taken up in the next sprint based on when the issue is reported.&#x20;




---

[Next Page](/llms-full.txt/1)

