From fa1d2b88efb50b9671bf35c58dea2d5e7f63d21a Mon Sep 17 00:00:00 2001
From: saipradeep_ravipati <saipradeep.ravipati@tarento.com>
Date: Tue, 25 Apr 2023 14:32:02 +0530
Subject: [PATCH] Added validate-api for OGHR question assestment requirement

---
 pom.xml                                       |    1 +
 validate-api/pom.xml                          |   59 +
 validate-api/validate-actors/pom.xml          |  123 ++
 .../org/sunbird/actors/HealthActor.scala      |   20 +
 .../src/test/resources/application.conf       |  416 +++++++
 .../scala/org/sunbird/actors/BaseSpec.scala   |   78 ++
 .../validate-hierarchy-manager/pom.xml        |  136 +++
 .../src/test/resources/application.conf       |  423 +++++++
 .../src/test/resources/cassandra-unit.yaml    |  590 ++++++++++
 .../src/test/resources/logback.xml            |   28 +
 .../scala/org/sunbird/managers/BaseSpec.scala |  101 ++
 .../app/controllers/BaseController.scala      |   73 ++
 .../app/controllers/HealthController.scala    |   31 +
 .../QuestionValidateController.java           |   37 +
 .../app/filters/AccessLogFilter.scala         |   45 +
 .../app/handlers/SignalHandler.scala          |   33 +
 .../app/modules/AssessmentModule.scala        |   16 +
 .../app/utils/ActorNames.scala                |    7 +
 .../validate-service/app/utils/ApiId.scala    |    9 +
 .../validate-service/app/utils/Attrs.java     |   21 +
 .../app/utils/JavaJsonUtils.scala             |   38 +
 .../validate-service/app/utils/JsonKey.java   | 1020 +++++++++++++++++
 .../app/utils/QuestionOperations.scala        |    6 +
 .../app/utils/RequestContext.java             |   87 ++
 .../validate-service/conf/application.conf    |  407 +++++++
 .../validate-service/conf/logback.xml         |   28 +
 validate-api/validate-service/conf/routes     |    8 +
 validate-api/validate-service/pom.xml         |  188 +++
 .../test/controllers/base/BaseSpec.scala      |   38 +
 .../controllers/v3/HealthControllerSpec.scala |   18 +
 .../test/modules/TestModule.scala             |   26 +
 31 files changed, 4111 insertions(+)
 create mode 100644 validate-api/pom.xml
 create mode 100644 validate-api/validate-actors/pom.xml
 create mode 100644 validate-api/validate-actors/src/main/scala/org/sunbird/actors/HealthActor.scala
 create mode 100644 validate-api/validate-actors/src/test/resources/application.conf
 create mode 100644 validate-api/validate-actors/src/test/scala/org/sunbird/actors/BaseSpec.scala
 create mode 100644 validate-api/validate-hierarchy-manager/pom.xml
 create mode 100644 validate-api/validate-hierarchy-manager/src/test/resources/application.conf
 create mode 100755 validate-api/validate-hierarchy-manager/src/test/resources/cassandra-unit.yaml
 create mode 100644 validate-api/validate-hierarchy-manager/src/test/resources/logback.xml
 create mode 100644 validate-api/validate-hierarchy-manager/src/test/scala/org/sunbird/managers/BaseSpec.scala
 create mode 100644 validate-api/validate-service/app/controllers/BaseController.scala
 create mode 100644 validate-api/validate-service/app/controllers/HealthController.scala
 create mode 100644 validate-api/validate-service/app/controllers/QuestionValidateController.java
 create mode 100644 validate-api/validate-service/app/filters/AccessLogFilter.scala
 create mode 100644 validate-api/validate-service/app/handlers/SignalHandler.scala
 create mode 100644 validate-api/validate-service/app/modules/AssessmentModule.scala
 create mode 100644 validate-api/validate-service/app/utils/ActorNames.scala
 create mode 100644 validate-api/validate-service/app/utils/ApiId.scala
 create mode 100644 validate-api/validate-service/app/utils/Attrs.java
 create mode 100644 validate-api/validate-service/app/utils/JavaJsonUtils.scala
 create mode 100644 validate-api/validate-service/app/utils/JsonKey.java
 create mode 100644 validate-api/validate-service/app/utils/QuestionOperations.scala
 create mode 100644 validate-api/validate-service/app/utils/RequestContext.java
 create mode 100644 validate-api/validate-service/conf/application.conf
 create mode 100644 validate-api/validate-service/conf/logback.xml
 create mode 100644 validate-api/validate-service/conf/routes
 create mode 100644 validate-api/validate-service/pom.xml
 create mode 100644 validate-api/validate-service/test/controllers/base/BaseSpec.scala
 create mode 100644 validate-api/validate-service/test/controllers/v3/HealthControllerSpec.scala
 create mode 100644 validate-api/validate-service/test/modules/TestModule.scala

diff --git a/pom.xml b/pom.xml
index 0558992df..d5ecfe39b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,6 +31,7 @@
 				<module>taxonomy-api</module>
 				<module>platform-modules</module>
 				<module>search-api</module>
+				<module>validate-api</module>
 			</modules>
 		</profile>
 		<profile>
