diff --git a/.circleci/config.yml b/.circleci/config.yml index b789ae0..98fede3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2.1 jobs: build: docker: - - image: circleci/openjdk:8-jdk + - image: circleci/openjdk:11-jdk-buster-node-browsers-legacy working_directory: ~/project steps: - checkout diff --git a/Dockerfile b/Dockerfile index 5ee86fe..fd8aa1c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:8-jre-alpine +FROM sunbird/openjdk-java11-alpine:latest RUN apk update \ && apk add unzip \ && apk add curl \ diff --git a/Jenkinsfile b/Jenkinsfile index 276534f..14bc8e2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,6 +7,7 @@ node('build-slave') { String ANSI_YELLOW = "\u001B[33m" ansiColor('xterm') { + withEnv(["JAVA_HOME=${JAVA11_HOME}"]) { stage('Checkout') { if (!env.hub_org) { println(ANSI_BOLD + ANSI_RED + "Uh Oh! Please set a Jenkins environment variable named hub_org with value as registery/sunbidrded" + ANSI_NORMAL) @@ -15,18 +16,9 @@ node('build-slave') { println(ANSI_BOLD + ANSI_GREEN + "Found environment variable named hub_org with value as: " + hub_org + ANSI_NORMAL) } cleanWs() - if (params.github_release_tag == "") { - checkout scm - commit_hash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim() - branch_name = sh(script: 'git name-rev --name-only HEAD | rev | cut -d "/" -f1| rev', returnStdout: true).trim() - build_tag = branch_name + "" + commit_hash + "" + env.BUILD_NUMBER - println(ANSI_BOLD + ANSI_YELLOW + "github_release_tag not specified, using the latest commit hash: " + commit_hash + ANSI_NORMAL) - } else { - def scmVars = checkout scm - checkout scm: [$class: 'GitSCM', branches: [[name: "refs/tags/$params.github_release_tag"]], userRemoteConfigs: [[url: scmVars.GIT_URL]]] - build_tag = params.github_release_tag + "_" + env.BUILD_NUMB - println(ANSI_BOLD + ANSI_YELLOW + "github_release_tag specified, building from tag: " + params.github_release_tag + ANSI_NORMAL) - } + checkout scm + commit_hash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim() + build_tag = sh(script: "echo " + params.github_release_tag.split('/')[-1] + "_" + commit_hash + "_" + env.BUILD_NUMBER, returnStdout: true).trim() echo "build_tag: " + build_tag stage('Build') { @@ -39,7 +31,7 @@ node('build-slave') { sh 'mvn clean install' } stage('Package') { - // Create a deployment package + // Create a deployment packageCertificationActor dir('service') { sh 'mvn play2:dist' sh 'cp target/service-1.0.0-SNAPSHOT-dist.zip ../' @@ -51,6 +43,7 @@ node('build-slave') { archiveArtifacts "metadata.json" currentBuild.description = "${build_tag}" } + } } } catch (err) { diff --git a/all-actors/pom.xml b/all-actors/pom.xml index 14a7b80..2b30a4d 100644 --- a/all-actors/pom.xml +++ b/all-actors/pom.xml @@ -11,9 +11,9 @@ 1.0.0 - org.sunbird - sb-actor - 1.0.0 + com.typesafe.akka + akka-actor_${scala.major.version} + ${akka.x.version} org.sunbird @@ -44,8 +44,8 @@ com.typesafe.akka - akka-testkit_2.12 - 2.6.0-M5 + akka-testkit_${scala.major.version} + 2.5.22 test @@ -54,7 +54,7 @@ org.jacoco jacoco-maven-plugin - 0.7.5.201505241946 + ${jacoco.maven.plugin.version} ${basedir}/target/coverage-reports/jacoco-unit.exec ${basedir}/target/coverage-reports/jacoco-unit.exec diff --git a/all-actors/src/main/java/org/sunbird/ActorOperations.java b/all-actors/src/main/java/org/sunbird/ActorOperations.java index 79bbdf8..f0a1150 100644 --- a/all-actors/src/main/java/org/sunbird/ActorOperations.java +++ b/all-actors/src/main/java/org/sunbird/ActorOperations.java @@ -15,6 +15,7 @@ public enum ActorOperations { DELETE_CERT_CASSANDRA("delete_cert_cassandra"), READ("read"), SEARCH("search"), + SEARCHV2("searchV2"), READ_CERT_META_DATA("readCertMetaData"), DOWNLOADV2("downloadV2"); diff --git a/all-actors/src/main/java/org/sunbird/Application.java b/all-actors/src/main/java/org/sunbird/Application.java deleted file mode 100644 index 593a298..0000000 --- a/all-actors/src/main/java/org/sunbird/Application.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.sunbird; - -import akka.actor.ActorRef; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sunbird.actor.core.ActorCache; -import org.sunbird.actor.core.ActorService; -import org.sunbird.helper.CassandraConnectionManager; -import org.sunbird.helper.CassandraConnectionMngrFactory; -import org.sunbird.message.IResponseMessage; -import org.sunbird.message.Localizer; -import org.sunbird.message.ResponseCode; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -/** - * this class is used to instantiate the actor system and open saber. - * @author Amit Kumar - */ -public class Application { - private final static String actorSystemName = "certActorSystem"; - private static Application instance = new Application(); - private static Localizer localizer = Localizer.getInstance(); - private static Logger logger = LoggerFactory.getLogger(Application.class); - - - // private constructor restricted to this class itself - private Application() { - } - - // static method to create instance of ActorService class - public static Application getInstance() { - return instance; - } - - // instantiate actor system and actors - public void init() throws BaseException { - List actorClassPaths = new ArrayList<>(); - actorClassPaths.add("org.sunbird"); - ActorService.getInstance().init(actorSystemName, actorClassPaths); - createCassandraConnection(JsonKeys.SUNBIRD); - } - - - /** - * this method is used to get the reference of actor from in memory cache. - * @param operation - * @return - */ - public ActorRef getActorRef(String operation) { - return ActorCache.getActorRef(operation); - } - - /** - * This method will read the configuration from System variable. - * - * @return boolean - */ - public static boolean createCassandraConnection(String keyspace) throws BaseException { - boolean response = false; - String ips = System.getenv(JsonKeys.SUNBIRD_CASSANDRA_IP); - String envPort = System.getenv(JsonKeys.SUNBIRD_CASSANDRA_PORT); - CassandraConnectionManager cassandraConnectionManager = - CassandraConnectionMngrFactory.getObject(JsonKeys.STANDALONE_MODE); - - if (StringUtils.isBlank(ips) || StringUtils.isBlank(envPort)) { - logger.info("Configuration value is not coming form System variable."); - return false; - } - String[] portList = envPort.split(","); - String userName = System.getenv(JsonKeys.SUNBIRD_CASSANDRA_USER_NAME); - String password = System.getenv(JsonKeys.SUNBIRD_CASSANDRA_PASSWORD); - try { - boolean result = - cassandraConnectionManager.createConnection(ips, portList[0], userName, password, keyspace); - if (result) { - response = true; - logger.info( - "CONNECTION CREATED SUCCESSFULLY FOR IP's: " + ips + " : KEYSPACE :" + keyspace); - } else { - logger.info( - "CONNECTION CREATION FAILED FOR IP: " + ips + " : KEYSPACE :" + keyspace); - } - } catch (BaseException ex) { - logger.error("Application:createCassandraConnection: Exception occurred with message = " + ex.getMessage()); - } - if (!response) { - throw new BaseException( - IResponseMessage.INVALID_CONFIGURATION, - getLocalizedMessage(IResponseMessage.INVALID_CONFIGURATION,null), - ResponseCode.SERVER_ERROR.hashCode()); - } - return response; - } - - private static String getLocalizedMessage(String key, Locale locale){ - return localizer.getMessage(key, locale); - } -} diff --git a/all-actors/src/main/java/org/sunbird/BaseActor.java b/all-actors/src/main/java/org/sunbird/BaseActor.java index 4f83b14..6fea037 100644 --- a/all-actors/src/main/java/org/sunbird/BaseActor.java +++ b/all-actors/src/main/java/org/sunbird/BaseActor.java @@ -9,10 +9,7 @@ import org.sunbird.request.Request; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; +import java.util.*; /** * @author Amit Kumar @@ -29,9 +26,13 @@ public void onReceive(Object message) throws Throwable { Request request = (Request) message; Map trace = new HashMap<>(); if (request.getHeaders().containsKey(JsonKeys.REQUEST_MESSAGE_ID)) { - ArrayList requestIds = - (ArrayList) request.getHeaders().get(JsonKeys.REQUEST_MESSAGE_ID); - trace.put(JsonKeys.REQUEST_MESSAGE_ID, requestIds.get(0)); + if(request.getHeaders().get(JsonKeys.REQUEST_MESSAGE_ID) instanceof String) { + trace.put(JsonKeys.REQUEST_MESSAGE_ID, request.getHeaders().get(JsonKeys.REQUEST_MESSAGE_ID)); + } else { + ArrayList requestIds = + (ArrayList) request.getHeaders().get(JsonKeys.REQUEST_MESSAGE_ID); + trace.put(JsonKeys.REQUEST_MESSAGE_ID, requestIds.get(0)); + } logger.setMDC(trace); // set mdc for non actors new BaseLogger().setReqId(logger.getMDC()); @@ -60,7 +61,7 @@ public void onReceive(Object message) throws Throwable { * @throws Exception */ protected void onReceiveException(String callerName, Exception exception) throws Exception { - logger.error("Exception in message processing for: " + callerName + " :: message: " + exception.getMessage(), exception); + logger.error("Exception in message processing for: " + callerName + " :: message: " + exception, exception); sender().tell(exception, self()); } diff --git a/all-actors/src/main/java/org/sunbird/RegistryCredential.java b/all-actors/src/main/java/org/sunbird/RegistryCredential.java new file mode 100644 index 0000000..de6dcf8 --- /dev/null +++ b/all-actors/src/main/java/org/sunbird/RegistryCredential.java @@ -0,0 +1,41 @@ +package org.sunbird; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * this class will help in getting the env values for calling the cert service + * @author anmolgupta + */ +public class RegistryCredential { + + private static Logger logger= LoggerFactory.getLogger(RegistryCredential.class); + private static final String SERVICE_BASE_URL = getPropsFromEnvs(JsonKeys.REGISTRY_CREDENTIAL_SERVICE_BASE_URL); + private static final String CERTIFICATE_TYPE = getPropsFromEnvs(JsonKeys.RC_ENTITY); + private static final String API = "/api/v1/%s"; + + public static String getSERVICE_BASE_URL() { + if(StringUtils.isBlank(SERVICE_BASE_URL)){ + logger.error("RegistryCredential:getPropsFromEnvs:no suitable host found"); + System.exit(-1); + } + return SERVICE_BASE_URL; + } + public static String getDOWNLOAD_URI() { + return String.format(API, CERTIFICATE_TYPE); + } + + private static String getPropsFromEnvs(String props){ + String propValue = System.getenv(props); + return propValue; + } + + + public static String getRCSearchUri(){ + String apiUrl = String.format(API, CERTIFICATE_TYPE); + String rcSearchApi = String.format("%s/%s/search", getSERVICE_BASE_URL().split(",")[0], apiUrl); + logger.info("RegistryCredential:getRCSearchUri:es uri formed: "+rcSearchApi); + return rcSearchApi; + } +} diff --git a/all-actors/src/main/java/org/sunbird/actor/CertBackgroundActor.java b/all-actors/src/main/java/org/sunbird/actor/CertBackgroundActor.java index 6ff4335..88f44a2 100644 --- a/all-actors/src/main/java/org/sunbird/actor/CertBackgroundActor.java +++ b/all-actors/src/main/java/org/sunbird/actor/CertBackgroundActor.java @@ -2,24 +2,15 @@ import org.sunbird.BaseActor; import org.sunbird.BaseException; -import org.sunbird.BaseLogger; import org.sunbird.JsonKeys; -import org.sunbird.actor.core.ActorConfig; import org.sunbird.cassandra.CassandraOperation; import org.sunbird.common.ElasticSearchHelper; import org.sunbird.common.factory.EsClientFactory; import org.sunbird.common.inf.ElasticSearchService; import org.sunbird.helper.ServiceFactory; import org.sunbird.request.Request; - -import java.util.HashMap; import java.util.Map; -@ActorConfig( - tasks = {"add_cert_es","delete_cert_cassandra"}, - dispatcher = "", - asyncTasks = {} -) public class CertBackgroundActor extends BaseActor { private ElasticSearchService elasticSearchService = getESService(); private CassandraOperation cassandraOperation = getCassandraOperation(); diff --git a/all-actors/src/main/java/org/sunbird/actor/CertificationActor.java b/all-actors/src/main/java/org/sunbird/actor/CertificationActor.java index a541a70..d656654 100644 --- a/all-actors/src/main/java/org/sunbird/actor/CertificationActor.java +++ b/all-actors/src/main/java/org/sunbird/actor/CertificationActor.java @@ -1,32 +1,33 @@ package org.sunbird.actor; +import akka.actor.ActorRef; +import com.fasterxml.jackson.core.JsonProcessingException; import org.sunbird.BaseActor; import org.sunbird.BaseException; -import org.sunbird.BaseLogger; import org.sunbird.JsonKeys; -import org.sunbird.actor.core.ActorConfig; import org.sunbird.request.Request; import org.sunbird.response.Response; import org.sunbird.service.ICertService; import org.sunbird.serviceimpl.CertsServiceImpl; -import java.util.HashMap; -import java.util.Map; +import javax.inject.Inject; +import javax.inject.Named; +import java.util.concurrent.ExecutionException; -@ActorConfig( - tasks = {"add","validate","download","generate","verify","search","read", "addV2", "downloadV2"}, - dispatcher = "", - asyncTasks = {} -) public class CertificationActor extends BaseActor { private ICertService certService = getCertServiceImpl(); + @Inject + @Named("certificate_background_actor") + private ActorRef certBackgroundActorRef; + + private ICertService getCertServiceImpl(){ return new CertsServiceImpl(); } @Override - public void onReceive(Request request) throws BaseException { + public void onReceive(Request request) throws BaseException, InterruptedException, ExecutionException, JsonProcessingException { logger.info("CertificationActor:onReceive:request arrived with operation" + request.getOperation()); String operation = request.getOperation(); switch (operation) { @@ -57,13 +58,16 @@ public void onReceive(Request request) throws BaseException { case "downloadV2" : downloadV2(request); break; + case "searchV2": + searchV2(request); + break; default: onReceiveUnsupportedMessage("CertificationActor"); } } private void add(Request request) throws BaseException { - String id = certService.add(request); + String id = certService.add(request, certBackgroundActorRef); Response response = new Response(); response.put(JsonKeys.ID, id); sender().tell(response, self()); @@ -93,6 +97,10 @@ private void read(Request request) throws BaseException { private void search(Request request) throws BaseException{ sender().tell(certService.search(request),self()); } + + private void searchV2(Request request) throws BaseException{ + sender().tell(certService.searchV2(request),self()); + } private void downloadV2(Request request) throws BaseException { sender().tell(certService.downloadV2(request), self()); diff --git a/all-actors/src/main/java/org/sunbird/service/ICertService.java b/all-actors/src/main/java/org/sunbird/service/ICertService.java index 6b0abd6..5639693 100644 --- a/all-actors/src/main/java/org/sunbird/service/ICertService.java +++ b/all-actors/src/main/java/org/sunbird/service/ICertService.java @@ -1,10 +1,14 @@ package org.sunbird.service; +import akka.actor.ActorRef; +import com.fasterxml.jackson.core.JsonProcessingException; import org.sunbird.BaseException; import org.sunbird.request.Request; import org.sunbird.response.Response; +import java.util.concurrent.ExecutionException; + /** * this is an interface class for implementing certificate related operations * @author anmolgupta @@ -12,9 +16,9 @@ */ public interface ICertService{ - Response delete(Request request) throws BaseException; + Response delete(Request request, ActorRef certBackgroundActorRef) throws BaseException; - String add(Request request) throws BaseException; + String add(Request request, ActorRef certBackgroundActorRef) throws BaseException; Response validate(Request request) throws BaseException; @@ -29,5 +33,7 @@ public interface ICertService{ Response read(Request request) throws BaseException; Response search(Request request) throws BaseException; + + Response searchV2(Request request) throws BaseException; } diff --git a/all-actors/src/main/java/org/sunbird/serviceimpl/CertsServiceImpl.java b/all-actors/src/main/java/org/sunbird/serviceimpl/CertsServiceImpl.java index 8e20b17..1c00c83 100644 --- a/all-actors/src/main/java/org/sunbird/serviceimpl/CertsServiceImpl.java +++ b/all-actors/src/main/java/org/sunbird/serviceimpl/CertsServiceImpl.java @@ -1,7 +1,9 @@ package org.sunbird.serviceimpl; +import akka.actor.ActorRef; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.JsonNode; import org.apache.commons.collections.CollectionUtils; @@ -14,6 +16,7 @@ import org.sunbird.BaseException; import org.sunbird.CertVars; import org.sunbird.JsonKeys; +import org.sunbird.RegistryCredential; import org.sunbird.builders.Certificate; import org.sunbird.builders.Recipient; import org.sunbird.message.IResponseMessage; @@ -29,10 +32,8 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.MessageFormat; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -50,11 +51,11 @@ public class CertsServiceImpl implements ICertService { } @Override - public Response delete(Request request) throws BaseException { + public Response delete(Request request, ActorRef certBackgroundActorRef) throws BaseException { Map certAddReqMap = request.getRequest(); Response response = new Response(); if(StringUtils.isNotBlank((String)certAddReqMap.get(JsonKeys.OLD_ID))){ - boolean bool = CertificateUtil.deleteRecord((String)certAddReqMap.get(JsonKeys.OLD_ID)); + boolean bool = CertificateUtil.deleteRecord((String)certAddReqMap.get(JsonKeys.OLD_ID), certBackgroundActorRef); response.getResult().put(JsonKeys.RESPONSE,bool); logger.info("CertsServiceImpl:delete Deleted the record from cert_registry table for id "+certAddReqMap.get(JsonKeys.OLD_ID)); } @@ -62,21 +63,21 @@ public Response delete(Request request) throws BaseException { } @Override - public String add(Request request) throws BaseException { + public String add(Request request, ActorRef certBackgroundActorRef) throws BaseException { Map reqMap = request.getRequest(); if(isPresentRecipientIdAndCertId(request)){ validateCertAndRecipientId(reqMap); - deleteOldCertificate((String) reqMap.get(JsonKeys.OLD_ID)); + deleteOldCertificate((String) reqMap.get(JsonKeys.OLD_ID),certBackgroundActorRef); } Map certAddReqMap = request.getRequest(); assureUniqueCertId((String) certAddReqMap.get(JsonKeys.ID)); - processRecord(certAddReqMap,(String) request.getContext().get(JsonKeys.VERSION)); + processRecord(certAddReqMap,(String) request.getContext().get(JsonKeys.VERSION), certBackgroundActorRef); logger.info("CertsServiceImpl:add:record successfully processed with request:"+certAddReqMap.get(JsonKeys.ID)); return (String)certAddReqMap.get(JsonKeys.ID); } - private void deleteOldCertificate(String oldCertId) throws BaseException { - CertificateUtil.deleteRecord(oldCertId); + private void deleteOldCertificate(String oldCertId, ActorRef certBackgroundActorRef) throws BaseException { + CertificateUtil.deleteRecord(oldCertId, certBackgroundActorRef); } private void validateCertAndRecipientId(Map reqMap) throws BaseException { @@ -117,13 +118,13 @@ private void assureUniqueCertId(String certificatedId) throws BaseException { } - private Response processRecord(Map certReqAddMap, String version) throws BaseException { + private Response processRecord(Map certReqAddMap, String version, ActorRef certBackgroundActorRef) throws BaseException { Certificate certificate=getCertificate(certReqAddMap); if(version.equalsIgnoreCase(JsonKeys.VERSION_1)) { certificate.setPdfUrl((String)certReqAddMap.get(JsonKeys.PDF_URL)); } MaprecordMap= requestMapper.convertValue(certificate,Map.class); - return CertificateUtil.insertRecord(recordMap); + return CertificateUtil.insertRecord(recordMap, certBackgroundActorRef); } private Certificate getCertificate(Map certReqAddMap) { Certificate certificate = new Certificate.Builder() @@ -204,7 +205,7 @@ public Response download(Request request) throws BaseException { String signedUrl=jsonResponse.getBody().getObject().getJSONObject(JsonKeys.RESULT).getString(JsonKeys.SIGNED_URL); response.put(JsonKeys.SIGNED_URL,signedUrl); } else { - throw new BaseException(IResponseMessage.INVALID_REQUESTED_DATA, MessageFormat.format(getLocalizedMessage(IResponseMessage.INVALID_PROVIDED_URL,null),(String)request.getRequest().get(JsonKeys.PDF_URL)), ResponseCode.CLIENT_ERROR.getCode()); + throw new BaseException(IResponseMessage.INVALID_REQUESTED_DATA, MessageFormat.format(getLocalizedMessage(IResponseMessage.INVALID_PROVIDED_URL, null), (String) request.getRequest().get(JsonKeys.PDF_URL)), ResponseCode.CLIENT_ERROR.getCode()); } } catch (Exception e) { @@ -221,11 +222,11 @@ public Response downloadV2(Request request) throws BaseException { Response certData = CertificateUtil.getCertRecordByID(certId); Response response = new Response(); List> resultList = (List>) certData.getResult().get(JsonKeys.RESPONSE); + String printUri; if (CollectionUtils.isNotEmpty(resultList) && MapUtils.isNotEmpty(resultList.get(0))) { Map certInfo = resultList.get(0); try { String jsonUrl = (String) certInfo.get(JsonKeys.JSON_URL); - String printUri; //in-some cases jsonUrl was not filled(1.5.0 prior to fix), After fix jsonUrl is being filled (because of svg content growth,now we are uploading cert to cloud) if (StringUtils.isEmpty(jsonUrl)) { logger.info("getJsonSignedUrl: jsonUrl is empty , print uri is present in data object"); @@ -241,12 +242,49 @@ public Response downloadV2(Request request) throws BaseException { } response.put(JsonKeys.PRINT_URI, printUri); } catch (Exception e) { - logger.error("CertsServiceImpl:downloadV2:exception occurred:" + e); + logger.error("CertsServiceImpl:downloadV2:exception occurred: " + e); throw new BaseException(IResponseMessage.INTERNAL_ERROR, getLocalizedMessage(IResponseMessage.INTERNAL_ERROR, null), ResponseCode.SERVER_ERROR.getCode()); } } else { - throw new BaseException(IResponseMessage.RESOURCE_NOT_FOUND, localizer.getMessage(IResponseMessage.RESOURCE_NOT_FOUND, null), ResponseCode.RESOURCE_NOT_FOUND.getCode()); + Map headerMap = new HashMap<>(); + headerMap.put(JsonKeys.ACCEPT, JsonKeys.APPLICATION_JSON); + if(request.getHeaders() != null && request.getHeaders().get(JsonKeys.X_AUTHENTICATED_USER_TOKEN) != null) { + headerMap.put(JsonKeys.X_AUTHENTICATED_USER_TOKEN, request.getHeaders().get(JsonKeys.X_AUTHENTICATED_USER_TOKEN).toString()); + } + if(request.getHeaders() != null && request.getHeaders().get(JsonKeys.X_AUTHENTICATED_FOR) != null) { + headerMap.put(JsonKeys.X_AUTHENTICATED_FOR, request.getHeaders().get(JsonKeys.X_AUTHENTICATED_FOR).toString()); + } + + String rcApi = RegistryCredential.getSERVICE_BASE_URL().concat(RegistryCredential.getDOWNLOAD_URI())+"/"+certId; + Future> rcResponseFuture=CertificateUtil.makeAsyncGetCall(rcApi,headerMap); + try { + HttpResponse rcJsonResponse = rcResponseFuture.get(); + if (rcJsonResponse != null && rcJsonResponse.getStatus() == HttpStatus.SC_OK) { + String templateUrl = rcJsonResponse.getBody().getObject().getString(JsonKeys.TEMPLATE_URL); + logger.info("CertsServiceImpl:downloadV2: templateUrl: "+templateUrl); + headerMap.put(JsonKeys.ACCEPT, JsonKeys.IMAGE_SVG_XML); + headerMap.put("template", templateUrl); + HttpResponse rcDownloadResFuture = CertificateUtil.makeAsyncGetCallString(rcApi, headerMap); + if (rcDownloadResFuture != null && rcDownloadResFuture.getStatus() == HttpStatus.SC_OK) { + logger.info("CertsServiceImpl:downloadV2: success: "); + String responseBody = rcDownloadResFuture.getBody(); + if(responseBody != null) { + response.put(JsonKeys.PRINT_URI, responseBody); + } + } else { + logger.error("CertsServiceImpl:downloadV2:resource image is not found for certificate-id : " +certId); + throw new BaseException(IResponseMessage.RESOURCE_NOT_FOUND, localizer.getMessage(IResponseMessage.RESOURCE_NOT_FOUND, null), ResponseCode.RESOURCE_NOT_FOUND.getCode()); + } + } else { + logger.error("CertsServiceImpl:downloadV2:resource template json not found for certificate-id : " +certId); + throw new BaseException(IResponseMessage.RESOURCE_NOT_FOUND, localizer.getMessage(IResponseMessage.RESOURCE_NOT_FOUND, null), ResponseCode.RESOURCE_NOT_FOUND.getCode()); + } + } catch (ExecutionException | InterruptedException e) { + logger.error("CertsServiceImpl:downloadV2:exception occurred while calling sunbird-rc registry: " + e); + throw new BaseException(IResponseMessage.RESOURCE_NOT_FOUND, localizer.getMessage(IResponseMessage.RESOURCE_NOT_FOUND, null), ResponseCode.RESOURCE_NOT_FOUND.getCode()); + } } + return response; } @@ -373,25 +411,118 @@ private static String getLocalizedMessage(String key, Locale locale){ @Override public Response search(Request request) throws BaseException{ Response response = new Response(); + Map headerMap = new HashMap<>(); + ObjectMapper mapper = new ObjectMapper(); + headerMap.put(JsonKeys.CONTENT_TYPE, JsonKeys.APPLICATION_JSON); + if(request.getHeaders() != null && request.getHeaders().get(JsonKeys.X_AUTHENTICATED_USER_TOKEN) != null) { + headerMap.put(JsonKeys.X_AUTHENTICATED_USER_TOKEN, request.getHeaders().get(JsonKeys.X_AUTHENTICATED_USER_TOKEN).toString()); + } + if(request.getHeaders() != null && request.getHeaders().get(JsonKeys.X_AUTHENTICATED_FOR) != null) { + headerMap.put(JsonKeys.X_AUTHENTICATED_FOR, request.getHeaders().get(JsonKeys.X_AUTHENTICATED_FOR).toString()); + } + try { + ESResponseMapper mappedResponse = null; + mappedResponse = searchEsPostCall(request); + String rcSearchApiCall = RegistryCredential.getRCSearchUri(); + logger.info("RegistryCredential:rcSearchApiCall:complete url found: " + rcSearchApiCall); + Map req = request.getRequest(); + ObjectNode jsonNode = mapper.convertValue(req, ObjectNode.class); + ObjectNode jsonNode1 = (ObjectNode) jsonNode.at(JsonKeys.QUERY_MUST_PHRASE).get(0).at(JsonKeys.MATCH_PHRASE); + Iterator> fields = jsonNode1.fields(); + Map filters = new HashMap<>(); + Map fieldKeyMap = new HashMap<>(); + fields.forEachRemaining(field -> { + Map fieldValueMap = new HashMap<>(); + fieldValueMap.put("eq", field.getValue().asText()); + fieldKeyMap.put(field.getKey(), fieldValueMap); + }); + filters.put(JsonKeys.FILTERS, fieldKeyMap); + String filterString = mapper.writeValueAsString(filters); + Future> rcResponseFuture = CertificateUtil.makeAsyncPostCall(rcSearchApiCall, filterString, headerMap); + HttpResponse rcJsonResponse = rcResponseFuture.get(); + if (rcJsonResponse != null && rcJsonResponse.getStatus() == HttpStatus.SC_OK) { + String rcJsonArray = rcJsonResponse.getBody().getArray().toString(); + List> rcSearchApiResp = requestMapper.readValue(rcJsonArray, List.class); + if(mappedResponse != null) { + mappedResponse.setCount(mappedResponse.getCount() + rcSearchApiResp.size()); + List> oldCertMapLst = convertResponseToOldCertFormat(rcSearchApiResp); + mappedResponse.getContent().addAll(oldCertMapLst); + } else { + mappedResponse = new ESResponseMapper(); + mappedResponse.setCount(rcSearchApiResp.size()); + List> oldCertMapLst = convertResponseToOldCertFormat(rcSearchApiResp); + mappedResponse.setContent(oldCertMapLst); + } + } else { + logger.info("CertsServiceImpl:search:invalid request data"); + throw new BaseException(IResponseMessage.INVALID_REQUESTED_DATA,rcJsonResponse.getBody().toString(), ResponseCode.CLIENT_ERROR.getCode()); + } + response.put(JsonKeys.RESPONSE, mappedResponse); + + } catch (Exception e) { + logger.error("CertsServiceImpl:search:exception occurred: " + e); + throw new BaseException(IResponseMessage.INTERNAL_ERROR, IResponseMessage.INTERNAL_ERROR, ResponseCode.SERVER_ERROR.getCode()); + } + return response; + } + + private List> convertResponseToOldCertFormat(List> rcSearchApiResp) { + List> oldCertMapList = new ArrayList<>(); + rcSearchApiResp.forEach(rcMap -> { + Map oldCertMap = new HashMap<>(); + Map sourceMap = new HashMap<>(); + Map dataMap = new HashMap<>(); + Map couserMap = new HashMap<>(); + Map badgeMap = new HashMap<>(); + Map issuerMap = new HashMap<>(); + issuerMap.put(JsonKeys.NAME, ((Map)rcMap.get(JsonKeys.ISSUER)).get(JsonKeys.NAME)); + badgeMap.put(JsonKeys.NAME, ((Map)rcMap.get(JsonKeys.TRAINING)).get(JsonKeys.NAME)); + badgeMap.put(JsonKeys.ISSUER, issuerMap); + couserMap.put(JsonKeys.COURSE_ID, ((Map)rcMap.get(JsonKeys.TRAINING)).get(JsonKeys.ID)); + dataMap.put(JsonKeys.BADGE, badgeMap); + dataMap.put(JsonKeys.ISSUED_ON, ((Map)rcMap.get(JsonKeys.TRAINING)).get("osCreatedAt")); + sourceMap.put(JsonKeys.PDF_URL, null); + sourceMap.put(JsonKeys.DATA, dataMap); + sourceMap.put(JsonKeys.RELATED, couserMap); + oldCertMap.put("_index", "certv3"); + oldCertMap.put("_type", "_doc"); + oldCertMap.put("_id", rcMap.get(JsonKeys.OSID)); + oldCertMap.put("_score", ""); + oldCertMap.put("_source", sourceMap); + oldCertMapList.add(oldCertMap); + }); + return oldCertMapList; + } + + @Override + public Response searchV2(Request request) throws BaseException{ + Response response = new Response(); + ESResponseMapper mappedResponse = searchEsPostCall(request); + response.put(JsonKeys.RESPONSE, mappedResponse); + return response; + } + + private ESResponseMapper searchEsPostCall(Request request) throws BaseException { + ESResponseMapper mappedResponse = null; try { String requestBody = requestMapper.writeValueAsString(request.getRequest()); logger.info("CertsServiceImpl:search:request body found."); String apiToCall = CertVars.getEsSearchUri(); - logger.info("CertsServiceImpl:search:complete url found:" + apiToCall); + logger.info("CertsServiceImpl:search:complete url found: " + apiToCall); Future> responseFuture = CertificateUtil.makeAsyncPostCall(apiToCall, requestBody, headerMap); HttpResponse jsonResponse = responseFuture.get(); if (jsonResponse != null && jsonResponse.getStatus() == HttpStatus.SC_OK) { String jsonArray = jsonResponse.getBody().getObject().getJSONObject(JsonKeys.HITS).toString(); - Map apiResp=requestMapper.readValue(jsonArray,Map.class); - ESResponseMapper mappedResponse = new ObjectMapper().convertValue(apiResp,ESResponseMapper.class); - response.put(JsonKeys.RESPONSE, mappedResponse); + Map apiResp = requestMapper.readValue(jsonArray, Map.class); + mappedResponse = new ObjectMapper().convertValue(apiResp, ESResponseMapper.class); } else { - throw new BaseException(IResponseMessage.INVALID_REQUESTED_DATA,jsonResponse.getBody().toString(), ResponseCode.CLIENT_ERROR.getCode()); + logger.error("CertsServiceImpl:searchEsPostCall: Invalid request data "); + throw new BaseException(IResponseMessage.INVALID_REQUESTED_DATA, jsonResponse.getBody().toString(), ResponseCode.CLIENT_ERROR.getCode()); } } catch (Exception e) { - logger.error("CertsServiceImpl:search:exception occurred:" + e); + logger.error("CertsServiceImpl:searchEsPostCall:exception occurred: " + e); throw new BaseException(IResponseMessage.INTERNAL_ERROR, IResponseMessage.INTERNAL_ERROR, ResponseCode.SERVER_ERROR.getCode()); } - return response; + return mappedResponse; } } \ No newline at end of file diff --git a/all-actors/src/main/java/org/sunbird/utilities/CertificateUtil.java b/all-actors/src/main/java/org/sunbird/utilities/CertificateUtil.java index 0d97959..4659baf 100644 --- a/all-actors/src/main/java/org/sunbird/utilities/CertificateUtil.java +++ b/all-actors/src/main/java/org/sunbird/utilities/CertificateUtil.java @@ -10,7 +10,6 @@ import org.slf4j.LoggerFactory; import org.slf4j.MDC; import org.sunbird.ActorOperations; -import org.sunbird.Application; import org.sunbird.BaseException; import org.sunbird.JsonKeys; import org.sunbird.cassandra.CassandraOperation; @@ -26,7 +25,10 @@ import org.sunbird.response.Response; import java.sql.Timestamp; -import java.util.*; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -60,7 +62,7 @@ public static Response getCertRecordByID(String id) throws BaseException { return cassandraOperation.getRecordById(JsonKeys.SUNBIRD,JsonKeys.CERT_REGISTRY,id); } - public static Boolean deleteRecord(String id) throws BaseException { + public static Boolean deleteRecord(String id, ActorRef certBackgroundActorRef) throws BaseException { Boolean bool = (Boolean)ElasticSearchHelper.getResponseFromFuture(elasticSearchService.delete(JsonKeys.CERT_ALIAS,id)); logger.info("Data deleted from ES for id "+id); //Delete the data from cassandra @@ -70,11 +72,11 @@ public static Boolean deleteRecord(String id) throws BaseException { RequestParams params = new RequestParams(); params.setMsgid(MDC.get(JsonKeys.REQUEST_MESSAGE_ID)); req.setParams(params); - Application.getInstance().getActorRef(ActorOperations.DELETE_CERT_CASSANDRA.getOperation()).tell(req, ActorRef.noSender()); + certBackgroundActorRef.tell(req, ActorRef.noSender()); return bool; } - public static Response insertRecord(MapcertAddReqMap) throws BaseException { + public static Response insertRecord(MapcertAddReqMap, ActorRef certBackgroundActorRef) throws BaseException { MapcertMap = new HashMap<>(); long createdAt = System.currentTimeMillis(); certAddReqMap.put(JsonKeys.CREATED_AT,createdAt); @@ -106,7 +108,7 @@ public static Response insertRecord(MapcertAddReqMap) throws Base req.setParams(params); req.setOperation(ActorOperations.ADD_CERT_ES.getOperation()); req.getRequest().put(JsonKeys.REQUEST,certAddReqMap); - Application.getInstance().getActorRef(ActorOperations.ADD_CERT_ES.getOperation()).tell(req, ActorRef.noSender()); + certBackgroundActorRef.tell(req, ActorRef.noSender()); return response; } @@ -127,7 +129,24 @@ public static Future> makeAsyncPostCall(String apiToCall, .asJsonAsync(); return jsonResponse; } - + + public static HttpResponse makeAsyncGetCallString(String apiToCall, MapheaderMap) throws ExecutionException, InterruptedException { + logger.info("CertificateUtil:makeAsyncGetCallString:get request to make get call for API:"+apiToCall); + HttpResponse jsonResponse + = Unirest.get(apiToCall) + .headers(headerMap) + .asStringAsync().get(); + return jsonResponse; + } + + public static Future> makeAsyncGetCall(String apiToCall, MapheaderMap){ + logger.info("CertificateUtil:makeAsyncGetCall:get request to make get call for API:"+apiToCall); + Future> jsonResponse + = Unirest.get(apiToCall) + .headers(headerMap) + .asJsonAsync(); + return jsonResponse; + } private static String getLocalizedMessage(String key, Locale locale){ return localizer.getMessage(key, locale); } diff --git a/all-actors/src/main/java/org/sunbird/utilities/ESResponseMapper.java b/all-actors/src/main/java/org/sunbird/utilities/ESResponseMapper.java index 46c71a1..1aa8d21 100644 --- a/all-actors/src/main/java/org/sunbird/utilities/ESResponseMapper.java +++ b/all-actors/src/main/java/org/sunbird/utilities/ESResponseMapper.java @@ -19,6 +19,8 @@ public ESResponseMapper( this.content = content; this.count = count; } + + public ESResponseMapper() {} public List> getContent() { return content; @@ -27,4 +29,12 @@ public List> getContent() { public int getCount() { return count; } + + public void setContent(List> content) { + this.content = content; + } + + public void setCount(int count) { + this.count = count; + } } \ No newline at end of file diff --git a/all-actors/src/main/resources/application.conf b/all-actors/src/main/resources/application.conf deleted file mode 100644 index 3b6fcd0..0000000 --- a/all-actors/src/main/resources/application.conf +++ /dev/null @@ -1,129 +0,0 @@ -certActorSystem { - default-dispatcher { - type = "Dispatcher" - executor = "fork-join-executor" - fork-join-executor { - parallelism-min = 8 - parallelism-factor = 32.0 - parallelism-max = 64 - } - # Throughput for default Dispatcher, set to 1 for as fair as possible - throughput = 1 - } - router-dispatcher { - type = "Dispatcher" - executor = "fork-join-executor" - fork-join-executor { - parallelism-min = 8 - parallelism-factor = 32.0 - parallelism-max = 64 - } - # Throughput for default Dispatcher, set to 1 for as fair as possible - throughput = 1 - } - supervisor-dispatcher { - type = "Dispatcher" - executor = "fork-join-executor" - fork-join-executor { - parallelism-min = 8 - parallelism-factor = 32.0 - parallelism-max = 64 - } - # Throughput for default Dispatcher, set to 1 for as fair as possible - throughput = 1 - } - user-dispatcher { - type = "Dispatcher" - executor = "fork-join-executor" - fork-join-executor { - parallelism-min = 8 - parallelism-factor = 32.0 - parallelism-max = 64 - } - # Throughput for default Dispatcher, set to 1 for as fair as possible - throughput = 1 - } - search-read-dispatcher { - type = "Dispatcher" - executor = "fork-join-executor" - fork-join-executor { - parallelism-min = 12 - parallelism-factor = 32.0 - parallelism-max = 64 - } - # Throughput for default Dispatcher, set to 1 for as fair as possible - throughput = 1 - } - org-dispatcher { - type = "Dispatcher" - executor = "fork-join-executor" - fork-join-executor { - parallelism-min = 8 - parallelism-factor = 32.0 - parallelism-max = 64 - } - # Throughput for default Dispatcher, set to 1 for as fair as possible - throughput = 1 - } - - akka { - - loggers = ["akka.event.slf4j.Slf4jLogger"] - loglevel = "INFO" - stdout-loglevel = "DEBUG" - logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" - - - actor { - akka.actor.allow-java-serialization = off - debug { - # enable DEBUG logging of all AutoReceiveMessages (Kill, PoisonPill etc.) - autoreceive = on - # enable DEBUG logging of actor lifecycle changes - lifecycle = on - # enable DEBUG logging of unhandled messages - unhandled = on - # enable DEBUG logging of all LoggingFSMs for events, transitions and timers - fsm = on - # enable DEBUG logging of subscription changes on the eventStream - event-stream = on - } - - default-dispatcher { - type = "Dispatcher" - executor = "fork-join-executor" - fork-join-executor { - parallelism-min = 8 - parallelism-factor = 32.0 - parallelism-max = 64 - } - # Throughput for default Dispatcher, set to 1 for as fair as possible - throughput = 1 - } - deployment { - /CertificationActor - { - router = smallest-mailbox-pool - nr-of-instances = 5 - dispatcher = user-dispatcher - } - /CertBackgroundActor - { - router = smallest-mailbox-pool - nr-of-instances = 5 - dispatcher = user-dispatcher - } - } - } - remote { - maximum-payload-bytes = 30000000 bytes - netty.tcp { - port = 8088 - message-frame-size = 30000000b - send-buffer-size = 30000000b - receive-buffer-size = 30000000b - maximum-frame-size = 30000000b - } - } - } -} diff --git a/all-actors/src/main/resources/cassandra.config.properties b/all-actors/src/main/resources/cassandra.config.properties index d673fd5..e6ecc19 100644 --- a/all-actors/src/main/resources/cassandra.config.properties +++ b/all-actors/src/main/resources/cassandra.config.properties @@ -5,4 +5,5 @@ maxConnectionsPerHostForRemote=4 maxRequestsPerConnection=32768 heartbeatIntervalSeconds=60 poolTimeoutMillis=0 -queryLoggerConstantThreshold=300 \ No newline at end of file +queryLoggerConstantThreshold=300 +isMultiDCEnabled=false \ No newline at end of file diff --git a/all-actors/src/test/java/org/sunbird/actor/CertificationActorTest.java b/all-actors/src/test/java/org/sunbird/actor/CertificationActorTest.java index c78a060..9adbe44 100644 --- a/all-actors/src/test/java/org/sunbird/actor/CertificationActorTest.java +++ b/all-actors/src/test/java/org/sunbird/actor/CertificationActorTest.java @@ -20,10 +20,7 @@ import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.sunbird.ActorOperations; -import org.sunbird.BaseException; -import org.sunbird.CertVars; -import org.sunbird.JsonKeys; +import org.sunbird.*; import org.sunbird.cassandra.CassandraOperation; import org.sunbird.cassandraimpl.CassandraDACImpl; import org.sunbird.common.ElasticSearchRestHighImpl; @@ -62,9 +59,10 @@ CassandraOperation.class, CassandraDACImpl.class, CertVars.class, + RegistryCredential.class, IOUtils.class, URL.class}) -@PowerMockIgnore("javax.management.*") +@PowerMockIgnore({"javax.management.*", "jdk.internal.reflect.*"}) public class CertificationActorTest { @@ -78,6 +76,7 @@ public static void setUp() throws Exception { JSONObject object2 = null; public void beforeTestSetUp() throws Exception { PowerMockito.mockStatic(CertVars.class); + PowerMockito.mockStatic(RegistryCredential.class); PowerMockito.mockStatic(EsClientFactory.class); ElasticSearchRestHighImpl elasticSearchRestHigh = PowerMockito.mock(ElasticSearchRestHighImpl.class); PowerMockito.whenNew(ElasticSearchRestHighImpl.class).withNoArguments().thenReturn(elasticSearchRestHigh); @@ -90,7 +89,7 @@ public void beforeTestSetUp() throws Exception { when(CertificateUtil.isIdPresent(Mockito.anyString())).thenReturn(false); CertsServiceImpl certsService = PowerMockito.mock(CertsServiceImpl.class); PowerMockito.whenNew(CertsServiceImpl.class).withNoArguments().thenReturn(certsService); - when(certsService.add(Mockito.any(Request.class))).thenReturn("id"); + when(certsService.add(Mockito.any(Request.class), Mockito.any(ActorRef.class))).thenReturn("id"); when(certsService.validate(Mockito.any(Request.class))).thenReturn(getValidateCertResponse()); Map map = new HashMap<>(); @@ -99,6 +98,9 @@ public void beforeTestSetUp() throws Exception { when(CertVars.getSERVICE_BASE_URL()).thenReturn("service_base_url"); when(CertVars.getDOWNLOAD_URI()).thenReturn("download_url"); when(CertVars.getEsSearchUri()).thenReturn("es_search_uri"); + when(RegistryCredential.getSERVICE_BASE_URL()).thenReturn("service_base_url"); + when(RegistryCredential.getDOWNLOAD_URI()).thenReturn("download_url"); + when(RegistryCredential.getRCSearchUri()).thenReturn("es_search_uri"); final Future> mockedFuture = Mockito.mock(Future.class); when(CertificateUtil.makeAsyncPostCall(Mockito.anyString(),Mockito.anyString(),Mockito.anyMap())).thenReturn(mockedFuture); final HttpResponse mockedResponse = Mockito.mock(HttpResponse.class); @@ -116,6 +118,10 @@ public void beforeTestSetUp() throws Exception { String signedUrl ="http://localhost:9000/dev-e-credentials/0125450863553740809/4d88c2e4-212b-4c00-aa83-1cd3fde7b447.json"; when(object2.getString(JsonKeys.SIGNED_URL)).thenReturn(signedUrl); when(object2.get(JsonKeys.RESPONSE)).thenReturn(map); + + final Future> mockedGetFuture = Mockito.mock(Future.class); + when(CertificateUtil.makeAsyncGetCall(Mockito.anyString(),Mockito.anyMap())).thenReturn(mockedGetFuture); + when(mockedGetFuture.get()).thenReturn(null); when(certsService.download(Mockito.any(Request.class))).thenReturn(getValidateCertResponse()); when(CertificateUtil.getCertificate(Mockito.anyString())).thenReturn(map); @@ -191,7 +197,7 @@ public void testReadCertificate() throws Exception { @Test public void testSearchCertificate() throws Exception { Request request = createDownloadCertRequest(); - request.setOperation(ActorOperations.SEARCH.getOperation()); + request.setOperation(ActorOperations.SEARCHV2.getOperation()); beforeTestSetUp(); TestKit testKit = new TestKit(system); ActorRef actorRef = system.actorOf(props); @@ -296,6 +302,8 @@ private Request createDownloadV2CertRequest() { Map reqMap = new HashMap<>(); reqMap.put(JsonKeys.ID,"anyMockId"); reqObj.getRequest().putAll(reqMap); + reqObj.getHeaders().put(JsonKeys.X_AUTHENTICATED_FOR, "X_AUTHENTICATED_FOR"); + reqObj.getHeaders().put(JsonKeys.X_AUTHENTICATED_USER_TOKEN, "X_AUTHENTICATED_USER_TOKEN"); return reqObj; } diff --git a/auto_build_deploy b/auto_build_deploy index f689eb9..955b0f2 100644 --- a/auto_build_deploy +++ b/auto_build_deploy @@ -8,6 +8,7 @@ node('build-slave') { String ANSI_YELLOW = "\u001B[33m" ansiColor('xterm') { + withEnv(["JAVA_HOME=${JAVA11_HOME}"]) { stage('Checkout') { tag_name = env.JOB_NAME.split("/")[-1] pre_checks() @@ -52,6 +53,7 @@ node('build-slave') { slack_notify(currentBuild.result, tag_name) email_notify() auto_build_deploy() + } } catch (err) { currentBuild.result = "FAILURE" diff --git a/cassandra-utils/pom.xml b/cassandra-utils/pom.xml index f0193f4..7825ee9 100644 --- a/cassandra-utils/pom.xml +++ b/cassandra-utils/pom.xml @@ -5,7 +5,11 @@ cassandra-utils 1.0-SNAPSHOT Cassandra Utils - + + certification-service + org.sunbird + 1.2.0 + 2.3.1 1.8 @@ -20,6 +24,12 @@ org.cassandraunit cassandra-unit 3.11.2.0 + + + io.netty + * + + com.datastax.cassandra @@ -39,6 +49,12 @@ com.datastax.cassandra cassandra-driver-mapping ${cassandra.driver.version} + + + com.datastax.cassandra + cassandra-driver-core + + com.fasterxml.jackson.core @@ -61,7 +77,7 @@ org.powermock powermock-module-junit4 - 1.6.5 + ${powermock.version} test @@ -73,7 +89,7 @@ org.powermock powermock-api-mockito - 1.6.5 + ${powermock.version} test @@ -117,7 +133,7 @@ org.jacoco jacoco-maven-plugin - 0.7.5.201505241946 + ${jacoco.maven.plugin.version} ${basedir}/target/coverage-reports/jacoco-unit.exec ${basedir}/target/coverage-reports/jacoco-unit.exec diff --git a/cassandra-utils/src/main/java/org/sunbird/common/Constants.java b/cassandra-utils/src/main/java/org/sunbird/common/Constants.java index 2ce363f..f2740cb 100644 --- a/cassandra-utils/src/main/java/org/sunbird/common/Constants.java +++ b/cassandra-utils/src/main/java/org/sunbird/common/Constants.java @@ -72,4 +72,5 @@ public interface Constants { public static final String OBJECT_TYPE = "objectType"; public static final String INSERT = "insert"; public static final String STANDALONE_MODE = "standalone"; + public static final String IS_MULTI_DC_ENABLED = "isMultiDCEnabled"; } diff --git a/cassandra-utils/src/main/java/org/sunbird/helper/CassandraConnectionManagerImpl.java b/cassandra-utils/src/main/java/org/sunbird/helper/CassandraConnectionManagerImpl.java index 57e445c..9d4140e 100644 --- a/cassandra-utils/src/main/java/org/sunbird/helper/CassandraConnectionManagerImpl.java +++ b/cassandra-utils/src/main/java/org/sunbird/helper/CassandraConnectionManagerImpl.java @@ -12,6 +12,7 @@ import com.datastax.driver.core.QueryOptions; import com.datastax.driver.core.Session; import com.datastax.driver.core.TableMetadata; +import com.datastax.driver.core.policies.DCAwareRoundRobinPolicy; import com.datastax.driver.core.policies.DefaultRetryPolicy; import java.util.Collection; import java.util.HashMap; @@ -102,9 +103,9 @@ private boolean createStandaloneConnection( poolingOptions.setPoolTimeoutMillis( Integer.parseInt(cache.getProperty(Constants.POOL_TIMEOUT))); if (!StringUtils.isBlank(userName) && !StringUtils.isBlank(password)) { - cluster = createCluster(ips, port, userName, password, poolingOptions); + cluster = createCluster(ips, port, userName, password, poolingOptions, Boolean.parseBoolean(cache.getProperty(Constants.IS_MULTI_DC_ENABLED))); } else { - cluster = createCluster(ips, port, poolingOptions); + cluster = createCluster(ips, port, poolingOptions, Boolean.parseBoolean(cache.getProperty(Constants.IS_MULTI_DC_ENABLED))); } QueryLogger queryLogger = QueryLogger.builder() @@ -175,7 +176,7 @@ private static ConsistencyLevel getConsistencyLevel() { * @return Cassandra cluster */ private static Cluster createCluster( - String ips, String port, String userName, String password, PoolingOptions poolingOptions) { + String ips, String port, String userName, String password, PoolingOptions poolingOptions, boolean isMultiDCEnabled) { String[] hosts = null; if (StringUtils.isNotBlank(ips)) { hosts = ips.split(","); @@ -203,6 +204,11 @@ private static Cluster createCluster( builder.withQueryOptions(new QueryOptions().setConsistencyLevel(consistencyLevel)); } + logger.info( + "CassandraConnectionManagerImpl:createCluster: isMultiDCEnabled = " + isMultiDCEnabled); + if (isMultiDCEnabled) { + builder.withLoadBalancingPolicy(DCAwareRoundRobinPolicy.builder().build()); + } return builder.build(); } @@ -214,8 +220,8 @@ private static Cluster createCluster( * @param poolingOptions Pooling options * @return Cassandra cluster */ - private static Cluster createCluster(String ip, String port, PoolingOptions poolingOptions) { - return createCluster(ip, port, null, null, poolingOptions); + private static Cluster createCluster(String ip, String port, PoolingOptions poolingOptions, boolean isMultiDCEnabled) { + return createCluster(ip, port, null, null, poolingOptions, isMultiDCEnabled); } @Override diff --git a/cassandra-utils/src/test/java/org/sunbird/cassandra/helper/ConnectionManagerImplTest.java b/cassandra-utils/src/test/java/org/sunbird/cassandra/helper/ConnectionManagerImplTest.java index 86fb207..a6c4281 100644 --- a/cassandra-utils/src/test/java/org/sunbird/cassandra/helper/ConnectionManagerImplTest.java +++ b/cassandra-utils/src/test/java/org/sunbird/cassandra/helper/ConnectionManagerImplTest.java @@ -36,7 +36,7 @@ Host.class, InetAddress.class }) -@PowerMockIgnore("javax.management.*") +@PowerMockIgnore({"javax.management.*", "jdk.internal.reflect.*"}) public class ConnectionManagerImplTest { PropertiesCache cache = null; diff --git a/cassandra-utils/src/test/java/org/sunbird/cassandraimpl/CassandraOperationImplTest.java b/cassandra-utils/src/test/java/org/sunbird/cassandraimpl/CassandraOperationImplTest.java index 0296fc6..6592bc1 100644 --- a/cassandra-utils/src/test/java/org/sunbird/cassandraimpl/CassandraOperationImplTest.java +++ b/cassandra-utils/src/test/java/org/sunbird/cassandraimpl/CassandraOperationImplTest.java @@ -69,7 +69,7 @@ Session.class }) -@PowerMockIgnore("javax.management.*") +@PowerMockIgnore({"javax.management.*", "jdk.internal.reflect.*"}) public class CassandraOperationImplTest { Localizer localizer = Localizer.getInstance(); private static Cluster cluster; diff --git a/pom.xml b/pom.xml index 12fd31d..6d99929 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ 1.8 1.8 2.9.10 - 2.6.0-M2 + 2.5.22 4.12 2.3.1 @@ -24,10 +24,12 @@ 1.0.7 UTF-8 - 2.6.5 - 2.12.8 - 1.6.5 + 2.7.2 + 2.11.12 + 2.11 + 1.7.4 4.5.1 + 0.8.5 @@ -35,7 +37,6 @@ cassandra-utils sb-es-utils all-actors - sb-actor service diff --git a/sb-actor/pom.xml b/sb-actor/pom.xml deleted file mode 100644 index 0502b37..0000000 --- a/sb-actor/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - certification-service - org.sunbird - 1.2.0 - - 4.0.0 - - sb-actor - 1.0.0 - - - com.typesafe.akka - akka-actor_2.12 - ${akka.x.version} - - - org.reflections - reflections - 0.9.10 - - - org.apache.commons - commons-lang3 - 3.9 - - - - - diff --git a/sb-actor/src/main/java/org/sunbird/actor/core/ActorCache.java b/sb-actor/src/main/java/org/sunbird/actor/core/ActorCache.java deleted file mode 100644 index 7b733e9..0000000 --- a/sb-actor/src/main/java/org/sunbird/actor/core/ActorCache.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.sunbird.actor.core; - -import akka.actor.ActorRef; - -import java.util.HashMap; -import java.util.Map; - -/** - * This class will maintain the cache of actor reference. - * NOTE:: Today does not handle remote actor references - * @author Amit Kumar - */ -public class ActorCache { - - private ActorCache(){} - - private static Map actorRefCache = new HashMap<>(); - - /** - * This method will return the map of actor operation and actor reference. - * @return Map of string and actor reference - */ - public static Map getActorCache() { - return actorRefCache; - } - - /** - * This method will return the actor reference based on actor operation - * @param actorOperation operation performed by actor - * @return ActorRef actor reference - */ - public static ActorRef getActorRef(String actorOperation){ - return actorRefCache.get(actorOperation); - } -} diff --git a/sb-actor/src/main/java/org/sunbird/actor/core/ActorConfig.java b/sb-actor/src/main/java/org/sunbird/actor/core/ActorConfig.java deleted file mode 100644 index 5ec3f15..0000000 --- a/sb-actor/src/main/java/org/sunbird/actor/core/ActorConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.sunbird.actor.core; - - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Amit Kumar - */ - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Inherited -public @interface ActorConfig { - String[] tasks(); - - String[] asyncTasks(); - - String dispatcher() default ""; -} diff --git a/sb-actor/src/main/java/org/sunbird/actor/core/ActorService.java b/sb-actor/src/main/java/org/sunbird/actor/core/ActorService.java deleted file mode 100644 index cb9e1b3..0000000 --- a/sb-actor/src/main/java/org/sunbird/actor/core/ActorService.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.sunbird.actor.core; - -import akka.actor.ActorRef; -import akka.actor.ActorSystem; -import akka.actor.Props; -import akka.routing.FromConfig; -import com.typesafe.config.Config; -import com.typesafe.config.ConfigFactory; -import org.apache.commons.lang3.StringUtils; -import org.reflections.Reflections; - -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * This class contains method to instantiate actor system and actors. - * @author Amit Kumar - */ -public class ActorService { - - private static ActorSystem system; - private static Config config = - ConfigFactory.systemEnvironment().withFallback(ConfigFactory.load()); - private static Map actorRefCache = ActorCache.getActorCache(); - - // static variable instance of type ActorService - private static ActorService instance = null; - - // private constructor restricted to this class itself - private ActorService() { } - - // static method to create instance of ActorService class - public static ActorService getInstance() - { - if (instance == null) - instance = new ActorService(); - - return instance; - } - - // instantiate actor system and actors - public void init(String actorSystemName, List actorsClassPathList) { - - getActorSystem(actorSystemName); - initActors(actorsClassPathList); - - } - - /** - * This method will instantiate actor system - * @return actor system - */ - private ActorSystem getActorSystem(String actorSystemName) { - - if (null == system) { - Config conf = config.getConfig(actorSystemName); - system = ActorSystem.create(actorSystemName, conf); - } - - return system; - - } - - /** - * initialize the actors - */ - private void initActors(List actorsClassPathList) { - Set> actors = getActors(actorsClassPathList); - for (Class actor : actors) { - ActorConfig routerDetails = actor.getAnnotation(ActorConfig.class); - if (null != routerDetails) { - String[] operations = routerDetails.tasks(); - String dispatcher = (StringUtils.isNotBlank(routerDetails.dispatcher())) ? routerDetails.dispatcher() : "default-dispatcher"; - createActor(actor,operations, dispatcher); - } - } - } - - - private Set> getActors(List actorsClassPathList) { - synchronized (ActorService.class) { - Reflections reflections = null; - Set> actors = new HashSet<>(); - for(String classpath : actorsClassPathList){ - reflections = new Reflections(classpath); - actors.addAll(reflections.getTypesAnnotatedWith(ActorConfig.class)); - } - return actors; - } - } - - - private void createActor(Class actor, - String[] operations, - String dispatcher) { - - if (null != operations && operations.length > 0) { - Props props; - if (StringUtils.isNotBlank(dispatcher)) { - props = Props.create(actor).withDispatcher(dispatcher); - } else { - props = Props.create(actor); - } - ActorRef actorRef = - system.actorOf(FromConfig.getInstance().props(props), actor.getSimpleName()); - for (String operation : operations) { - actorRefCache.put(operation, actorRef); - } - } - } - -} diff --git a/sb-es-utils/pom.xml b/sb-es-utils/pom.xml index 1a21a81..64a3e2b 100755 --- a/sb-es-utils/pom.xml +++ b/sb-es-utils/pom.xml @@ -23,7 +23,7 @@ org.elasticsearch.client elasticsearch-rest-high-level-client - 6.4.0 + 6.8.22 org.scala-lang @@ -53,7 +53,7 @@ com.typesafe.akka - akka-actor_2.12 + akka-actor_${scala.major.version} ${akka.x.version} compile @@ -99,7 +99,7 @@ org.jacoco jacoco-maven-plugin - 0.7.5.201505241946 + ${jacoco.maven.plugin.version} ${basedir}/target/coverage-reports/jacoco-unit.exec ${basedir}/target/coverage-reports/jacoco-unit.exec diff --git a/sb-utils/pom.xml b/sb-utils/pom.xml index c630e28..2a8d228 100644 --- a/sb-utils/pom.xml +++ b/sb-utils/pom.xml @@ -39,14 +39,14 @@ org.powermock powermock-module-junit4 - 1.6.5 + ${powermock.version} org.powermock powermock-api-mockito - 1.6.5 + ${powermock.version} @@ -55,7 +55,7 @@ org.jacoco jacoco-maven-plugin - 0.7.5.201505241946 + ${jacoco.maven.plugin.version} ${basedir}/target/coverage-reports/jacoco-unit.exec ${basedir}/target/coverage-reports/jacoco-unit.exec diff --git a/sb-utils/src/main/java/org.sunbird/JsonKeys.java b/sb-utils/src/main/java/org.sunbird/JsonKeys.java index 0ccd32c..f529e78 100644 --- a/sb-utils/src/main/java/org.sunbird/JsonKeys.java +++ b/sb-utils/src/main/java/org.sunbird/JsonKeys.java @@ -58,6 +58,7 @@ public class JsonKeys { public static final String OLD_ID="oldId"; public static final String READ = "read"; public static final String SEARCH = "search"; + public static final String SEARCH_V2 = "searchV2"; public static final String HITS ="hits"; public static final String CERT_ALIAS ="certs"; public static final String READ_CERT_META_DATA = "readCertMetaData"; @@ -75,5 +76,22 @@ public class JsonKeys { public static final String REQ_ID ="reqId"; public static final String REQUEST_MESSAGE_ID = "msgId"; public static final String X_REQUEST_ID = "X-Request-ID"; + public static final String ACCEPT = "Accept"; + public static final String CONTENT_TYPE = "Content-Type"; + public static final String IMAGE_SVG_XML = "image/svg+xml"; + public static final String TEMPLATE_URL = "templateUrl"; + public static final String REGISTRY_CREDENTIAL_SERVICE_BASE_URL= "registry_credential_service_base_url"; + public static final String RC_ENTITY = "rc_entity"; + public static final String APPLICATION_JSON = "application/json"; + public static final String QUERY_MUST_PHRASE = "/query/bool/must"; + public static final String MATCH_PHRASE = "/match_phrase"; + public static final String FILTERS = "filters"; + public static final String COURSE_ID = "courseId"; + public static final String CERTIFICATE_LABEL = "certificateLabel"; + public static final String OSID = "osid"; + public static final String TRAINING = "training"; + public static final String X_AUTHENTICATED_USER_TOKEN = "x-authenticated-user-token"; + public static final String X_AUTHENTICATED_FOR = "x-authenticated-for"; + } diff --git a/service/app/controllers/BaseController.java b/service/app/controllers/BaseController.java index 6baceb7..8af18b7 100644 --- a/service/app/controllers/BaseController.java +++ b/service/app/controllers/BaseController.java @@ -1,5 +1,9 @@ package controllers; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import javax.inject.Inject; @@ -8,9 +12,9 @@ import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sunbird.Application; import org.sunbird.BaseException; import org.sunbird.message.IResponseMessage; import org.sunbird.message.Localizer; @@ -21,6 +25,7 @@ import play.libs.Json; import play.libs.concurrent.HttpExecutionContext; import play.mvc.Controller; +import play.mvc.Http; import play.mvc.Result; import play.mvc.Results; import utils.RequestMapper; @@ -83,10 +88,6 @@ public void endTrace(String tag) { logger.info("Method call ended."); } - protected ActorRef getActorRef(String operation) throws BaseException { - return Application.getInstance().getActorRef(operation); - } - /** * this method will take play.mv.http request and a validation function and * lastly operation(Actor operation) this method is validating the request and , @@ -99,17 +100,21 @@ protected ActorRef getActorRef(String operation) throws BaseException { * @param operation * @return */ - public CompletionStage handleRequest(play.mvc.Http.Request req, RequestValidatorFunction validatorFunction, + public CompletionStage handleRequest(ActorRef actorRef, play.mvc.Http.Request req, RequestValidatorFunction validatorFunction, String operation) { try { Request request = new Request(); if (req.body() != null && req.body().asJson() != null) { request = (Request) RequestMapper.mapRequest(req, Request.class); } + if (req.getHeaders() != null && request.getHeaders() != null) { + Map map = getAllRequestHeaders(req); + request.setHeaders(map); + } if (validatorFunction != null) { validatorFunction.apply(request); } - return new RequestHandler().handleRequest(request, operation,req); + return new RequestHandler().handleRequest(request, actorRef, operation, req); } catch (Exception ex) { return CompletableFuture.supplyAsync(() -> { return RequestHandler.handleFailureResponse(ex,req); @@ -125,4 +130,15 @@ private void handleSigTerm() throws BaseException { throw new BaseException(IResponseMessage.SERVICE_UNAVAILABLE, IResponseMessage.SERVICE_UNAVAILABLE, ResponseCode.SERVICE_UNAVAILABLE.getCode()); } } + + public Map getAllRequestHeaders(Http.Request request) { + Map map = new HashMap<>(); + Map> headers = request.getHeaders().toMap(); + Iterator>> itr = headers.entrySet().iterator(); + while (itr.hasNext()) { + Map.Entry> entry = itr.next(); + map.put(entry.getKey(), entry.getValue().get(0)); + } + return map; + } } diff --git a/service/app/controllers/CertificateController.java b/service/app/controllers/CertificateController.java index 22b172e..c930245 100644 --- a/service/app/controllers/CertificateController.java +++ b/service/app/controllers/CertificateController.java @@ -1,10 +1,14 @@ package controllers; +import akka.actor.ActorRef; import org.sunbird.JsonKeys; import org.sunbird.request.Request; +import play.mvc.Http; import play.mvc.Result; import validators.*; +import javax.inject.Inject; +import javax.inject.Named; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletionStage; @@ -15,14 +19,19 @@ */ public class CertificateController extends BaseController { + + @Inject + @Named("certification_actor") + private ActorRef certificationActorRef; + /** * this action method will be called for adding certificate * @return CompletionStage of Result */ - public CompletionStage add() + public CompletionStage add(Http.Request httpRequest) { IRequestValidator requestValidator=new CertAddRequestValidator(); - return handleRequest(request(), + return handleRequest(certificationActorRef, httpRequest, request -> { Request req = (Request) request; Map context = new HashMap<>(); @@ -37,10 +46,10 @@ public CompletionStage add() * this action method will be called for adding certificate * @return CompletionStage of Result */ - public CompletionStage addV2() + public CompletionStage addV2(Http.Request httpRequest) { IRequestValidator requestValidator=new CertAddRequestValidator(); - return handleRequest(request(), + return handleRequest(certificationActorRef, httpRequest, request -> { Request req = (Request) request; Map context = new HashMap<>(); @@ -55,10 +64,10 @@ public CompletionStage addV2() * this action method will be called for verifying certificate * @return CompletionStage of Result */ - public CompletionStage validate() + public CompletionStage validate(Http.Request httpRequest) { IRequestValidator requestValidator=new CertValidateRequestValidator(); - return handleRequest(request(), + return handleRequest(certificationActorRef, httpRequest, request -> { Request req = (Request) request; requestValidator.validate(req); @@ -70,10 +79,10 @@ public CompletionStage validate() * this action method will be called for downloading certificate * @return CompletionStage of Result */ - public CompletionStage download() + public CompletionStage download(Http.Request httpRequest) { IRequestValidator requestValidator=new CertDownloadRequestValidator(); - return handleRequest(request(), + return handleRequest(certificationActorRef, httpRequest, request -> { Request req = (Request) request; requestValidator.validate(req); @@ -87,9 +96,9 @@ public CompletionStage download() * * @return CompletionStage of Result */ - public CompletionStage downloadV2(String id) { + public CompletionStage downloadV2(String id, Http.Request httpRequest) { IRequestValidator requestValidator = new CertDownloadV2RequestValidator(); - return handleRequest(request(), + return handleRequest(certificationActorRef, httpRequest, request -> { Request req = (Request) request; req.getRequest().put(JsonKeys.ID, id); @@ -102,10 +111,10 @@ public CompletionStage downloadV2(String id) { * this action method will be called for verify certificate * @return CompletionStage of Result */ - public CompletionStage verify() + public CompletionStage verify(Http.Request httpRequest) { IRequestValidator requestValidator=new CertVerifyRequestValidator(); - return handleRequest(request(), + return handleRequest(certificationActorRef, httpRequest, request -> { Request req = (Request) request; requestValidator.validate(req); @@ -117,9 +126,9 @@ public CompletionStage verify() * this action method will be called for reading certificate with id * @return CompletionStage of Result */ - public CompletionStage read(String id) { + public CompletionStage read(String id, Http.Request httpRequest) { IRequestValidator requestValidator = new CertReadRequestValidator(); - return handleRequest(request(), + return handleRequest(certificationActorRef, httpRequest, request -> { Request req = (Request) request; req.getRequest().put(JsonKeys.ID, id); @@ -131,15 +140,26 @@ public CompletionStage read(String id) { } - public CompletionStage search() + public CompletionStage search(Http.Request httpRequest) { IRequestValidator requestValidator=new CertSearchRequestValidator(); - return handleRequest(request(), + return handleRequest(certificationActorRef, httpRequest, request -> { Request req = (Request) request; requestValidator.validate(req); return null; }, JsonKeys.SEARCH); } + + public CompletionStage searchV2(Http.Request httpRequest) + { + IRequestValidator requestValidator=new CertSearchRequestValidator(); + return handleRequest(certificationActorRef, httpRequest, + request -> { + Request req = (Request) request; + requestValidator.validate(req); + return null; + }, JsonKeys.SEARCH_V2); + } } diff --git a/service/app/controllers/RequestHandler.java b/service/app/controllers/RequestHandler.java index 0ace81d..f8ba711 100644 --- a/service/app/controllers/RequestHandler.java +++ b/service/app/controllers/RequestHandler.java @@ -1,5 +1,7 @@ package controllers; +import akka.actor.ActorRef; +import akka.actor.ActorSelection; import akka.pattern.Patterns; import akka.util.Timeout; import java.util.concurrent.CompletionStage; @@ -7,7 +9,6 @@ import java.util.function.Function; import org.apache.commons.lang3.StringUtils; import org.sunbird.BaseException; -import org.sunbird.JsonKeys; import org.sunbird.message.IResponseMessage; import org.sunbird.message.ResponseCode; import org.sunbird.request.Request; @@ -35,11 +36,16 @@ public class RequestHandler extends BaseController { * @return CompletionStage * @throws Exception */ - public CompletionStage handleRequest(Request request, String operation, play.mvc.Http.Request req) throws Exception { + public CompletionStage handleRequest(Request request, Object actorRef, String operation, play.mvc.Http.Request req) throws Exception { request.setOperation(operation); Function fn = object -> handleResponse(object, req); + Future future; Timeout t = new Timeout(Long.valueOf(request.getTimeout()), TimeUnit.SECONDS); - Future future = Patterns.ask(getActorRef(operation), request, t); + if (actorRef instanceof ActorRef) { + future = Patterns.ask((ActorRef) actorRef, request, t); + } else { + future = Patterns.ask((ActorSelection) actorRef, request, t); + } return FutureConverters.toJava(future).thenApplyAsync(fn); } diff --git a/service/app/controllers/health/HealthController.java b/service/app/controllers/health/HealthController.java index 8d14dd2..dc818f9 100644 --- a/service/app/controllers/health/HealthController.java +++ b/service/app/controllers/health/HealthController.java @@ -1,17 +1,9 @@ package controllers.health; import controllers.BaseController; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - -import org.sunbird.BaseException; -import org.sunbird.message.IResponseMessage; -import org.sunbird.message.ResponseCode; +import play.mvc.Http; import play.mvc.Result; -import play.mvc.Results; -import utils.module.SignalHandler; - -import javax.inject.Inject; /** * This controller class will responsible to check health of the services. @@ -25,8 +17,8 @@ public class HealthController extends BaseController { * * @return a CompletableFuture of success response */ - public CompletionStage getHealth() { - CompletionStage response = handleRequest(request()); + public CompletionStage getHealth(Http.Request httpRequest) { + CompletionStage response = handleRequest(httpRequest); return response; } /** @@ -34,8 +26,8 @@ public CompletionStage getHealth() { * * @return a CompletableFuture of success response */ - public CompletionStage getServiceHealth(String service) { - CompletionStage response = handleRequest(request()); + public CompletionStage getServiceHealth(String service, Http.Request httpRequest) { + CompletionStage response = handleRequest(httpRequest); return response; } diff --git a/service/app/utils/ApplicationStart.java b/service/app/utils/ApplicationStart.java index 1296dca..322d752 100644 --- a/service/app/utils/ApplicationStart.java +++ b/service/app/utils/ApplicationStart.java @@ -1,14 +1,23 @@ package utils; -import org.sunbird.Application; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sunbird.BaseException; +import org.sunbird.JsonKeys; +import org.sunbird.helper.CassandraConnectionManager; +import org.sunbird.helper.CassandraConnectionMngrFactory; +import org.sunbird.message.IResponseMessage; +import org.sunbird.message.Localizer; +import org.sunbird.message.ResponseCode; import play.api.Environment; import play.api.inject.ApplicationLifecycle; import javax.inject.Inject; import javax.inject.Singleton; -import java.io.IOException; +import java.util.Locale; +import java.util.concurrent.CompletableFuture; /** * This class will be called after on application startup. only one instance of this class will be @@ -18,20 +27,71 @@ */ @Singleton public class ApplicationStart { - /** + + private static Logger logger = LoggerFactory.getLogger(ApplicationStart.class); + private static Localizer localizer = Localizer.getInstance(); + + /** * All one time initialization which required during server startup will fall here. * @param lifecycle ApplicationLifecycle * @param environment Environment */ @Inject public ApplicationStart(ApplicationLifecycle lifecycle, Environment environment) throws BaseException { - //instantiate actor system and initialize all the actors - - Application.getInstance().init(); - // Shut-down hook -// lifecycle.addStopHook( -// () -> { -// return CompletableFuture.completedFuture(null); -// }); + logger.info("ApplicationStart: Start"); + createCassandraConnection(JsonKeys.SUNBIRD); + // Shut-down hook + lifecycle.addStopHook( + () -> { + return CompletableFuture.completedFuture(null); + }); + logger.info("ApplicationStart: End"); } + + /** + * This method will read the configuration from System variable. + * + * @return boolean + */ + public static boolean createCassandraConnection(String keyspace) throws BaseException { + boolean response = false; + String ips = System.getenv(JsonKeys.SUNBIRD_CASSANDRA_IP); + String envPort = System.getenv(JsonKeys.SUNBIRD_CASSANDRA_PORT); + CassandraConnectionManager cassandraConnectionManager = + CassandraConnectionMngrFactory.getObject(JsonKeys.STANDALONE_MODE); + + if (StringUtils.isBlank(ips) || StringUtils.isBlank(envPort)) { + logger.info("Configuration value is not coming form System variable."); + return false; + } + String[] portList = envPort.split(","); + String userName = System.getenv(JsonKeys.SUNBIRD_CASSANDRA_USER_NAME); + String password = System.getenv(JsonKeys.SUNBIRD_CASSANDRA_PASSWORD); + try { + boolean result = + cassandraConnectionManager.createConnection(ips, portList[0], userName, password, keyspace); + if (result) { + response = true; + logger.info( + "CONNECTION CREATED SUCCESSFULLY FOR IP's: " + ips + " : KEYSPACE :" + keyspace); + } else { + logger.info( + "CONNECTION CREATION FAILED FOR IP: " + ips + " : KEYSPACE :" + keyspace); + } + } catch (BaseException ex) { + logger.error("Application:createCassandraConnection: Exception occurred with message = " + ex.getMessage()); + } + if (!response) { + throw new BaseException( + IResponseMessage.INVALID_CONFIGURATION, + getLocalizedMessage(IResponseMessage.INVALID_CONFIGURATION,null), + ResponseCode.SERVER_ERROR.hashCode()); + } + return response; + } + + private static String getLocalizedMessage(String key, Locale locale){ + return localizer.getMessage(key, locale); + } + } diff --git a/service/app/utils/module/ACTOR_NAMES.java b/service/app/utils/module/ACTOR_NAMES.java new file mode 100644 index 0000000..7904882 --- /dev/null +++ b/service/app/utils/module/ACTOR_NAMES.java @@ -0,0 +1,26 @@ +package utils.module; + + +import org.sunbird.actor.CertBackgroundActor; +import org.sunbird.actor.CertificationActor; + +public enum ACTOR_NAMES { + CERTIFICATION_ACTOR(CertificationActor.class, "certification_actor"), + CERTIFICATE_BACKGROUND_ACTOR(CertBackgroundActor.class, "certificate_background_actor"); + + ACTOR_NAMES(Class clazz, String name) { + actorClass = clazz; + actorName = name; + } + + private Class actorClass; + private String actorName; + + public Class getActorClass() { + return actorClass; + } + + public String getActorName() { + return actorName; + } +} diff --git a/service/app/utils/module/ActorStartModule.java b/service/app/utils/module/ActorStartModule.java new file mode 100644 index 0000000..316a0b0 --- /dev/null +++ b/service/app/utils/module/ActorStartModule.java @@ -0,0 +1,24 @@ +package utils.module; + +import akka.routing.FromConfig; +import akka.routing.RouterConfig; +import com.google.inject.AbstractModule; +import play.libs.akka.AkkaGuiceSupport; + +public class ActorStartModule extends AbstractModule implements AkkaGuiceSupport { + + @Override + protected void configure() { + System.out.println("binding actors for dependency injection"); + final RouterConfig config = new FromConfig(); + for (ACTOR_NAMES actor : ACTOR_NAMES.values()) { + bindActor( + actor.getActorClass(), + actor.getActorName(), + (props) -> { + return props.withRouter(config); + }); + } + System.out.println("binding completed"); + } +} diff --git a/service/conf/application.conf b/service/conf/application.conf index 42e32f2..ebf7e63 100755 --- a/service/conf/application.conf +++ b/service/conf/application.conf @@ -22,17 +22,88 @@ # Play uses Akka internally and exposes Akka Streams and actors in Websockets and # other streaming HTTP responses. akka { - # "akka.log-config-on-start" is extraordinarly useful because it log the complete - # configuration at INFO level, including defaults and overrides, so it s worth - # putting at the very top. - # - # Put the following in your conf/logback.xml file: - # - # - # - # And then uncomment this line to debug the configuration. - # - #log-config-on-start = true + 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 { + java = "akka.serialization.JavaSerializer" + } + serialization-bindings { + "org.sunbird.request.Request" = java + "org.sunbird.response.Response" = java + } + default-dispatcher { + # This will be used if you have set "executor = "fork-join-executor"" + fork-join-executor { + # Min number of threads to cap factor-based parallelism number to + parallelism-min = 8 + + # The parallelism factor is used to determine thread pool size using the + # following formula: ceil(available processors * factor). Resulting size + # is then bounded by the parallelism-min and parallelism-max values. + parallelism-factor = 32.0 + + # Max number of threads to cap factor-based parallelism number to + parallelism-max = 64 + + # Setting to "FIFO" to use queue like peeking mode which "poll" or "LIFO" to use stack + # like peeking mode which "pop". + task-peeking-mode = "FIFO" + } + } + router-dispatcher { + type = "Dispatcher" + executor = "fork-join-executor" + fork-join-executor { + parallelism-min = 8 + parallelism-factor = 32.0 + parallelism-max = 64 + } + # Throughput for default Dispatcher, set to 1 for as fair as possible + throughput = 1 + } + cert-dispatcher { + type = "Dispatcher" + executor = "fork-join-executor" + fork-join-executor { + parallelism-min = 8 + parallelism-factor = 32.0 + parallelism-max = 64 + } + # Throughput for default Dispatcher, set to 1 for as fair as possible + throughput = 1 + } + deployment { + /certification_actor + { + router = smallest-mailbox-pool + nr-of-instances = 5 + dispatcher = cert-dispatcher + } + + /certificate_background_actor + { + router = smallest-mailbox-pool + nr-of-instances = 5 + dispatcher = cert-dispatcher + } + } + } + remote { + maximum-payload-bytes = 30000000 bytes + netty.tcp { + port = 8088 + message-frame-size = 30000000b + send-buffer-size = 30000000b + receive-buffer-size = 30000000b + maximum-frame-size = 30000000b + } + } } ## Secret key @@ -58,6 +129,7 @@ play.modules { # explicitly below. # If there are any built-in modules that you want to disable, you can list them here. enabled += utils.module.StartModule + enabled += utils.module.ActorStartModule # If there are any built-in modules that you want to disable, you can list them here. #disabled += "" @@ -153,15 +225,42 @@ play.http { ## Netty Provider # https://www.playframework.com/documentation/latest/SettingsNetty # ~~~~~ -play.server.netty { - # Whether the Netty wire should be logged - #log.wire = true - - # If you run Play on Linux, you can use Netty's native socket transport - # for higher performance with less garbage. - #transport = "native" +play.server { + # The server provider class name + provider = "play.core.server.NettyServerProvider" + netty { + # The number of event loop threads. 0 means let Netty decide, which by default will select 2 times the number of + # available processors. + eventLoopThreads = 30 + + # The transport to use, either jdk or native. + # Native socket transport has higher performance and produces less garbage but are only available on linux + transport = "native" + + # If you run Play on Linux, you can use Netty's native socket transport + # for higher performance with less garbage. + #transport = "native" + maxChunkSize = 30000000 + option { + + # Set whether connections should use TCP keep alive + # child.keepAlive = true + + # Set whether the TCP no delay flag is set + # child.tcpNoDelay = false + + # Set the size of the backlog of TCP connections. The default and exact meaning of this parameter is JDK specific. + # backlog = 100 + } + } } + +## WS (HTTP Client) +# ~~~~~ +libraryDependencies += javaWs + + ## WS (HTTP Client) # https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS # ~~~~~ @@ -201,7 +300,7 @@ play.ws { # Play comes with an integrated cache API that can reduce the operational # overhead of repeated requests. You must enable this by adding to build.sbt: # -# libraryDependencies += cache +libraryDependencies += cache # play.cache { # If you want to bind several caches, you can bind the individually diff --git a/service/conf/routes b/service/conf/routes index de98469..93e0e27 100755 --- a/service/conf/routes +++ b/service/conf/routes @@ -3,19 +3,21 @@ # ~~~~ #Health check -GET /health @controllers.health.HealthController.getHealth() -GET /:service/health @controllers.health.HealthController.getServiceHealth(service:String) +GET /health @controllers.health.HealthController.getHealth(request: play.mvc.Http.Request) +GET /:service/health @controllers.health.HealthController.getServiceHealth(service:String, request: play.mvc.Http.Request) # CERT APIs -POST /certs/v1/registry/add @controllers.CertificateController.add() -POST /certs/v2/registry/add @controllers.CertificateController.addV2() -POST /certs/v1/registry/validate @controllers.CertificateController.validate() -POST /certs/v1/registry/download @controllers.CertificateController.download() -GET /certs/v2/registry/download/:id @controllers.CertificateController.downloadV2(id:String) -POST /certs/v1/registry/verify @controllers.CertificateController.verify() -GET /certs/v1/registry/read/:id @controllers.CertificateController.read(id:String) -POST /certs/v1/registry/search @controllers.CertificateController.search() +POST /certs/v1/registry/add @controllers.CertificateController.add(request: play.mvc.Http.Request) +POST /certs/v2/registry/add @controllers.CertificateController.addV2(request: play.mvc.Http.Request) +POST /certs/v1/registry/validate @controllers.CertificateController.validate(request: play.mvc.Http.Request) +POST /certs/v1/registry/download @controllers.CertificateController.download(request: play.mvc.Http.Request) +GET /certs/v2/registry/download/:id @controllers.CertificateController.downloadV2(id:String, request: play.mvc.Http.Request) +POST /certs/v1/registry/verify @controllers.CertificateController.verify(request: play.mvc.Http.Request) +GET /certs/v1/registry/read/:id @controllers.CertificateController.read(id:String, request: play.mvc.Http.Request) +POST /certs/v1/registry/search @controllers.CertificateController.search(request: play.mvc.Http.Request) +POST /certs/v2/registry/search @controllers.CertificateController.searchV2(request: play.mvc.Http.Request) + diff --git a/service/pom.xml b/service/pom.xml index d5c0134..5be9acb 100755 --- a/service/pom.xml +++ b/service/pom.xml @@ -23,6 +23,12 @@ + + com.typesafe.play + play-netty-server_${scala.major.version} + ${play2.version} + runtime + com.fasterxml.jackson.core jackson-databind @@ -35,7 +41,7 @@ com.typesafe.play - play_2.12 + play_${scala.major.version} ${play2.version} @@ -46,11 +52,15 @@ org.scala-lang scala-java8-compat_2.11 + + com.google.guava + guava + com.typesafe.play - play-guice_2.12 + play-guice_${scala.major.version} ${play2.version} @@ -65,18 +75,18 @@ com.typesafe.play - play-akka-http-server_2.12 + play-akka-http-server_${scala.major.version} ${play2.version} runtime com.typesafe.akka - akka-remote_2.12 + akka-remote_${scala.major.version} ${akka.x.version} com.typesafe.play - filters-helpers_2.12 + filters-helpers_${scala.major.version} ${play2.version} @@ -107,8 +117,8 @@ com.typesafe.play - play-test_2.12 - 2.6.7 + play-test_${scala.major.version} + ${play2.version} test @@ -134,7 +144,7 @@ com.google.code.play2-maven-plugin play2-maven-plugin - 1.0.0-rc1 + 1.0.0-rc5 true @@ -149,10 +159,9 @@ org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.8.1 - 1.8 - 1.8 + 11 @@ -169,7 +178,7 @@ org.jacoco jacoco-maven-plugin - 0.7.5.201505241946 + ${jacoco.maven.plugin.version} ${basedir}/target/coverage-reports/jacoco-unit.exec ${basedir}/target/coverage-reports/jacoco-unit.exec diff --git a/service/test/controllers/BaseApplicationTest.java b/service/test/controllers/BaseApplicationTest.java index 9a63950..899b439 100644 --- a/service/test/controllers/BaseApplicationTest.java +++ b/service/test/controllers/BaseApplicationTest.java @@ -1,23 +1,11 @@ package controllers; -import akka.actor.ActorRef; -import akka.actor.ActorSystem; -import akka.actor.Props; -import akka.dispatch.Futures; -import akka.pattern.Patterns; -import akka.util.Timeout; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.sunbird.BaseException; -import org.sunbird.message.ResponseCode; -import org.sunbird.request.Request; import org.sunbird.response.Response; import org.sunbird.response.ResponseParams; import play.Application; @@ -27,70 +15,48 @@ import play.mvc.Http; import play.mvc.Result; import play.test.Helpers; -import scala.concurrent.Await; -import scala.concurrent.Future; -import scala.concurrent.duration.FiniteDuration; -import utils.module.OnRequestHandler; +import utils.module.ACTOR_NAMES; import utils.module.StartModule; import java.io.File; import java.io.IOException; -import java.util.HashMap; +import java.util.List; import java.util.Map; -import static org.powermock.api.mockito.PowerMockito.when; +import static play.inject.Bindings.bind; @RunWith(PowerMockRunner.class) -@PrepareForTest({org.sunbird.Application.class, BaseController.class, ActorRef.class, Await.class, org.sunbird.Application.class, Patterns.class}) -@PowerMockIgnore({"javax.management.*", "javax.net.ssl.*", "javax.security.*"}) +@PowerMockIgnore({"javax.management.*", "javax.net.ssl.*", "javax.security.*", "jdk.internal.reflect.*"}) public abstract class BaseApplicationTest { protected Application application; - private ActorSystem system; - private Props props; - private org.sunbird.Application app; - private static ActorRef actorRef; - private static BaseController baseController; - public void setup(Class actorClass) { + public void setup(Class actorClass, ACTOR_NAMES actor) { try { application = - new GuiceApplicationBuilder() - .in(new File("path/to/app")) - .in(Mode.TEST) - .disable(StartModule.class) - .build(); + new GuiceApplicationBuilder() + .in(new File("path/to/app")) + .in(Mode.TEST) + .disable(StartModule.class) +// .disable(ActorStartModule.class) + .overrides(bind(actor.getActorClass()).to(actorClass)) + .build(); Helpers.start(application); - system = ActorSystem.create("system"); - props = Props.create(actorClass); - actorRef = system.actorOf(props); - baseController = Mockito.mock(BaseController.class); - applicationSetUp(); - Mockito.when(baseController.getActorRef(Mockito.anyString())).thenReturn(actorRef); - PowerMockito.mockStatic(OnRequestHandler.class); - PowerMockito.mockStatic(Patterns.class); - Futuref1= Futures.successful(getResponseObject()); - when(Patterns.ask(Mockito.any(ActorRef.class),Mockito.any(Request.class),Mockito.any(Timeout.class))).thenReturn(f1); } catch (Exception e) { } } - public void applicationSetUp() throws BaseException { - app = PowerMockito.mock(org.sunbird.Application.class); - PowerMockito.mockStatic(org.sunbird.Application.class); - PowerMockito.when(org.sunbird.Application.getInstance()).thenReturn(app); - app.init(); - } - private Response getResponseObject() { - - Response response = new Response(); - response.put("ResponseCode", "success"); - return response; - } - - public Result performTest(String url, String method) { - Http.RequestBuilder req = new Http.RequestBuilder().uri(url).method(method); - Result result = Helpers.route(application, req); - return result; + public void setup(List actors, Class actorClass) { + GuiceApplicationBuilder applicationBuilder = + new GuiceApplicationBuilder() + .in(new File("path/to/app")) + .in(Mode.TEST) + .disable(StartModule.class); +// .disable(ActorStartModule.class); + for (ACTOR_NAMES actor : actors) { + applicationBuilder = applicationBuilder.overrides(bind(actor.getActorClass()).to(actorClass)); + } + application = applicationBuilder.build(); + Helpers.start(application); } public String getResponseCode(Result result) { diff --git a/service/test/controllers/BaseControllerTest.java b/service/test/controllers/BaseControllerTest.java deleted file mode 100644 index 9c7bc87..0000000 --- a/service/test/controllers/BaseControllerTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package controllers; - -import akka.actor.ActorRef; -import org.apache.commons.lang3.StringUtils; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.sunbird.BaseException; -import org.sunbird.response.Response; -import scala.concurrent.Await; -import utils.JsonKey; - -import static org.junit.Assert.assertEquals; - - -@RunWith(PowerMockRunner.class) -@PrepareForTest({org.sunbird.Application.class, BaseController.class, ActorRef.class, Await.class, org.sunbird.Application.class}) -@PowerMockIgnore({"javax.management.*", "javax.net.ssl.*", "javax.security.*"}) - -public class BaseControllerTest { - private org.sunbird.Application application; - - public BaseControllerTest() throws BaseException { - baseControllerTestsetUp(); - } - - public void baseControllerTestsetUp() throws BaseException { - application = PowerMockito.mock(org.sunbird.Application.class); - PowerMockito.mockStatic(org.sunbird.Application.class); - PowerMockito.when(org.sunbird.Application.getInstance()).thenReturn(application); - application.init(); - } - - @Test - public void testJsonifyResponseFailure() { - Response response = new Response(); - BaseController controller = new BaseController(); - response.put(JsonKey.MESSAGE, response.getResult()); - String jsonifyResponse = "";//controller.jsonify(response); - assertEquals(StringUtils.EMPTY, jsonifyResponse); - } -} \ No newline at end of file diff --git a/service/test/controllers/CertificateControllerTest.java b/service/test/controllers/CertificateControllerTest.java index 32ba2e0..a6962ce 100644 --- a/service/test/controllers/CertificateControllerTest.java +++ b/service/test/controllers/CertificateControllerTest.java @@ -8,19 +8,16 @@ import org.junit.Test; import org.powermock.core.classloader.annotations.PrepareForTest; import org.sunbird.JsonKeys; -import org.sunbird.message.ResponseCode; -import org.sunbird.request.HeaderParam; import play.libs.Json; import play.mvc.Http; import play.mvc.Result; import play.test.Helpers; -import utils.JsonKey; +import utils.module.ACTOR_NAMES; import utils.module.OnRequestHandler; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; @@ -29,7 +26,7 @@ public class CertificateControllerTest extends BaseApplicationTest { @Before public void before() { - setup(DummyActor.class); + setup(Arrays.asList(ACTOR_NAMES.CERTIFICATION_ACTOR),DummyActor.class); } @Test diff --git a/service/test/controllers/TestHelper.java b/service/test/controllers/TestHelper.java index 3e102a4..7982200 100644 --- a/service/test/controllers/TestHelper.java +++ b/service/test/controllers/TestHelper.java @@ -6,7 +6,9 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import play.libs.Json; @@ -42,7 +44,8 @@ public Result performTest(String url, String method, Map requestMap, Map headerM } else { req = new Http.RequestBuilder().uri(url).method(method); } - req.headers(headerMap); + Http.Headers headers = new Http.Headers(headerMap); + req.headers(headers); Result result = route(fakeApplication(), req); return result; } @@ -80,10 +83,10 @@ public int getResponseStatus(Result result) { * * @return */ - public Map getHeaderMap() { - Map headerMap = new HashMap<>(); - headerMap.put("x-authenticated-user-token", new String[] {"Some authenticated user ID"}); - headerMap.put("Authorization", new String[] {"Bearer ...."}); + public Map> getHeaderMap() { + Map> headerMap = new HashMap<>(); + headerMap.put("x-authenticated-user-token", Arrays.asList("Some authenticated user ID")); + headerMap.put("Authorization", Arrays.asList("Bearer ....")); return headerMap; } } \ No newline at end of file diff --git a/service/test/controllers/health/HealthControllerTest.java b/service/test/controllers/health/HealthControllerTest.java index d7362ea..fa6dbd3 100644 --- a/service/test/controllers/health/HealthControllerTest.java +++ b/service/test/controllers/health/HealthControllerTest.java @@ -1,56 +1,38 @@ package controllers.health; -import controllers.BaseControllerTest; -import controllers.TestHelper; -import org.junit.After; +import controllers.BaseApplicationTest; +import controllers.DummyActor; import org.junit.Before; import org.junit.Test; -import org.sunbird.BaseException; -import play.Application; import play.mvc.Result; -import play.test.Helpers; +import utils.module.ACTOR_NAMES; import javax.ws.rs.core.Response; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; -public class HealthControllerTest extends BaseControllerTest { - TestHelper testHelper; - public static Application app; - public static Map headerMap; - - public HealthControllerTest() throws BaseException { - super(); - } +public class HealthControllerTest extends BaseApplicationTest { @Before - public void setUp(){ - testHelper = new TestHelper(); - app = Helpers.fakeApplication(); - Helpers.start(app); - headerMap = testHelper.getHeaderMap(); + public void before() { + setup(Arrays.asList(ACTOR_NAMES.CERTIFICATION_ACTOR), DummyActor.class); } - @After - public void tearDown(){ - headerMap = null; - app = null; - testHelper = null; - } @Test public void testGetHealthSuccess() { Map reqMap = new HashMap<>(); reqMap.put("accept", "yes"); - Result result = testHelper.performTest("/health", "GET", reqMap, headerMap); - assertTrue(testHelper.getResponseStatus(result) == Response.Status.OK.getStatusCode()); + Result result = performTest("/health", "GET", reqMap); + assertTrue(getResponseStatus(result) == Response.Status.OK.getStatusCode()); } @Test public void testGetHealthFailure() { Map reqMap = new HashMap<>(); reqMap.put("accept", "yes"); - Result result = testHelper.performTest("/health", "POST", reqMap, headerMap); - assertTrue(testHelper.getResponseStatus(result) == Response.Status.NOT_FOUND.getStatusCode()); + Result result = performTest("/health", "POST", reqMap); + assertTrue(getResponseStatus(result) == Response.Status.NOT_FOUND.getStatusCode()); } } \ No newline at end of file