Skip to content

Commit 7ea4c2c

Browse files
Merge pull request #216 from chethann007/release-8.0.0
fix: enhance assessment validation and add API fallback for content metadata retrieval
2 parents a377ffa + 9b38967 commit 7ea4c2c

File tree

1 file changed

+53
-9
lines changed
  • lms-jobs/credential-generator/collection-cert-pre-processor/src/main/scala/org/sunbird/job/collectioncert/functions

1 file changed

+53
-9
lines changed

lms-jobs/credential-generator/collection-cert-pre-processor/src/main/scala/org/sunbird/job/collectioncert/functions/IssueCertificateHelper.scala

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ trait IssueCertificateHelper {
2929
logger.info("IssueCertificateHelper:: issueCertificate:: enrolledUser:: "+enrolledUser)
3030

3131
//validateAssessmentCriteria
32-
val assessedUser = validateAssessmentCriteria(event, criteria.getOrElse(config.assessment, Map[String, AnyRef]()).asInstanceOf[Map[String, AnyRef]], enrolledUser.userId, additionalProps)(metrics, cassandraUtil, contentCache, config)
32+
val assessedUser = validateAssessmentCriteria(event, criteria.getOrElse(config.assessment, Map[String, AnyRef]()).asInstanceOf[Map[String, AnyRef]], enrolledUser.userId, additionalProps)(metrics, cassandraUtil, contentCache, config, httpUtil)
3333
logger.info("IssueCertificateHelper:: issueCertificate:: assessedUser:: "+assessedUser)
3434

3535
//validateUserCriteria
@@ -84,10 +84,10 @@ trait IssueCertificateHelper {
8484
} else EnrolledUser(event.userId, "")
8585
}
8686

