Document Release Version
Project Release Version Date
Important note to the adopters
This release includes upgrades to inQuiry building block to function with the QuML 1.1 format. The changes are detailed out in the link here . The V2 version of the components as it is known from release 6.0.0 will start working with QuML 1.1 format and hence the questions that previously exist in the system has to be migrated from QuML 1.0 to QuML 1.1 format. A one time migration activity needs to be done on the existing question / questionsets.
Following are the Planned Tickets of R 6.0.0
Sl.no JIRA Id Issue Type Description Integrate V2 player and Editor in the inQuiry Portal
User is able to see all the fields editable in review mode
Remove hard coding in the QuML Player
Integrate latest common form library in editor
Remove hard coding of content organisation and target frameworks to point to a specific framework
Editor/Player: Update the Node version from 14 to 16
Mark it video, PDF, and EPUB player as optional in the resource library
Integration of Editor and Player web component into inQuiry portal
Integration of QuML player web component into the sunbird resource library
Integration of QuML player web component into the editor
inQuiry V2 API Implementation
Zoom icon and show answer button are overlapping for the subjective question with image
User is not able to send for review when reset the set max and warning timer for question set
Player changes to ensure QuML compliance
Editor changes to ensure QuML compliance
Inquiry - QuML Design Changes to ensure QuML complaince
Footer is not aligned Properly when console is open.
Release Tags:
Question Set Editor :
Tag: v6.0.0
Install: npm i @project-sunbird/sunbird-questionset-editor@6.0.0
URL: https://www.npmjs.com/package/@project-sunbird/sunbird-questionset-editor/v/6.0.0
Question Set Editor Web Component :
Tag: v2.0.0
Install: npm i @project-sunbird/sunbird-questionset-editor-web-component@2.0.0
URL:https://www.npmjs.com/package/@project-sunbird/sunbird-questionset-editor-web-component/v/2.0.0
Form field Config Change as per QuML spec 1.1
Form Field Sample Config as per QuML 1.1 Comments { "code": "showTimer", "name": "show Timer", "label": "show Timer", "placeholder": "show Timer", "description": "show Timer", "default": false, "dataType": "boolean", "inputType": "checkbox", "editable": true, "required": false, "visible": true, "renderingHints": { "class": "sb-g-col-lg-1" } }
Data type of showTimer
is changes from string to boolean so form Config change is required for this field.
{ "code": "showFeedback", "name": "Show Feedback", "label": "Show Question Feedback", "placeholder": "Select Option", "description": "If feedback is selected, users are informed whether they have correctly answered question or not", "dataType": "boolean", "inputType": "checkbox", "editable": true, "required": false, "visible": true, "renderingHints": { "class": "sb-g-col-lg-1" } }
Data type of showFeedback
is changes from string to boolean, so form Config change is required for this field.
{ "code": "showSolutions", "name": "Show Solution", "label": "Show Solution", "placeholder": "Select Option", "description": "If show solution is selected then solutions for each question will be shown to the user", "dataType": "boolean", "inputType": "checkbox", "editable": true, "required": false, "visible": true, "renderingHints": { "class": "sb-g-col-lg-1" } }
Data type of showSolutions
is changed from string to boolean, so form Config change is required for this field.
No Config for warning time.
This field is not needed in QuML 1.1 .Warning time will be handled by playerConfig.
{ "code": "complexityLevel", "dataType": "list", "description": "Learning level", "editable": true, "inputType": "nestedselect", "label": "Learning level", "name": "Learning level", "placeholder": "Select Learning level", "renderingHints": { "class": "sb-g-col-lg-1" }, "required": false, "visible": true, "range": [ "remember", "understand", "apply", "analyse", "evaluate", "create" ], "validations": [] }
bloomsLevel
property is changed to complexityLevel
and it's datatype is also changed from string to array so the config change is required for this field
QuML Player:
Tag: v6.0.0
Install: npm i @project-sunbird/sunbird-quml-player@6.0.0
URL: https://www.npmjs.com/package/@project-sunbird/sunbird-quml-player/v/6.0.0
QuML Player Web Component:
Tag: v2.0.0
Install: npm i @project-sunbird/sunbird-quml-player-web-component@2.0.0
URL: https://www.npmjs.com/package/@project-sunbird/sunbird-quml-player-web-component/v/2.0.0
Resource Library:
Tag: v6.0.0
Install: npm i @project-sunbird/sunbird-resource-library@6.0.0
URL: https://www.npmjs.com/package/@project-sunbird/sunbird-resource-library/v/6.0.0
Question & Question Set Service:
Component Service To Build Build Tag Core Release Tag Service To Deploy Deploy Tag Comment Build/job/Core/job/Assessment/
Deploy/job/dev/job/Kubernetes/job/Assessment/
Deploy/job/dev/job/Kubernetes/job/InquiryUploadSchema/
Build/job/KnowledgePlatform/job/InquiryFlinkJob
Deploy/job/dev/job/KnowledgePlatform/job/InquiryFlinkJob/
Configuration Changes For Assessment Service:
File Name: ansible/roles/stack-sunbird/templates/assessment-service_application.conf
Copy actor {
deployment {
/healthActor
{
router = smallest-mailbox-pool
nr-of-instances = 5
dispatcher = actors-dispatcher
}
/itemSetActor
{
router = smallest-mailbox-pool
nr-of-instances = 2
dispatcher = actors-dispatcher
}
/questionActor
{
router = smallest-mailbox-pool
nr-of-instances = 5
dispatcher = actors-dispatcher
}
/questionSetActor
{
router = smallest-mailbox-pool
nr-of-instances = 5
dispatcher = actors-dispatcher
}
/questionV5Actor
{
router = smallest-mailbox-pool
nr-of-instances = 5
dispatcher = actors-dispatcher
}
/questionSetV5Actor
{
router = smallest-mailbox-pool
nr-of-instances = 5
dispatcher = actors-dispatcher
}
}
}
assessment.copy.props_to_remove=["downloadUrl", "artifactUrl", "variants",
"createdOn", "collections", "children", "lastUpdatedOn", "SYS_INTERNAL_LAST_UPDATED_ON",
"versionKey", "s3Key", "status", "pkgVersion", "toc_url", "mimeTypesCount",
"contentTypesCount", "leafNodesCount", "childNodes", "prevState", "lastPublishedOn",
"flagReasons", "compatibilityLevel", "size", "publishChecklist", "publishComment",
"LastPublishedBy", "rejectReasons", "rejectComment", "gradeLevel", "subject",
"medium", "board", "topic", "purpose", "subtopic", "contentCredits",
"owner", "collaborators", "creators", "contributors", "badgeAssertions", "dialcodes",
"concepts", "keywords", "reservedDialcodes", "dialcodeRequired", "leafNodes", "sYS_INTERNAL_LAST_UPDATED_ON", "prevStatus", "lastPublishedBy", "streamingUrl", "publish_type", "migrationVersion"]
# V5 API Configurations
v5_supported_qumlVersions=[1.1]
v5_default_qumlVersion=1.1
V2 API Onboarding Script:
File Name: ansible/roles/kong-api/defaults/main.yml
Copy - name: questionCreateV2
uris: "{{ question_prefix }}/v2/create"
upstream_url: "{{ assessment_service_url }}/question/v5/create"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentCreate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionReadV2
uris: "{{ question_prefix }}/v2/read"
upstream_url: "{{ assessment_service_url }}/question/v5/read"
strip_uri: true
plugins:
- name: cors
- "{{ statsd_pulgin }}"
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: ip
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionPrivateReadV2
uris: "{{ question_prefix }}/v2/private/read"
upstream_url: "{{ assessment_service_url }}/question/v5/private/read"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentAccess
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionUpdateV2
uris: "{{ question_prefix }}/v2/update"
upstream_url: "{{ assessment_service_url }}/question/v5/update"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentUpdate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionRetireV2
uris: "{{ question_prefix }}/v2/retire"
upstream_url: "{{ assessment_service_url }}/question/v5/retire"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentAdmin
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionReviewV2
uris: "{{ question_prefix }}/v2/review"
upstream_url: "{{ assessment_service_url }}/question/v5/review"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentAdmin
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionPublishV2
uris: "{{ question_prefix }}/v2/publish"
upstream_url: "{{ assessment_service_url }}/question/v5/publish"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentCreate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionListV2
uris: "{{ question_prefix }}/v2/list"
upstream_url: "{{ assessment_service_url }}/question/v5/list"
strip_uri: true
plugins:
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: ip
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionRejectV2
uris: "{{ question_prefix }}/v2/reject"
upstream_url: "{{ assessment_service_url }}/question/v5/reject"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentAdmin
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: copyQuestionV2
uris: "{{ question_prefix }}/v2/copy"
upstream_url: "{{ assessment_service_url }}/question/v5/copy"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentCreate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetCreateV2
uris: "{{ questionset_prefix }}/v2/create"
upstream_url: "{{ assessment_service_url }}/questionset/v5/create"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentCreate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetReadV2
uris: "{{ questionset_prefix }}/v2/read"
upstream_url: "{{ assessment_service_url }}/questionset/v5/read"
strip_uri: true
plugins:
- name: cors
- "{{ statsd_pulgin }}"
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: ip
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetPrivateReadV2
uris: "{{ questionset_prefix }}/v2/private/read"
upstream_url: "{{ assessment_service_url }}/questionset/v5/private/read"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentAccess
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetUpdateV2
uris: "{{ questionset_prefix }}/v2/update"
upstream_url: "{{ assessment_service_url }}/questionset/v5/update"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentUpdate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetAddQuestionV2
uris: "{{ questionset_prefix }}/v2/add"
upstream_url: "{{ assessment_service_url }}/questionset/v5/add"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- 'contentUpdate'
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetRemoveQuestionV2
uris: "{{ questionset_prefix }}/v2/remove"
upstream_url: "{{ assessment_service_url }}/questionset/v5/remove"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- 'contentUpdate'
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetRetireV2
uris: "{{ questionset_prefix }}/v2/retire"
upstream_url: "{{ assessment_service_url }}/questionset/v5/retire"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentAdmin
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetReviewV2
uris: "{{ questionset_prefix }}/v2/review"
upstream_url: "{{ assessment_service_url }}/questionset/v5/review"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentAdmin
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetPublishV2
uris: "{{ questionset_prefix }}/v2/publish"
upstream_url: "{{ assessment_service_url }}/questionset/v5/publish"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentAdmin
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetUpdateHierarchyV2
uris: "{{ questionset_prefix }}/v2/hierarchy/update"
upstream_url: "{{ assessment_service_url }}/questionset/v5/hierarchy/update"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentUpdate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetReadHierarchyV2
uris: "{{ questionset_prefix }}/v2/hierarchy"
upstream_url: "{{ assessment_service_url }}/questionset/v5/hierarchy"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- anonymousContentAccess
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionSetRejectV2
uris: "{{ questionset_prefix }}/v2/reject"
upstream_url: "{{ assessment_service_url }}/questionset/v5/reject"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentAdmin
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionImportAPIV2
uris: "{{ question_prefix }}/v2/import"
upstream_url: "{{ assessment_service_url }}/question/v5/import"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentCreate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: questionsetImportAPIV2
uris: "{{ questionset_prefix }}/v2/import"
upstream_url: "{{ assessment_service_url }}/questionset/v5/import"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentCreate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
- name: copyQuestionSetV2
uris: "{{ questionset_prefix }}/v2/copy"
upstream_url: "{{ assessment_service_url }}/questionset/v5/copy"
strip_uri: true
plugins:
- name: jwt
- name: cors
- "{{ statsd_pulgin }}"
- name: acl
config.whitelist:
- contentCreate
- name: rate-limiting
config.policy: local
config.hour: "{{ medium_rate_limit_per_hour }}"
config.limit_by: credential
- name: request-size-limiting
config.allowed_payload_size: "{{ medium_request_size_limit }}"
- name: opa-checks
config.required: false
config.enabled: false
DB Model Changes For V2 API:
Copy ALTER TABLE {{ question_keyspace_name }}.question_data ADD (outcomeDeclaration text, feedback text);
Jenkins Job Changes:
A New Jenkins Job Created For Kafka Topic Management. The job can be imported using https://github.com/Sunbird-inQuiry/data-pipeline/blob/release-6.0.0_RC2/scripts/jenkins-jobs/Deploy/KnowledgePlatform/InquiryKafkaSetup/config.xml
For Build, Upload, and Deploy operation of data-pipeline jobs, jenkins jobs are available for import here
Note:
1. For V2 API's, compatibilityLevel increased by 1. So for Question object, value is 5 and for Questionset object, value is 6. If any application consume data based on compatibilityLevel, it should make the the changes accordingly.
Last updated 8 months ago