diff --git a/.circleci/config.yml b/.circleci/config.yml index 2c5b2e01d..1501c53a6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,9 +24,8 @@ jobs: - run: name: sonar command: | - srcBranch=$(curl -s https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$CIRCLE_PR_NUMBER | jq .head.ref -r) - tarBranch=$(curl -s https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$CIRCLE_PR_NUMBER | jq .base.ref -r) - mvn verify -DskipTests=true sonar:sonar -Dsonar.projectKey=project-sunbird_sunbird-course-service -Dsonar.organization=project-sunbird -Dsonar.host.url=https://sonarcloud.io -Dsonar.pullrequest.branch=$srcbranch -Dsonar.pullrequest.key=$CIRCLE_PR_NUMBER -Dsonar.pullrequest.base=$tarbranch -Dsonar.scala.coverage.reportPaths=/home/circleci/project/course-mw/enrolment-actor/target/scoverage.xml,/home/circleci/project/course-mw/sunbird-util/cache-utils/target/scoverage.xml -Dsonar.scanner.force-deprecated-java-version-grace-period=true + JAVA_REPORT_PATHS=`find /home/circleci/project -iname jacoco.xml | awk 'BEGIN { RS = "" ; FS = "\n"; OFS = ","}{$1=$1; print $0}'` + mvn verify -DskipTests=true sonar:sonar -Dsonar.projectKey=project-sunbird_sunbird-course-service -Dsonar.organization=project-sunbird -Dsonar.host.url=https://sonarcloud.io -Dsonar.pullrequest.branch=$srcbranch -Dsonar.pullrequest.key=$CIRCLE_PR_NUMBER -Dsonar.pullrequest.base=$tarbranch -Dsonar.scala.coverage.reportPaths=/home/circleci/project/course-mw/enrolment-actor/target/scoverage.xml,/home/circleci/project/course-mw/sunbird-util/cache-utils/target/scoverage.xml -Dsonar.coverage.jacoco.xmlReportPaths=${JAVA_REPORT_PATHS} workflows: version: 2.1 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..c67e8858f --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,32 @@ +Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. + +### Type of change + +Please choose appropriate options. + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +### How Has This Been Tested? + +Please describe the tests that you ran to verify your changes in the below checkboxes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration + +- [ ] Ran Test A +- [ ] Ran Test B + +**Test Configuration**: +* Software versions: Java-11, play2-2.7.2, scala-2.11, redis-5.0.3 +* Hardware versions: 2 CPU/ 4GB RAM + +### Checklist: + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] Any dependent changes have been merged and published in downstream modules diff --git a/.github/workflows/jira-description-action.yml b/.github/workflows/jira-description-action.yml new file mode 100644 index 000000000..76d3fa771 --- /dev/null +++ b/.github/workflows/jira-description-action.yml @@ -0,0 +1,16 @@ +name: jira-description-action +on: + pull_request_target: + types: [opened, labeled] +jobs: + add-jira-description: + runs-on: ubuntu-latest + steps: + - uses: project-sunbird/jira-description-action@v0.4.0 + name: jira-description-action + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + jira-token: ${{ secrets.JIRA_TOKEN }} + jira-base-url: ${{ secrets.JIRA_BASE_URL }} + fail-when-jira-issue-not-found: ${{ secrets.FAIL_WHEN_JIRA_ISSUE_NOT_FOUND }} + use: both diff --git a/course-mw/course-actors-common/pom.xml b/course-mw/course-actors-common/pom.xml index 94f301dab..4b6a904a2 100644 --- a/course-mw/course-actors-common/pom.xml +++ b/course-mw/course-actors-common/pom.xml @@ -16,6 +16,16 @@ 1.0.7 + + net.logstash.logback + logstash-logback-encoder + 6.6 + + + ch.qos.logback + logback-classic + 1.2.3 + joda-time joda-time @@ -68,11 +78,6 @@ - - log4j - log4j - 1.2.17 - com.typesafe.akka akka-testkit_2.11 @@ -168,9 +173,11 @@ maven-surefire-plugin 3.0.0-M4 - - --illegal-access=warn - + + + **/*Spec.java + **/*Test.java + diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/actor/base/BaseActor.java b/course-mw/course-actors-common/src/main/java/org/sunbird/actor/base/BaseActor.java index c71b2b54d..abb1d3e7e 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/actor/base/BaseActor.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/actor/base/BaseActor.java @@ -3,6 +3,7 @@ import akka.actor.UntypedAbstractActor; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.Response; +import org.sunbird.common.models.response.ResponseParams; import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.request.Request; import org.sunbird.common.responsecode.ResponseCode; @@ -51,4 +52,16 @@ public Response successResponse() { response.put("response", "SUCCESS"); return response; } + + public Response clientError(String message) { + Response response = new Response(); + response.setResponseCode(ResponseCode.CLIENT_ERROR); + ResponseParams params = new ResponseParams(); + params.setStatus(ResponseParams.StatusType.FAILED.name()); + params.setErr(ResponseCode.invalidRequestData.getErrorCode()); + params.setErrmsg(ResponseCode.invalidRequestData.getErrorMessage()); + response.setParams(params); + response.put("response", message); + return response; + } } diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/BackgroundJobManager.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/BackgroundJobManager.java index ce231d6e3..801acd246 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/BackgroundJobManager.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/BackgroundJobManager.java @@ -161,7 +161,7 @@ private boolean insertDataToElastic( logger.info(requestContext, "BackgroundJobManager:insertDataToElastic: type = " + type + " identifier = " + identifier); Future responseF = esService.save(requestContext, type, identifier, data); String response = (String) ElasticSearchHelper.getResponseFromFuture(responseF); - logger.debug(requestContext, "ES save response for identifier :" + identifier + " : ", response); + logger.debug(requestContext, "ES save response for identifier :" + identifier, null, new HashMap() {{put("response", response);}}); if (!StringUtils.isBlank(response)) { return true; } diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/PageManagementActor.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/PageManagementActor.java index fc7adea97..f8f52ddae 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/PageManagementActor.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/PageManagementActor.java @@ -11,6 +11,7 @@ import org.apache.commons.lang3.StringUtils; import org.sunbird.actor.base.BaseActor; import org.sunbird.cassandra.CassandraOperation; +import org.sunbird.common.CassandraUtil; import org.sunbird.common.ElasticSearchHelper; import org.sunbird.common.cacheloader.PageCacheLoaderService; import org.sunbird.common.exception.ProjectCommonException; @@ -25,6 +26,7 @@ import org.sunbird.common.request.Request; import org.sunbird.common.request.RequestContext; import org.sunbird.common.responsecode.ResponseCode; +import org.sunbird.common.util.JsonUtil; import org.sunbird.dto.SearchDTO; import org.sunbird.helper.ServiceFactory; import org.sunbird.learner.util.ContentSearchUtil; @@ -37,8 +39,11 @@ import scala.concurrent.Promise; import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -47,6 +52,7 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import java.util.TimeZone; import static org.sunbird.common.models.util.JsonKey.ID; @@ -67,10 +73,15 @@ public class PageManagementActor extends BaseActor { private static final String DYNAMIC_FILTERS = "dynamicFilters"; private static List userProfilePropList = Arrays.asList("board"); private LoggerUtil logger = new LoggerUtil(PageManagementActor.class); + private static final SimpleDateFormat DATE_FORMAT = ProjectUtil.getDateFormatter(); + static { + DATE_FORMAT.setTimeZone( + TimeZone.getTimeZone(ProjectUtil.getConfigValue(JsonKey.SUNBIRD_TIMEZONE))); + } @Override public void onReceive(Request request) throws Throwable { - Util.initializeContext(request, TelemetryEnvKey.PAGE); + Util.initializeContext(request, TelemetryEnvKey.PAGE, this.getClass().getName()); if(request.getOperation().equalsIgnoreCase(ActorOperations.GET_DIAL_PAGE_DATA.getValue())) { getDIALPageData(request); @@ -114,7 +125,7 @@ private void getAllSections(RequestContext requestContext) { } @SuppressWarnings("unchecked") - private void getSection(Request actorMessage) { + private void getSection(Request actorMessage) throws Exception { Response response = null; Map req = actorMessage.getRequest(); String sectionId = (String) req.get(JsonKey.ID); @@ -132,7 +143,7 @@ private void getSection(Request actorMessage) { Map map = result.get(0); removeUnwantedData(map, ""); Response section = new Response(); - section.put(JsonKey.SECTION, response.get(JsonKey.RESPONSE)); + section.put(JsonKey.SECTION, JsonUtil.convertWithDateFormat(response.get(JsonKey.RESPONSE), Map.class, DATE_FORMAT)); PageCacheLoaderService.putDataIntoCache( ActorOperations.GET_SECTION.getValue(), sectionId, response.get(JsonKey.RESPONSE)); sender().tell(section, self()); @@ -142,7 +153,7 @@ private void getSection(Request actorMessage) { } } else { response = new Response(); - response.put(JsonKey.SECTION, sectionMap); + response.put(JsonKey.SECTION, JsonUtil.convertWithDateFormat(sectionMap, Map.class, DATE_FORMAT)); } sender().tell(response, self()); } @@ -171,7 +182,22 @@ private void updatePageSection(Request actorMessage) { logger.error(actorMessage.getRequestContext(), "Exception occurred while processing display " + e.getMessage(), e); } } - sectionMap.put(JsonKey.UPDATED_DATE, ProjectUtil.getFormattedDate()); + sectionMap.put(JsonKey.UPDATED_DATE, ProjectUtil.getTimeStamp()); + sectionMap = CassandraUtil.changeCassandraColumnMapping(sectionMap); + + if (!StringUtils.isBlank((String) sectionMap.get(JsonKey.ID))) { + Map map = new HashMap<>(); + map.put(JsonKey.ID, (String) sectionMap.get(JsonKey.ID)); + Response res = + cassandraOperation.getRecordsByProperties( + actorMessage.getRequestContext(), sectionDbInfo.getKeySpace(), sectionDbInfo.getTableName(), map); + if (!((List>) res.get(JsonKey.RESPONSE)).isEmpty()) { + Map pageSection = ((List>) res.get(JsonKey.RESPONSE)).get(0); + pageSection.put(JsonKey.CREATED_DATE, createdDateCheck(pageSection)); + } + } + + sectionMap = CassandraUtil.changeCassandraColumnMapping(sectionMap); Response response = cassandraOperation.updateRecord( actorMessage.getRequestContext(), sectionDbInfo.getKeySpace(), sectionDbInfo.getTableName(), sectionMap); @@ -215,7 +241,8 @@ private void createPageSection(Request actorMessage) { } sectionMap.put(JsonKey.ID, uniqueId); sectionMap.put(JsonKey.STATUS, ProjectUtil.Status.ACTIVE.getValue()); - sectionMap.put(JsonKey.CREATED_DATE, ProjectUtil.getFormattedDate()); + sectionMap.put(JsonKey.CREATED_DATE, ProjectUtil.getTimeStamp()); + sectionMap = CassandraUtil.changeCassandraColumnMapping(sectionMap); Response response = cassandraOperation.insertRecord( actorMessage.getRequestContext(), sectionDbInfo.getKeySpace(), sectionDbInfo.getTableName(), sectionMap); @@ -442,6 +469,7 @@ private void updatePage(Request actorMessage) { actorMessage.getRequestContext(), pageDbInfo.getKeySpace(), pageDbInfo.getTableName(), map); if (!((List>) res.get(JsonKey.RESPONSE)).isEmpty()) { Map page = ((List>) res.get(JsonKey.RESPONSE)).get(0); + pageMap.put(JsonKey.CREATED_DATE, createdDateCheck(page)); if (!(((String) page.get(JsonKey.ID)).equals(pageMap.get(JsonKey.ID)))) { ProjectCommonException exception = new ProjectCommonException( @@ -453,7 +481,7 @@ private void updatePage(Request actorMessage) { } } } - pageMap.put(JsonKey.UPDATED_DATE, ProjectUtil.getFormattedDate()); + pageMap.put(JsonKey.UPDATED_DATE, ProjectUtil.getTimeStamp()); if (null != pageMap.get(JsonKey.PORTAL_MAP)) { try { pageMap.put(JsonKey.PORTAL_MAP, mapper.writeValueAsString(pageMap.get(JsonKey.PORTAL_MAP))); @@ -468,6 +496,7 @@ private void updatePage(Request actorMessage) { logger.error(actorMessage.getRequestContext(), "Exception occurred while updating app map data " + e.getMessage(), e); } } + pageMap = CassandraUtil.changeCassandraColumnMapping(pageMap); Response response = cassandraOperation.updateRecord( actorMessage.getRequestContext(), pageDbInfo.getKeySpace(), pageDbInfo.getTableName(), pageMap); @@ -516,7 +545,7 @@ private void createPage(Request actorMessage) { } } pageMap.put(JsonKey.ID, uniqueId); - pageMap.put(JsonKey.CREATED_DATE, ProjectUtil.getFormattedDate()); + pageMap.put(JsonKey.CREATED_DATE, ProjectUtil.getTimeStamp()); if (null != pageMap.get(JsonKey.PORTAL_MAP)) { try { pageMap.put(JsonKey.PORTAL_MAP, mapper.writeValueAsString(pageMap.get(JsonKey.PORTAL_MAP))); @@ -531,6 +560,7 @@ private void createPage(Request actorMessage) { logger.error(actorMessage.getRequestContext(), "createPage: " + e.getMessage(), e); } } + pageMap = CassandraUtil.changeCassandraColumnMapping(pageMap); Response response = cassandraOperation.insertRecord( actorMessage.getRequestContext(), pageDbInfo.getKeySpace(), pageDbInfo.getTableName(), pageMap); @@ -932,4 +962,16 @@ private List getStringListFromObj(Object obj) { return Arrays.asList((String)obj); } } + + // Remove this implementation after deprecating text date columns + private Date createdDateCheck(Map page) { + try { + if (page.containsKey(JsonKey.CREATED_DATE) && page.get(JsonKey.CREATED_DATE) == null) { + return DATE_FORMAT.parse((String) page.get(JsonKey.OLD_CREATED_DATE)); + } + } catch (ParseException e) { + logger.error(null, "PageManagementActor:createdDateCheck: Exception occurred with error message = " + e.getMessage(), e); + } + return (Date) page.get(JsonKey.CREATED_DATE); + } } 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 630b104a2..d109cb229 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 @@ -41,7 +41,7 @@ public String getValue() { @Override public void onReceive(Request request) throws Throwable { - Util.initializeContext(request, TelemetryEnvKey.USER); + Util.initializeContext(request, TelemetryEnvKey.USER, this.getClass().getName()); String requestedOperation = request.getOperation(); switch (requestedOperation) { diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/certificate/service/CourseBatchCertificateActor.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/certificate/service/CourseBatchCertificateActor.java index 8ac3e17e7..a92c90270 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/certificate/service/CourseBatchCertificateActor.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/certificate/service/CourseBatchCertificateActor.java @@ -33,7 +33,7 @@ public class CourseBatchCertificateActor extends BaseActor { @Override public void onReceive(Request request) throws Throwable { - Util.initializeContext(request, TelemetryEnvKey.USER); + Util.initializeContext(request, TelemetryEnvKey.USER, this.getClass().getName()); String requestedOperation = request.getOperation(); switch (requestedOperation) { diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/course/CourseManagementActor.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/course/CourseManagementActor.java index 272ac9fc7..b0ecafa46 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/course/CourseManagementActor.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/course/CourseManagementActor.java @@ -35,7 +35,8 @@ public class CourseManagementActor extends BaseActor { @Override public void onReceive(Request request) throws Throwable { - Util.initializeContext(request, TelemetryEnvKey.COURSE_CREATE); + Util.initializeContext(request, TelemetryEnvKey.COURSE_CREATE, this.getClass().getName()); + String requestedOperation = request.getOperation(); switch (requestedOperation) { case "createCourse": diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/dao/impl/CourseBatchDaoImpl.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/dao/impl/CourseBatchDaoImpl.java index b10f6fcb9..34adda2f9 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/dao/impl/CourseBatchDaoImpl.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/dao/impl/CourseBatchDaoImpl.java @@ -4,9 +4,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; + import org.sunbird.cassandra.CassandraOperation; +import org.sunbird.common.CassandraUtil; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.Response; +import org.sunbird.common.models.util.CassandraPropertyReader; import org.sunbird.common.models.util.JsonKey; import org.sunbird.common.request.RequestContext; import org.sunbird.common.responsecode.ResponseCode; @@ -19,12 +23,14 @@ public class CourseBatchDaoImpl implements CourseBatchDao { private CassandraOperation cassandraOperation = ServiceFactory.getInstance(); private Util.DbInfo courseBatchDb = Util.dbInfoMap.get(JsonKey.COURSE_BATCH_DB); - + private static final CassandraPropertyReader propertiesCache = + CassandraPropertyReader.getInstance(); private ObjectMapper mapper = new ObjectMapper(); @Override public Response create(RequestContext requestContext, CourseBatch courseBatch) { Map map = mapper.convertValue(courseBatch, Map.class); + map = CassandraUtil.changeCassandraColumnMapping(map); return cassandraOperation.insertRecord( requestContext, courseBatchDb.getKeySpace(), courseBatchDb.getTableName(), map); } @@ -38,6 +44,7 @@ public Response update(RequestContext requestContext, String courseId, String ba attributeMap.putAll(map); attributeMap.remove(JsonKey.COURSE_ID); attributeMap.remove(JsonKey.BATCH_ID); + attributeMap = CassandraUtil.changeCassandraColumnMapping(attributeMap); return cassandraOperation.updateRecord( requestContext, courseBatchDb.getKeySpace(), courseBatchDb.getTableName(), attributeMap, primaryKey); } diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/dao/impl/UserCoursesDaoImpl.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/dao/impl/UserCoursesDaoImpl.java index 270d519c3..96597914a 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/dao/impl/UserCoursesDaoImpl.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/dao/impl/UserCoursesDaoImpl.java @@ -22,7 +22,7 @@ public class UserCoursesDaoImpl implements UserCoursesDao { Util.dbInfoMap.get(JsonKey.LEARNER_COURSE_DB).getKeySpace(); private static final String TABLE_NAME = Util.dbInfoMap.get(JsonKey.LEARNER_COURSE_DB).getTableName(); - private static final String USER_ENROLMENTS = "user_enrolments"; + private static final String USER_ENROLMENTS = Util.dbInfoMap.get(JsonKey.USER_ENROLMENTS_DB).getTableName(); public static UserCoursesDao getInstance() { if (userCoursesDao == null) { userCoursesDao = new UserCoursesDaoImpl(); @@ -89,9 +89,9 @@ public Response updateV2(RequestContext requestContext, String userId, String co primaryKey.put(JsonKey.BATCH_ID, batchId); Map updateList = new HashMap<>(); updateList.putAll(updateAttributes); - updateList.remove(JsonKey.BATCH_ID); - updateList.remove(JsonKey.COURSE_ID); - updateList.remove(JsonKey.USER_ID); + updateList.remove(JsonKey.BATCH_ID_KEY); + updateList.remove(JsonKey.COURSE_ID_KEY); + updateList.remove(JsonKey.USER_ID_KEY); return cassandraOperation.updateRecord(requestContext, KEYSPACE_NAME, USER_ENROLMENTS, updateList, primaryKey); } diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/service/UserCoursesService.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/service/UserCoursesService.java index ef33521ff..4835ecbb0 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/service/UserCoursesService.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/coursebatch/service/UserCoursesService.java @@ -33,23 +33,6 @@ public static String generateUserCourseESId(String batchId, String userId) { return batchId + UNDERSCORE + userId; } - public void validateUserUnenroll(RequestContext requestContext, UserCourses userCourseResult) { - if (userCourseResult == null || !userCourseResult.isActive()) { - logger.info(requestContext, "UserCoursesService:validateUserUnenroll: User is not enrolled yet"); - throw new ProjectCommonException( - ResponseCode.userNotEnrolledCourse.getErrorCode(), - ResponseCode.userNotEnrolledCourse.getErrorMessage(), - ResponseCode.CLIENT_ERROR.getResponseCode()); - } - if (userCourseResult.getStatus() == ProjectUtil.ProgressStatus.COMPLETED.getValue()) { - logger.debug(requestContext, "UserCoursesService:validateUserUnenroll: User already completed the course"); - throw new ProjectCommonException( - ResponseCode.userAlreadyCompletedCourse.getErrorCode(), - ResponseCode.userAlreadyCompletedCourse.getErrorMessage(), - ResponseCode.CLIENT_ERROR.getResponseCode()); - } - } - public static String getPrimaryKey(Map userCourseMap) { String userId = (String) userCourseMap.get(JsonKey.USER_ID); String courseId = (String) userCourseMap.get(JsonKey.COURSE_ID); @@ -66,40 +49,6 @@ public static String getPrimaryKey(String userId, String courseId, String batchI + batchId); } - public void enroll(RequestContext requestContext, String batchId, String courseId, List userIds) { - Integer count = 0; - - List> records = new ArrayList<>(); - Map userCoursesCommon = new HashMap<>(); - userCoursesCommon.put(JsonKey.BATCH_ID, batchId); - userCoursesCommon.put(JsonKey.COURSE_ID, courseId); - userCoursesCommon.put(JsonKey.COURSE_ENROLL_DATE, ProjectUtil.getFormattedDate()); - userCoursesCommon.put(JsonKey.ACTIVE, ProjectUtil.ActiveStatus.ACTIVE.getValue()); - userCoursesCommon.put(JsonKey.STATUS, ProjectUtil.ProgressStatus.NOT_STARTED.getValue()); - userCoursesCommon.put(JsonKey.COURSE_PROGRESS, 0); - - for (String userId : userIds) { - Map userCourses = new HashMap<>(); - userCourses.put(JsonKey.USER_ID, userId); - userCourses.putAll(userCoursesCommon); - - count++; - records.add(userCourses); - if (count > CASSANDRA_BATCH_SIZE) { - performBatchInsert(requestContext, records); - syncUsersToES(requestContext, records); - records.clear(); - count = 0; - } - if (count != 0) { - performBatchInsert(requestContext, records); - syncUsersToES(requestContext, records); - records.clear(); - count = 0; - } - } - } - private void syncUsersToES(RequestContext requestContext, List> records) { for (Map userCourses : records) { @@ -130,15 +79,6 @@ protected void performBatchInsert(RequestContext requestContext, List updateAttributes = new HashMap<>(); - updateAttributes.put(JsonKey.ACTIVE, ProjectUtil.ActiveStatus.INACTIVE.getValue()); - userCourseDao.update(requestContext, userCourses.getBatchId(), userCourses.getUserId(), updateAttributes); - sync(requestContext, updateAttributes, userCourses.getBatchId(), userCourses.getUserId()); - } - public Map getActiveEnrollments(String userId) { Map filter = new HashMap<>(); filter.put(JsonKey.USER_ID, userId); diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/health/HealthActor.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/health/HealthActor.java index 092dd149c..f2c8c7055 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/health/HealthActor.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/health/HealthActor.java @@ -34,13 +34,15 @@ public class HealthActor extends BaseActor { private Util.DbInfo pagesDbInfo = Util.dbInfoMap.get(JsonKey.PAGE_MGMT_DB); private ElasticSearchService esUtil = EsClientFactory.getInstance(JsonKey.REST); private static final String LMS_SERVICE = "lms-service"; + public LoggerUtil logger = new LoggerUtil(this.getClass()); @Override public void onReceive(Request message) throws Throwable { if (message instanceof Request) { try { Request actorMessage = message; - Util.initializeContext(actorMessage, TelemetryEnvKey.USER); + Util.initializeContext(actorMessage, TelemetryEnvKey.USER, this.getClass().getName()); + // set request id fto thread loacl... if (actorMessage.getOperation().equalsIgnoreCase(ActorOperations.HEALTH_CHECK.getValue())) { checkAllComponentHealth(); diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/qrcodedownload/QRCodeDownloadManagementActor.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/qrcodedownload/QRCodeDownloadManagementActor.java index ccbd658ec..66246e7ee 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/qrcodedownload/QRCodeDownloadManagementActor.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/qrcodedownload/QRCodeDownloadManagementActor.java @@ -55,7 +55,8 @@ public class QRCodeDownloadManagementActor extends BaseActor { @Override public void onReceive(Request request) throws Throwable { - Util.initializeContext(request, TelemetryEnvKey.QR_CODE_DOWNLOAD); + Util.initializeContext(request, TelemetryEnvKey.QR_CODE_DOWNLOAD, this.getClass().getName()); + String requestedOperation = request.getOperation(); switch (requestedOperation) { case "downloadQRCodes": diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/search/SearchHandlerActor.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/search/SearchHandlerActor.java index 1ec8eb2a6..58a5f2f0b 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/search/SearchHandlerActor.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/actors/search/SearchHandlerActor.java @@ -1,37 +1,28 @@ package org.sunbird.learner.actors.search; -import com.mashape.unirest.http.HttpResponse; -import com.mashape.unirest.http.Unirest; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang.BooleanUtils; import org.sunbird.actor.base.BaseActor; import org.sunbird.common.ElasticSearchHelper; -import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.factory.EsClientFactory; import org.sunbird.common.inf.ElasticSearchService; -import org.sunbird.common.models.response.HttpUtilResponse; import org.sunbird.common.models.response.Response; -import org.sunbird.common.models.util.ActorOperations; -import org.sunbird.common.models.util.HttpUtil; -import org.sunbird.common.models.util.JsonKey; -import org.sunbird.common.models.util.ProjectUtil; +import org.sunbird.common.models.util.*; import org.sunbird.common.models.util.ProjectUtil.EsType; -import org.sunbird.common.models.util.PropertiesCache; -import org.sunbird.common.models.util.TelemetryEnvKey; import org.sunbird.common.request.Request; import org.sunbird.common.request.RequestContext; -import org.sunbird.common.responsecode.ResponseCode; import org.sunbird.dto.SearchDTO; import org.sunbird.learner.actors.coursebatch.service.UserCoursesService; -import org.sunbird.learner.util.JsonUtil; import org.sunbird.learner.util.Util; import org.sunbird.telemetry.util.TelemetryWriter; +import org.sunbird.userorg.UserOrgService; +import org.sunbird.userorg.UserOrgServiceImpl; import scala.concurrent.Future; import java.time.Instant; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -47,13 +38,15 @@ public class SearchHandlerActor extends BaseActor { private String topn = PropertiesCache.getInstance().getProperty(JsonKey.SEARCH_TOP_N); private ElasticSearchService esService = EsClientFactory.getInstance(JsonKey.REST); private static final String CREATED_BY = "createdBy"; - - + private static LoggerUtil logger = new LoggerUtil(SearchHandlerActor.class); + private UserOrgService userOrgService = UserOrgServiceImpl.getInstance(); + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public void onReceive(Request request) throws Throwable { request.toLower(); - Util.initializeContext(request, TelemetryEnvKey.USER); + Util.initializeContext(request, TelemetryEnvKey.USER, this.getClass().getName()); + // set request id fto thread loacl... if (request.getOperation().equalsIgnoreCase(ActorOperations.COMPOSITE_SEARCH.getValue())) { @@ -102,7 +95,7 @@ public void onReceive(Request request) throws Throwable { Response response = new Response(); if (result != null) { if (BooleanUtils.isTrue(showCreator)) - populateCreatorDetails(request.getRequestContext(), result); + populateCreatorDetails(request.getContext(), result, request.getRequestContext()); if (!searchQueryMap.containsKey(JsonKey.FIELDS)) addCollectionId(result); response.put(JsonKey.RESPONSE, result); @@ -119,58 +112,26 @@ public void onReceive(Request request) throws Throwable { } } - private void populateCreatorDetails(RequestContext requestContext, Map result) throws Exception { + private void populateCreatorDetails(Map context, Map result, RequestContext requestContext) { List> content = (List>) result.getOrDefault("content", new ArrayList>()); - if(CollectionUtils.isNotEmpty(content)){ - List creatorIds = content.stream().filter(map -> map.containsKey(CREATED_BY)).map(map -> (String) map.get(CREATED_BY)).collect(Collectors.toList()); - Map creatorDetails = getCreatorDetails(requestContext, creatorIds); - if(MapUtils.isNotEmpty(creatorDetails)){ - content.stream().filter(map -> creatorDetails.containsKey((String) map.get(CREATED_BY))).map(map -> map.put("creatorDetails", creatorDetails.get((String) map.get(CREATED_BY)))).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(content)) { + List creatorIds = content.stream().filter(map -> map.containsKey(CREATED_BY)).map(map -> (String) map.get(CREATED_BY)).collect(Collectors.toList()); + List> userDetails = userOrgService.getUsersByIds(creatorIds, (String) context.getOrDefault(JsonKey.X_AUTH_TOKEN, "")); + logger.info(requestContext, "SearchHandlerActor::populateCreatorDetails::userDetails : " + userDetails); + if(CollectionUtils.isNotEmpty(userDetails)) { + List> creatorDetails = userDetails.stream().map(user -> new HashMap() {{ + put(JsonKey.ID, user.get(JsonKey.ID)); + put(JsonKey.FIRST_NAME, user.get(JsonKey.FIRST_NAME)); + put(JsonKey.LAST_NAME, user.get(JsonKey.LAST_NAME)); + }}).collect(Collectors.toList()); + Map tempResult = CollectionUtils.isNotEmpty(creatorDetails) ? creatorDetails.stream().collect(Collectors.toMap(s -> (String) s.remove("id"), s -> s)) : new HashMap<>(); + if (MapUtils.isNotEmpty(tempResult)) { + content.stream().filter(map -> tempResult.containsKey(map.get(CREATED_BY))).map(map -> map.put("creatorDetails", tempResult.get((String) map.get(CREATED_BY)))).collect(Collectors.toList()); } + } } } - private Map getCreatorDetails(RequestContext requestContext, List creatorIds) throws Exception { - String userSearchUrl = ProjectUtil.getConfigValue(JsonKey.USER_SEARCH_BASE_URL) + "/private/user/v1/search"; - List fields = Arrays.asList(ProjectUtil.getConfigValue(JsonKey.CREATOR_DETAILS_FIELDS).split(",")); - String reqStr = getUserSearchRequest(creatorIds, fields); - logger.info(requestContext, "Calling user search to fetch creator details for IDs: " + creatorIds); - List> tempResult = makePostRequest(requestContext, userSearchUrl, reqStr); - return CollectionUtils.isNotEmpty(tempResult) ? tempResult.stream().collect(Collectors.toMap(s -> (String) s.remove("id"), s -> s)) : new HashMap(); - } - - private String getUserSearchRequest(List creatorIds, List fields) throws Exception { - Map reqMap = new HashMap() {{ - put("request", new HashMap() {{ - put("filters", new HashMap() {{ - put("id", creatorIds); - }}); - put("fields", fields); - }}); - }}; - return JsonUtil.serialize(reqMap); - } - - private List> makePostRequest(RequestContext requestContext, String url, String req) throws Exception { - HttpUtilResponse resp = HttpUtil.doPostRequest(url, req, HttpUtil.getHeader(null)); - logger.info(requestContext, "Response from user search for creator details: " + resp.getStatusCode() + " and body: " + resp.getBody()); - Response response = getResponse(resp.getBody()); - return (List>) ((Map) response.getResult().getOrDefault("response", new HashMap())).getOrDefault("content", new ArrayList>()); - } - - private Response getResponse(String body) { - Response resp = new Response(); - try { - resp = JsonUtil.deserialize(body, Response.class); - } catch (Exception e) { - throw new ProjectCommonException( - ResponseCode.unableToParseData.getErrorCode(), - ResponseCode.unableToParseData.getErrorMessage(), - ResponseCode.SERVER_ERROR.getResponseCode()); - } - return resp; - } - private List getParticipantList(RequestContext requestContext, String id) { UserCoursesService userCourseService = new UserCoursesService(); return userCourseService.getEnrolledUserFromBatch(requestContext, 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 70d3361f0..8576d4ef2 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 @@ -15,13 +15,11 @@ import org.apache.http.HttpHeaders; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.HttpUtilResponse; -import org.sunbird.common.models.util.HttpUtil; -import org.sunbird.common.models.util.JsonKey; -import org.sunbird.common.models.util.LoggerEnum; -import org.sunbird.common.models.util.ProjectLogger; -import org.sunbird.common.models.util.ProjectUtil; -import org.sunbird.common.models.util.PropertiesCache; +import org.sunbird.common.models.util.*; +import org.sunbird.common.request.Request; +import org.sunbird.common.request.RequestContext; import org.sunbird.common.responsecode.ResponseCode; +import org.sunbird.common.util.JsonUtil; /** * This class will make the call to EkStep content search @@ -31,12 +29,19 @@ public final class ContentUtil { private static ObjectMapper mapper = new ObjectMapper(); + public static Map headerMap = new HashMap<>(); private static String EKSTEP_COURSE_SEARCH_QUERY = "{\"request\": {\"filters\":{\"contentType\": [\"Course\"], \"identifier\": \"COURSE_ID_PLACEHOLDER\", \"status\": \"Live\", \"mimeType\": \"application/vnd.ekstep.content-collection\", \"trackable.enabled\": \"Yes\"},\"limit\": 1}}"; - - + private static LoggerUtil logger = new LoggerUtil(ContentUtil.class); private ContentUtil() {} + static { + String header = ProjectUtil.getConfigValue(JsonKey.EKSTEP_AUTHORIZATION); + header = JsonKey.BEARER + header; + headerMap.put(JsonKey.AUTHORIZATION, header); + headerMap.put("Content-Type", "application/json"); + } + /** * @param params String * @param headers Map @@ -56,23 +61,22 @@ public static Map searchContent(String params, Map(){{put("response", response);}}); Map data = mapper.readValue(response, Map.class); if (MapUtils.isNotEmpty(data)) { String resmsgId = (String) ((Map) data.get("params")).get("resmsgid"); String apiId = (String) data.get("id"); data = (Map) data.get(JsonKey.RESULT); - ProjectLogger.log( + logger.info(null, "Total number of content fetched from Ekstep while assembling page data : " - + data.get("count"), - LoggerEnum.INFO.name()); + + data.get("count")); if (MapUtils.isNotEmpty(data)) { Object contentList = data.get(JsonKey.CONTENT); Map param = new HashMap<>(); @@ -89,10 +93,10 @@ public static Map searchContent(String params, Map searchContent(String params, Map(){{put("data", body);}}); Map headers = new HashMap<>(); headers.put("Content-Type", "application/json; charset=utf-8"); headers.put(JsonKey.AUTHORIZATION, authKey); HttpUtilResponse response = HttpUtil.doPostRequest(url, body, headers); if (response == null || response.getStatusCode() != 200) { - ProjectLogger.log( - "BaseMetricsActor:makePostRequest: Status code from analytics is not 200 ", - LoggerEnum.INFO.name()); + logger.info(null, + "BaseMetricsActor:makePostRequest: Status code from analytics is not 200"); throw new ProjectCommonException( ResponseCode.unableToConnect.getErrorCode(), ResponseCode.unableToConnect.getErrorMessage(), @@ -118,23 +120,23 @@ public static String contentCall(String baseURL, String apiURL, String authKey, } String result = response.getBody(); - ProjectLogger.log( - "BaseMetricsActor:makePostRequest: Response from analytics store for metrics = " + result, - LoggerEnum.INFO.name()); + logger.info(null, + "BaseMetricsActor:makePostRequest: Response from analytics store for metrics", null, new HashMap<>(){{put("result", result);}}); return result; } - public static Map getContent(String courseId) { + public static Map getContent(String courseId, List fields) { Map resMap = new HashMap<>(); Map headers = new HashMap<>(); try { - String baseContentreadUrl = ProjectUtil.getConfigValue(JsonKey.EKSTEP_BASE_URL) + "/content/v3/read/" + courseId + "?fields=status"; + String fieldsStr = StringUtils.join(fields, ","); + String baseContentreadUrl = ProjectUtil.getConfigValue(JsonKey.EKSTEP_BASE_URL) + "/content/v3/read/" + courseId + "?fields=" + fieldsStr; headers.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); headers.put(JsonKey.AUTHORIZATION, PropertiesCache.getInstance().getProperty(JsonKey.EKSTEP_AUTHORIZATION)); - ProjectLogger.log("making call for content read ==" + courseId, LoggerEnum.INFO.name()); + logger.info(null, "making call for content read ==" + courseId); String response = HttpUtil.sendGetRequest(baseContentreadUrl, headers); - ProjectLogger.log("Content read response is == " + response, LoggerEnum.INFO.name()); + logger.info(null, "Content read response", null, new HashMap<>(){{put("response", response);}}); Map data = mapper.readValue(response, Map.class); if (MapUtils.isNotEmpty(data)) { data = (Map) data.get(JsonKey.RESULT); @@ -142,15 +144,15 @@ public static Map getContent(String courseId) { Object content = data.get(JsonKey.CONTENT); resMap.put(JsonKey.CONTENT, content); }else { - ProjectLogger.log("EkStepRequestUtil:searchContent No data found", LoggerEnum.INFO.name()); + logger.info(null, "EkStepRequestUtil:searchContent No data found"); } } else { - ProjectLogger.log("EkStepRequestUtil:searchContent No data found", LoggerEnum.INFO.name()); + logger.info(null, "EkStepRequestUtil:searchContent No data found"); } } catch (IOException e) { - ProjectLogger.log("Error found during content search parse==" + e.getMessage(), e); + logger.error(null, "Error found during content search parse==" + e.getMessage(), e); } catch (UnirestException e) { - ProjectLogger.log("Error found during content search parse==" + e.getMessage(), e); + logger.error(null, "Error found during content search parse==" + e.getMessage(), e); } return resMap; } @@ -158,7 +160,7 @@ public static Map getContent(String courseId) { public static Map getCourseObjectFromEkStep( String courseId, Map headers) { - ProjectLogger.log("Requested course id is ==" + courseId, LoggerEnum.INFO.name()); + logger.info(null, "Requested course id is ==" + courseId); if (!StringUtils.isBlank(courseId)) { try { String query = EKSTEP_COURSE_SEARCH_QUERY.replaceAll("COURSE_ID_PLACEHOLDER", courseId); @@ -167,15 +169,32 @@ public static Map getCourseObjectFromEkStep( return ((List>) result.get(JsonKey.CONTENTS)).get(0); // return (Map) contentObject; } else { - ProjectLogger.log( + logger.info(null, "CourseEnrollmentActor:getCourseObjectFromEkStep: Content not found for requested courseId " - + courseId, - LoggerEnum.INFO.name()); + + courseId); } } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } } return null; } + + public static boolean updateCollection(RequestContext requestContext, String collectionId, Map data) { + String response = ""; + try { + String contentUpdateBaseUrl = ProjectUtil.getConfigValue(JsonKey.LEARNING_SERVICE_BASE_URL); + Request request = new Request(); + request.put("content", data); + response = + HttpUtil.sendPatchRequest( + contentUpdateBaseUrl + + PropertiesCache.getInstance().getProperty(JsonKey.EKSTEP_CONTENT_UPDATE_URL) + + collectionId, JsonUtil.serialize(request), + headerMap); + } catch (Exception e) { + logger.error(requestContext, "Error while doing system update to collection " + e.getMessage(), e); + } + return JsonKey.SUCCESS.equalsIgnoreCase(response); + } } diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/CustomDateSerializer.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/CustomDateSerializer.java new file mode 100644 index 000000000..d9085c980 --- /dev/null +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/CustomDateSerializer.java @@ -0,0 +1,62 @@ +package org.sunbird.learner.util; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.util.TokenBuffer; +import org.sunbird.common.models.util.JsonKey; +import org.sunbird.common.models.util.LoggerUtil; +import org.sunbird.common.models.util.ProjectUtil; +import org.sunbird.models.course.batch.CourseBatch; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +public class CustomDateSerializer extends JsonSerializer { + private SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSSZ"); + private SimpleDateFormat sd2 = new SimpleDateFormat("yyyy-MM-dd"); + private List dateOnlyFormat = JsonKey.CHANGE_IN_DATE_FORMAT; + private List setEndOfDay = JsonKey.SET_END_OF_DAY; + public LoggerUtil logger = new LoggerUtil(this.getClass()); + + public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException { + TokenBuffer buffer = (TokenBuffer) jgen; + ObjectCodec codec = buffer.getCodec(); + buffer.setCodec(null); + if (((CourseBatch) jgen.getCurrentValue()).getConvertDateAsString() != null && ((CourseBatch) jgen.getCurrentValue()).getConvertDateAsString()) { + if (dateOnlyFormat.contains(jgen.getOutputContext().getCurrentName())) + buffer.writeObject(sd2.format(value)); + else + buffer.writeObject(sd.format(value)); + } else { + value = setEndOfDay(value, jgen); + buffer.writeObject(value); + } + buffer.setCodec(codec); + } + + public Date setEndOfDay(Date value, JsonGenerator jgen) { + try { + if (setEndOfDay.contains(jgen.getOutputContext().getCurrentName())) { + Calendar cal = + Calendar.getInstance( + TimeZone.getTimeZone(ProjectUtil.getConfigValue(JsonKey.SUNBIRD_TIMEZONE))); + cal.setTime(sd2.parse(sd2.format(value))); + cal.set(Calendar.HOUR_OF_DAY, 23); + cal.set(Calendar.MINUTE, 59); + cal.set(Calendar.SECOND, 59); + cal.set(Calendar.MILLISECOND, 999); + return cal.getTime(); + } + } catch (ParseException e) { + logger.error(null, "CustomDateSerializer:setEndOfDay: Exception occurred with message = " + e.getMessage(), e); + } + return value; + } +} diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/Util.java b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/Util.java index 8f2d307c5..168111449 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/Util.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/learner/util/Util.java @@ -46,7 +46,7 @@ private Util() {} /** This method will initialize the cassandra data base property */ private static void initializeDBProperty() { dbInfoMap.put( - JsonKey.LEARNER_COURSE_DB, getDbInfoObject(COURSE_KEY_SPACE_NAME, "user_courses")); + JsonKey.LEARNER_COURSE_DB, getDbInfoObject(COURSE_KEY_SPACE_NAME, "user_enrolments")); dbInfoMap.put( JsonKey.LEARNER_CONTENT_DB, getDbInfoObject(COURSE_KEY_SPACE_NAME, "user_content_consumption")); dbInfoMap.put( @@ -69,6 +69,7 @@ private static void initializeDBProperty() { JsonKey.GROUP_ACTIVITY_DB, getDbInfoObject(COURSE_KEY_SPACE_NAME, "user_activity_agg")); dbInfoMap.put( JsonKey.ASSESSMENT_AGGREGATOR_DB, getDbInfoObject(COURSE_KEY_SPACE_NAME, "assessment_aggregator")); + dbInfoMap.put(JsonKey.USER_ENROLMENTS_DB, getDbInfoObject(COURSE_KEY_SPACE_NAME, "user_enrolments")); } /** @@ -342,7 +343,7 @@ public static boolean isNotNull(Object obj) { return null != obj ? true : false; } - public static void initializeContext(Request actorMessage, String env) { + public static void initializeContext(Request actorMessage, String env, String log_env) { Map requestContext = null; if ((actorMessage.getContext().get(JsonKey.TELEMETRY_CONTEXT) != null)) { // means request context is already set by some other actor ... @@ -370,6 +371,9 @@ public static void initializeContext(Request actorMessage, String env) { requestContext.put(JsonKey.X_AUTH_TOKEN, getKeyFromContext(JsonKey.X_AUTH_TOKEN, actorMessage)); actorMessage.getContext().putAll(requestContext); + if (actorMessage.getRequestContext() != null) + actorMessage.getRequestContext().setEnv(log_env); + // and global context will be set at the time of creation of thread local // automatically ... } @@ -380,6 +384,7 @@ public static String getKeyFromContext(String key, Request actorMessage) { ? (String) actorMessage.getContext().get(key) : ""; } + } @FunctionalInterface diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/models/course/batch/CourseBatch.java b/course-mw/course-actors-common/src/main/java/org/sunbird/models/course/batch/CourseBatch.java index 8af9c29df..21798fc9b 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/models/course/batch/CourseBatch.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/models/course/batch/CourseBatch.java @@ -3,9 +3,13 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import java.io.Serializable; +import java.util.Date; import java.util.List; import java.util.Map; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.sunbird.common.models.util.ProjectUtil; +import org.sunbird.learner.util.CustomDateSerializer; @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) @@ -16,26 +20,37 @@ public class CourseBatch implements Serializable { private String courseCreator; private String courseId; private String createdBy; - private String createdDate; - private List createdFor; - private String description; - @JsonInclude(JsonInclude.Include.ALWAYS) - private String endDate; + private String oldCreatedDate; + private String oldEndDate; + private String oldEnrollmentEndDate; + private String oldStartDate; + private String oldUpdatedDate; + + @JsonSerialize(using = CustomDateSerializer.class) + private Date createdDate; + @JsonSerialize(using = CustomDateSerializer.class) + private Date endDate; + @JsonSerialize(using = CustomDateSerializer.class) + private Date enrollmentEndDate; + @JsonSerialize(using = CustomDateSerializer.class) + private Date updatedDate; + @JsonSerialize(using = CustomDateSerializer.class) + private Date startDate; - @JsonInclude(JsonInclude.Include.ALWAYS) - private String enrollmentEndDate; + private List createdFor; + private String description; private String enrollmentType; private String hashTagId; private List mentors; private String name; - private String startDate; + private Integer status; - private String updatedDate; - private Map cert_templates; + private Map certTemplates; + private Boolean convertDateAsString; public String getCourseCreator() { return courseCreator; @@ -61,11 +76,11 @@ public void setCreatedBy(String createdBy) { this.createdBy = createdBy; } - public String getCreatedDate() { + public Date getCreatedDate() { return createdDate; } - public void setCreatedDate(String createdDate) { + public void setCreatedDate(Date createdDate) { this.createdDate = createdDate; } @@ -85,11 +100,11 @@ public void setDescription(String description) { this.description = description; } - public String getEndDate() { + public Date getEndDate() { return endDate; } - public void setEndDate(String endDate) { + public void setEndDate(Date endDate) { this.endDate = endDate; } @@ -101,11 +116,11 @@ public void setEnrollmentType(String enrollmentType) { this.enrollmentType = enrollmentType; } - public String getEnrollmentEndDate() { + public Date getEnrollmentEndDate() { return enrollmentEndDate; } - public void setEnrollmentEndDate(String enrollmentEndDate) { + public void setEnrollmentEndDate(Date enrollmentEndDate) { this.enrollmentEndDate = enrollmentEndDate; } @@ -133,11 +148,9 @@ public void setName(String name) { this.name = name; } - public String getStartDate() { - return startDate; - } + public Date getStartDate() { return startDate; } - public void setStartDate(String startDate) { + public void setStartDate(Date startDate) { this.startDate = startDate; } @@ -149,17 +162,18 @@ public void setStatus(int status) { this.status = status; } - public String getUpdatedDate() { + public Date getUpdatedDate() { return updatedDate; } - public void setUpdatedDate(String updatedDate) { + public void setUpdatedDate(Date updatedDate) { this.updatedDate = updatedDate; } public void setContentDetails(Map contentDetails, String createdBy) { this.setCreatedBy(createdBy); - this.setCreatedDate(ProjectUtil.getFormattedDate()); + this.setOldCreatedDate(ProjectUtil.getFormattedDate()); + this.setCreatedDate(new Date()); } public String getBatchId() { @@ -170,8 +184,49 @@ public void setBatchId(String batchId) { this.batchId = batchId; } - public Map getCert_templates() { - return cert_templates; + public Map getCertTemplates() { + return certTemplates; + } + + public Map setCertTemplates(Map certTemplates) { + return this.certTemplates = certTemplates; + } + + public Boolean getConvertDateAsString() { + return this.convertDateAsString; } + public void setConvertDateAsString(boolean convert) { + this.convertDateAsString = convert; + } + + // After deprecating the text dates remove the below + public String getOldCreatedDate() { + return oldCreatedDate; + } + public void setOldCreatedDate(String createdDate) { + this.oldCreatedDate = createdDate; + } + public String getOldEndDate() { + return oldEndDate; + } + public void setOldEndDate(String endDate) { + this.oldEndDate = endDate; + } + public String getOldEnrollmentEndDate() { + return oldEnrollmentEndDate; + } + public void setOldEnrollmentEndDate(String enrollmentEndDate) { + this.oldEnrollmentEndDate = enrollmentEndDate; + } + public String getOldStartDate() { return oldStartDate; } + public void setOldStartDate(String startDate) { + this.oldStartDate = startDate; + } + public String getOldUpdatedDate() { + return oldUpdatedDate; + } + public void setOldUpdatedDate(String updatedDate) { + this.oldUpdatedDate = updatedDate; + } } diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/models/user/courses/UserCourses.java b/course-mw/course-actors-common/src/main/java/org/sunbird/models/user/courses/UserCourses.java index 9481d9b03..56a9d000d 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/models/user/courses/UserCourses.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/models/user/courses/UserCourses.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import java.io.Serializable; +import java.util.Date; @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) @@ -14,7 +15,7 @@ public class UserCourses implements Serializable { private String batchId; private String courseId; private String delta; - private String enrolledDate; + private Date enrolledDate; private String grade; private String datetime; private String lastReadContentId; @@ -64,11 +65,11 @@ public void setDelta(String delta) { this.delta = delta; } - public String getEnrolledDate() { + public Date getEnrolledDate() { return enrolledDate; } - public void setEnrolledDate(String enrolledDate) { + public void setEnrolledDate(Date enrolledDate) { this.enrolledDate = enrolledDate; } diff --git a/course-mw/course-actors-common/src/main/java/org/sunbird/userorg/UserOrgServiceImpl.java b/course-mw/course-actors-common/src/main/java/org/sunbird/userorg/UserOrgServiceImpl.java index c7fff8b65..8776277ef 100644 --- a/course-mw/course-actors-common/src/main/java/org/sunbird/userorg/UserOrgServiceImpl.java +++ b/course-mw/course-actors-common/src/main/java/org/sunbird/userorg/UserOrgServiceImpl.java @@ -5,17 +5,22 @@ import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.Response; import org.sunbird.common.models.util.JsonKey; import org.sunbird.common.models.util.LoggerUtil; +import org.sunbird.common.request.RequestContext; import org.sunbird.common.responsecode.ResponseCode; import org.sunbird.common.util.KeycloakRequiredActionLinkUtil; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; +import java.util.stream.Collectors; import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.sunbird.common.exception.ProjectCommonException.throwServerErrorException; @@ -172,18 +177,16 @@ public Map getUserById(String id, String authToken) { } String relativeUrl = getConfigValue(SUNBIRD_GET_SINGLE_USER_API) + FORWARD_SLASH + id; Response response = getUserOrgResponse(relativeUrl, HttpMethod.GET, requestMap, headers); - if (response != null) { + if (response != null && ResponseCode.OK == response.getResponseCode()) { return (Map) response.get(RESPONSE); - } - return null; + } else + return new HashMap<>(); } @Override public List> getUsersByIds(List ids, String authToken) { - Map filterlist = new HashMap<>(); - filterlist.put(ID, ids); - Map requestMap = getRequestMap(filterlist); - return getUsersResponse(requestMap, authToken); + List>> futures = ids.stream().map(id -> getUserDetail(id, authToken)).collect(Collectors.toList()); + return futures.stream().map(CompletableFuture::join).filter(map -> MapUtils.isNotEmpty(map)).collect(Collectors.toList()); } @Override @@ -228,4 +231,13 @@ private List> getUsersResponse(Map requestMa } return null; } + + private CompletableFuture> getUserDetail(String userId, String authToken) { + return CompletableFuture.supplyAsync(new Supplier>() { + @Override + public Map get() { + return getUserById(userId, authToken); + } + }); + } } diff --git a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/PageManagementActorTest.java b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/PageManagementActorTest.java index cce9a148f..52e9d2718 100644 --- a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/PageManagementActorTest.java +++ b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/PageManagementActorTest.java @@ -34,6 +34,7 @@ import org.sunbird.common.models.util.ActorOperations; import org.sunbird.common.models.util.JsonKey; import org.sunbird.common.request.Request; +import org.sunbird.common.request.RequestContext; import org.sunbird.common.responsecode.ResponseCode; import org.sunbird.helper.ServiceFactory; import org.sunbird.learner.util.ContentSearchUtil; diff --git a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/SearchHandlerActorTest.java b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/SearchHandlerActorTest.java index baeb8b3fc..d4fad90c2 100644 --- a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/SearchHandlerActorTest.java +++ b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/SearchHandlerActorTest.java @@ -15,12 +15,14 @@ import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.commons.collections.CollectionUtils; +import com.mashape.unirest.http.HttpResponse; +import com.mashape.unirest.http.Unirest; +import com.mashape.unirest.http.exceptions.UnirestException; +import com.mashape.unirest.request.GetRequest; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; @@ -60,7 +62,8 @@ ServiceFactory.class, ElasticSearchRestHighImpl.class, UserCoursesDaoImpl.class, - EsClientFactory.class, HttpUtil.class, KeycloakRequiredActionLinkUtil.class , ProjectUtil.class + EsClientFactory.class, HttpUtil.class, KeycloakRequiredActionLinkUtil.class , ProjectUtil.class, + Unirest.class }) @PowerMockIgnore({"javax.management.*"}) public class SearchHandlerActorTest { @@ -171,29 +174,6 @@ public void testInvalidOperation() { assertTrue(null != exc); } - @Test - public void testGetUserSearchRequest() throws Exception { - Method method = SearchHandlerActor.class.getDeclaredMethod("getUserSearchRequest", List.class, List.class); - method.setAccessible(true); - List creatorIds = Arrays.asList("test_id1", "test_id2"); - List fields = Arrays.asList("firstName", "lastName", "id"); - String result = (String) method.invoke(actorRef.underlyingActor(), creatorIds, fields); - assertTrue(StringUtils.isNotBlank(result)); - assertTrue(result.contains("test_id1")); - assertTrue(result.contains("firstName")); - assertTrue(result.contains("filters")); - assertTrue(result.contains("fields")); - } - - @Test - public void testMakePostRequest() throws Exception { - String req = "{\"request\":{\"filters\":{\"id\":[\"test_id1\",\"test_id2\"]},\"fields\":[\"firstName\",\"lastName\",\"id\"]}}"; - Method method = SearchHandlerActor.class.getDeclaredMethod("makePostRequest", RequestContext.class, String.class, String.class); - method.setAccessible(true); - List> result = (List>) method.invoke(actorRef.underlyingActor(), null, "test_url", req); - assertTrue(CollectionUtils.isNotEmpty(result)); - } - @Test public void testPopulateCreatorDetails() throws Exception { Map input = new HashMap(){{ @@ -201,7 +181,7 @@ public void testPopulateCreatorDetails() throws Exception { put("content", new ArrayList>(){{ add(new HashMap(){{ put("identifier", "0129889020926115845"); - put("createdBy", "0ac58586-76c9-491f-8af4-f184b3c34a67"); + put("createdBy", "8454cb21-3ce9-4e30-85b5-fade097880d8"); }}); add(new HashMap(){{ put("identifier", "0129889020926115952"); @@ -209,13 +189,34 @@ public void testPopulateCreatorDetails() throws Exception { }}); }}); }}; - Method method = SearchHandlerActor.class.getDeclaredMethod("populateCreatorDetails", RequestContext.class, Map.class); + mockResponse(); + HashMap context = new HashMap<>(){{put("JsonKey.X_AUTH_TOKEN","authToken");}}; + RequestContext requestContext = new RequestContext( "uid", "did", "sid", "appId", "appVer", "reqId", "debugEnabled", null); + Method method = SearchHandlerActor.class.getDeclaredMethod("populateCreatorDetails", Map.class, Map.class, RequestContext.class); method.setAccessible(true); - method.invoke(actorRef.underlyingActor(), null, input); + method.invoke(actorRef.underlyingActor(), context, input, requestContext); List> content = (List>) input.getOrDefault("content", new ArrayList>()); for(Map map : content){ if(StringUtils.equalsIgnoreCase("95e4942d-cbe8-477d-aebd-ad8e6de4bfc8", (String) map.get("createdBy"))) assertTrue(MapUtils.isNotEmpty((Map) map.get("creatorDetails"))); } } + private void mockResponse() throws UnirestException { + GetRequest http = Mockito.mock(GetRequest.class); + GetRequest http2 = Mockito.mock(GetRequest.class); + HttpResponse response = Mockito.mock(HttpResponse.class); + HttpResponse response2 = Mockito.mock(HttpResponse.class); + mockStatic(Unirest.class); + when(Unirest.get(Mockito.anyString())).thenReturn(http, http2); + when(http.headers(Mockito.anyMap())).thenReturn(http); + when(http2.headers(Mockito.anyMap())).thenReturn(http2); + when(http.asString()).thenReturn(response); + when(http2.asString()).thenReturn(response2); + when(response.getStatus()).thenReturn(200); + when(response2.getStatus()).thenReturn(200); + String resp1 = "{\"result\":{\"response\":{\"id\":\"8454cb21-3ce9-4e30-85b5-fade097880d8\",\"firstName\":\"FirstName1\",\"lastName\":\"LastName1\"}}}"; + String resp2 = "{\"result\":{\"response\":{\"id\":\"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"firstName\":\"FirstName2\",\"lastName\":\"LastName2\"}}}"; + when(response.getBody()).thenReturn(resp1); + when(response2.getBody()).thenReturn(resp2); + } } diff --git a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/certificate/CertificateActorTest.java b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/certificate/CertificateActorTest.java index c5bc260d4..fa86f417b 100644 --- a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/certificate/CertificateActorTest.java +++ b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/certificate/CertificateActorTest.java @@ -25,6 +25,7 @@ import org.sunbird.common.models.response.Response; import org.sunbird.common.models.util.JsonKey; import org.sunbird.common.request.Request; +import org.sunbird.common.request.RequestContext; import org.sunbird.kafka.client.InstructionEventGenerator; import org.sunbird.kafka.client.KafkaClient; import org.sunbird.learner.actors.certificate.service.CertificateActor; diff --git a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/coursebatch/service/UserCourseServiceTest.java b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/coursebatch/service/UserCourseServiceTest.java index 8dc3475e9..0e4e200f7 100644 --- a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/coursebatch/service/UserCourseServiceTest.java +++ b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/actors/coursebatch/service/UserCourseServiceTest.java @@ -68,42 +68,6 @@ public void beforeEachTest() throws Exception { userCoursesService = new UserCoursesService(); } - @Test - public void validateUserUnenrollEmptyUserCoursesTest() { - try { - userCoursesService = new UserCoursesService(); - userCoursesService.validateUserUnenroll(null, null); - } catch (ProjectCommonException e) { - Assert.assertEquals(ResponseCode.userNotEnrolledCourse.getErrorCode(), e.getCode()); - } - } - - @Test - public void validateUserUnenrollAlreadyUnrolledTest() { - try { - UserCourses userCourses = new UserCourses(); - userCourses.setActive(false); - userCoursesService = new UserCoursesService(); - userCoursesService.validateUserUnenroll(null, userCourses); - } catch (ProjectCommonException e) { - Assert.assertEquals(ResponseCode.userNotEnrolledCourse.getErrorCode(), e.getCode()); - } - } - - @Test - public void validateUserUnenrollAlreadyCompletedTest() { - try { - UserCourses userCourses = new UserCourses(); - userCourses.setActive(true); - // userCourses.setLeafNodesCount(1); - userCourses.setProgress(1); - userCoursesService = new UserCoursesService(); - userCoursesService.validateUserUnenroll(null, userCourses); - } catch (ProjectCommonException e) { - Assert.assertEquals(ResponseCode.userAlreadyCompletedCourse.getErrorCode(), e.getCode()); - } - } - @Test public void getPrimaryKeyTest() { Assert.assertEquals( diff --git a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/util/ContentUtilTest.java b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/util/ContentUtilTest.java index 7ca7095bd..e8fc9d43b 100644 --- a/course-mw/course-actors-common/src/test/java/org/sunbird/learner/util/ContentUtilTest.java +++ b/course-mw/course-actors-common/src/test/java/org/sunbird/learner/util/ContentUtilTest.java @@ -88,7 +88,7 @@ public void contentCallFailureTest() throws IOException { public void getContentTest() throws Exception { PowerMockito.when(HttpUtil.sendGetRequest(Mockito.anyString(), Mockito.any())) .thenReturn("{\"result\":{\"content\":{\"contentType\":\"Course\",\"identifier\":\"do_1130293726460805121168\",\"languageCode\":[\"en\"],\"status\":\"Live\"}}}"); - Map result = ContentUtil.getContent("do_1130293726460805121168"); + Map result = ContentUtil.getContent("do_1130293726460805121168", null); Assert.assertNotNull(result); Assert.assertNotNull(result.get(JsonKey.CONTENT)); } diff --git a/course-mw/course-actors-common/src/test/java/org/sunbird/userorg/UserOrgServiceTest.java b/course-mw/course-actors-common/src/test/java/org/sunbird/userorg/UserOrgServiceTest.java new file mode 100644 index 000000000..eb0748193 --- /dev/null +++ b/course-mw/course-actors-common/src/test/java/org/sunbird/userorg/UserOrgServiceTest.java @@ -0,0 +1,62 @@ +package org.sunbird.userorg; + +import com.mashape.unirest.http.HttpResponse; +import com.mashape.unirest.http.Unirest; +import com.mashape.unirest.http.exceptions.UnirestException; +import com.mashape.unirest.request.GetRequest; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertTrue; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({Unirest.class}) +@PowerMockIgnore({"javax.management.*"}) +public class UserOrgServiceTest { + private UserOrgService userOrgService = UserOrgServiceImpl.getInstance(); + + @Test + public void testgetUsersByIds() throws Exception { + List ids = new ArrayList() {{ + add("8454cb21-3ce9-4e30-85b5-fade097880d8"); + add("95e4942d-cbe8-477d-aebd-ad8e6de4bfc8"); + }}; + mockResponse(); + List> content = userOrgService.getUsersByIds(ids, "authToken"); + for(Map map : content){ + if(StringUtils.equalsIgnoreCase("95e4942d-cbe8-477d-aebd-ad8e6de4bfc8", (String) map.get("id"))) + assertTrue(StringUtils.isNotEmpty((String) map.get("firstName"))); + } + } + + private void mockResponse() throws UnirestException { + GetRequest http = Mockito.mock(GetRequest.class); + GetRequest http2 = Mockito.mock(GetRequest.class); + HttpResponse response = Mockito.mock(HttpResponse.class); + HttpResponse response2 = Mockito.mock(HttpResponse.class); + mockStatic(Unirest.class); + when(Unirest.get(Mockito.anyString())).thenReturn(http, http2); + when(http.headers(Mockito.anyMap())).thenReturn(http); + when(http2.headers(Mockito.anyMap())).thenReturn(http2); + when(http.asString()).thenReturn(response); + when(http2.asString()).thenReturn(response2); + when(response.getStatus()).thenReturn(200); + when(response2.getStatus()).thenReturn(200); + String resp1 = "{\"result\":{\"response\":{\"id\":\"8454cb21-3ce9-4e30-85b5-fade097880d8\",\"firstName\":\"FirstName1\",\"lastName\":\"LastName1\"}}}"; + String resp2 = "{\"result\":{\"response\":{\"id\":\"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"firstName\":\"FirstName2\",\"lastName\":\"LastName2\"}}}"; + when(response.getBody()).thenReturn(resp1); + when(response2.getBody()).thenReturn(resp2); + } +} diff --git a/course-mw/course-actors/pom.xml b/course-mw/course-actors/pom.xml index 3d9c3222f..f729c6f7b 100644 --- a/course-mw/course-actors/pom.xml +++ b/course-mw/course-actors/pom.xml @@ -15,6 +15,16 @@ UTF-8 + + ch.qos.logback + logback-classic + 1.2.3 + + + net.logstash.logback + logstash-logback-encoder + 6.3 + org.sunbird course-actors-common diff --git a/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/bulkupload/BulkUploadBackGroundJobActor.java b/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/bulkupload/BulkUploadBackGroundJobActor.java index ebe919647..b37341727 100644 --- a/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/bulkupload/BulkUploadBackGroundJobActor.java +++ b/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/bulkupload/BulkUploadBackGroundJobActor.java @@ -54,7 +54,7 @@ public class BulkUploadBackGroundJobActor extends BaseActor { @Override public void onReceive(Request request) throws Throwable { - Util.initializeContext(request, TelemetryEnvKey.USER); + Util.initializeContext(request, TelemetryEnvKey.USER, this.getClass().getName()); if (request.getOperation().equalsIgnoreCase(ActorOperations.PROCESS_BULK_UPLOAD.getValue())) { process(request); } else { @@ -165,6 +165,7 @@ private void validateBatchUserListAndAdd( Map map = null; List createdFor = (List) courseBatchObject.get(JsonKey.COURSE_CREATED_FOR); List> userDetails = userOrgService.getUsersByIds(userIds, (String) context.getOrDefault(JsonKey.X_AUTH_TOKEN, "")); + logger.info(requestContext, "BulkUploadBackGroundJobActor::validateBatchUserListAndAdd::userDetails : " + userDetails); Map userToRootOrg = userDetails .stream() diff --git a/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/bulkupload/BulkUploadManagementActor.java b/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/bulkupload/BulkUploadManagementActor.java index f206c04f0..4b387afc0 100644 --- a/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/bulkupload/BulkUploadManagementActor.java +++ b/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/bulkupload/BulkUploadManagementActor.java @@ -53,7 +53,8 @@ public class BulkUploadManagementActor extends BaseBulkUploadActor { @Override public void onReceive(Request request) throws Throwable { - Util.initializeContext(request, TelemetryEnvKey.USER); + Util.initializeContext(request, TelemetryEnvKey.USER, this.getClass().getName()); + // set request id fto thread local... if (request.getOperation().equalsIgnoreCase(ActorOperations.BULK_UPLOAD.getValue())) { upload(request); diff --git a/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/coursebatch/CourseBatchManagementActor.java b/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/coursebatch/CourseBatchManagementActor.java index 29857ea6a..20451b4ba 100644 --- a/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/coursebatch/CourseBatchManagementActor.java +++ b/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/coursebatch/CourseBatchManagementActor.java @@ -1,11 +1,10 @@ package org.sunbird.learner.actors.coursebatch; import static org.sunbird.common.models.util.JsonKey.ID; +import static org.sunbird.common.models.util.JsonKey.NULL; import static org.sunbird.common.models.util.JsonKey.PARTICIPANTS; import akka.actor.ActorRef; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; import java.text.MessageFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -13,6 +12,7 @@ import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Named; + import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; @@ -27,6 +27,7 @@ import org.sunbird.common.request.Request; import org.sunbird.common.request.RequestContext; import org.sunbird.common.responsecode.ResponseCode; +import org.sunbird.common.util.JsonUtil; import org.sunbird.kafka.client.InstructionEventGenerator; import org.sunbird.learner.actors.coursebatch.dao.CourseBatchDao; import org.sunbird.learner.actors.coursebatch.dao.impl.CourseBatchDaoImpl; @@ -51,8 +52,6 @@ public class CourseBatchManagementActor extends BaseActor { private ElasticSearchService esService = EsClientFactory.getInstance(JsonKey.REST); private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); private List validCourseStatus = Arrays.asList("Live", "Unlisted"); - private static final ObjectMapper mapper = new ObjectMapper(); - @Inject @Named("course-batch-notification-actor") @@ -66,7 +65,7 @@ public class CourseBatchManagementActor extends BaseActor { @Override public void onReceive(Request request) throws Throwable { - Util.initializeContext(request, TelemetryEnvKey.BATCH); + Util.initializeContext(request, TelemetryEnvKey.BATCH, this.getClass().getName()); String requestedOperation = request.getOperation(); switch (requestedOperation) { @@ -79,12 +78,6 @@ public void onReceive(Request request) throws Throwable { case "getBatch": getCourseBatch(request); break; - case "addUserBatch": - addUserCourseBatch(request); - break; - case "removeUserFromBatch": - removeUserCourseBatch(request); - break; case "getParticipants": getParticipants(request); break; @@ -109,21 +102,22 @@ private void createCourseBatch(Request actorMessage) throws Throwable { ProjectUtil.formatMessage( ResponseCode.invalidRequestParameter.getErrorMessage(), PARTICIPANTS)); } - CourseBatch courseBatch = new ObjectMapper().convertValue(request, CourseBatch.class); + CourseBatch courseBatch = JsonUtil.convert(request, CourseBatch.class); courseBatch.setStatus(setCourseBatchStatus(actorMessage.getRequestContext(), (String) request.get(JsonKey.START_DATE))); String courseId = (String) request.get(JsonKey.COURSE_ID); Map contentDetails = getContentDetails(actorMessage.getRequestContext(),courseId, headers); - courseBatch.setCreatedDate(ProjectUtil.getFormattedDate()); + courseBatch.setCreatedDate(ProjectUtil.getTimeStamp()); if(StringUtils.isBlank(courseBatch.getCreatedBy())) courseBatch.setCreatedBy(requestedBy); validateContentOrg(actorMessage.getRequestContext(), courseBatch.getCreatedFor()); - validateMentors(courseBatch, (String) actorMessage.getContext().getOrDefault(JsonKey.X_AUTH_TOKEN, "")); + validateMentors(courseBatch, (String) actorMessage.getContext().getOrDefault(JsonKey.X_AUTH_TOKEN, ""), actorMessage.getRequestContext()); courseBatch.setBatchId(courseBatchId); Response result = courseBatchDao.create(actorMessage.getRequestContext(), courseBatch); result.put(JsonKey.BATCH_ID, courseBatchId); + Map esCourseMap = esCourseMapping(courseBatch); CourseBatchUtil.syncCourseBatchForeground(actorMessage.getRequestContext(), - courseBatchId, new ObjectMapper().convertValue(courseBatch, Map.class)); + courseBatchId, esCourseMap); sender().tell(result, self()); targetObject = @@ -138,8 +132,7 @@ private void createCourseBatch(Request actorMessage) throws Throwable { TelemetryUtil.telemetryProcessingCall(request, targetObject, correlatedObject, actorMessage.getContext()); // updateBatchCount(courseBatch); - //Generate Instruction event. Send courseId for batch - pushInstructionEvent(actorMessage.getRequestContext(), courseId,courseBatchId); + updateCollection(actorMessage.getRequestContext(), esCourseMap, contentDetails); if (courseNotificationActive()) { batchOperationNotifier(actorMessage, courseBatch, null); } @@ -183,6 +176,9 @@ private void updateCourseBatch(Request actorMessage) throws Exception { Map participantsMap = new HashMap<>(); List> correlatedObject = new ArrayList<>(); + Map headers = + (Map) actorMessage.getContext().get(JsonKey.HEADER); + String requestedBy = (String) actorMessage.getContext().get(JsonKey.REQUESTED_BY); Map request = actorMessage.getRequest(); if (Util.isNotNull(request.get(JsonKey.PARTICIPANTS))) { @@ -195,23 +191,24 @@ private void updateCourseBatch(Request actorMessage) throws Exception { request.containsKey(JsonKey.BATCH_ID) ? (String) request.get(JsonKey.BATCH_ID) : (String) request.get(JsonKey.ID); - String requestedBy = (String) actorMessage.getContext().get(JsonKey.REQUESTED_BY); CourseBatch oldBatch = courseBatchDao.readById((String) request.get(JsonKey.COURSE_ID), batchId, actorMessage.getRequestContext()); CourseBatch courseBatch = getUpdateCourseBatch(actorMessage.getRequestContext(), request); - courseBatch.setUpdatedDate(ProjectUtil.getFormattedDate()); + courseBatch.setUpdatedDate(ProjectUtil.getTimeStamp()); checkBatchStatus(courseBatch); + Map contentDetails = getContentDetails(actorMessage.getRequestContext(),courseBatch.getCourseId(), headers); validateUserPermission(courseBatch, requestedBy); validateContentOrg(actorMessage.getRequestContext(), courseBatch.getCreatedFor()); - validateMentors(courseBatch, (String) actorMessage.getContext().getOrDefault(JsonKey.X_AUTH_TOKEN, "")); + validateMentors(courseBatch, (String) actorMessage.getContext().getOrDefault(JsonKey.X_AUTH_TOKEN, ""), actorMessage.getRequestContext()); participantsMap = getMentorLists(participantsMap, oldBatch, courseBatch); - Map courseBatchMap = new ObjectMapper().convertValue(courseBatch, Map.class); + Map courseBatchMap = JsonUtil.convert(courseBatch, Map.class); Response result = courseBatchDao.update(actorMessage.getRequestContext(), (String) request.get(JsonKey.COURSE_ID), batchId, courseBatchMap); - Map updatedCourseObject = mapESFieldsToObject(courseBatchMap); + CourseBatch updatedCourseObject = mapESFieldsToObject(courseBatch); sender().tell(result, self()); + Map esCourseMap = esCourseMapping(updatedCourseObject); - CourseBatchUtil.syncCourseBatchForeground(actorMessage.getRequestContext(), batchId, updatedCourseObject); + CourseBatchUtil.syncCourseBatchForeground(actorMessage.getRequestContext(), batchId, esCourseMap); targetObject = TelemetryUtil.generateTargetObject(batchId, TelemetryEnvKey.BATCH, JsonKey.UPDATE, null); @@ -220,7 +217,7 @@ private void updateCourseBatch(Request actorMessage) throws Exception { rollUp.put("l1", courseBatch.getCourseId()); TelemetryUtil.addTargetObjectRollUp(rollUp, targetObject); TelemetryUtil.telemetryProcessingCall(courseBatchMap, targetObject, correlatedObject, actorMessage.getContext()); - pushInstructionEvent(actorMessage.getRequestContext(), (String) request.get(JsonKey.COURSE_ID),batchId); + updateCollection(actorMessage.getRequestContext(), esCourseMap, contentDetails); if (courseNotificationActive()) { batchOperationNotifier(actorMessage, courseBatch, participantsMap); } @@ -259,7 +256,7 @@ private void checkBatchStatus(CourseBatch courseBatch) { } @SuppressWarnings("unchecked") - private CourseBatch getUpdateCourseBatch(RequestContext requestContext, Map request) { + private CourseBatch getUpdateCourseBatch(RequestContext requestContext, Map request) throws Exception { CourseBatch courseBatch = courseBatchDao.readById( (String) request.get(JsonKey.COURSE_ID), (String) request.get(JsonKey.ID), requestContext); @@ -291,150 +288,6 @@ private String getEnrollmentType(String requestEnrollmentType, String dbEnrollme return dbEnrollmentType; } - @SuppressWarnings("unchecked") - private void addUserCourseBatch(Request actorMessage) { - Map req = actorMessage.getRequest(); - Response response = new Response(); - - Map targetObject = null; - List> correlatedObject = new ArrayList<>(); - - String batchId = (String) req.get(JsonKey.BATCH_ID); - TelemetryUtil.generateCorrelatedObject(batchId, TelemetryEnvKey.BATCH, null, correlatedObject); - Map courseBatchObject = getValidatedCourseBatch(actorMessage.getRequestContext(), batchId); - String batchCreator = (String) courseBatchObject.get(JsonKey.CREATED_BY); - String batchCreatorRootOrgId = getRootOrg(batchCreator, (String) actorMessage.getContext().getOrDefault(JsonKey.X_AUTH_TOKEN, "")); - List participants = - userCoursesService.getEnrolledUserFromBatch( - actorMessage.getRequestContext(), (String) courseBatchObject.get(JsonKey.BATCH_ID)); - CourseBatch courseBatch = new ObjectMapper().convertValue(courseBatchObject, CourseBatch.class); - List userIds = (List) req.get(JsonKey.USER_IDs); - if (participants == null) { - participants = new ArrayList<>(); - } - Map participantWithRootOrgIds = getRootOrgForMultipleUsers(userIds, (String) actorMessage.getContext().getOrDefault(JsonKey.X_AUTH_TOKEN, "")); - List addedParticipants = new ArrayList<>(); - for (String userId : userIds) { - if (!(participants.contains(userId))) { - if (!participantWithRootOrgIds.containsKey(userId) - || (!batchCreatorRootOrgId.equals(participantWithRootOrgIds.get(userId)))) { - response.put( - userId, - MessageFormat.format( - ResponseCode.userNotAssociatedToRootOrg.getErrorMessage(), userId)); - continue; - } - addedParticipants.add(userId); - - } else { - response.getResult().put(userId, JsonKey.SUCCESS); - } - } - - userCoursesService.enroll( - actorMessage.getRequestContext(), batchId, (String) courseBatchObject.get(JsonKey.COURSE_ID), addedParticipants); - for (String userId : addedParticipants) { - participants.add(userId); - response.getResult().put(userId, JsonKey.SUCCESS); - - targetObject = - TelemetryUtil.generateTargetObject(userId, TelemetryEnvKey.USER, JsonKey.UPDATE, null); - correlatedObject = new ArrayList<>(); - TelemetryUtil.generateCorrelatedObject( - batchId, TelemetryEnvKey.BATCH, null, correlatedObject); - TelemetryUtil.telemetryProcessingCall(req, targetObject, correlatedObject, actorMessage.getContext()); - } - sender().tell(response, self()); - if (courseNotificationActive()) { - Map participantMentorMap = new HashMap<>(); - participantMentorMap.put(JsonKey.ADDED_PARTICIPANTS, addedParticipants); - batchOperationNotifier(actorMessage, courseBatch, participantMentorMap); - } - } - - @SuppressWarnings("unchecked") - private void removeUserCourseBatch(Request actorMessage) { - Map req = actorMessage.getRequest(); - Response response = new Response(); - - Map targetObject = null; - List> correlatedObject = new ArrayList<>(); - - String batchId = (String) req.get(JsonKey.BATCH_ID); - TelemetryUtil.generateCorrelatedObject(batchId, TelemetryEnvKey.BATCH, null, correlatedObject); - Map courseBatchObject = getValidatedCourseBatch(actorMessage.getRequestContext(), batchId); - List participants = - userCoursesService.getEnrolledUserFromBatch( - actorMessage.getRequestContext(), (String) courseBatchObject.get(JsonKey.BATCH_ID)); - CourseBatch courseBatch = new ObjectMapper().convertValue(courseBatchObject, CourseBatch.class); - List userIds = (List) req.get(JsonKey.USER_IDs); - if (participants == null) { - participants = new ArrayList<>(); - } - List participantsList = - CollectionUtils.isEmpty(participants) ? new ArrayList<>() : participants; - List removedParticipants = new ArrayList<>(); - userIds.forEach( - id -> { - if (!participantsList.contains(id)) { - response.getResult().put(id, ResponseCode.userNotEnrolledCourse.getErrorMessage()); - } else { - try { - userCoursesService.unenroll(actorMessage.getRequestContext(), batchId, id); - removedParticipants.add(id); - response.getResult().put(id, JsonKey.SUCCESS); - } catch (ProjectCommonException ex) { - response.getResult().put(id, ex.getMessage()); - } - } - }); - - for (String userId : removedParticipants) { - targetObject = - TelemetryUtil.generateTargetObject(userId, TelemetryEnvKey.USER, JsonKey.REMOVE, null); - correlatedObject = new ArrayList<>(); - TelemetryUtil.generateCorrelatedObject( - batchId, TelemetryEnvKey.BATCH, null, correlatedObject); - TelemetryUtil.telemetryProcessingCall(req, targetObject, correlatedObject, actorMessage.getContext()); - } - sender().tell(response, self()); - if (courseNotificationActive()) { - Map participantMentorMap = new HashMap<>(); - participantMentorMap.put(JsonKey.REMOVED_PARTICIPANTS, removedParticipants); - batchOperationNotifier(actorMessage, courseBatch, participantMentorMap); - } - } - - private Map getValidatedCourseBatch(RequestContext requestContext, String batchId) { - Future> resultF = - esService.getDataByIdentifier(requestContext, ProjectUtil.EsType.courseBatch.getTypeName(), batchId); - Map courseBatchObject = - (Map) ElasticSearchHelper.getResponseFromFuture(resultF); - - if (ProjectUtil.isNull(courseBatchObject.get(JsonKey.ENROLLMENT_TYPE)) - || !((String) courseBatchObject.get(JsonKey.ENROLLMENT_TYPE)) - .equalsIgnoreCase(JsonKey.INVITE_ONLY)) { - throw new ProjectCommonException( - ResponseCode.enrollmentTypeValidation.getErrorCode(), - ResponseCode.enrollmentTypeValidation.getErrorMessage(), - ResponseCode.CLIENT_ERROR.getResponseCode()); - } - if (CollectionUtils.isEmpty((List) courseBatchObject.get(JsonKey.COURSE_CREATED_FOR))) { - throw new ProjectCommonException( - ResponseCode.courseCreatedForIsNull.getErrorCode(), - ResponseCode.courseCreatedForIsNull.getErrorMessage(), - ResponseCode.RESOURCE_NOT_FOUND.getResponseCode()); - } - String batchCreator = (String) courseBatchObject.get(JsonKey.CREATED_BY); - if (StringUtils.isBlank(batchCreator)) { - throw new ProjectCommonException( - ResponseCode.invalidCourseCreatorId.getErrorCode(), - ResponseCode.invalidCourseCreatorId.getErrorMessage(), - ResponseCode.RESOURCE_NOT_FOUND.getResponseCode()); - } - return courseBatchObject; - } - private void getCourseBatch(Request actorMessage) { Future> resultF = esService.getDataByIdentifier( @@ -449,45 +302,6 @@ private void getCourseBatch(Request actorMessage) { sender().tell(response, self()); } - private void pushInstructionEvent(RequestContext requestContext, String courseId, String batchId) - throws Exception { - Map data = new HashMap<>(); - - data.put( - CourseJsonKey.ACTOR, - new HashMap() { - { - put(JsonKey.ID, InstructionEvent.COURSE_BATCH_UPDATE.getActorId()); - put(JsonKey.TYPE, InstructionEvent.COURSE_BATCH_UPDATE.getActorType()); - } - }); - - data.put( - CourseJsonKey.OBJECT, - new HashMap() { - { - put(JsonKey.ID, courseId + CourseJsonKey.UNDERSCORE + batchId); - put(JsonKey.TYPE, InstructionEvent.COURSE_BATCH_UPDATE.getType()); - } - }); - - data.put(CourseJsonKey.ACTION, InstructionEvent.COURSE_BATCH_UPDATE.getAction()); - - data.put( - CourseJsonKey.E_DATA, - new HashMap() { - { - put(JsonKey.COURSE_ID, courseId); - put(JsonKey.BATCH_ID, batchId); - put(CourseJsonKey.ACTION, InstructionEvent.COURSE_BATCH_UPDATE.getAction()); - put(CourseJsonKey.ITERATION, 1); - } - }); - String topic = ProjectUtil.getConfigValue("kafka_topics_instruction"); - logger.info(requestContext, "CourseBatchManagementctor: pushInstructionEvent :Event Data " - + data+" and Topic "+topic); - InstructionEventGenerator.pushInstructionEvent(batchId, topic, data); - } private int setCourseBatchStatus(RequestContext requestContext, String startDate) { try { @@ -506,36 +320,42 @@ private int setCourseBatchStatus(RequestContext requestContext, String startDate return ProgressStatus.NOT_STARTED.getValue(); } - private void validateMentors(CourseBatch courseBatch, String authToken) { + private void validateMentors(CourseBatch courseBatch, String authToken, RequestContext requestContext) { List mentors = courseBatch.getMentors(); if (CollectionUtils.isNotEmpty(mentors)) { + mentors = mentors.stream().distinct().collect(Collectors.toList()); + courseBatch.setMentors(mentors); String batchCreatorRootOrgId = getRootOrg(courseBatch.getCreatedBy(), authToken); List> mentorDetailList = userOrgService.getUsersByIds(mentors, authToken); - Map> mentorDetails = - mentorDetailList - .stream() - .collect(Collectors.toMap(map -> (String) map.get(JsonKey.ID), map -> map)); - for (String userId : mentors) { - Map result = mentorDetails.get(userId); - String mentorRootOrgId = getRootOrgFromUserMap(result); - if (!batchCreatorRootOrgId.equals(mentorRootOrgId)) { - throw new ProjectCommonException( - ResponseCode.userNotAssociatedToRootOrg.getErrorCode(), - ResponseCode.userNotAssociatedToRootOrg.getErrorMessage(), - ResponseCode.CLIENT_ERROR.getResponseCode(), - userId); - } - if ((ProjectUtil.isNull(result)) - || (ProjectUtil.isNotNull(result) && result.isEmpty()) - || (ProjectUtil.isNotNull(result) - && result.containsKey(JsonKey.IS_DELETED) - && ProjectUtil.isNotNull(result.get(JsonKey.IS_DELETED)) - && (Boolean) result.get(JsonKey.IS_DELETED))) { - throw new ProjectCommonException( - ResponseCode.invalidUserId.getErrorCode(), - ResponseCode.invalidUserId.getErrorMessage(), - ResponseCode.CLIENT_ERROR.getResponseCode()); + logger.info(requestContext, "CourseBatchManagementActor::validateMentors::mentorDetailList : " + mentorDetailList); + if(CollectionUtils.isNotEmpty(mentorDetailList)){ + Map> mentorDetails = + mentorDetailList.stream().collect(Collectors.toMap(map -> (String) map.get(JsonKey.ID), map -> map)); + + for(String mentorId: mentors) { + Map result = mentorDetails.getOrDefault(mentorId, new HashMap<>()); + if(MapUtils.isEmpty(result) || (result.containsKey(JsonKey.IS_DELETED) && (Boolean) result.get(JsonKey.IS_DELETED))) { + throw new ProjectCommonException( + ResponseCode.invalidUserId.getErrorCode(), + ResponseCode.invalidUserId.getErrorMessage(), + ResponseCode.CLIENT_ERROR.getResponseCode()); + } else { + String mentorRootOrgId = getRootOrgFromUserMap(result); + if (!batchCreatorRootOrgId.equals(mentorRootOrgId)) { + throw new ProjectCommonException( + ResponseCode.userNotAssociatedToRootOrg.getErrorCode(), + ResponseCode.userNotAssociatedToRootOrg.getErrorMessage(), + ResponseCode.CLIENT_ERROR.getResponseCode(), + mentorId); + } + } } + } else { + logger.info( requestContext,"Invalid mentors for batchId: " + courseBatch.getBatchId() +", mentors: " + mentors); + throw new ProjectCommonException( + ResponseCode.invalidUserId.getErrorCode(), + ResponseCode.invalidUserId.getErrorMessage(), + ResponseCode.CLIENT_ERROR.getResponseCode()); } } } @@ -557,8 +377,8 @@ private List getUpdatedCreatedFor( } @SuppressWarnings("unchecked") - private void updateCourseBatchDate(RequestContext requestContext, CourseBatch courseBatch, Map req) { - Map courseBatchMap = new ObjectMapper().convertValue(courseBatch, Map.class); + private void updateCourseBatchDate(RequestContext requestContext, CourseBatch courseBatch, Map req) throws Exception { + Map courseBatchMap = JsonUtil.convert(courseBatch, Map.class); Date todayDate = getDate(requestContext, null, DATE_FORMAT, null); Date dbBatchStartDate = getDate(requestContext, JsonKey.START_DATE, DATE_FORMAT, courseBatchMap); Date dbBatchEndDate = getDate(requestContext, JsonKey.END_DATE, DATE_FORMAT, courseBatchMap); @@ -567,6 +387,11 @@ private void updateCourseBatchDate(RequestContext requestContext, CourseBatch co Date requestedEndDate = getDate(requestContext, JsonKey.END_DATE, DATE_FORMAT, req); Date requestedEnrollmentEndDate = getDate(requestContext, JsonKey.ENROLLMENT_END_DATE, DATE_FORMAT, req); + // After deprecating the text date remove below + dbBatchStartDate = dbBatchStartDate == null ? getDate(requestContext, JsonKey.OLD_START_DATE, DATE_FORMAT, courseBatchMap) : dbBatchStartDate; + dbBatchEndDate = dbBatchEndDate == null ? getDate(requestContext, JsonKey.OLD_END_DATE, DATE_FORMAT, courseBatchMap) : dbBatchEndDate; + dbEnrollmentEndDate = dbEnrollmentEndDate == null ? getDate(requestContext, JsonKey.OLD_ENROLLMENT_END_DATE, DATE_FORMAT, courseBatchMap) : dbEnrollmentEndDate; + validateUpdateBatchStartDate(requestedStartDate); validateBatchStartAndEndDate( dbBatchStartDate, dbBatchEndDate, requestedStartDate, requestedEndDate, todayDate); @@ -583,11 +408,17 @@ private void updateCourseBatchDate(RequestContext requestContext, CourseBatch co requestedEnrollmentEndDate, todayDate); courseBatch.setStartDate( - requestedStartDate != null - ? (String) req.get(JsonKey.START_DATE) - : courseBatch.getStartDate()); - courseBatch.setEndDate((String) req.get(JsonKey.END_DATE)); - courseBatch.setEnrollmentEndDate((String) req.get(JsonKey.ENROLLMENT_END_DATE)); + requestedStartDate != null + ? DATE_FORMAT.parse((String) req.get(JsonKey.START_DATE)) + : courseBatch.getStartDate()); + courseBatch.setEndDate( + requestedEndDate != null + ? DATE_FORMAT.parse((String) req.get(JsonKey.END_DATE)) + : courseBatch.getEndDate()); + courseBatch.setEnrollmentEndDate( + requestedEnrollmentEndDate != null + ? DATE_FORMAT.parse((String) req.get(JsonKey.ENROLLMENT_END_DATE)) + : courseBatch.getEnrollmentEndDate()); } private void validateUserPermission(CourseBatch courseBatch, String requestedBy) { @@ -604,21 +435,6 @@ private void validateUserPermission(CourseBatch courseBatch, String requestedBy) } } - @SuppressWarnings("unchecked") - private Map getRootOrgForMultipleUsers(List userIds, String authToken) { - - List> userlist = userOrgService.getUsersByIds(userIds, authToken); - Map userWithRootOrgs = new HashMap<>(); - if (CollectionUtils.isNotEmpty(userlist)) { - userlist.forEach( - user -> { - String rootOrg = getRootOrgFromUserMap(user); - userWithRootOrgs.put((String) user.get(JsonKey.ID), rootOrg); - }); - } - return userWithRootOrgs; - } - private String getRootOrg(String batchCreator, String authToken) { Map userInfo = userOrgService.getUserById(batchCreator, authToken); @@ -702,9 +518,15 @@ private Date getDate(RequestContext requestContext, String key, SimpleDateFormat if (MapUtils.isEmpty(map)) { return format.parse(format.format(new Date())); } else { - if (StringUtils.isNotBlank((String) map.get(key))) { - Date d = format.parse((String) map.get(key)); - if (key.equals(JsonKey.END_DATE) || key.equals(JsonKey.ENROLLMENT_END_DATE)) { + if (map.get(key) != null) { + Date d; + if (map.get(key) instanceof Date) { + d = format.parse(format.format(map.get(key))); + } else { + d = format.parse((String) map.get(key)); + } + if (key.equalsIgnoreCase(JsonKey.END_DATE) || key.equalsIgnoreCase(JsonKey.ENROLLMENT_END_DATE) || + key.equalsIgnoreCase(JsonKey.OLD_END_DATE) || key.equalsIgnoreCase(JsonKey.OLD_ENROLLMENT_END_DATE)) { Calendar cal = Calendar.getInstance( TimeZone.getTimeZone(ProjectUtil.getConfigValue(JsonKey.SUNBIRD_TIMEZONE))); @@ -772,9 +594,9 @@ private boolean isOrgValid(RequestContext requestContext, String orgId) { } private Map getContentDetails(RequestContext requestContext, String courseId, Map headers) { - Map ekStepContent = ContentUtil.getContent(courseId); - logger.info(requestContext, "CourseBatchManagementActor:getEkStepContent: courseId: " + courseId, - " :: content: " + ekStepContent); + Map ekStepContent = ContentUtil.getContent(courseId, Arrays.asList("status", "batches")); + logger.info(requestContext, "CourseBatchManagementActor:getEkStepContent: courseId: " + courseId, null, + ekStepContent); String status = (String) ((Map)ekStepContent.getOrDefault("content", new HashMap<>())).getOrDefault("status", ""); if (null == ekStepContent || ekStepContent.size() == 0 || @@ -823,10 +645,8 @@ private void getParticipants(Request actorMessage) { sender().tell(response, self()); } - private Map mapESFieldsToObject(Map courseBatch) { - Map> certificateTemplates = - (Map>) - courseBatch.get(CourseJsonKey.CERTIFICATE_TEMPLATES_COLUMN); + private CourseBatch mapESFieldsToObject(CourseBatch courseBatch) { + Map certificateTemplates = courseBatch.getCertTemplates(); if(MapUtils.isNotEmpty(certificateTemplates)) { certificateTemplates .entrySet() @@ -834,8 +654,8 @@ private Map mapESFieldsToObject(Map courseBatch) .forEach( cert_template -> certificateTemplates.put( - cert_template.getKey(), mapToObject(cert_template.getValue()))); - courseBatch.put(CourseJsonKey.CERTIFICATE_TEMPLATES_COLUMN, certificateTemplates); + cert_template.getKey(), mapToObject((Map) cert_template.getValue()))); + courseBatch.setCertTemplates(certificateTemplates); } return courseBatch; } @@ -844,37 +664,63 @@ private Map mapToObject(Map template) { try { template.put( JsonKey.CRITERIA, - mapper.readValue( - (String) template.get(JsonKey.CRITERIA), - new TypeReference>() {})); + JsonUtil.deserialize((String) template.get(JsonKey.CRITERIA), Map.class)); if(StringUtils.isNotEmpty((String)template.get(CourseJsonKey.SIGNATORY_LIST))) { template.put( CourseJsonKey.SIGNATORY_LIST, - mapper.readValue( - (String) template.get(CourseJsonKey.SIGNATORY_LIST), - new TypeReference>() { - })); + JsonUtil.deserialize((String) template.get(CourseJsonKey.SIGNATORY_LIST), ArrayList.class)); } if(StringUtils.isNotEmpty((String)template.get(CourseJsonKey.ISSUER))) { template.put( CourseJsonKey.ISSUER, - mapper.readValue( - (String) template.get(CourseJsonKey.ISSUER), - new TypeReference>() { - })); + JsonUtil.deserialize((String) template.get(CourseJsonKey.ISSUER), Map.class)); } if(StringUtils.isNotEmpty((String)template.get(CourseJsonKey.NOTIFY_TEMPLATE))) { template.put( CourseJsonKey.NOTIFY_TEMPLATE, - mapper.readValue( - (String) template.get(CourseJsonKey.NOTIFY_TEMPLATE), - new TypeReference>() { - })); + JsonUtil.deserialize((String) template.get(CourseJsonKey.NOTIFY_TEMPLATE), Map.class)); } } catch (Exception ex) { - ProjectLogger.log( - "CourseBatchCertificateActor:mapToObject Exception occurred with error message ==", ex); + logger.error(null, "CourseBatchCertificateActor:mapToObject Exception occurred with error message ==", ex); } return template; } + + private void updateCollection(RequestContext requestContext, Map courseBatch, Map contentDetails) { + List> batches = (List>) contentDetails.getOrDefault("batches", new ArrayList<>()); + Map data = new HashMap<>(); + data.put("batchId", courseBatch.getOrDefault(JsonKey.BATCH_ID, "")); + data.put("name", courseBatch.getOrDefault(JsonKey.NAME, "")); + data.put("createdFor", courseBatch.getOrDefault(JsonKey.COURSE_CREATED_FOR, "")); + data.put("startDate", courseBatch.getOrDefault(JsonKey.START_DATE, "")); + data.put("endDate", courseBatch.getOrDefault(JsonKey.END_DATE, null)); + data.put("enrollmentType", courseBatch.getOrDefault(JsonKey.ENROLLMENT_TYPE, "")); + data.put("status", courseBatch.getOrDefault(JsonKey.STATUS, "")); + data.put("enrollmentEndDate", getEnrollmentEndDate((String) courseBatch.getOrDefault(JsonKey.ENROLLMENT_END_DATE, null), (String) courseBatch.getOrDefault(JsonKey.END_DATE, null))); + batches.removeIf(map -> StringUtils.equalsIgnoreCase((String) courseBatch.getOrDefault(JsonKey.BATCH_ID, ""), (String) map.get("batchId"))); + batches.add(data); + ContentUtil.updateCollection(requestContext, (String) courseBatch.getOrDefault(JsonKey.COURSE_ID, ""), new HashMap() {{ put("batches", batches);}}); + } + + private Object getEnrollmentEndDate(String enrollmentEndDate, String endDate) { + return Optional.ofNullable(enrollmentEndDate).map(x -> x).orElse(Optional.ofNullable(endDate).map(y ->{ + Calendar cal = Calendar.getInstance(); + try { + cal.setTime(DATE_FORMAT.parse(y)); + cal.add(Calendar.DAY_OF_MONTH, -1); + return DATE_FORMAT.format(cal.getTime()); + } catch (ParseException e) { + return null; + } + }).orElse(null)); + } + + // Remove the implementation after fixing the customDateSerializer + private Map esCourseMapping(CourseBatch courseBatch) throws Exception{ + courseBatch.setConvertDateAsString(true); + Map esCourseMap = JsonUtil.convert(courseBatch, Map.class); + esCourseMap.remove(JsonKey.CONVERT_DATE_AS_STRING); + return esCourseMap; + } + } diff --git a/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/coursebatch/CourseBatchNotificationActor.java b/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/coursebatch/CourseBatchNotificationActor.java index 9953609ed..be0dc968f 100644 --- a/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/coursebatch/CourseBatchNotificationActor.java +++ b/course-mw/course-actors/src/main/java/org/sunbird/learner/actors/coursebatch/CourseBatchNotificationActor.java @@ -1,14 +1,13 @@ package org.sunbird.learner.actors.coursebatch; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.collections.CollectionUtils; import org.sunbird.actor.base.BaseActor; import org.sunbird.common.models.util.ActorOperations; import org.sunbird.common.models.util.JsonKey; -import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.PropertiesCache; import org.sunbird.common.request.Request; import org.sunbird.common.request.RequestContext; +import org.sunbird.common.util.JsonUtil; import org.sunbird.learner.util.ContentUtil; import org.sunbird.learner.util.CourseBatchSchedulerUtil; import org.sunbird.models.course.batch.CourseBatch; @@ -30,6 +29,8 @@ public class CourseBatchNotificationActor extends BaseActor { .getProperty(JsonKey.SUNBIRD_COURSE_BATCH_NOTIFICATION_SIGNATURE); private static String baseUrl = PropertiesCache.getInstance().getProperty(JsonKey.SUNBIRD_WEB_URL); + private static String courseBatchPath = + PropertiesCache.getInstance().getProperty(JsonKey.COURSE_BATCH_PATH); private UserOrgService userOrgService = UserOrgServiceImpl.getInstance(); @Override @@ -45,7 +46,7 @@ public void onReceive(Request request) throws Throwable { } } - private void courseBatchNotification(Request request) { + private void courseBatchNotification(Request request) throws Exception { Map requestMap = request.getRequest(); @@ -119,7 +120,7 @@ private void triggerEmailNotification( CourseBatch courseBatch, String subject, String template, - Map contentDetails, String authToken) { + Map contentDetails, String authToken) throws Exception { logger.debug(requestContext, "CourseBatchNotificationActor:triggerEmailNotification: userIdList = " + userIdList); @@ -141,11 +142,11 @@ private Map createEmailRequest( CourseBatch courseBatch, Map contentDetails, String subject, - String template) { - Map courseBatchObject = new ObjectMapper().convertValue(courseBatch, Map.class); + String template) throws Exception { + Map courseBatchObject = JsonUtil.convert(courseBatch, Map.class); Map request = new HashMap<>(); - Map requestMap = new HashMap(); + Map requestMap = new HashMap<>(); requestMap.put(JsonKey.SUBJECT, subject); requestMap.put(JsonKey.EMAIL_TEMPLATE_TYPE, template); @@ -167,9 +168,8 @@ private Map createEmailRequest( } private String getCourseBatchUrl(String courseId, String batchId) { - - String url = baseUrl + "/learn/course/" + courseId + "/batch/" + batchId; - return url; + String url = courseBatchPath.replace("courseId", courseId).replace("batchId", batchId); + return baseUrl+url; } private void sendMail(RequestContext requestContext, Map requestMap, String authToken) { diff --git a/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/bulkupload/BulkUploadManagementActorTest.java b/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/bulkupload/BulkUploadManagementActorTest.java index 673f7ed87..db7651833 100644 --- a/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/bulkupload/BulkUploadManagementActorTest.java +++ b/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/bulkupload/BulkUploadManagementActorTest.java @@ -33,6 +33,7 @@ import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.models.util.ProjectUtil; import org.sunbird.common.request.Request; +import org.sunbird.common.request.RequestContext; import org.sunbird.helper.ServiceFactory; import org.sunbird.learner.util.Util; diff --git a/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursebatch/CourseBatchManagementActorTest.java b/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursebatch/CourseBatchManagementActorTest.java index c26ddfa34..4a31fd8ca 100644 --- a/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursebatch/CourseBatchManagementActorTest.java +++ b/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursebatch/CourseBatchManagementActorTest.java @@ -28,6 +28,7 @@ import org.sunbird.common.models.response.Response; import org.sunbird.common.models.util.JsonKey; import org.sunbird.common.request.Request; +import org.sunbird.common.request.RequestContext; import org.sunbird.helper.ServiceFactory; import org.sunbird.kafka.client.InstructionEventGenerator; import org.sunbird.kafka.client.KafkaClient; @@ -65,7 +66,6 @@ public void createBatchInviteSuccess() throws Exception { Map courseBatch = CustomObjectBuilder.getCourseBatchBuilder() .generateRandomFields() - .addField(JsonKey.ENROLLMENT_TYPE, JsonKey.INVITE_ONLY) .build() .get(); when(group @@ -146,6 +146,6 @@ private void mockCourseEnrollmentActor(){ }}); }}; when(ContentUtil.getContent( - Mockito.anyString())).thenReturn(courseMap); + Mockito.anyString(), Mockito.anyList())).thenReturn(courseMap); } } diff --git a/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursebatch/CourseBatchUserManagementActorTest.java b/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursebatch/CourseBatchUserManagementActorTest.java index e81d3b415..82aab7d39 100644 --- a/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursebatch/CourseBatchUserManagementActorTest.java +++ b/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursebatch/CourseBatchUserManagementActorTest.java @@ -30,6 +30,7 @@ import org.sunbird.common.models.util.JsonKey; import org.sunbird.common.models.util.ProjectUtil.EsType; import org.sunbird.common.request.Request; +import org.sunbird.common.request.RequestContext; import org.sunbird.helper.ServiceFactory; import org.sunbird.userorg.UserOrgServiceImpl; import scala.concurrent.Future; @@ -99,139 +100,4 @@ public void getBatchParticipantsEmptySuccess() { List participants = (List) result.get(JsonKey.PARTICIPANTS); Assert.assertTrue(participants.isEmpty()); } - - @Test - @PrepareForTest({ServiceFactory.class, EsClientFactory.class, UserOrgServiceImpl.class}) - public void addUserToBatchSuccess() { - group = - MockerBuilder.getFreshMockerGroup() - .withCassandraMock(new CassandraMocker()) - .withESMock(new ESMocker()) - .withUserOrgMock(new UserOrgMocker()); - Map caller = CustomObjectBuilder.getRandomUser().get(); - when(group.getUserOrgMockerService().getUserById(Mockito.anyString(), Mockito.anyString())).thenReturn(caller); - when(group.getUserOrgMockerService().getUsersByIds(Mockito.anyList(), Mockito.anyString())) - .then( - new Answer>>() { - - @Override - public List> answer(InvocationOnMock invocation) - throws Throwable { - List ids = (List) invocation.getArguments()[0]; - List> users = - CustomObjectBuilder.getRandomUsersWithIds( - ids, (String) caller.get(JsonKey.ROOT_ORG_ID)) - .get(); - return users; - } - }); - Future> courseBatchES = - CustomObjectBuilder.getCourseBatchBuilder() - .generateRandomFields() - .addField(JsonKey.ENROLLMENT_TYPE, JsonKey.INVITE_ONLY) - .addField(JsonKey.CREATED_BY, "randomCreator") - .build() - .asESIdentifierResult(); - when(group - .getESMockerService() - .getDataByIdentifier(Mockito.any(), Mockito.eq(EsType.courseBatch.getTypeName()), Mockito.anyString())) - .thenReturn(courseBatchES); - CustomObjectWrapper>> userCoursesWrapper = - CustomObjectBuilder.getRandomUserCoursesList(5); - List availableUsers = - userCoursesWrapper - .get() - .stream() - .map(uc -> (String) uc.get(JsonKey.USER_ID)) - .collect(Collectors.toList()); - when(group - .getCassandraMockerService() - .getRecordsByIndexedProperty( - Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any())) - .thenReturn(userCoursesWrapper.asCassandraResponse()); - when(group - .getESMockerService() - .upsert( - Mockito.any(), Mockito.eq(EsType.usercourses.getTypeName()), - Mockito.anyString(), - Mockito.anyMap())) - .thenReturn(Futures.successful(true)); - Request req = new Request(); - List userIds = Arrays.asList("addUserId1", "addUserId2"); - availableUsers.addAll(userIds); - req.setOperation("addUserBatch"); - req.put(JsonKey.BATCH_ID, "randomBatchId"); - req.put(JsonKey.USER_IDs, availableUsers); - Response response = executeInTenSeconds(req, Response.class); - Assert.assertNotNull(response); - } - - @Test - @Ignore - @PrepareForTest({ServiceFactory.class, EsClientFactory.class}) - public void removeUserToBatchSuccess() { - group = - MockerBuilder.getFreshMockerGroup() - .withCassandraMock(new CassandraMocker()) - .withESMock(new ESMocker()); - Map caller = CustomObjectBuilder.getRandomUser().get(); - Future> courseBatchES = - CustomObjectBuilder.getCourseBatchBuilder() - .generateRandomFields() - .addField(JsonKey.ENROLLMENT_TYPE, JsonKey.INVITE_ONLY) - .addField(JsonKey.CREATED_BY, "randomCreator") - .build() - .asESIdentifierResult(); - when(group - .getESMockerService() - .getDataByIdentifier(Mockito.any(), Mockito.eq(EsType.courseBatch.getTypeName()), Mockito.anyString())) - .thenReturn(courseBatchES); - CustomObjectWrapper>> userCoursesWrapper = - CustomObjectBuilder.getRandomUserCoursesList(5); - List availableUsers = - userCoursesWrapper - .get() - .stream() - .map(uc -> (String) uc.get(JsonKey.USER_ID)) - .collect(Collectors.toList()); - when(group - .getCassandraMockerService() - .getRecords( - Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyMap(), Mockito.anyList())) - .thenReturn(userCoursesWrapper.asCassandraResponse()); - when(group - .getESMockerService() - .upsert( - Mockito.any(), Mockito.eq(EsType.usercourses.getTypeName()), - Mockito.anyString(), - Mockito.anyMap())) - .thenReturn(Futures.successful(true)); - when(group - .getCassandraMockerService() - .getRecordByIdentifier(Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyMap(), Mockito.anyList())) - .then( - new Answer() { - - @Override - public Response answer(InvocationOnMock invocation) throws Throwable { - Map inputKeys = (Map) invocation.getArguments()[2]; - return CustomObjectBuilder.getUserCoursesBuilder() - .generateRandomFields() - .addField(JsonKey.BATCH_ID, (String) inputKeys.get(JsonKey.BATCH_ID)) - .addField(JsonKey.USER_ID, (String) inputKeys.get(JsonKey.USER_ID)) - .addField(JsonKey.ACTIVE, true) - .wrapToList() - .buildList() - .asCassandraResponse(); - } - }); - Request req = new Request(); - List userIds = Arrays.asList("addUserId1", "addUserId2"); - availableUsers.addAll(userIds); - req.setOperation("removeUserFromBatch"); - req.put(JsonKey.BATCH_ID, "randomBatchId"); - req.put(JsonKey.USER_IDs, availableUsers); - Response response = executeInTenSeconds(req, Response.class); - Assert.assertNotNull(response); - } } diff --git a/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursemanagement/CourseBatchManagementActorTest.java b/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursemanagement/CourseBatchManagementActorTest.java index 68dfd5ee4..1dfe4fb06 100644 --- a/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursemanagement/CourseBatchManagementActorTest.java +++ b/course-mw/course-actors/src/test/java/org/sunbird/learner/actors/coursemanagement/CourseBatchManagementActorTest.java @@ -31,17 +31,18 @@ import org.sunbird.common.responsecode.ResponseCode; import org.sunbird.helper.ServiceFactory; import org.sunbird.kafka.client.InstructionEventGenerator; -import org.sunbird.kafka.client.KafkaClient; import org.sunbird.learner.actors.coursebatch.CourseBatchManagementActor; import org.sunbird.learner.constants.CourseJsonKey; +import org.sunbird.learner.util.ContentUtil; import org.sunbird.learner.util.CourseBatchUtil; import org.sunbird.learner.util.JsonUtil; import org.sunbird.learner.util.Util; @RunWith(PowerMockRunner.class) -@SuppressStaticInitializationFor("org.sunbird.kafka.client.KafkaClient") -@PrepareForTest({ServiceFactory.class, EsClientFactory.class, CourseBatchUtil.class, Util.class, InstructionEventGenerator.class, KafkaClient.class}) -@PowerMockIgnore({"javax.management.*"}) +@PrepareForTest({ServiceFactory.class, EsClientFactory.class, CourseBatchUtil.class, Util.class, ContentUtil.class}) +@PowerMockIgnore({"javax.management.*", "javax.net.ssl.*", "javax.security.*", "jdk.internal.reflect.*", + "sun.security.ssl.*", "javax.net.ssl.*", "javax.crypto.*", + "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class CourseBatchManagementActorTest { public ActorSystem system = ActorSystem.create("system"); @@ -58,21 +59,11 @@ public class CourseBatchManagementActorTest { @Before public void setUp() throws Exception { mockCassandraOperation = mock(CassandraOperationImpl.class); - PowerMockito.mockStatic(InstructionEventGenerator.class); - PowerMockito.mockStatic(KafkaClient.class); - PowerMockito.doNothing() - .when( - InstructionEventGenerator.class, - "pushInstructionEvent", - Mockito.anyString(), - Mockito.anyMap()); - - PowerMockito.doNothing() - .when(KafkaClient.class, "send", Mockito.anyString(), Mockito.anyString()); ActorRef actorRef = mock(ActorRef.class); PowerMockito.mockStatic(ServiceFactory.class); when(ServiceFactory.getInstance()).thenReturn(mockCassandraOperation); PowerMockito.mockStatic(CourseBatchUtil.class); + PowerMockito.mockStatic(ContentUtil.class); } private String calculateDate(int dayOffset) { @@ -90,6 +81,7 @@ private ProjectCommonException performUpdateCourseBatchFailureTest( when(mockCassandraOperation.getRecordByIdentifier( Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyMap(), Mockito.any())) .thenReturn(mockGetRecordByIdResponse); + mockCourseEnrollmentActor(); TestKit probe = new TestKit(system); ActorRef subject = system.actorOf(props); @@ -126,6 +118,8 @@ private Response performUpdateCourseBatchSuccessTest( PowerMockito.doNothing().when(CourseBatchUtil.class); CourseBatchUtil.syncCourseBatchForeground(null, BATCH_ID, new HashMap<>()); + PowerMockito.mockStatic(ContentUtil.class); + mockCourseEnrollmentActor(); TestKit probe = new TestKit(system); ActorRef subject = system.actorOf(props); @@ -219,13 +213,15 @@ private String getOffsetDate(String date, int offSet) { public void checkTelemetryKeyFailure() throws Exception { String telemetryEnvKey = "batch"; + String envKey = "CourseBatchManagementActor"; PowerMockito.mockStatic(Util.class); doNothing() .when( Util.class, "initializeContext", Mockito.any(Request.class), - Mockito.eq(telemetryEnvKey)); + Mockito.eq(telemetryEnvKey), + Mockito.eq(envKey)); int batchProgressStatus = ProjectUtil.ProgressStatus.STARTED.getValue(); Response mockGetRecordByIdResponse = getMockCassandraRecordByIdResponse(batchProgressStatus); @@ -502,4 +498,15 @@ private Map getCertTemplate() throws Exception{ "}"; return JsonUtil.deserialize(template, Map.class); } + + private void mockCourseEnrollmentActor(){ + Map courseMap = new HashMap() {{ + put("content", new HashMap() {{ + put("contentType", "Course"); + put("status", "Live"); + }}); + }}; + when(ContentUtil.getContent( + Mockito.anyString(), Mockito.anyList())).thenReturn(courseMap); + } } diff --git a/course-mw/enrolment-actor/src/main/scala/org/sunbird/aggregate/CollectionSummaryAggregate.scala b/course-mw/enrolment-actor/src/main/scala/org/sunbird/aggregate/CollectionSummaryAggregate.scala index 64c5f1b03..7ad16f285 100644 --- a/course-mw/enrolment-actor/src/main/scala/org/sunbird/aggregate/CollectionSummaryAggregate.scala +++ b/course-mw/enrolment-actor/src/main/scala/org/sunbird/aggregate/CollectionSummaryAggregate.scala @@ -19,6 +19,7 @@ import org.sunbird.learner.actors.coursebatch.dao.CourseBatchDao import org.sunbird.learner.actors.coursebatch.dao.impl.CourseBatchDaoImpl import org.sunbird.learner.util.{JsonUtil, Util} import java.math.BigDecimal +import java.text.SimpleDateFormat import scala.collection.JavaConverters._ @@ -31,7 +32,8 @@ class CollectionSummaryAggregate @Inject()(implicit val cacheUtil: RedisCacheUti var courseBatchDao: CourseBatchDao = new CourseBatchDaoImpl() override def onReceive(request: Request): Unit = { - Util.initializeContext(request, TelemetryEnvKey.BATCH) + Util.initializeContext(request, TelemetryEnvKey.BATCH, this.getClass.getName) + val response = new Response() val filters = request.getRequest.get(JsonKey.FILTERS).asInstanceOf[util.Map[String, AnyRef]] val groupByKeys = request.getRequest.getOrDefault(JsonKey.GROUPBY, new util.ArrayList[String]()).asInstanceOf[util.ArrayList[String]].asScala.toList @@ -218,16 +220,17 @@ class CollectionSummaryAggregate @Inject()(implicit val cacheUtil: RedisCacheUti def getDate(requestContext: RequestContext, date: String, courseId: String, batchId: String): String = { val dateTimeFormate = DateTimeFormat.forPattern("yyyy-MM-dd") + val sd = new SimpleDateFormat("yyyy-MM-dd"); // When endate is null in the table considering default date as 7 - val defaultEndDate = dateTimeFormate.print(DateTime.now(DateTimeZone.UTC).minusDays(7)) + val defaultEndDate = sd.format(sd.parse(dateTimeFormate.print(DateTime.now(DateTimeZone.UTC).minusDays(7)))) val nofDates = date.replaceAll("[^0-9]", "") - val endDate = dateTimeFormate.print(DateTime.now(DateTimeZone.UTC).plusDays(1)) // Adding 1 Day extra - val startDate: String = if (!StringUtils.equalsIgnoreCase(date, "ALL")) { - dateTimeFormate.print(DateTime.now(DateTimeZone.UTC).minusDays(nofDates.toInt)) + val endDate = sd.format(sd.parse(dateTimeFormate.print(DateTime.now(DateTimeZone.UTC).plusDays(1)))) // Adding 1 Day extra + val startDate = if (!StringUtils.equalsIgnoreCase(date, "ALL")) { + sd.format(sd.parse(dateTimeFormate.print(DateTime.now(DateTimeZone.UTC).minusDays(nofDates.toInt)))) } else { val batchEndDate = courseBatchDao.readById(courseId, batchId, requestContext).getEndDate logger.debug(requestContext, s"BatchId: $batchId, CourseId: $courseId, EndDate" + batchEndDate) - Option(batchEndDate).map(date => if (date.isEmpty) defaultEndDate else date).getOrElse(defaultEndDate) + Option(batchEndDate).map(date => if (date == null) defaultEndDate else date).getOrElse(defaultEndDate) } s"$startDate/$endDate" } diff --git a/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/ContentConsumptionActor.scala b/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/ContentConsumptionActor.scala index 6898f25dd..7f157d103 100644 --- a/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/ContentConsumptionActor.scala +++ b/course-mw/enrolment-actor/src/main/scala/org/sunbird/enrolments/ContentConsumptionActor.scala @@ -1,17 +1,20 @@ package org.sunbird.enrolments import java.util +import java.util.{Date, TimeZone, UUID} import com.fasterxml.jackson.databind.ObjectMapper import javax.inject.Inject import org.apache.commons.collections4.{CollectionUtils, MapUtils} import org.apache.commons.lang3.StringUtils import org.sunbird.cassandra.CassandraOperation +import org.sunbird.common.CassandraUtil import org.sunbird.common.exception.ProjectCommonException import org.sunbird.common.models.response.Response import org.sunbird.common.models.util._ import org.sunbird.common.request.{Request, RequestContext} import org.sunbird.common.responsecode.ResponseCode +import org.sunbird.common.util.JsonUtil import org.sunbird.helper.ServiceFactory import org.sunbird.kafka.client.{InstructionEventGenerator, KafkaClient} import org.sunbird.learner.constants.{CourseJsonKey, InstructionEvent} @@ -26,23 +29,38 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { private var pushTokafkaEnabled: Boolean = true //TODO: to be removed once all are in scala private val consumptionDBInfo = Util.dbInfoMap.get(JsonKey.LEARNER_CONTENT_DB) private val assessmentAggregatorDBInfo = Util.dbInfoMap.get(JsonKey.ASSESSMENT_AGGREGATOR_DB) + private val enrolmentDBInfo = Util.dbInfoMap.get(JsonKey.LEARNER_COURSE_DB) val dateFormatter = ProjectUtil.getDateFormatter + //Added default fields in env varible: + //content.default.fields=contentid,userid,batchid,courseid,completedcount,completionpercentage,lastcompletedtime,status,viewcount + val defaultFields: Set[String] = if(ProjectUtil.getConfigValue("content.default.fields")!=null) ProjectUtil.getConfigValue("content.default.fields").split(",").toSet else Set[String]("contentid","userid","batchid","courseid","completedcount","completionpercentage","lastcompletedtime","status","viewcount") + val jsonFields = Set[String]("progressdetails") + override def onReceive(request: Request): Unit = { - Util.initializeContext(request, TelemetryEnvKey.BATCH) + Util.initializeContext(request, TelemetryEnvKey.BATCH, this.getClass.getName) + + dateFormatter.setTimeZone( + TimeZone.getTimeZone(ProjectUtil.getConfigValue(JsonKey.SUNBIRD_TIMEZONE))) + request.getOperation match { case "updateConsumption" => updateConsumption(request) case "getConsumption" => getConsumption(request) case _ => onReceiveUnsupportedOperation(request.getOperation) } } - + def updateConsumption(request: Request): Unit = { val requestBy = request.get(JsonKey.REQUESTED_BY).asInstanceOf[String] val requestedFor = request.get(JsonKey.REQUESTED_FOR).asInstanceOf[String] - - processAssessments(request, requestBy, requestedFor) - processContents(request, requestBy, requestedFor) + val assessmentEvents = request.getRequest.getOrDefault(JsonKey.ASSESSMENT_EVENTS, new java.util.ArrayList[java.util.Map[String, AnyRef]]).asInstanceOf[java.util.List[java.util.Map[String, AnyRef]]] + val contentList = request.getRequest.getOrDefault(JsonKey.CONTENTS, new java.util.ArrayList[java.util.Map[String, AnyRef]]).asInstanceOf[java.util.List[java.util.Map[String, AnyRef]]] + if(CollectionUtils.isEmpty(contentList) && CollectionUtils.isEmpty(assessmentEvents)) { + processEnrolmentSync(request, requestBy, requestedFor) + } else { + processAssessments(request, requestBy, requestedFor) + processContents(request, requestBy, requestedFor) + } } def processAssessments(request: Request, requestedBy: String, requestedFor: String) = { @@ -113,15 +131,16 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { val courseId = if (entry._2.head.containsKey(JsonKey.COURSE_ID)) entry._2.head.getOrDefault(JsonKey.COURSE_ID, "").asInstanceOf[String] else entry._2.head.getOrDefault(JsonKey.COLLECTION_ID, "").asInstanceOf[String] if(entry._2.head.containsKey(JsonKey.COLLECTION_ID)) entry._2.head.remove(JsonKey.COLLECTION_ID) val contentIds = entry._2.map(e => e.getOrDefault(JsonKey.CONTENT_ID, "").asInstanceOf[String]).asJava - val existingContents = getContentsConsumption(userId, courseId, contentIds, batchId, request.getRequestContext).groupBy(x => x.get("contentId").asInstanceOf[String]).map(e => e._1 -> e._2.toList.head).toMap + val existingContents = getContentsConsumption(userId, courseId, contentIds, batchId, defaultFields, request.getRequestContext).groupBy(x => x.get("contentId").asInstanceOf[String]).map(e => e._1 -> e._2.toList.head).toMap val contents:List[java.util.Map[String, AnyRef]] = entry._2.toList.map(inputContent => { val existingContent = existingContents.getOrElse(inputContent.get("contentId").asInstanceOf[String], new java.util.HashMap[String, AnyRef]) - processContentConsumption(inputContent, existingContent, userId) + CassandraUtil.changeCassandraColumnMapping(processContentConsumption(inputContent, existingContent, userId)) }) + // First push the event to kafka and then update cassandra user_content_consumption table + pushInstructionEvent(request.getRequestContext, userId, batchId, courseId, contents.asJava) cassandraOperation.batchInsertLogged(request.getRequestContext, consumptionDBInfo.getKeySpace, consumptionDBInfo.getTableName, contents) val updateData = getLatestReadDetails(userId, batchId, contents) - cassandraOperation.updateRecordV2(request.getRequestContext, "sunbird_courses", "user_enrolments", updateData._1, updateData._2, true) - pushInstructionEvent(request.getRequestContext, userId, batchId, courseId, contents.asJava) + cassandraOperation.updateRecordV2(request.getRequestContext, enrolmentDBInfo.getKeySpace, enrolmentDBInfo.getTableName, updateData._1, updateData._2, true) contentIds.map(id => responseMessage.put(id,JsonKey.SUCCESS)) } else { @@ -166,7 +185,7 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { } private def pushInvalidDataToKafka(requestContext: RequestContext, data: java.util.Map[String, AnyRef], dataType: String): Unit = { - logger.info(requestContext, "LearnerStateUpdater - Invalid " + dataType, data) + logger.info(requestContext, "LearnerStateUpdater - Invalid " + dataType, null, data) val topic = ProjectUtil.getConfigValue("kafka_topics_contentstate_invalid") try { val event = mapper.writeValueAsString(data) @@ -177,7 +196,7 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { } } - def getContentsConsumption(userId: String, courseId : String, contentIds: java.util.List[String], batchId: String, requestContext: RequestContext):java.util.List[java.util.Map[String, AnyRef]] = { + def getContentsConsumption(userId: String, courseId : String, contentIds: java.util.List[String], batchId: String, fields: java.util.Set[String], requestContext: RequestContext):java.util.List[java.util.Map[String, AnyRef]] = { val filters = new java.util.HashMap[String, AnyRef]() {{ put("userid", userId) put("courseid", courseId) @@ -185,7 +204,7 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { if(CollectionUtils.isNotEmpty(contentIds)) put("contentid", contentIds) }} - val response = cassandraOperation.getRecords(requestContext, consumptionDBInfo.getKeySpace, consumptionDBInfo.getTableName, filters, null) + val response = cassandraOperation.getRecords(requestContext, consumptionDBInfo.getKeySpace, consumptionDBInfo.getTableName, filters, fields.toList) response.getResult.getOrDefault(JsonKey.RESPONSE, new java.util.ArrayList[java.util.Map[String, AnyRef]]).asInstanceOf[java.util.List[java.util.Map[String, AnyRef]]] } @@ -193,16 +212,19 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { val inputStatus = inputContent.getOrDefault(JsonKey.STATUS, 0.asInstanceOf[AnyRef]).asInstanceOf[Number].intValue() val updatedContent = new java.util.HashMap[String, AnyRef]() updatedContent.putAll(inputContent) + val parsedMap = new java.util.HashMap[String, AnyRef]() + jsonFields.flatMap(f => if(inputContent.containsKey(f)) Some(parsedMap.put(f,mapper.writeValueAsString(inputContent.get(f)))) else None) + updatedContent.putAll(parsedMap) val inputCompletedTime = parseDate(inputContent.getOrDefault(JsonKey.LAST_COMPLETED_TIME, "").asInstanceOf[String]) val inputAccessTime = parseDate(inputContent.getOrDefault(JsonKey.LAST_ACCESS_TIME, "").asInstanceOf[String]) if(MapUtils.isNotEmpty(existingContent)) { - val existingAccessTime = parseDate(existingContent.getOrDefault(JsonKey.LAST_ACCESS_TIME, "").asInstanceOf[String]) + val existingAccessTime = if(parseDate(existingContent.get(JsonKey.LAST_ACCESS_TIME).asInstanceOf[Date]) == null) parseDate(existingContent.getOrDefault(JsonKey.OLD_LAST_ACCESS_TIME, "").asInstanceOf[String]) else parseDate(existingContent.get(JsonKey.LAST_ACCESS_TIME).asInstanceOf[Date]) updatedContent.put(JsonKey.LAST_ACCESS_TIME, compareTime(existingAccessTime, inputAccessTime)) val inputProgress = inputContent.getOrDefault(JsonKey.PROGRESS, 0.asInstanceOf[AnyRef]).asInstanceOf[Number].intValue() val existingProgress = Option(existingContent.getOrDefault(JsonKey.PROGRESS, 0.asInstanceOf[AnyRef]).asInstanceOf[Number]).getOrElse(0.asInstanceOf[Number]).intValue() updatedContent.put(JsonKey.PROGRESS, List(inputProgress, existingProgress).max.asInstanceOf[AnyRef]) val existingStatus = Option(existingContent.getOrDefault(JsonKey.STATUS, 0.asInstanceOf[AnyRef]).asInstanceOf[Number]).getOrElse(0.asInstanceOf[Number]).intValue() - val existingCompletedTime = parseDate(existingContent.getOrDefault(JsonKey.LAST_COMPLETED_TIME, "").asInstanceOf[String]) + val existingCompletedTime = if (parseDate(existingContent.get(JsonKey.LAST_COMPLETED_TIME).asInstanceOf[Date]) == null) parseDate(existingContent.getOrDefault(JsonKey.OLD_LAST_COMPLETED_TIME, "").asInstanceOf[String]) else parseDate(existingContent.get(JsonKey.LAST_COMPLETED_TIME).asInstanceOf[Date]) if(inputStatus >= existingStatus) { if(inputStatus >= 2) { updatedContent.put(JsonKey.STATUS, 2.asInstanceOf[AnyRef]) @@ -221,7 +243,7 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { } updatedContent.put(JsonKey.LAST_ACCESS_TIME, compareTime(null, inputAccessTime)) } - updatedContent.put(JsonKey.LAST_UPDATED_TIME, ProjectUtil.getFormattedDate) + updatedContent.put(JsonKey.LAST_UPDATED_TIME, ProjectUtil.getTimeStamp) updatedContent.put(JsonKey.USER_ID, userId) updatedContent } @@ -232,27 +254,33 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { } else null } - def compareTime(existingTime: java.util.Date, inputTime: java.util.Date): String = { - if(null == existingTime && null == inputTime) { - ProjectUtil.getFormattedDate - } else if(null == existingTime) dateFormatter.format(inputTime) - else if(null == inputTime) dateFormatter.format(existingTime) + def parseDate(date: Date) = { + if(date != null) { + dateFormatter.parse(dateFormatter.format(date)) + } else null + } + + def compareTime(existingTime: java.util.Date, inputTime: java.util.Date): Date = { + if (null == existingTime && null == inputTime) { + ProjectUtil.getTimeStamp + } else if (null == existingTime) inputTime + else if (null == inputTime) existingTime else { - if(inputTime.after(existingTime)) dateFormatter.format(inputTime) - else dateFormatter.format(existingTime) + if (inputTime.after(existingTime)) inputTime + else existingTime } } def getLatestReadDetails(userId: String, batchId: String, contents: List[java.util.Map[String, AnyRef]]) = { - val lastAccessContent: java.util.Map[String, AnyRef] = contents.groupBy(x => x.getOrDefault(JsonKey.LAST_ACCESS_TIME, "").asInstanceOf[String]).maxBy(_._1)._2.get(0) + val lastAccessContent: java.util.Map[String, AnyRef] = contents.groupBy(x => x.getOrDefault(JsonKey.LAST_ACCESS_TIME_KEY, null).asInstanceOf[Date]).maxBy(_._1)._2.get(0) val updateMap = new java.util.HashMap[String, AnyRef] () {{ - put("lastreadcontentid", lastAccessContent.get("contentId")) + put("lastreadcontentid", lastAccessContent.get(JsonKey.CONTENT_ID_KEY)) put("lastreadcontentstatus", lastAccessContent.get("status")) }} val selectMap = new util.HashMap[String, AnyRef]() {{ put("batchId", batchId) put("userId", userId) - put("courseId", lastAccessContent.get("courseId")) + put("courseId", lastAccessContent.get(JsonKey.COURSE_ID_KEY)) }} (selectMap, updateMap) } @@ -270,7 +298,7 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { }}) data.put(CourseJsonKey.ACTION, InstructionEvent.BATCH_USER_STATE_UPDATE.getAction) val contentsMap = contents.map(c => new java.util.HashMap[String, AnyRef]() {{ - put(JsonKey.CONTENT_ID, c.get(JsonKey.CONTENT_ID)) + put(JsonKey.CONTENT_ID, c.get(JsonKey.CONTENT_ID_KEY)) put(JsonKey.STATUS, c.get(JsonKey.STATUS)) }}).asJava data.put(CourseJsonKey.E_DATA, new java.util.HashMap[String, AnyRef]() {{ @@ -293,15 +321,21 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { val courseId = request.get(JsonKey.COURSE_ID).asInstanceOf[String] val contentIds = request.getRequest.getOrDefault(JsonKey.CONTENT_IDS, new java.util.ArrayList[String]()).asInstanceOf[java.util.List[String]] val fields = request.getRequest.getOrDefault(JsonKey.FIELDS, new java.util.ArrayList[String](){{ add(JsonKey.PROGRESS) }}).asInstanceOf[java.util.List[String]] - val contentsConsumed = getContentsConsumption(userId, courseId, contentIds, batchId, request.getRequestContext) + val finalFields = defaultFields ++ fields + val contentsConsumed = getContentsConsumption(userId, courseId, contentIds, batchId, finalFields.asJava, request.getRequestContext) val response = new Response if(CollectionUtils.isNotEmpty(contentsConsumed)) { val filteredContents = contentsConsumed.map(m => { - ProjectUtil.removeUnwantedFields(m, JsonKey.DATE_TIME, JsonKey.USER_ID, JsonKey.ADDED_BY, JsonKey.LAST_UPDATED_TIME) + ProjectUtil.removeUnwantedFields(m, JsonKey.DATE_TIME, JsonKey.USER_ID, JsonKey.ADDED_BY, JsonKey.LAST_UPDATED_TIME, JsonKey.OLD_LAST_ACCESS_TIME, JsonKey.OLD_LAST_UPDATED_TIME, JsonKey.OLD_LAST_COMPLETED_TIME) m.put(JsonKey.COLLECTION_ID, m.getOrDefault(JsonKey.COURSE_ID, "")) + jsonFields.foreach(field => + if(fields.contains(field)) + m.put(field, mapper.readTree(m.get(field).asInstanceOf[String])) + ) + val formattedMap = JsonUtil.convertWithDateFormat(m, classOf[util.Map[String, Object]], dateFormatter) if (fields.contains(JsonKey.ASSESSMENT_SCORE)) - m.putAll(mapAsJavaMap(Map(JsonKey.ASSESSMENT_SCORE -> getScore(userId, courseId, m.get("contentId").asInstanceOf[String], batchId, request.getRequestContext)))) - m + formattedMap.putAll(mapAsJavaMap(Map(JsonKey.ASSESSMENT_SCORE -> getScore(userId, courseId, m.get("contentId").asInstanceOf[String], batchId, request.getRequestContext)))) + formattedMap }).asJava response.put(JsonKey.RESPONSE, filteredContents) } else { @@ -337,4 +371,42 @@ class ContentConsumptionActor @Inject() extends BaseEnrolmentActor { val response = cassandraOperation.getRecordsWithLimit(requestContext, assessmentAggregatorDBInfo.getKeySpace, assessmentAggregatorDBInfo.getTableName, filters, fieldsToGet, limit) response.getResult.getOrDefault(JsonKey.RESPONSE, new java.util.ArrayList[java.util.Map[String, AnyRef]]).asInstanceOf[java.util.List[java.util.Map[String, AnyRef]]] } + + def processEnrolmentSync(request: Request, requestedBy: String, requestedFor: String): Unit = { + val primaryUserId = if (StringUtils.isNotBlank(requestedFor)) requestedFor else requestedBy + val userId: String = request.getOrDefault(JsonKey.USER_ID, primaryUserId).asInstanceOf[String] + val courseId: String = request.getOrDefault(JsonKey.COURSE_ID, "").asInstanceOf[String] + val batchId: String = request.getOrDefault(JsonKey.BATCH_ID, "").asInstanceOf[String] + val filters = Map[String, AnyRef]("userid"-> userId, "courseid"-> courseId, "batchid"-> batchId).asJava + val result = cassandraOperation + .getRecords(request.getRequestContext, enrolmentDBInfo.getKeySpace, enrolmentDBInfo.getTableName, filters, + null) + val resp = result.getResult + .getOrDefault(JsonKey.RESPONSE, new java.util.ArrayList[java.util.Map[String, AnyRef]]) + .asInstanceOf[java.util.List[java.util.Map[String, AnyRef]]] + val response = { + if (CollectionUtils.isNotEmpty(resp)) { + pushEnrolmentSyncEvent(userId, courseId, batchId) + successResponse() + } else { + new ProjectCommonException(ResponseCode.invalidRequestData.getErrorCode, + s"""No Enrolment found for userId: $userId, batchId: $batchId, courseId: $courseId""", ResponseCode.CLIENT_ERROR.getResponseCode) + } + } + sender().tell(response, self) + } + + def pushEnrolmentSyncEvent(userId: String, courseId: String, batchId: String) = { + val now = System.currentTimeMillis() + val event = + s"""{"eid":"BE_JOB_REQUEST","ets":$now,"mid":"LP.$now.${UUID.randomUUID()}" + |,"actor":{"type":"System","id":"Course Batch Updater"},"context":{"pdata":{"ver":"1.0","id":"org.sunbird.platform"}} + |,"object":{"type":"CourseBatchEnrolment","id":"${batchId}_${userId}"},"edata":{"action":"user-enrolment-sync" + |,"iteration":1,"batchId":"$batchId","userId":"$userId","courseId":"$courseId"}}""".stripMargin + .replaceAll("\n", "") + if(pushTokafkaEnabled){ + val topic = ProjectUtil.getConfigValue("kafka_enrolment_sync_topic") + KafkaClient.send(userId, event, topic) + } + } } 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 a1f9c6fe8..204c2f8ca 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 @@ -1,9 +1,9 @@ package org.sunbird.enrolments import java.sql.Timestamp -import java.text.MessageFormat +import java.text.{MessageFormat, SimpleDateFormat} import java.time.format.DateTimeFormatter -import java.time.{LocalDate, LocalDateTime, LocalTime} +import java.time.{LocalDate, LocalDateTime, LocalTime, ZoneId} import java.util import java.util.Date @@ -25,6 +25,7 @@ import org.sunbird.learner.util.{ContentSearchUtil, ContentUtil, CourseBatchSche import org.sunbird.models.course.batch.CourseBatch import org.sunbird.models.user.courses.UserCourses import org.sunbird.cache.util.RedisCacheUtil +import org.sunbird.common.CassandraUtil import org.sunbird.telemetry.util.TelemetryUtil import scala.collection.JavaConversions._ @@ -44,6 +45,7 @@ class CourseEnrolmentActor @Inject()(@Named("course-batch-notification-actor") c (ProjectUtil.getConfigValue("user_enrolments_response_cache_enable")).toBoolean else true val ttl: Int = if (StringUtils.isNotBlank(ProjectUtil.getConfigValue("user_enrolments_response_cache_ttl"))) (ProjectUtil.getConfigValue("user_enrolments_response_cache_ttl")).toInt else 60 + private val DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd") override def preStart { println("Starting CourseEnrolmentActor") } @@ -60,7 +62,8 @@ class CourseEnrolmentActor @Inject()(@Named("course-batch-notification-actor") c } override def onReceive(request: Request): Unit = { - Util.initializeContext(request, TelemetryEnvKey.BATCH) + Util.initializeContext(request, TelemetryEnvKey.BATCH, this.getClass.getName) + request.getOperation match { case "enrol" => enroll(request) case "unenrol" => unEnroll(request) @@ -198,10 +201,10 @@ class CourseEnrolmentActor @Inject()(@Named("course-batch-notification-actor") c if(EnrolmentType.inviteOnly.getVal.equalsIgnoreCase(batchData.getEnrollmentType)) ProjectCommonException.throwClientErrorException(ResponseCode.enrollmentTypeValidation, ResponseCode.enrollmentTypeValidation.getErrorMessage) - if((2 == batchData.getStatus) || (null != batchData.getEndDate && LocalDateTime.now().isAfter(LocalDate.parse(batchData.getEndDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX)))) + if((2 == batchData.getStatus) || (null != batchData.getEndDate && LocalDateTime.now().isAfter(LocalDate.parse(DATE_FORMAT.format(batchData.getEndDate), DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX)))) ProjectCommonException.throwClientErrorException(ResponseCode.courseBatchAlreadyCompleted, ResponseCode.courseBatchAlreadyCompleted.getErrorMessage) - if(isEnrol && null != batchData.getEnrollmentEndDate && LocalDateTime.now().isAfter(LocalDate.parse(batchData.getEnrollmentEndDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX))) + if(isEnrol && null != batchData.getEnrollmentEndDate && LocalDateTime.now().isAfter(LocalDate.parse(DATE_FORMAT.format(batchData.getEnrollmentEndDate), DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX))) ProjectCommonException.throwClientErrorException(ResponseCode.courseBatchEnrollmentDateEnded, ResponseCode.courseBatchEnrollmentDateEnded.getErrorMessage) if(isEnrol && null != enrolmentData && enrolmentData.isActive) ProjectCommonException.throwClientErrorException(ResponseCode.userAlreadyEnrolledCourse, ResponseCode.userAlreadyEnrolledCourse.getErrorMessage) @@ -210,10 +213,11 @@ class CourseEnrolmentActor @Inject()(@Named("course-batch-notification-actor") c } def upsertEnrollment(userId: String, courseId: String, batchId: String, data: java.util.Map[String, AnyRef], isNew: Boolean, requestContext: RequestContext): Unit = { + val dataMap = CassandraUtil.changeCassandraColumnMapping(data) if(isNew) { - userCoursesDao.insertV2(requestContext, data) + userCoursesDao.insertV2(requestContext, dataMap) } else { - userCoursesDao.updateV2(requestContext, userId, courseId, batchId, data) + userCoursesDao.updateV2(requestContext, userId, courseId, batchId, dataMap) } } @@ -225,7 +229,7 @@ class CourseEnrolmentActor @Inject()(@Named("course-batch-notification-actor") c put(JsonKey.ACTIVE, ProjectUtil.ActiveStatus.ACTIVE.getValue.asInstanceOf[AnyRef]) if (null == enrolmentData) { put(JsonKey.ADDED_BY, requestedBy) - put(JsonKey.COURSE_ENROLL_DATE, ProjectUtil.getFormattedDate) + put(JsonKey.COURSE_ENROLL_DATE, ProjectUtil.getTimeStamp) put(JsonKey.STATUS, ProjectUtil.ProgressStatus.NOT_STARTED.getValue.asInstanceOf[AnyRef]) put(JsonKey.DATE_TIME, new Timestamp(new Date().getTime)) put(JsonKey.COURSE_PROGRESS, 0.asInstanceOf[AnyRef]) @@ -259,24 +263,13 @@ class CourseEnrolmentActor @Inject()(@Named("course-batch-notification-actor") c } def updateProgressData(enrolments: java.util.List[java.util.Map[String, AnyRef]], userId: String, courseIds: java.util.List[String], requestContext: RequestContext): util.List[java.util.Map[String, AnyRef]] = { - val enrolmentMap: Map[String, java.util.Map[String, AnyRef]] = enrolments.map(enrolment => enrolment.get(JsonKey.COURSE_ID).asInstanceOf[String] + "_" + enrolment.get(JsonKey.BATCH_ID).asInstanceOf[String] -> enrolment).toMap - val response: Response = groupDao.readEntries("Course", java.util.Arrays.asList(userId), courseIds, requestContext) - if (response.getResponseCode != ResponseCode.OK) - ProjectCommonException.throwServerErrorException(ResponseCode.erroCallGrooupAPI, MessageFormat.format(ResponseCode.erroCallGrooupAPI.getErrorMessage())) - val userActivityList: util.List[util.Map[String, AnyRef]] = response.getResult.getOrDefault("response", new util.ArrayList()).asInstanceOf[util.List[util.Map[String, AnyRef]]] - userActivityList.map(activity => { - val completedCount: Int = activity.getOrDefault("agg", new util.HashMap[String, AnyRef]()) - .asInstanceOf[util.Map[String, AnyRef]].getOrDefault("completedCount", 0.asInstanceOf[AnyRef]).asInstanceOf[Int] - val key = activity.getOrDefault("activity_id", "").asInstanceOf[String] + "_" + activity.getOrDefault("context_id", "").asInstanceOf[String].replaceAll("cb:", "") - val enrolment = enrolmentMap.getOrDefault(key, new util.HashMap[String, AnyRef]()) - if(MapUtils.isNotEmpty(enrolment)) { - val leafNodesCount: Int = enrolment.get("leafNodesCount").asInstanceOf[Int] - enrolment.put("progress", completedCount.asInstanceOf[AnyRef]) - enrolment.put("status", getCompletionStatus(completedCount, leafNodesCount).asInstanceOf[AnyRef]) - enrolment.put("completionPercentage", getCompletionPerc(completedCount, leafNodesCount).asInstanceOf[AnyRef]) - } + enrolments.map(enrolment => { + val leafNodesCount: Int = enrolment.getOrDefault("leafNodesCount", 0.asInstanceOf[AnyRef]).asInstanceOf[Int] + val progress: Int = enrolment.getOrDefault("progress", 0.asInstanceOf[AnyRef]).asInstanceOf[Int] + enrolment.put("status", getCompletionStatus(progress, leafNodesCount).asInstanceOf[AnyRef]) + enrolment.put("completionPercentage", getCompletionPerc(progress, leafNodesCount).asInstanceOf[AnyRef]) }) - enrolmentMap.values.toList.asJava + enrolments } def getCompletionStatus(completedCount: Int, leafNodesCount: Int): Int = completedCount match { diff --git a/course-mw/enrolment-actor/src/main/scala/org/sunbird/group/GroupAggregatesActor.scala b/course-mw/enrolment-actor/src/main/scala/org/sunbird/group/GroupAggregatesActor.scala index e2b45fb98..4be7d2642 100644 --- a/course-mw/enrolment-actor/src/main/scala/org/sunbird/group/GroupAggregatesActor.scala +++ b/course-mw/enrolment-actor/src/main/scala/org/sunbird/group/GroupAggregatesActor.scala @@ -102,11 +102,10 @@ class GroupAggregatesActor @Inject()(implicit val cacheUtil: RedisCacheUtil) ext val finalMemberList = if(CollectionUtils.isNotEmpty(usersAggs) && CollectionUtils.isNotEmpty(groupMembers)) { val membersMap = groupMembers.asScala.toList.filter(x => StringUtils.isNotBlank(x.getOrDefault("userId", "").asInstanceOf[String])) .map(obj => (obj.getOrDefault("userId", "").asInstanceOf[String], obj)).toMap.asJava - val aggName = "completedCount" usersAggs.map(dbAggRecord => { val dbAgg = dbAggRecord.get("agg").asInstanceOf[java.util.Map[String, AnyRef]] val aggLastUpdated = dbAggRecord.get("agg_last_updated").asInstanceOf[java.util.Map[String, AnyRef]] - val agg = List(Map("metric"-> aggName, "value" -> dbAgg.get(aggName), "lastUpdatedOn" -> aggLastUpdated.get(aggName)).asJava).asJava + val agg = dbAgg.map(aggregate => Map("metric"-> aggregate._1, "value" -> aggregate._2, "lastUpdatedOn" -> aggLastUpdated.get(aggregate._1)).asJava).toList.asJava val userId = dbAggRecord.get("user_id").asInstanceOf[String] (membersMap.get(userId).filterKeys(key => GROUP_MEMBERS_METADATA.contains(key)) ++ Map("agg" -> agg)).asJava }).toList diff --git a/course-mw/enrolment-actor/src/test/scala/org/sunbird/enrolments/CourseConsumptionActorTest.scala b/course-mw/enrolment-actor/src/test/scala/org/sunbird/enrolments/CourseConsumptionActorTest.scala index fb19c2f6b..cfad2c062 100644 --- a/course-mw/enrolment-actor/src/test/scala/org/sunbird/enrolments/CourseConsumptionActorTest.scala +++ b/course-mw/enrolment-actor/src/test/scala/org/sunbird/enrolments/CourseConsumptionActorTest.scala @@ -11,7 +11,7 @@ import org.sunbird.common.Constants import org.sunbird.common.exception.ProjectCommonException import org.sunbird.common.inf.ElasticSearchService import org.sunbird.common.models.response.Response -import org.sunbird.common.models.util.ProjectUtil +import org.sunbird.common.models.util.{JsonKey, ProjectUtil} import org.sunbird.common.request.{Request, RequestContext} import org.sunbird.common.responsecode.ResponseCode import org.sunbird.dto.SearchDTO @@ -22,6 +22,96 @@ import scala.concurrent.duration.FiniteDuration class CourseConsumptionActorTest extends FlatSpec with Matchers with MockFactory { implicit val ec: ExecutionContext = ExecutionContext.global val system = ActorSystem.create("system") + + "get Consumption with progressDetails" should "return response" in { + val cassandraOperation = mock[CassandraOperation] + + val progressResponse = new java.util.HashMap[String, AnyRef]() + progressResponse.put("key1", "val1") + progressResponse.put("key2", "val2") + + val response = new Response() + response.put("response", new java.util.ArrayList[java.util.Map[String, AnyRef]] {{ + add(new java.util.HashMap[String, AnyRef] {{ + put("userId", "user1") + put("courseId", "do_123") + put("batchId", "0123") + put("contentId", "do_456") + put("progressdetails", "{}") + put("progressDetails", progressResponse) + }}) + }}) + + ((requestContext: RequestContext, keyspace: _root_.scala.Predef.String, table: _root_.scala.Predef.String, filters: _root_.java.util.Map[_root_.scala.Predef.String, AnyRef], fields: _root_.java.util.List[_root_.scala.Predef.String]) => cassandraOperation.getRecords(requestContext, keyspace, table, filters, fields)).expects(*,*,*,*,*).returns(response) + val result = callActor(getStateReadRequestWithProgressField(), Props(new ContentConsumptionActor().setCassandraOperation(cassandraOperation, false))) + + result.getResult().get("response").toString.shouldEqual("[{progressDetails={key1=val1, key2=val2}, contentId=do_456, batchId=0123, courseId=do_123, collectionId=do_123, progressdetails={}}]") + assert(null!= result) + } + + def getStateReadRequestWithProgressField(): Request = { + val request = new Request + request.setOperation("getConsumption") + request.put("userId", "user1") + request.put("courseId", "do_123") + request.put("batchId", "0123") + request.put("contentId", "do_456") + request.put("fields", new java.util.ArrayList[String](){{ add("progressDetails")}}) + + request + } + + "update Consumption with progressDetails" should "return success on updating the progress" in { + val cassandraOperation = mock[CassandraOperation] + val esService = mock[ElasticSearchService] + val progressResponse = new java.util.HashMap[String, AnyRef]() + progressResponse.put("key1", "val1") + progressResponse.put("key2", "val2") + val response = new Response() + response.put("response", new java.util.ArrayList[java.util.Map[String, AnyRef]] {{ + add(new java.util.HashMap[String, AnyRef] {{ + put("userId", "user1") + put("courseId", "do_123") + put("batchId", "0123") + put("contentId", "do_456") + put("progressDetails", progressResponse) + + }}) + + }}) + (esService.search(_:RequestContext, _: SearchDTO, _: String)).expects(*,*,*).returns(concurrent.Future{validBatchData()}) + (cassandraOperation.getRecords(_:RequestContext, _: String, _: String, _: java.util.Map[String, AnyRef], _: java.util.List[String])).expects(*,*,*,*,*).returns(response) + (cassandraOperation.batchInsertLogged(_:RequestContext, _: String, _: String, _: java.util.List[java.util.Map[String, AnyRef]])).expects(*,*,*,*) + (cassandraOperation.updateRecordV2(_:RequestContext, _: String, _: String, _: java.util.Map[String, AnyRef], _: java.util.Map[String, AnyRef], _: Boolean)).expects(*,"sunbird_courses", "user_enrolments",*,*,true) + val result = callActor(getStateUpdateRequestWithProgress(), Props(new ContentConsumptionActor().setCassandraOperation(cassandraOperation, false).setEsService(esService))) + assert(null!= result) + } + + def getStateUpdateRequestWithProgress(): Request = { + val request = new Request + request.setOperation("updateConsumption") + request.put("userId", "user1") + request.put("requestedBy", "user1") + request.put("contents", new java.util.ArrayList[java.util.Map[String, AnyRef]] {{ + add(new java.util.HashMap[String, AnyRef] {{ + put("courseId", "do_123") + put("batchId", "0123") + put("contentId", "do_456") + put("status", 2.asInstanceOf[AnyRef]) + put("progressDetails",new java.util.HashMap()) + + }}) + add(new java.util.HashMap[String, AnyRef] {{ + put("courseId", "do_123") + put("batchId", "0123") + put("contentId", "do_789") + put("status", 2.asInstanceOf[AnyRef]) + put("progressDetails",new java.util.HashMap()) + + }}) + }}) + request + } "get Consumption" should "return success on not giving contentIds" in { val cassandraOperation = mock[CassandraOperation] @@ -81,6 +171,40 @@ class CourseConsumptionActorTest extends FlatSpec with Matchers with MockFactory assert(null!= result) } + "sync enrolment" should "return success on updating the progress" in { + val cassandraOperation = mock[CassandraOperation] + val esService = mock[ElasticSearchService] + val response = new Response() + response.put("response", new java.util.ArrayList[java.util.Map[String, AnyRef]] {{ + add(new java.util.HashMap[String, AnyRef] {{ + put("userId", "user1") + put("courseId", "do_123") + put("batchId", "0123") + put("contentId", "do_456") + }}) + add(new java.util.HashMap[String, AnyRef] {{ + put("userId", "user1") + put("courseId", "do_123") + put("batchId", "0123") + put("contentId", "do_789") + }}) + }}) + (cassandraOperation.getRecords(_:RequestContext, _: String, _: String, _: java.util.Map[String, AnyRef], _: java.util.List[String])).expects(*,*,*,*,*).returns(response) + val result = callActor(getEnrolmentSyncRequest(), Props(new ContentConsumptionActor().setCassandraOperation(cassandraOperation, false).setEsService(esService))) + + } + + "sync enrolment" should "return client for no enrolments" in { + val cassandraOperation = mock[CassandraOperation] + val esService = mock[ElasticSearchService] + val response = new Response() + response.put("response", new java.util.ArrayList[java.util.Map[String, AnyRef]]()) + (cassandraOperation.getRecords(_:RequestContext, _: String, _: String, _: java.util.Map[String, AnyRef], _: java.util.List[String])).expects(*,*,*,*,*).returns(response) + val result = callActorForFailure(getEnrolmentSyncRequest(), Props(new ContentConsumptionActor().setCassandraOperation(cassandraOperation, false).setEsService(esService))) + assert(null!= result) + assert(ResponseCode.CLIENT_ERROR.getResponseCode == result.getResponseCode) + } + "update AssementScore " should "return success on updating the progress" in { val cassandraOperation = mock[CassandraOperation] val esService = mock[ElasticSearchService] @@ -135,6 +259,16 @@ class CourseConsumptionActorTest extends FlatSpec with Matchers with MockFactory request } + def getEnrolmentSyncRequest(): Request = { + val request = new Request + request.setOperation("updateConsumption") + request.put("userId", "user1") + request.put("courseId", "do_123") + request.put("batchId", "0123") + request.put("requestedBy", "user1") + request + } + def validBatchData(): java.util.Map[String, AnyRef] = { new java.util.HashMap[String, AnyRef] {{ put("content", new java.util.ArrayList[java.util.Map[String, AnyRef]]{{ diff --git a/course-mw/enrolment-actor/src/test/scala/org/sunbird/enrolments/CourseEnrolmentTest.scala b/course-mw/enrolment-actor/src/test/scala/org/sunbird/enrolments/CourseEnrolmentTest.scala index 65d58920e..bae8e208a 100644 --- a/course-mw/enrolment-actor/src/test/scala/org/sunbird/enrolments/CourseEnrolmentTest.scala +++ b/course-mw/enrolment-actor/src/test/scala/org/sunbird/enrolments/CourseEnrolmentTest.scala @@ -1,5 +1,7 @@ package org.sunbird.enrolments +import java.sql.Timestamp +import java.text.SimpleDateFormat import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.util.concurrent.TimeUnit @@ -30,6 +32,9 @@ class CourseEnrolmentTest extends FlatSpec with Matchers with MockFactory { val groupDao = mock[GroupDaoImpl] val cacheUtil = mock[RedisCacheUtil] val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") + val simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd") + val sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSSZ") + "CourseEnrolmentActor" should "return success on enrol" in { (courseDao.readById(_: String, _: String,_: RequestContext)).expects(*,*,*).returns(validCourseBatch()) @@ -68,7 +73,8 @@ class CourseEnrolmentTest extends FlatSpec with Matchers with MockFactory { "On previous enrollment end batch" should "return client error" in { val courseBatch = validCourseBatch() courseBatch.setStatus(1) - courseBatch.setEnrollmentEndDate("2019-01-01") + val date = simpleDateFormat.parse("2019-01-01") + courseBatch.setEnrollmentEndDate(new Timestamp(date.getTime())) (courseDao.readById(_: String, _: String, _:RequestContext)).expects(*,*,*).returns(courseBatch) (userDao.read(_: RequestContext, _: String,_: String,_: String)).expects(*,*,*,*).returns(null) val response = callActorForFailure(getEnrolRequest(), Props(new CourseEnrolmentActor(null)(cacheUtil).setDao(courseDao, userDao, groupDao))) @@ -87,7 +93,8 @@ class CourseEnrolmentTest extends FlatSpec with Matchers with MockFactory { "On previous batch end date" should "return client error" in { val courseBatch = validCourseBatch() - courseBatch.setEndDate("2019-07-01") + val date = simpleDateFormat.parse("2019-07-01") + courseBatch.setEndDate(new Timestamp(date.getTime())) (courseDao.readById(_: String, _: String, _:RequestContext)).expects(*,*,*).returns(courseBatch) (userDao.read(_: RequestContext, _: String,_: String,_: String)).expects(*,*,*,*).returns(null) val response = callActorForFailure(getEnrolRequest(), Props(new CourseEnrolmentActor(null)(cacheUtil).setDao(courseDao, userDao, groupDao))) @@ -144,7 +151,6 @@ class CourseEnrolmentTest extends FlatSpec with Matchers with MockFactory { userCourse.setCourseId("do_11305605610466508811") userCourse.setBatchId("0130598559365038081") (userDao.listEnrolments(_: RequestContext, _: String)).expects(*,*).returns(getEnrolmentLists()) - ((activityType: _root_.scala.Predef.String, userId: _root_.java.util.List[_root_.scala.Predef.String], activityIds: _root_.java.util.List[_root_.scala.Predef.String], requestContext: RequestContext) => groupDao.readEntries(activityType, userId, activityIds, requestContext)).expects(*, *, *, *).returns(getReadEntriesResponse) val response = callActor(getListEnrolRequest(), Props(new CourseEnrolmentActor(null)(cacheUtil).setDao(courseDao, userDao, groupDao))) println(response) assert(null != response) @@ -155,14 +161,11 @@ class CourseEnrolmentTest extends FlatSpec with Matchers with MockFactory { userCourse.setActive(true) userCourse.setCourseId("do_11305984881537024012255") userCourse.setBatchId("0130598559365038081") - val groupResponseStr = "{\"id\":null,\"ver\":null,\"ts\":null,\"params\":null,\"responseCode\":\"OK\",\"result\":{\"response\":[{\"agg\":{\"completedCount\":1},\"user_id\":\"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"activity_type\":\"Course\",\"agg_last_updated\":{\"completedCount\":1595506598142},\"activity_id\":\"do_11305984881537024012255\",\"context_id\":\"cb:0130598559365038081\"},{\"agg\":{\"completedCount\":1},\"user_id\":\"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"activity_type\":\"Course\",\"agg_last_updated\":{\"completedCount\":1595506598145},\"activity_id\":\"do_11305984881537024012255\",\"context_id\":\"cb:0130598559365038082\"}]}}" - val groupResponse = JsonUtil.deserialize(groupResponseStr, classOf[Response]) val enrolmentsString = "[{\"dateTime\":1594219912979,\"lastReadContentStatus\":2,\"completionpercentage\":100,\"enrolledDate\":\"1594219912979\",\"addedBy\":\"6cf06951-55fe-2a81-4e37-4475428ece80\",\"delta\":null,\"active\":true,\"contentstatus\":{\"do_11305605610466508811\":2},\"batchId\":\"0130598559365038081\",\"userId\":\"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"certificates\":[],\"completedOn\":1595422618082,\"grade\":null,\"progress\":1,\"lastReadContentId\":\"do_11305605610466508811\",\"courseId\":\"do_11305984881537024012255\",\"status\":2},{\"dateTime\":1594219912979,\"completionpercentage\":0,\"enrolledDate\":\"1594219912978\",\"addedBy\":\"6cf06951-55fe-2a81-4e37-4475428ece80\",\"delta\":null,\"active\":true,\"batchId\":\"0130598559365038083\",\"userId\":\"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"certificates\":[],\"grade\":null,\"progress\":0,\"lastReadContentId\":\"do_11305605610466508811\",\"courseId\":\"do_11305984881537024012255\",\"status\":0}]" val enrolmentsList = mapper.readValue(enrolmentsString, classOf[java.util.List[java.util.Map[String, AnyRef]]]) (userDao.listEnrolments(_: RequestContext, _: String)).expects(*,*).returns(enrolmentsList) - ((activityType: _root_.scala.Predef.String, userId: _root_.java.util.List[_root_.scala.Predef.String], activityIds: _root_.java.util.List[_root_.scala.Predef.String], requestContext: RequestContext) => groupDao.readEntries(activityType, userId, activityIds, requestContext)).expects(*, *, *, *).returns(groupResponse) val response = callActor(getListEnrolRequest(), Props(new CourseEnrolmentActor(null)(cacheUtil).setDao(courseDao, userDao, groupDao))) println(response) assert(null != response) @@ -191,7 +194,6 @@ class CourseEnrolmentTest extends FlatSpec with Matchers with MockFactory { userCourse.setBatchId("0130598559365038081") (cacheUtil.get(_: String, _: String => String, _: Int)).expects(*, *, *).returns(null) (userDao.listEnrolments(_: RequestContext, _: String)).expects(*, *).returns(getEnrolmentLists()) - ((activityType: _root_.scala.Predef.String, userId: _root_.java.util.List[_root_.scala.Predef.String], activityIds: _root_.java.util.List[_root_.scala.Predef.String], requestContext: RequestContext) => groupDao.readEntries(activityType, userId, activityIds, requestContext)).expects(*, *, *, *).returns(getReadEntriesResponse) (cacheUtil.set(_: String, _: String, _: Int)).expects(*, *, *).once() val request = getListEnrolRequest() request.getContext.put("cache", true.asInstanceOf[AnyRef]) @@ -231,7 +233,8 @@ class CourseEnrolmentTest extends FlatSpec with Matchers with MockFactory { val courseBatch = new CourseBatch() courseBatch.setBatchId("0123") courseBatch.setCourseId("do_123") - courseBatch.setEndDate("2099-07-01") + val date = simpleDateFormat.parse("2099-07-01") + courseBatch.setEndDate(new Timestamp(date.getTime())) courseBatch.setStatus(1) courseBatch } @@ -303,25 +306,29 @@ class CourseEnrolmentTest extends FlatSpec with Matchers with MockFactory { } private def getBatchWithValidEnrolmentEndDateAndBatchEndDate(): CourseBatch = { - val startDate = LocalDateTime.now().minusDays(3).format(dateTimeFormatter) - val today = LocalDateTime.now().format(dateTimeFormatter) - val batchData: String = "{\"batchId\": \"0130901005678510081\",\"endDate\": \""+ today +"\",\"description\": \"batch description1\",\"batchId\": \"0130901005678510081\",\"createdDate\": \"2020-08-20 08:28:47:534+0000\",\"createdBy\": \"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"name\": \"Batch-3\",\"enrollmentType\": \"open\",\"courseId\": \"do_11308799051844812811152\",\"enrollmentEndDate\": \""+ today +"\",\"startDate\": \""+ startDate +"\",\"status\": 1}" + val startDate = sd.format(simpleDateFormat.parse(LocalDateTime.now().minusDays(3).format(dateTimeFormatter))) + val enrolmentEndDate = sd.format(simpleDateFormat.parse(LocalDateTime.now().plusDays(7).format(dateTimeFormatter))) + val endDate = sd.format(simpleDateFormat.parse(LocalDateTime.now().plusDays(10).format(dateTimeFormatter))) + val batchData: String = "{\"batchId\": \"0130901005678510081\",\"endDate\": \""+ endDate +"\",\"description\": \"batch description1\",\"batchId\": \"0130901005678510081\",\"createdDate\": \"2020-08-20 08:28:47:534+0000\",\"createdBy\": \"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"name\": \"Batch-3\",\"enrollmentType\": \"open\",\"courseId\": \"do_11308799051844812811152\",\"enrollmentEndDate\": \""+ enrolmentEndDate +"\",\"startDate\": \""+ startDate +"\",\"status\": 1}" + mapper.setDateFormat(sd) mapper.readValue(batchData, classOf[CourseBatch]) } private def getBatchWithInvalidEnrolmentEndDate(): CourseBatch = { - val startDate = LocalDateTime.now().minusDays(3).format(dateTimeFormatter) - val endDate = LocalDateTime.now().plusDays(1).format(dateTimeFormatter) - val enrolmentEnddate = LocalDateTime.now().minusDays(1).format(dateTimeFormatter) + val startDate = sd.format(simpleDateFormat.parse(LocalDateTime.now().minusDays(3).format(dateTimeFormatter))) + val endDate = sd.format(simpleDateFormat.parse(LocalDateTime.now().plusDays(1).format(dateTimeFormatter))) + val enrolmentEnddate = sd.format(simpleDateFormat.parse(LocalDateTime.now().minusDays(1).format(dateTimeFormatter))) val batchData: String = "{\"batchId\": \"0130901005678510081\",\"endDate\": \""+ endDate +"\",\"description\": \"batch description1\",\"batchId\": \"0130901005678510081\",\"createdDate\": \"2020-08-20 08:28:47:534+0000\",\"createdBy\": \"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"name\": \"Batch-3\",\"enrollmentType\": \"open\",\"courseId\": \"do_11308799051844812811152\",\"enrollmentEndDate\": \""+ enrolmentEnddate +"\",\"startDate\": \""+ startDate +"\",\"status\": 1}" + mapper.setDateFormat(sd) mapper.readValue(batchData, classOf[CourseBatch]) } private def getBatchWithInvalidBatchEndDate(): CourseBatch = { - val startDate = LocalDateTime.now().minusDays(3).format(dateTimeFormatter) - val endDate = LocalDateTime.now().minusDays(1).format(dateTimeFormatter) - val enrolmentEndDate = LocalDateTime.now().minusDays(2).format(dateTimeFormatter) + val startDate = sd.format(simpleDateFormat.parse(LocalDateTime.now().minusDays(3).format(dateTimeFormatter))) + val endDate = sd.format(simpleDateFormat.parse(LocalDateTime.now().minusDays(1).format(dateTimeFormatter))) + val enrolmentEndDate = sd.format(simpleDateFormat.parse(LocalDateTime.now().minusDays(2).format(dateTimeFormatter))) val batchData: String = "{\"batchId\": \"0130901005678510081\",\"endDate\": \""+ endDate +"\",\"description\": \"batch description1\",\"batchId\": \"0130901005678510081\",\"createdDate\": \"2020-08-20 08:28:47:534+0000\",\"createdBy\": \"95e4942d-cbe8-477d-aebd-ad8e6de4bfc8\",\"name\": \"Batch-3\",\"enrollmentType\": \"open\",\"courseId\": \"do_11308799051844812811152\",\"enrollmentEndDate\": \""+ enrolmentEndDate +"\",\"startDate\": \""+ startDate +"\",\"status\": 1}" + mapper.setDateFormat(sd) mapper.readValue(batchData, classOf[CourseBatch]) } } diff --git a/course-mw/sunbird-util/cache-utils/pom.xml b/course-mw/sunbird-util/cache-utils/pom.xml index a45e92db2..be59f7c57 100644 --- a/course-mw/sunbird-util/cache-utils/pom.xml +++ b/course-mw/sunbird-util/cache-utils/pom.xml @@ -47,14 +47,14 @@ 0.0.1-SNAPSHOT - org.apache.logging.log4j - log4j-api - 2.8.2 + ch.qos.logback + logback-classic + 1.2.3 - org.apache.logging.log4j - log4j-core - 2.8.2 + net.logstash.logback + logstash-logback-encoder + 6.3 diff --git a/course-mw/sunbird-util/sunbird-cache-utils/pom.xml b/course-mw/sunbird-util/sunbird-cache-utils/pom.xml index 83c2ea03f..75e6990d2 100644 --- a/course-mw/sunbird-util/sunbird-cache-utils/pom.xml +++ b/course-mw/sunbird-util/sunbird-cache-utils/pom.xml @@ -21,14 +21,14 @@ 3.2.0 - org.apache.logging.log4j - log4j-api - 2.8.2 + ch.qos.logback + logback-classic + 1.2.3 - org.apache.logging.log4j - log4j-core - 2.8.2 + net.logstash.logback + logstash-logback-encoder + 6.3 org.sunbird diff --git a/course-mw/sunbird-util/sunbird-cache-utils/src/main/java/org/sunbird/redis/RedisConnectionManager.java b/course-mw/sunbird-util/sunbird-cache-utils/src/main/java/org/sunbird/redis/RedisConnectionManager.java index 3ac382cc9..c522dae6a 100644 --- a/course-mw/sunbird-util/sunbird-cache-utils/src/main/java/org/sunbird/redis/RedisConnectionManager.java +++ b/course-mw/sunbird-util/sunbird-cache-utils/src/main/java/org/sunbird/redis/RedisConnectionManager.java @@ -64,8 +64,7 @@ private static void initialisingClusterServer(String host, String port) { "RedisConnectionManager: initialisingClusterServer called with host = " + host + " port = " - + port, - LoggerEnum.INFO.name()); + + port); String[] hosts = host.split(","); String[] ports = port.split(","); diff --git a/course-mw/sunbird-util/sunbird-cassandra-utils/pom.xml b/course-mw/sunbird-util/sunbird-cassandra-utils/pom.xml index 487f03788..23a2a0c80 100644 --- a/course-mw/sunbird-util/sunbird-cassandra-utils/pom.xml +++ b/course-mw/sunbird-util/sunbird-cassandra-utils/pom.xml @@ -47,9 +47,14 @@ - log4j - log4j - 1.2.17 + ch.qos.logback + logback-classic + 1.2.3 + + + net.logstash.logback + logstash-logback-encoder + 6.3 com.fasterxml.jackson.core diff --git a/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/cassandraimpl/CassandraDACImpl.java b/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/cassandraimpl/CassandraDACImpl.java index d77c74484..46d971044 100644 --- a/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/cassandraimpl/CassandraDACImpl.java +++ b/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/cassandraimpl/CassandraDACImpl.java @@ -23,7 +23,7 @@ import org.sunbird.common.responsecode.ResponseCode; public class CassandraDACImpl extends CassandraOperationImpl { - + @Override public Response getRecords( RequestContext requestContext, String keySpace, String table, Map filters, List fields) { @@ -32,7 +32,7 @@ public Response getRecords( try { Select select; if (CollectionUtils.isNotEmpty(fields)) { - select = QueryBuilder.select((String[]) fields.toArray()).from(keySpace, table); + select = QueryBuilder.select(fields.toArray()).from(keySpace, table); } else { select = QueryBuilder.select().all().from(keySpace, table); } @@ -156,7 +156,7 @@ public Response updateMapRecord( return response; } catch (Exception e) { e.printStackTrace(); - ProjectLogger.log(Constants.EXCEPTION_MSG_FETCH + table + " : " + e.getMessage(), e); + logger.error(null,Constants.EXCEPTION_MSG_FETCH + table + " : " + e.getMessage(), e); throw new ProjectCommonException( ResponseCode.SERVER_ERROR.getErrorCode(), ResponseCode.SERVER_ERROR.getErrorMessage(), diff --git a/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/cassandraimpl/CassandraOperationImpl.java b/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/cassandraimpl/CassandraOperationImpl.java index 3e6eddf80..a807e1fa0 100644 --- a/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/cassandraimpl/CassandraOperationImpl.java +++ b/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/cassandraimpl/CassandraOperationImpl.java @@ -67,7 +67,7 @@ public Response insertRecord(RequestContext requestContext, String keyspaceName, while (iterator.hasNext()) { array[i++] = iterator.next(); } - if(null != statement) logger.debug(requestContext, statement.getQueryString(), null); + if(null != statement) logger.debug(requestContext, statement.getQueryString()); connectionManager.getSession(keyspaceName).execute(boundStatement.bind(array)); response.put(Constants.RESPONSE, Constants.SUCCESS); } catch (Exception e) { @@ -189,8 +189,9 @@ public Response getRecordsByProperty( selectStatement.and(QueryBuilder.eq(propertyName, propertyValue)); } ResultSet results = null; + Select selectQuery = selectStatement.allowFiltering(); if (null != selectStatement) logger.debug(requestContext, selectStatement.getQueryString()); - results = session.execute(selectStatement); + results = session.execute(selectQuery); response = CassandraUtil.createResponse(results); } catch (Exception e) { logger.error(requestContext, Constants.EXCEPTION_MSG_FETCH + tableName + " : " + e.getMessage(), e); @@ -213,8 +214,7 @@ public Response getRecordsByProperties( String keyspaceName, String tableName, Map propertyMap, List fields, RequestContext requestContext) { long startTime = System.currentTimeMillis(); logger.info(requestContext, - "Cassandra Service getRecordsByProperties method started at ==" + startTime, - LoggerEnum.INFO); + "Cassandra Service getRecordsByProperties method started at ==" + startTime); Response response = new Response(); try { Builder selectBuilder; @@ -261,8 +261,7 @@ public Response getPropertiesValueById( String keyspaceName, String tableName, String id, RequestContext requestContext, String... properties) { long startTime = System.currentTimeMillis(); logger.info(requestContext, - "Cassandra Service getPropertiesValueById method started at ==" + startTime, - LoggerEnum.INFO); + "Cassandra Service getPropertiesValueById method started at ==" + startTime); Response response = new Response(); try { String selectQuery = CassandraUtil.getSelectStatement(keyspaceName, tableName, properties); @@ -502,7 +501,7 @@ public Response batchInsert( | QueryValidationException | NoHostAvailableException | IllegalStateException e) { - logger.info(requestContext, "Cassandra Batch Insert Failed." + e.getMessage(), e); + logger.error(requestContext, "Cassandra Batch Insert Failed." + e.getMessage(), e); throw new ProjectCommonException( ResponseCode.SERVER_ERROR.getErrorCode(), ResponseCode.SERVER_ERROR.getErrorMessage(), @@ -559,8 +558,7 @@ public Response getRecordsByIndexedProperty( String keyspaceName, String tableName, String propertyName, Object propertyValue, RequestContext requestContext) { long startTime = System.currentTimeMillis(); logger.info(requestContext, - "CassandraOperationImpl:getRecordsByIndexedProperty called at " + startTime, - LoggerEnum.INFO); + "CassandraOperationImpl:getRecordsByIndexedProperty called at " + startTime); Response response = new Response(); try { Select selectQuery = QueryBuilder.select().all().from(keyspaceName, tableName); @@ -592,8 +590,7 @@ public void deleteRecord( String keyspaceName, String tableName, Map compositeKeyMap, RequestContext requestContext) { long startTime = System.currentTimeMillis(); logger.info(requestContext, - "CassandraOperationImpl: deleteRecord by composite key called at " + startTime, - LoggerEnum.INFO); + "CassandraOperationImpl: deleteRecord by composite key called at " + startTime); try { Delete delete = QueryBuilder.delete().from(keyspaceName, tableName); Delete.Where deleteWhere = delete.where(); @@ -777,7 +774,7 @@ public Response batchInsertLogged( | QueryValidationException | NoHostAvailableException | IllegalStateException e) { - logger.info(requestContext, "Cassandra Batch Insert Failed." + e.getMessage(), e); + logger.error(requestContext, "Cassandra Batch Insert Failed." + e.getMessage(), e); if (e instanceof WriteTimeoutException && writeType.contains(((WriteTimeoutException) e).getWriteType().name())) response.put(Constants.RESPONSE, Constants.SUCCESS); else { diff --git a/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/common/CassandraUtil.java b/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/common/CassandraUtil.java index e3043c275..a955db896 100644 --- a/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/common/CassandraUtil.java +++ b/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/common/CassandraUtil.java @@ -22,10 +22,7 @@ import org.sunbird.cassandraannotation.PartitioningKey; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.Response; -import org.sunbird.common.models.util.CassandraPropertyReader; -import org.sunbird.common.models.util.JsonKey; -import org.sunbird.common.models.util.ProjectLogger; -import org.sunbird.common.models.util.ProjectUtil; +import org.sunbird.common.models.util.*; import org.sunbird.common.responsecode.ResponseCode; /** @@ -37,6 +34,7 @@ public final class CassandraUtil { private static final CassandraPropertyReader propertiesCache = CassandraPropertyReader.getInstance(); private static final String SERIAL_VERSION_UID = "serialVersionUID"; + protected static LoggerUtil logger = new LoggerUtil(CassandraUtil.class); private CassandraUtil() {} @@ -63,7 +61,7 @@ public static String getPreparedStatement( } } query.append(commaSepValueBuilder + Constants.CLOSING_BRACE); - ProjectLogger.log(query.toString()); + logger.info(null, query.toString()); return query.toString(); } @@ -87,7 +85,7 @@ public static Response createResponse(ResultSet results) { .forEach(entry -> rowMap.put(entry.getKey(), row.getObject(entry.getValue()))); responseList.add(rowMap); }); - ProjectLogger.log(responseList.toString()); + logger.info(null, responseList.toString()); response.put(Constants.RESPONSE, responseList); return response; } @@ -144,7 +142,7 @@ public static String getSelectStatement( + Constants.IDENTIFIER + Constants.EQUAL + " ?; "); - ProjectLogger.log(query.toString()); + logger.info(null, query.toString()); return query.toString(); } @@ -198,7 +196,7 @@ public static Map> batchUpdateQuery(T clazz) { } } } catch (Exception ex) { - ProjectLogger.log("Exception occurred - batchUpdateQuery", ex); + logger.error(null,"Exception occurred - batchUpdateQuery", ex); throw new ProjectCommonException( ResponseCode.SERVER_ERROR.getErrorCode(), ResponseCode.SERVER_ERROR.getErrorMessage(), @@ -245,7 +243,7 @@ public static Map getPrimaryKey(T clazz) { } } } catch (Exception ex) { - ProjectLogger.log("Exception occurred - getPrimaryKey", ex); + logger.error(null, "Exception occurred - getPrimaryKey", ex); throw new ProjectCommonException( ResponseCode.SERVER_ERROR.getErrorCode(), ResponseCode.SERVER_ERROR.getErrorMessage(), @@ -343,4 +341,10 @@ public static void createQuery(String key, Object value, Where where) { where.and(QueryBuilder.eq(key, value)); } } + + public static Map changeCassandraColumnMapping(Map map) { + Map newMap = new HashMap<>(); + map.entrySet().forEach(entry -> newMap.put(propertiesCache.readPropertyValue(entry.getKey()), entry.getValue())); + return newMap; + } } diff --git a/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/helper/CassandraConnectionManagerImpl.java b/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/helper/CassandraConnectionManagerImpl.java index 39e7b29b0..53c52a88a 100644 --- a/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/helper/CassandraConnectionManagerImpl.java +++ b/course-mw/sunbird-util/sunbird-cassandra-utils/src/main/java/org/sunbird/helper/CassandraConnectionManagerImpl.java @@ -16,6 +16,7 @@ public class CassandraConnectionManagerImpl implements CassandraConnectionManager { private static Cluster cluster; private static Map cassandraSessionMap = new ConcurrentHashMap<>(2); + public static LoggerUtil logger = new LoggerUtil(CassandraConnectionManagerImpl.class); static { registerShutDownHook(); @@ -66,17 +67,17 @@ private void createCassandraConnection(String[] hosts) { final Metadata metadata = cluster.getMetadata(); String msg = String.format("Connected to cluster: %s", metadata.getClusterName()); - ProjectLogger.log(msg); + logger.info(null, msg); for (final Host host : metadata.getAllHosts()) { msg = String.format( "Datacenter: %s; Host: %s; Rack: %s", host.getDatacenter(), host.getAddress(), host.getRack()); - ProjectLogger.log(msg); + logger.info(null, msg); } } catch (Exception e) { - ProjectLogger.log("Error occured while creating cassandra connection :", e); + logger.error(null, "Error occured while creating cassandra connection :", e); throw new ProjectCommonException( ResponseCode.internalError.getErrorCode(), e.getMessage(), @@ -94,9 +95,8 @@ private static Cluster createCluster(String[] hosts, PoolingOptions poolingOptio .withPoolingOptions(poolingOptions); ConsistencyLevel consistencyLevel = getConsistencyLevel(); - ProjectLogger.log( - "CassandraConnectionManagerImpl:createCluster: Consistency level = " + consistencyLevel, - LoggerEnum.INFO); + logger.info(null, + "CassandraConnectionManagerImpl:createCluster: Consistency level = " + consistencyLevel); if (consistencyLevel != null) { builder.withQueryOptions(new QueryOptions().setConsistencyLevel(consistencyLevel)); @@ -108,19 +108,17 @@ private static Cluster createCluster(String[] hosts, PoolingOptions poolingOptio private static ConsistencyLevel getConsistencyLevel() { String consistency = ProjectUtil.getConfigValue(JsonKey.SUNBIRD_CASSANDRA_CONSISTENCY_LEVEL); - ProjectLogger.log( - "CassandraConnectionManagerImpl:getConsistencyLevel: level = " + consistency, - LoggerEnum.INFO); + logger.info(null, + "CassandraConnectionManagerImpl:getConsistencyLevel: level = " + consistency); if (StringUtils.isBlank(consistency)) return null; try { return ConsistencyLevel.valueOf(consistency.toUpperCase()); } catch (IllegalArgumentException exception) { - ProjectLogger.log( + logger.info(null, "CassandraConnectionManagerImpl:getConsistencyLevel: Exception occurred with error message = " - + exception.getMessage(), - LoggerEnum.ERROR); + + exception.getMessage()); } return null; } @@ -137,7 +135,7 @@ public List getTableList(String keyspacename) { public static void registerShutDownHook() { Runtime runtime = Runtime.getRuntime(); runtime.addShutdownHook(new ResourceCleanUp()); - ProjectLogger.log("Cassandra ShutDownHook registered."); + logger.info(null, "Cassandra ShutDownHook registered."); } /** @@ -148,14 +146,14 @@ static class ResourceCleanUp extends Thread { @Override public void run() { try { - ProjectLogger.log("started resource cleanup Cassandra."); + logger.info(null, "started resource cleanup Cassandra."); for (Map.Entry entry : cassandraSessionMap.entrySet()) { cassandraSessionMap.get(entry.getKey()).close(); } cluster.close(); - ProjectLogger.log("completed resource cleanup Cassandra."); + logger.info(null, "completed resource cleanup Cassandra."); } catch (Exception ex) { - ProjectLogger.log("Error :", ex); + logger.error(null, "Error :", ex); } } } diff --git a/course-mw/sunbird-util/sunbird-es-utils/pom.xml b/course-mw/sunbird-util/sunbird-es-utils/pom.xml index 7085c8ea3..d5e029acd 100644 --- a/course-mw/sunbird-util/sunbird-es-utils/pom.xml +++ b/course-mw/sunbird-util/sunbird-es-utils/pom.xml @@ -35,14 +35,14 @@ - org.apache.logging.log4j - log4j-api - 2.8.2 + ch.qos.logback + logback-classic + 1.2.3 - org.apache.logging.log4j - log4j-core - 2.8.2 + net.logstash.logback + logstash-logback-encoder + 6.3 org.sunbird diff --git a/course-mw/sunbird-util/sunbird-es-utils/src/main/java/org/sunbird/common/ElasticSearchRestHighImpl.java b/course-mw/sunbird-util/sunbird-es-utils/src/main/java/org/sunbird/common/ElasticSearchRestHighImpl.java index 8d0b40771..4adfb93cf 100644 --- a/course-mw/sunbird-util/sunbird-es-utils/src/main/java/org/sunbird/common/ElasticSearchRestHighImpl.java +++ b/course-mw/sunbird-util/sunbird-es-utils/src/main/java/org/sunbird/common/ElasticSearchRestHighImpl.java @@ -242,7 +242,7 @@ public void onResponse(GetResponse getResponse) { @Override public void onFailure(Exception e) { - logger.debug(requestContext, + logger.error(requestContext, "ElasticSearchRestHighImpl:getDataByIdentifier: method Failed with error == " , e); promise.failure(e); } @@ -550,7 +550,7 @@ public void onResponse(BulkResponse bulkResponse) { @Override public void onFailure(Exception e) { - logger.debug(requestContext, "ElasticSearchRestHighImpl:bulkinsert: Bulk upload error block", e); + logger.error(requestContext, "ElasticSearchRestHighImpl:bulkinsert: Bulk upload error block", e); promise.success(false); } }; diff --git a/course-mw/sunbird-util/sunbird-es-utils/src/main/java/org/sunbird/helper/ConnectionManager.java b/course-mw/sunbird-util/sunbird-es-utils/src/main/java/org/sunbird/helper/ConnectionManager.java index f4077ac3d..442f2ccdd 100644 --- a/course-mw/sunbird-util/sunbird-es-utils/src/main/java/org/sunbird/helper/ConnectionManager.java +++ b/course-mw/sunbird-util/sunbird-es-utils/src/main/java/org/sunbird/helper/ConnectionManager.java @@ -11,6 +11,7 @@ import org.elasticsearch.client.RestHighLevelClient; import org.sunbird.common.models.util.JsonKey; import org.sunbird.common.models.util.LoggerEnum; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; /** @@ -23,6 +24,7 @@ public class ConnectionManager { private static RestHighLevelClient restClient = null; private static List host = new ArrayList<>(); private static List ports = new ArrayList<>(); + public static LoggerUtil logger = new LoggerUtil(ConnectionManager.class); static { System.setProperty("es.set.netty.runtime.available.processors", "false"); @@ -50,17 +52,16 @@ private static boolean initialiseRestClientConnection() { ports.add(Integer.parseInt(val)); } response = createRestClient(cluster, host); - ProjectLogger.log( + logger.info(null, "ELASTIC SEARCH CONNECTION ESTABLISHED for restClient from EVN with Following Details cluster " + cluster + " hostName" + hostName + " port " + port - + response, - LoggerEnum.INFO.name()); + + response); } catch (Exception e) { - ProjectLogger.log("Error while initialising connection for restClient from the Env", e); + logger.error(null, "Error while initialising connection for restClient from the Env", e); return false; } return response; @@ -73,13 +74,11 @@ private static boolean initialiseRestClientConnection() { */ public static RestHighLevelClient getRestClient() { if (restClient == null) { - ProjectLogger.log( - "ConnectionManager:getRestClient eLastic search rest clinet is null ", - LoggerEnum.INFO.name()); + logger.info(null, + "ConnectionManager:getRestClient eLastic search rest clinet is null "); initialiseRestClientConnection(); - ProjectLogger.log( - "ConnectionManager:getRestClient after calling initialiseRestClientConnection ES client value ", - LoggerEnum.INFO.name()); + logger.info(null, + "ConnectionManager:getRestClient after calling initialiseRestClientConnection ES client value "); } return restClient; } @@ -98,8 +97,8 @@ private static boolean createRestClient(String clusterName, List host) { httpHost[i] = new HttpHost(host.get(i), 9200); } restClient = new RestHighLevelClient(RestClient.builder(httpHost)); - ProjectLogger.log( - "ConnectionManager:createRestClient client initialisation done. ", LoggerEnum.INFO.name()); + logger.info(null, + "ConnectionManager:createRestClient client initialisation done. "); return true; } @@ -116,10 +115,9 @@ public void run() { restClient.close(); } catch (IOException e) { e.printStackTrace(); - ProjectLogger.log( + logger.info(null, "ConnectionManager:ResourceCleanUp error occured during restclient resource cleanup " - + e, - LoggerEnum.ERROR.name()); + + e); } } } diff --git a/course-mw/sunbird-util/sunbird-platform-core/actor-core/pom.xml b/course-mw/sunbird-util/sunbird-platform-core/actor-core/pom.xml index 1a67b5e51..a72618a67 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/actor-core/pom.xml +++ b/course-mw/sunbird-util/sunbird-platform-core/actor-core/pom.xml @@ -14,6 +14,16 @@ 2.5.19 + + ch.qos.logback + logback-classic + 1.2.3 + + + net.logstash.logback + logstash-logback-encoder + 6.3 + org.sunbird common-util @@ -34,11 +44,6 @@ reflections 0.9.10 - - log4j - log4j - 1.2.17 - com.fasterxml.jackson.core jackson-core diff --git a/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/core/BaseActor.java b/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/core/BaseActor.java index 0fa22bbb5..f034802aa 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/core/BaseActor.java +++ b/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/core/BaseActor.java @@ -12,6 +12,7 @@ import org.sunbird.actor.service.SunbirdMWService; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.Response; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.request.Request; import org.sunbird.common.responsecode.ResponseCode; @@ -23,17 +24,18 @@ public abstract class BaseActor extends UntypedAbstractActor { public static final int AKKA_WAIT_TIME = 30; protected static Timeout timeout = new Timeout(AKKA_WAIT_TIME, TimeUnit.SECONDS); + public LoggerUtil logger = new LoggerUtil(this.getClass()); @Override public void onReceive(Object message) throws Throwable { if (message instanceof Request) { Request request = (Request) message; String operation = request.getOperation(); - ProjectLogger.log("BaseActor: onReceive called for operation: " + operation); + logger.info(request.getRequestContext(), "BaseActor: onReceive called for operation: " + operation); try { onReceive(request); } catch (Exception e) { - ProjectLogger.log("BaseActor: FAILED onReceive called for operation: " + operation); + logger.info(request.getRequestContext(), "BaseActor: FAILED onReceive called for operation: " + operation); onReceiveException(operation, e); } } @@ -53,12 +55,12 @@ public void unSupportedMessage() throws Exception { } public void onReceiveUnsupportedOperation(String callerName) throws Exception { - ProjectLogger.log(callerName + ": unsupported message"); + logger.info(null, callerName + ": unsupported message"); unSupportedMessage(); } public void onReceiveUnsupportedMessage(String callerName) { - ProjectLogger.log(callerName + ": unsupported operation"); + logger.info(null, callerName + ": unsupported operation"); ProjectCommonException exception = new ProjectCommonException( ResponseCode.invalidOperationName.getErrorCode(), @@ -68,7 +70,7 @@ public void onReceiveUnsupportedMessage(String callerName) { } protected void onReceiveException(String callerName, Exception exception) throws Exception { - ProjectLogger.log( + logger.error(null, "Exception in message processing for: " + callerName + " :: message: " @@ -93,7 +95,7 @@ protected ActorRef getActorRef(String operation) { try { actor = futureActor.toCompletableFuture().get(); } catch (Exception e) { - ProjectLogger.log( + logger.error(null, "InterServiceCommunicationImpl : getResponse - unable to get actorref from actorselection " + e.getMessage(), e); diff --git a/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/core/BaseRouter.java b/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/core/BaseRouter.java index 85b4ada43..ec3570581 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/core/BaseRouter.java +++ b/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/core/BaseRouter.java @@ -113,7 +113,7 @@ public void unSupportedMessage() { @Override public void onReceiveException(String callerName, Exception e) { - ProjectLogger.log(callerName + ": exception in message processing = " + e.getMessage(), e); + logger.error(null, callerName + ": exception in message processing = " + e.getMessage(), e); sender().tell(e, ActorRef.noSender()); } } diff --git a/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/router/RequestRouter.java b/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/router/RequestRouter.java index b396cb5bf..a0f4b7b90 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/router/RequestRouter.java +++ b/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/router/RequestRouter.java @@ -77,12 +77,11 @@ public static String getMode() { */ private boolean route(ActorRef router, Request message, ExecutionContext ec) { long startTime = System.currentTimeMillis(); - ProjectLogger.log( + logger.info(message.getRequestContext(), "Actor Service Call start for api ==" + message.getOperation() + " start time " - + startTime, - LoggerEnum.PERF_LOG); + + startTime); Timeout timeout = new Timeout(Duration.create(message.getTimeout(), TimeUnit.SECONDS)); Future future = Patterns.ask(router, message, timeout); ActorRef parent = sender(); @@ -92,7 +91,7 @@ private boolean route(ActorRef router, Request message, ExecutionContext ec) { public void onComplete(Throwable failure, Object result) { if (failure != null) { // We got a failure, handle it here - ProjectLogger.log(failure.getMessage(), failure); + logger.error(null, failure.getMessage(), failure); if (failure instanceof ProjectCommonException) { parent.tell(failure, self()); } else if (failure instanceof akka.pattern.AskTimeoutException) { diff --git a/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/service/BaseMWService.java b/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/service/BaseMWService.java index 3763c922d..1b103f443 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/service/BaseMWService.java +++ b/course-mw/sunbird-util/sunbird-platform-core/actor-core/src/main/java/org/sunbird/actor/service/BaseMWService.java @@ -15,6 +15,7 @@ import org.sunbird.actor.router.BackgroundRequestRouter; import org.sunbird.actor.router.RequestRouter; import org.sunbird.common.models.util.LoggerEnum; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; /** @author Mahesh Kumar Gangula */ @@ -27,6 +28,7 @@ public class BaseMWService { protected static String name = "SunbirdMWSystem"; protected static ActorRef requestRouter; protected static ActorRef bgRequestRouter; + protected static LoggerUtil logger = new LoggerUtil(BaseMWService.class); protected static String getMode() { if (StringUtils.isBlank(actorMode)) { @@ -75,7 +77,7 @@ protected static ActorSystem getActorSystem(String host, String port) { } else { conf = config.getConfig(name); } - ProjectLogger.log("ActorSystem starting with mode: " + getMode(), LoggerEnum.INFO.name()); + logger.info(null, "ActorSystem starting with mode: " + getMode()); system = ActorSystem.create(name, conf); } return system; @@ -92,7 +94,7 @@ protected static Config getRemoteConfig(String host, String port) { } protected static void initRouters() { - ProjectLogger.log("RequestRouter mode: " + RequestRouter.getMode(), LoggerEnum.INFO.name()); + logger.info(null, "RequestRouter mode: " + RequestRouter.getMode()); if (!RouterMode.OFF.name().equalsIgnoreCase(RequestRouter.getMode())) { requestRouter = system.actorOf( @@ -100,9 +102,8 @@ protected static void initRouters() { .props(Props.create(RequestRouter.class).withDispatcher("rr-dispatcher")), RequestRouter.class.getSimpleName()); } - ProjectLogger.log( - "BackgroundRequestRouter mode: " + BackgroundRequestRouter.getMode(), - LoggerEnum.INFO.name()); + logger.info(null, + "BackgroundRequestRouter mode: " + BackgroundRequestRouter.getMode()); if (!RouterMode.OFF.name().equalsIgnoreCase(BackgroundRequestRouter.getMode())) { bgRequestRouter = system.actorOf( diff --git a/course-mw/sunbird-util/sunbird-platform-core/actor-util/pom.xml b/course-mw/sunbird-util/sunbird-platform-core/actor-util/pom.xml index 546399c48..d9fd56c04 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/actor-util/pom.xml +++ b/course-mw/sunbird-util/sunbird-platform-core/actor-util/pom.xml @@ -64,6 +64,16 @@ sunbird-es-utils 1.0-SNAPSHOT + + ch.qos.logback + logback-classic + 1.2.3 + + + net.logstash.logback + logstash-logback-encoder + 6.3 + diff --git a/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/impl/InterServiceCommunicationImpl.java b/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/impl/InterServiceCommunicationImpl.java index 7cee8c132..e57a3c23f 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/impl/InterServiceCommunicationImpl.java +++ b/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/impl/InterServiceCommunicationImpl.java @@ -7,6 +7,7 @@ import org.sunbird.actorutil.InterServiceCommunication; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.util.LoggerEnum; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.request.Request; import org.sunbird.common.responsecode.ResponseCode; @@ -17,13 +18,14 @@ public class InterServiceCommunicationImpl implements InterServiceCommunication { private Timeout t = new Timeout(Duration.create(10, TimeUnit.SECONDS)); + private LoggerUtil logger = new LoggerUtil(this.getClass()); @Override public Object getResponse(ActorRef actorRef, Request request) { try { return Await.result(getFuture(actorRef, request), t.duration()); } catch (Exception e) { - ProjectLogger.log( + logger.error(request.getRequestContext(), "InterServiceCommunicationImpl:getResponse: Exception occurred with error message = " + e.getMessage(), e); @@ -37,8 +39,8 @@ public Object getResponse(ActorRef actorRef, Request request) { @Override public Future getFuture(ActorRef actorRef, Request request) { if (null == actorRef) { - ProjectLogger.log( - "InterServiceCommunicationImpl:getFuture: actorRef is null", LoggerEnum.INFO); + logger.info(request.getRequestContext(), + "InterServiceCommunicationImpl:getFuture: actorRef is null"); ProjectCommonException.throwServerErrorException( ResponseCode.unableToCommunicateWithActor, ResponseCode.unableToCommunicateWithActor.getErrorMessage()); @@ -46,7 +48,7 @@ public Future getFuture(ActorRef actorRef, Request request) { try { return Patterns.ask(actorRef, request, t); } catch (Exception e) { - ProjectLogger.log( + logger.error(request.getRequestContext(), "InterServiceCommunicationImpl:getFuture: Exception occured with error message = " + e.getMessage(), e); diff --git a/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/location/impl/LocationClientImpl.java b/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/location/impl/LocationClientImpl.java index d0653101f..0d5f73b17 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/location/impl/LocationClientImpl.java +++ b/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/location/impl/LocationClientImpl.java @@ -13,11 +13,7 @@ import org.sunbird.actorutil.location.LocationClient; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.Response; -import org.sunbird.common.models.util.GeoLocationJsonKey; -import org.sunbird.common.models.util.JsonKey; -import org.sunbird.common.models.util.LocationActorOperation; -import org.sunbird.common.models.util.LoggerEnum; -import org.sunbird.common.models.util.ProjectLogger; +import org.sunbird.common.models.util.*; import org.sunbird.common.request.Request; import org.sunbird.common.responsecode.ResponseCode; import org.sunbird.models.location.Location; @@ -28,6 +24,7 @@ public class LocationClientImpl implements LocationClient { private static InterServiceCommunication interServiceCommunication = InterServiceCommunicationFactory.getInstance(); private ObjectMapper mapper = new ObjectMapper(); + private LoggerUtil logger = new LoggerUtil(this.getClass()); @Override public List getLocationsByCodes(ActorRef actorRef, List codeList) { @@ -58,7 +55,7 @@ private List getSearchResponse(ActorRef actorRef, String param, Object Request request = new Request(); request.setOperation(LocationActorOperation.SEARCH_LOCATION.getValue()); request.getRequest().putAll(searchRequestMap); - ProjectLogger.log("LocationClientImpl : callSearchLocation ", LoggerEnum.INFO); + logger.info(null,"LocationClientImpl : callSearchLocation "); Object obj = interServiceCommunication.getResponse(actorRef, request); if (obj instanceof Response) { Response responseObj = (Response) obj; @@ -93,7 +90,7 @@ public String createLocation(ActorRef actorRef, UpsertLocationRequest location) request.getRequest().putAll(mapper.convertValue(location, Map.class)); Map resLocation = new HashMap<>(); request.setOperation(LocationActorOperation.CREATE_LOCATION.getValue()); - ProjectLogger.log("LocationClientImpl : callCreateLocation ", LoggerEnum.INFO); + logger.info(null, "LocationClientImpl : callCreateLocation "); Object obj = interServiceCommunication.getResponse(actorRef, request); checkLocationResponseForException(obj); if (obj instanceof Response) { @@ -108,7 +105,7 @@ public void updateLocation(ActorRef actorRef, UpsertLocationRequest location) { Request request = new Request(); request.getRequest().putAll(mapper.convertValue(location, Map.class)); request.setOperation(LocationActorOperation.UPDATE_LOCATION.getValue()); - ProjectLogger.log("LocationClientImpl : callUpdateLocation ", LoggerEnum.INFO); + logger.info(null, "LocationClientImpl : callUpdateLocation "); Object obj = interServiceCommunication.getResponse(actorRef, request); checkLocationResponseForException(obj); } @@ -122,7 +119,7 @@ public List getRelatedLocationIds(ActorRef actorRef, List codes) request.setOperation(LocationActorOperation.GET_RELATED_LOCATION_IDS.getValue()); request.getRequest().putAll(requestMap); - ProjectLogger.log("LocationClientImpl: getRelatedLocationIds called", LoggerEnum.INFO); + logger.info(null, "LocationClientImpl: getRelatedLocationIds called"); Object obj = interServiceCommunication.getResponse(actorRef, request); checkLocationResponseForException(obj); diff --git a/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/org/impl/OrganisationClientImpl.java b/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/org/impl/OrganisationClientImpl.java index 1365e5f13..c4c1f4b08 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/org/impl/OrganisationClientImpl.java +++ b/course-mw/sunbird-util/sunbird-platform-core/actor-util/src/main/java/org/sunbird/actorutil/org/impl/OrganisationClientImpl.java @@ -17,11 +17,7 @@ import org.sunbird.common.factory.EsClientFactory; import org.sunbird.common.inf.ElasticSearchService; import org.sunbird.common.models.response.Response; -import org.sunbird.common.models.util.ActorOperations; -import org.sunbird.common.models.util.JsonKey; -import org.sunbird.common.models.util.LoggerEnum; -import org.sunbird.common.models.util.ProjectLogger; -import org.sunbird.common.models.util.ProjectUtil; +import org.sunbird.common.models.util.*; import org.sunbird.common.request.Request; import org.sunbird.common.responsecode.ResponseCode; import org.sunbird.dto.SearchDTO; @@ -29,7 +25,7 @@ import scala.concurrent.Future; public class OrganisationClientImpl implements OrganisationClient { - + private LoggerUtil logger = new LoggerUtil(this.getClass()); public static OrganisationClient organisationClient = null; public static OrganisationClient getInstance() { if (organisationClient == null) { @@ -49,13 +45,13 @@ public static OrganisationClient getInstance() { @Override public String createOrg(ActorRef actorRef, Map orgMap) { - ProjectLogger.log("OrganisationClientImpl: createOrg called", LoggerEnum.INFO); + logger.info(null, "OrganisationClientImpl: createOrg called"); return upsertOrg(actorRef, orgMap, ActorOperations.CREATE_ORG.getValue()); } @Override public void updateOrg(ActorRef actorRef, Map orgMap) { - ProjectLogger.log("OrganisationClientImpl: updateOrg called", LoggerEnum.INFO); + logger.info(null, "OrganisationClientImpl: updateOrg called"); upsertOrg(actorRef, orgMap, ActorOperations.UPDATE_ORG.getValue()); } @@ -85,7 +81,7 @@ private String upsertOrg(ActorRef actorRef, Map orgMap, String o @Override public Organisation getOrgById(ActorRef actorRef, String orgId) { - ProjectLogger.log("OrganisationClientImpl: getOrgById called", LoggerEnum.INFO); + logger.info(null, "OrganisationClientImpl: getOrgById called"); Organisation organisation = null; Request request = new Request(); diff --git a/course-mw/sunbird-util/sunbird-platform-core/auth-verifier/pom.xml b/course-mw/sunbird-util/sunbird-platform-core/auth-verifier/pom.xml index 89aab9dfb..f42d214e6 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/auth-verifier/pom.xml +++ b/course-mw/sunbird-util/sunbird-platform-core/auth-verifier/pom.xml @@ -43,6 +43,16 @@ ${powermock.module.junit4.version} test + + ch.qos.logback + logback-classic + 1.2.3 + + + net.logstash.logback + logstash-logback-encoder + 6.3 + diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/pom.xml b/course-mw/sunbird-util/sunbird-platform-core/common-util/pom.xml index a1c4540c8..e540d5e88 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/pom.xml +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/pom.xml @@ -36,14 +36,14 @@ ${learner.akka.version} - org.apache.logging.log4j - log4j-api - 2.8.2 + ch.qos.logback + logback-classic + 1.2.3 - org.apache.logging.log4j - log4j-core - 2.8.2 + net.logstash.logback + logstash-logback-encoder + 6.3 @@ -264,11 +264,6 @@ kafka-clients 0.10.0.1 - - net.logstash.logback - logstash-logback-encoder - 6.3 - diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/CassandraPropertyReader.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/CassandraPropertyReader.java index 9d3c62806..9b73fb648 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/CassandraPropertyReader.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/CassandraPropertyReader.java @@ -2,7 +2,10 @@ import java.io.IOException; import java.io.InputStream; +import java.util.List; +import java.util.Map; import java.util.Properties; +import java.util.stream.Collectors; /** * This class will be used to read cassandratablecolumn properties file. @@ -14,6 +17,7 @@ public class CassandraPropertyReader { private final Properties properties = new Properties(); private static final String file = "cassandratablecolumn.properties"; private static CassandraPropertyReader cassandraPropertyReader = null; + public LoggerUtil logger = new LoggerUtil(this.getClass()); /** private default constructor */ private CassandraPropertyReader() { @@ -21,7 +25,7 @@ private CassandraPropertyReader() { try { properties.load(in); } catch (IOException e) { - ProjectLogger.log("Error in properties cache", e); + logger.error(null, "Error in properties cache", e); } } @@ -45,4 +49,18 @@ public static CassandraPropertyReader getInstance() { public String readProperty(String key) { return properties.getProperty(key) != null ? properties.getProperty(key) : key; } + + /** + * Method to read value from resource file . + * + * @param key to read property key + * @return key corresponding to given value if found else will return value itself. + */ + public String readPropertyValue(String key) { + List> s = properties.entrySet() + .stream() + .filter(entry -> key.equals(entry.getValue())) + .collect(Collectors.toList()); + return s.isEmpty() ? key : (String) s.get(0).getKey(); + } } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/CustomLogFormat.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/CustomLogFormat.java new file mode 100644 index 000000000..ca00a5919 --- /dev/null +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/CustomLogFormat.java @@ -0,0 +1,47 @@ +package org.sunbird.common.models.util; + +import org.sunbird.common.request.RequestContext; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class CustomLogFormat { + private String edataType = "system"; + private String eid = "LOG"; + private String ver = "3.0"; + private Map edata = new HashMap<>(); + private Map eventMap = new HashMap<>(); + + CustomLogFormat(RequestContext requestContext, String msg, Map object, Map params) { + if (params != null) + this.edata.put("params", new ArrayList>(){{add(params);}}); + setEventMap(requestContext, msg); + if (object != null) + this.eventMap.put("object", object); + } + + public Map getEventMap() { + return this.eventMap; + } + + public void setEventMap(RequestContext requestContext, String msg) { + this.edata.put("type", edataType); + this.edata.put("requestid", requestContext.getRequestId()); + this.edata.put("message", msg); + this.edata.put("level", requestContext.getLoggerLevel()); + this.eventMap.putAll(new HashMap() {{ + put("eid", eid); + put("ets", System.currentTimeMillis()); + put("ver", ver); + put("mid", "LOG:" + UUID.randomUUID().toString()); + put("context", requestContext.getContextMap()); + put("actor", new HashMap() {{ + put("id", requestContext.getActorId()); + put("type", requestContext.getActorType()); + }}); + put("edata", edata); + }}); + } +} 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 67a9acac4..d283b5b07 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 @@ -1,5 +1,8 @@ package org.sunbird.common.models.util; +import java.util.ArrayList; +import java.util.List; + /** * This class will contains all the key related to request and response. * @@ -417,7 +420,6 @@ public final class JsonKey { public static final String PHONE_NUMBER_VERIFIED = "phoneNumberVerified"; public static final String PHONE_UNIQUE = "phoneUnique"; public static final String PHONE_VERIFIED = "phoneVerified"; - public static final String PID = "pid"; public static final String PORTAL_MAP = "portalMap"; public static final String PORTAL_SECTIONS = "portalSections"; public static final String POSITION = "position"; @@ -1035,6 +1037,30 @@ public final class JsonKey { public static final String X_AUTH_TOKEN = "X_AUTH_TOKEN"; public static final String TEMPLATE = "template"; public static final String ASSESSMENT_AGGREGATOR_DB = "assessment_aggregator_db"; + public static final String SERVICE_NAME = "course-service"; + public static final String PRODUCER_NAME = "org.sunbird.course-service"; + public static final String PID = "course-service"; + public static final String P_VERSION = "1.0"; + public static final String X_DEVICE_ID = "x-device-id"; + public static final String X_SESSION_ID = "x-session-id"; + public static final String X_TRACE_ID = "x-trace-id"; + public static final String CONVERT_DATE_AS_STRING = "convertDateAsString"; + public static final String USER_ENROLMENTS_DB = "user_enrolments"; + public static final List CHANGE_IN_DATE_FORMAT = new ArrayList() {{add("startDate"); add("endDate"); add("enrollmentEndDate");}}; + public static final String OLD_START_DATE = "oldStartDate"; + public static final String OLD_END_DATE = "oldEndDate"; + public static final String OLD_ENROLLMENT_END_DATE = "oldEnrollmentEndDate"; + public static final String OLD_LAST_ACCESS_TIME = "oldLastAccessTime"; + public static final String OLD_LAST_COMPLETED_TIME = "oldLastCompletedTime"; + public static final String OLD_LAST_UPDATED_TIME = "oldLastUpdatedTime"; + public static final String COURSE_ID_KEY = "courseid"; + public static final String CONTENT_ID_KEY = "contentid"; + public static final String LAST_ACCESS_TIME_KEY = "last_access_time"; + public static final List SET_END_OF_DAY = new ArrayList() {{add("endDate"); add("enrollmentEndDate");}}; + public static final String BATCH_ID_KEY = "batchid"; + public static final String USER_ID_KEY = "userid"; + public static final String OLD_CREATED_DATE = "oldCreatedDate"; + public static final String COURSE_BATCH_PATH = "sunbird_course_batch_path"; private JsonKey() {} } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/KeyCloakConnectionProvider.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/KeyCloakConnectionProvider.java index d88daae12..f2cc75a9c 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/KeyCloakConnectionProvider.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/KeyCloakConnectionProvider.java @@ -17,12 +17,14 @@ public class KeyCloakConnectionProvider { public static String SSO_URL = null; public static String SSO_REALM = null; public static String CLIENT_ID = null; + public static LoggerUtil logger = new LoggerUtil(KeyCloakConnectionProvider.class); + static { try { initialiseConnection(); } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } registerShutDownHook(); } @@ -33,7 +35,7 @@ public class KeyCloakConnectionProvider { * @return Keycloak connection */ public static Keycloak initialiseConnection() throws Exception { - ProjectLogger.log("key cloak instance is creation started."); + logger.info(null, "key cloak instance is creation started."); keycloak = initialiseEnvConnection(); if (keycloak != null) { return keycloak; @@ -58,7 +60,7 @@ public static Keycloak initialiseConnection() throws Exception { CLIENT_ID = cache.getProperty(JsonKey.SSO_CLIENT_ID); keycloak = keycloakBuilder.build(); - ProjectLogger.log("key cloak instance is created successfully."); + logger.info(null, "key cloak instance is created successfully."); return keycloak; } @@ -80,12 +82,12 @@ private static Keycloak initialiseEnvConnection() throws Exception { || StringUtils.isBlank(password) || StringUtils.isBlank(cleintId) || StringUtils.isBlank(relam)) { - ProjectLogger.log( - "key cloak connection is not provided by Environment variable.", LoggerEnum.INFO.name()); + logger.info(null, + "key cloak connection is not provided by Environment variable."); return null; } SSO_URL = url; - ProjectLogger.log("SSO url is==" + SSO_URL, LoggerEnum.INFO.name()); + logger.info(null, "SSO url is==" + SSO_URL); SSO_REALM = relam; CLIENT_ID = cleintId; KeycloakBuilder keycloakBuilder = @@ -102,15 +104,13 @@ private static Keycloak initialiseEnvConnection() throws Exception { if (StringUtils.isNotBlank(clientSecret)) { keycloakBuilder.clientSecret(clientSecret); - ProjectLogger.log( - "KeyCloakConnectionProvider:initialiseEnvConnection client sceret is provided.", - LoggerEnum.INFO.name()); + logger.info(null, + "KeyCloakConnectionProvider:initialiseEnvConnection client sceret is provided."); } keycloakBuilder.grantType("client_credentials"); keycloak = keycloakBuilder.build(); - ProjectLogger.log( - "key cloak instance is created from Environment variable settings .", - LoggerEnum.INFO.name()); + logger.info(null, + "key cloak instance is created from Environment variable settings ."); return keycloak; } @@ -126,7 +126,7 @@ public static Keycloak getConnection() { try { return initialiseConnection(); } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } } return null; @@ -140,9 +140,9 @@ public static Keycloak getConnection() { */ static class ResourceCleanUp extends Thread { public void run() { - ProjectLogger.log("started resource cleanup."); + logger.info(null, "started resource cleanup."); keycloak.close(); - ProjectLogger.log("completed resource cleanup."); + logger.info(null, "completed resource cleanup."); } } @@ -150,6 +150,6 @@ public void run() { public static void registerShutDownHook() { Runtime runtime = Runtime.getRuntime(); runtime.addShutdownHook(new ResourceCleanUp()); - ProjectLogger.log("ShutDownHook registered."); + logger.info(null, "ShutDownHook registered."); } } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/LoggerUtil.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/LoggerUtil.java index 2627d7997..d95d0f186 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/LoggerUtil.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/LoggerUtil.java @@ -1,6 +1,7 @@ package org.sunbird.common.models.util; -import net.logstash.logback.marker.Markers; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,59 +17,71 @@ public class LoggerUtil { private Logger logger; - - public LoggerUtil(Class c) { + private String infoLevel = "INFO"; + private String debugLevel = "DEBUG"; + private String errorLevel = "ERROR"; + private String warnLevel = "WARN"; + private final ObjectMapper mapper = new ObjectMapper(); + + public LoggerUtil(Class c) { logger = LoggerFactory.getLogger(c); } - - public void info(RequestContext requestContext, String message, Object data) { - if(null != requestContext) { - logger.info(Markers.appendEntries(requestContext.getContextMap()), message, data); - } else { - logger.info(message, data); - } - + + public void info(RequestContext requestContext, String message, Map object, Map param) { + if (requestContext != null) { + requestContext.setLoggerLevel(infoLevel); + logger.info(jsonMapper(requestContext, message, object, param)); + } else logger.info(message); } public void info(RequestContext requestContext, String message) { - info(requestContext, message, null); + info(requestContext, message, null, null); } - public void error(RequestContext requestContext, String message, Throwable e) { - if(null != requestContext) { - logger.error(Markers.appendEntries(requestContext.getContextMap()) ,message, e); - } else { - logger.error(message, e); - } + public void debug(RequestContext requestContext, String message, Map object, Map param) { + if (isDebugEnabled(requestContext)) { + requestContext.setLoggerLevel(debugLevel); + logger.info(jsonMapper(requestContext, message, object, param)); + } else logger.debug(message); } - - public void error(RequestContext requestContext, String message, Throwable e, Map telemetryInfo) { - if(null != requestContext) { - logger.error(Markers.appendEntries(requestContext.getContextMap()) ,message, e); - } else { - logger.error(message, e); - } + + public void debug(RequestContext requestContext, String message) { + debug(requestContext, message, null, null); + } + + public void error(RequestContext requestContext, String message, Map object, Map param, Throwable e) { + if (requestContext != null) { + requestContext.setLoggerLevel(errorLevel); + logger.error(jsonMapper(requestContext, message, object, param), e); + } else logger.error(message, e); + } + + public void error(RequestContext requestContext, String message, Map object, Map param, Throwable e, Map telemetryInfo) { + if (requestContext != null) { + requestContext.setLoggerLevel(errorLevel); + logger.error(jsonMapper(requestContext, message, object, param), e); + } else logger.error(message, e); telemetryProcess(requestContext, telemetryInfo, e); } - public void warn(RequestContext requestContext, String message, Throwable e) { - if(null != requestContext) { - logger.warn(Markers.appendEntries(requestContext.getContextMap()), message, e); - } else { - logger.warn(message, e); - } - + public void error(RequestContext requestContext, String message, Throwable e) { + error(requestContext, message, null, null, e); } - - public void debug(RequestContext requestContext, String message, Object data) { - if(isDebugEnabled(requestContext)) { - logger.info(Markers.appendEntries(requestContext.getContextMap()), message, data); - } else { - logger.debug(message, data); - } + + public void error(RequestContext requestContext, String message, Throwable e, Map telemetryInfo) { + error(requestContext, message, null, null, e, telemetryInfo); } - public void debug(RequestContext requestContext, String message) {debug(requestContext, message, null);} + public void warn(RequestContext requestContext, String message, Map object, Map param, Throwable e) { + if (requestContext != null) { + requestContext.setLoggerLevel(warnLevel); + logger.warn((jsonMapper(requestContext, message, object, param)), e); + } else logger.warn(message, e); + } + + public void warn(RequestContext requestContext, String message, Throwable e) { + warn(requestContext, message, null, null, e); + } private static boolean isDebugEnabled(RequestContext requestContext) { return (null != requestContext && StringUtils.equalsIgnoreCase("true", requestContext.getDebugEnabled())); @@ -95,7 +108,7 @@ private void telemetryProcess(RequestContext requestContext, Map // lmaxWriter.submitMessage(request); TelemetryWriter.write(request); } - + private String generateStackTrace(StackTraceElement[] elements) { StringBuilder builder = new StringBuilder(""); for (StackTraceElement element : elements) { @@ -103,4 +116,13 @@ private String generateStackTrace(StackTraceElement[] elements) { } return builder.toString(); } + + private String jsonMapper(RequestContext requestContext, String message, Map object, Map param) { + try { + return mapper.writeValueAsString(new CustomLogFormat(requestContext, message, object, param).getEventMap()); + } catch (JsonProcessingException e) { + error(requestContext, e.getMessage(), e); + } + return ""; + } } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/ProjectUtil.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/ProjectUtil.java index 2b9d023e5..ece3c6b42 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/ProjectUtil.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/ProjectUtil.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; +import java.sql.Timestamp; import java.text.MessageFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -16,6 +17,7 @@ import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.commons.validator.UrlValidator; +import org.apache.hadoop.util.Time; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; @@ -38,6 +40,7 @@ public class ProjectUtil { public static final String ELASTIC_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; public static final String YEAR_MONTH_DATE_FORMAT = "yyyy-MM-dd"; private static final int randomPasswordLength = 9; + private static LoggerUtil logger = new LoggerUtil(ProjectUtil.class); protected static final String FILE_NAME[] = { "cassandratablecolumn.properties", @@ -265,6 +268,15 @@ public static String getFormattedDate() { return getDateFormatter().format(new Date()); } + /** + * This method will provide timestamp + * + * @return + */ + public static Date getTimeStamp() { + return new Timestamp(System.currentTimeMillis()); + } + /** * This method will provide formatted date * @@ -586,7 +598,7 @@ private static String getSunbirdLogoUrl(Map map) { if (StringUtils.isBlank(logoUrl)) { logoUrl = getConfigValue(JsonKey.SUNBIRD_ENV_LOGO_URL); } - ProjectLogger.log("ProjectUtil:getSunbirdLogoUrl: url = " + logoUrl, LoggerEnum.INFO.name()); + logger.info(null,"ProjectUtil:getSunbirdLogoUrl: url = " + logoUrl); return logoUrl; } @@ -605,7 +617,7 @@ private static String getFromEmail(Map map) { if (StringUtils.isBlank(fromEmail)) { fromEmail = getConfigValue(JsonKey.EMAIL_SERVER_FROM); } - ProjectLogger.log("ProjectUtil:getFromEmail: fromEmail = " + fromEmail, LoggerEnum.INFO.name()); + logger.info(null,"ProjectUtil:getFromEmail: fromEmail = " + fromEmail); return fromEmail; } @@ -671,7 +683,7 @@ public static String registertag(String tagId, String body, Map throws Exception { String tagStatus = ""; try { - ProjectLogger.log("start call for registering the tag ==" + tagId); + logger.info(null,"start call for registering the tag ==" + tagId); String analyticsBaseUrl = getConfigValue(JsonKey.ANALYTICS_API_BASE_URL); tagStatus = HttpUtil.sendPostRequest( @@ -681,7 +693,7 @@ public static String registertag(String tagId, String body, Map + tagId, body, header); - ProjectLogger.log( + logger.info(null, "end call for tag registration id and status ==" + tagId + " " + tagStatus); } catch (Exception e) { throw e; @@ -760,8 +772,8 @@ public static boolean validatePhone(String phNumber, String countryCode) { phoneNumber = phoneNumberUtil.parse(phNumber, isoCode); return phoneNumberUtil.isValidNumber(phoneNumber); } catch (NumberParseException e) { - ProjectLogger.log("Exception occurred while validating phone number : ", e); - ProjectLogger.log(phNumber + "this phone no. is not a valid one."); + logger.error(null,"Exception occurred while validating phone number : ", e); + logger.info(null,phNumber + "this phone no. is not a valid one."); } return false; } @@ -799,7 +811,7 @@ public static String getSMSBody(Map smsTemplate) { t.merge(context, writer); return writer.toString(); } catch (Exception ex) { - ProjectLogger.log("Exception occurred while formating and sending SMS " + ex); + logger.error(null,"Exception occurred while formating and sending SMS ", ex); } return ""; } @@ -813,7 +825,7 @@ public static boolean isDateValidFormat(String format, String value) { date = null; } } catch (ParseException ex) { - ProjectLogger.log(ex.getMessage(), ex); + logger.error(null, ex.getMessage(), ex); } return date != null; } @@ -911,7 +923,7 @@ public static String convertMapToJsonString(List> mapList) { try { return mapper.writeValueAsString(mapList); } catch (IOException e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } return null; } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/Slug.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/Slug.java index da58937d2..04834715c 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/Slug.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/Slug.java @@ -21,13 +21,14 @@ public class Slug { private static final Pattern NONLATIN = Pattern.compile("[^\\w-\\.]"); private static final Pattern WHITESPACE = Pattern.compile("[\\s]"); private static final Pattern DUPDASH = Pattern.compile("-+"); + private static LoggerUtil logger = new LoggerUtil(Slug.class); public static String makeSlug(String input, boolean transliterate) { String origInput = input; String tempInputValue = ""; // Validate the input if (input == null) { - ProjectLogger.log("Provided input value is null"); + logger.info(null, "Provided input value is null"); return input; } // Remove extra spaces @@ -57,7 +58,7 @@ public static String makeSlug(String input, boolean transliterate) { private static void validateResult(String input, String origInput) { // Check if we are not left with a blank if (input.length() == 0) { - ProjectLogger.log("Failed to cleanup the input " + origInput); + logger.info(null,"Failed to cleanup the input " + origInput); } } @@ -70,7 +71,7 @@ public static String urlDecode(String input) { try { value = URLDecoder.decode(input, "UTF-8"); } catch (Exception ex) { - ProjectLogger.log(ex.getMessage(), ex); + logger.error(null, ex.getMessage(), ex); } return value; } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/azure/AzureFileUtility.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/azure/AzureFileUtility.java index 0d5e1c14e..f619776a2 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/azure/AzureFileUtility.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/models/util/azure/AzureFileUtility.java @@ -15,12 +15,15 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.tika.Tika; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; +import org.sunbird.common.models.util.Slug; /** @author Manzarul */ public class AzureFileUtility { private static final String DEFAULT_CONTAINER = "default"; + private static LoggerUtil logger = new LoggerUtil(Slug.class); /** * This method will remove the file from Azure Storage. @@ -31,16 +34,16 @@ public class AzureFileUtility { */ public static boolean deleteFile(String containerName, String fileName) { if (fileName == null) { - ProjectLogger.log("File name can not be null"); + logger.info(null,"File name can not be null"); return false; } if (StringUtils.isBlank(containerName)) { - ProjectLogger.log("Container name can't be null or empty"); + logger.info(null,"Container name can't be null or empty"); return false; } CloudBlobContainer container = AzureConnectionManager.getContainer(containerName, true); if (container == null) { - ProjectLogger.log("Unable to get Azure contains object"); + logger.info(null,"Unable to get Azure contains object"); return false; } try { @@ -49,11 +52,11 @@ public static boolean deleteFile(String containerName, String fileName) { // Delete the blob. boolean response = blob.deleteIfExists(); if (!response) { - ProjectLogger.log("Provided file not found to delete."); + logger.info(null,"Provided file not found to delete."); } return true; } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } return false; } @@ -66,24 +69,24 @@ public static boolean deleteFile(String containerName, String fileName) { */ public static boolean deleteContainer(String containerName) { if (StringUtils.isBlank(containerName)) { - ProjectLogger.log("Container name can't be null or empty"); + logger.info(null,"Container name can't be null or empty"); return false; } CloudBlobContainer container = AzureConnectionManager.getContainer(containerName, true); if (container == null) { - ProjectLogger.log("Unable to get Azure contains object"); + logger.info(null,"Unable to get Azure contains object"); return false; } try { boolean response = container.deleteIfExists(); if (!response) { - ProjectLogger.log("Container not found.."); + logger.info(null,"Container not found.."); } else { - ProjectLogger.log("Container is deleted==="); + logger.info(null,"Container is deleted==="); } return true; } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } return false; } @@ -101,21 +104,21 @@ public static String uploadFile(String containerName, String blobName, String fi File source = new File(fileName); fis = new FileInputStream(source); String mimeType = tika.detect(source); - ProjectLogger.log("File - " + source.getName() + " mimeType " + mimeType); + logger.info(null,"File - " + source.getName() + " mimeType " + mimeType); blob.getProperties().setContentType(mimeType); blob.upload(fis, source.length()); // fileUrl = blob.getStorageUri().getPrimaryUri().getPath(); fileUrl = blob.getUri().toString(); } catch (URISyntaxException | IOException e) { - ProjectLogger.log("Unable to upload file :" + fileName, e); + logger.error(null,"Unable to upload file :" + fileName, e); } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } finally { if (null != fis) { try { fis.close(); } catch (IOException e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } } } @@ -160,21 +163,21 @@ public static String uploadFile(String containerName, File source) { // File source = new File(fileName); fis = new FileInputStream(source); String mimeType = tika.detect(source); - ProjectLogger.log("File - " + source.getName() + " mimeType " + mimeType); + logger.info(null,"File - " + source.getName() + " mimeType " + mimeType); blob.getProperties().setContentType(mimeType); blob.upload(fis, source.length()); // fileUrl = blob.getStorageUri().getPrimaryUri().getPath(); fileUrl = blob.getUri().toString(); } catch (URISyntaxException | IOException e) { - ProjectLogger.log("Unable to upload file :" + source.getName(), e); + logger.error(null,"Unable to upload file :" + source.getName(), e); } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } finally { if (null != fis) { try { fis.close(); } catch (IOException e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } } } @@ -201,15 +204,15 @@ public static boolean downloadFile(String containerName, String blobName, String blob.download(fos); } } catch (URISyntaxException | StorageException | FileNotFoundException e) { - ProjectLogger.log("Unable to upload blobfile :" + blobName, e); + logger.error(null,"Unable to upload blobfile :" + blobName, e); } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } finally { if (null != fos) { try { fos.close(); } catch (IOException e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } } } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/BaseRequestValidator.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/BaseRequestValidator.java index 2dd730e69..c385ff153 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/BaseRequestValidator.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/BaseRequestValidator.java @@ -8,12 +8,7 @@ import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.sunbird.common.exception.ProjectCommonException; -import org.sunbird.common.models.util.EmailValidator; -import org.sunbird.common.models.util.JsonKey; -import org.sunbird.common.models.util.LoggerEnum; -import org.sunbird.common.models.util.ProjectLogger; -import org.sunbird.common.models.util.ProjectUtil; -import org.sunbird.common.models.util.StringFormatter; +import org.sunbird.common.models.util.*; import org.sunbird.common.responsecode.ResponseCode; /** @@ -22,6 +17,7 @@ * @author B Vinaya Kumar */ public class BaseRequestValidator { + public LoggerUtil logger = new LoggerUtil(this.getClass()); /** * Helper method which throws an exception if given parameter value is blank (null or empty). @@ -94,7 +90,7 @@ public void validateListParamSize(String paramName, String key, List lis */ public ProjectCommonException createExceptionByResponseCode(ResponseCode code, int errorCode) { if (code == null) { - ProjectLogger.log("ResponseCode object is coming as null", LoggerEnum.INFO.name()); + logger.info(null, "ResponseCode object is coming as null"); return new ProjectCommonException( ResponseCode.invalidData.getErrorCode(), ResponseCode.invalidData.getErrorMessage(), @@ -114,7 +110,7 @@ public ProjectCommonException createExceptionByResponseCode(ResponseCode code, i public ProjectCommonException createExceptionByResponseCode( ResponseCode code, int errorCode, String errorMsgArgument) { if (code == null) { - ProjectLogger.log("ResponseCode object is coming as null", LoggerEnum.INFO.name()); + logger.info(null, "ResponseCode object is coming as null"); return new ProjectCommonException( ResponseCode.invalidData.getErrorCode(), ResponseCode.invalidData.getErrorMessage(), diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/Request.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/Request.java index 969e56adc..23544b214 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/Request.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/Request.java @@ -183,4 +183,12 @@ public RequestContext getRequestContext() { public void setRequestContext(RequestContext requestContext) { this.requestContext = requestContext; } + + public Object getOrDefault(String key, Object defaultVal) { + return request.getOrDefault(key, defaultVal); + } + + public Boolean contains(String key) { + return request.containsKey(key); + } } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/RequestContext.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/RequestContext.java index e7621b996..604484e05 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/RequestContext.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/request/RequestContext.java @@ -1,8 +1,7 @@ package org.sunbird.common.request; -import org.sunbird.common.util.JsonUtil; - import java.util.HashMap; +import java.util.List; import java.util.Map; public class RequestContext { @@ -10,81 +9,76 @@ public class RequestContext { private String uid; private String did; private String sid; - private String appId; - private String appVer; - private String reqId; private String debugEnabled; - private String op; - private final String pid = "lms-service"; + private String actorId; + private String actorType; + private String loggerLevel; + private String requestId; + private String env; private Map contextMap = new HashMap<>(); - - - public RequestContext(String uid, String did, String sid, String appId, String appVer, String reqId, String debugEnabled, String op) { - this.uid = uid; + private String channel; + private Map pdata = new HashMap<>(); + + public RequestContext(String channel, String pdataId, String env, String did, String sid, String pid, String pver, List cdata) { this.did = did; this.sid = sid; - this.appId = appId; - this.appVer = appVer; - this.reqId = reqId; - this.debugEnabled = debugEnabled; - this.op = op; - - contextMap.putAll(new HashMap(){{ - put("uid", uid); + this.channel = channel; + this.pdata.put("id", pdataId); + this.pdata.put("pid", pid); + this.pdata.put("ver", pver); + this.contextMap.putAll(new HashMap() {{ put("did", did); put("sid", sid); - put("appId", appId); - put("appVer", appVer); - put("reqId", reqId); - put("op", op); + put("channel", channel); + put("env", env); + put("pdata", pdata); + if (cdata != null) + put("cdata", cdata); }}); - } - - - public String getReqId() { - return reqId; + public String getActorId() { + return actorId; } - - public String getActorOperation() { - return op; + public void setActorId(String actorId) { + this.actorId = actorId; } - public void setActorOperation(String actorOperation) { - this.op = actorOperation; + public String getActorType() { + return actorType; } - public String getUid() { - return uid; + public void setActorType(String actorType) { + this.actorType = actorType; } - - public String getDid() { - return did; + public String getLoggerLevel() { + return loggerLevel; } - - public String getSid() { - return sid; + public void setLoggerLevel(String loggerLevel) { + this.loggerLevel = loggerLevel; } - public String getAppId() { - return appId; + public String getRequestId() { + return requestId; } - - public String getAppVer() { - return appVer; + public void setRequestId(String requestId) { + this.requestId = requestId; } public String getDebugEnabled() { return debugEnabled; } - public String getOp() { - return op; + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; } public Map getContextMap() { diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/util/JsonUtil.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/util/JsonUtil.java index 636bd5a68..c9e6a2623 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/util/JsonUtil.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/common/util/JsonUtil.java @@ -4,15 +4,18 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.InputStream; +import java.text.SimpleDateFormat; public class JsonUtil { private static ObjectMapper mapper = new ObjectMapper(); + private static ObjectMapper mapperWithDateFormat = new ObjectMapper(); static { mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } public static String serialize(Object obj) throws Exception { + mapper.configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS , false); return mapper.writeValueAsString(obj); } @@ -27,4 +30,10 @@ public static T deserialize(InputStream value, Class clazz) throws Except public static T convert(Object value, Class clazz) throws Exception { return mapper.convertValue(value, clazz); } + + // pass @dateFormat with timezone for serialization of dateType variables + public static T convertWithDateFormat(Object value, Class clazz, SimpleDateFormat dateFormat) throws Exception { + mapperWithDateFormat.setDateFormat(dateFormat); + return mapperWithDateFormat.convertValue(value, clazz); + } } diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/kafka/client/KafkaClient.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/kafka/client/KafkaClient.java index 0e22edc1b..b728f9c46 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/kafka/client/KafkaClient.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/kafka/client/KafkaClient.java @@ -15,6 +15,7 @@ import org.apache.kafka.common.serialization.StringSerializer; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.util.LoggerEnum; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.models.util.ProjectUtil; import org.sunbird.common.responsecode.ResponseCode; @@ -30,6 +31,7 @@ public class KafkaClient { private static Producer producer; private static Consumer consumer; private static volatile Map> topics; + public static LoggerUtil logger = new LoggerUtil(KafkaClient.class); static { loadProducerProperties(); @@ -52,8 +54,8 @@ private static void loadTopics() { loadConsumerProperties(); } topics = consumer.listTopics(); - ProjectLogger.log( - "KafkaClient:loadTopics Kafka topic infos =>" + topics, LoggerEnum.INFO.name()); + logger.info(null, + "KafkaClient:loadTopics Kafka topic infos =>" + topics); } private static void loadConsumerProperties() { @@ -79,7 +81,7 @@ public static void send(String event, String topic) throws Exception { ProducerRecord record = new ProducerRecord(topic, event); producer.send(record); } else { - ProjectLogger.log("Topic id: " + topic + ", does not exists.", LoggerEnum.ERROR); + logger.error(null, "Topic id: " + topic + ", does not exists.", null); throw new ProjectCommonException( "TOPIC_NOT_EXISTS_EXCEPTION", "Topic id: " + topic + ", does not exists.", @@ -93,7 +95,7 @@ public static void send(String key, String event, String topic) throws Exception ProducerRecord record = new ProducerRecord(topic, key, event); producer.send(record); } else { - ProjectLogger.log("Topic id: " + topic + ", does not exists.", LoggerEnum.ERROR); + logger.error(null, "Topic id: " + topic + ", does not exists.", null); throw new ProjectCommonException( "TOPIC_NOT_EXISTS_EXCEPTION", "Topic id: " + topic + ", does not exists.", diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/services/sso/impl/KeyCloakServiceImpl.java b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/services/sso/impl/KeyCloakServiceImpl.java index 8a0f30527..ec0d40e7a 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/services/sso/impl/KeyCloakServiceImpl.java +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/java/org/sunbird/services/sso/impl/KeyCloakServiceImpl.java @@ -22,12 +22,7 @@ import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.sunbird.common.exception.ProjectCommonException; -import org.sunbird.common.models.util.JsonKey; -import org.sunbird.common.models.util.KeyCloakConnectionProvider; -import org.sunbird.common.models.util.LoggerEnum; -import org.sunbird.common.models.util.ProjectLogger; -import org.sunbird.common.models.util.ProjectUtil; -import org.sunbird.common.models.util.PropertiesCache; +import org.sunbird.common.models.util.*; import org.sunbird.common.responsecode.ResponseCode; import org.sunbird.common.util.KeycloakRequiredActionLinkUtil; import org.sunbird.services.sso.SSOManager; @@ -47,10 +42,11 @@ public class KeyCloakServiceImpl implements SSOManager { + "/protocol/openid-connect/token"; private static PublicKey SSO_PUBLIC_KEY = null; + private static LoggerUtil logger = new LoggerUtil(Slug.class); public PublicKey getPublicKey() { if (null == SSO_PUBLIC_KEY) { - ProjectLogger.log("KeyCloakService - Empty Key. So, generating public key from Env."); + logger.info(null,"KeyCloakService - Empty Key. So, generating public key from Env."); SSO_PUBLIC_KEY = toPublicKey(System.getenv(JsonKey.SSO_PUBLIC_KEY)); } return SSO_PUBLIC_KEY; @@ -94,9 +90,8 @@ public boolean updatePassword(String userId, String password) { ur.resetPassword(cr); return true; } catch (Exception e) { - ProjectLogger.log( - "KeyCloakServiceImpl:updatePassword: Exception occurred with error message = " + e, - LoggerEnum.ERROR.name()); + logger.error(null, + "KeyCloakServiceImpl:updatePassword: Exception occurred with error message = " + e, e); } return false; } @@ -205,7 +200,7 @@ public String syncUserData(Map request) { needTobeUpdate = true; ur.setEmail((String) request.get(JsonKey.EMAIL)); } - ProjectLogger.log( + logger.info(null, "check user email is verified or not ,resource.toRepresentation().isEmailVerified() :" + resource.toRepresentation().isEmailVerified() + " for userId :" @@ -331,9 +326,8 @@ public String activateUser(Map request) { private void makeUserActiveOrInactive(String userId, boolean status) { try { String fedUserId = getFederatedUserId(userId); - ProjectLogger.log( - "KeyCloakServiceImpl:makeUserActiveOrInactive: fedration id formed: " + fedUserId, - LoggerEnum.INFO.name()); + logger.info(null, + "KeyCloakServiceImpl:makeUserActiveOrInactive: fedration id formed: " + fedUserId); validateUserId(fedUserId); Keycloak keycloak = KeyCloakConnectionProvider.getConnection(); UserResource resource = @@ -344,9 +338,8 @@ private void makeUserActiveOrInactive(String userId, boolean status) { resource.update(ur); } } catch (Exception e) { - ProjectLogger.log( - "KeyCloakServiceImpl:makeUserActiveOrInactive:error occurred while blocking user: " + e, - LoggerEnum.ERROR.name()); + logger.error(null, + "KeyCloakServiceImpl:makeUserActiveOrInactive:error occurred while blocking user: " + e, e); ProjectUtil.createAndThrowInvalidUserDataException(); } } @@ -431,7 +424,7 @@ public boolean doPasswordUpdate(String userId, String password) { resource.resetPassword(newCredential); response = true; } catch (Exception ex) { - ProjectLogger.log(ex.getMessage(), ex); + logger.error(null,ex.getMessage(), ex); } return response; } @@ -453,7 +446,7 @@ public String getLastLoginTime(String userId) { lastLoginTime = list.get(0); } } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null,e.getMessage(), e); } return lastLoginTime; } @@ -485,7 +478,7 @@ public boolean addUserLoginTime(String userId) { ur.setAttributes(map); resource.update(ur); } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null,e.getMessage(), e); response = false; } return response; @@ -529,7 +522,7 @@ private void updateEmailVerifyStatus(String userId, boolean status) { resource.update(ur); } } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null,e.getMessage(), e); ProjectUtil.createAndThrowInvalidUserDataException(); } } @@ -557,16 +550,15 @@ public String getUsernameById(String userId) { UserRepresentation ur = resource.toRepresentation(); return ur.getUsername(); } catch (Exception e) { - ProjectLogger.log( + logger.error(null, "KeyCloakServiceImpl:getUsernameById: User not found for userId = " + userId + " error message = " + e.getMessage(), e); } - ProjectLogger.log( - "KeyCloakServiceImpl:getUsernameById: User not found for userId = " + userId, - LoggerEnum.INFO.name()); + logger.info(null, + "KeyCloakServiceImpl:getUsernameById: User not found for userId = " + userId); return ""; } @@ -584,7 +576,7 @@ public String verifyToken(String accessToken, String url, boolean checkActive) { ssoUrl + "realms/" + KeyCloakConnectionProvider.SSO_REALM, checkActive, true); - ProjectLogger.log( + logger.info(null, token.getId() + " " + token.issuedFor @@ -597,8 +589,7 @@ public String verifyToken(String accessToken, String url, boolean checkActive) { + " isExpired: " + token.isExpired() + " " - + token.issuedNow().getExpiration(), - LoggerEnum.INFO.name()); + + token.issuedNow().getExpiration()); String tokenSubject = token.getSubject(); if (StringUtils.isNotBlank(tokenSubject)) { int pos = tokenSubject.lastIndexOf(":"); @@ -606,17 +597,16 @@ public String verifyToken(String accessToken, String url, boolean checkActive) { } return token.getSubject(); } else { - ProjectLogger.log( - "KeyCloakServiceImpl:verifyToken: SSO_PUBLIC_KEY is NULL.", LoggerEnum.ERROR); + logger.error(null, + "KeyCloakServiceImpl:verifyToken: SSO_PUBLIC_KEY is NULL.", null); throw new ProjectCommonException( ResponseCode.keyCloakDefaultError.getErrorCode(), ResponseCode.keyCloakDefaultError.getErrorMessage(), ResponseCode.keyCloakDefaultError.getResponseCode()); } } catch (Exception e) { - ProjectLogger.log( - "KeyCloakServiceImpl:verifyToken: Exception occurred with message = " + e.getMessage(), - LoggerEnum.ERROR); + logger.error(null, + "KeyCloakServiceImpl:verifyToken: Exception occurred with message = " + e.getMessage(), e); throw new ProjectCommonException( ResponseCode.unAuthorized.getErrorCode(), ResponseCode.unAuthorized.getErrorMessage(), diff --git a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/resources/cassandratablecolumn.properties b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/resources/cassandratablecolumn.properties index 945c21446..8bcda64ac 100644 --- a/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/resources/cassandratablecolumn.properties +++ b/course-mw/sunbird-util/sunbird-platform-core/common-util/src/main/resources/cassandratablecolumn.properties @@ -2,7 +2,6 @@ id=id courseid=courseId coursename=courseName userid=userId -enrolleddate=enrolledDate description=description tocurl=tocUrl status=status @@ -18,28 +17,22 @@ datetime=dateTime contentid=contentId viewposition=viewPosition viewcount=viewCount -lastaccesstime=lastAccessTime completedcount=completedCount position=position result=result score= score contentversion=contentVersion -lastupdatedtime=lastUpdatedTime -lastcompletedtime=lastCompletedTime facultyid=facultyId facultyname=facultyName organisationid=organisationId organisationname=organisationName enrollementstartdate=enrollementStartDate -enrollmentenddate=enrollmentEndDate courseduration=courseDuration addedbyid=addedById addedbyname=addedByName publishedbyid=publishedById publishedbyname=publishedByName -createddate=createdDate publisheddate=publishedDate -updateddate=updatedDate updatedbyid=updatedById updatedbyname=updatedByName createdfor=createdFor @@ -94,7 +87,6 @@ yearofpassing=yearOfPassing boardoruniversity=boardOrUniversity jobname=jobName joiningdate=joiningDate -enddate=endDate orgid=orgId orgname=orgName boardname=boardName @@ -139,8 +131,6 @@ processendtime=processEndTime enrollmenttype=enrollmentType participant=participant enrolmenttype=enrolmentType -startdate=startDate -enddate=endDate lastupdatedon=lastUpdatedOn createdfor=createdFor coursecreator=courseCreator @@ -251,4 +241,22 @@ issued_certificates=issuedCertificates attempt_id=attemptId last_attempted_on=lastAttemptedOn total_max_score=totalMaxScore -total_score=totalScore \ No newline at end of file +total_score=totalScore +createddate=oldCreatedDate +startdate=oldStartDate +enddate=oldEndDate +enrollmentenddate=oldEnrollmentEndDate +updateddate=oldUpdatedDate +enrolleddate=oldEnrolledDate +lastupdatedtime=oldLastUpdatedTime +lastaccesstime=oldLastAccessTime +lastcompletedtime=oldLastCompletedTime +created_date=createdDate +start_date=startDate +end_date=endDate +enrollment_enddate=enrollmentEndDate +updated_date=updatedDate +enrolled_date=enrolledDate +last_access_time=lastAccessTime +last_completed_time=lastCompletedTime +last_updated_time=lastUpdatedTime \ No newline at end of file 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 c9e4c2e9b..09d66c743 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 @@ -13,7 +13,7 @@ sunbird_search_service_api_base_url=https://dev.sunbirded.org/action ekstep_api_base_url=https://dev.sunbirded.org/action sunbird_user_org_api_base_url=https://dev.sunbirded.org/api sunbird_search_organisation_api=/v1/org/search -sunbird_read_user_api=/v1/user/read +sunbird_read_user_api=/private/user/v1/read sunbird_search_user_api=/v1/user/search sunbird_send_email_notifictaion_api=/v1/notification/email sunbird_mail_server_host= @@ -203,3 +203,4 @@ kafka_assessment_topic= sunbird_msg_sender= sunbird_msg_91_auth= sunbird_api_mgr_base_url=https://dev.sunbirded.org/api +sunbird_course_batch_path=/app/toc/{courseId}/overview?batchId={batchId} \ No newline at end of file diff --git a/course-mw/textbook-actors/pom.xml b/course-mw/textbook-actors/pom.xml index 42a25cd3b..32a1071d9 100644 --- a/course-mw/textbook-actors/pom.xml +++ b/course-mw/textbook-actors/pom.xml @@ -15,6 +15,16 @@ UTF-8 + + ch.qos.logback + logback-classic + 1.2.3 + + + net.logstash.logback + logstash-logback-encoder + 6.3 + org.sunbird course-actors-common diff --git a/course-mw/textbook-actors/src/main/java/org/sunbird/content/util/TextBookTocUtil.java b/course-mw/textbook-actors/src/main/java/org/sunbird/content/util/TextBookTocUtil.java index 9d1d0d429..98a6bb390 100644 --- a/course-mw/textbook-actors/src/main/java/org/sunbird/content/util/TextBookTocUtil.java +++ b/course-mw/textbook-actors/src/main/java/org/sunbird/content/util/TextBookTocUtil.java @@ -102,10 +102,10 @@ private static Response handleReadRequest( response.getResponseCode().getResponseCode()); } } catch (IOException e) { - logger.info(null, "TextBookTocUtil:handleReadRequest: Exception occurred with error message = " + e.getMessage(), e); + logger.error(null, "TextBookTocUtil:handleReadRequest: Exception occurred with error message = " + e.getMessage(), e); throwServerErrorException(ResponseCode.SERVER_ERROR); } catch (UnirestException e) { - logger.info(null, "TextBookTocUtil:handleReadRequest: Exception occurred with error message = " + e.getMessage(), e); + logger.error(null, "TextBookTocUtil:handleReadRequest: Exception occurred with error message = " + e.getMessage(), e); throwServerErrorException(ResponseCode.SERVER_ERROR); } return response; diff --git a/course-mw/textbook-actors/src/main/java/org/sunbird/learner/actors/textbook/TextbookTocActor.java b/course-mw/textbook-actors/src/main/java/org/sunbird/learner/actors/textbook/TextbookTocActor.java index c92e3b09a..3479ffcaa 100644 --- a/course-mw/textbook-actors/src/main/java/org/sunbird/learner/actors/textbook/TextbookTocActor.java +++ b/course-mw/textbook-actors/src/main/java/org/sunbird/learner/actors/textbook/TextbookTocActor.java @@ -519,7 +519,7 @@ private List callDialcodeSearchApi(Set dialCodes, String channel } } } catch (Exception ex) { - logger.info(null, + logger.error(null, "TextbookTocActor:callDialcodeSearchApi : Exception occurred with message:" + ex.getMessage(), ex); @@ -715,9 +715,8 @@ private Map readAndValidateCSV(InputStream inputStream) throws I try { if (null != csvFileParser) csvFileParser.close(); } catch (IOException e) { - logger.info(null, - "TextbookTocActor:readAndValidateCSV : Exception occurred while closing stream", - LoggerEnum.ERROR); + logger.error(null, + "TextbookTocActor:readAndValidateCSV : Exception occurred while closing stream", e); } } return result; @@ -1032,7 +1031,7 @@ private Response callUpdateHierarchyAndLinkDialCodeApi( "Timed:TextbookTocActor:callUpdateHierarchyAndLinkDialCodeApi duration for link dial code: " + (Instant.now().toEpochMilli() - startTime.toEpochMilli())); } catch (Exception ex) { - logger.info(null, + logger.error(null, "TextbookTocActor:callUpdateHierarchyAndLinkDialCodeApi : Exception occurred while linking dial code : ", ex); response @@ -1424,7 +1423,7 @@ private Response updateHierarchy(String tbId, Map updateRequest) .body(mapper.writeValueAsString(updateRequest)) .asString(); } catch (Exception ex) { - logger.info(null, "TextbookTocActor:updateHierarchy : Update response call ", ex); + logger.error(null, "TextbookTocActor:updateHierarchy : Update response call ", ex); } logger.info(null, "TextbookTocActor:updateHierarchy : access token : " + mapper.writeValueAsString(headers)); @@ -1463,7 +1462,7 @@ private Response updateHierarchy(String tbId, Map updateRequest) ResponseCode.CLIENT_ERROR.getResponseCode()); } } catch (Exception ex) { - logger.info(null, + logger.error(null, "TextbookTocActor:updateHierarchy : Update response body " + updateResponse.getBody(), ex); if (ex instanceof ProjectCommonException) { diff --git a/pom.xml b/pom.xml index 8a15e3865..65ebecce4 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,10 @@ sunbird_lms_service - 1.0.0-rc5 + 11 + 11 + 11 + 1.0.0-rc5 diff --git a/service/app/controllers/BaseController.java b/service/app/controllers/BaseController.java index 2cf097181..6a01bd51c 100644 --- a/service/app/controllers/BaseController.java +++ b/service/app/controllers/BaseController.java @@ -18,6 +18,7 @@ import org.sunbird.common.models.util.LoggerEnum; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.models.util.ProjectUtil; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.request.HeaderParam; import org.sunbird.common.request.RequestContext; import org.sunbird.common.responsecode.ResponseCode; @@ -59,13 +60,14 @@ public class BaseController extends Controller { public static final int AKKA_WAIT_TIME = 30; protected Timeout timeout = new Timeout(AKKA_WAIT_TIME, TimeUnit.SECONDS); private static final String debugEnabled = "false"; + public static final LoggerUtil logger = new LoggerUtil(BaseController.class); private org.sunbird.common.request.Request initRequest( org.sunbird.common.request.Request request, String operation, Http.Request httpRequest) { request.setOperation(operation); request.setRequestId(httpRequest.attrs().getOptional(Attrs.REQUEST_ID).orElse(null)); request.setEnv(getEnvironment()); - request.setRequestContext(getRequestContext(httpRequest, operation)); + request.setRequestContext(getRequestContext(httpRequest, request)); request.getContext().put(JsonKey.REQUESTED_BY, httpRequest.attrs().getOptional(Attrs.USER_ID).orElse(null)); if (StringUtils.isNotBlank(httpRequest.attrs().getOptional(Attrs.REQUESTED_FOR).orElse(null))) request.getContext().put(SunbirdKey.REQUESTED_FOR, httpRequest.attrs().get(Attrs.REQUESTED_FOR)); @@ -74,13 +76,17 @@ private org.sunbird.common.request.Request initRequest( return request; } - private RequestContext getRequestContext(Request httpRequest, String actorOperation) { - RequestContext requestContext = new RequestContext(httpRequest.attrs().getOptional(Attrs.USER_ID).orElse(null), - httpRequest.header("x-device-id").orElse(null), httpRequest.header("x-session-id").orElse(null), - httpRequest.header("x-app-id").orElse(null), httpRequest.header("x-app-ver").orElse(null), - httpRequest.header("x-trace-id").orElse(UUID.randomUUID().toString()), - (httpRequest.header("x-trace-enabled").isPresent() ? httpRequest.header("x-trace-enabled").orElse(debugEnabled): debugEnabled), - actorOperation); + private RequestContext getRequestContext(Http.Request httpRequest, org.sunbird.common.request.Request request) { + RequestContext requestContext = new RequestContext( + JsonKey.SERVICE_NAME, + JsonKey.PRODUCER_NAME, + request.getContext().getOrDefault(JsonKey.ENV, "").toString(), + httpRequest.header(JsonKey.X_DEVICE_ID).orElse(null), + httpRequest.header(JsonKey.X_SESSION_ID).orElse(null), + JsonKey.PID,JsonKey.P_VERSION, null); + requestContext.setActorId(httpRequest.attrs().getOptional(Attrs.ACTOR_ID).orElse(null)); + requestContext.setActorType(httpRequest.attrs().getOptional(Attrs.ACTOR_TYPE).orElse(null)); + requestContext.setRequestId(httpRequest.attrs().getOptional(Attrs.REQUEST_ID).orElse(null)); return requestContext; } @@ -235,7 +241,7 @@ protected CompletionStage handleRequest( return actorResponseHandler(actorRef, request, timeout, null, httpRequest); } catch (Exception e) { - ProjectLogger.log( + logger.error(null, "BaseController:handleRequest: Exception occurred with error message = " + e.getMessage(), e); return CompletableFuture.completedFuture(createCommonExceptionResponse(e, httpRequest)); @@ -276,7 +282,7 @@ protected CompletionStage handleSearchRequest( } return actorResponseHandler(actorRef, request, timeout, null, httpRequest); } catch (Exception e) { - ProjectLogger.log( + logger.error(null, "BaseController:handleRequest: Exception occurred with error message = " + e.getMessage(), e); return CompletableFuture.completedFuture(createCommonExceptionResponse(e, httpRequest)); @@ -369,7 +375,7 @@ public static String getApiVersion(String request) { */ public static Response createResponseOnException( Http.Request request, ProjectCommonException exception) { - ProjectLogger.log( + logger.error(null, exception != null ? exception.getMessage() : "Message is not coming", exception, genarateTelemetryInfoForError(request)); @@ -482,7 +488,7 @@ private Map generateTelemetryRequestForController( */ public Result createCommonExceptionResponse(Exception e, Http.Request request) { Request req = request; - ProjectLogger.log(e.getMessage(), e, genarateTelemetryInfoForError(request)); + logger.error(null, e.getMessage(), e, genarateTelemetryInfoForError(request)); ProjectCommonException exception = null; if (e instanceof ProjectCommonException) { exception = (ProjectCommonException) e; @@ -722,10 +728,9 @@ private void setGlobalHealthFlag(Object result) { } else { OnRequestHandler.isServiceHealthy = false; } - ProjectLogger.log( + logger.info(null, "BaseController:setGlobalHealthFlag: isServiceHealthy = " - + OnRequestHandler.isServiceHealthy, - LoggerEnum.INFO.name()); + + OnRequestHandler.isServiceHealthy); } protected String getQueryString(Map queryStringMap) { diff --git a/service/app/controllers/LearnerController.java b/service/app/controllers/LearnerController.java index 19f8c049b..d3ef23192 100644 --- a/service/app/controllers/LearnerController.java +++ b/service/app/controllers/LearnerController.java @@ -63,7 +63,7 @@ public CompletionStage getContentState(Http.Request httpRequest) { public CompletionStage updateContentState(Http.Request httpRequest) { try { JsonNode requestData = httpRequest.body().asJson(); - ProjectLogger.log(" updateContentState request data=" + requestData, LoggerEnum.INFO.name()); + logger.info(null, " updateContentState request data", null, new HashMap<>(){{put("requestData", requestData);}}); Request reqObj = (Request) mapper.RequestMapper.mapRequest(requestData, Request.class); RequestValidator.validateUpdateContent(reqObj); reqObj = transformUserId(reqObj); @@ -71,11 +71,16 @@ public CompletionStage updateContentState(Http.Request httpRequest) { reqObj.setRequestId(httpRequest.attrs().getOptional(Attrs.REQUEST_ID).orElse(null)); reqObj.setEnv(getEnvironment()); HashMap innerMap = new HashMap<>(); - innerMap.put(JsonKey.CONTENTS, reqObj.getRequest().get(JsonKey.CONTENTS)); innerMap.put(JsonKey.REQUESTED_BY, httpRequest.attrs().getOptional(Attrs.USER_ID).orElse(null)); if (StringUtils.isNotBlank(httpRequest.attrs().getOptional(Attrs.REQUESTED_FOR).orElse(null))) innerMap.put(SunbirdKey.REQUESTED_FOR, httpRequest.attrs().getOptional(Attrs.REQUESTED_FOR).orElse(null)); - innerMap.put(JsonKey.ASSESSMENT_EVENTS, reqObj.getRequest().get(JsonKey.ASSESSMENT_EVENTS)); + if(!reqObj.contains(JsonKey.CONTENTS) && !reqObj.contains(JsonKey.ASSESSMENT_EVENTS)) { + innerMap.put(JsonKey.COURSE_ID, reqObj.getOrDefault(JsonKey.COURSE_ID, "")); + innerMap.put(JsonKey.BATCH_ID, reqObj.getOrDefault(JsonKey.BATCH_ID, "")); + } else { + innerMap.put(JsonKey.CONTENTS, reqObj.get(JsonKey.CONTENTS)); + innerMap.put(JsonKey.ASSESSMENT_EVENTS, reqObj.getRequest().get(JsonKey.ASSESSMENT_EVENTS)); + } innerMap.put(JsonKey.USER_ID, reqObj.getRequest().get(JsonKey.USER_ID)); reqObj.setRequest(innerMap); return actorResponseHandler(contentConsumptionActor, reqObj, timeout, null, httpRequest); diff --git a/service/app/controllers/bulkapimanagement/BaseBulkUploadController.java b/service/app/controllers/bulkapimanagement/BaseBulkUploadController.java index 4276ca4e1..f02c06ef3 100644 --- a/service/app/controllers/bulkapimanagement/BaseBulkUploadController.java +++ b/service/app/controllers/bulkapimanagement/BaseBulkUploadController.java @@ -46,7 +46,7 @@ public class BaseBulkUploadController extends BaseController { protected org.sunbird.common.request.Request createAndInitBulkRequest( String operation, String objectType, Boolean validateFileZize, Http.Request httpRequest) throws IOException { - ProjectLogger.log("API call for operation : " + operation); + logger.info(null, "API call for operation : " + operation); org.sunbird.common.request.Request reqObj = new org.sunbird.common.request.Request(); Map map = new HashMap<>(); byte[] byteArray = null; diff --git a/service/app/controllers/coursemanagement/CourseBatchController.java b/service/app/controllers/coursemanagement/CourseBatchController.java index 3e5ad630c..63a1c9ef2 100644 --- a/service/app/controllers/coursemanagement/CourseBatchController.java +++ b/service/app/controllers/coursemanagement/CourseBatchController.java @@ -78,48 +78,19 @@ public CompletionStage updateBatch(Http.Request httpRequest) { httpRequest); } - public CompletionStage addUserToCourseBatch(String batchId, Http.Request httpRequest) { - return handleRequest( - courseBatchActorRef, - ActorOperations.ADD_USER_TO_BATCH.getValue(), - httpRequest.body().asJson(), - (request) -> { - new CourseBatchRequestValidator().validateAddUserToCourseBatchRequest((Request) request); - return null; - }, - batchId, - JsonKey.BATCH_ID, - httpRequest); - } - - public CompletionStage removeUserFromCourseBatch( - String batchId, Http.Request httpRequest) { - return handleRequest( - courseBatchActorRef, - ActorOperations.REMOVE_USER_FROM_BATCH.getValue(), - httpRequest.body().asJson(), - (request) -> { - new CourseBatchRequestValidator().validateAddUserToCourseBatchRequest((Request) request); - return null; - }, - batchId, - JsonKey.BATCH_ID, - httpRequest); - } - @SuppressWarnings({"unchecked", "rawtypes"}) public CompletionStage search(Http.Request httpRequest) { try { JsonNode requestData = httpRequest.body().asJson(); - ProjectLogger.log( - "CourseBatchController: search called with data = " + requestData, - LoggerEnum.DEBUG.name()); + logger.debug(null, + "CourseBatchController: search called with data = ", null, new HashMap<>(){{put("requestData", requestData);}}); Request reqObj = (Request) mapper.RequestMapper.mapRequest(requestData, Request.class); reqObj.put("creatorDetails", httpRequest.queryString().containsKey("creatorDetails")); reqObj.setOperation(ActorOperations.COMPOSITE_SEARCH.getValue()); reqObj.setRequestId(httpRequest.attrs().getOptional(Attrs.REQUEST_ID).orElse(null)); reqObj.setEnv(getEnvironment()); reqObj.put(JsonKey.REQUESTED_BY, httpRequest.attrs().getOptional(Attrs.USER_ID).orElse(null)); + reqObj.getContext().put(JsonKey.X_AUTH_TOKEN, httpRequest.attrs().getOptional(Attrs.X_AUTH_TOKEN).orElse("")); String requestedField = httpRequest.getQueryString(JsonKey.FIELDS); reqObj.getContext().put(JsonKey.PARTICIPANTS, requestedField); List esObjectType = new ArrayList<>(); diff --git a/service/app/controllers/coursemanagement/CourseController.java b/service/app/controllers/coursemanagement/CourseController.java index 0528fad8a..07d2dfdec 100644 --- a/service/app/controllers/coursemanagement/CourseController.java +++ b/service/app/controllers/coursemanagement/CourseController.java @@ -12,6 +12,7 @@ import javax.inject.Inject; import javax.inject.Named; +import java.util.HashMap; import java.util.concurrent.CompletionStage; public class CourseController extends BaseController { @@ -21,9 +22,8 @@ public class CourseController extends BaseController { private ActorRef courseActorRef; public CompletionStage createCourse(Http.Request httpRequest) { - ProjectLogger.log( - "Create course method is called = " + httpRequest.body().asJson(), - LoggerEnum.DEBUG.name()); + logger.debug(null, + "Create course method is called", null, new HashMap<>(){{put("requestData", httpRequest.body().asJson());}}); return handleRequest( courseActorRef, ActorOperations.CREATE_COURSE.getValue(), diff --git a/service/app/controllers/coursemanagement/validator/CourseBatchRequestValidator.java b/service/app/controllers/coursemanagement/validator/CourseBatchRequestValidator.java index 0bf38be38..dca25ba97 100644 --- a/service/app/controllers/coursemanagement/validator/CourseBatchRequestValidator.java +++ b/service/app/controllers/coursemanagement/validator/CourseBatchRequestValidator.java @@ -117,8 +117,7 @@ private void validateEnrolmentType(Request request) { ResponseCode.mandatoryParamsMissing, JsonKey.ENROLLMENT_TYPE); String enrolmentType = (String) request.getRequest().get(JsonKey.ENROLLMENT_TYPE); - if (!ProjectUtil.EnrolmentType.open.getVal().equalsIgnoreCase(enrolmentType) - && !ProjectUtil.EnrolmentType.inviteOnly.getVal().equalsIgnoreCase(enrolmentType)) { + if (!ProjectUtil.EnrolmentType.open.getVal().equalsIgnoreCase(enrolmentType)) { throw new ProjectCommonException( ResponseCode.invalidParameterValue.getErrorCode(), ResponseCode.invalidParameterValue.getErrorMessage(), @@ -313,7 +312,7 @@ private boolean validateBatchStatus(Request request) { status = checkProgressStatus(Integer.parseInt("" + request.getRequest().get(JsonKey.STATUS))); } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } return status; } diff --git a/service/app/controllers/group/GroupAggController.java b/service/app/controllers/group/GroupAggController.java index 0c3cc5551..651146839 100644 --- a/service/app/controllers/group/GroupAggController.java +++ b/service/app/controllers/group/GroupAggController.java @@ -22,9 +22,7 @@ public class GroupAggController extends BaseController { public CompletionStage getGroupActivityAggregates(Http.Request httpRequest) { - ProjectLogger.log( - "Aggregate Group Activity method is called = " + httpRequest.body().asJson(), - LoggerEnum.DEBUG.name()); + logger.debug(null, "Aggregate Group Activity method is called = " + httpRequest.body().asJson()); return handleRequest( groupAggregatesActorRef, ActorOperations.GROUP_ACTIVITY_AGGREGATES.getValue(), diff --git a/service/app/controllers/healthmanager/HealthController.java b/service/app/controllers/healthmanager/HealthController.java index 7cb86dfce..4f8a929c5 100644 --- a/service/app/controllers/healthmanager/HealthController.java +++ b/service/app/controllers/healthmanager/HealthController.java @@ -12,6 +12,8 @@ import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sunbird.common.models.response.Response; import org.sunbird.common.models.util.*; import org.sunbird.common.request.Request; @@ -60,7 +62,7 @@ public CompletionStage getHealth(Http.Request httpRequest) { * @return CompletionStage */ public CompletionStage getServiceHealth(Http.Request httpRequest) { - ProjectLogger.log("Call to get play service health for service.", LoggerEnum.INFO.name()); + logger.info(null, "Call to get play service health for service."); Map finalResponseMap = new HashMap<>(); List> responseList = new ArrayList<>(); responseList.add(ProjectUtil.createCheckResponse(JsonKey.LEARNER_SERVICE, false, null)); diff --git a/service/app/controllers/pagemanagement/PageController.java b/service/app/controllers/pagemanagement/PageController.java index 0fec0818e..1735f9146 100644 --- a/service/app/controllers/pagemanagement/PageController.java +++ b/service/app/controllers/pagemanagement/PageController.java @@ -92,8 +92,8 @@ public CompletionStage getPageSetting( String pageId, String organisationId, Http.Request httpRequest) { try { - ProjectLogger.log( - "getting data for particular page settings = " + pageId, LoggerEnum.INFO.name()); + logger.info(null, + "getting data for particular page settings = " + pageId); Request reqObj = new Request(); reqObj.setOperation(ActorOperations.GET_PAGE_SETTING.getValue()); reqObj.setRequestId(httpRequest.attrs().getOptional(Attrs.REQUEST_ID).orElse(null)); @@ -114,7 +114,7 @@ public CompletionStage getPageSetting( public CompletionStage getPageSettings(Http.Request httpRequest) { try { - ProjectLogger.log("getting page settings api called = ", LoggerEnum.INFO.name()); + logger.info(null, "getting page settings api called = "); Request reqObj = new Request(); reqObj.setOperation(ActorOperations.GET_PAGE_SETTINGS.getValue()); reqObj.setRequestId(httpRequest.attrs().getOptional(Attrs.REQUEST_ID).orElse(null)); @@ -147,9 +147,8 @@ public CompletionStage getPageData(Http.Request httpRequest) { reqObj.setRequest(map); return actorResponseHandler(pageManagementActorRef, reqObj, timeout, null, httpRequest); } catch (Exception e) { - ProjectLogger.log( - "PageController:getPageData: Exception occurred with error message = " + e.getMessage(), - LoggerEnum.ERROR.name()); + logger.info(null, + "PageController:getPageData: Exception occurred with error message = " + e.getMessage()); return CompletableFuture.completedFuture(createCommonExceptionResponse(e, httpRequest)); } } @@ -176,9 +175,8 @@ public CompletionStage getDIALPageData(Http.Request httpRequest) { reqObj.setRequest(map); return actorResponseHandler(pageManagementActorRef, reqObj, timeout, null, httpRequest); } catch (Exception e) { - ProjectLogger.log( - "PageController:getPageData: Exception occurred with error message = " + e.getMessage(), - LoggerEnum.ERROR.name()); + logger.info(null, + "PageController:getPageData: Exception occurred with error message = " + e.getMessage()); return CompletableFuture.completedFuture(createCommonExceptionResponse(e, httpRequest)); } } @@ -209,8 +207,8 @@ public CompletionStage createPageSection(Http.Request httpRequest) { try { JsonNode requestData = httpRequest.body().asJson(); - ProjectLogger.log( - "getting create page section data request=" + requestData, LoggerEnum.INFO.name()); + logger.info(null, + "getting create page section data request=" + requestData); Request reqObj = (Request) mapper.RequestMapper.mapRequest(requestData, Request.class); RequestValidator.validateCreateSection(reqObj); reqObj.setOperation(ActorOperations.CREATE_SECTION.getValue()); @@ -235,8 +233,8 @@ public CompletionStage updatePageSection(Http.Request httpRequest) { try { JsonNode requestData = httpRequest.body().asJson(); - ProjectLogger.log( - "getting update page section data request=" + requestData, LoggerEnum.INFO.name()); + logger.info(null, + "getting update page section data request=" + requestData); Request reqObj = (Request) mapper.RequestMapper.mapRequest(requestData, Request.class); RequestValidator.validateUpdateSection(reqObj); reqObj.setOperation(ActorOperations.UPDATE_SECTION.getValue()); @@ -261,8 +259,8 @@ public CompletionStage updatePageSection(Http.Request httpRequest) { public CompletionStage getSection(String sectionId, Http.Request httpRequest) { try { - ProjectLogger.log( - "getting data for particular page section =" + sectionId, LoggerEnum.INFO.name()); + logger.info(null, + "getting data for particular page section =" + sectionId); Request reqObj = new Request(); reqObj.setOperation(ActorOperations.GET_SECTION.getValue()); reqObj.setRequestId(httpRequest.attrs().getOptional(Attrs.REQUEST_ID).orElse(null)); @@ -282,7 +280,7 @@ public CompletionStage getSection(String sectionId, Http.Request httpReq public CompletionStage getSections(Http.Request httpRequest) { try { - ProjectLogger.log("get page all section method called = ", LoggerEnum.INFO.name()); + logger.info(null, "get page all section method called = "); Request reqObj = new Request(); reqObj.setOperation(ActorOperations.GET_ALL_SECTION.getValue()); reqObj.setRequestId(httpRequest.attrs().getOptional(Attrs.REQUEST_ID).orElse(null)); diff --git a/service/app/controllers/qrcodedownload/QRCodeDownloadController.java b/service/app/controllers/qrcodedownload/QRCodeDownloadController.java index 5d8e1dd4a..f6a7ebd86 100644 --- a/service/app/controllers/qrcodedownload/QRCodeDownloadController.java +++ b/service/app/controllers/qrcodedownload/QRCodeDownloadController.java @@ -20,9 +20,8 @@ public class QRCodeDownloadController extends BaseController { private ActorRef qrcodeDownloadActorRef; public CompletionStage downloadQRCodes(Http.Request httpRequest) { - ProjectLogger.log( - "Download QR Code method is called = " + httpRequest.body().asJson(), - LoggerEnum.DEBUG.name()); + logger.debug(null, + "Download QR Code method is called = " + httpRequest.body().asJson()); return handleRequest( qrcodeDownloadActorRef, ActorOperations.DOWNLOAD_QR_CODES.getValue(), diff --git a/service/app/controllers/search/SearchController.java b/service/app/controllers/search/SearchController.java index 11dbbe11d..e9a71115c 100644 --- a/service/app/controllers/search/SearchController.java +++ b/service/app/controllers/search/SearchController.java @@ -38,7 +38,7 @@ public class SearchController extends BaseController { public CompletionStage sync(Http.Request httpRequest) { try { JsonNode requestData = httpRequest.body().asJson(); - ProjectLogger.log("making a call to data synch api = " + requestData, LoggerEnum.INFO.name()); + logger.info(null, "making a call to data synch api = " + requestData); Request reqObj = (Request) mapper.RequestMapper.mapRequest(requestData, Request.class); RequestValidator.validateSyncRequest(reqObj); String operation = (String) reqObj.getRequest().get(JsonKey.OPERATION_FOR); diff --git a/service/app/controllers/textbook/TextbookController.java b/service/app/controllers/textbook/TextbookController.java index d1bc239cd..9b5892865 100644 --- a/service/app/controllers/textbook/TextbookController.java +++ b/service/app/controllers/textbook/TextbookController.java @@ -75,14 +75,14 @@ public CompletionStage getTocUrl(String textbookId, Http.Request httpReq // @Override public Request createAndInitUploadRequest( String operation, String objectType, Http.Request httpRequest) throws IOException { - ProjectLogger.log("API call for operation : " + operation); + logger.info(null, "API call for operation : " + operation); Request reqObj = new Request(); Map map = new HashMap<>(); InputStream inputStream = null; String fileUrl = httpRequest.getQueryString(JsonKey.FILE_URL); if (StringUtils.isNotBlank(fileUrl)) { - ProjectLogger.log("Got fileUrl from path parameter: " + fileUrl, LoggerEnum.INFO.name()); + logger.info(null, "Got fileUrl from path parameter: " + fileUrl); URL url = new URL(fileUrl.trim()); inputStream = url.openStream(); } else { @@ -106,7 +106,7 @@ public Request createAndInitUploadRequest( inputStream = new FileInputStream(filePart.get(0).getRef().path().toFile()); } } else { - ProjectLogger.log("Textbook toc upload request body is empty", LoggerEnum.INFO.name()); + logger.info(null, "Textbook toc upload request body is empty"); throwClientErrorException( ResponseCode.invalidData, ResponseCode.invalidData.getErrorMessage()); } @@ -118,8 +118,7 @@ public Request createAndInitUploadRequest( inputStream.close(); } } catch (Exception e) { - ProjectLogger.log( - "TextbookController:createAndInitUploadRequest : Exception occurred while closing stream"); + logger.error(null, "TextbookController:createAndInitUploadRequest : Exception occurred while closing stream", e); } reqObj.setOperation(operation); reqObj.setRequestId(httpRequest.attrs().getOptional(Attrs.REQUEST_ID).orElse(null)); diff --git a/service/app/filters/AccessLogFilter.java b/service/app/filters/AccessLogFilter.java index fa8fd91fc..6c91dff9f 100644 --- a/service/app/filters/AccessLogFilter.java +++ b/service/app/filters/AccessLogFilter.java @@ -11,6 +11,7 @@ import org.apache.commons.lang3.StringUtils; import org.sunbird.common.models.util.JsonKey; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.telemetry.util.TelemetryEvents; import org.sunbird.telemetry.util.TelemetryWriter; @@ -24,6 +25,7 @@ public class AccessLogFilter extends EssentialFilter { private final Executor executor; private ObjectMapper objectMapper = new ObjectMapper(); + public LoggerUtil logger = new LoggerUtil(this.getClass()); @Inject public AccessLogFilter(Executor executor) { @@ -65,7 +67,7 @@ public EssentialAction apply(EssentialAction next) { TelemetryWriter.write(req); } } catch (Exception ex) { - ProjectLogger.log("AccessLogFilter:apply Exception in writing telemetry", ex); + logger.error(null, "AccessLogFilter:apply Exception in writing telemetry", ex); } return result; }, diff --git a/service/app/loggers/CustomLayout.java b/service/app/loggers/CustomLayout.java deleted file mode 100644 index dd9c772e7..000000000 --- a/service/app/loggers/CustomLayout.java +++ /dev/null @@ -1,23 +0,0 @@ -package loggers; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.contrib.json.classic.JsonLayout; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class CustomLayout extends JsonLayout { - - @Override - protected Map toJsonMap(ILoggingEvent event) { - Map map = new LinkedHashMap(); - addTimestamp(TIMESTAMP_ATTR_NAME, this.includeTimestamp, event.getTimeStamp(), map); - add(LEVEL_ATTR_NAME, this.includeLevel, String.valueOf(event.getLevel()), map); - add("tname", this.includeThreadName, event.getThreadName(), map); - add("lname", this.includeLoggerName, event.getLoggerName(), map); - add("msg", this.includeFormattedMessage, event.getFormattedMessage(), map); - addThrowableInfo(EXCEPTION_ATTR_NAME, this.includeException, event, map); - addCustomDataToJsonMap(map, event); - return map; - } -} diff --git a/service/app/mapper/RequestMapper.java b/service/app/mapper/RequestMapper.java index 3fbe09d62..0d656413d 100644 --- a/service/app/mapper/RequestMapper.java +++ b/service/app/mapper/RequestMapper.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import org.sunbird.common.models.util.LoggerEnum; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.models.util.ProjectUtil; import org.sunbird.common.responsecode.ResponseCode; @@ -14,6 +15,7 @@ * @author Manzarul */ public class RequestMapper { + public static LoggerUtil logger = new LoggerUtil(RequestMapper.class); /** * Method to map request @@ -31,9 +33,9 @@ public static Object mapRequest(JsonNode requestData, Class obj) throws R try { return Json.fromJson(requestData, obj); } catch (Exception e) { - ProjectLogger.log("ControllerRequestMapper error : " + e.getMessage(), e); - ProjectLogger.log( - "RequestMapper:mapRequest Requested data : " + requestData, LoggerEnum.INFO.name()); + logger.error(null, "ControllerRequestMapper error : " + e.getMessage(), e); + logger.info(null, + "RequestMapper:mapRequest Requested data : " + requestData); throw ProjectUtil.createClientException(ResponseCode.invalidData); } } diff --git a/service/app/modules/ApplicationStart.java b/service/app/modules/ApplicationStart.java index 4b8617b46..b55d1082f 100644 --- a/service/app/modules/ApplicationStart.java +++ b/service/app/modules/ApplicationStart.java @@ -9,6 +9,7 @@ import org.sunbird.common.models.util.LoggerEnum; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.models.util.ProjectUtil; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.learner.util.SchedulerManager; import org.sunbird.learner.util.Util; import play.api.Environment; @@ -25,6 +26,7 @@ public class ApplicationStart { public static ProjectUtil.Environment env; public static String ssoPublicKey = ""; + public LoggerUtil logger = new LoggerUtil(this.getClass()); /** * All one time initialization which required during server startup will fall here. @@ -37,7 +39,7 @@ public ApplicationStart(ApplicationLifecycle lifecycle, Environment environment) System.out.println("ApplicationStart:ApplicationStart: Start"); setEnvironment(environment); ssoPublicKey = System.getenv(JsonKey.SSO_PUBLIC_KEY); - ProjectLogger.log("Server started.. with environment: " + env.name(), LoggerEnum.INFO.name()); + logger.info(null, "Server started.. with environment: " + env.name()); checkCassandraConnections(); SchedulerManager.schedule(); lifecycle.addStopHook( diff --git a/service/app/modules/ErrorHandler.java b/service/app/modules/ErrorHandler.java index 2bba4ca12..36f4a9dac 100644 --- a/service/app/modules/ErrorHandler.java +++ b/service/app/modules/ErrorHandler.java @@ -9,6 +9,7 @@ import javax.inject.Singleton; import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.Response; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.responsecode.ResponseCode; import play.Environment; @@ -22,6 +23,7 @@ @Singleton public class ErrorHandler extends DefaultHttpErrorHandler { + public LoggerUtil logger = new LoggerUtil(this.getClass()); @Inject public ErrorHandler( @@ -34,7 +36,7 @@ public ErrorHandler( @Override public CompletionStage onServerError(Http.RequestHeader request, Throwable t) { - ProjectLogger.log("Global: onError called for path = " + request.path(), t); + logger.error(null, "Global: onError called for path = " + request.path(), t); Response response = null; ProjectCommonException commonException = null; if (t instanceof ProjectCommonException) { diff --git a/service/app/modules/OnRequestHandler.java b/service/app/modules/OnRequestHandler.java index ebdb777e9..cd8171093 100644 --- a/service/app/modules/OnRequestHandler.java +++ b/service/app/modules/OnRequestHandler.java @@ -8,6 +8,7 @@ import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.Response; import org.sunbird.common.models.util.JsonKey; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.models.util.ProjectUtil; import org.sunbird.common.request.HeaderParam; @@ -40,8 +41,10 @@ public class OnRequestHandler implements ActionCreator { public static boolean isServiceHealthy = true; private final List USER_UNAUTH_STATES = Arrays.asList(JsonKey.UNAUTHORIZED, JsonKey.ANONYMOUS); + public LoggerUtil logger = new LoggerUtil(this.getClass()); - @Override + + @Override public Action createAction(Http.Request request, Method actionMethod) { Optional optionalMessageId = request.header(JsonKey.MESSAGE_ID); String messageId; @@ -111,7 +114,7 @@ private String getRequestedForId(Http.Request request) { try { requestedForUserID = UUID.fromString(uuidSegment).toString(); } catch (IllegalArgumentException iae) { - ProjectLogger.log("Perhaps this is another API, like search that doesn't carry user id."); + logger.info(null, "Perhaps this is another API, like search that doesn't carry user id."); } } return requestedForUserID; @@ -127,7 +130,7 @@ private String getRequestedForId(Http.Request request) { */ public CompletionStage onDataValidationError( Http.Request request, String errorMessage, int responseCode) { - ProjectLogger.log("Data error found--" + errorMessage); + logger.info(null, "Data error found--" + errorMessage); ResponseCode code = ResponseCode.getResponse(errorMessage); ResponseCode headerCode = ResponseCode.CLIENT_ERROR; Response resp = BaseController.createFailureResponse(request, code, headerCode); diff --git a/service/app/util/AuthenticationHelper.java b/service/app/util/AuthenticationHelper.java index 2e492d197..f440e718d 100644 --- a/service/app/util/AuthenticationHelper.java +++ b/service/app/util/AuthenticationHelper.java @@ -9,6 +9,7 @@ import org.sunbird.common.exception.ProjectCommonException; import org.sunbird.common.models.response.Response; import org.sunbird.common.models.util.JsonKey; +import org.sunbird.common.models.util.LoggerUtil; import org.sunbird.common.models.util.ProjectLogger; import org.sunbird.common.models.util.PropertiesCache; import org.sunbird.common.models.util.datasecurity.EncryptionService; @@ -29,6 +30,7 @@ public class AuthenticationHelper { private static CassandraOperation cassandraOperation = ServiceFactory.getInstance(); private static DbInfo userAuth = Util.dbInfoMap.get(JsonKey.USER_AUTH_DB); + public static LoggerUtil logger = new LoggerUtil(AuthenticationHelper.class); /** * This method will verify the incoming user access token against store data base /cache. If token @@ -53,7 +55,7 @@ public static String verifyUserAccessToken(String token) { } } } catch (Exception e) { - ProjectLogger.log("invalid auth token =" + token, e); + logger.error(null, "invalid auth token =" + token, e); } return userId; } @@ -75,7 +77,7 @@ public static String verifyClientAccessToken(String clientId, String clientToken validClientId = (String) dataList.get(0).get(JsonKey.ID); } } catch (Exception e) { - ProjectLogger.log("Validating client token failed due to : ", e); + logger.error(null, "Validating client token failed due to : ", e); } return validClientId; } diff --git a/service/app/util/RequestValidator.java b/service/app/util/RequestValidator.java index b9a1b1bf1..8146de6df 100644 --- a/service/app/util/RequestValidator.java +++ b/service/app/util/RequestValidator.java @@ -4,13 +4,9 @@ import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.sunbird.common.exception.ProjectCommonException; -import org.sunbird.common.models.util.JsonKey; -import org.sunbird.common.models.util.ProjectLogger; -import org.sunbird.common.models.util.ProjectUtil; +import org.sunbird.common.models.util.*; import org.sunbird.common.models.util.ProjectUtil.ProgressStatus; import org.sunbird.common.models.util.ProjectUtil.Source; -import org.sunbird.common.models.util.PropertiesCache; -import org.sunbird.common.models.util.StringFormatter; import org.sunbird.common.request.Request; import org.sunbird.common.responsecode.ResponseCode; import org.sunbird.common.responsecode.ResponseMessage; @@ -31,6 +27,7 @@ */ public final class RequestValidator { private static final int ERROR_CODE = ResponseCode.CLIENT_ERROR.getResponseCode(); + public static LoggerUtil logger = new LoggerUtil(RequestValidator.class); private RequestValidator() {} @@ -101,7 +98,7 @@ public static void validateUpdateContent(Request contentRequestDto) { } List> assessmentData = (List>) contentRequestDto.getRequest().get(JsonKey.ASSESSMENT_EVENTS); - if (!CollectionUtils.isEmpty(assessmentData)) { + if (CollectionUtils.isNotEmpty(assessmentData)) { for (Map map : assessmentData) { if (!map.containsKey(JsonKey.ASSESSMENT_TS)) { throw new ProjectCommonException( @@ -158,6 +155,29 @@ public static void validateUpdateContent(Request contentRequestDto) { } } } + // Validation for enrolment sync + if(CollectionUtils.isEmpty(list) && CollectionUtils.isEmpty(assessmentData)) { + contentRequestDto.getRequest().put(JsonKey.COURSE_ID, contentRequestDto.getOrDefault(JsonKey.COURSE_ID, contentRequestDto.getOrDefault(JsonKey.COLLECTION_ID, ""))); + if (StringUtils.isBlank((String) contentRequestDto.getOrDefault(JsonKey.COURSE_ID, ""))) { + throw new ProjectCommonException( + ResponseCode.courseIdRequired.getErrorCode(), + ResponseCode.courseIdRequiredError.getErrorMessage(), + ERROR_CODE); + } + if (StringUtils.isBlank((String) contentRequestDto.getOrDefault(JsonKey.BATCH_ID, ""))) { + throw new ProjectCommonException( + ResponseCode.courseBatchIdRequired.getErrorCode(), + ResponseCode.courseBatchIdRequired.getErrorMessage(), + ERROR_CODE); + } + + if (StringUtils.isBlank((String) contentRequestDto.getOrDefault(JsonKey.USER_ID, ""))) { + throw new ProjectCommonException( + ResponseCode.userIdRequired.getErrorCode(), + ResponseCode.userIdRequired.getErrorMessage(), + ERROR_CODE); + } + } } /** @@ -550,7 +570,7 @@ private static boolean validateBatchStatus(Request request) { status = checkProgressStatus(Integer.parseInt("" + request.getRequest().get(JsonKey.STATUS))); } catch (Exception e) { - ProjectLogger.log(e.getMessage(), e); + logger.error(null, e.getMessage(), e); } return status; } diff --git a/service/conf/application.conf b/service/conf/application.conf index daa878d39..61a09c426 100644 --- a/service/conf/application.conf +++ b/service/conf/application.conf @@ -6,6 +6,12 @@ # https://www.playframework.com/documentation/latest/JavaAkka#Configuration # ~~~~~ akka { + loggers = ["akka.event.slf4j.Slf4jLogger"] + loglevel = "INFO" + stdout-loglevel = "DEBUG" + logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" + log-config-on-start = off + actor { provider = "akka.actor.LocalActorRefProvider" serializers { diff --git a/service/conf/log4j2.properties b/service/conf/log4j2.properties deleted file mode 100644 index b49aeb545..000000000 --- a/service/conf/log4j2.properties +++ /dev/null @@ -1,16 +0,0 @@ -status = info -name = PropertiesConfig -appenders = console - -appender.console.type = Console -appender.console.name = STDOUT -appender.console.layout.type = PatternLayout -appender.console.layout.pattern = %m%n - -logger.default.name = defaultLogger -logger.default.level = info - - -rootLogger.level = debug -rootLogger.appenderRefs = STDOUT -rootLogger.appenderRef.stdout.ref = STDOUT \ No newline at end of file diff --git a/service/conf/logback.xml b/service/conf/logback.xml index 1168fb2e8..27869184f 100644 --- a/service/conf/logback.xml +++ b/service/conf/logback.xml @@ -55,6 +55,25 @@ + + + + + + + + + + + + + + + + + + + @@ -63,10 +82,6 @@ - - - - diff --git a/service/conf/routes b/service/conf/routes index e971381d8..8ed54a05c 100644 --- a/service/conf/routes +++ b/service/conf/routes @@ -47,8 +47,6 @@ POST /private/v1/course/batch/create @controllers.coursemanagement.CourseBa PATCH /v1/course/batch/update @controllers.coursemanagement.CourseBatchController.updateBatch(request: play.mvc.Http.Request) GET /v1/course/batch/read/:batchId @controllers.coursemanagement.CourseBatchController.getBatch(batchId:String, request: play.mvc.Http.Request) POST /v1/course/batch/search @controllers.coursemanagement.CourseBatchController.search(request: play.mvc.Http.Request) -POST /v1/course/batch/users/add/:batchId @controllers.coursemanagement.CourseBatchController.addUserToCourseBatch(batchId:String, request: play.mvc.Http.Request) -POST /v1/course/batch/users/remove/:batchId @controllers.coursemanagement.CourseBatchController.removeUserFromCourseBatch(batchId:String, request: play.mvc.Http.Request) POST /v1/batch/participants/list @controllers.coursemanagement.CourseBatchController.getParticipants(request: play.mvc.Http.Request) # Textbook APIs diff --git a/service/pom.xml b/service/pom.xml index 0d88b8309..f8b78b6c8 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -64,7 +64,7 @@ com.google.inject guice - 3.0 + 4.2.2 @@ -221,21 +221,19 @@ 0.2.0-RC2 - ch.qos.logback.contrib - logback-jackson - 0.1.5 - - - - - ch.qos.logback.contrib - logback-json-classic - 0.1.5 + ch.qos.logback + logback-classic + 1.2.3 net.logstash.logback logstash-logback-encoder - 6.3 + 6.6 + + + org.slf4j + slf4j-api + 1.7.25 @@ -269,89 +267,30 @@ -feature -deprecation -Xfatal-warnings - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - false - 0 - - --illegal-access=warn - - - org.jacoco jacoco-maven-plugin - 0.8.4 - - ${basedir}/target/coverage-reports/jacoco-unit.exec - ${basedir}/target/coverage-reports/jacoco-unit.exec - - **/common/** - **/router/** - **/Reverse*/** - **/routes.* - **/routes$javascript.** - - + 0.8.5 - jacoco-initialize + default-prepare-agent prepare-agent - jacoco-site - package + default-report + prepare-package report - default-check + report-aggregate + verify - check + report-aggregate - - - - BUNDLE - - - COMPLEXITY - COVEREDRATIO - 0.40 - - - INSTRUCTION - COVEREDRATIO - 0.40 - - - - - - CLASS - - *Controller - - - - - - - diff --git a/service/test/controllers/LearnerControllerTest.java b/service/test/controllers/LearnerControllerTest.java index 46a2c8c78..642df0009 100644 --- a/service/test/controllers/LearnerControllerTest.java +++ b/service/test/controllers/LearnerControllerTest.java @@ -163,6 +163,15 @@ public void testPreflightAll() { Assert.assertEquals(200, result.status()); } + @Test + public void testUpdateContentStateForEnrolmentSync() { + JsonNode json = createGetContentStateRequest(USER_ID, COURSE_ID, BATCH_ID); + Http.RequestBuilder req = + new Http.RequestBuilder().uri(CONTENT_STATE_UPDATE_URL).bodyJson(json).method("PATCH"); + Result result = Helpers.route(application, req); + Assert.assertEquals(200, result.status()); + } + private JsonNode createUpdateContentStateRequest( String contentId, String status, String lastUpdatedTime, String courseId) { Map requestMap = new HashMap<>(); diff --git a/service/test/controllers/coursemanagement/CourseBatchControllerTest.java b/service/test/controllers/coursemanagement/CourseBatchControllerTest.java index 6521d918a..60fa0bc06 100644 --- a/service/test/controllers/coursemanagement/CourseBatchControllerTest.java +++ b/service/test/controllers/coursemanagement/CourseBatchControllerTest.java @@ -42,9 +42,6 @@ public class CourseBatchControllerTest extends BaseApplicationTest { String GET_BATCH_URL = "/v1/course/batch/read/"+BATCH_ID; String SEARCH_BATCH_URL = "/v1/course/batch/search"; String BATCH_PARTICIPANTS_LIST_URL = "/v1/batch/participants/list"; - String ADD_USERS_BATCH_URL = "/v1/course/batch/users/add/"+BATCH_ID; - String REMOVE_USERS_BATCH_URL = "/v1/course/batch/users/remove/"+BATCH_ID; - @Before public void before() { @@ -56,7 +53,7 @@ public void testCreateBatchSuccess() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(CREATE_BATCH_URL) - .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.INVITE_ONLY,new Date(),getEndDate(true),getEnrollmentEndDate(true),null )) + .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.OPEN,new Date(),getEndDate(true),getEnrollmentEndDate(true),null )) .method("POST"); Result result = Helpers.route(application, req); Assert.assertEquals( 200, result.status()); @@ -67,7 +64,7 @@ public void testCreateBatchSuccessWithValidMentors() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(CREATE_BATCH_URL) - .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.INVITE_ONLY,new Date(),getEndDate(true),getEnrollmentEndDate(true),MENTORS )) + .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.OPEN,new Date(),getEndDate(true),getEnrollmentEndDate(true),MENTORS )) .method("POST"); Result result = Helpers.route(application, req); Assert.assertEquals( 200, result.status()); @@ -79,7 +76,7 @@ public void testCreateBatchSuccessWithoutEndDate() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(CREATE_BATCH_URL) - .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.INVITE_ONLY,new Date(),null,null,null )) + .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.OPEN,new Date(),null,null,null )) .method("POST"); Result result = Helpers.route(application, req); Assert.assertEquals( 200, result.status()); @@ -101,7 +98,7 @@ public void testCreateBatchFailureWithInvalidMentorType() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(CREATE_BATCH_URL) - .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.INVITE_ONLY,new Date(),getEndDate(true),getEnrollmentEndDate(true),INVALID_MENTORS_TYPE )) + .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.OPEN,new Date(),getEndDate(true),getEnrollmentEndDate(true),INVALID_MENTORS_TYPE )) .method("POST"); Result result = Helpers.route(application, req); Assert.assertEquals( 400, result.status()); @@ -112,7 +109,7 @@ public void testCreateBatchFailureWithEndDateBeforeStartDate() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(CREATE_BATCH_URL) - .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.INVITE_ONLY,new Date(),getEndDate(false),getEnrollmentEndDate(true),null )) + .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.OPEN,new Date(),getEndDate(false),getEnrollmentEndDate(true),null )) .method("POST"); Result result = Helpers.route(application, req); Assert.assertEquals( 400, result.status()); @@ -123,7 +120,7 @@ public void testCreateBatchFailureWithStartDateBeforeToday() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(CREATE_BATCH_URL) - .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME, JsonKey.INVITE_ONLY, DateUtils.addDays(new Date(), -1), getEndDate(false), getEnrollmentEndDate(true), null)) + .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME, JsonKey.OPEN, DateUtils.addDays(new Date(), -1), getEndDate(false), getEnrollmentEndDate(true), null)) .method("POST"); Result result = Helpers.route(application, req); Assert.assertEquals(400, result.status()); @@ -135,7 +132,7 @@ public void testCreateBatchFailureWithSameStartAndEndDate() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(CREATE_BATCH_URL) - .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.INVITE_ONLY, currentdate, + .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.OPEN, currentdate, currentdate,null,null )) .method("POST"); Result result = Helpers.route(application, req); @@ -147,7 +144,7 @@ public void testCreateBatchFailureWithEnrollmentEndDateBeforeStartDate() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(CREATE_BATCH_URL) - .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.INVITE_ONLY, new Date(),null, + .bodyJson(createCourseBatchRequest(COURSE_ID, COURSE_NAME,JsonKey.OPEN, new Date(),null, getEnrollmentEndDate(false),null )) .method("POST"); Result result = Helpers.route(application, req); @@ -160,7 +157,7 @@ public void testUpdateBatchSuccess() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(UPDATE_BATCH_URL) - .bodyJson(updateCourseBatchRequest(COURSE_ID,BATCH_ID,COURSE_NAME,JsonKey.INVITE_ONLY, new Date(), + .bodyJson(updateCourseBatchRequest(COURSE_ID,BATCH_ID,COURSE_NAME,JsonKey.OPEN, new Date(), getEndDate(true),null )) .method("PATCH"); System.out.println(req.toString()); @@ -173,7 +170,7 @@ public void testUpdateBatchSuccessWithoutEndDate() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(UPDATE_BATCH_URL) - .bodyJson(updateCourseBatchRequest(COURSE_ID,BATCH_ID, COURSE_NAME,JsonKey.INVITE_ONLY, new Date(), + .bodyJson(updateCourseBatchRequest(COURSE_ID,BATCH_ID, COURSE_NAME,JsonKey.OPEN, new Date(), null,null )) .method("PATCH"); Result result = Helpers.route(application, req); @@ -185,7 +182,7 @@ public void testUpdateBatchFailureWithEndDateBeforeStartDate() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(UPDATE_BATCH_URL) - .bodyJson(updateCourseBatchRequest(COURSE_ID,BATCH_ID, COURSE_NAME,JsonKey.INVITE_ONLY, new Date(), + .bodyJson(updateCourseBatchRequest(COURSE_ID,BATCH_ID, COURSE_NAME,JsonKey.OPEN, new Date(), getEndDate(false),null )) .method("PATCH"); Result result = Helpers.route(application, req); @@ -198,7 +195,7 @@ public void testUpdateBatchFailureWithSameStartAndEndDate() { Http.RequestBuilder req = new Http.RequestBuilder() .uri(UPDATE_BATCH_URL) - .bodyJson(updateCourseBatchRequest(COURSE_ID,BATCH_ID, COURSE_NAME,JsonKey.INVITE_ONLY, currentDate, + .bodyJson(updateCourseBatchRequest(COURSE_ID,BATCH_ID, COURSE_NAME,JsonKey.OPEN, currentDate, currentDate,null )) .method("PATCH"); Result result = Helpers.route(application, req); @@ -251,50 +248,6 @@ public void testSearchBatchSuccessWithEmptyFilters() { Assert.assertEquals( 200, result.status()); } - @Test - public void testAddUserToBatchSuccess() { - Http.RequestBuilder req = - new Http.RequestBuilder() - .uri(ADD_USERS_BATCH_URL) - .bodyJson(addAndRemoveUserToBatchRequest(true)) - .method("POST"); - Result result = Helpers.route(application, req); - Assert.assertEquals( 200, result.status()); - } - - @Test - public void testAddUserToBatchFailureWithoutUserIds() { - Http.RequestBuilder req = - new Http.RequestBuilder() - .uri(ADD_USERS_BATCH_URL) - .bodyJson(addAndRemoveUserToBatchRequest(false)) - .method("POST"); - Result result = Helpers.route(application, req); - Assert.assertEquals( 400, result.status()); - } - - @Test - public void testRemoveUserFromBatchSuccess() { - Http.RequestBuilder req = - new Http.RequestBuilder() - .uri(REMOVE_USERS_BATCH_URL) - .bodyJson(addAndRemoveUserToBatchRequest(true)) - .method("POST"); - Result result = Helpers.route(application, req); - Assert.assertEquals( 200, result.status()); - } - - @Test - public void testRemoveUserToBatchFailureWithoutUserIds() { - Http.RequestBuilder req = - new Http.RequestBuilder() - .uri(REMOVE_USERS_BATCH_URL) - .bodyJson(addAndRemoveUserToBatchRequest(false)) - .method("POST"); - Result result = Helpers.route(application, req); - Assert.assertEquals( 400, result.status()); - } - @Test public void testGetParticipantListFailureWithoutBatchId() { Http.RequestBuilder req = diff --git a/service/test/util/RequestValidatorTest.java b/service/test/util/RequestValidatorTest.java index a79543b0b..8c9a670d2 100644 --- a/service/test/util/RequestValidatorTest.java +++ b/service/test/util/RequestValidatorTest.java @@ -100,22 +100,6 @@ public void testValidteUpdateContentFailureWithoutStatus() { } } - @Test - public void testValidteUpdateContentFailureWithEmptyContents() { - Request request = new Request(); - List> listOfMap = new ArrayList<>(); - Map innerMap = new HashMap<>(); - innerMap.put(JsonKey.CONTENTS, listOfMap); - innerMap.put(JsonKey.USER_ID, "user123"); - request.setRequest(innerMap); - try { - RequestValidator.validateUpdateContent(request); - } catch (ProjectCommonException e) { - Assert.assertEquals(ResponseCode.CLIENT_ERROR.getResponseCode(), e.getResponseCode()); - Assert.assertEquals(ResponseCode.contentIdRequiredError.getErrorCode(), e.getCode()); - } - } - @Test public void testValidateRegisterClientFailureWithEmptyClientName() { Request request = new Request(); @@ -527,4 +511,65 @@ public void testValdateUpdateContentWithAllEmpty() { } Assert.assertEquals(false, response); } + + @Test + public void testValidateSyncEnrolment() { + Request request = new Request(); + boolean response = false; + List> listOfMap = new ArrayList<>(); + Map requestObj = new HashMap<>(); + listOfMap.add(requestObj); + Map innerMap = new HashMap<>(); + innerMap.put(JsonKey.USER_ID, "user1"); + innerMap.put(JsonKey.COURSE_ID, "do_123"); + innerMap.put(JsonKey.BATCH_ID, "0123"); + request.setRequest(innerMap); + try { + RequestValidator.validateUpdateContent(request); + response = true; + } catch (ProjectCommonException e) {} + Assert.assertEquals(true, response); + } + + @Test + public void testValidateSyncEnrolmentWithoutCourseId() { + Request request = new Request(); + boolean response = false; + List> listOfMap = new ArrayList<>(); + Map requestObj = new HashMap<>(); + listOfMap.add(requestObj); + Map innerMap = new HashMap<>(); + innerMap.put(JsonKey.USER_ID, "user1"); + innerMap.put(JsonKey.BATCH_ID, "0123"); + request.setRequest(innerMap); + try { + RequestValidator.validateUpdateContent(request); + response = true; + } catch (ProjectCommonException e) { + Assert.assertEquals(ResponseCode.CLIENT_ERROR.getResponseCode(), e.getResponseCode()); + Assert.assertEquals(ResponseCode.courseIdRequiredError.getErrorCode(), e.getCode()); + } + Assert.assertEquals(false, response); + } + + @Test + public void testValidateSyncEnrolmentWithoutBatchId() { + Request request = new Request(); + boolean response = false; + List> listOfMap = new ArrayList<>(); + Map requestObj = new HashMap<>(); + listOfMap.add(requestObj); + Map innerMap = new HashMap<>(); + innerMap.put(JsonKey.USER_ID, "user1"); + innerMap.put(JsonKey.COURSE_ID, "0123"); + request.setRequest(innerMap); + try { + RequestValidator.validateUpdateContent(request); + response = true; + } catch (ProjectCommonException e) { + Assert.assertEquals(ResponseCode.CLIENT_ERROR.getResponseCode(), e.getResponseCode()); + Assert.assertEquals(ResponseCode.courseBatchIdRequired.getErrorCode(), e.getCode()); + } + Assert.assertEquals(false, response); + } }