From 552380b414b05ee467361aade1efada437e5b7aa Mon Sep 17 00:00:00 2001 From: Karthikeyan Rajendran <70887864+karthik-tarento@users.noreply.github.com> Date: Mon, 9 Dec 2024 11:13:24 +0530 Subject: [PATCH] 4.8.19 event cert re issue (#51) * 4.8.20 dev v1 (#48) * 4.8.18 dev hot fix (#41) * Added Local Cache for Storing Enrollment List Batches * Add log to confirm batch retrieval from cache * removed unused class (#42) --------- Co-authored-by: saipradeep_ravipati Co-authored-by: shankaragoudab <140387294+shankaragoudab@users.noreply.github.com> * added code for reissue certificates for events * changed kafka topic --------- Co-authored-by: Karthikeyan Rajendran <70887864+karthik-tarento@users.noreply.github.com> Co-authored-by: saipradeep_ravipati Co-authored-by: shankaragoudab <140387294+shankaragoudab@users.noreply.github.com> Co-authored-by: karthik-tarento Co-authored-by: anilkumar * added action type for event (#49) Co-authored-by: anilkumar * update kafka msg for event (#50) Co-authored-by: anilkumar --------- Co-authored-by: anilkumarkammalapalli <121931293+anilkumarkammalapalli@users.noreply.github.com> Co-authored-by: saipradeep_ravipati Co-authored-by: shankaragoudab <140387294+shankaragoudab@users.noreply.github.com> Co-authored-by: anilkumar --- .../operations/CourseActorOperations.java | 3 +- .../certificate/service/CertificateActor.java | 101 +++++++++++++++++- .../learner/util/BatchCacheHandler.java | 58 ++++++++++ .../org/sunbird/learner/util/ContentUtil.java | 48 ++++++++- .../sunbird/learner/util/CourseBatchUtil.java | 17 +++ .../learner/util/SchedulerManager.java | 2 + .../enrolments/BaseEnrolmentActor.scala | 3 + .../enrolments/CourseEnrolmentActor.scala | 24 ++++- .../sunbird/common/models/util/JsonKey.java | 4 + .../resources/externalresource.properties | 4 +- .../certificate/CertificateController.java | 17 +++ .../CertificateRequestValidator.java | 11 ++ service/app/util/RequestInterceptor.java | 1 + service/conf/routes | 1 + 14 files changed, 282 insertions(+), 12 deletions(-) create mode 100644 course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/BatchCacheHandler.java diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actor/operations/CourseActorOperations.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actor/operations/CourseActorOperations.java index 7d592f5a1..00f0bf017 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actor/operations/CourseActorOperations.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actor/operations/CourseActorOperations.java @@ -3,7 +3,8 @@ public enum CourseActorOperations { ISSUE_CERTIFICATE("issueCertificate"), ADD_BATCH_CERTIFICATE("addCertificateToCourseBatch"), - DELETE_BATCH_CERTIFICATE("removeCertificateFromCourseBatch"); + DELETE_BATCH_CERTIFICATE("removeCertificateFromCourseBatch"), + ISSUE_EVENT_CERTIFICATE("issueEventCertificate"); private String value; diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/certificate/service/CertificateActor.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/certificate/service/CertificateActor.java index d109cb229..21e180313 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/certificate/service/CertificateActor.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/certificate/service/CertificateActor.java @@ -1,10 +1,9 @@ package org.sunbird.learner.actors.certificate.service; import java.text.MessageFormat; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; + import org.apache.commons.collections.CollectionUtils; import org.sunbird.actor.base.BaseActor; import org.sunbird.common.exception.ProjectCommonException; @@ -17,6 +16,7 @@ import org.sunbird.common.request.Request; import org.sunbird.common.responsecode.ResponseCode; import org.sunbird.kafka.client.InstructionEventGenerator; +import org.sunbird.kafka.client.KafkaClient; import org.sunbird.learner.constants.CourseJsonKey; import org.sunbird.learner.constants.InstructionEvent; import org.sunbird.learner.util.CourseBatchUtil; @@ -48,6 +48,9 @@ public void onReceive(Request request) throws Throwable { case "issueCertificate": issueCertificate(request); break; + case "issueEventCertificate": + issueEventCertificate(request); + break; default: onReceiveUnsupportedOperation(request.getOperation()); break; @@ -148,4 +151,94 @@ private void pushInstructionEvent( String topic = ProjectUtil.getConfigValue("kafka_topics_certificate_instruction"); InstructionEventGenerator.pushInstructionEvent(batchId, topic, data); } + + private void issueEventCertificate(Request request) { + logger.info(request.getRequestContext(), "issueEventCertificate request=" + request.getRequest()); + final String batchId = (String) request.getRequest().get(JsonKey.BATCH_ID); + final String eventId = (String) request.getRequest().get(JsonKey.EVENT_ID); + List userIds = (List) request.getRequest().get(JsonKey.USER_IDs); + final boolean reIssue = isReissue(request.getContext().get(CourseJsonKey.REISSUE)); + Map courseBatchResponse = + CourseBatchUtil.validateEventBatch(request.getRequestContext(), eventId, batchId); + if (null == courseBatchResponse.get("cert_templates")) { + ProjectCommonException.throwClientErrorException( + ResponseCode.CLIENT_ERROR, "No certificate templates associated with " + batchId); + } + Response response = new Response(); + Map resultData = new HashMap<>(); + resultData.put( + JsonKey.STATUS, MessageFormat.format(ResponseMessage.SUBMITTED.getValue(), batchId)); + resultData.put(JsonKey.BATCH_ID, batchId); + resultData.put(JsonKey.EVENT_ID, eventId); + resultData.put(JsonKey.COLLECTION_ID, eventId); + response.put(JsonKey.RESULT, resultData); + try { + pushCertificateGenerateKafkaTopic(userIds,eventId,batchId,100.0,reIssue); + } catch (Exception e) { + logger.error(request.getRequestContext(), "issueCertificate pushInstructionEvent error for eventId=" + + eventId + ", batchId=" + batchId, e); + resultData.put( + JsonKey.STATUS, MessageFormat.format(ResponseMessage.FAILED.getValue(), batchId)); + } + sender().tell(response, self()); + } + + public void pushCertificateGenerateKafkaTopic(List userIds, String eventId, String batchId, double completionPercentage, boolean reIssue) { + long now = System.currentTimeMillis(); + + String userIdsJson = userIds.stream() + .map(id -> "\"" + id + "\"") + .collect(Collectors.joining(", ", "[", "]")); + + String event = String.format( + "{" + + "\"actor\":{" + + " \"id\": \"Issue Certificate Generator\"," + + " \"type\": \"System\"" + + "}," + + "\"context\":{" + + " \"pdata\":{" + + " \"version\": \"1.0\"," + + " \"id\": \"org.sunbird.learning.platform\"" + + " }" + + "}," + + "\"edata\": {" + + " \"action\": \"issue-event-certificate\"," + + " \"batchId\": \"%s\"," + + " \"eventId\": \"%s\"," + + " \"userIds\": %s," + + " \"eventCompletionPercentage\": %.2f%s" + + "}," + + "\"eid\": \"BE_JOB_REQUEST\"," + + "\"ets\": %d," + + "\"mid\": \"EVENT.%s\"," + + "\"object\": {" + + " \"id\": \"batch_%s\"," + + " \"type\": \"IssueCertificate\"" + + "}" + + "}", + batchId, + eventId, + userIdsJson, + completionPercentage, + reIssue ? ",\"reIssue\": true" : "", + now, + UUID.randomUUID().toString(), + batchId + ); + + + String topic = ProjectUtil.getConfigValue("user_issue_certificate_for_event"); + try { + KafkaClient.send(String.join(",", userIds), event, topic); + } catch (Exception e) { + throw new ProjectCommonException( + "BE_JOB_REQUEST_EXCEPTION", + "Invalid topic id.", + ResponseCode.CLIENT_ERROR.getResponseCode() + ); + } + + } + } diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/BatchCacheHandler.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/BatchCacheHandler.java new file mode 100644 index 000000000..b784671a5 --- /dev/null +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/BatchCacheHandler.java @@ -0,0 +1,58 @@ +/** */ +package org.sunbird.learner.util; + +import org.sunbird.common.models.util.JsonKey; +import org.sunbird.common.models.util.LoggerUtil; +import org.sunbird.common.models.util.PropertiesCache; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * This class will handle the data cache. + * + * @author Amit Kumar + */ +public class BatchCacheHandler implements Runnable { + + private static Map batchMap = new ConcurrentHashMap<>(); + + private LoggerUtil logger = new LoggerUtil(BatchCacheHandler.class); + + @Override + public void run() { + logger.info(null, "BatchCacheHandler:run: Cache refresh started."); + cache(batchMap); + logger.info(null, "BatchCacheHandler:run: Cache refresh completed."); + } + + @SuppressWarnings("unchecked") + private void cache(Map map) { + try { + Map contents = ContentUtil.getAllBatches(Integer.parseInt(PropertiesCache.getInstance() + .getProperty(JsonKey.PAGE_SIZE_CONTENT_FETCH))); + batchMap.putAll(contents); + logger.debug(null, "content keyset " + map.keySet()); + logger.info(null, " cache size: " + map.size()); + } catch (Exception e) { + logger.error(null, "ContentCacheHandler:cache: Exception in retrieving content section " + e.getMessage(), e); + } + } + + /** @return the contentCache */ + public static Map getBatchMap() { + return batchMap; + } + + public static Map getBatch(String id) { + Map obj = (Map) batchMap.get(id); + if(obj != null) + return obj; + else{ + batchMap.putAll(ContentUtil.getAllBatches(Arrays.asList(id),Integer.parseInt(PropertiesCache.getInstance() + .getProperty(JsonKey.PAGE_SIZE_CONTENT_FETCH)))); + return (Map) batchMap.get(id); + } + } +} diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/ContentUtil.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/ContentUtil.java index b14da33f1..7061da63b 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/ContentUtil.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/ContentUtil.java @@ -11,7 +11,6 @@ import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpHeaders; -import org.sunbird.common.Constants; import org.sunbird.common.ElasticSearchHelper; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.factory.EsClientFactory; @@ -264,6 +263,22 @@ public static boolean getContentRead(String courseId, Map allHea } return flag; } + public static Map getAllBatches(List identifierList,int pageSize) { + //int recordStart = 0; + int remainingRecords; + Map allRecords = new HashMap<>(); + do { + Map.Entry>> contentsResult = batches(identifierList,allRecords.size(), pageSize); + int count = contentsResult.getKey(); + Map> batchMap = contentsResult.getValue(); + allRecords.putAll(batchMap); + // Update remaining records and move to the next page if needed + remainingRecords = count - allRecords.size(); + // recordStart = allRecords.size() - 1; + } while (remainingRecords > 0); + + return allRecords; + } public static Map getAllContent(List identifierList,int pageSize) { //int recordStart = 0; int remainingRecords; @@ -280,9 +295,40 @@ public static Map getAllContent(List identifierList,int pageSize return allRecords; } + public static Map getAllBatches(int pageSize) { + return getAllBatches(null, pageSize); + } public static Map getAllContent(int pageSize) { return getAllContent(null, pageSize); } + + public static Map.Entry>> batches(List identifierList,int offset, int limit) { + SearchDTO searchDTO = new SearchDTO(); + searchDTO.setOffset(offset); + searchDTO.setLimit(limit); + HashMap sort = new HashMap(); + sort.put("createdDate","asc"); + searchDTO.setSortBy(sort); + HashMap filters = new java.util.HashMap(); + if(identifierList != null && identifierList.size() > 0) + filters.put(JsonKey.BATCH_ID,identifierList); + searchDTO.getAdditionalProperties().put(JsonKey.FILTERS, filters); + Future> resultFuture = EsClientFactory.getInstance(JsonKey.REST).search(null,searchDTO, ProjectUtil.EsType.courseBatch.getTypeName(),isCotentElasticSearchTypeDoc()); + HashMap result= (HashMap) ElasticSearchHelper.getResponseFromFuture(resultFuture); + Long longCount = (Long) result.getOrDefault(JsonKey.COUNT, 0L); + int count = longCount.intValue(); + List> batchesList = (List>) result.getOrDefault(JsonKey.CONTENT, new ArrayList<>()); + Map> batchesMap = new HashMap<>(); + if (CollectionUtils.isNotEmpty(batchesList)) { + for (Map batch : batchesList) { + String batchId = (String) batch.get(JsonKey.IDENTIFIER); + if(null != batchId && !batchId.isEmpty()) + batchesMap.put(batchId, batch); + } + } + return new AbstractMap.SimpleEntry<>(count, batchesMap); + } + public static Map.Entry>> contents(List identifierList,int offset, int limit) { SearchDTO searchDTO = new SearchDTO(); searchDTO.setOffset(offset); diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/CourseBatchUtil.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/CourseBatchUtil.java index e9cee340c..95bc2f57c 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/CourseBatchUtil.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/CourseBatchUtil.java @@ -287,4 +287,21 @@ public static Map esEventMapping(EventBatch eventBatch, String p return esCourseMap; } + public static Map validateEventBatch(RequestContext requestContext, String eventId, String batchId) { + Future> resultF = + esUtil.getDataByIdentifier(requestContext, EsType.eventBatch.getTypeName(), batchId); + Map result = + (Map) ElasticSearchHelper.getResponseFromFuture(resultF); + if (MapUtils.isEmpty(result)) { + ProjectCommonException.throwClientErrorException( + ResponseCode.CLIENT_ERROR, "No such batchId exists"); + } + if (StringUtils.isNotBlank(eventId) + && !StringUtils.equals(eventId, (String) result.get(JsonKey.EVENT_ID))) { + ProjectCommonException.throwClientErrorException( + ResponseCode.CLIENT_ERROR, "batchId is not linked with eventId"); + } + return result; + } + } diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/SchedulerManager.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/SchedulerManager.java index 6f7354ea1..0068980c8 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/SchedulerManager.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/SchedulerManager.java @@ -24,6 +24,8 @@ public static void schedule() { service.scheduleWithFixedDelay(new DataCacheHandler(), 0, PAGE_DATA_TTL, TimeUnit.HOURS); service.scheduleWithFixedDelay(new PageCacheLoaderService(), 0, PAGE_DATA_TTL, TimeUnit.HOURS); service.scheduleWithFixedDelay(new ContentCacheHandler(), 0, 15, TimeUnit.MINUTES); + service.scheduleWithFixedDelay(new BatchCacheHandler(), 0, 15, TimeUnit.MINUTES); + logger.info(null, "SchedulerManager:schedule: Started scheduler job for cache refresh."); } diff --git a/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/BaseEnrolmentActor.scala b/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/BaseEnrolmentActor.scala index f4bd7b5ac..4fafdd38d 100644 --- a/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/BaseEnrolmentActor.scala +++ b/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/BaseEnrolmentActor.scala @@ -11,6 +11,7 @@ import org.sunbird.common.models.util.{JsonKey, ProjectUtil} import org.sunbird.common.request.RequestContext import org.sunbird.dto.SearchDTO import org.sunbird.helper.ServiceFactory +import org.sunbird.learner.util.BatchCacheHandler abstract class BaseEnrolmentActor extends BaseActor { @@ -28,6 +29,8 @@ abstract class BaseEnrolmentActor extends BaseActor { response.getOrDefault(JsonKey.CONTENT, new java.util.ArrayList[util.Map[String, AnyRef]]).asInstanceOf[util.List[util.Map[String, AnyRef]]] } + + def getBatchesV2(requestContext: RequestContext, batchId: String, courseId: String, requestedFields: java.util.List[String]): java.util.List[java.util.Map[String, AnyRef]] = { val filters = new java.util.HashMap[String, AnyRef]() { { diff --git a/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/CourseEnrolmentActor.scala b/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/CourseEnrolmentActor.scala index 03401d2a9..c8266c676 100644 --- a/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/CourseEnrolmentActor.scala +++ b/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/CourseEnrolmentActor.scala @@ -9,7 +9,7 @@ import java.util.{Calendar, Collections, Comparator, Date, TimeZone, UUID} import akka.actor.ActorRef import com.fasterxml.jackson.databind.ObjectMapper import org.sunbird.common.models.util.JsonKey -import org.sunbird.learner.util.Util +import org.sunbird.learner.util.{BatchCacheHandler, ContentCacheHandler, ContentSearchUtil, ContentUtil, CourseBatchSchedulerUtil, JsonUtil, Util} import scala.collection.JavaConverters._ import javax.inject.{Inject, Named} @@ -24,7 +24,6 @@ import org.sunbird.common.responsecode.ResponseCode import org.sunbird.learner.actors.coursebatch.dao.impl.{BatchUserDaoImpl, CourseBatchDaoImpl, UserCoursesDaoImpl} import org.sunbird.learner.actors.coursebatch.dao.{BatchUserDao, CourseBatchDao, UserCoursesDao} import org.sunbird.learner.actors.group.dao.impl.GroupDaoImpl -import org.sunbird.learner.util.{ContentCacheHandler, ContentSearchUtil, ContentUtil, CourseBatchSchedulerUtil, JsonUtil, Util} import org.sunbird.models.course.batch.CourseBatch import org.sunbird.models.user.courses.UserCourses import org.sunbird.cache.util.RedisCacheUtil @@ -280,11 +279,18 @@ class CourseEnrolmentActor @Inject()(@Named("course-batch-notification-actor") c new ObjectMapper().writeValueAsString(searchRequest) } - def addBatchDetails(enrolmentList: util.List[util.Map[String, AnyRef]], request: Request): util.List[util.Map[String, AnyRef]] = { + def addBatchDetails(enrolmentList: util.List[util.Map[String, AnyRef]], request: Request,version:String): util.List[util.Map[String, AnyRef]] = { val batchIds:java.util.List[String] = enrolmentList.map(e => e.getOrDefault(JsonKey.BATCH_ID, "").asInstanceOf[String]).distinct.filter(id => StringUtils.isNotBlank(id)).toList.asJava val batchDetails = new java.util.ArrayList[java.util.Map[String, AnyRef]](); val searchIdentifierMaxSize = Integer.parseInt(ProjectUtil.getConfigValue(JsonKey.SEARCH_IDENTIFIER_MAX_SIZE)); - if (batchIds.size() > searchIdentifierMaxSize) { + if(JsonKey.VERSION_2.equalsIgnoreCase(version) && + JsonKey.TRUE.equalsIgnoreCase(ProjectUtil.getConfigValue(JsonKey.ENROLLMENT_LIST_CACHE_BATCH_FETCH_ENABLED))){ + logger.info(request.getRequestContext, "Retrieving batch details from the local cache"); + for (i <- 0 to batchIds.size()-1) { + batchDetails.add(getBatchFrmLocalCache(batchIds.get(i))) + } + } + else if (batchIds.size() > searchIdentifierMaxSize) { for (i <- 0 to batchIds.size() by searchIdentifierMaxSize) { val batchIdsSubList: java.util.List[String] = batchIds.subList(i, Math.min(batchIds.size(), i + searchIdentifierMaxSize)); batchDetails.addAll(searchBatchDetails(batchIdsSubList, request)) @@ -541,7 +547,7 @@ class CourseEnrolmentActor @Inject()(@Named("course-batch-notification-actor") c //if ("v2".equals(version)) // addBatchDetails_v2(updatedEnrolmentList, request) //else - addBatchDetails(updatedEnrolmentList, request) + addBatchDetails(updatedEnrolmentList, request,version.asInstanceOf[String]) } else new java.util.ArrayList[java.util.Map[String, AnyRef]]() } @@ -580,6 +586,14 @@ class CourseEnrolmentActor @Inject()(@Named("course-batch-notification-actor") c courseContent } + def getBatchFrmLocalCache(batchId: String): java.util.Map[String, AnyRef] = { + val batchesMap = BatchCacheHandler.getBatchMap.asInstanceOf[java.util.Map[String, java.util.Map[String, AnyRef]]] + var batch = batchesMap.get(batchId) + if (batch == null || batch.size() < 1) + batch = BatchCacheHandler.getBatch(batchId) + batch + } + def isCourseEligible(enrolment: java.util.Map[String, AnyRef]): Boolean = { val courseContent = getCourseContent(enrolment.get(JsonKey.COURSE_ID).asInstanceOf[String]) if (null == courseContent || (!JsonKey.LIVE.equalsIgnoreCase(courseContent.get(JsonKey.STATUS).asInstanceOf[String]) diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/JsonKey.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/JsonKey.java index 2e6c1906a..165dabd90 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/JsonKey.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/JsonKey.java @@ -1177,5 +1177,9 @@ public final class JsonKey { public static final String MEETING_LINK_URL = "meeting_link_url"; public static final String MEETING_LINK = "meetingLink"; public static final String KARMAYOGI_SAPTAH_END_DATE = "karmayogi_saptah_end_date"; + public static final String ENROLLMENT_LIST_CACHE_BATCH_FETCH_ENABLED ="use_cache_for_enrollment_list_batch_fetch"; + public static final String TRUE="true"; + public static final String EVENT_COMPLETION_PERCENTAGE="eventCompletionPercentage"; + public static final String ISSUE_EVENT_CERTIFICATE = "issue-event-certificate"; private JsonKey() {} } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/resources/externalresource.properties b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/resources/externalresource.properties index 45a004f04..cbde633f6 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/resources/externalresource.properties +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/resources/externalresource.properties @@ -231,4 +231,6 @@ event.update.url=/event/v4/update/ user_issue_certificate_for_event =dev.issue.certificate.request dashboard_user_event_state=dashboard.user.state meeting_link_url=https://teams.microsoft.com/l/meetup-join/19%3ameeting_M2Y3ZDE2ZDMtMWQwYS00OWQzLWE3NDctNDRkNTdjOGI4Yzll%40thread.v2/0?context=%7b%22Tid%22%3a%2240cfb65c-9b71-435f-8bc2-bc2c69df1aca%22%2c%22Oid%22%3a%22cbd37bc9-5c33-401f-b590-9decb3c370f8%22%7d -karmayogi_saptah_end_date=2024-10-31 \ No newline at end of file +karmayogi_saptah_end_date=2024-10-31 +use_cache_for_enrollment_list_batch_fetch=true +kafka_topics_event_certificate_instruction=local.event.issue.certificate.request \ No newline at end of file diff --git a/service/app/controllers/certificate/CertificateController.java b/service/app/controllers/certificate/CertificateController.java index 00afca13d..202dd3f04 100644 --- a/service/app/controllers/certificate/CertificateController.java +++ b/service/app/controllers/certificate/CertificateController.java @@ -101,4 +101,21 @@ public CompletionStage privateAddEventCertificate(Http.Request httpReque getAllRequestHeaders(httpRequest), httpRequest); } + + public CompletionStage issueEventCertificate(Http.Request httpRequest) { + return handleRequest( + certificateActorRef, + CourseActorOperations.ISSUE_EVENT_CERTIFICATE.getValue(), + httpRequest.body().asJson(), + (request) -> { + Request req = (Request) request; + String eventId = req.getRequest().containsKey(JsonKey.EVENT_ID) ? JsonKey.EVENT_ID : JsonKey.COLLECTION_ID; + req.getRequest().put(JsonKey.EVENT_ID, req.getRequest().get(eventId)); + new CertificateRequestValidator().validateIssueEventCertificateRequest(req); + req.getContext().put(REISSUE, httpRequest.queryString().get(REISSUE)); + return null; + }, + getAllRequestHeaders(httpRequest), + httpRequest); + } } diff --git a/service/app/controllers/certificate/CertificateRequestValidator.java b/service/app/controllers/certificate/CertificateRequestValidator.java index c3a17e9e8..d5d624491 100644 --- a/service/app/controllers/certificate/CertificateRequestValidator.java +++ b/service/app/controllers/certificate/CertificateRequestValidator.java @@ -28,6 +28,17 @@ public void validateIssueCertificateRequest(Request certRequestDto) { JsonKey.BATCH_ID); } + public void validateIssueEventCertificateRequest(Request certRequestDto) { + validateParam( + (String) certRequestDto.getRequest().get(JsonKey.EVENT_ID), + ResponseCode.mandatoryParamsMissing, + JsonKey.EVENT_ID+"/"+JsonKey.COLLECTION_ID); + validateParam( + (String) certRequestDto.getRequest().get(JsonKey.BATCH_ID), + ResponseCode.mandatoryParamsMissing, + JsonKey.BATCH_ID); + } + public void validateAddCertificateRequest(Request certRequestDto, String contextIdName) { Map batch = (Map) certRequestDto.getRequest().get(JsonKey.BATCH); diff --git a/service/app/util/RequestInterceptor.java b/service/app/util/RequestInterceptor.java index dd8d89e97..adcbdc329 100644 --- a/service/app/util/RequestInterceptor.java +++ b/service/app/util/RequestInterceptor.java @@ -49,6 +49,7 @@ private RequestInterceptor() {} apiHeaderIgnoreMap.put("/private/v3/user/courses/list/:uid", var); apiHeaderIgnoreMap.put("/private/v2/event/batch/create", var); apiHeaderIgnoreMap.put("/v1/blended/program/admin/enroll", var); + apiHeaderIgnoreMap.put("/v1/event/batch/cert/issue", var); } /** diff --git a/service/conf/routes b/service/conf/routes index f4c32ed82..a947e8f64 100644 --- a/service/conf/routes +++ b/service/conf/routes @@ -75,6 +75,7 @@ POST /v1/course/batch/cert/issue @controllers.certificate.CertificateC PATCH /v1/course/batch/cert/template/add @controllers.certificate.CertificateController.addCertificate(request: play.mvc.Http.Request) PATCH /v1/course/batch/cert/template/remove @controllers.certificate.CertificateController.deleteCertificate(request: play.mvc.Http.Request) PATCH /private/v1/course/batch/cert/template/add @controllers.certificate.CertificateController.privateAddCertificate(request: play.mvc.Http.Request) +POST /v1/event/batch/cert/issue @controllers.certificate.CertificateController.issueEventCertificate(request: play.mvc.Http.Request) #QR Code Download APIs POST /v1/course/qrcode/download @controllers.qrcodedownload.QRCodeDownloadController.downloadQRCodes(request: play.mvc.Http.Request)