diff --git a/validate-api/pom.xml b/validate-api/pom.xml
new file mode 100644
index 000000000..fc043cb92
--- /dev/null
+++ b/validate-api/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>knowledge-platform</artifactId>
+        <groupId>org.sunbird</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>validate-api</artifactId>
+    <packaging>pom</packaging>
+    <name>validate-api</name>
+    <modules>
+        <module>validate-actors</module>
+        <module>validate-service</module>
+        <module>validate-hierarchy-manager</module>
+    </modules>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <scala.major.version>2.11</scala.major.version>
+    </properties>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-assembly-plugin</artifactId>
+                    <version>3.3.0</version>
+                    <configuration>
+                        <descriptors>
+                            <descriptor>src/assembly/bin.xml</descriptor>
+                        </descriptors>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.8.1</version>
+                    <configuration>
+                        <release>11</release>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.scoverage</groupId>
+                    <artifactId>scoverage-maven-plugin</artifactId>
+                    <configuration>
+                        <scalaVersion>${scala.version}</scalaVersion>
+                        <aggregate>true</aggregate>
+                        <highlighting>true</highlighting>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+</project>
diff --git a/validate-api/validate-actors/pom.xml b/validate-api/validate-actors/pom.xml
new file mode 100644
index 000000000..99a3ea676
--- /dev/null
+++ b/validate-api/validate-actors/pom.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>validate-api</artifactId>
+        <groupId>org.sunbird</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>validate-actors</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala-library</artifactId>
+            <version>${scala.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.inject</groupId>
+            <artifactId>javax.inject</artifactId>
+            <version>1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.sunbird</groupId>
+            <artifactId>actor-core</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.sunbird</groupId>
+            <artifactId>graph-engine_2.11</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.sunbird</groupId>
+            <artifactId>validate-hierarchy-manager</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.sunbird</groupId>
+            <artifactId>import-manager</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.scalatest</groupId>
+            <artifactId>scalatest_${scala.maj.version}</artifactId>
+            <version>${scalatest.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.scalamock</groupId>
+            <artifactId>scalamock_${scala.maj.version}</artifactId>
+            <version>4.4.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-testkit_${scala.maj.version}</artifactId>
+            <version>2.5.22</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <sourceDirectory>src/main/scala</sourceDirectory>
+        <testSourceDirectory>src/test/scala</testSourceDirectory>
+        <plugins>
+            <plugin>
+                <groupId>net.alchim31.maven</groupId>
+                <artifactId>scala-maven-plugin</artifactId>
+                <version>4.4.0</version>
+                <configuration>
+                    <scalaVersion>${scala.version}</scalaVersion>
+                    <checkMultipleScalaVersions>false</checkMultipleScalaVersions>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>scala-compile-first</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>scala-test-compile</id>
+                        <phase>process-test-resources</phase>
+                        <goals>
+                            <goal>testCompile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.scalatest</groupId>
+                <artifactId>scalatest-maven-plugin</artifactId>
+                <version>2.0.0</version>
+                <executions>
+                    <execution>
+                        <id>test</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.scoverage</groupId>
+                <artifactId>scoverage-maven-plugin</artifactId>
+                <version>${scoverage.plugin.version}</version>
+                <configuration>
+                    <scalaVersion>${scala.version}</scalaVersion>
+                    <aggregate>true</aggregate>
+                    <highlighting>true</highlighting>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/validate-api/validate-actors/src/main/scala/org/sunbird/actors/HealthActor.scala b/validate-api/validate-actors/src/main/scala/org/sunbird/actors/HealthActor.scala
new file mode 100644
index 000000000..3072bb928
--- /dev/null
+++ b/validate-api/validate-actors/src/main/scala/org/sunbird/actors/HealthActor.scala
@@ -0,0 +1,20 @@
+package org.sunbird.actors
+
+import javax.inject.Inject
+import org.sunbird.actor.core.BaseActor
+import org.sunbird.common.dto.{Request, Response}
+import org.sunbird.graph.OntologyEngineContext
+import org.sunbird.graph.health.HealthCheckManager
+
+import scala.concurrent.{ExecutionContext, Future}
+
+
+class HealthActor @Inject() (implicit oec: OntologyEngineContext) extends BaseActor {
+
+    implicit val ec: ExecutionContext = getContext().dispatcher
+
+    @throws[Throwable]
+    override def onReceive(request: Request): Future[Response] = {
+        HealthCheckManager.checkAllSystemHealth()
+    }
+}
diff --git a/validate-api/validate-actors/src/test/resources/application.conf b/validate-api/validate-actors/src/test/resources/application.conf
new file mode 100644
index 000000000..24d3a74f2
--- /dev/null
+++ b/validate-api/validate-actors/src/test/resources/application.conf
@@ -0,0 +1,416 @@
+# This is the main configuration file for the application.
+# https://www.playframework.com/documentation/latest/ConfigFile
+# ~~~~~
+# Play uses HOCON as its configuration file format.  HOCON has a number
+# of advantages over other config formats, but there are two things that
+# can be used when modifying settings.
+#
+# You can include other configuration files in this main application.conf file:
+#include "extra-config.conf"
+#
+# You can declare variables and substitute for them:
+#mykey = ${some.value}
+#
+# And if an environment variable exists when there is no other substitution, then
+# HOCON will fall back to substituting environment variable:
+#mykey = ${JAVA_HOME}
+
+## Akka
+# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration
+# https://www.playframework.com/documentation/latest/JavaAkka#Configuration
+# ~~~~~
+# 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:
+  #
+  # <logger name="akka.actor" level="INFO" />
+  #
+  # And then uncomment this line to debug the configuration.
+  #
+  #log-config-on-start = true
+}
+
+## Secret key
+# http://www.playframework.com/documentation/latest/ApplicationSecret
+# ~~~~~
+# The secret key is used to sign Play's session cookie.
+# This must be changed for production, but we don't recommend you change it in this file.
+play.http.secret.key = a-long-secret-to-calm-the-rage-of-the-entropy-gods
+
+## Modules
+# https://www.playframework.com/documentation/latest/Modules
+# ~~~~~
+# Control which modules are loaded when Play starts.  Note that modules are
+# the replacement for "GlobalSettings", which are deprecated in 2.5.x.
+# Please see https://www.playframework.com/documentation/latest/GlobalSettings
+# for more information.
+#
+# You can also extend Play functionality by using one of the publically available
+# Play modules: https://playframework.com/documentation/latest/ModuleDirectory
+play.modules {
+  # By default, Play will load any class called Module that is defined
+  # in the root package (the "app" directory), or you can define them
+  # explicitly below.
+  # If there are any built-in modules that you want to enable, you can list them here.
+  #enabled += my.application.Module
+
+  # If there are any built-in modules that you want to disable, you can list them here.
+  #disabled += ""
+}
+
+## IDE
+# https://www.playframework.com/documentation/latest/IDE
+# ~~~~~
+# Depending on your IDE, you can add a hyperlink for errors that will jump you
+# directly to the code location in the IDE in dev mode. The following line makes
+# use of the IntelliJ IDEA REST interface:
+#play.editor="http://localhost:63342/api/file/?file=%s&line=%s"
+
+## Internationalisation
+# https://www.playframework.com/documentation/latest/JavaI18N
+# https://www.playframework.com/documentation/latest/ScalaI18N
+# ~~~~~
+# Play comes with its own i18n settings, which allow the user's preferred language
+# to map through to internal messages, or allow the language to be stored in a cookie.
+play.i18n {
+  # The application languages
+  langs = [ "en" ]
+
+  # Whether the language cookie should be secure or not
+  #langCookieSecure = true
+
+  # Whether the HTTP only attribute of the cookie should be set to true
+  #langCookieHttpOnly = true
+}
+
+## Play HTTP settings
+# ~~~~~
+play.http {
+  ## Router
+  # https://www.playframework.com/documentation/latest/JavaRouting
+  # https://www.playframework.com/documentation/latest/ScalaRouting
+  # ~~~~~
+  # Define the Router object to use for this application.
+  # This router will be looked up first when the application is starting up,
+  # so make sure this is the entry point.
+  # Furthermore, it's assumed your route file is named properly.
+  # So for an application router like `my.application.Router`,
+  # you may need to define a router file `conf/my.application.routes`.
+  # Default to Routes in the root package (aka "apps" folder) (and conf/routes)
+  #router = my.application.Router
+
+  ## Action Creator
+  # https://www.playframework.com/documentation/latest/JavaActionCreator
+  # ~~~~~
+  #actionCreator = null
+
+  ## ErrorHandler
+  # https://www.playframework.com/documentation/latest/JavaRouting
+  # https://www.playframework.com/documentation/latest/ScalaRouting
+  # ~~~~~
+  # If null, will attempt to load a class called ErrorHandler in the root package,
+  #errorHandler = null
+
+  ## Session & Flash
+  # https://www.playframework.com/documentation/latest/JavaSessionFlash
+  # https://www.playframework.com/documentation/latest/ScalaSessionFlash
+  # ~~~~~
+  session {
+    # Sets the cookie to be sent only over HTTPS.
+    #secure = true
+
+    # Sets the cookie to be accessed only by the server.
+    #httpOnly = true
+
+    # Sets the max-age field of the cookie to 5 minutes.
+    # NOTE: this only sets when the browser will discard the cookie. Play will consider any
+    # cookie value with a valid signature to be a valid session forever. To implement a server side session timeout,
+    # you need to put a timestamp in the session and check it at regular intervals to possibly expire it.
+    #maxAge = 300
+
+    # Sets the domain on the session cookie.
+    #domain = "example.com"
+  }
+
+  flash {
+    # Sets the cookie to be sent only over HTTPS.
+    #secure = true
+
+    # Sets the cookie to be accessed only by the server.
+    #httpOnly = true
+  }
+}
+
+## 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"
+}
+
+## WS (HTTP Client)
+# https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS
+# ~~~~~
+# The HTTP client primarily used for REST APIs.  The default client can be
+# configured directly, but you can also create different client instances
+# with customized settings. You must enable this by adding to build.sbt:
+#
+# libraryDependencies += ws // or javaWs if using java
+#
+play.ws {
+  # Sets HTTP requests not to follow 302 requests
+  #followRedirects = false
+
+  # Sets the maximum number of open HTTP connections for the client.
+  #ahc.maxConnectionsTotal = 50
+
+  ## WS SSL
+  # https://www.playframework.com/documentation/latest/WsSSL
+  # ~~~~~
+  ssl {
+    # Configuring HTTPS with Play WS does not require programming.  You can
+    # set up both trustManager and keyManager for mutual authentication, and
+    # turn on JSSE debugging in development with a reload.
+    #debug.handshake = true
+    #trustManager = {
+    #  stores = [
+    #    { type = "JKS", path = "exampletrust.jks" }
+    #  ]
+    #}
+  }
+}
+
+## Cache
+# https://www.playframework.com/documentation/latest/JavaCache
+# https://www.playframework.com/documentation/latest/ScalaCache
+# ~~~~~
+# 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
+#
+play.cache {
+  # If you want to bind several caches, you can bind the individually
+  #bindCaches = ["db-cache", "user-cache", "session-cache"]
+}
+
+## Filter Configuration
+# https://www.playframework.com/documentation/latest/Filters
+# ~~~~~
+# There are a number of built-in filters that can be enabled and configured
+# to give Play greater security.
+#
+play.filters {
+
+  # Enabled filters are run automatically against Play.
+  # CSRFFilter, AllowedHostFilters, and SecurityHeadersFilters are enabled by default.
+  enabled = []
+
+  # Disabled filters remove elements from the enabled list.
+  # disabled += filters.CSRFFilter
+
+
+  ## CORS filter configuration
+  # https://www.playframework.com/documentation/latest/CorsFilter
+  # ~~~~~
+  # CORS is a protocol that allows web applications to make requests from the browser
+  # across different domains.
+  # NOTE: You MUST apply the CORS configuration before the CSRF filter, as CSRF has
+  # dependencies on CORS settings.
+  cors {
+    # Filter paths by a whitelist of path prefixes
+    #pathPrefixes = ["/some/path", ...]
+
+    # The allowed origins. If null, all origins are allowed.
+    #allowedOrigins = ["http://www.example.com"]
+
+    # The allowed HTTP methods. If null, all methods are allowed
+    #allowedHttpMethods = ["GET", "POST"]
+  }
+
+  ## Security headers filter configuration
+  # https://www.playframework.com/documentation/latest/SecurityHeaders
+  # ~~~~~
+  # Defines security headers that prevent XSS attacks.
+  # If enabled, then all options are set to the below configuration by default:
+  headers {
+    # The X-Frame-Options header. If null, the header is not set.
+    #frameOptions = "DENY"
+
+    # The X-XSS-Protection header. If null, the header is not set.
+    #xssProtection = "1; mode=block"
+
+    # The X-Content-Type-Options header. If null, the header is not set.
+    #contentTypeOptions = "nosniff"
+
+    # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set.
+    #permittedCrossDomainPolicies = "master-only"
+
+    # The Content-Security-Policy header. If null, the header is not set.
+    #contentSecurityPolicy = "default-src 'self'"
+  }
+
+  ## Allowed hosts filter configuration
+  # https://www.playframework.com/documentation/latest/AllowedHostsFilter
+  # ~~~~~
+  # Play provides a filter that lets you configure which hosts can access your application.
+  # This is useful to prevent cache poisoning attacks.
+  hosts {
+    # Allow requests to example.com, its subdomains, and localhost:9000.
+    #allowed = [".example.com", "localhost:9000"]
+  }
+}
+
+# Learning-Service Configuration
+content.metadata.visibility.parent=["textbookunit", "courseunit", "lessonplanunit"]
+
+# Cassandra Configuration
+content.keyspace.name=content_store
+content.keyspace.table=content_data
+#TODO: Add Configuration for assessment. e.g: question_data
+orchestrator.keyspace.name=script_store
+orchestrator.keyspace.table=script_data
+cassandra.lp.connection="127.0.0.1:9042,127.0.0.2:9042,127.0.0.3:9042"
+cassandra.lpa.connection="127.0.0.1:9042,127.0.0.2:9042,127.0.0.3:9042"
+
+# Redis Configuration
+redis.host=localhost
+redis.port=6379
+redis.maxConnections=128
+
+#Condition to enable publish locally
+content.publish_task.enabled=true
+
+#directory location where store unzip file
+dist.directory=/data/tmp/dist/
+output.zipfile=/data/tmp/story.zip
+source.folder=/data/tmp/temp2/
+save.directory=/data/tmp/temp/
+
+# Content 2 vec analytics URL
+CONTENT_TO_VEC_URL="http://172.31.27.233:9000/content-to-vec"
+
+# FOR CONTENT WORKFLOW PIPELINE (CWP)
+
+#--Content Workflow Pipeline Mode
+OPERATION_MODE=TEST
+
+#--Maximum Content Package File Size Limit in Bytes (50 MB)
+MAX_CONTENT_PACKAGE_FILE_SIZE_LIMIT=52428800
+
+#--Maximum Asset File Size Limit in Bytes (20 MB)
+MAX_ASSET_FILE_SIZE_LIMIT=20971520
+
+#--No of Retry While File Download Fails
+RETRY_ASSET_DOWNLOAD_COUNT=1
+
+#Google-vision-API
+google.vision.tagging.enabled = false
+
+#Orchestrator env properties
+env="https://dev.ekstep.in/api/learning"
+
+#Current environment
+cloud_storage.env=dev
+
+
+#Folder configuration
+cloud_storage.content.folder=content
+cloud_storage.asset.folder=assets
+cloud_storage.artefact.folder=artifact
+cloud_storage.bundle.folder=bundle
+cloud_storage.media.folder=media
+cloud_storage.ecar.folder=ecar_files
+
+# Media download configuration
+content.media.base.url="https://dev.open-sunbird.org"
+plugin.media.base.url="https://dev.open-sunbird.org"
+
+# Configuration
+graph.dir=/data/testingGraphDB
+akka.request_timeout=30
+environment.id=10000000
+graph.ids=["domain"]
+graph.passport.key.base=31b6fd1c4d64e745c867e61a45edc34a
+route.domain="bolt://localhost:7687"
+route.bolt.write.domain="bolt://localhost:7687"
+route.bolt.read.domain="bolt://localhost:7687"
+route.bolt.comment.domain="bolt://localhost:7687"
+route.all="bolt://localhost:7687"
+route.bolt.write.all="bolt://localhost:7687"
+route.bolt.read.all="bolt://localhost:7687"
+route.bolt.comment.all="bolt://localhost:7687"
+
+shard.id=1
+platform.auth.check.enabled=false
+platform.cache.ttl=3600000
+
+
+framework.max_term_creation_limit=200
+
+# Enable Suggested Framework in Get Channel API.
+channel.fetch.suggested_frameworks=true
+
+
+#Top N Config for Search Telemetry
+telemetry_env=dev
+telemetry.search.topn=5
+
+installation.id=ekstep
+
+
+channel.default="in.ekstep"
+
+
+# Language-Code Configuration
+platform.language.codes=["as","bn","en","gu","hi","hoc","jun","ka","mai","mr","unx","or","san","sat","ta","te","urd", "pj"]
+
+
+framework.categories_cached=["subject", "medium", "gradeLevel", "board"]
+framework.cache.ttl=86400
+framework.cache.read=false
+
+
+# Max size(width/height) of thumbnail in pixels
+max.thumbnail.size.pixels=150
+
+schema.base_path="../../schemas/"
+
+assessment.skip.validation=true
+uestion.keyspace="dev_question_store"
+questionset.keyspace="dev_hierarchy_store"
+cassandra {
+  lp {
+    connection: "127.0.0.1:9042,127.0.0.1:9042,127.0.0.1:9042"
+  }
+  lpa {
+    connection: "127.0.0.1:9042"
+  }
+}
+questionset.keyspace = "dev_hierarchy_store"
+
+import {
+  request_size_limit = 200
+  output_topic_name = "local.auto.creation.job.request"
+  required_props {
+    question = ["name", "code", "mimeType", "framework", "channel"]
+    questionset = ["name", "code", "mimeType", "framework", "channel"]
+  }
+  remove_props {
+    question = []
+    questionset = []
+  }
+}
+
+
+
diff --git a/validate-api/validate-actors/src/test/scala/org/sunbird/actors/BaseSpec.scala b/validate-api/validate-actors/src/test/scala/org/sunbird/actors/BaseSpec.scala
new file mode 100644
index 000000000..b1abb5a29
--- /dev/null
+++ b/validate-api/validate-actors/src/test/scala/org/sunbird/actors/BaseSpec.scala
@@ -0,0 +1,78 @@
+package org.sunbird.actors
+
+import java.util
+import java.util.concurrent.TimeUnit
+
+import akka.actor.{ActorSystem, Props}
+import akka.testkit.TestKit
+import org.scalatest.{FlatSpec, Matchers}
+import org.sunbird.common.dto.{Request, Response}
+import org.sunbird.graph.OntologyEngineContext
+import org.sunbird.graph.dac.model.Node
+
+import scala.concurrent.duration.FiniteDuration
+
+class BaseSpec extends FlatSpec with Matchers {
+  val system = ActorSystem.create("system")
+
+  def testUnknownOperation(props: Props, request: Request)(implicit oec: OntologyEngineContext) = {
+    request.setOperation("unknown")
+    val response = callActor(request, props)
+    assert("failed".equals(response.getParams.getStatus))
+  }
+
+  def callActor(request: Request, props: Props): Response = {
+    val probe = new TestKit(system)
+    val actorRef = system.actorOf(props)
+    actorRef.tell(request, probe.testActor)
+    probe.expectMsgType[Response](FiniteDuration.apply(100, TimeUnit.SECONDS))
+  }
+
+  def getNode(objectType: String, metadata: Option[util.Map[String, AnyRef]]): Node = {
+    val node = new Node("domain", "DATA_NODE", objectType)
+    node.setGraphId("domain")
+    val nodeMetadata = metadata.getOrElse(new util.HashMap[String, AnyRef]() {{
+      put("name", "Sunbird Node")
+      put("code", "sunbird-node")
+      put("status", "Draft")
+    }})
+    node.setNodeType("DATA_NODE")
+    node.setMetadata(nodeMetadata)
+    node.setObjectType(objectType)
+    node.setIdentifier("test_id")
+    node
+  }
+  def getCategoryNode(): util.List[Node] = {
+    val node = new Node()
+    node.setIdentifier("board")
+    node.setNodeType("DATA_NODE")
+    node.setObjectType("Category")
+    node.setMetadata(new util.HashMap[String, AnyRef]() {
+      {
+        put("code", "board")
+        put("orgIdFieldName", "boardIds")
+        put("targetIdFieldName", "targetBoardIds")
+        put("searchIdFieldName", "se_boardIds")
+        put("searchLabelFieldName", "se_boards")
+        put("status", "Live")
+      }
+    })
+    util.Arrays.asList(node)
+  }
+
+  def getNode(identifier: String, objectType: String, metadata: Option[util.Map[String, AnyRef]]): Node = {
+    val node = new Node("domain", "DATA_NODE", objectType)
+    node.setGraphId("domain")
+    val nodeMetadata = metadata.getOrElse(new util.HashMap[String, AnyRef]() {{
+      put("name", "Question 1")
+      put("code", "ques.1")
+      put("status", "Draft")
+      put("primaryCategory", "Multiple Choice Question")
+    }})
+    node.setNodeType("DATA_NODE")
+    node.setMetadata(nodeMetadata)
+    node.setObjectType(objectType)
+    node.setIdentifier(identifier)
+    node
+  }
+}
diff --git a/validate-api/validate-hierarchy-manager/pom.xml b/validate-api/validate-hierarchy-manager/pom.xml
new file mode 100644
index 000000000..05de0ff39
--- /dev/null
+++ b/validate-api/validate-hierarchy-manager/pom.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>validate-api</artifactId>
+        <groupId>org.sunbird</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>validate-hierarchy-manager</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.sunbird</groupId>
+            <artifactId>graph-engine_2.11</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.sunbird</groupId>
+            <artifactId>platform-common</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala-library</artifactId>
+            <version>${scala.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.scalatest</groupId>
+            <artifactId>scalatest_${scala.maj.version}</artifactId>
+            <version>3.1.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.neo4j</groupId>
+            <artifactId>neo4j-bolt</artifactId>
+            <version>3.5.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.neo4j</groupId>
+            <artifactId>neo4j-graphdb-api</artifactId>
+            <version>3.5.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.neo4j</groupId>
+            <artifactId>neo4j</artifactId>
+            <version>3.5.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.cassandraunit</groupId>
+            <artifactId>cassandra-unit</artifactId>
+            <version>3.11.2.0</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>httpcore</artifactId>
+                    <groupId>org.apache.httpcomponents</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>httpclient</artifactId>
+                    <groupId>org.apache.httpcomponents</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.mashape.unirest</groupId>
+            <artifactId>unirest-java</artifactId>
+            <version>1.4.9</version>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <sourceDirectory>src/main/scala</sourceDirectory>
+        <testSourceDirectory>src/test/scala</testSourceDirectory>
+        <plugins>
+            <plugin>
+                <groupId>net.alchim31.maven</groupId>
+                <artifactId>scala-maven-plugin</artifactId>
+                <version>4.4.0</version>
+                <configuration>
+                    <scalaVersion>${scala.version}</scalaVersion>
+                    <checkMultipleScalaVersions>false</checkMultipleScalaVersions>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>scala-compile-first</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>scala-test-compile</id>
+                        <phase>process-test-resources</phase>
+                        <goals>
+                            <goal>testCompile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.scalatest</groupId>
+                <artifactId>scalatest-maven-plugin</artifactId>
+                <version>2.0.0</version>
+                <executions>
+                    <execution>
+                        <id>test</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.scoverage</groupId>
+                <artifactId>scoverage-maven-plugin</artifactId>
+                <version>${scoverage.plugin.version}</version>
+                <configuration>
+                    <scalaVersion>${scala.version}</scalaVersion>
+                    <aggregate>true</aggregate>
+                    <highlighting>true</highlighting>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/validate-api/validate-hierarchy-manager/src/test/resources/application.conf b/validate-api/validate-hierarchy-manager/src/test/resources/application.conf
new file mode 100644
index 000000000..82fe873b5
--- /dev/null
+++ b/validate-api/validate-hierarchy-manager/src/test/resources/application.conf
@@ -0,0 +1,423 @@
+# This is the main configuration file for the application.
+# https://www.playframework.com/documentation/latest/ConfigFile
+# ~~~~~
+# Play uses HOCON as its configuration file format. HOCON has a number
+# of advantages over other config formats, but there are two things that
+# can be used when modifying settings.
+#
+# You can include other configuration files in this main application.conf file:
+#include "extra-config.conf"
+#
+# You can declare variables and substitute for them:
+#mykey = ${some.value}
+#
+# And if an environment variable exists when there is no other substitution, then
+# HOCON will fall back to substituting environment variable:
+#mykey = ${JAVA_HOME}
+
+## Akka
+# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration
+# https://www.playframework.com/documentation/latest/JavaAkka#Configuration
+# ~~~~~
+# 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:
+  #
+  # <logger name="akka.actor" level="INFO" />
+  #
+  # And then uncomment this line to debug the configuration.
+  #
+  #log-config-on-start = true
+  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"
+    }
+  }
+  actors-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
+  }
+  actor {
+    deployment {
+      /healthActor
+        {
+          router = smallest-mailbox-pool
+          nr-of-instances = 5
+          dispatcher = actors-dispatcher
+        }
+      /itemSetActor
+        {
+          router = smallest-mailbox-pool
+          nr-of-instances = 2
+          dispatcher = actors-dispatcher
+        }
+      /questionActor
+        {
+          router = smallest-mailbox-pool
+          nr-of-instances = 5
+          dispatcher = actors-dispatcher
+        }
+      /questionSetActor
+        {
+          router = smallest-mailbox-pool
+          nr-of-instances = 5
+          dispatcher = actors-dispatcher
+        }
+    }
+  }
+}
+
+## Secret key
+# http://www.playframework.com/documentation/latest/ApplicationSecret
+# ~~~~~
+# The secret key is used to sign Play's session cookie.
+# This must be changed for production, but we don't recommend you change it in this file.
+play.http.secret.key= a-long-secret-to-calm-the-rage-of-the-entropy-gods
+
+## Modules
+# https://www.playframework.com/documentation/latest/Modules
+# ~~~~~
+# Control which modules are loaded when Play starts. Note that modules are
+# the replacement for "GlobalSettings", which are deprecated in 2.5.x.
+# Please see https://www.playframework.com/documentation/latest/GlobalSettings
+# for more information.
+#
+# You can also extend Play functionality by using one of the publically available
+# Play modules: https://playframework.com/documentation/latest/ModuleDirectory
+play.modules {
+  # By default, Play will load any class called Module that is defined
+  # in the root package (the "app" directory), or you can define them
+  # explicitly below.
+  # If there are any built-in modules that you want to enable, you can list them here.
+  #enabled += my.application.Module
+
+  # If there are any built-in modules that you want to disable, you can list them here.
+  #disabled += ""
+  enabled += modules.AssessmentModule
+}
+
+## IDE
+# https://www.playframework.com/documentation/latest/IDE
+# ~~~~~
+# Depending on your IDE, you can add a hyperlink for errors that will jump you
+# directly to the code location in the IDE in dev mode. The following line makes
+# use of the IntelliJ IDEA REST interface:
+#play.editor="http://localhost:63342/api/file/?file=%s&line=%s"
+
+## Internationalisation
+# https://www.playframework.com/documentation/latest/JavaI18N
+# https://www.playframework.com/documentation/latest/ScalaI18N
+# ~~~~~
+# Play comes with its own i18n settings, which allow the user's preferred language
+# to map through to internal messages, or allow the language to be stored in a cookie.
+play.i18n {
+  # The application languages
+  langs = [ "en" ]
+
+  # Whether the language cookie should be secure or not
+  #langCookieSecure = true
+
+  # Whether the HTTP only attribute of the cookie should be set to true
+  #langCookieHttpOnly = true
+}
+
+## Play HTTP settings
+# ~~~~~
+play.http {
+  ## Router
+  # https://www.playframework.com/documentation/latest/JavaRouting
+  # https://www.playframework.com/documentation/latest/ScalaRouting
+  # ~~~~~
+  # Define the Router object to use for this application.
+  # This router will be looked up first when the application is starting up,
+  # so make sure this is the entry point.
+  # Furthermore, it's assumed your route file is named properly.
+  # So for an application router like `my.application.Router`,
+  # you may need to define a router file `conf/my.application.routes`.
+  # Default to Routes in the root package (aka "apps" folder) (and conf/routes)
+  #router = my.application.Router
+
+  ## Action Creator
+  # https://www.playframework.com/documentation/latest/JavaActionCreator
+  # ~~~~~
+  #actionCreator = null
+
+  ## ErrorHandler
+  # https://www.playframework.com/documentation/latest/JavaRouting
+  # https://www.playframework.com/documentation/latest/ScalaRouting
+  # ~~~~~
+  # If null, will attempt to load a class called ErrorHandler in the root package,
+  #errorHandler = null
+
+  ## Session & Flash
+  # https://www.playframework.com/documentation/latest/JavaSessionFlash
+  # https://www.playframework.com/documentation/latest/ScalaSessionFlash
+  # ~~~~~
+  session {
+    # Sets the cookie to be sent only over HTTPS.
+    #secure = true
+
+    # Sets the cookie to be accessed only by the server.
+    #httpOnly = true
+
+    # Sets the max-age field of the cookie to 5 minutes.
+    # NOTE: this only sets when the browser will discard the cookie. Play will consider any
+    # cookie value with a valid signature to be a valid session forever. To implement a server side session timeout,
+    # you need to put a timestamp in the session and check it at regular intervals to possibly expire it.
+    #maxAge = 300
+
+    # Sets the domain on the session cookie.
+    #domain = "example.com"
+  }
+
+  flash {
+    # Sets the cookie to be sent only over HTTPS.
+    #secure = true
+
+    # Sets the cookie to be accessed only by the server.
+    #httpOnly = true
+  }
+}
+
+play.server.http.idleTimeout = 60s
+play.http.parser.maxDiskBuffer = 10MB
+parsers.anyContent.maxLength = 10MB
+
+## 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"
+}
+
+## WS (HTTP Client)
+# https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS
+# ~~~~~
+# The HTTP client primarily used for REST APIs. The default client can be
+# configured directly, but you can also create different client instances
+# with customized settings. You must enable this by adding to build.sbt:
+#
+# libraryDependencies += ws // or javaWs if using java
+#
+play.ws {
+  # Sets HTTP requests not to follow 302 requests
+  #followRedirects = false
+
+  # Sets the maximum number of open HTTP connections for the client.
+  #ahc.maxConnectionsTotal = 50
+
+  ## WS SSL
+  # https://www.playframework.com/documentation/latest/WsSSL
+  # ~~~~~
+  ssl {
+    # Configuring HTTPS with Play WS does not require programming. You can
+    # set up both trustManager and keyManager for mutual authentication, and
+    # turn on JSSE debugging in development with a reload.
+    #debug.handshake = true
+    #trustManager = {
+    # stores = [
+    # { type = "JKS", path = "exampletrust.jks" }
+    # ]
+    #}
+  }
+}
+
+## Cache
+# https://www.playframework.com/documentation/latest/JavaCache
+# https://www.playframework.com/documentation/latest/ScalaCache
+# ~~~~~
+# 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
+#
+play.cache {
+  # If you want to bind several caches, you can bind the individually
+  #bindCaches = ["db-cache", "user-cache", "session-cache"]
+}
+
+## Filter Configuration
+# https://www.playframework.com/documentation/latest/Filters
+# ~~~~~
+# There are a number of built-in filters that can be enabled and configured
+# to give Play greater security.
+#
+play.filters {
+
+  # Enabled filters are run automatically against Play.
+  # CSRFFilter, AllowedHostFilters, and SecurityHeadersFilters are enabled by default.
+  enabled = [filters.AccessLogFilter]
+
+  # Disabled filters remove elements from the enabled list.
+  # disabled += filters.CSRFFilter
+
+
+  ## CORS filter configuration
+  # https://www.playframework.com/documentation/latest/CorsFilter
+  # ~~~~~
+  # CORS is a protocol that allows web applications to make requests from the browser
+  # across different domains.
+  # NOTE: You MUST apply the CORS configuration before the CSRF filter, as CSRF has
+  # dependencies on CORS settings.
+  cors {
+    # Filter paths by a whitelist of path prefixes
+    #pathPrefixes = ["/some/path", ...]
+
+    # The allowed origins. If null, all origins are allowed.
+    #allowedOrigins = ["http://www.example.com"]
+
+    # The allowed HTTP methods. If null, all methods are allowed
+    #allowedHttpMethods = ["GET", "POST"]
+  }
+
+  ## Security headers filter configuration
+  # https://www.playframework.com/documentation/latest/SecurityHeaders
+  # ~~~~~
+  # Defines security headers that prevent XSS attacks.
+  # If enabled, then all options are set to the below configuration by default:
+  headers {
+    # The X-Frame-Options header. If null, the header is not set.
+    #frameOptions = "DENY"
+
+    # The X-XSS-Protection header. If null, the header is not set.
+    #xssProtection = "1; mode=block"
+
+    # The X-Content-Type-Options header. If null, the header is not set.
+    #contentTypeOptions = "nosniff"
+
+    # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set.
+    #permittedCrossDomainPolicies = "master-only"
+
+    # The Content-Security-Policy header. If null, the header is not set.
+    #contentSecurityPolicy = "default-src 'self'"
+  }
+
+  ## Allowed hosts filter configuration
+  # https://www.playframework.com/documentation/latest/AllowedHostsFilter
+  # ~~~~~
+  # Play provides a filter that lets you configure which hosts can access your application.
+  # This is useful to prevent cache poisoning attacks.
+  hosts {
+    # Allow requests to example.com, its subdomains, and localhost:9000.
+    #allowed = [".example.com", "localhost:9000"]
+  }
+}
+
+play.http.parser.maxMemoryBuffer = 50MB
+akka.http.parsing.max-content-length = 50MB
+schema.base_path="../../schemas/"
+
+# Cassandra Configuration
+cassandra.lp.connection="127.0.0.1:9042"
+content.keyspace = "content_store"
+
+# Redis Configuration
+redis.host="localhost"
+redis.port=6379
+redis.maxConnections=128
+
+# Graph Configuration
+graph.dir=/data/testingGraphDB
+akka.request_timeout=30
+environment.id=10000000
+graph.ids=["domain"]
+graph.passport.key.base=31b6fd1c4d64e745c867e61a45edc34a
+route.domain="bolt://localhost:7687"
+route.bolt.write.domain="bolt://localhost:7687"
+route.bolt.read.domain="bolt://localhost:7687"
+route.bolt.comment.domain="bolt://localhost:7687"
+route.all="bolt://localhost:7687"
+route.bolt.write.all="bolt://localhost:7687"
+route.bolt.read.all="bolt://localhost:7687"
+route.bolt.comment.all="bolt://localhost:7687"
+
+shard.id=1
+platform.auth.check.enabled=false
+platform.cache.ttl=3600000
+
+#Top N Config for Search Telemetry
+telemetry_env=dev
+
+installation.id=ekstep
+
+
+languageCode {
+  assamese : "as"
+  bengali : "bn"
+  english : "en"
+  gujarati : "gu"
+  hindi : "hi"
+  kannada : "ka"
+  marathi : "mr"
+  odia : "or"
+  tamil : "ta"
+  telugu : "te"
+}
+
+kafka {
+  urls : "localhost:9092"
+  topic.send.enable : true
+  topics.instruction : "sunbirddev.assessment.publish.request"
+}
+objectcategorydefinition.keyspace="category_store"
+question {
+  keyspace = "question_store"
+  list.limit=20
+}
+questionset.keyspace="hierarchy_store"
+
+cassandra {
+  lp {
+    connection: "localhost:9042"
+  }
+  lpa {
+    connection: "localhost:9042"
+  }
+}
+neo4j_objecttypes_enabled=["Question"]
+
+import {
+  request_size_limit = 200
+  output_topic_name = "local.auto.creation.job.request"
+  required_props {
+    question = ["name", "code", "mimeType", "framework", "channel"]
+    questionset = ["name", "code", "mimeType", "framework", "channel"]
+  }
+  remove_props {
+    question = []
+    questionset = []
+  }
+}
+
+root_node_visibility=["Default","Private"]
\ No newline at end of file
diff --git a/validate-api/validate-hierarchy-manager/src/test/resources/cassandra-unit.yaml b/validate-api/validate-hierarchy-manager/src/test/resources/cassandra-unit.yaml
new file mode 100755
index 000000000..a965a8fe5
--- /dev/null
+++ b/validate-api/validate-hierarchy-manager/src/test/resources/cassandra-unit.yaml
@@ -0,0 +1,590 @@
+# Cassandra storage config YAML
+
+# NOTE:
+#   See http://wiki.apache.org/cassandra/StorageConfiguration for
+#   full explanations of configuration directives
+# /NOTE
+
+# The name of the cluster. This is mainly used to prevent machines in
+# one logical cluster from joining another.
+cluster_name: 'Test Cluster'
+
+# You should always specify InitialToken when setting up a production
+# cluster for the first time, and often when adding capacity later.
+# The principle is that each node should be given an equal slice of
+# the token ring; see http://wiki.apache.org/cassandra/Operations
+# for more details.
+#
+# If blank, Cassandra will request a token bisecting the range of
+# the heaviest-loaded existing node.  If there is no load information
+# available, such as is the case with a new cluster, it will pick
+# a random token, which will lead to hot spots.
+#initial_token:
+
+# See http://wiki.apache.org/cassandra/HintedHandoff
+hinted_handoff_enabled: true
+# this defines the maximum amount of time a dead host will have hints
+# generated.  After it has been dead this long, new hints for it will not be
+# created until it has been seen alive and gone down again.
+max_hint_window_in_ms: 10800000 # 3 hours
+# Maximum throttle in KBs per second, per delivery thread.  This will be
+# reduced proportionally to the number of nodes in the cluster.  (If there
+# are two nodes in the cluster, each delivery thread will use the maximum
+# rate; if there are three, each will throttle to half of the maximum,
+# since we expect two nodes to be delivering hints simultaneously.)
+hinted_handoff_throttle_in_kb: 1024
+# Number of threads with which to deliver hints;
+# Consider increasing this number when you have multi-dc deployments, since
+# cross-dc handoff tends to be slower
+max_hints_delivery_threads: 2
+
+hints_directory: target/embeddedCassandra/hints
+
+# The following setting populates the page cache on memtable flush and compaction
+# WARNING: Enable this setting only when the whole node's data fits in memory.
+# Defaults to: false
+# populate_io_cache_on_flush: false
+
+# Authentication backend, implementing IAuthenticator; used to identify users
+# Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthenticator,
+# PasswordAuthenticator}.
+#
+# - AllowAllAuthenticator performs no checks - set it to disable authentication.
+# - PasswordAuthenticator relies on username/password pairs to authenticate
+#   users. It keeps usernames and hashed passwords in system_auth.credentials table.
+#   Please increase system_auth keyspace replication factor if you use this authenticator.
+authenticator: AllowAllAuthenticator
+
+# Authorization backend, implementing IAuthorizer; used to limit access/provide permissions
+# Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthorizer,
+# CassandraAuthorizer}.
+#
+# - AllowAllAuthorizer allows any action to any user - set it to disable authorization.
+# - CassandraAuthorizer stores permissions in system_auth.permissions table. Please
+#   increase system_auth keyspace replication factor if you use this authorizer.
+authorizer: AllowAllAuthorizer
+
+# Validity period for permissions cache (fetching permissions can be an
+# expensive operation depending on the authorizer, CassandraAuthorizer is
+# one example). Defaults to 2000, set to 0 to disable.
+# Will be disabled automatically for AllowAllAuthorizer.
+permissions_validity_in_ms: 2000
+
+
+# The partitioner is responsible for distributing rows (by key) across
+# nodes in the cluster.  Any IPartitioner may be used, including your
+# own as long as it is on the classpath.  Out of the box, Cassandra
+# provides org.apache.cassandra.dht.{Murmur3Partitioner, RandomPartitioner
+# ByteOrderedPartitioner, OrderPreservingPartitioner (deprecated)}.
+#
+# - RandomPartitioner distributes rows across the cluster evenly by md5.
+#   This is the default prior to 1.2 and is retained for compatibility.
+# - Murmur3Partitioner is similar to RandomPartioner but uses Murmur3_128
+#   Hash Function instead of md5.  When in doubt, this is the best option.
+# - ByteOrderedPartitioner orders rows lexically by key bytes.  BOP allows
+#   scanning rows in key order, but the ordering can generate hot spots
+#   for sequential insertion workloads.
+# - OrderPreservingPartitioner is an obsolete form of BOP, that stores
+# - keys in a less-efficient format and only works with keys that are
+#   UTF8-encoded Strings.
+# - CollatingOPP collates according to EN,US rules rather than lexical byte
+#   ordering.  Use this as an example if you need custom collation.
+#
+# See http://wiki.apache.org/cassandra/Operations for more on
+# partitioners and token selection.
+partitioner: org.apache.cassandra.dht.Murmur3Partitioner
+
+# directories where Cassandra should store data on disk.
+data_file_directories:
+    - target/embeddedCassandra/data
+
+# commit log
+commitlog_directory: target/embeddedCassandra/commitlog
+
+cdc_raw_directory: target/embeddedCassandra/cdc
+
+# policy for data disk failures:
+# stop: shut down gossip and Thrift, leaving the node effectively dead, but
+#       can still be inspected via JMX.
+# best_effort: stop using the failed disk and respond to requests based on
+#              remaining available sstables.  This means you WILL see obsolete
+#              data at CL.ONE!
+# ignore: ignore fatal errors and let requests fail, as in pre-1.2 Cassandra
+disk_failure_policy: stop
+
+
+# Maximum size of the key cache in memory.
+#
+# Each key cache hit saves 1 seek and each row cache hit saves 2 seeks at the
+# minimum, sometimes more. The key cache is fairly tiny for the amount of
+# time it saves, so it's worthwhile to use it at large numbers.
+# The row cache saves even more time, but must store the whole values of
+# its rows, so it is extremely space-intensive. It's best to only use the
+# row cache if you have hot rows or static rows.
+#
+# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup.
+#
+# Default value is empty to make it "auto" (min(5% of Heap (in MB), 100MB)). Set to 0 to disable key cache.
+key_cache_size_in_mb:
+
+# Duration in seconds after which Cassandra should
+# safe the keys cache. Caches are saved to saved_caches_directory as
+# specified in this configuration file.
+#
+# Saved caches greatly improve cold-start speeds, and is relatively cheap in
+# terms of I/O for the key cache. Row cache saving is much more expensive and
+# has limited use.
+#
+# Default is 14400 or 4 hours.
+key_cache_save_period: 14400
+
+# Number of keys from the key cache to save
+# Disabled by default, meaning all keys are going to be saved
+# key_cache_keys_to_save: 100
+
+# Maximum size of the row cache in memory.
+# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup.
+#
+# Default value is 0, to disable row caching.
+row_cache_size_in_mb: 0
+
+# Duration in seconds after which Cassandra should
+# safe the row cache. Caches are saved to saved_caches_directory as specified
+# in this configuration file.
+#
+# Saved caches greatly improve cold-start speeds, and is relatively cheap in
+# terms of I/O for the key cache. Row cache saving is much more expensive and
+# has limited use.
+#
+# Default is 0 to disable saving the row cache.
+row_cache_save_period: 0
+
+# Number of keys from the row cache to save
+# Disabled by default, meaning all keys are going to be saved
+# row_cache_keys_to_save: 100
+
+# saved caches
+saved_caches_directory: target/embeddedCassandra/saved_caches
+
+# commitlog_sync may be either "periodic" or "batch."
+# When in batch mode, Cassandra won't ack writes until the commit log
+# has been fsynced to disk.  It will wait up to
+# commitlog_sync_batch_window_in_ms milliseconds for other writes, before
+# performing the sync.
+#
+# commitlog_sync: batch
+# commitlog_sync_batch_window_in_ms: 50
+#
+# the other option is "periodic" where writes may be acked immediately
+# and the CommitLog is simply synced every commitlog_sync_period_in_ms
+# milliseconds.
+commitlog_sync: periodic
+commitlog_sync_period_in_ms: 10000
+
+# The size of the individual commitlog file segments.  A commitlog
+# segment may be archived, deleted, or recycled once all the data
+# in it (potentially from each columnfamily in the system) has been
+# flushed to sstables.
+#
+# The default size is 32, which is almost always fine, but if you are
+# archiving commitlog segments (see commitlog_archiving.properties),
+# then you probably want a finer granularity of archiving; 8 or 16 MB
+# is reasonable.
+commitlog_segment_size_in_mb: 32
+
+# any class that implements the SeedProvider interface and has a
+# constructor that takes a Map<String, String> of parameters will do.
+seed_provider:
+    # Addresses of hosts that are deemed contact points.
+    # Cassandra nodes use this list of hosts to find each other and learn
+    # the topology of the ring.  You must change this if you are running
+    # multiple nodes!
+    - class_name: org.apache.cassandra.locator.SimpleSeedProvider
+      parameters:
+          # seeds is actually a comma-delimited list of addresses.
+          # Ex: "<ip1>,<ip2>,<ip3>"
+          - seeds: "127.0.0.1"
+
+
+# For workloads with more data than can fit in memory, Cassandra's
+# bottleneck will be reads that need to fetch data from
+# disk. "concurrent_reads" should be set to (16 * number_of_drives) in
+# order to allow the operations to enqueue low enough in the stack
+# that the OS and drives can reorder them.
+#
+# On the other hand, since writes are almost never IO bound, the ideal
+# number of "concurrent_writes" is dependent on the number of cores in
+# your system; (8 * number_of_cores) is a good rule of thumb.
+concurrent_reads: 32
+concurrent_writes: 32
+
+# Total memory to use for memtables.  Cassandra will flush the largest
+# memtable when this much memory is used.
+# If omitted, Cassandra will set it to 1/3 of the heap.
+# memtable_total_space_in_mb: 2048
+
+# Total space to use for commitlogs.
+# If space gets above this value (it will round up to the next nearest
+# segment multiple), Cassandra will flush every dirty CF in the oldest
+# segment and remove it.
+# commitlog_total_space_in_mb: 4096
+
+# This sets the amount of memtable flush writer threads.  These will
+# be blocked by disk io, and each one will hold a memtable in memory
+# while blocked. If you have a large heap and many data directories,
+# you can increase this value for better flush performance.
+# By default this will be set to the amount of data directories defined.
+#memtable_flush_writers: 1
+
+# the number of full memtables to allow pending flush, that is,
+# waiting for a writer thread.  At a minimum, this should be set to
+# the maximum number of secondary indexes created on a single CF.
+#memtable_flush_queue_size: 4
+
+# Whether to, when doing sequential writing, fsync() at intervals in
+# order to force the operating system to flush the dirty
+# buffers. Enable this to avoid sudden dirty buffer flushing from
+# impacting read latencies. Almost always a good idea on SSD:s; not
+# necessarily on platters.
+trickle_fsync: false
+trickle_fsync_interval_in_kb: 10240
+
+# TCP port, for commands and data
+storage_port: 0
+
+# SSL port, for encrypted communication.  Unused unless enabled in
+# encryption_options
+ssl_storage_port: 7011
+
+# Address to bind to and tell other Cassandra nodes to connect to. You
+# _must_ change this if you want multiple nodes to be able to
+# communicate!
+#
+# Leaving it blank leaves it up to InetAddress.getLocalHost(). This
+# will always do the Right Thing *if* the node is properly configured
+# (hostname, name resolution, etc), and the Right Thing is to use the
+# address associated with the hostname (it might not be).
+#
+# Setting this to 0.0.0.0 is always wrong.
+listen_address: 127.0.0.1
+
+start_native_transport: true
+# port for the CQL native transport to listen for clients on
+native_transport_port: 9042
+
+# Whether to start the thrift rpc server.
+start_rpc: true
+
+# Address to broadcast to other Cassandra nodes
+# Leaving this blank will set it to the same value as listen_address
+# broadcast_address: 1.2.3.4
+
+# The address to bind the Thrift RPC service to -- clients connect
+# here. Unlike ListenAddress above, you *can* specify 0.0.0.0 here if
+# you want Thrift to listen on all interfaces.
+#
+# Leaving this blank has the same effect it does for ListenAddress,
+# (i.e. it will be based on the configured hostname of the node).
+rpc_address: localhost
+# port for Thrift to listen for clients on
+rpc_port: 0
+
+# enable or disable keepalive on rpc connections
+rpc_keepalive: true
+
+# Cassandra provides three options for the RPC Server:
+#
+# sync  -> One connection per thread in the rpc pool (see below).
+#          For a very large number of clients, memory will be your limiting
+#          factor; on a 64 bit JVM, 128KB is the minimum stack size per thread.
+#          Connection pooling is very, very strongly recommended.
+#
+# async -> Nonblocking server implementation with one thread to serve
+#          rpc connections.  This is not recommended for high throughput use
+#          cases. Async has been tested to be about 50% slower than sync
+#          or hsha and is deprecated: it will be removed in the next major release.
+#
+# hsha  -> Stands for "half synchronous, half asynchronous." The rpc thread pool
+#          (see below) is used to manage requests, but the threads are multiplexed
+#          across the different clients.
+#
+# The default is sync because on Windows hsha is about 30% slower.  On Linux,
+# sync/hsha performance is about the same, with hsha of course using less memory.
+rpc_server_type: sync
+
+# Uncomment rpc_min|max|thread to set request pool size.
+# You would primarily set max for the sync server to safeguard against
+# misbehaved clients; if you do hit the max, Cassandra will block until one
+# disconnects before accepting more.  The defaults for sync are min of 16 and max
+# unlimited.
+#
+# For the Hsha server, the min and max both default to quadruple the number of
+# CPU cores.
+#
+# This configuration is ignored by the async server.
+#
+# rpc_min_threads: 16
+# rpc_max_threads: 2048
+
+# uncomment to set socket buffer sizes on rpc connections
+# rpc_send_buff_size_in_bytes:
+# rpc_recv_buff_size_in_bytes:
+
+# Frame size for thrift (maximum field length).
+# 0 disables TFramedTransport in favor of TSocket. This option
+# is deprecated; we strongly recommend using Framed mode.
+thrift_framed_transport_size_in_mb: 15
+
+# The max length of a thrift message, including all fields and
+# internal thrift overhead.
+thrift_max_message_length_in_mb: 16
+
+# Set to true to have Cassandra create a hard link to each sstable
+# flushed or streamed locally in a backups/ subdirectory of the
+# Keyspace data.  Removing these links is the operator's
+# responsibility.
+incremental_backups: false
+
+# Whether or not to take a snapshot before each compaction.  Be
+# careful using this option, since Cassandra won't clean up the
+# snapshots for you.  Mostly useful if you're paranoid when there
+# is a data format change.
+snapshot_before_compaction: false
+
+# Whether or not a snapshot is taken of the data before keyspace truncation
+# or dropping of column families. The STRONGLY advised default of true
+# should be used to provide data safety. If you set this flag to false, you will
+# lose data on truncation or drop.
+auto_snapshot: false
+
+# Add column indexes to a row after its contents reach this size.
+# Increase if your column values are large, or if you have a very large
+# number of columns.  The competing causes are, Cassandra has to
+# deserialize this much of the row to read a single column, so you want
+# it to be small - at least if you do many partial-row reads - but all
+# the index data is read for each access, so you don't want to generate
+# that wastefully either.
+column_index_size_in_kb: 64
+
+# Size limit for rows being compacted in memory.  Larger rows will spill
+# over to disk and use a slower two-pass compaction process.  A message
+# will be logged specifying the row key.
+#in_memory_compaction_limit_in_mb: 64
+
+# Number of simultaneous compactions to allow, NOT including
+# validation "compactions" for anti-entropy repair.  Simultaneous
+# compactions can help preserve read performance in a mixed read/write
+# workload, by mitigating the tendency of small sstables to accumulate
+# during a single long running compactions. The default is usually
+# fine and if you experience problems with compaction running too
+# slowly or too fast, you should look at
+# compaction_throughput_mb_per_sec first.
+#
+# This setting has no effect on LeveledCompactionStrategy.
+#
+# concurrent_compactors defaults to the number of cores.
+# Uncomment to make compaction mono-threaded, the pre-0.8 default.
+#concurrent_compactors: 1
+
+# Multi-threaded compaction. When enabled, each compaction will use
+# up to one thread per core, plus one thread per sstable being merged.
+# This is usually only useful for SSD-based hardware: otherwise,
+# your concern is usually to get compaction to do LESS i/o (see:
+# compaction_throughput_mb_per_sec), not more.
+#multithreaded_compaction: false
+
+# Throttles compaction to the given total throughput across the entire
+# system. The faster you insert data, the faster you need to compact in
+# order to keep the sstable count down, but in general, setting this to
+# 16 to 32 times the rate you are inserting data is more than sufficient.
+# Setting this to 0 disables throttling. Note that this account for all types
+# of compaction, including validation compaction.
+compaction_throughput_mb_per_sec: 16
+
+# Track cached row keys during compaction, and re-cache their new
+# positions in the compacted sstable.  Disable if you use really large
+# key caches.
+#compaction_preheat_key_cache: true
+
+# Throttles all outbound streaming file transfers on this node to the
+# given total throughput in Mbps. This is necessary because Cassandra does
+# mostly sequential IO when streaming data during bootstrap or repair, which
+# can lead to saturating the network connection and degrading rpc performance.
+# When unset, the default is 200 Mbps or 25 MB/s.
+# stream_throughput_outbound_megabits_per_sec: 200
+
+# How long the coordinator should wait for read operations to complete
+read_request_timeout_in_ms: 5000
+# How long the coordinator should wait for seq or index scans to complete
+range_request_timeout_in_ms: 10000
+# How long the coordinator should wait for writes to complete
+write_request_timeout_in_ms: 2000
+# How long a coordinator should continue to retry a CAS operation
+# that contends with other proposals for the same row
+cas_contention_timeout_in_ms: 1000
+# How long the coordinator should wait for truncates to complete
+# (This can be much longer, because unless auto_snapshot is disabled
+# we need to flush first so we can snapshot before removing the data.)
+truncate_request_timeout_in_ms: 60000
+# The default timeout for other, miscellaneous operations
+request_timeout_in_ms: 10000
+
+# Enable operation timeout information exchange between nodes to accurately
+# measure request timeouts.  If disabled, replicas will assume that requests
+# were forwarded to them instantly by the coordinator, which means that
+# under overload conditions we will waste that much extra time processing
+# already-timed-out requests.
+#
+# Warning: before enabling this property make sure to ntp is installed
+# and the times are synchronized between the nodes.
+cross_node_timeout: false
+
+# Enable socket timeout for streaming operation.
+# When a timeout occurs during streaming, streaming is retried from the start
+# of the current file. This _can_ involve re-streaming an important amount of
+# data, so you should avoid setting the value too low.
+# Default value is 0, which never timeout streams.
+# streaming_socket_timeout_in_ms: 0
+
+# phi value that must be reached for a host to be marked down.
+# most users should never need to adjust this.
+# phi_convict_threshold: 8
+
+# endpoint_snitch -- Set this to a class that implements
+# IEndpointSnitch.  The snitch has two functions:
+# - it teaches Cassandra enough about your network topology to route
+#   requests efficiently
+# - it allows Cassandra to spread replicas around your cluster to avoid
+#   correlated failures. It does this by grouping machines into
+#   "datacenters" and "racks."  Cassandra will do its best not to have
+#   more than one replica on the same "rack" (which may not actually
+#   be a physical location)
+#
+# IF YOU CHANGE THE SNITCH AFTER DATA IS INSERTED INTO THE CLUSTER,
+# YOU MUST RUN A FULL REPAIR, SINCE THE SNITCH AFFECTS WHERE REPLICAS
+# ARE PLACED.
+#
+# Out of the box, Cassandra provides
+#  - SimpleSnitch:
+#    Treats Strategy order as proximity. This improves cache locality
+#    when disabling read repair, which can further improve throughput.
+#    Only appropriate for single-datacenter deployments.
+#  - PropertyFileSnitch:
+#    Proximity is determined by rack and data center, which are
+#    explicitly configured in cassandra-topology.properties.
+#  - RackInferringSnitch:
+#    Proximity is determined by rack and data center, which are
+#    assumed to correspond to the 3rd and 2nd octet of each node's
+#    IP address, respectively.  Unless this happens to match your
+#    deployment conventions (as it did Facebook's), this is best used
+#    as an example of writing a custom Snitch class.
+#  - Ec2Snitch:
+#    Appropriate for EC2 deployments in a single Region.  Loads Region
+#    and Availability Zone information from the EC2 API. The Region is
+#    treated as the Datacenter, and the Availability Zone as the rack.
+#    Only private IPs are used, so this will not work across multiple
+#    Regions.
+#  - Ec2MultiRegionSnitch:
+#    Uses public IPs as broadcast_address to allow cross-region
+#    connectivity.  (Thus, you should set seed addresses to the public
+#    IP as well.) You will need to open the storage_port or
+#    ssl_storage_port on the public IP firewall.  (For intra-Region
+#    traffic, Cassandra will switch to the private IP after
+#    establishing a connection.)
+#
+# You can use a custom Snitch by setting this to the full class name
+# of the snitch, which will be assumed to be on your classpath.
+endpoint_snitch: SimpleSnitch
+
+# controls how often to perform the more expensive part of host score
+# calculation
+dynamic_snitch_update_interval_in_ms: 100
+# controls how often to reset all host scores, allowing a bad host to
+# possibly recover
+dynamic_snitch_reset_interval_in_ms: 600000
+# if set greater than zero and read_repair_chance is < 1.0, this will allow
+# 'pinning' of replicas to hosts in order to increase cache capacity.
+# The badness threshold will control how much worse the pinned host has to be
+# before the dynamic snitch will prefer other replicas over it.  This is
+# expressed as a double which represents a percentage.  Thus, a value of
+# 0.2 means Cassandra would continue to prefer the static snitch values
+# until the pinned host was 20% worse than the fastest.
+dynamic_snitch_badness_threshold: 0.1
+
+# request_scheduler -- Set this to a class that implements
+# RequestScheduler, which will schedule incoming client requests
+# according to the specific policy. This is useful for multi-tenancy
+# with a single Cassandra cluster.
+# NOTE: This is specifically for requests from the client and does
+# not affect inter node communication.
+# org.apache.cassandra.scheduler.NoScheduler - No scheduling takes place
+# org.apache.cassandra.scheduler.RoundRobinScheduler - Round robin of
+# client requests to a node with a separate queue for each
+# request_scheduler_id. The scheduler is further customized by
+# request_scheduler_options as described below.
+request_scheduler: org.apache.cassandra.scheduler.NoScheduler
+
+# Scheduler Options vary based on the type of scheduler
+# NoScheduler - Has no options
+# RoundRobin
+#  - throttle_limit -- The throttle_limit is the number of in-flight
+#                      requests per client.  Requests beyond
+#                      that limit are queued up until
+#                      running requests can complete.
+#                      The value of 80 here is twice the number of
+#                      concurrent_reads + concurrent_writes.
+#  - default_weight -- default_weight is optional and allows for
+#                      overriding the default which is 1.
+#  - weights -- Weights are optional and will default to 1 or the
+#               overridden default_weight. The weight translates into how
+#               many requests are handled during each turn of the
+#               RoundRobin, based on the scheduler id.
+#
+# request_scheduler_options:
+#    throttle_limit: 80
+#    default_weight: 5
+#    weights:
+#      Keyspace1: 1
+#      Keyspace2: 5
+
+# request_scheduler_id -- An identifer based on which to perform
+# the request scheduling. Currently the only valid option is keyspace.
+# request_scheduler_id: keyspace
+
+# index_interval controls the sampling of entries from the primrary
+# row index in terms of space versus time.  The larger the interval,
+# the smaller and less effective the sampling will be.  In technicial
+# terms, the interval coresponds to the number of index entries that
+# are skipped between taking each sample.  All the sampled entries
+# must fit in memory.  Generally, a value between 128 and 512 here
+# coupled with a large key cache size on CFs results in the best trade
+# offs.  This value is not often changed, however if you have many
+# very small rows (many to an OS page), then increasing this will
+# often lower memory usage without a impact on performance.
+index_interval: 128
+
+# Enable or disable inter-node encryption
+# Default settings are TLS v1, RSA 1024-bit keys (it is imperative that
+# users generate their own keys) TLS_RSA_WITH_AES_128_CBC_SHA as the cipher
+# suite for authentication, key exchange and encryption of the actual data transfers.
+# NOTE: No custom encryption options are enabled at the moment
+# The available internode options are : all, none, dc, rack
+#
+# If set to dc cassandra will encrypt the traffic between the DCs
+# If set to rack cassandra will encrypt the traffic between the racks
+#
+# The passwords used in these options must match the passwords used when generating
+# the keystore and truststore.  For instructions on generating these files, see:
+# http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore
+#
+encryption_options:
+    internode_encryption: none
+    keystore: conf/.keystore
+    keystore_password: cassandra
+    truststore: conf/.truststore
+    truststore_password: cassandra
+    # More advanced defaults below:
+    # protocol: TLS
+    # algorithm: SunX509
+    # store_type: JKS
+    # cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA]
\ No newline at end of file
diff --git a/validate-api/validate-hierarchy-manager/src/test/resources/logback.xml b/validate-api/validate-hierarchy-manager/src/test/resources/logback.xml
new file mode 100644
index 000000000..73529d622
--- /dev/null
+++ b/validate-api/validate-hierarchy-manager/src/test/resources/logback.xml
@@ -0,0 +1,28 @@
+<configuration>
+
+	<conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
+
+	<!-- transaction-event-trigger START -->
+	<timestamp key="timestamp" datePattern="yyyy-MM-dd"/>
+	<!-- common transactions logs -->
+	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>%d %msg%n</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
+		<appender-ref ref="STDOUT" />
+	</appender>
+
+
+	<logger name="play" level="INFO" />
+	<logger name="DefaultPlatformLogger" level="INFO" />
+	<!-- Telemetry Loggers-->
+	<logger name="TelemetryEventLogger" level="INFO" />
+
+	<root level="INFO">
+		<appender-ref ref="ASYNCSTDOUT" />
+	</root>
+
+</configuration>
\ No newline at end of file
diff --git a/validate-api/validate-hierarchy-manager/src/test/scala/org/sunbird/managers/BaseSpec.scala b/validate-api/validate-hierarchy-manager/src/test/scala/org/sunbird/managers/BaseSpec.scala
new file mode 100644
index 000000000..01bad4b13
--- /dev/null
+++ b/validate-api/validate-hierarchy-manager/src/test/scala/org/sunbird/managers/BaseSpec.scala
@@ -0,0 +1,101 @@
+package org.sunbird.managers
+
+import java.io.{File, IOException}
+
+import com.datastax.driver.core.{ResultSet, Session}
+import org.apache.commons.io.FileUtils
+import org.cassandraunit.utils.EmbeddedCassandraServerHelper
+import org.neo4j.graphdb.GraphDatabaseService
+import org.neo4j.graphdb.factory.GraphDatabaseFactory
+import org.neo4j.graphdb.factory.GraphDatabaseSettings.Connector.ConnectorType
+import org.neo4j.kernel.configuration.BoltConnector
+import org.scalatest.{AsyncFlatSpec, BeforeAndAfterAll, BeforeAndAfterEach, Matchers}
+import org.sunbird.cassandra.CassandraConnector
+import org.sunbird.common.Platform
+
+class BaseSpec extends AsyncFlatSpec with Matchers with BeforeAndAfterAll with BeforeAndAfterEach{
+
+    var graphDb: GraphDatabaseService = null
+    var session: Session = null
+
+    def setUpEmbeddedNeo4j(): Unit = {
+        if(null == graphDb) {
+            val bolt: BoltConnector = new BoltConnector("0")
+            graphDb = new GraphDatabaseFactory()
+                            .newEmbeddedDatabaseBuilder(new File(Platform.config.getString("graph.dir")))
+                            .setConfig(bolt.`type`, ConnectorType.BOLT.name())
+                    .setConfig(bolt.enabled, "true").setConfig(bolt.listen_address, "localhost:7687").newGraphDatabase
+            registerShutdownHook(graphDb)
+        }
+    }
+
+    private def registerShutdownHook(graphDb: GraphDatabaseService): Unit = {
+        Runtime.getRuntime.addShutdownHook(new Thread() {
+            override def run(): Unit = {
+                try {
+                    tearEmbeddedNeo4JSetup
+                } catch {
+                    case e: Exception =>
+                        e.printStackTrace()
+                }
+            }
+        })
+    }
+
+
+    @throws[Exception]
+    private def tearEmbeddedNeo4JSetup(): Unit = {
+        if (null != graphDb) graphDb.shutdown
+        Thread.sleep(2000)
+        deleteEmbeddedNeo4j(new File(Platform.config.getString("graph.dir")))
+    }
+
+    private def deleteEmbeddedNeo4j(emDb: File): Unit = {
+        try{
+            FileUtils.deleteDirectory(emDb)
+        }catch{
+            case e: Exception =>
+                e.printStackTrace()
+        }
+    }
+
+
+    def setUpEmbeddedCassandra(): Unit = {
+        System.setProperty("cassandra.unsafesystem", "true")
+        EmbeddedCassandraServerHelper.startEmbeddedCassandra("/cassandra-unit.yaml", 100000L)
+    }
+
+    override def beforeAll(): Unit = {
+        tearEmbeddedNeo4JSetup()
+        setUpEmbeddedNeo4j()
+        setUpEmbeddedCassandra()
+    }
+
+    override def afterAll(): Unit = {
+        tearEmbeddedNeo4JSetup()
+        if(null != session && !session.isClosed)
+            session.close()
+        EmbeddedCassandraServerHelper.cleanEmbeddedCassandra()
+    }
+
+
+    def executeCassandraQuery(queries: String*): Unit = {
+        if(null == session || session.isClosed){
+            session = CassandraConnector.getSession
+        }
+        for(query <- queries) {
+            session.execute(query)
+        }
+    }
+
+    def readFromCassandra(query: String) : ResultSet = {
+        if(null == session || session.isClosed){
+            session = CassandraConnector.getSession
+        }
+        session.execute(query)
+    }
+
+    def createRelationData(): Unit = {
+        graphDb.execute("UNWIND [{identifier:\"Num:C3:SC2\",code:\"Num:C3:SC2\",keywords:[\"Subconcept\",\"Class 3\"],IL_SYS_NODE_TYPE:\"DATA_NODE\",subject:\"numeracy\",channel:\"in.ekstep\",description:\"Multiplication\",versionKey:\"1484389136575\",gradeLevel:[\"Grade 3\",\"Grade 4\"],IL_FUNC_OBJECT_TYPE:\"Concept\",name:\"Multiplication\",lastUpdatedOn:\"2016-06-15T17:15:45.951+0000\",IL_UNIQUE_ID:\"Num:C3:SC2\",status:\"Live\"}, {code:\"31d521da-61de-4220-9277-21ca7ce8335c\",previewUrl:\"https://ekstep-public-dev.s3-ap-south-1.amazonaws.com/assets/do_11232724509261824014/object-oriented-javascript.pdf\",downloadUrl:\"https://ekstep-public-dev.s3-ap-south-1.amazonaws.com/ecar_files/do_11232724509261824014/untitled-content_1504790847410_do_11232724509261824014_2.0.ecar\",channel:\"in.ekstep\",language:[\"English\"],variants:\"{\\\"spine\\\":{\\\"ecarUrl\\\":\\\"https://ekstep-public-dev.s3-ap-south-1.amazonaws.com/ecar_files/do_11232724509261824014/untitled-content_1504790848197_do_11232724509261824014_2.0_spine.ecar\\\",\\\"size\\\":890.0}}\",mimeType:\"application/pdf\",streamingUrl:\"https://ekstep-public-dev.s3-ap-south-1.amazonaws.com/assets/do_11232724509261824014/object-oriented-javascript.pdf\",idealScreenSize:\"normal\",createdOn:\"2017-09-07T13:24:20.720+0000\",contentDisposition:\"inline\",artifactUrl:\"https://ekstep-public-dev.s3-ap-south-1.amazonaws.com/assets/do_11232724509261824014/object-oriented-javascript.pdf\",contentEncoding:\"identity\",lastUpdatedOn:\"2017-09-07T13:25:53.595+0000\",SYS_INTERNAL_LAST_UPDATED_ON:\"2017-09-07T13:27:28.417+0000\",contentType:\"Resource\",lastUpdatedBy:\"Ekstep\",audience:[\"Student\"],visibility:\"Default\",os:[\"All\"],IL_SYS_NODE_TYPE:\"DATA_NODE\",consumerId:\"e84015d2-a541-4c07-a53f-e31d4553312b\",mediaType:\"content\",osId:\"org.ekstep.quiz.app\",lastPublishedBy:\"Ekstep\",pkgVersion:2,versionKey:\"1504790848417\",license:\"Creative Commons Attribution (CC BY)\",idealScreenDensity:\"hdpi\",s3Key:\"ecar_files/do_11232724509261824014/untitled-content_1504790847410_do_11232724509261824014_2.0.ecar\",size:4864851,lastPublishedOn:\"2017-09-07T13:27:27.410+0000\",createdBy:\"390\",compatibilityLevel:4,IL_FUNC_OBJECT_TYPE:\"Content\",name:\"Untitled Content\",publisher:\"EkStep\",IL_UNIQUE_ID:\"do_11232724509261824014\",status:\"Live\",resourceType:[\"Study material\"]}] as row CREATE (n:domain) SET n += row")
+    }
+}
diff --git a/validate-api/validate-service/app/controllers/BaseController.scala b/validate-api/validate-service/app/controllers/BaseController.scala
new file mode 100644
index 000000000..a3b47974b
--- /dev/null
+++ b/validate-api/validate-service/app/controllers/BaseController.scala
@@ -0,0 +1,73 @@
+package controllers
+
+import java.util.UUID
+
+import akka.actor.ActorRef
+import akka.pattern.Patterns
+import org.sunbird.common.DateUtils
+import org.sunbird.common.dto.{Response, ResponseHandler}
+import org.sunbird.common.exception.ResponseCode
+import play.api.mvc._
+import utils.JavaJsonUtils
+
+import collection.JavaConverters._
+import scala.concurrent.{ExecutionContext, Future}
+
+abstract class BaseController(protected val cc: ControllerComponents)(implicit exec: ExecutionContext) extends AbstractController(cc) {
+
+    def requestBody()(implicit request: Request[AnyContent]) = {
+        val body = request.body.asJson.getOrElse("{}").toString
+        JavaJsonUtils.deserialize[java.util.Map[String, Object]](body).getOrDefault("request", new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]]
+    }
+
+    def commonHeaders()(implicit request: Request[AnyContent]): java.util.Map[String, Object] = {
+        val customHeaders = Map("x-channel-id" -> "channel", "X-Consumer-ID" -> "consumerId", "X-App-Id" -> "appId")
+        customHeaders.map(ch => {
+            val value = request.headers.get(ch._1)
+            if (value.isDefined && !value.isEmpty) {
+                collection.mutable.HashMap[String, Object](ch._2 -> value.get).asJava
+            } else {
+                collection.mutable.HashMap[String, Object]().asJava
+            }
+        }).reduce((a, b) => {
+            a.putAll(b)
+            return a
+        })
+    }
+
+    def getRequest(input: java.util.Map[String, AnyRef], context: java.util.Map[String, AnyRef], operation: String): org.sunbird.common.dto.Request = {
+        new org.sunbird.common.dto.Request(context, input, operation, null);
+    }
+
+    def getResult(apiId: String, actor: ActorRef, request: org.sunbird.common.dto.Request) : Future[Result] = {
+        val future = Patterns.ask(actor, request, 30000) recoverWith {case e: Exception => Future(ResponseHandler.getErrorResponse(e))}
+        future.map(f => {
+            val result = f.asInstanceOf[Response]
+            result.setId(apiId)
+            setResponseEnvelope(result)
+            val response = JavaJsonUtils.serialize(result);
+            result.getResponseCode match {
+                case ResponseCode.OK => Ok(response).as("application/json")
+                case ResponseCode.CLIENT_ERROR => BadRequest(response).as("application/json")
+                case ResponseCode.RESOURCE_NOT_FOUND => NotFound(response).as("application/json")
+                case _ => play.api.mvc.Results.InternalServerError(response).as("application/json")
+            }
+        })
+    }
+
+    def setResponseEnvelope(response: Response) = {
+        response.setTs(DateUtils.formatCurrentDate("yyyy-MM-dd'T'HH:mm:ss'Z'XXX"))
+        response.getParams.setResmsgid(UUID.randomUUID().toString)
+    }
+
+    def setRequestContext(request:org.sunbird.common.dto.Request, version: String, objectType: String, schemaName: String): Unit = {
+        var contextMap: java.util.Map[String, AnyRef] = new java.util.HashMap[String, AnyRef](){{
+            put("graph_id", "domain")
+            put("version" , version)
+            put("objectType" , objectType)
+            put("schemaName", schemaName)
+        }};
+        request.setObjectType(objectType);
+        request.setContext(contextMap)
+    }
+}
diff --git a/validate-api/validate-service/app/controllers/HealthController.scala b/validate-api/validate-service/app/controllers/HealthController.scala
new file mode 100644
index 000000000..d278b7681
--- /dev/null
+++ b/validate-api/validate-service/app/controllers/HealthController.scala
@@ -0,0 +1,31 @@
+package controllers
+
+import akka.actor.{ActorRef, ActorSystem}
+import handlers.SignalHandler
+import javax.inject._
+import org.sunbird.common.JsonUtils
+import org.sunbird.common.dto.ResponseHandler
+import play.api.mvc._
+import utils.{ActorNames, ApiId}
+
+import scala.concurrent.{ExecutionContext, Future}
+
+class HealthController @Inject()(@Named(ActorNames.HEALTH_ACTOR) healthActor: ActorRef, cc: ControllerComponents, actorSystem: ActorSystem, signalHandler: SignalHandler)(implicit exec: ExecutionContext) extends BaseController(cc) {
+
+    def health() = Action.async { implicit request =>
+        if (signalHandler.isShuttingDown) {
+            Future { ServiceUnavailable }
+        } else {
+            getResult(ApiId.APPLICATION_HEALTH, healthActor, new org.sunbird.common.dto.Request())
+        }
+    }
+
+    def serviceHealth() = Action.async { implicit request =>
+        if (signalHandler.isShuttingDown)
+            Future { ServiceUnavailable }
+        else {
+            val response = ResponseHandler.OK().setId(ApiId.APPLICATION_SERVICE_HEALTH).put("healthy", true)
+            Future { Ok(JsonUtils.serialize(response)).as("application/json") }
+        }
+    }
+}
diff --git a/validate-api/validate-service/app/controllers/QuestionValidateController.java b/validate-api/validate-service/app/controllers/QuestionValidateController.java
new file mode 100644
index 000000000..c892eed16
--- /dev/null
+++ b/validate-api/validate-service/app/controllers/QuestionValidateController.java
@@ -0,0 +1,37 @@
+/** */
+package controllers;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import play.mvc.Controller;
+import play.mvc.Http;
+import play.mvc.Result;
+import play.mvc.Results;
+import utils.Attrs;
+
+/**
+ * This controller will handler all the request related to learner state.
+ *
+ * @author Manzarul
+ */
+public class QuestionValidateController extends Controller {
+
+
+
+  /**
+   * This method will update learner current state with last store state.
+   *
+   * @return Result
+   */
+  public Result assessment(Http.Request httpRequest) {
+    JsonNode requestData = httpRequest.body().asJson();
+    String loggingHeaders =  httpRequest.attrs().getOptional(Attrs.X_LOGGING_HEADERS).orElse(null);
+    String requestedBy = httpRequest.attrs().getOptional(Attrs.USER_ID).orElse(null);
+    String requestedFor = httpRequest.attrs().getOptional(Attrs.REQUESTED_FOR).orElse(null);
+    String apiDebugLog = "UpdateContentState Request: " + requestData.toString() + " RequestedBy: " + requestedBy + " RequestedFor: " + requestedFor + " ";
+
+    return Results.ok();
+  }
+
+
+}
diff --git a/validate-api/validate-service/app/filters/AccessLogFilter.scala b/validate-api/validate-service/app/filters/AccessLogFilter.scala
new file mode 100644
index 000000000..aad9f8419
--- /dev/null
+++ b/validate-api/validate-service/app/filters/AccessLogFilter.scala
@@ -0,0 +1,45 @@
+package filters
+
+import akka.util.ByteString
+import javax.inject.Inject
+import org.sunbird.telemetry.util.TelemetryAccessEventUtil
+import play.api.Logging
+import play.api.libs.streams.Accumulator
+import play.api.mvc._
+
+import scala.concurrent.ExecutionContext
+import scala.collection.JavaConverters._
+
+class AccessLogFilter @Inject() (implicit ec: ExecutionContext) extends EssentialFilter with Logging {
+
+    val xHeaderNames = Map("x-session-id" -> "X-Session-ID", "X-Consumer-ID" -> "x-consumer-id", "x-device-id" -> "X-Device-ID", "x-app-id" -> "APP_ID", "x-authenticated-userid" -> "X-Authenticated-Userid", "x-channel-id" -> "X-Channel-Id")
+
+    def apply(nextFilter: EssentialAction) = new EssentialAction {
+      def apply(requestHeader: RequestHeader) = {
+
+        val startTime = System.currentTimeMillis
+
+        val accumulator: Accumulator[ByteString, Result] = nextFilter(requestHeader)
+
+        accumulator.map { result =>
+          val endTime     = System.currentTimeMillis
+          val requestTime = endTime - startTime
+
+          val path = requestHeader.uri
+          if(!path.contains("/health")){
+            val headers = requestHeader.headers.headers.groupBy(_._1).mapValues(_.map(_._2))
+            val appHeaders = headers.filter(header => xHeaderNames.keySet.contains(header._1.toLowerCase))
+                .map(entry => (xHeaderNames.get(entry._1.toLowerCase()).get, entry._2.head))
+            val otherDetails = Map[String, Any]("StartTime" -> startTime, "env" -> "assessment",
+                "RemoteAddress" -> requestHeader.remoteAddress,
+                "ContentLength" -> result.body.contentLength.getOrElse(0),
+                "Status" -> result.header.status, "Protocol" -> "http",
+                "path" -> path,
+                "Method" -> requestHeader.method.toString)
+            TelemetryAccessEventUtil.writeTelemetryEventLog((otherDetails ++ appHeaders).asInstanceOf[Map[String, AnyRef]].asJava)
+          }
+          result.withHeaders("Request-Time" -> requestTime.toString)
+        }
+      }
+    }
+  }
\ No newline at end of file
diff --git a/validate-api/validate-service/app/handlers/SignalHandler.scala b/validate-api/validate-service/app/handlers/SignalHandler.scala
new file mode 100644
index 000000000..4cad301c1
--- /dev/null
+++ b/validate-api/validate-service/app/handlers/SignalHandler.scala
@@ -0,0 +1,33 @@
+package handlers
+
+import java.util.concurrent.TimeUnit
+
+import akka.actor.ActorSystem
+import javax.inject.{Inject, Singleton}
+import org.slf4j.LoggerFactory
+import play.api.inject.DefaultApplicationLifecycle
+import sun.misc.Signal
+
+import scala.concurrent.duration.Duration
+
+@Singleton
+class SignalHandler @Inject()(implicit actorSystem: ActorSystem, lifecycle: DefaultApplicationLifecycle) {
+    val LOG = LoggerFactory.getLogger(classOf[SignalHandler])
+    val STOP_DELAY = Duration.create(30, TimeUnit.SECONDS)
+    var isShuttingDown = false
+
+    println("Initializing SignalHandler...")
+    Signal.handle(new Signal("TERM"), new sun.misc.SignalHandler() {
+        override def handle(signal: Signal): Unit = {
+            // $COVERAGE-OFF$ Disabling scoverage as this code is impossible to test
+            isShuttingDown = true
+            println("Termination required, swallowing SIGTERM to allow current requests to finish. : " + System.currentTimeMillis())
+            actorSystem.scheduler.scheduleOnce(STOP_DELAY)(() => {
+                println("ApplicationLifecycle stop triggered... : " + System.currentTimeMillis())
+                lifecycle.stop()
+            })(actorSystem.dispatcher)
+            // $COVERAGE-ON
+        }
+    })
+}
+
diff --git a/validate-api/validate-service/app/modules/AssessmentModule.scala b/validate-api/validate-service/app/modules/AssessmentModule.scala
new file mode 100644
index 000000000..067d502e9
--- /dev/null
+++ b/validate-api/validate-service/app/modules/AssessmentModule.scala
@@ -0,0 +1,16 @@
+package modules
+
+import com.google.inject.AbstractModule
+import org.sunbird.actors.{HealthActor, ItemSetActor, QuestionActor, QuestionSetActor}
+import play.libs.akka.AkkaGuiceSupport
+import utils.ActorNames
+
+class AssessmentModule extends AbstractModule with AkkaGuiceSupport {
+
+    override def configure() = {
+//        super.configure()
+        bindActor(classOf[HealthActor], ActorNames.HEALTH_ACTOR)
+
+        println("Initialized application actors for assessment-service")
+    }
+}
diff --git a/validate-api/validate-service/app/utils/ActorNames.scala b/validate-api/validate-service/app/utils/ActorNames.scala
new file mode 100644
index 000000000..3420a3cc5
--- /dev/null
+++ b/validate-api/validate-service/app/utils/ActorNames.scala
@@ -0,0 +1,7 @@
+package utils
+
+object ActorNames {
+
+    final val HEALTH_ACTOR = "healthActor"
+
+}
diff --git a/validate-api/validate-service/app/utils/ApiId.scala b/validate-api/validate-service/app/utils/ApiId.scala
new file mode 100644
index 000000000..70aa790dc
--- /dev/null
+++ b/validate-api/validate-service/app/utils/ApiId.scala
@@ -0,0 +1,9 @@
+package utils
+
+object ApiId {
+
+	final val APPLICATION_HEALTH = "api.assessment.health"
+	final val APPLICATION_SERVICE_HEALTH = "api.assessment.service.health"
+
+
+}
diff --git a/validate-api/validate-service/app/utils/Attrs.java b/validate-api/validate-service/app/utils/Attrs.java
new file mode 100644
index 000000000..956a9e0a8
--- /dev/null
+++ b/validate-api/validate-service/app/utils/Attrs.java
@@ -0,0 +1,21 @@
+package utils;
+
+import play.libs.typedmap.TypedKey;
+
+public class Attrs {
+    public static final TypedKey<String> USER_ID = TypedKey.<String>create(JsonKey.USER_ID);
+    public static final TypedKey<String> AUTH_WITH_MASTER_KEY = TypedKey.<String>create(JsonKey.AUTH_WITH_MASTER_KEY);
+    public static final TypedKey<String> REQUEST_ID = TypedKey.<String>create(JsonKey.REQUEST_ID);
+    public static final TypedKey<String> CONTEXT = TypedKey.<String>create(JsonKey.CONTEXT);
+    public static final TypedKey<String> REQUESTED_FOR = TypedKey.<String>create(JsonKey.REQUESTED_FOR);
+    public static final TypedKey<String> IS_AUTH_REQ = TypedKey.<String>create(JsonKey.IS_AUTH_REQ);
+    public static final TypedKey<String> SIGNUP_TYPE = TypedKey.<String>create(JsonKey.SIGNUP_TYPE);
+    public static final TypedKey<String> REQUEST_SOURCE = TypedKey.<String>create(JsonKey.REQUEST_SOURCE);
+    public static final TypedKey<String> CHANNEL = TypedKey.<String>create(JsonKey.CHANNEL);
+    public static final TypedKey<String> APP_ID = TypedKey.<String>create(JsonKey.APP_ID);
+    public static final TypedKey<String> DEVICE_ID = TypedKey.<String>create(JsonKey.DEVICE_ID);
+    public static final TypedKey<String> ACTOR_ID = TypedKey.<String>create(JsonKey.ACTOR_ID);
+    public static final TypedKey<String> ACTOR_TYPE = TypedKey.<String>create(JsonKey.ACTOR_TYPE);
+    public static final TypedKey<String> X_AUTH_TOKEN = TypedKey.<String>create(JsonKey.X_AUTH_TOKEN);
+    public static final TypedKey<String> X_LOGGING_HEADERS = TypedKey.<String>create(JsonKey.X_LOGGING_HEADERS);
+}
diff --git a/validate-api/validate-service/app/utils/JavaJsonUtils.scala b/validate-api/validate-service/app/utils/JavaJsonUtils.scala
new file mode 100644
index 000000000..2093c2e33
--- /dev/null
+++ b/validate-api/validate-service/app/utils/JavaJsonUtils.scala
@@ -0,0 +1,38 @@
+package utils
+
+import java.lang.reflect.{ParameterizedType, Type}
+
+import com.fasterxml.jackson.core.`type`.TypeReference
+import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMapper}
+
+object JavaJsonUtils {
+
+    @transient val mapper = new ObjectMapper();
+    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+//    mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
+//    mapper.setSerializationInclusion(Include.NON_NULL);
+
+    @throws(classOf[Exception])
+    def serialize(obj: AnyRef): String = {
+        mapper.writeValueAsString(obj);
+    }
+
+    @throws(classOf[Exception])
+    def deserialize[T: Manifest](value: String): T = mapper.readValue(value, typeReference[T]);
+
+    private[this] def typeReference[T: Manifest] = new TypeReference[T] {
+        override def getType = typeFromManifest(manifest[T])
+    }
+
+
+    private[this] def typeFromManifest(m: Manifest[_]): Type = {
+        if (m.typeArguments.isEmpty) { m.runtimeClass }
+        // $COVERAGE-OFF$Disabling scoverage as this code is impossible to test
+        else new ParameterizedType {
+            def getRawType = m.runtimeClass
+            def getActualTypeArguments = m.typeArguments.map(typeFromManifest).toArray
+            def getOwnerType = null
+        }
+        // $COVERAGE-ON$
+    }
+}
diff --git a/validate-api/validate-service/app/utils/JsonKey.java b/validate-api/validate-service/app/utils/JsonKey.java
new file mode 100644
index 000000000..1c190f25b
--- /dev/null
+++ b/validate-api/validate-service/app/utils/JsonKey.java
@@ -0,0 +1,1020 @@
+package utils;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This class will contains all the key related to request and response.
+ *
+ * @author Manzarul
+ */
+public final class JsonKey {
+  public static final String ANONYMOUS = "Anonymous";
+  public static final String UNAUTHORIZED = "Unauthorized";
+  public static final String MW_SYSTEM_HOST = "sunbird_mw_system_host";
+  public static final String MW_SYSTEM_PORT = "sunbird_mw_system_port";
+  public static final String MW_SYSTEM_CLIENT_PORT = "sunbird_mw_system_client_port";
+  public static final String ACCESS_TOKEN = "access_token";
+  public static final String ACCESSTOKEN = "accessToken";
+  public static final String ACCOUNT_KEY = "sunbird_account_key";
+  public static final String ACCOUNT_NAME = "sunbird_account_name";
+  public static final String DOWNLOAD_LINK_EXPIRY_TIMEOUT = "download_link_expiry_timeout";
+  public static final String SIGNED_URL = "signedUrl";
+  public static final String REPORTS = "reports";
+  public static final String PROGRESS_REPORT_SIGNED_URL = "courseProgressReportUrl";
+  public static final String ASSESSMENT_REPORT_BLOB_URL = "reportUrl";
+  public static final String ASSESSMENT_REPORT_SIGNED_URL = "assessmentReportUrl";
+  public static final String BULK_UPLOAD_STATUS = "Status";
+  public static final String BULK_UPLOAD_ERROR = "Remarks";
+  public static final String ACTION_GROUP = "action_group";
+  public static final String ACTION_GROUPS = "actionGroups";
+  public static final String ACTION_NAME = "actionName";
+  public static final String ACTION_URL = "actionUrl";
+  public static final String ACTIONS = "actions";
+  public static final String ACTIVE = "active";
+  public static final String ACTOR_ID = "actorId";
+  public static final String ACTOR_SERVICE = "Actor service";
+  public static final String ACTOR_TYPE = "actorType";
+  public static final String ADD_TYPE = "addType";
+  public static final String ADDED_AT = "addedAt";
+  public static final String ADDED_BY = "addedBy";
+  public static final String ADDED_BY_NAME = "addedByName";
+  public static final String ADDITIONAL_INFO = "ADDITIONAL_INFO";
+  public static final String ADDRESS = "address";
+  public static final String ADDRESS_DB = "address";
+  public static final String ADDRESS_ID = "addressId";
+  public static final String ADDRESS_LINE1 = "addressLine1";
+  public static final String ADDRESS_LINE2 = "addressLine2";
+  public static final String ADDRESS_TYPE = "address type";
+  public static final String AGGREGATIONS = "aggregations";
+  public static final String ALL = "all";
+  public static final String ALLOWED_LOGIN = "allowedLogin";
+  public static final String ANNOUNCEMENT = "announcement";
+  public static final String API_ACCESS = "api_access";
+  public static final String API_ACTOR_PROVIDER = "api_actor_provider";
+  public static final String API_CALL = "API_CALL";
+  public static final String API_ID = "apiId";
+  public static final String APP_ICON = "appIcon";
+  public static final String APP_MAP = "appMap";
+  public static final String APP_SECTIONS = "appSections";
+  public static final String APP_URL = "appUrl";
+  public static final String APPICON = "appIcon";
+  public static final String APPLICABLE_FOR = "applicableFor";
+  public static final String APPROOVE_DATE = "approvalDate";
+  public static final String APPROVED_BY = "approvedBy";
+  public static final String APPROVED_BY_NAME = "approvedByName";
+  public static final String APPROVED_DATE = "approvedDate";
+  public static final String ASSESSMENT = "assessment";
+  public static final String ASSESSMENT_EVENTS = "assessments";
+  public static final String ASSESSMENT_TS = "assessmentTs";
+  public static final String ASSESSMENT_ANSWERS = "answers";
+  public static final String ASSESSMENT_ATTEMPT_DATE = "attemptedDate";
+  public static final String ASSESSMENT_EVAL_DB = "assessment_eval_db";
+  public static final String ASSESSMENT_GRADE = "grade";
+  public static final String ASSESSMENT_ITEM_DB = "assessment_item_db";
+  public static final String ASSESSMENT_ITEM_ID = "assessmentItemId";
+  public static final String ASSESSMENT_MAX_SCORE = "maxScore";
+  public static final String ASSESSMENT_SCORE = "score";
+  public static final String ASSESSMENT_STATUS = "assessmentStatus";
+  public static final String ASSESSMENT_TYPE = "assessmentType";
+  public static final String ATTEMPT_ID = "attemptId";
+  public static final String ASSESSMENT_EVENTS_KEY = "events";
+  public static final String ASSESSMENT_ACTOR = "actor";
+  public static final String ATTEMPTED_COUNT = "attemptedCount";
+  public static final String AUTH_TOKEN = "authToken";
+  public static final String AUTH_USER_HEADER = "X-Authenticated-Userid";
+  public static final String AUTH_WITH_MASTER_KEY = "authWithMasterKey";
+  public static final String AUTHORIZATION = "Authorization";
+  public static final String BACKGROUND_ACTOR_PROVIDER = "background_actor_provider";
+  public static final String BAD_REQUEST = "badRequest";
+  public static final String BATCH = "batch";
+  public static final String BATCH_ID = "batchId";
+  public static final String BEARER = "Bearer ";
+  public static final String BLOCKED = "blocked";
+  public static final String BODY = "body";
+  public static final String BULK_OP_DB = "BulkOpDb";
+  public static final String BULK_UPLOAD_BATCH_DATA_SIZE = "bulk_upload_batch_data_size";
+  public static final String BULK_USER_UPLOAD = "bulkUserUpload";
+  public static final String CASSANDRA_IN_EMBEDDED_MODE = "cassandraInEmbeddedMode";
+  public static final String CASSANDRA_SERVICE = "Cassandra service";
+  public static final String CATEGORIES = "categories";
+  public static final String CHANNEL = "channel";
+  public static final String CHANNEL_REG_STATUS = "channelRegStatus";
+  public static final String CHANNEL_REG_STATUS_ID = "003";
+  public static final String CHANNELS = "channels";
+  public static final String CHECKS = "checks";
+  public static final String CHILD_OF = "childOf";
+  public static final String CHILDREN = "children";
+  public static final String CITY = "city";
+  public static final String CLASS = "class";
+  public static final String CLIENT_ID = "clientId";
+  public static final String CLIENT_INFO_DB = "clientInfo_db";
+  public static final String CLIENT_NAME = "clientName";
+  public static final String CLIENT_NAMES = "client.names";
+  public static final String CODE = "code";
+  public static final String COMPLETED_COUNT = "completedCount";
+  public static final String COMPLETENESS = "completeness";
+  public static final String CONSUMER = "consumer";
+  public static final String CONTACT_DETAILS = "contactDetail";
+  public static final String CONTAINER = "container";
+  public static final String CONTENT = "content";
+  public static final String CONTENT_CREATOR = "CONTENT_CREATOR";
+  public static final String CONTENT_ID = "contentId";
+  public static final String CONTENT_IDS = "contentIds";
+  public static final String CONTENT_LIST = "contentList";
+  public static final String CONTENT_NAME = "contentName";
+  public static final String CONTENT_PROGRESS = "progress";
+  public static final String CONTENT_TYPE = "contentType";
+  public static final String CONTENT_VERSION = "contentVersion";
+  public static final String CONTENTS = "contents";
+  public static final String CONTEXT = "context";
+  public static final String CORRELATED_OBJECTS = "correlatedObjects";
+  public static final String COUNT = "count";
+  public static final String COUNT_DECREMENT_DATE = "countDecrementDate";
+  public static final String COUNT_INCREMENT_DATE = "countIncrementDate";
+  public static final String COUNTER_DECREMENT_STATUS = "countDecrementStatus";
+  public static final String COUNTER_INCREMENT_STATUS = "countIncrementStatus";
+  public static final String COUNTRY = "country";
+  public static final String COUNTRY_CODE = "countryCode";
+  public static final String COURSE = "course";
+  public static final String COURSE_ADDITIONAL_INFO = "courseAdditionalInfo";
+  public static final String COURSE_BATCH_DB = "courseBatchDB";
+  public static final String COURSE_CREATED_FOR = "createdFor";
+  public static final String COURSE_CREATOR = "courseCreator";
+  public static final String COURSE_DURATION = "courseDuration";
+  public static final String COURSE_ENROLL_DATE = "enrolledDate";
+  public static final String COURSE_ID = "courseId";
+  public static final String COURSE_IDS = "courseIds";
+  public static final String COURSE_LIST = "courseList";
+  public static final String COURSE_LOGO_URL = "courseLogoUrl";
+  public static final String COURSE_MANAGEMENT_DB = "courseManagement_db";
+  public static final String COURSE_NAME = "courseName";
+  public static final String COURSE_PROGRESS = "progress";
+  public static final String COURSE_PUBLISHED_STATUS = "course_publish_status";
+  public static final String COURSE_VERSION = "courseVersion";
+  public static final String CourseConsumption = "courseConsumption";
+  public static final String CourseProgress = "courseProgress";
+  public static final String COURSES = "courses";
+  public static final String CREATE = "create";
+  public static final String CREATED_BY = "createdBy";
+  public static final String CREATED_DATE = "createdDate";
+  public static final String CRITERIA = "criteria";
+  public static final String CURRENT_LOGIN_TIME = "currentLoginTime";
+  public static final String CURRENT_STATE = "CURRENT_STATE";
+  public static final String DASHBOARD = "dashboard";
+  public static final String DATA = "data";
+  public static final String KEY = "key";
+  public static final String KEYS = "keys";
+  public static final String DATE = "date";
+  public static final String DATE_HISTOGRAM = "DATE_HISTOGRAM";
+  public static final String DATE_TIME = "dateTime";
+  public static final String DB_IP = "db.ip";
+  public static final String DB_KEYSPACE = "db.keyspace";
+  public static final String DB_PASSWORD = "db.password";
+  public static final String DB_PORT = "db.port";
+  public static final String DB_USERNAME = "db.username";
+  public static final String DEFAULT_ACTION_NAME = "Download Reports";
+  public static final String DEFAULT_CONSUMER_ID = "internal";
+  public static final String DEFAULT_ROOT_ORG_ID = "ORG_001";
+  public static final String DEGREE = "degree";
+  public static final String DELETE = "delete";
+  public static final String DELTA = "delta";
+  public static final String DESCRIPTION = "description";
+  public static final String DOB = "dob";
+  public static final String DOWNLOAD_URL = "downloadUrl";
+  public static final String DUPLICATE = "duplicate";
+  public static final String EDUCATION = "education";
+  public static final String EDUCATION_DB = "user_education";
+  public static final String EKS = "eks";
+  public static final String SEARCH_SERVICE_API_BASE_URL = "sunbird_search_service_api_base_url";
+  public static final String ANALYTICS_API_BASE_URL = "sunbird_analytics_api_base_url";
+  public static final String EKSTEP_AUTHORIZATION = "ekstep_authorization";
+  public static final String EKSTEP_BASE_URL = "ekstep_api_base_url";
+  public static final String EKSTEP_CONTENT_SEARCH_BASE_URL = "ekstep_content_search_base_url";
+  public static final String EKSTEP_CONTENT_SEARCH_URL = "ekstep_content_search_url";
+  public static final String EKSTEP_CONTENT_UPDATE_URL = "ekstep.content.update.url";
+  public static final String EKSTEP_SERVICE = "EkStep service";
+  public static final String EKSTEP_TAG_API_URL = "ekstep.tag.api.url";
+  public static final String EMAIL = "email";
+  public static final String EMAIL_REQUEST = "emailReq";
+  public static final String EMAIL_SERVER_FROM = "sunbird_mail_server_from_email";
+  public static final String EMAIL_SERVER_HOST = "sunbird_mail_server_host";
+  public static final String EMAIL_SERVER_PASSWORD = "sunbird_mail_server_password";
+  public static final String EMAIL_SERVER_PORT = "sunbird_mail_server_port";
+  public static final String EMAIL_SERVER_USERNAME = "sunbird_mail_server_username";
+  public static final String EMAIL_TEMPLATE_TYPE = "emailTemplateType";
+  public static final String EMAIL_UNIQUE = "emailUnique";
+  public static final String EMAIL_VERIFIED = "emailVerified";
+  public static final String EMAIL_VERIFIED_UPDATED = "emailVerifiedUpdated";
+  public static final String EMBEDDED = "embedded";
+  public static final String EMBEDDED_MODE = "embedded";
+  public static final String ENC_EMAIL = "encEmail";
+  public static final String ENC_PHONE = "encPhone";
+  public static final String ENCRYPTION_KEY = "sunbird_encryption_key";
+  public static final String END_DATE = "endDate";
+  public static final String END_TIME = "endTime";
+  public static final String ENDORSE_DATE = "endorseDate";
+  public static final String ENDORSED_USER_ID = "endorsedUserId";
+  public static final String ENDORSEMENT_COUNT = "endorsementCount";
+  public static final String ENDORSERS = "endorsers";
+  public static final String ENDORSERS_LIST = "endorsersList";
+  public static final String ENROLLMENT_END_DATE = "enrollmentEndDate";
+  public static final String ENROLLMENT_START_DATE = "enrollementStartDate";
+  public static final String ENROLLMENT_TYPE = "enrollmentType";
+  public static final String ENROLMENTTYPE = "enrolmentType";
+  public static final String ENV = "env";
+  public static final String ERR_TYPE = "errtype";
+  public static final String ERROR = "err";
+  public static final String ERROR_MSG = "err_msg";
+  public static final String ERRORMSG = "errmsg";
+  public static final String ES_METRICS_PORT = "es_metrics_port";
+  public static final String ES_SERVICE = "Elastic search service";
+  public static final String ES_URL = "es_search_url";
+  public static final String ESTIMATED_COUNT_REQ = "estimatedCountReq";
+  public static final String EVENTS = "events";
+  public static final String EXISTS = "exists";
+  public static final String EXTERNAL_ID = "externalId";
+  public static final String EXTERNAL_ID_VALUE = "externalIdValue";
+  public static final String FACETS = "facets";
+  public static final String FAILED = "FAILED";
+  public static final String FAILURE = "failure";
+  public static final String FAILURE_RESULT = "failureResult";
+  public static final String FCM = "fcm";
+  public static final String FCM_URL = "fcm.url";
+  public static final String FIELD = "field";
+  public static final String FIELDS = "fields";
+  public static final String FILE = "file";
+  public static final String FILE_NAME = "fileName";
+  public static final String FILE_PARAMS = "fileParams";
+  public static final String FILE_URL = "fileUrl";
+  public static final String FILTER = "filter";
+  public static final String FILTERS = "filters";
+  public static final String FIRST_NAME = "firstName";
+  public static final String FORM_PARAMS = "formParams";
+  public static final String FORMAT = "format";
+  public static final String FRAMEWORK = "framework";
+  public static final String FROM_EMAIL = "fromEmail";
+  public static final String GENDER = "gender";
+  public static final String GEO_LOCATION_DB = "geoLocationDb";
+  public static final String GRADE = "grade";
+  public static final String GRADE_LEVEL = "gradeLevel";
+  public static final String GROUP = "group";
+  public static final String GROUPID = "groupId";
+  public static final String GROUP_QUERY = "groupQuery";
+  public static final String HASH_TAG_ID = "hashtagid";
+  public static final String HASHTAGID = "hashTagId";
+  public static final String HEADER = "header";
+  public static final String Healthy = "healthy";
+  public static final String HOME_URL = "homeUrl";
+  public static final String ID = "id";
+  public static final String IDENTIFIER = "identifier";
+  public static final String IMAGE = "image";
+  public static final String INACTIVE = "inactive";
+  public static final String INDEX = "index";
+  public static final String INFO = "info";
+  public static final String INSERT = "insert";
+  public static final String INVITE_ONLY = "invite-only";
+  public static final String IS_APPROVED = "isApproved";
+  public static final String IS_AUTH_REQ = "isAuthReq";
+  public static final String IS_DEFAULT = "isDefault";
+  public static final String IS_DELETED = "isDeleted";
+  public static final String IS_REJECTED = "isRejected";
+  public static final String IS_ROOT_ORG = "isRootOrg";
+  public static final String IS_SSO_ENABLED = "sso.enabled";
+  public static final String IS_VERIFIED = "isVerified";
+  public static final String JOB_NAME = "jobName";
+  public static final String JOB_PROFILE = "jobProfile";
+  public static final String JOB_PROFILE_DB = "user_job_profile";
+  public static final String JOINING_DATE = "joiningDate";
+  public static final String LANGUAGE = "language";
+  public static final String LAST_ACCESS_TIME = "lastAccessTime";
+  public static final String LAST_COMPLETED_TIME = "lastCompletedTime";
+  public static final String LAST_LOGIN_TIME = "lastLoginTime";
+  public static final String LAST_LOGOUT_TIME = "lastLogoutTime";
+  public static final String LAST_NAME = "lastName";
+  public static final String LAST_READ_CONTENT_STATUS = "lastReadContentStatus";
+  public static final String LAST_READ_CONTENT_VERSION = "lastReadContentVersion";
+  public static final String LAST_READ_CONTENTID = "lastReadContentId";
+  public static final String LAST_UPDATED_TIME = "lastUpdatedTime";
+  public static final String LEAF_NODE_COUNT = "leafNodesCount";
+  public static final String LEARNER_CONTENT_DB = "learnerContent_db";
+  public static final String LEARNER_COURSE_DB = "learnerCourse_db";
+  public static final String LEARNER_SERVICE = "Learner service";
+  public static final String LEVEL = "level";
+  public static final String LIMIT = "limit";
+  public static final String LIST = "List";
+  public static final String LOC_ID = "locationId";
+  public static final String LOCATION = "location";
+  public static final String LOCATION_NAME = "locationName";
+  public static final String LOCATION_ID = "locationId";
+  public static final String LOCATION_IDS = "locationIds";
+  public static final String LOCATIONS = "locations";
+  public static final String LOG_LEVEL = "logLevel";
+  public static final String LOG_RECORD = "logRecord";
+  public static final String LOG_TYPE = "logType";
+  public static final String LOGIN_GENERAL = "general";
+  public static final String LOGIN_ID = "loginId";
+  public static final String LOGIN_ID_DELIMETER = "@";
+  public static final String LOGIN_TYPE = "type";
+  public static final String MAIL_NOTE = "mail_note";
+  public static final String MANDATORY_FIELDS = "mandatoryFields";
+  public static final String MAP = "map";
+  public static final String MAPPED_FORM_PARAMS = "mappedFormParams";
+  public static final String MASKED_EMAIL = "maskedEmail";
+  public static final String MASKED_PHONE = "maskedPhone";
+  public static final String MASTER_ACTION = "master_action";
+  public static final String MASTER_KEY = "masterKey";
+  public static final String MEDIA_TYPE_DB = "mediaTypeDB";
+  public static final String MENTORS = "mentors";
+  public static final String MESSAGE = "message";
+  public static final String MESSAGE_Id = "message_id";
+  public static final String MESSAGE_ID = "X-msgId";
+  public static final String METHOD = "method";
+  public static final String METHOD_NAME = "methodName";
+  public static final String METRICS = "metrics";
+  public static final String MISSING_FIELDS = "missingFields";
+  public static final String MOBILE = "mobile";
+  public static final String NAME = "name";
+  public static final String NEW_PASSWORD = "newPassword";
+  public static final String NO_OF_LECTURES = "noOfLectures";
+  public static final String NO_OF_MEMBERS = "noOfMembers";
+  public static final String NOT_AVAILABLE = "NA";
+  public static final String NOT_EXISTS = "not_exists";
+  public static final String NOTE = "note";
+  public static final String NOTE_ID = "noteId";
+  public static final String NOTIFICATION = "notification";
+  public static final String NULL = "null";
+  public static final String OBJECT_ID = "objectId";
+  public static final String OBJECT_IDS = "objectIds";
+  public static final String OBJECT_TYPE = "objectType";
+  public static final String OFFSET = "offset";
+  public static final String ON = "ON";
+  public static final String ONBOARDING_WELCOME_MAIL_BODY = "onboarding_welcome_mail_body";
+  public static final String OPEN = "open";
+  public static final String OPERATION = "operation";
+  public static final String OPERATION_FOR = "operationFor";
+  public static final String OPERATION_TYPE = "operationType";
+  public static final String ORDER = "order";
+  public static final String ORG_CODE = "orgCode";
+  public static final String ORG_CODE_HEADER = "X-Org-code";
+  public static final String ORG_EXT_ID_DB = "org_external_identity";
+  public static final String ORG_DB = "org_db";
+  public static final String ORG_ID = "orgId";
+  public static final String ORG_ID_ONE = "orgIdOne";
+  public static final String ORG_ID_TWO = "orgIdTwo";
+  public static final String ORG_IMAGE_URL = "orgImageUrl";
+  public static final String ORG_JOIN_DATE = "orgJoinDate";
+  public static final String ORG_LEFT_DATE = "orgLeftDate";
+  public static final String ORG_MAP_DB = "org_mapping";
+  public static final String ORG_NAME = "orgName";
+  public static final String ORG_SERVER_FROM_NAME = "orgServerFromName";
+  public static final String ORG_TYPE = "orgType";
+  public static final String ORG_TYPE_DB = "org_type";
+  public static final String ORG_TYPE_ID = "orgTypeId";
+  public static final String ORGANISATION = "organisation";
+  public static final String ORGANISATION_ID = "organisationId";
+  public static final String ORGANISATION_NAME = "orgName";
+  public static final String ORGANISATIONS = "organisations";
+  public static final String OrgConsumption = "orgConsumption";
+  public static final String OrgCreation = "orgCreation";
+  public static final String OTP = "otp";
+  public static final String OTP_EMAIL_RESET_PASSWORD_TEMPLATE = "otpEmailResetPasswordTemplate";
+  public static final String OTP_PHONE_RESET_PASSWORD_TEMPLATE = "otpPhoneResetPasswordTemplate";
+  public static final String VERIFY_PHONE_OTP_TEMPLATE = "verifyPhoneOtpTemplate";
+  public static final String PAGE = "page";
+  public static final String PAGE_ID = "pageId";
+  public static final String PAGE_MGMT_DB = "page_mgmt_db";
+  public static final String PAGE_NAME = "name";
+  public static final String PAGE_SECTION = "page_section";
+  public static final String PAGE_SECTION_DB = "page_section_db";
+  public static final String PARAMS = "params";
+  public static final String PARENT_OF = "parentOf";
+  public static final String PARENT_ORG_ID = "parentOrgId";
+  public static final String PARTICIPANT = "participant";
+  public static final String PARTICIPANTS = "participants";
+  public static final String PASSWORD = "password";
+  public static final String PDATA = "pdata";
+
+  public static final String PERCENTAGE = "percentage";
+  public static final String PERIOD = "period";
+  public static final String PHONE = "phone";
+  public static final String PHONE_NUMBER_VERIFIED = "phoneNumberVerified";
+  public static final String PHONE_UNIQUE = "phoneUnique";
+  public static final String PHONE_VERIFIED = "phoneVerified";
+  public static final String PORTAL_MAP = "portalMap";
+  public static final String PORTAL_SECTIONS = "portalSections";
+  public static final String POSITION = "position";
+  public static final String PREFERRED_LANGUAGE = "preferredLanguage";
+  public static final String PREV_STATE = "PREV_STATE";
+  public static final String PRIMARY_KEY_DELIMETER = "##";
+  public static final String PRIVATE = "private";
+  public static final String PROCESS_END_TIME = "processEndTime";
+  public static final String PROCESS_ID = "processId";
+  public static final String PROCESS_START_TIME = "processStartTime";
+  public static final String PROCESSING_STATUS = "processingStatus";
+  public static final String PDATA_ID = "telemetry_pdata_id";
+  public static final String PDATA_PID = "telemetry_pdata_pid";
+  public static final String PDATA_VERSION = "telemetry_pdata_ver";
+  public static final String PROFILE_SUMMARY = "profileSummary";
+  public static final String PROFILE_VISIBILITY = "profileVisibility";
+  public static final String PROGRESS = "progress";
+  public static final String PROPERTIES = "properties";
+  public static final String PROPS = "props";
+  public static final String PROVIDER = "provider";
+  public static final String PUBLIC = "public";
+  public static final String PUBLISH_COURSE = "publishCourse";
+  public static final String QUERY = "query";
+  public static final String QUERY_FIELDS = "queryFields";
+  public static final String RECEIVER_ID = "receiverId";
+  public static final String RECIPIENT_COUNT = "recipientCount";
+  public static final String RECIPIENT_EMAILS = "recipientEmails";
+  public static final String RECIPIENT_USERIDS = "recipientUserIds";
+  public static final String RECOMMEND_TYPE = "recommendType";
+  public static final String REGISTERED_ORG = "registeredOrg";
+  public static final String REGISTERED_ORG_ID = "regOrgId";
+  public static final String RELATION = "relation";
+  public static final String RELATIONS = "relations";
+  public static final String REMOTE = "remote";
+  public static final String REPLACE_WITH_ASTERISK = "*";
+  public static final String REPLACE_WITH_X = "X";
+  public static final String REPORT_TRACKING_DB = "reportTrackingDb";
+  public static final String REQ_ID = "reqId";
+  public static final String REQUEST = "request";
+  public static final String REQUEST_ID = "requestId";
+  public static final String REQUEST_MESSAGE_ID = "msgId";
+  public static final String REQUEST_TYPE = "requestType";
+  public static final String REQUESTED_BY = "requestedBy";
+  public static final String RES_MSG_ID = "resmsgId";
+  public static final String RESOURCE_ID = "resourceId";
+  public static final String RESPONSE = "response";
+  public static final String RESULT = "result";
+  public static final String RETIRED = "retired";
+  public static final String RETRY_COUNT = "retryCount";
+  public static final String ROLE = "role";
+  public static final String ROLE_GROUP = "role_group";
+  public static final String ROLE_GROUP_ID = "rolegroupid";
+  public static final String ROLES = "roles";
+  public static final String ROLLUP = "rollup";
+  public static final String ROOT_ORG = "rootOrg";
+  public static final String ROOT_ORG_ID = "rootOrgId";
+  public static final String SCHEDULER_JOB = "scheduler";
+  public static final String SEARCH = "search";
+  public static final String SEARCH_QUERY = "searchQuery";
+  public static final String SEARCH_TOP_N = "searchTopN";
+  public static final String SECTION = "section";
+  public static final String SECTION_DATA_TYPE = "sectionDataType";
+  public static final String SECTION_DISPLAY = "display";
+  public static final String SECTION_ID = "sectionId";
+  public static final String SECTION_MGMT_DB = "section_mgmt_db";
+  public static final String SECTION_NAME = "name";
+  public static final String SECTIONS = "sections";
+  public static final String SERIES = "series";
+  public static final String SIZE = "size";
+  public static final String SKILL_ENDORSEMENT_DB = "skillEndorsementDb";
+  public static final String SKILL_NAME = "skillName";
+  public static final String SKILL_NAME_TO_LOWERCASE = "skillnametolowercase";
+  public static final String SKILLS = "skills";
+  public static final String SKILLS_LIST_DB = "skillsListDb";
+  public static final String SLUG = "slug";
+  public static final String SNAPSHOT = "snapshot";
+  public static final String SORT = "sort";
+  public static final String SORT_BY = "sort_by";
+  public static final String SOURCE = "source";
+  public static final String SOURCE_HEADER = "X-Source";
+  public static final String SPLIT = "split";
+  public static final String SSO_CLIENT_ID = "sso.client.id";
+  public static final String SSO_CLIENT_SECRET = "sso.client.secret";
+  public static final String SSO_PASSWORD = "sso.password";
+  public static final String SSO_POOL_SIZE = "sso.connection.pool.size";
+  public static final String SSO_PUBLIC_KEY = "sunbird_sso_publickey";
+  public static final String SSO_REALM = "sso.realm";
+  public static final String SSO_URL = "sso.url";
+  public static final String SSO_USERNAME = "sso.username";
+  public static final String STACKTRACE = "stacktrace";
+  public static final String STANDALONE_MODE = "standalone";
+  public static final String START_DATE = "startDate";
+  public static final String START_TIME = "startTime";
+  public static final String STATE = "state";
+  public static final String STATUS = "status";
+  public static final String STATUS_CODE = "statusCode";
+  public static final String SUB_SECTIONS = "subSections";
+  public static final String SUBJECT = "subject";
+  public static final String SUBMIT_DATE = "submitDate";
+  public static final String SUBTYPE = "subtype";
+  public static final String SUCCESS = "SUCCESS";
+  public static final String SUCCESS_RESULT = "successResult";
+  public static final String SUMMARY = "summary";
+  public static final String SUNBIRD = "sunbird";
+  public static final String SUNBIRD_ALLOWED_LOGIN = "sunbird_allowed_login";
+  public static final String SUNBIRD_API_BASE_URL = "sunbird_api_base_url";
+  public static final String SUNBIRD_CASSANDRA_IP = "sunbird_cassandra_host";
+  public static final String SUNBIRD_CASSANDRA_KEYSPACE = "sunbird_cassandra_keyspace";
+  public static final String SUNBIRD_CASSANDRA_MODE = "sunbird_cassandra_mode";
+  public static final String SUNBIRD_CASSANDRA_PASSWORD = "sunbird_cassandra_password";
+  public static final String SUNBIRD_CASSANDRA_PORT = "sunbird_cassandra_port";
+  public static final String SUNBIRD_CASSANDRA_USER_NAME = "sunbird_cassandra_username";
+  public static final String SUNBIRD_ENCRYPTION = "sunbird_encryption";
+  public static final String SUNBIRD_ENV_LOGO_URL = "sunbird_env_logo_url";
+  public static final String SUNBIRD_ES_CHANNEL = "es.channel.name";
+  public static final String SUNBIRD_ES_CLUSTER = "sunbird_es_cluster";
+  public static final String SUNBIRD_ES_IP = "sunbird_es_host";
+  public static final String SUNBIRD_ES_PORT = "sunbird_es_port";
+  public static final String SUNBIRD_FCM_ACCOUNT_KEY = "sunbird_fcm_account_key";
+  public static final String SUNBIRD_INSTALLATION = "sunbird_installation";
+  public static final String SUNBIRD_NETTY_HOST = "sunbird_netty_host";
+  public static final String SUNBIRD_NETTY_PORT = "sunbird_netty_port";
+  public static final String SUNBIRD_PG_DB = "sunbird_pg_db";
+  public static final String SUNBIRD_PG_HOST = "sunbird_pg_host";
+  public static final String SUNBIRD_PG_PASSWORD = "sunbird_pg_password";
+  public static final String SUNBIRD_PG_PORT = "sunbird_pg_port";
+  public static final String SUNBIRD_PG_USER = "sunbird_pg_user";
+  public static final String SUNBIRD_PLUGIN = "sunbirdplugin";
+  public static final String SUNBIRD_QUARTZ_MODE = "sunbird_quartz_mode";
+  public static final String SUNBIRD_SSO_CLIENT_ID = "sunbird_sso_client_id";
+  public static final String SUNBIRD_SSO_CLIENT_SECRET = "sunbird_sso_client_secret";
+  public static final String SUNBIRD_SSO_PASSWORD = "sunbird_sso_password";
+  public static final String SUNBIRD_SSO_RELAM = "sunbird_sso_realm";
+  public static final String SUNBIRD_SSO_URL = "sunbird_sso_url";
+  public static final String SUNBIRD_SSO_USERNAME = "sunbird_sso_username";
+  public static final String SUNBIRD_WEB_URL = "sunbird_web_url";
+  public static final String SUNBIRD_GET_ORGANISATION_API = "sunbird_search_organisation_api";
+  public static final String SUNBIRD_GET_SINGLE_USER_API = "sunbird_read_user_api";
+  public static final String SUNBIRD_GET_MULTIPLE_USER_API = "sunbird_search_user_api";
+  public static final String SUNBIRD_CONTENT_GET_HIERARCHY_API = "sunbird_get_hierarchy_api";
+  public static final String SUNBIRD_CONTENT_READ_API = "sunbird_content_read_api";
+  public static final String SYSTEM = "system";
+  public static final String SYSTEM_SETTINGS_DB = "system_settings";
+  public static final String TAG = "tag";
+  public static final String TAGS = "tags";
+  public static final String TARGET_OBJECT = "targetObject";
+  public static final String TC_UPDATED_DATE = "tcUpdatedAt";
+  public static final String TELEMETRY_CONTEXT = "TELEMETRY_CONTEXT";
+  public static final String TELEMETRY_EVENT_TYPE = "telemetryEventType";
+  public static final String TEMPORARY_PASSWORD = "tempPassword";
+  public static final String TENANT_PREFERENCE = "tenantPreference";
+  public static final String TENANT_PREFERENCE_DB = "tenantPreferenceDb";
+  public static final String TERM_AND_CONDITION_STATUS = "tcStatus";
+  public static final String TERMS = "terms";
+  public static final String THEME = "theme";
+  public static final String THUMBNAIL = "thumbnail";
+  public static final String TIME_TAKEN = "timeTaken";
+  public static final String TIME_UNIT = "time_unit";
+  public static final String TITLE = "title";
+  public static final String TO = "to";
+  public static final String TOC_URL = "tocUrl";
+  public static final String TOKEN = "token";
+  public static final String TOPIC = "topic";
+  public static final String TOPIC_NAME = "topicName";
+  public static final String TOPICS = "topics";
+  public static final String TOPN = "topn";
+  public static final String TRY_COUNT = "tryCount";
+  public static final String TYPE = "type";
+  public static final String UNDEFINED_IDENTIFIER = "Undefined column name ";
+  public static final String UNIQUE = "unique";
+  public static final String UNKNOWN_IDENTIFIER = "Unknown identifier ";
+  public static final String UPDATE = "update";
+  public static final String UPDATED_BY = "updatedBy";
+  public static final String UPDATED_BY_NAME = "updatedByName";
+  public static final String UPDATED_DATE = "updatedDate";
+  public static final String UPLOADED_BY = "uploadedBy";
+  public static final String UPLOADED_DATE = "uploadedDate";
+  public static final String URL = "url";
+  public static final String URL_ACTION = "url_action";
+  public static final String URL_ACTION_ID = "url_action_ids";
+  public static final String URLS = "urls";
+  public static final String USER = "user";
+  public static final String USER_ACTION_ROLE = "user_action_role";
+  public static final String USER_AUTH_DB = "userAuth_db";
+  public static final String USER_COUNT = "userCount";
+  public static final String USER_COUNT_TTL = "userCountTTL";
+  public static final String USER_COURSE = "user_course";
+  public static final String USER_COURSES = "userCourses";
+  public static final String USER_DB = "user_db";
+  public static final String USER_FOUND = "user exist with this login Id.";
+  public static final String USER_ID = "userId";
+  public static final String USER_IDs = "userIds";
+  public static final String USER_LIST = "userList";
+  public static final String USER_LIST_REQ = "userListReq";
+  public static final String USER_NAME = "username";
+  public static final String USER_NOT_FOUND = "user does not exist with this login Id.";
+  public static final String USER_NOTES_DB = "userNotes_db";
+  public static final String USER_ORG = "user_org";
+  public static final String USER_ORG_DB = "user_org_db";
+  public static final String USER_SKILL_DB = "userSkillDb";
+  public static final String USERIDS = "userIds";
+  public static final String USERNAME = "userName";
+  public static final String USR_EXT_ID_DB = "user_external_identity";
+  public static final String USR_ORG_DB = "user_org";
+  public static final String VALUE = "value";
+  public static final String VER = "ver";
+  public static final String VERSION = "version";
+  public static final String VIEW_COUNT = "viewCount";
+  public static final String VIEW_POSITION = "viewPosition";
+  public static final String WEB_PAGES = "webPages";
+  public static final String WEB_URL = "webUrl";
+  public static final String WELCOME_MESSAGE = "welcomeMessage";
+  public static final String YEAR_OF_PASSING = "yearOfPassing";
+  public static final String ZIPCODE = "zipcode";
+  public static final String SUNBIRD_CONTENT_SERVICE_BASE_URL = "sunbird_content_service_base_url";
+  public static final String SUNBIRD_CONTENT_SERVICE_AUTHORIZATION =
+          "sunbird_content_service_authorization";
+  public static final String SUNBIRD_HEALTH_CHECK_ENABLE = "sunbird_health_check_enable";
+  public static final String HEALTH = "health";
+  public static final String SERVICE = "service";
+  public static final String SOFT_CONSTRAINTS = "softConstraints";
+  public static final String SUNBIRD_USER_ORG_API_BASE_URL = "sunbird_user_org_api_base_url";
+  public static final String SUNBIRD_API_MGR_BASE_URL = "sunbird_api_mgr_base_url";
+  public static final String SUNBIRD_AUTHORIZATION = "sunbird_authorization";
+  public static final String SUNBIRD_CS_BASE_URL = "sunbird_cs_base_url";
+  public static final String SUNBIRD_CS_SEARCH_PATH = "sunbird_cs_search_path";
+  public static final String SUNBIRD_LMS_TELEMETRY = "Sunbird_LMS_Telemetry";
+  public static final String SUNBIRD_LMS_AUTHORIZATION = "sunbird_authorization";
+  public static final String ETS = "ets";
+  public static final String CONTENT_ENCODING = "Content-Encoding";
+  public static final String EK_STEP = "EK-STEP";
+  public static final String RESOURCE_NAME = "resourceName";
+  public static final String DURATION = "duration";
+  public static final String OBJECT_STORE = "object-store";
+  public static final String IMAGE_URL = "imgUrl";
+  public static final String COMMUNITY_ID = "communityId";
+  public static final String LOCATION_CODE = "locationCode";
+  public static final String LATITUDE = "latitude";
+  public static final String LONGITUDE = "longitude";
+  public static final String UPLOAD_FILE_MAX_SIZE = "file_upload_max_size";
+  public static final String PRIMARY_KEY = "PK";
+  public static final String NON_PRIMARY_KEY = "NonPK";
+  public static final String PARENT_ID = "parentId";
+  public static final String CREATED_ON = "createdOn";
+  public static final String UPDATED_ON = "updatedOn";
+  public static final String LAST_UPDATED_ON = "lastUpdatedOn";
+  public static final String LAST_UPDATED_BY = "lastUpdatedBy";
+  public static final String SUNBIRD_DEFAULT_CHANNEL = "sunbird_default_channel";
+  public static final String CASSANDRA_WRITE_BATCH_SIZE = "cassandra_write_batch_size";
+  public static final String CASSANDRA_UPDATE_BATCH_SIZE = "cassandra_update_batch_size";
+  public static final String ORG_EXTERNAL_ID = "orgExternalId";
+  public static final String ORG_PROVIDER = "orgProvider";
+  public static final String EXTERNAL_IDS = "externalIds";
+  public static final String EXTERNAL_ID_TYPE = "externalIdType";
+  public static final String ID_TYPE = "idType";
+  public static final String ADD = "add";
+  public static final String REMOVE = "remove";
+  public static final String EDIT = "edit";
+  public static final String DEFAULT_FRAMEWORK = "defaultFramework";
+  public static final String EXTERNAL_ID_PROVIDER = "externalIdProvider";
+  public static final String USR_EXT_IDNT_TABLE = "usr_external_identity";
+  public static final String END_TIME_IN_HOUR_MINUTE_SECOND = " 23:59:59";
+  public static final String REGISTRY_ID = "registryId";
+  public static final String RESPONSE_CODE = "responseCode";
+  public static final String OK = "ok";
+  public static final String SUNBIRD_DEFAULT_COUNTRY_CODE = "sunbird_default_country_code";
+  public static final String ONBOARDING_MAIL_SUBJECT = "onboarding_mail_subject";
+  public static final String ONBOARDING_MAIL_MESSAGE = "onboarding_welcome_message";
+  public static final String ES_TYPES = "types";
+  public static final String RECIPIENT_SEARCH_QUERY = "recipientSearchQuery";
+  public static final String ORIGINAL_EXTERNAL_ID = "originalExternalId";
+  public static final String ORIGINAL_ID_TYPE = "originalIdType";
+  public static final String ORIGINAL_PROVIDER = "originalProvider";
+  public static final String SUNBIRD_CASSANDRA_CONSISTENCY_LEVEL =
+          "sunbird_cassandra_consistency_level";
+  public static final String VERSION_2 = "v2";
+  public static final String CUSTODIAN_ORG_CHANNEL = "custodianOrgChannel";
+  public static final String CUSTODIAN_ORG_ID = "custodianOrgId";
+  public static final String APP_ID = "appId";
+  public static final String REDIRECT_URI = "redirectUri";
+  public static final String SET_PASSWORD_LINK = "set_password_link";
+  public static final String VERIFY_EMAIL_LINK = "verify_email_link";
+  public static final String LINK = "link";
+  public static final String SET_PW_LINK = "setPasswordLink";
+  public static final String SUNBIRD_URL_SHORTNER_ENABLE = "sunbird_url_shortner_enable";
+  public static final String USER_PROFILE_CONFIG = "userProfileConfig";
+  public static final String PUBLIC_FIELDS = "publicFields";
+  public static final String PRIVATE_FIELDS = "privateFields";
+  public static final String DEFAULT_PROFILE_FIELD_VISIBILITY = "defaultProfileFieldVisibility";
+
+  public static final String SUNBIRD_COURSE_BATCH_NOTIFICATIONS_ENABLED =
+          "sunbird_course_batch_notification_enabled";
+
+  public static final String BATCH_START_DATE = "batchStartDate";
+  public static final String BATCH_END_DATE = "batchEndDate";
+  public static final String BATCH_NAME = "batchName";
+  public static final String BATCH_MENTOR_ENROL = "batchMentorEnrol";
+  public static final String BATCH_LEARNER_ENROL = "batchLearnerEnrol";
+  public static final String COURSE_INVITATION = "Course Invitation";
+  public static final String BATCH_LEARNER_UNENROL = "batchLearnerUnenrol";
+  public static final String BATCH_MENTOR_UNENROL = "batchMentorUnenrol";
+  public static final String UNENROLL_FROM_COURSE_BATCH = "Unenrolled from Training";
+  public static final String OPEN_BATCH_LEARNER_UNENROL = "openBatchLearnerUnenrol";
+
+  public static final String MENTOR = "mentor";
+  public static final String OLD = "old";
+  public static final String NEW = "new";
+  public static final String COURSE_BATCH = "courseBatch";
+  public static final String ADDED_MENTORS = "addedMentors";
+  public static final String REMOVED_MENTORS = "removedMentors";
+  public static final String ADDED_PARTICIPANTS = "addedParticipants";
+  public static final String REMOVED_PARTICIPANTS = "removedParticipants";
+  public static final String URL_QUERY_STRING = "urlQueryString";
+  public static final String SUNBIRD_API_REQUEST_LOWER_CASE_FIELDS =
+          "sunbird_api_request_lower_case_fields";
+  public static final String ATTRIBUTE = "attribute";
+  public static final String ERRORS = "errors";
+  public static final String ROLE_LIST = "roleList";
+  public static final String SUNBIRD_USER_PROFILE_READ_EXCLUDED_FIELDS = "read.excludedFields";
+  public static final String COMPLETED_ON = "completedOn";
+  public static final String CALLER_ID = "callerId";
+  public static final String USER_TYPE = "userType";
+
+  public static final String COURSE_BATCH_URL = "courseBatchUrl";
+  public static final String SUNBIRD_COURSE_BATCH_NOTIFICATION_SIGNATURE =
+          "sunbird_course_batch_notification_signature";
+  public static final String SIGNATURE = "signature";
+  public static final String OPEN_BATCH_LEARNER_ENROL = "openBatchLearnerEnrol";
+  public static final String CONTENT_PROPERTY_MEDIUM = "medium";
+  public static final String CONTENT_PROPERTY_GRADE_LEVEL = "gradeLevel";
+  public static final String CONTENT_PROPERTY_SUBJECT = "subject";
+  public static final String CONTENT_PROPERTY_NAME = "name";
+  public static final String CONTENT_PROPERTY_VISIBILITY = "visibility";
+  public static final String CONTENT_PROPERTY_VISIBILITY_PARENT = "Parent";
+  public static final String CONTENT_PROPERTY_MIME_TYPE = "mimeType";
+  public static final String CONTENT_MIME_TYPE_COLLECTION =
+          "application/vnd.ekstep.content-collection";
+  public static final String VERSION_KEY = "versionKey";
+  public static final String CSV_SEPERATOR = ",";
+  public static final String CONTENT_CLOUD_STORAGE_TYPE = "sunbird_cloud_service_provider";
+  public static final String CONTENT_CLOUD_STORAGE_CONTAINER =
+          "sunbird_content_cloud_storage_container";
+  public static final String AZURE_STR = "azure";
+  public static final String AWS_STR = "aws";
+  public static final String GCLOUD_STR = "gcloud";
+
+  public static final String CLOUD_FOLDER_CONTENT = "sunbird_cloud_content_folder";
+  public static final String CLOUD_STORE_BASE_PATH = "cloud_storage_base_url";
+  public static final String CLOUD_STORAGE_CNAME_URL= "cloud_storage_cname_url";
+  public static final String CLOUD_STORAGE_DIAL_BUCKET_NAME = "cloud_storage_dial_bucketname";
+  public static final String DIAL_STORAGE_BASE_PATH_PLACEHOLDER="cloud_storage_path_prefix_dial";
+  public static final String CLOUD_STORE_BASE_PATH_PLACEHOLDER = "cloud_store_base_path_placeholder";
+  public static final String TO_URL = "toUrl";
+  public static final String TTL = "ttl";
+  public static final String TEXTBOOK_TOC_CSV_TTL = "sunbird_texbook_toc_csv_ttl";
+  public static final String FILE_TYPE_CSV = "csv";
+
+  // Texbook TOC
+  public static final String TEXTBOOK = "textbook";
+  public static final String TEXTBOOK_ID = "textbookId";
+  public static final String MODE = "mode";
+  public static final String MIME_TYPE = "mimeType";
+  public static final String METADATA = "metadata";
+  public static final String HIERARCHY = "hierarchy";
+  public static final String FILE_DATA = "fileData";
+  public static final String FRAMEWORK_METADATA = "frameworkCategories";
+  public static final String TEXTBOOK_TOC_ALLOWED_MIMETYPE =
+          "application/vnd.ekstep.content-collection";
+  public static final String TEXTBOOK_TOC_ALLOWED_CONTNET_TYPES =
+          "textbook_toc_allowed_content_types";
+  public static final String TEXTBOOK_TOC_MAX_CSV_ROWS = "textbook_toc_max_csv_rows";
+  public static final String TEXTBOOK_TOC_INPUT_MAPPING = "textbook_toc_input_mapping";
+  public static final String NODES_MODIFIED = "nodesModified";
+  public static final String TEXT_TOC_FILE_SUPPRESS_COLUMN_NAMES =
+          "textbook_toc_file_suppress_column_names";
+  public static final String TEXTBOOK_TOC_MANDATORY_FIELDS = "textbook_toc_mandatory_fields";
+  public static final String DOWNLOAD = "download";
+  public static final String COLLECTION_MIME_TYPE = "application/vnd.ekstep.content-collection";
+  public static final String TB_ROOT = "root";
+  public static final String TB_IS_NEW = "isNew";
+  public static final String KEYWORDS = "keywords";
+  public static final String UNIT = "Unit";
+  public static final String UPDATE_HIERARCHY_API = "sunbird_update_hierarchy_api";
+  public static final String TB_MESSAGES = "messages";
+  public static final String TNC_ACCEPTED_ON = "tncAcceptedOn";
+  public static final String TNC_ACCEPTED_VERSION = "tncAcceptedVersion";
+  public static final String TNC_LATEST_VERSION_URL = "tncLatestVersionUrl";
+  public static final String PROMPT_TNC = "promptTnC";
+  public static final String TNC_LATEST_VERSION = "tncLatestVersion";
+  public static final String BULK_ORG_UPLOAD = "bulkOrgUpload";
+  public static final String FRAMEWORKS = "frameworks";
+  public static final String LATEST_VERSION = "latestVersion";
+  public static final String TNC_CONFIG = "tncConfig";
+  public static final String TNC = "tnc";
+  public static final String ACCEPT = "accept";
+  public static final String ROOT_ORG_NAME = "rootOrgName";
+  public static final String OTP_EXPIRATION_IN_MINUTES = "otpExpiryInMinutes";
+  public static final String SUNBIRD_USER_MAX_PHONE_LENGTH = "sunbird_user_max_phone_length";
+  public static final String RATE_LIMIT = "rate_limit";
+  public static final String RATE_LIMIT_UNIT = "unit";
+  public static final String RATE = "rate";
+  public static final String INSTALLATION_NAME = "installationName";
+  public static final String LOCATION_CODES = "locationCodes";
+  public static final String BATCH_DETAILS = "batchDetails";
+  public static final String USER_LOCATIONS = "userLocations";
+  public static final String DIAL_CODES = "dialcodes";
+  public static final String DIAL_CODE_REQUIRED = "dialcodeRequired";
+  public static final String NO = "No";
+  public static final String YES = "Yes";
+  public static final String QR_CODE_REQUIRED = "QR Code Required?";
+  public static final String QR_CODE = "QR Code";
+  public static final String RESERVED_DIAL_CODES = "reservedDialcodes";
+  public static final String FRAMEWORK_READ_API_URL = "framework_read_api_url";
+  public static final String DIAL_CODE_IDENTIFIER_MAP = "dialCodeIdentifierMap";
+  public static final String LINK_DIAL_CODE_API = "sunbird_link_dial_code_api";
+  public static final String LINKED_CONTENT = "linkedContent";
+  public static final String MAX_ALLOWED_CONTENT_SIZE = "max_allowed_content_size";
+  public static final String LINKED_CONTENT_COLUMN_KEY = "Linked Content";
+
+  public static final String BATCHES = "batches";
+  public static final String ENROLLED_ON = "enrolledOn";
+  public static final String LAST_ACCESSED_ON = "lastAccessedOn";
+  public static final String OTHER = "OTHER";
+  public static final String TEACHER = "TEACHER";
+  public static final String USER_EXTERNAL_ID = "userExternalId";
+  public static final String USER_ID_TYPE = "userIdType";
+  public static final String USER_PROVIDER = "userProvider";
+  public static final String SORTBY = "sortBy";
+  public static final String SORT_ORDER = "sortOrder";
+  public static final String NUMERIC = "NUMERIC";
+  public static final String ASC = "asc";
+  public static final String TERM = "term";
+  public static final String DESC = "desc";
+  public static final String SUNBIRD_TOC_LINKED_CONTENT_COLUMN_NAME =
+          "sunbird_toc_linked_content_column_name";
+  public static final String SUNBIRD_TOC_MAX_FIRST_LEVEL_UNITS =
+          "sunbird_toc_max_first_level_units";
+  public static final String TEXTBOOK_TOC_OUTPUT_MAPPING = "textbook_toc_output_mapping";
+  public static final String TEXTBOOK_UNIT = "TextBookUnit";
+  public static final String USER_NAME_HEADER = "User Name";
+  public static final String ORG_NAME_HEADER = "Org Name";
+  public static final String SCHOOL_NAME_HEADER = "School Name";
+  public static final String COURSE_ENROLL_DATE_HEADER = "Enrollment Date";
+  public static final String PROGRESS_HEADER = "Progress";
+  public static final String SUNBIRD_CONTENT_SEARCH_URL = "sunbird_content_search_url";
+  public static final String DATE_TIME_HEADER = "Date time stamp";
+  public static final String PHONE_HEADER = "Mobile Number";
+  public static final String EMAIL_HEADER = "Email Id";
+  public static final String COURSE_PROGRESS_MAIL_TEMPLATE = "courseProgressMailTemplate";
+  public static final String SUNBIRD_TIMEZONE = "sunbird_time_zone";
+  public static final String COURSE_STAT_MAIL_DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
+  public static final String DATA_SOURCE = "dataSource";
+  public static final String SUNBIRD_DIALCODE_SEARCH_API = "sunbird_dialcode_search_api";
+  public static final String FROM_BEGINING = "fromBegining";
+  public static final String SUNBIRD_KEYCLOAK_USER_FEDERATION_PROVIDER_ID =
+          "sunbird_keycloak_user_federation_provider_id";
+  public static final String DEVICE_ID = "did";
+  public static final String SUNBIRD_GZIP_FILTER_ENABLED = "sunbird_gzip_filter_enabled";
+  public static final String COMPLETED_PERCENT = "completedPercent";
+  public static final String PARTICIPANT_COUNT = "participantCount";
+  public static final String BOARD = "board";
+  public static final String MEDIUM = "medium";
+  public static final String SUNBIRD_GZIP_ENABLE = "sunbird_gzip_enable";
+  public static final String SHOW_DOWNLOAD_LINK = "showDownloadLink";
+  public static final String SUNBIRD_SYNC_READ_WAIT_TIME = "sunbird_sync_read_wait_time";
+  public static final String REPORT_UPDATED_ON = "reportUpdatedOn";
+  public static final String SUNBIRD_GZIP_SIZE_THRESHOLD = "sunbird_gzip_size_threshold";
+  public static final String PAGE_MANAGEMENT = "page_management";
+  public static final String MAP_NAME = "mapName";
+  public static final String PAGE_ASSEMBLE = "pageAssemble";
+  public static final String SIGNUP_TYPE = "signupType";
+  public static final String REQUEST_SOURCE = "source";
+
+  public static final String SUNBIRD_REDIS_CONN_POOL_SIZE = "sunbird_redis_connection_pool_size";
+  public static final String RECIPIENT_PHONES = "recipientPhones";
+  public static final String TCP = "tcp";
+  public static final String REST = "rest";
+  public static final String ES_OR_OPERATION = "$or";
+  public static final String PREV_USED_EMAIL = "prevUsedEmail";
+  public static final String PREV_USED_PHONE = "prevUsedPhone";
+  public static final String MERGE_USER = "Mergeuser";
+  public static final String FROM_ACCOUNT_ID = "fromAccountId";
+  public static final String TO_ACCOUNT_ID = "toAccountId";
+  public static final String MERGEE_ID = "mergeeId";
+  public static final String USER_MERGEE_ACCOUNT = "userMergeeAccount";
+  public static final String SEARCH_FUZZY = "fuzzy";
+  public static final String CERT_ID = "certId";
+  public static final String ACCESS_CODE = "accessCode";
+  public static final String USER_CERT = "user_cert";
+  public static final String STORE = "store";
+  public static final String JSON = "json";
+  public static final String PDF = "pdf";
+  public static final String JSON_DATA = "jsonData";
+  public static final String PDF_URL = "pdfURL";
+  public static final String CREATED_AT = "createdAt";
+  public static final String UPDATED_AT = "updatedAt";
+  public static final String SIGN_KEYS = "signKeys";
+  public static final String ENC_KEYS = "encKeys";
+  public static final String SUNBIRD_STATE_IMG_URL = "sunbird_state_img_url";
+  public static final String SUNBIRD_DIKSHA_IMG_URL = "sunbird_diksha_img_url";
+  public static final String SUNBIRD_CERT_COMPLETION_IMG_URL = "sunbird_cert_completion_img_url";
+  public static final String stateImgUrl = "stateImgUrl";
+  public static final String dikshaImgUrl = "dikshaImgUrl";
+  public static final String certificateImgUrl = "certificateImgUrl";
+  public static final String X_AUTHENTICATED_USER_TOKEN = "x-authenticated-user-token";
+  public static final String X_SOURCE_USER_TOKEN = "x-source-user-token";
+  public static final String SUNBIRD_SUBDOMAIN_KEYCLOAK_BASE_URL =
+          "sunbird_subdomain_keycloak_base_url";
+  public static final String ACTION = "action";
+  public static final String ITERATION = "iteration";
+  public static final String TELEMETRY_TARGET_USER_MERGE_TYPE = "MergeUserCoursesAndCert";
+  public static final String TELEMETRY_PRODUCER_USER_MERGE_ID = "org.sunbird.platform";
+  public static final String TELEMETRY_EDATA_USER_MERGE_ACTION = "merge-user-courses-and-cert";
+  public static final String BE_JOB_REQUEST = "BE_JOB_REQUEST";
+  public static final String TELEMETRY_ACTOR_USER_MERGE_ID = "Merge User Courses and Cert";
+  public static final String SUNBIRD_COURSE_DIALCODES_DB = "sunbird_course_dialcodes_db";
+  public static final String CERTIFICATE = "Certificate";
+  public static final String OLD_CERTIFICATE = "oldCertificate";
+  public static final String MERGE_CERT = "Mergecert";
+  public static final String RECOVERY_EMAIL = "recoveryEmail";
+  public static final String RECOVERY_PHONE = "recoveryPhone";
+  public static final String SUPPORTED_COlUMNS = "supportedColumns";
+  public static final String INPUT_STATUS = "input status";
+  public static final String EXTERNAL_USER_ID = "ext user id";
+  public static final String EXTERNAL_ORG_ID = "ext org id";
+  public static final String MIGRATION_USER_OBJECT = "MigrationUser";
+  public static final String TASK_COUNT = "taskCount";;
+  public static final String NESTED_KEY_FILTER = "nestedFilters";
+  public static final String SHADOW_USER = "shadow_user";
+  public static final String USER_EXT_ID = "userExtId";
+  public static final String ORG_EXT_ID = "orgExtId";
+  public static final String STATE_VALIDATED = "stateValidated";
+  public static final String FLAGS_VALUE = "flagsValue";
+  public static final String USER_STATUS = "userStatus";
+  public static final String CLAIM_STATUS = "claimStatus";
+  public static final String CLAIMED_ON = "claimedOn";
+  public static final String SMS = "sms";
+  public static final String CONTEXT_TELEMETRY = "telemetryContext";
+  public static final String OLD_ID = "oldId";
+  public static final String MAX_ATTEMPT = "maxAttempt";
+  public static final String REMAINING_ATTEMPT = "remainingAttempt";
+  public static final String IS_SSO_ROOTORG_ENABLED = "isSSOEnabled";
+  public static final String USER_FEED_DB = "user_feed";
+  public static final String USER_FEED = "userFeed";
+  public static final String FEED_DATA = "data";
+  public static final String REJECT = "reject";
+  public static final String FEED_ID = "feedId";
+  public static final String LICENSE = "license";
+  public static final String DEFAULT_LICENSE = "defaultLicense";
+  public static final String SUNBIRD_PASS_REGEX = "sunbird_pass_regex";
+  public static final String NESTED_EXISTS = "nested_exists";
+  public static final String NESTED_NOT_EXISTS = "nested_not_exists";
+  public static final String PROSPECT_CHANNELS = "prospectChannels";
+  public static final String PROSPECT_CHANNELS_IDS = "prospectChannelsIds";
+  public static final String CATEGORY = "category";
+  public static final String TEMPLATE_ID = "templateId";
+  public static final String TEMPLATE_ID_VALUE = "resetPasswordWithOtp";
+  public static final String VERSION_3 = "v3";
+  public static final String LEARNING_SERVICE_BASE_URL = "learning_service_base_url";
+  public static final String CREATOR_DETAILS_FIELDS = "sunbird_user_search_cretordetails_fields";
+  public static final String USER_SEARCH_BASE_URL = "sunbird_user_service_api_base_url";
+  public static final String SUNBIRD_QRCODE_COURSES_LIMIT ="sunbird_user_qrcode_courses_limit";
+  public static final String ACCESS_TOKEN_PUBLICKEY_BASEPATH = "accesstoken.publickey.basepath";
+  public static final String ACCESS_TOKEN_PUBLICKEY_KEYPREFIX = "accesstoken.publickey.keyprefix";
+  public static final String ACCESS_TOKEN_PUBLICKEY_KEYCOUNT = "accesstoken.publickey.keycount";
+  public static final String SHA_256_WITH_RSA = "SHA256withRSA";
+  public static final String SUB = "sub";
+  public static final String DOT_SEPARATOR = ".";
+  public static final String REQUESTED_FOR = "requestedFor";
+  public static final String CONTENT_PROPS_TO_ADD ="learning.content.props.to.add";
+  public static final String GROUP_ACTIVITY_DB = "groupActivityDB";
+  public static final String ACTIVITYID = "activityId";
+  public static final String ACTIVITYTYPE = "activityType";
+  public static final String ACTIVITY_ID = "activity_id";
+  public static final String ACTIVITY_TYPE = "activity_type";
+  public static final String GROUP_SERVICE_API_BASE_URL ="sunbird_group_service_api_base_url";
+  public static final String GROUP_MEMBERS_METADATA ="group.members.metadata";
+  public static final String COLLECTION_ID = "collectionId";
+  public static final String TRACKABLE_ENABLED = "trackable.enabled";
+  public static final String GROUPBY = "groupBy";
+  public static final String X_AUTH_TOKEN = "X_AUTH_TOKEN";
+  public static final String TEMPLATE = "template";
+  public static final String ASSESSMENT_AGGREGATOR_DB = "assessment_aggregator_db";
+  public static final String SERVICE_NAME = "course-service";
+  public static final String PRODUCER_NAME = "org.sunbird.course-service";
+  public static final String PID = "course-service";
+  public static final String P_VERSION = "1.0";
+  public static final String X_DEVICE_ID = "x-device-id";
+  public static final String X_SESSION_ID = "x-session-id";
+  public static final String X_TRACE_ID = "x-trace-id";
+  public static final String USER_ENROLMENTS_DB = "user_enrolments";
+  public static final List<String> CHANGE_IN_SIMPLE_DATE_FORMAT = Arrays.asList("startDate", "endDate", "enrollmentEndDate");
+  public static final List<String> CHANGE_IN_DATE_FORMAT = Arrays.asList("createdDate", "updatedDate");
+  public static final List<String> CHANGE_IN_DATE_FORMAT_ALL = Arrays.asList("startDate", "endDate", "enrollmentEndDate", "createdDate", "updatedDate");
+  public static final String OLD_START_DATE = "oldStartDate";
+  public static final String OLD_END_DATE = "oldEndDate";
+  public static final String OLD_ENROLLMENT_END_DATE = "oldEnrollmentEndDate";
+  public static final String OLD_LAST_ACCESS_TIME = "oldLastAccessTime";
+  public static final String OLD_LAST_COMPLETED_TIME = "oldLastCompletedTime";
+  public static final String OLD_LAST_UPDATED_TIME = "oldLastUpdatedTime";
+  public static final String COURSE_ID_KEY = "courseid";
+  public static final String CONTENT_ID_KEY = "contentid";
+  public static final String LAST_ACCESS_TIME_KEY = "last_access_time";
+  public static final List<String> SET_END_OF_DAY = Arrays.asList("endDate", "enrollmentEndDate");
+  public static final String BATCH_ID_KEY = "batchid";
+  public static final String USER_ID_KEY = "userid";
+  public static final String OLD_CREATED_DATE = "oldCreatedDate";
+  public static final String X_LOGGING_HEADERS = "X_LOGGING_HEADERS";
+  public static final String LAST_CONTENT_ACCESS_TIME = "lastcontentaccesstime";
+  public static final String GCP="gcloud";
+  public static final String TEMPLATE_URL = "templateUrl";
+  public static final String SUNBIRD_DIAL_SERVICE_BASE_URL = "sunbird_dial_service_base_url";
+  public static final String SUNBIRD_DIAL_SERVICE_SEARCH_URL = "sunbird_dial_service_search_url";
+  public static final String AUTH_ENABLED = "AuthenticationEnabled";
+
+  private JsonKey() {}
+}
diff --git a/validate-api/validate-service/app/utils/QuestionOperations.scala b/validate-api/validate-service/app/utils/QuestionOperations.scala
new file mode 100644
index 000000000..ab3cea870
--- /dev/null
+++ b/validate-api/validate-service/app/utils/QuestionOperations.scala
@@ -0,0 +1,6 @@
+package utils
+
+object QuestionOperations extends Enumeration {
+	val createQuestion, readQuestion, readPrivateQuestion, updateQuestion,
+	reviewQuestion, publishQuestion, retireQuestion, importQuestion, systemUpdateQuestion, listQuestions, rejectQuestion = Value
+}
diff --git a/validate-api/validate-service/app/utils/RequestContext.java b/validate-api/validate-service/app/utils/RequestContext.java
new file mode 100644
index 000000000..3f51d3084
--- /dev/null
+++ b/validate-api/validate-service/app/utils/RequestContext.java
@@ -0,0 +1,87 @@
+package utils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class RequestContext {
+
+    private String uid;
+    private String did;
+    private String sid;
+    private String debugEnabled;
+    private String actorId;
+    private String actorType;
+    private String loggerLevel;
+    private String requestId;
+    private String env;
+    private Map<String, Object> contextMap = new HashMap<>();
+    private String channel;
+    private Map<String, Object> pdata = new HashMap<>();
+
+    public RequestContext(String channel, String pdataId, String env, String did, String sid, String pid, String pver, List<Object> cdata) {
+        this.did = did;
+        this.sid = sid;
+        this.channel = channel;
+        this.pdata.put("id", pdataId);
+        this.pdata.put("pid", pid);
+        this.pdata.put("ver", pver);
+        this.contextMap.putAll(new HashMap<String, Object>() {{
+            put("did", did);
+            put("sid", sid);
+            put("channel", channel);
+            put("env", env);
+            put("pdata", pdata);
+            if (cdata != null)
+                put("cdata", cdata);
+        }});
+    }
+
+    public String getActorId() {
+        return actorId;
+    }
+
+    public void setActorId(String actorId) {
+        this.actorId = actorId;
+    }
+
+    public String getActorType() {
+        return actorType;
+    }
+
+    public void setActorType(String actorType) {
+        this.actorType = actorType;
+    }
+
+    public String getLoggerLevel() {
+        return loggerLevel;
+    }
+
+    public void setLoggerLevel(String loggerLevel) {
+        this.loggerLevel = loggerLevel;
+    }
+
+    public String getRequestId() {
+        return requestId;
+    }
+
+    public void setRequestId(String requestId) {
+        this.requestId = requestId;
+    }
+
+    public String getDebugEnabled() {
+        return debugEnabled;
+    }
+
+    public String getEnv() {
+        return env;
+    }
+
+    public void setEnv(String env) {
+        this.env = env;
+    }
+
+    public Map<String, Object> getContextMap() {
+        return contextMap;
+    }
+}
diff --git a/validate-api/validate-service/conf/application.conf b/validate-api/validate-service/conf/application.conf
new file mode 100644
index 000000000..a2e0cc367
--- /dev/null
+++ b/validate-api/validate-service/conf/application.conf
@@ -0,0 +1,407 @@
+# This is the main configuration file for the application.
+# https://www.playframework.com/documentation/latest/ConfigFile
+# ~~~~~
+# Play uses HOCON as its configuration file format. HOCON has a number
+# of advantages over other config formats, but there are two things that
+# can be used when modifying settings.
+#
+# You can include other configuration files in this main application.conf file:
+#include "extra-config.conf"
+#
+# You can declare variables and substitute for them:
+#mykey = ${some.value}
+#
+# And if an environment variable exists when there is no other substitution, then
+# HOCON will fall back to substituting environment variable:
+#mykey = ${JAVA_HOME}
+
+## Akka
+# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration
+# https://www.playframework.com/documentation/latest/JavaAkka#Configuration
+# ~~~~~
+# 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:
+  #
+  # <logger name="akka.actor" level="INFO" />
+  #
+  # And then uncomment this line to debug the configuration.
+  #
+  #log-config-on-start = true
+  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"
+    }
+  }
+  actors-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
+  }
+  actor {
+    deployment {
+      /healthActor
+        {
+          router = smallest-mailbox-pool
+          nr-of-instances = 5
+          dispatcher = actors-dispatcher
+        }
+
+    }
+  }
+}
+
+## Secret key
+# http://www.playframework.com/documentation/latest/ApplicationSecret
+# ~~~~~
+# The secret key is used to sign Play's session cookie.
+# This must be changed for production, but we don't recommend you change it in this file.
+play.http.secret.key= a-long-secret-to-calm-the-rage-of-the-entropy-gods
+
+## Modules
+# https://www.playframework.com/documentation/latest/Modules
+# ~~~~~
+# Control which modules are loaded when Play starts. Note that modules are
+# the replacement for "GlobalSettings", which are deprecated in 2.5.x.
+# Please see https://www.playframework.com/documentation/latest/GlobalSettings
+# for more information.
+#
+# You can also extend Play functionality by using one of the publically available
+# Play modules: https://playframework.com/documentation/latest/ModuleDirectory
+play.modules {
+  # By default, Play will load any class called Module that is defined
+  # in the root package (the "app" directory), or you can define them
+  # explicitly below.
+  # If there are any built-in modules that you want to enable, you can list them here.
+  #enabled += my.application.Module
+
+  # If there are any built-in modules that you want to disable, you can list them here.
+  #disabled += ""
+  enabled += modules.AssessmentModule
+}
+
+## IDE
+# https://www.playframework.com/documentation/latest/IDE
+# ~~~~~
+# Depending on your IDE, you can add a hyperlink for errors that will jump you
+# directly to the code location in the IDE in dev mode. The following line makes
+# use of the IntelliJ IDEA REST interface:
+#play.editor="http://localhost:63342/api/file/?file=%s&line=%s"
+
+## Internationalisation
+# https://www.playframework.com/documentation/latest/JavaI18N
+# https://www.playframework.com/documentation/latest/ScalaI18N
+# ~~~~~
+# Play comes with its own i18n settings, which allow the user's preferred language
+# to map through to internal messages, or allow the language to be stored in a cookie.
+play.i18n {
+  # The application languages
+  langs = [ "en" ]
+
+  # Whether the language cookie should be secure or not
+  #langCookieSecure = true
+
+  # Whether the HTTP only attribute of the cookie should be set to true
+  #langCookieHttpOnly = true
+}
+
+## Play HTTP settings
+# ~~~~~
+play.http {
+  ## Router
+  # https://www.playframework.com/documentation/latest/JavaRouting
+  # https://www.playframework.com/documentation/latest/ScalaRouting
+  # ~~~~~
+  # Define the Router object to use for this application.
+  # This router will be looked up first when the application is starting up,
+  # so make sure this is the entry point.
+  # Furthermore, it's assumed your route file is named properly.
+  # So for an application router like `my.application.Router`,
+  # you may need to define a router file `conf/my.application.routes`.
+  # Default to Routes in the root package (aka "apps" folder) (and conf/routes)
+  #router = my.application.Router
+
+  ## Action Creator
+  # https://www.playframework.com/documentation/latest/JavaActionCreator
+  # ~~~~~
+  #actionCreator = null
+
+  ## ErrorHandler
+  # https://www.playframework.com/documentation/latest/JavaRouting
+  # https://www.playframework.com/documentation/latest/ScalaRouting
+  # ~~~~~
+  # If null, will attempt to load a class called ErrorHandler in the root package,
+  #errorHandler = null
+
+  ## Session & Flash
+  # https://www.playframework.com/documentation/latest/JavaSessionFlash
+  # https://www.playframework.com/documentation/latest/ScalaSessionFlash
+  # ~~~~~
+  session {
+    # Sets the cookie to be sent only over HTTPS.
+    #secure = true
+
+    # Sets the cookie to be accessed only by the server.
+    #httpOnly = true
+
+    # Sets the max-age field of the cookie to 5 minutes.
+    # NOTE: this only sets when the browser will discard the cookie. Play will consider any
+    # cookie value with a valid signature to be a valid session forever. To implement a server side session timeout,
+    # you need to put a timestamp in the session and check it at regular intervals to possibly expire it.
+    #maxAge = 300
+
+    # Sets the domain on the session cookie.
+    #domain = "example.com"
+  }
+
+  flash {
+    # Sets the cookie to be sent only over HTTPS.
+    #secure = true
+
+    # Sets the cookie to be accessed only by the server.
+    #httpOnly = true
+  }
+}
+
+play.server.http.idleTimeout = 60s
+play.http.parser.maxDiskBuffer = 10MB
+parsers.anyContent.maxLength = 10MB
+
+## 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"
+}
+
+## WS (HTTP Client)
+# https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS
+# ~~~~~
+# The HTTP client primarily used for REST APIs. The default client can be
+# configured directly, but you can also create different client instances
+# with customized settings. You must enable this by adding to build.sbt:
+#
+# libraryDependencies += ws // or javaWs if using java
+#
+play.ws {
+  # Sets HTTP requests not to follow 302 requests
+  #followRedirects = false
+
+  # Sets the maximum number of open HTTP connections for the client.
+  #ahc.maxConnectionsTotal = 50
+
+  ## WS SSL
+  # https://www.playframework.com/documentation/latest/WsSSL
+  # ~~~~~
+  ssl {
+    # Configuring HTTPS with Play WS does not require programming. You can
+    # set up both trustManager and keyManager for mutual authentication, and
+    # turn on JSSE debugging in development with a reload.
+    #debug.handshake = true
+    #trustManager = {
+    # stores = [
+    # { type = "JKS", path = "exampletrust.jks" }
+    # ]
+    #}
+  }
+}
+
+## Cache
+# https://www.playframework.com/documentation/latest/JavaCache
+# https://www.playframework.com/documentation/latest/ScalaCache
+# ~~~~~
+# 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
+#
+play.cache {
+  # If you want to bind several caches, you can bind the individually
+  #bindCaches = ["db-cache", "user-cache", "session-cache"]
+}
+
+## Filter Configuration
+# https://www.playframework.com/documentation/latest/Filters
+# ~~~~~
+# There are a number of built-in filters that can be enabled and configured
+# to give Play greater security.
+#
+play.filters {
+
+  # Enabled filters are run automatically against Play.
+  # CSRFFilter, AllowedHostFilters, and SecurityHeadersFilters are enabled by default.
+  enabled = [filters.AccessLogFilter]
+
+  # Disabled filters remove elements from the enabled list.
+  # disabled += filters.CSRFFilter
+
+
+  ## CORS filter configuration
+  # https://www.playframework.com/documentation/latest/CorsFilter
+  # ~~~~~
+  # CORS is a protocol that allows web applications to make requests from the browser
+  # across different domains.
+  # NOTE: You MUST apply the CORS configuration before the CSRF filter, as CSRF has
+  # dependencies on CORS settings.
+  cors {
+    # Filter paths by a whitelist of path prefixes
+    #pathPrefixes = ["/some/path", ...]
+
+    # The allowed origins. If null, all origins are allowed.
+    #allowedOrigins = ["http://www.example.com"]
+
+    # The allowed HTTP methods. If null, all methods are allowed
+    #allowedHttpMethods = ["GET", "POST"]
+  }
+
+  ## Security headers filter configuration
+  # https://www.playframework.com/documentation/latest/SecurityHeaders
+  # ~~~~~
+  # Defines security headers that prevent XSS attacks.
+  # If enabled, then all options are set to the below configuration by default:
+  headers {
+    # The X-Frame-Options header. If null, the header is not set.
+    #frameOptions = "DENY"
+
+    # The X-XSS-Protection header. If null, the header is not set.
+    #xssProtection = "1; mode=block"
+
+    # The X-Content-Type-Options header. If null, the header is not set.
+    #contentTypeOptions = "nosniff"
+
+    # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set.
+    #permittedCrossDomainPolicies = "master-only"
+
+    # The Content-Security-Policy header. If null, the header is not set.
+    #contentSecurityPolicy = "default-src 'self'"
+  }
+
+  ## Allowed hosts filter configuration
+  # https://www.playframework.com/documentation/latest/AllowedHostsFilter
+  # ~~~~~
+  # Play provides a filter that lets you configure which hosts can access your application.
+  # This is useful to prevent cache poisoning attacks.
+  hosts {
+    # Allow requests to example.com, its subdomains, and localhost:9000.
+    #allowed = [".example.com", "localhost:9000"]
+  }
+}
+
+play.http.parser.maxMemoryBuffer = 50MB
+akka.http.parsing.max-content-length = 50MB
+schema.base_path="../../schemas/"
+
+# Cassandra Configuration
+cassandra.lp.connection="127.0.0.1:9042"
+#content.keyspace = "content_store"
+content.keyspace = "dev_content_store"
+
+# Redis Configuration
+redis.host="localhost"
+redis.port=6379
+redis.maxConnections=128
+
+# Graph Configuration
+graph.dir=/data/testingGraphDB
+akka.request_timeout=30
+environment.id=10000000
+graph.ids=["domain"]
+graph.passport.key.base=31b6fd1c4d64e745c867e61a45edc34a
+route.domain="bolt://localhost:7687"
+route.bolt.write.domain="bolt://localhost:7687"
+route.bolt.read.domain="bolt://localhost:7687"
+route.bolt.comment.domain="bolt://localhost:7687"
+route.all="bolt://localhost:7687"
+route.bolt.write.all="bolt://localhost:7687"
+route.bolt.read.all="bolt://localhost:7687"
+route.bolt.comment.all="bolt://localhost:7687"
+
+shard.id=1
+platform.auth.check.enabled=false
+platform.cache.ttl=3600000
+
+#Top N Config for Search Telemetry
+telemetry_env=dev
+
+installation.id=ekstep
+
+
+languageCode {
+  assamese : "as"
+  bengali : "bn"
+  english : "en"
+  gujarati : "gu"
+  hindi : "hi"
+  kannada : "ka"
+  marathi : "mr"
+  odia : "or"
+  tamil : "ta"
+  telugu : "te"
+}
+
+kafka {
+  urls : "localhost:9092"
+  topic.send.enable : true
+  topics.instruction : "sunbirddev.assessment.publish.request"
+}
+objectcategorydefinition.keyspace="dev_category_store"
+question {
+  keyspace = "dev_question_store"
+  list.limit=20
+}
+questionset.keyspace="dev_hierarchy_store"
+
+cassandra {
+  lp {
+    connection: "localhost:9042"
+  }
+  lpa {
+    connection: "localhost:9042"
+  }
+}
+neo4j_objecttypes_enabled=["Question"]
+
+import {
+  request_size_limit = 200
+  output_topic_name = "local.auto.creation.job.request"
+  required_props {
+    question = ["name", "code", "mimeType", "framework", "channel"]
+    questionset = ["name", "code", "mimeType", "framework", "channel"]
+  }
+  remove_props {
+    question = []
+    questionset = []
+  }
+}
+
+root_node_visibility=["Default","Private"]
\ No newline at end of file
diff --git a/validate-api/validate-service/conf/logback.xml b/validate-api/validate-service/conf/logback.xml
new file mode 100644
index 000000000..73529d622
--- /dev/null
+++ b/validate-api/validate-service/conf/logback.xml
@@ -0,0 +1,28 @@
+<configuration>
+
+	<conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
+
+	<!-- transaction-event-trigger START -->
+	<timestamp key="timestamp" datePattern="yyyy-MM-dd"/>
+	<!-- common transactions logs -->
+	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>%d %msg%n</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
+		<appender-ref ref="STDOUT" />
+	</appender>
+
+
+	<logger name="play" level="INFO" />
+	<logger name="DefaultPlatformLogger" level="INFO" />
+	<!-- Telemetry Loggers-->
+	<logger name="TelemetryEventLogger" level="INFO" />
+
+	<root level="INFO">
+		<appender-ref ref="ASYNCSTDOUT" />
+	</root>
+
+</configuration>
\ No newline at end of file
diff --git a/validate-api/validate-service/conf/routes b/validate-api/validate-service/conf/routes
new file mode 100644
index 000000000..9fac2a84a
--- /dev/null
+++ b/validate-api/validate-service/conf/routes
@@ -0,0 +1,8 @@
+# Routes
+# This file defines all application routes (Higher priority routes first)
+# ~~~~
+GET		  /health						    controllers.HealthController.health
+GET       /service/health                   controllers.HealthController.serviceHealth
+
+
+PATCH    /v1/question/assestment/validate     	@controllers.QuestionValidateController.assessment(request: play.mvc.Http.Request)
diff --git a/validate-api/validate-service/pom.xml b/validate-api/validate-service/pom.xml
new file mode 100644
index 000000000..570ad27ed
--- /dev/null
+++ b/validate-api/validate-service/pom.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>validate-api</artifactId>
+        <groupId>org.sunbird</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>validate-service</artifactId>
+    <packaging>play2</packaging>
+
+    <repositories>
+        <repository>
+            <id>scalaz-bintray</id>
+            <name>Scalaz Bintray - releases</name>
+            <url>https://dl.bintray.com/scalaz/releases/</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+    <pluginRepositories>
+        <pluginRepository>
+            <id>typesafe-releases-plugins</id>
+            <url>https://repo.typesafe.com/typesafe/releases/</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
+    <properties>
+        <play2.version>2.7.2</play2.version>
+        <play2.plugin.version>1.0.0-rc5</play2.plugin.version>
+        <sbt-compiler.plugin.version>1.0.0</sbt-compiler.plugin.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>18.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <version>3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject.extensions</groupId>
+            <artifactId>guice-assistedinject</artifactId>
+            <version>3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.play</groupId>
+            <artifactId>play_${scala.major.version}</artifactId>
+            <version>${play2.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.play</groupId>
+            <artifactId>play-guice_${scala.major.version}</artifactId>
+            <version>${play2.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.play</groupId>
+            <artifactId>filters-helpers_${scala.major.version}</artifactId>
+            <version>${play2.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.play</groupId>
+            <artifactId>play-logback_${scala.major.version}</artifactId>
+            <version>${play2.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.play</groupId>
+            <artifactId>play-netty-server_${scala.major.version}</artifactId>
+            <version>${play2.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala-library</artifactId>
+            <version>${scala.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.sunbird</groupId>
+            <artifactId>assessment-actors</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <type>jar</type>
+            <exclusions>
+                <exclusion>
+                    <artifactId>slf4j-log4j12</artifactId>
+                    <groupId>org.slf4j</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.scalatest</groupId>
+            <artifactId>scalatest_${scala.maj.version}</artifactId>
+            <version>3.1.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.play</groupId>
+            <artifactId>play-specs2_${scala.maj.version}</artifactId>
+            <version>${play2.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.joda</groupId>
+            <artifactId>joda-convert</artifactId>
+            <version>2.2.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.danielwegener</groupId>
+            <artifactId>logback-kafka-appender</artifactId>
+            <version>0.2.0-RC2</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <sourceDirectory>${basedir}/app</sourceDirectory>
+        <testSourceDirectory>${basedir}/test</testSourceDirectory>
+        <resources>
+            <resource>
+                <directory>${basedir}/conf</directory>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M4</version>
+                <configuration>
+                    <includes>
+                        <include>**/*Spec.java</include>
+                        <include>**/*Test.java</include>
+                    </includes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.google.code.play2-maven-plugin</groupId>
+                <artifactId>play2-maven-plugin</artifactId>
+                <version>${play2.plugin.version}</version>
+                <extensions>true</extensions>
+            </plugin>
+            <plugin>
+                <groupId>com.google.code.sbt-compiler-maven-plugin</groupId>
+                <artifactId>sbt-compiler-maven-plugin</artifactId>
+                <version>${sbt-compiler.plugin.version}</version>
+                <configuration>
+                    <scalacOptions>-feature -deprecation -Xfatal-warnings</scalacOptions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.scoverage</groupId>
+                <artifactId>scoverage-maven-plugin</artifactId>
+                <version>${scoverage.plugin.version}</version>
+                <configuration>
+                    <scalaVersion>${scala.version}</scalaVersion>
+                    <aggregate>true</aggregate>
+                    <highlighting>true</highlighting>
+                    <excludedFiles>.*RoutesPrefix.*;.*Routes.*;.*javascript.*</excludedFiles>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/validate-api/validate-service/test/controllers/base/BaseSpec.scala b/validate-api/validate-service/test/controllers/base/BaseSpec.scala
new file mode 100644
index 000000000..883693c86
--- /dev/null
+++ b/validate-api/validate-service/test/controllers/base/BaseSpec.scala
@@ -0,0 +1,38 @@
+package controllers.base
+
+import com.typesafe.config.ConfigFactory
+import modules.TestModule
+import org.specs2.mutable.Specification
+import play.api.inject.guice.GuiceApplicationBuilder
+import play.api.libs.json.Json
+import play.api.mvc.Result
+import play.api.test.Helpers.{POST, contentAsString, contentType, defaultAwaitTimeout, route, status, _}
+import play.api.test.{FakeHeaders, FakeRequest}
+
+import scala.concurrent.Future
+
+class BaseSpec extends Specification {
+    implicit val app = new GuiceApplicationBuilder()
+      .disable(classOf[modules.AssessmentModule])
+      .bindings(new TestModule)
+      .build
+    implicit val config = ConfigFactory.load()
+
+    def post(apiURL: String, request: String, h: FakeHeaders = FakeHeaders(Seq()))
+    : Future[Result] = {
+        val headers = h.add(("content-type", "application/json"))
+        route(app, FakeRequest(POST, apiURL, headers, Json.toJson(Json.parse(request)))).get
+    }
+
+    def isOK(response: Future[Result]) {
+        status(response) must equalTo(OK)
+        contentType(response) must beSome.which(_ == "application/json")
+        contentAsString(response) must contain(""""status":"successful"""")
+    }
+
+    def hasClientError(response: Future[Result]) {
+        status(response) must equalTo(BAD_REQUEST)
+        contentType(response) must beSome.which(_ == "application/json")
+        contentAsString(response) must contain(""""err":"CLIENT_ERROR","status":"failed"""")
+    }
+}
diff --git a/validate-api/validate-service/test/controllers/v3/HealthControllerSpec.scala b/validate-api/validate-service/test/controllers/v3/HealthControllerSpec.scala
new file mode 100644
index 000000000..49f351a62
--- /dev/null
+++ b/validate-api/validate-service/test/controllers/v3/HealthControllerSpec.scala
@@ -0,0 +1,18 @@
+package controllers.v3
+
+import controllers.base.BaseSpec
+import org.junit.runner.RunWith
+import org.specs2.runner.JUnitRunner
+import play.api.test.{FakeRequest, Helpers}
+import play.api.test.Helpers.{OK, status}
+
+@RunWith(classOf[JUnitRunner])
+class HealthControllerSpec extends BaseSpec {
+
+	"return api health status report - successful response" in {
+		val controller = app.injector.instanceOf[controllers.HealthController]
+		val result = controller.health()(FakeRequest())
+		isOK(result)
+		status(result)(Helpers.defaultAwaitTimeout) must equalTo(OK)
+	}
+}
diff --git a/validate-api/validate-service/test/modules/TestModule.scala b/validate-api/validate-service/test/modules/TestModule.scala
new file mode 100644
index 000000000..3799b17c6
--- /dev/null
+++ b/validate-api/validate-service/test/modules/TestModule.scala
@@ -0,0 +1,26 @@
+package modules
+
+import com.google.inject.AbstractModule
+import org.sunbird.actor.core.BaseActor
+import org.sunbird.common.dto.{Request, Response, ResponseHandler}
+import play.libs.akka.AkkaGuiceSupport
+import utils.ActorNames
+
+import scala.concurrent.{ExecutionContext, Future}
+
+class TestModule extends AbstractModule with AkkaGuiceSupport {
+	override def configure(): Unit = {
+	bindActor(classOf[TestActor], ActorNames.HEALTH_ACTOR)
+
+		println("Test Module is initialized...")
+	}
+}
+
+class TestActor extends BaseActor {
+
+	implicit val ec: ExecutionContext = getContext().dispatcher
+
+	override def onReceive(request: Request): Future[Response] = {
+		Future(ResponseHandler.OK)
+	}
+}
-- 
GitLab