87-
def validateAssessmentCriteria(event: Event, assessmentCriteria: Map[String, AnyRef], enrolledUser: String, additionalProps: Map[String, List[String]])(metrics:Metrics, cassandraUtil: CassandraUtil, contentCache: DataCache, config:CollectionCertPreProcessorConfig):AssessedUser = {
87+
def validateAssessmentCriteria(event: Event, assessmentCriteria: Map[String, AnyRef], enrolledUser: String, additionalProps: Map[String, List[String]])(metrics:Metrics, cassandraUtil: CassandraUtil, contentCache: DataCache, config:CollectionCertPreProcessorConfig, httpUtil: HttpUtil):AssessedUser = {
8888
logger.info("IssueCertificateHelper:: validateAssessmentCriteria:: assessmentCriteria:: " + assessmentCriteria + " || enrolledUser:: " + enrolledUser)
8989
if(assessmentCriteria.nonEmpty && enrolledUser.nonEmpty) {
90-
val filteredUserAssessments = getMaxScore(event)(metrics, cassandraUtil, config, contentCache)
90+
val filteredUserAssessments = getMaxScore(event)(metrics, cassandraUtil, config, contentCache, httpUtil)
9191
val scoreMap = filteredUserAssessments.map(sc => sc._1 -> (sc._2.head.score * 100 / sc._2.head.totalScore))
9292
val score:Double = if (scoreMap.nonEmpty) scoreMap.values.max else 0d
9393

@@ -119,7 +119,38 @@ trait IssueCertificateHelper {
119119
} else Map[String, AnyRef]()
120120
}
121121

122-
def getMaxScore(event: Event)(metrics:Metrics, cassandraUtil: CassandraUtil, config:CollectionCertPreProcessorConfig, contentCache: DataCache):Map[String, Set[AssessmentUserAttempt]] = {
122+
def getContentMetadataFromAPI(contentId: String)(config: CollectionCertPreProcessorConfig, httpUtil: HttpUtil): Map[String, AnyRef] = {
123+
try {
124+
val contentReadUrl = config.contentBasePath + config.contentReadApi + "/" + contentId
125+
logger.info(s"IssueCertificateHelper:: getContentMetadataFromAPI:: Fetching content metadata for contentId: $contentId from API: $contentReadUrl")
126+
127+
val httpResponse = httpUtil.get(contentReadUrl, config.defaultHeaders)
128+
129+
if (httpResponse.isSuccess) {
130+
val contentReadResp = ScalaJsonUtil.deserialize[Map[String, AnyRef]](httpResponse.body)
131+
val responseCode = contentReadResp.getOrElse("responseCode", "").asInstanceOf[String]
132+
133+
if (responseCode.equalsIgnoreCase("OK")) {
134+
val result = contentReadResp.getOrElse("result", Map[String, AnyRef]()).asInstanceOf[Map[String, AnyRef]]
135+
val content = result.getOrElse("content", Map[String, AnyRef]()).asInstanceOf[Map[String, AnyRef]]
136+
logger.info(s"IssueCertificateHelper:: getContentMetadataFromAPI:: Successfully fetched metadata for contentId: $contentId, contentType: ${content.getOrElse("contentType", "")}")
137+
content
138+
} else {
139+
logger.error(s"IssueCertificateHelper:: getContentMetadataFromAPI:: Failed to fetch content metadata for contentId: $contentId, responseCode: $responseCode")
140+
Map[String, AnyRef]()
141+
}
142+
} else {
143+
logger.error(s"IssueCertificateHelper:: getContentMetadataFromAPI:: HTTP request failed for contentId: $contentId, status: ${httpResponse.status}")
144+
Map[String, AnyRef]()
145+
}
146+
} catch {
147+
case e: Exception =>
148+
logger.error(s"IssueCertificateHelper:: getContentMetadataFromAPI:: Exception while fetching content metadata for contentId: $contentId, error: ${e.getMessage}", e)
149+
Map[String, AnyRef]()
150+
}
151+
}
152+
153+
def getMaxScore(event: Event)(metrics:Metrics, cassandraUtil: CassandraUtil, config:CollectionCertPreProcessorConfig, contentCache: DataCache, httpUtil: HttpUtil):Map[String, Set[AssessmentUserAttempt]] = {
123154
val contextId = "cb:" + event.batchId
124155
val query = QueryBuilder.select().column("aggregates").column("agg").from(config.keyspace, config.userActivityAggTable)
125156
.where(QueryBuilder.eq("activity_type", "Course")).and(QueryBuilder.eq("activity_id", event.courseId))
@@ -143,12 +174,25 @@ trait IssueCertificateHelper {
143174
val filteredUserAssessments = userAssessments.filterKeys(key => {
144175
val metadata = contentCache.getWithRetry(key)
145176
if (metadata.nonEmpty) {
146-
val contentType = metadata.getOrElse("contenttype", "")
177+
// Check both lowercase and camelCase variants for contentType
178+
val contentType = metadata.getOrElse("contentType", metadata.getOrElse("contenttype", "")).toString
147179
config.assessmentContentTypes.contains(contentType)
148-
} else if(metadata.isEmpty && config.enableSuppressException){
149-
logger.error("Suppressed exception: Metadata cache not available for: " + key)
150-
false
151-
} else throw new Exception("Metadata cache not available for: " + key)
180+
} else {
181+
// Fallback: Try to fetch metadata from API
182+
logger.info(s"IssueCertificateHelper:: getMaxScore:: Metadata not available in cache for: $key, attempting API fallback")
183+
val apiMetadata = getContentMetadataFromAPI(key)(config, httpUtil)
184+
185+
if (apiMetadata.nonEmpty) {
186+
val contentType = apiMetadata.getOrElse("contentType", apiMetadata.getOrElse("contenttype", "")).toString
187+
logger.info(s"IssueCertificateHelper:: getMaxScore:: Successfully fetched metadata from API for: $key, contentType: $contentType")
188+
config.assessmentContentTypes.contains(contentType)
189+
} else if (config.enableSuppressException) {
190+
logger.error(s"IssueCertificateHelper:: getMaxScore:: Suppressed exception: Metadata not available in cache or API for: $key")
191+
false
192+
} else {
193+
throw new Exception("Metadata not available in cache or API " + key)
194+
}
195+
}
152196
})
153197
// TODO: Here we have an assumption that, we will consider max percentage from all the available attempts of different assessment contents.
154198
if (filteredUserAssessments.nonEmpty) filteredUserAssessments else Map()

0 commit comments

Comments
 (0)