From abf05ed7efbddab2cb9c18a31aa042c44ed5e84f Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 5 Apr 2021 18:45:36 +0530
Subject: [PATCH 01/53] Create Goals.sh
---
definition-scripts/Goals.sh | 52 +++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 definition-scripts/Goals.sh
diff --git a/definition-scripts/Goals.sh b/definition-scripts/Goals.sh
new file mode 100644
index 000000000..835dd71b5
--- /dev/null
+++ b/definition-scripts/Goals.sh
@@ -0,0 +1,52 @@
+curl -L -X POST '{{host}}/object/category/definition/v4/create' \
+-H 'Content-Type: application/json' \
+--data-raw {
+ "request": {
+ "objectCategoryDefinition": {
+ "categoryId": "obj-cat:goals",
+ "targetObjectType": "Collection",
+ "objectMetadata": {
+ "config": {},
+ "schema": {
+ "properties": {
+ "visibility": {
+ "type": "string",
+ "enum": [
+ "Default",
+ "Parent",
+ "Private"
+ ],
+ "default": "Private"
+ },
+ "trackable": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "string",
+ "enum": [
+ "Yes",
+ "No"
+ ],
+ "default": "Yes"
+ },
+ "autoBatch": {
+ "type": "string",
+ "enum": [
+ "Yes",
+ "No"
+ ],
+ "default": "Yes"
+ }
+ },
+ "default": {
+ "enabled": "Yes",
+ "autoBatch": "Yes"
+ },
+ "additionalProperties": false
+ }
+ }
+ }
+ }
+ }
+ }
+}'
From beaa8d82a312e1753f791f0c5368601bdde421d5 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 5 Apr 2021 18:46:27 +0530
Subject: [PATCH 02/53] Create Playlist.sh
---
definition-scripts/Playlist.sh | 52 ++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 definition-scripts/Playlist.sh
diff --git a/definition-scripts/Playlist.sh b/definition-scripts/Playlist.sh
new file mode 100644
index 000000000..6150ee430
--- /dev/null
+++ b/definition-scripts/Playlist.sh
@@ -0,0 +1,52 @@
+curl -L -X POST '{{host}}/object/category/definition/v4/create' \
+-H 'Content-Type: application/json' \
+--data-raw {
+ "request": {
+ "objectCategoryDefinition": {
+ "categoryId": "obj-cat:playlist",
+ "targetObjectType": "Collection",
+ "objectMetadata": {
+ "config": {},
+ "schema": {
+ "properties": {
+ "visibility": {
+ "type": "string",
+ "enum": [
+ "Default",
+ "Parent",
+ "Private"
+ ],
+ "default": "Private"
+ },
+ "trackable": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "string",
+ "enum": [
+ "Yes",
+ "No"
+ ],
+ "default": "Yes"
+ },
+ "autoBatch": {
+ "type": "string",
+ "enum": [
+ "Yes",
+ "No"
+ ],
+ "default": "Yes"
+ }
+ },
+ "default": {
+ "enabled": "Yes",
+ "autoBatch": "Yes"
+ },
+ "additionalProperties": false
+ }
+ }
+ }
+ }
+ }
+ }
+}'
From 16f0d4902ef984973995d52192c97d68b0959320 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 5 Apr 2021 18:47:50 +0530
Subject: [PATCH 03/53] Update master_category_create
---
definition-scripts/master_category_create | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/definition-scripts/master_category_create b/definition-scripts/master_category_create
index 93913a504..04aba02e9 100644
--- a/definition-scripts/master_category_create
+++ b/definition-scripts/master_category_create
@@ -9,6 +9,27 @@ curl --location --request POST '{{host}}/object/category/v4/create' \
}
}'
+curl --location --request POST '{{host}}/object/category/v4/create' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "request": {
+ "objectCategory": {
+ "name": "Playlist",
+ "description":"Playlist for Users"
+ }
+ }
+}'
+
+curl --location --request POST '{{host}}/object/category/v4/create' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "request": {
+ "objectCategory": {
+ "name": "Goals",
+ "description":"Goals for Users"
+ }
+ }
+}'
curl --location --request POST '{{host}}/object/category/v4/create' \
@@ -354,4 +375,4 @@ curl --location --request POST '{{host}}/object/category/v4/create' \
"description":"FTB Question"
}
}
-}'
\ No newline at end of file
+}'
From 5449bc5e094bd82af5af77b60e8f2f4068e0c53c Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 5 Apr 2021 18:53:43 +0530
Subject: [PATCH 04/53] Update schema.json
---
schemas/collection/1.0/schema.json | 48 ++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/schemas/collection/1.0/schema.json b/schemas/collection/1.0/schema.json
index a47722e68..acc1b2569 100644
--- a/schemas/collection/1.0/schema.json
+++ b/schemas/collection/1.0/schema.json
@@ -134,7 +134,8 @@
"type": "string",
"enum": [
"Default",
- "Parent"
+ "Parent",
+ "Private"
],
"default": "Default"
},
@@ -1068,6 +1069,49 @@
"me_totalRatingsCount": {
"type": "number"
},
+ "catalogPaths" : {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "competencies" : {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "sharedWith" : {
+ "type": "array"
+ },
+ "isExternal": {
+ "type": "boolean"
+ },
+ "learningMode": {
+ "type": "string",
+ "enum": [
+ "Self Paced",
+ "Instructor Led",
+ "Classroom"
+ ]
+ },
+ "creatorLogo" : {
+ "type": "string",
+ "format": "url"
+ },
+ "subTitles" : {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "reviewStatus" : {
+ "type" : "string",
+ "enum": [
+ "InReview",
+ "Reviewed"
+ ]
+ },
"boardIds": {
"type": "array",
"items": {
@@ -1204,4 +1248,4 @@
}
}
}
-}
\ No newline at end of file
+}
From 12e8f071fdce4ae759d5fc3b81cef07ceccef263 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Tue, 6 Apr 2021 12:02:31 +0530
Subject: [PATCH 05/53] Update schema.json
---
schemas/content/1.0/schema.json | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/schemas/content/1.0/schema.json b/schemas/content/1.0/schema.json
index f347f3a13..775e28e89 100644
--- a/schemas/content/1.0/schema.json
+++ b/schemas/content/1.0/schema.json
@@ -86,7 +86,8 @@
"audio/ogg",
"audio/webm",
"audio/x-wav",
- "audio/wav"
+ "audio/wav",
+ "application/json"
]
},
"osId": {
@@ -1304,4 +1305,4 @@
}
}
}
-}
\ No newline at end of file
+}
From 888250a76e244e0c609ae229ddec58b90ef8d635 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Tue, 6 Apr 2021 12:03:08 +0530
Subject: [PATCH 06/53] Update schema.json
---
schemas/asset/1.0/schema.json | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/schemas/asset/1.0/schema.json b/schemas/asset/1.0/schema.json
index ae73ccda4..36ed2fcf0 100644
--- a/schemas/asset/1.0/schema.json
+++ b/schemas/asset/1.0/schema.json
@@ -85,7 +85,8 @@
"audio/ogg",
"audio/webm",
"audio/x-wav",
- "audio/wav"
+ "audio/wav",
+ "application/json"
]
},
"osId": {
@@ -1247,4 +1248,4 @@
}
}
}
-}
\ No newline at end of file
+}
From 04845026b33d38d5ee9086092738728cc390234b Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Tue, 6 Apr 2021 12:14:05 +0530
Subject: [PATCH 07/53] Update schema.json
---
schemas/content/1.0/schema.json | 43 +++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/schemas/content/1.0/schema.json b/schemas/content/1.0/schema.json
index 775e28e89..7469e4ad7 100644
--- a/schemas/content/1.0/schema.json
+++ b/schemas/content/1.0/schema.json
@@ -1168,6 +1168,49 @@
},
"displayScore": {
"type": "boolean"
+ },
+ "catalogPaths" : {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "competencies" : {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "sharedWith" : {
+ "type": "array"
+ },
+ "isExternal": {
+ "type": "boolean"
+ },
+ "learningMode": {
+ "type": "string",
+ "enum": [
+ "Self Paced",
+ "Instructor Led",
+ "Classroom"
+ ]
+ },
+ "creatorLogo" : {
+ "type": "string",
+ "format": "url"
+ },
+ "subTitles" : {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "reviewStatus" : {
+ "type" : "string",
+ "enum": [
+ "InReview",
+ "Reviewed"
+ ]
},
"boardIds": {
"type": "array",
From f7e148cc2e711b47ee59ca77e4e8b67095e7e9c2 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 12 Apr 2021 19:42:50 +0530
Subject: [PATCH 08/53] Update pom.xml
---
platform-modules/mimetype-manager/pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/platform-modules/mimetype-manager/pom.xml b/platform-modules/mimetype-manager/pom.xml
index 9241f53e7..c58b6a748 100644
--- a/platform-modules/mimetype-manager/pom.xml
+++ b/platform-modules/mimetype-manager/pom.xml
@@ -30,7 +30,7 @@
org.sunbird
cloud-store-sdk
- 1.2.8
+ 1.3.0
org.scala-lang
@@ -143,4 +143,4 @@
-
\ No newline at end of file
+
From c7088464bdf95bf4145c8b5f78b5ae1608c229dd Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 12 Apr 2021 19:44:03 +0530
Subject: [PATCH 09/53] Update StorageService.scala
---
.../scala/org/sunbird/cloudstore/StorageService.scala | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/platform-modules/mimetype-manager/src/main/scala/org/sunbird/cloudstore/StorageService.scala b/platform-modules/mimetype-manager/src/main/scala/org/sunbird/cloudstore/StorageService.scala
index 4c9b69afc..8a610dfa4 100644
--- a/platform-modules/mimetype-manager/src/main/scala/org/sunbird/cloudstore/StorageService.scala
+++ b/platform-modules/mimetype-manager/src/main/scala/org/sunbird/cloudstore/StorageService.scala
@@ -28,7 +28,15 @@ class StorageService {
val storageKey = Platform.config.getString("aws_storage_key")
val storageSecret = Platform.config.getString("aws_storage_secret")
storageService = StorageServiceFactory.getStorageService(new StorageConfig(storageType, storageKey, storageSecret))
- } else throw new ServerException("ERR_INVALID_CLOUD_STORAGE", "Error while initialising cloud storage")
+ } else if (StringUtils.equalsIgnoreCase(storageType, "cephs3")) {
+ val storageKey = Platform.config.getString("cephs3_storage_key")
+ val storageSecret = Platform.config.getString("cephs3_storage_secret")
+ val endpoint = Platform.config.getString("cephs3_storage_endpoint")
+ storageService = StorageServiceFactory.getStorageService(new StorageConfig(storageType, storageKey, storageSecret, Option(endpoint)))
+
+ }
+
+ else throw new ServerException("ERR_INVALID_CLOUD_STORAGE", "Error while initialising cloud storage")
}
storageService
}
From 127a62b9d5bb7f3e881c29655a4d475b007d3192 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 12 Apr 2021 19:44:31 +0530
Subject: [PATCH 10/53] Update StorageService.scala
---
.../src/main/scala/org/sunbird/cloudstore/StorageService.scala | 2 ++
1 file changed, 2 insertions(+)
diff --git a/platform-modules/mimetype-manager/src/main/scala/org/sunbird/cloudstore/StorageService.scala b/platform-modules/mimetype-manager/src/main/scala/org/sunbird/cloudstore/StorageService.scala
index 8a610dfa4..80ed58c42 100644
--- a/platform-modules/mimetype-manager/src/main/scala/org/sunbird/cloudstore/StorageService.scala
+++ b/platform-modules/mimetype-manager/src/main/scala/org/sunbird/cloudstore/StorageService.scala
@@ -46,6 +46,8 @@ class StorageService {
Platform.config.getString("azure_storage_container")
else if (StringUtils.equalsIgnoreCase(storageType, "aws"))
Platform.config.getString("aws_storage_container")
+ else if (StringUtils.equalsIgnoreCase(storageType, "cephs3"))
+ Platform.config.getString("cephs3_storage_container")
else
throw new ServerException("ERR_INVALID_CLOUD_STORAGE", "Container name not configured.")
}
From 81cf617360b5398cbd7aacca056259f46d686639 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 12 Apr 2021 19:45:18 +0530
Subject: [PATCH 11/53] Update XmlParser.scala
---
.../scala/org/sunbird/mimetype/ecml/processor/XmlParser.scala | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platform-modules/mimetype-manager/src/main/scala/org/sunbird/mimetype/ecml/processor/XmlParser.scala b/platform-modules/mimetype-manager/src/main/scala/org/sunbird/mimetype/ecml/processor/XmlParser.scala
index 3f5453c3f..1181f0bb7 100644
--- a/platform-modules/mimetype-manager/src/main/scala/org/sunbird/mimetype/ecml/processor/XmlParser.scala
+++ b/platform-modules/mimetype-manager/src/main/scala/org/sunbird/mimetype/ecml/processor/XmlParser.scala
@@ -1,6 +1,6 @@
package org.sunbird.mimetype.ecml.processor
-import org.apache.commons.lang.{StringEscapeUtils, StringUtils}
+import org.apache.commons.lang3.{StringEscapeUtils, StringUtils}
import org.sunbird.common.exception.ClientException
import scala.collection.mutable.ListBuffer
From ac4e4c8ec451195a7c1fc3163a167527d3800523 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 12 Apr 2021 19:46:04 +0530
Subject: [PATCH 12/53] Update H5PMimeTypeMgrImpl.scala
---
.../org/sunbird/mimetype/mgr/impl/H5PMimeTypeMgrImpl.scala | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platform-modules/mimetype-manager/src/main/scala/org/sunbird/mimetype/mgr/impl/H5PMimeTypeMgrImpl.scala b/platform-modules/mimetype-manager/src/main/scala/org/sunbird/mimetype/mgr/impl/H5PMimeTypeMgrImpl.scala
index 01e7fcf57..ee7e7a7bb 100644
--- a/platform-modules/mimetype-manager/src/main/scala/org/sunbird/mimetype/mgr/impl/H5PMimeTypeMgrImpl.scala
+++ b/platform-modules/mimetype-manager/src/main/scala/org/sunbird/mimetype/mgr/impl/H5PMimeTypeMgrImpl.scala
@@ -3,7 +3,7 @@ package org.sunbird.mimetype.mgr.impl
import java.io.File
import java.util.concurrent.CompletionException
-import org.apache.hadoop.util.StringUtils
+import org.apache.commons.lang3.StringUtils
import org.sunbird.models.UploadParams
import org.sunbird.cloudstore.StorageService
import org.sunbird.common.Slug
From 741c1b2deb61c708b9d3f0ff0da4a5f68dbb9e48 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 12 Apr 2021 19:47:39 +0530
Subject: [PATCH 13/53] Update schema.json
---
schemas/content/1.0/schema.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/schemas/content/1.0/schema.json b/schemas/content/1.0/schema.json
index 7469e4ad7..ca889a75c 100644
--- a/schemas/content/1.0/schema.json
+++ b/schemas/content/1.0/schema.json
@@ -87,7 +87,8 @@
"audio/webm",
"audio/x-wav",
"audio/wav",
- "application/json"
+ "application/json",
+ "application/quiz"
]
},
"osId": {
From 14088eaf59242153c4af190b0017f02e2d89688d Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Mon, 19 Apr 2021 12:39:15 +0530
Subject: [PATCH 14/53] Update pom.xml
---
platform-modules/mimetype-manager/pom.xml | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/platform-modules/mimetype-manager/pom.xml b/platform-modules/mimetype-manager/pom.xml
index c58b6a748..9f609b0e2 100644
--- a/platform-modules/mimetype-manager/pom.xml
+++ b/platform-modules/mimetype-manager/pom.xml
@@ -13,8 +13,22 @@
2.11
2.7.2
-
+
+
+ cloud-store-sdk_1.3.1-beta
+ cloud-store-sdk_1.3.1-beta
+ https://oss.sonatype.org/content/repositories/orgsunbird-1104/
+
+ false
+
+
+
+
+ org.sunbird
+ cloud-store-sdk
+ 1.3.1-beta
+
org.sunbird
platform-common
From 16df195c13524c46f45b8e5a58962a4ce4db058e Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Thu, 25 Feb 2021 13:15:55 +0530
Subject: [PATCH 15/53] SC-2226 Event and EventSet APIs
---
.../sunbird/content/actors/ContentActor.scala | 18 +-
.../sunbird/content/actors/EventActor.scala | 49 ++++
.../content/actors/EventSetActor.scala | 144 ++++++++++
.../content/util/ContentConstants.scala | 1 +
.../controllers/v4/ContentController.scala | 10 +-
.../app/controllers/v4/EventController.scala | 43 +++
.../controllers/v4/EventSetController.scala | 52 ++++
.../app/modules/ContentModule.scala | 4 +-
.../app/utils/ActorNames.scala | 2 +
.../content-service/app/utils/ApiId.scala | 6 +
.../content-service/app/utils/Constants.scala | 1 +
.../content-service/conf/application.conf | 8 +-
content-api/content-service/conf/routes | 14 +
.../test/controllers/v4/EventSetSpec.scala | 93 +++++++
.../test/modules/TestModule.scala | 1 +
.../sunbird/utils/HierarchyConstants.scala | 1 +
.../src/test/resources/application.conf | 2 +-
.../schema/impl/CustomProblemHandler.java | 7 +
schemas/event/1.0/config.json | 62 +++++
schemas/event/1.0/schema.json | 244 +++++++++++++++++
schemas/eventSet/1.0/config.json | 33 +++
schemas/eventSet/1.0/schema.json | 252 ++++++++++++++++++
22 files changed, 1031 insertions(+), 16 deletions(-)
create mode 100644 content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala
create mode 100644 content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
create mode 100644 content-api/content-service/app/controllers/v4/EventController.scala
create mode 100644 content-api/content-service/app/controllers/v4/EventSetController.scala
create mode 100644 content-api/content-service/test/controllers/v4/EventSetSpec.scala
create mode 100644 schemas/event/1.0/config.json
create mode 100644 schemas/event/1.0/schema.json
create mode 100644 schemas/eventSet/1.0/config.json
create mode 100644 schemas/eventSet/1.0/schema.json
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/ContentActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/ContentActor.scala
index 76bb16b5d..743d93e4d 100644
--- a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/ContentActor.scala
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/ContentActor.scala
@@ -3,20 +3,20 @@ package org.sunbird.content.actors
import java.util
import java.util.concurrent.CompletionException
import java.io.File
-
import org.apache.commons.io.FilenameUtils
+
import javax.inject.Inject
import org.apache.commons.lang3.StringUtils
import org.sunbird.actor.core.BaseActor
import org.sunbird.cache.impl.RedisCache
-import org.sunbird.content.util.{AcceptFlagManager, CopyManager, DiscardManager, FlagManager, RetireManager}
+import org.sunbird.content.util.{AcceptFlagManager, ContentConstants, CopyManager, DiscardManager, FlagManager, RetireManager}
import org.sunbird.cloudstore.StorageService
import org.sunbird.common.{ContentParams, Platform, Slug}
import org.sunbird.common.dto.{Request, Response, ResponseHandler}
import org.sunbird.common.exception.ClientException
import org.sunbird.content.dial.DIALManager
import org.sunbird.content.mgr.ImportManager
-import org.sunbird.util. RequestUtil
+import org.sunbird.util.RequestUtil
import org.sunbird.content.upload.mgr.UploadManager
import org.sunbird.graph.OntologyEngineContext
import org.sunbird.graph.dac.model.Node
@@ -61,13 +61,19 @@ class ContentActor @Inject() (implicit oec: OntologyEngineContext, ss: StorageSe
}
def read(request: Request): Future[Response] = {
+ val responseSchemaName: String = request.getContext.getOrDefault(ContentConstants.RESPONSE_SCHEMA_NAME, "").asInstanceOf[String]
val fields: util.List[String] = JavaConverters.seqAsJavaListConverter(request.get("fields").asInstanceOf[String].split(",").filter(field => StringUtils.isNotBlank(field) && !StringUtils.equalsIgnoreCase(field, "null"))).asJava
request.getRequest.put("fields", fields)
DataNode.read(request).map(node => {
val metadata: util.Map[String, AnyRef] = NodeUtil.serialize(node, fields, node.getObjectType.toLowerCase.replace("image", ""), request.getContext.get("version").asInstanceOf[String])
metadata.put("identifier", node.getIdentifier.replace(".img", ""))
val response: Response = ResponseHandler.OK
- response.put("content", metadata)
+ if (responseSchemaName.isEmpty) {
+ response.put("content", metadata)
+ }
+ else {
+ response.put(responseSchemaName, metadata)
+ }
response
})
}
@@ -187,9 +193,9 @@ class ContentActor @Inject() (implicit oec: OntologyEngineContext, ss: StorageSe
if(StringUtils.isNotBlank(filePath) && filePath.size > 100)
throw new ClientException("ERR_CONTENT_INVALID_FILE_PATH", "Please provide valid filepath of character length 100 or Less ")
}
-
+
def dataModifier(node: Node): Node = {
- if(node.getMetadata.containsKey("trackable") &&
+ if(node.getMetadata.containsKey("trackable") &&
node.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].containsKey("enabled") &&
"Yes".equalsIgnoreCase(node.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].getOrDefault("enabled", "").asInstanceOf[String])) {
node.getMetadata.put("contentType", "Course")
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala
new file mode 100644
index 000000000..1c33f3b5c
--- /dev/null
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala
@@ -0,0 +1,49 @@
+package org.sunbird.content.actors
+
+import org.sunbird.cloudstore.StorageService
+import org.sunbird.common.dto.{Request, Response, ResponseHandler}
+import org.sunbird.common.exception.ResponseCode
+import org.sunbird.graph.OntologyEngineContext
+import org.sunbird.graph.dac.model.{Node, Relation}
+import org.sunbird.graph.nodes.DataNode
+
+import java.util
+import javax.inject.Inject
+import scala.collection.JavaConverters.asScalaBufferConverter
+import scala.concurrent.Future
+
+class EventActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageService) extends ContentActor {
+
+ override def dataModifier(node: Node): Node = {
+ if(node.getMetadata.containsKey("trackable") &&
+ node.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].containsKey("enabled") &&
+ "Yes".equalsIgnoreCase(node.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].getOrDefault("enabled", "").asInstanceOf[String])) {
+ node.getMetadata.put("contentType", "Event")
+ }
+ node
+ }
+
+ override def update(request: Request): Future[Response] = {
+ verifyStandaloneEventAndApply(super.update, request)
+ }
+
+ override def discard(request: Request): Future[Response] = {
+ verifyStandaloneEventAndApply(super.discard, request)
+ }
+
+ override def retire(request: Request): Future[Response] = {
+ verifyStandaloneEventAndApply(super.retire, request)
+ }
+
+ private def verifyStandaloneEventAndApply(f: Request => Future[Response], request: Request):Future[Response] = {
+ DataNode.read(request).flatMap(node => {
+ val inRelations = if (node.getInRelations == null) new util.ArrayList[Relation]() else node.getInRelations;
+ val hasEventSetParent = inRelations.asScala.exists(rel => "EventSet".equalsIgnoreCase(rel.getStartNodeObjectType))
+ if (hasEventSetParent)
+ Future(ResponseHandler.ERROR(ResponseCode.CLIENT_ERROR, ResponseCode.CLIENT_ERROR.name(), "ERROR: Can't modify an Event which is part of an Event Set!"))
+ else
+ f.apply(request)
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
new file mode 100644
index 000000000..9e1541969
--- /dev/null
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
@@ -0,0 +1,144 @@
+package org.sunbird.content.actors
+
+import org.apache.commons.lang3.StringUtils
+import org.sunbird.cloudstore.StorageService
+import org.sunbird.common.dto.{Request, Response, ResponseHandler}
+import org.sunbird.common.exception.{ClientException, ResponseCode}
+import org.sunbird.graph.OntologyEngineContext
+import org.sunbird.graph.common.enums.SystemProperties
+import org.sunbird.graph.dac.model.{Node, Relation}
+import org.sunbird.graph.nodes.DataNode
+import org.sunbird.graph.utils.NodeUtil
+import org.sunbird.util.RequestUtil
+import org.sunbird.utils.HierarchyConstants
+
+import java.util
+import javax.inject.Inject
+import scala.collection.JavaConverters._
+import scala.concurrent.Future
+
+class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageService) extends ContentActor {
+
+ override def onReceive(request: Request): Future[Response] = {
+ request.getContext.put(HierarchyConstants.SCHEMA_NAME, HierarchyConstants.EVENT_SET_SCHEMA_NAME)
+ request.getOperation match {
+ case "createContent" => create(request)
+ case "updateContent" => update(request)
+ case "getHierarchy" => getHierarchy(request)
+ case "readContent" => read(request)
+ case "retireContent" => retire(request)
+ case "discardContent" => discard(request)
+ case _ => ERROR(request.getOperation)
+ }
+ }
+
+ override def create(request: Request): Future[Response] = {
+ RequestUtil.restrictProperties(request)
+ val originalRequestContent = request.getRequest
+ addChildEvents(request)
+ .map(nodes => updateRequestWithChildRelations(request, originalRequestContent, nodes))
+ .flatMap(req => {
+ DataNode.create(req).map(node => {
+ val response = ResponseHandler.OK
+ response.put("identifier", node.getIdentifier)
+ response.put("node_id", node.getIdentifier)
+ response.put("versionKey", node.getMetadata.get("versionKey"))
+ response
+ })
+ }).recoverWith {
+ case e: Exception =>
+ Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
+ }
+ }
+
+ override def update(request: Request): Future[Response] = {
+ if (StringUtils.isBlank(request.getRequest.getOrDefault("versionKey", "").asInstanceOf[String])) throw new ClientException("ERR_INVALID_REQUEST", "Please Provide Version Key!")
+ RequestUtil.restrictProperties(request)
+ val originalRequestContent = request.getRequest
+ DataNode.read(request).flatMap(node => {
+ deleteExistingEvents(node.getOutRelations, request).flatMap(_ => {
+ addChildEvents(request).map(nodes => {
+ updateRequestWithChildRelations(request, originalRequestContent, nodes)
+ }).flatMap(req =>
+ DataNode.update(req).map(node => {
+ val response: Response = ResponseHandler.OK
+ val identifier: String = node.getIdentifier.replace(".img", "")
+ response.put("node_id", identifier)
+ response.put("identifier", identifier)
+ response.put("versionKey", node.getMetadata.get("versionKey"))
+ response
+ })
+ )
+ })
+ }).recoverWith {
+ case e: Exception =>
+ Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
+ }
+ }
+
+ def getHierarchy(request: Request): Future[Response] = {
+ DataNode.read(request).map(node => {
+ val outRelations = if (node.getOutRelations == null) List[Relation]() else node.getOutRelations.asScala
+ val childNodes = outRelations.map(relation => relation.getEndNodeId).toList
+ val children = outRelations.map(relation => relation.getEndNodeMetadata).map(metadata => {
+ SystemProperties.values().foreach(value => metadata.remove(value.name()))
+ metadata
+ }).toList
+
+ val metadata: util.Map[String, AnyRef] = NodeUtil.serialize(node, new util.ArrayList[String](), node.getObjectType.toLowerCase.replace("image", ""), request.getContext.get("version").asInstanceOf[String], true)
+ metadata.put("identifier", node.getIdentifier.replace(".img", ""))
+ metadata.put("childNodes", childNodes.asJava)
+ metadata.put("children", children.asJava)
+ val response: Response = ResponseHandler.OK
+ response.put("eventSet", metadata)
+ response
+ })
+ }
+
+ private def updateRequestWithChildRelations(request: Request, originalRequestContent: util.Map[String, AnyRef], nodes: List[Node]) = {
+ request.setRequest(originalRequestContent)
+ val relations = new util.ArrayList[util.Map[String, String]]()
+ nodes.foreach(node => {
+ relations.add(Map("identifier" -> node.getIdentifier).asJava)
+ })
+ request.getRequest.put("collections", relations)
+ request
+ }
+
+ private def addChildEvents(request: Request) = {
+ val newChildEvents = formChildEvents(request)
+ Future.sequence(newChildEvents.map(childEvent => {
+ val childRequest = new Request(request)
+ childRequest.setRequest(childEvent.asJava)
+ childRequest.getContext.put("schemaName", "event")
+ childRequest.getContext.put("objectType", "Event")
+ DataNode.create(childRequest)
+ }))
+ }
+
+ private def formChildEvents(contentRequest: Request): List[collection.mutable.Map[String, AnyRef]] = {
+ val scheduleObject = contentRequest.getRequest.getOrDefault("schedule", new util.HashMap[String, Object]()).asInstanceOf[util.Map[String, Object]]
+ val schedules = scheduleObject.getOrDefault("value", new util.ArrayList[util.Map[String, String]]()).asInstanceOf[util.List[util.Map[String, String]]].asScala
+ schedules.map(schedule => {
+ var event = collection.mutable.Map[String, AnyRef]() ++ contentRequest.getRequest.asScala
+ event ++= schedule.asScala
+ event -= "schedule"
+ event -= "identifier"
+ event
+ }).toList
+ }
+
+ private def deleteExistingEvents(relations: util.List[Relation], request: Request) = {
+ if (relations != null)
+ Future.sequence(relations.asScala.filter(rel => "Event".equalsIgnoreCase(rel.getEndNodeObjectType)).map(relation => {
+ val deleteReq = new Request()
+ deleteReq.setContext(request.getContext)
+ val delMap = new util.HashMap[String, AnyRef]()
+ delMap.put("identifier", relation.getEndNodeId)
+ deleteReq.setRequest(delMap)
+ DataNode.deleteNode(deleteReq)
+ }))
+ else
+ Future(List())
+ }
+}
\ No newline at end of file
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/util/ContentConstants.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/util/ContentConstants.scala
index ba5e71cde..29889d0eb 100644
--- a/content-api/content-actors/src/main/scala/org/sunbird/content/util/ContentConstants.scala
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/util/ContentConstants.scala
@@ -10,6 +10,7 @@ object ContentConstants {
val MIME_TYPE: String = "mimeType"
val CONTENT_SCHEMA_NAME: String = "content"
val SCHEMA_NAME: String = "schemaName"
+ val RESPONSE_SCHEMA_NAME: String = "responseSchemaName"
val SCHEMA_VERSION: String = "1.0"
val ARTIFACT_URL: String = "artifactUrl"
val IDENTIFIER: String = "identifier"
diff --git a/content-api/content-service/app/controllers/v4/ContentController.scala b/content-api/content-service/app/controllers/v4/ContentController.scala
index 3262c8b94..b01915009 100644
--- a/content-api/content-service/app/controllers/v4/ContentController.scala
+++ b/content-api/content-service/app/controllers/v4/ContentController.scala
@@ -24,7 +24,7 @@ class ContentController @Inject()(@Named(ActorNames.CONTENT_ACTOR) contentActor:
def create() = Action.async { implicit request =>
val headers = commonHeaders()
val body = requestBody()
- val content = body.getOrDefault("content", new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]];
+ val content = body.getOrDefault(schemaName, new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]];
content.putAll(headers)
if(!validatePrimaryCategory(content))
getErrorResponse(ApiId.CREATE_CONTENT, apiVersion, "VALIDATION_ERROR", "primaryCategory is a mandatory parameter")
@@ -61,7 +61,7 @@ class ContentController @Inject()(@Named(ActorNames.CONTENT_ACTOR) contentActor:
def update(identifier: String) = Action.async { implicit request =>
val headers = commonHeaders()
val body = requestBody()
- val content = body.getOrDefault("content", new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]];
+ val content = body.getOrDefault(schemaName, new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]];
content.putAll(headers)
val contentRequest = getRequest(content, headers, "updateContent")
setRequestContext(contentRequest, version, objectType, schemaName)
@@ -104,7 +104,7 @@ class ContentController @Inject()(@Named(ActorNames.CONTENT_ACTOR) contentActor:
def retire(identifier: String) = Action.async { implicit request =>
val headers = commonHeaders()
val body = requestBody()
- val content = body.getOrDefault("content", new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]]
+ val content = body.getOrDefault(schemaName, new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]]
content.put("identifier", identifier)
content.putAll(headers)
val contentRequest = getRequest(content, headers, "retireContent")
@@ -136,7 +136,7 @@ class ContentController @Inject()(@Named(ActorNames.CONTENT_ACTOR) contentActor:
def copy(identifier: String, mode: Option[String], copyType: String) = Action.async { implicit request =>
val headers = commonHeaders()
val body = requestBody()
- val content = body.getOrDefault("content", new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]]
+ val content = body.getOrDefault(schemaName, new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]]
content.putAll(headers)
content.putAll(Map("identifier" -> identifier, "mode" -> mode.getOrElse(""), "copyType" -> copyType).asJava)
val contentRequest = getRequest(content, headers, "copy")
@@ -147,7 +147,7 @@ class ContentController @Inject()(@Named(ActorNames.CONTENT_ACTOR) contentActor:
def uploadPreSigned(identifier: String, `type`: Option[String])= Action.async { implicit request =>
val headers = commonHeaders()
val body = requestBody()
- val content = body.getOrDefault("content", new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]]
+ val content = body.getOrDefault(schemaName, new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]]
content.putAll(headers)
content.putAll(Map("identifier" -> identifier, "type" -> `type`.getOrElse("assets")).asJava)
val contentRequest = getRequest(content, headers, "uploadPreSignedUrl")
diff --git a/content-api/content-service/app/controllers/v4/EventController.scala b/content-api/content-service/app/controllers/v4/EventController.scala
new file mode 100644
index 000000000..5c555e216
--- /dev/null
+++ b/content-api/content-service/app/controllers/v4/EventController.scala
@@ -0,0 +1,43 @@
+package controllers.v4
+
+import akka.actor.{ActorRef, ActorSystem}
+import com.google.inject.Singleton
+import play.api.mvc.ControllerComponents
+import utils.{ActorNames, ApiId, Constants}
+
+import javax.inject.{Inject, Named}
+import scala.collection.JavaConverters.mapAsJavaMapConverter
+import scala.concurrent.ExecutionContext
+
+@Singleton
+class EventController @Inject()(@Named(ActorNames.EVENT_ACTOR) contentActor: ActorRef, cc: ControllerComponents, actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends ContentController(contentActor, cc, actorSystem) {
+
+ override val objectType = "Event"
+ override val schemaName: String = "event"
+
+ override def create() = Action.async { implicit request =>
+ val headers = commonHeaders()
+ val body = requestBody()
+ val content = body.getOrDefault(schemaName, new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]];
+ content.putAll(headers)
+ if(validateContentType(content))
+ getErrorResponse(ApiId.CREATE_EVENT, apiVersion, "VALIDATION_ERROR", "contentType cannot be set from request.")
+ else {
+ val contentRequest = getRequest(content, headers, "createContent", false)
+ setRequestContext(contentRequest, version, objectType, schemaName)
+ getResult(ApiId.CREATE_EVENT, contentActor, contentRequest, version = apiVersion)
+ }
+ }
+
+ override def read(identifier: String, mode: Option[String], fields: Option[String]) = Action.async { implicit request =>
+ val headers = commonHeaders()
+ val content = new java.util.HashMap[String, Object]()
+ content.putAll(headers)
+ content.putAll(Map("identifier" -> identifier, "mode" -> mode.getOrElse("read"), "fields" -> fields.getOrElse("")).asJava)
+ val readRequest = getRequest(content, headers, "readContent")
+ setRequestContext(readRequest, version, objectType, schemaName)
+ readRequest.getContext.put(Constants.RESPONSE_SCHEMA_NAME, schemaName);
+ getResult(ApiId.READ_CONTENT, contentActor, readRequest, version = apiVersion)
+ }
+
+}
\ No newline at end of file
diff --git a/content-api/content-service/app/controllers/v4/EventSetController.scala b/content-api/content-service/app/controllers/v4/EventSetController.scala
new file mode 100644
index 000000000..17db13a83
--- /dev/null
+++ b/content-api/content-service/app/controllers/v4/EventSetController.scala
@@ -0,0 +1,52 @@
+package controllers.v4
+
+import akka.actor.{ActorRef, ActorSystem}
+import com.google.inject.Singleton
+import play.api.mvc.ControllerComponents
+import utils.{ActorNames, ApiId, Constants}
+
+import javax.inject.{Inject, Named}
+import scala.collection.JavaConverters.mapAsJavaMapConverter
+import scala.concurrent.ExecutionContext
+
+@Singleton
+class EventSetController @Inject()(@Named(ActorNames.EVENT_SET_ACTOR) eventSetActor: ActorRef, cc: ControllerComponents, actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends CollectionController(eventSetActor, eventSetActor, cc, actorSystem) {
+ override val objectType = "EventSet"
+ override val schemaName: String = "eventSet"
+
+ override def create() = Action.async { implicit request =>
+ val headers = commonHeaders()
+ val body = requestBody()
+ val content = body.getOrDefault(schemaName, new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]]
+ content.putAll(headers)
+ if(validateContentType(content))
+ getErrorResponse(ApiId.CREATE_EVENT_SET, apiVersion, "VALIDATION_ERROR", "contentType cannot be set from request.")
+ else {
+ val contentRequest = getRequest(content, headers, "createContent", false)
+ setRequestContext(contentRequest, version, objectType, schemaName)
+ getResult(ApiId.CREATE_EVENT_SET, eventSetActor, contentRequest, version = apiVersion)
+ }
+ }
+
+ override def read(identifier: String, mode: Option[String], fields: Option[String]) = Action.async { implicit request =>
+ val headers = commonHeaders()
+ val content = new java.util.HashMap().asInstanceOf[java.util.Map[String, Object]]
+ content.putAll(headers)
+ content.putAll(Map("identifier" -> identifier, "mode" -> mode.getOrElse("read"), "fields" -> fields.getOrElse("")).asJava)
+ val readRequest = getRequest(content, headers, "readContent")
+ setRequestContext(readRequest, version, objectType, schemaName)
+ readRequest.getContext.put(Constants.RESPONSE_SCHEMA_NAME, schemaName);
+ getResult(ApiId.READ_COLLECTION, eventSetActor, readRequest, version = apiVersion)
+ }
+
+ override def getHierarchy(identifier: String, mode: Option[String]) = Action.async { implicit request =>
+ val headers = commonHeaders()
+ val content = new java.util.HashMap().asInstanceOf[java.util.Map[String, Object]]
+ content.putAll(headers)
+ content.putAll(Map("identifier" -> identifier, "mode" -> mode.getOrElse("read")).asJava)
+ val readRequest = getRequest(content, headers, "getHierarchy")
+ setRequestContext(readRequest, version, objectType, schemaName)
+ getResult(ApiId.READ_COLLECTION, eventSetActor, readRequest, version = apiVersion)
+ }
+
+}
\ No newline at end of file
diff --git a/content-api/content-service/app/modules/ContentModule.scala b/content-api/content-service/app/modules/ContentModule.scala
index dc0d517a0..b7390bf72 100644
--- a/content-api/content-service/app/modules/ContentModule.scala
+++ b/content-api/content-service/app/modules/ContentModule.scala
@@ -2,7 +2,7 @@ package modules
import com.google.inject.AbstractModule
import org.sunbird.channel.actors.ChannelActor
-import org.sunbird.content.actors.{AssetActor, CategoryActor, CollectionActor, ContentActor, HealthActor, LicenseActor}
+import org.sunbird.content.actors.{AssetActor, CategoryActor, CollectionActor, ContentActor, EventActor, EventSetActor, HealthActor, LicenseActor}
import play.libs.akka.AkkaGuiceSupport
import utils.ActorNames
@@ -15,6 +15,8 @@ class ContentModule extends AbstractModule with AkkaGuiceSupport {
bindActor(classOf[ContentActor], ActorNames.CONTENT_ACTOR)
bindActor(classOf[LicenseActor], ActorNames.LICENSE_ACTOR)
bindActor(classOf[CollectionActor], ActorNames.COLLECTION_ACTOR)
+ bindActor(classOf[EventActor], ActorNames.EVENT_ACTOR)
+ bindActor(classOf[EventSetActor], ActorNames.EVENT_SET_ACTOR)
bindActor(classOf[ChannelActor], ActorNames.CHANNEL_ACTOR)
bindActor(classOf[CategoryActor], ActorNames.CATEGORY_ACTOR)
bindActor(classOf[AssetActor], ActorNames.ASSET_ACTOR)
diff --git a/content-api/content-service/app/utils/ActorNames.scala b/content-api/content-service/app/utils/ActorNames.scala
index fdf32915b..9b53d74c7 100644
--- a/content-api/content-service/app/utils/ActorNames.scala
+++ b/content-api/content-service/app/utils/ActorNames.scala
@@ -6,6 +6,8 @@ object ActorNames {
final val CONTENT_ACTOR = "contentActor"
final val LICENSE_ACTOR = "licenseActor"
final val COLLECTION_ACTOR = "collectionActor"
+ final val EVENT_ACTOR = "eventActor"
+ final val EVENT_SET_ACTOR = "eventSetActor"
final val CHANNEL_ACTOR = "channelActor"
final val CATEGORY_ACTOR = "categoryActor"
final val ASSET_ACTOR = "assetActor"
diff --git a/content-api/content-service/app/utils/ApiId.scala b/content-api/content-service/app/utils/ApiId.scala
index b6a92f44d..0790da953 100644
--- a/content-api/content-service/app/utils/ApiId.scala
+++ b/content-api/content-service/app/utils/ApiId.scala
@@ -69,4 +69,10 @@ object ApiId {
val UPDATE_HIERARCHY_V4 = "api.collection.hierarchy.update"
val GET_HIERARCHY_V4 = "api.collection.hierarchy.get"
+ val CREATE_EVENT = "api.event.create"
+ val UPDATE_EVENT = "api.event.update"
+
+ val CREATE_EVENT_SET = "api.eventSet.create"
+ val UPDATE_EVENT_SET = "api.eventSet.update"
+
}
diff --git a/content-api/content-service/app/utils/Constants.scala b/content-api/content-service/app/utils/Constants.scala
index 02396549c..b10c214e5 100644
--- a/content-api/content-service/app/utils/Constants.scala
+++ b/content-api/content-service/app/utils/Constants.scala
@@ -2,6 +2,7 @@ package utils
object Constants {
val SCHEMA_NAME: String = "schemaName"
+ val RESPONSE_SCHEMA_NAME: String = "responseSchemaName"
val VERSION: String = "version"
val CONTENT_SCHEMA_NAME: String = "content"
val COLLECTION_SCHEMA_NAME: String = "collection"
diff --git a/content-api/content-service/conf/application.conf b/content-api/content-service/conf/application.conf
index a9583f0d1..096ec7650 100644
--- a/content-api/content-service/conf/application.conf
+++ b/content-api/content-service/conf/application.conf
@@ -352,7 +352,7 @@ collection.keyspace = "hierarchy_store"
content.keyspace = "content_store"
# Learning-Service Configuration
-content.metadata.visibility.parent=["textbookunit", "courseunit", "lessonplanunit"]
+content.metadata.visibility.parent=["textbookunit", "courseunit", "lessonplanunit", "event"]
# Cassandra Configuration
//content.keyspace.name=content_store
@@ -596,6 +596,8 @@ contentTypeToPrimaryCategory {
Course: ["Course", "Curriculum Course", "Professional Development Course"]
CuriosityQuestionSet: "Practice Question Set"
eTextBook: "eTextbook"
+ Event: "Event"
+ EventSet: "Event Set"
ExperientialResource: "Learning Resource"
ExplanationResource: "Explanation Content"
ExplanationVideo: "Explanation Content"
@@ -653,11 +655,11 @@ mimeTypeToPrimaryCategory {
channel {
content{
- primarycategories=["Course Assessment", "eTextbook", "Explanation Content", "Learning Resource", "Practice Question Set", "Teacher Resource"]
+ primarycategories=["Course Assessment", "Event", "eTextbook", "Explanation Content", "Learning Resource", "Practice Question Set", "Teacher Resource"]
additionalcategories=["Classroom Teaching Video", "Concept Map", "Curiosity Question Set", "Experiential Resource", "Explanation Video", "Focus Spot", "Learning Outcome Definition", "Lesson Plan", "Marking Scheme Rubric", "Pedagogy Flow", "Previous Board Exam Papers", "TV Lesson", "Textbook"]
}
collection {
- primarycategories=["Content Playlist", "Course", "Digital Textbook", "Explanation Content"]
+ primarycategories=["Content Playlist", "Course", "Digital Textbook", "Explanation Content", "Event Set"]
additionalcategories=["Textbook", "Lesson Plan", "TV Lesson"]
}
asset {
diff --git a/content-api/content-service/conf/routes b/content-api/content-service/conf/routes
index 1ddbbfb0a..a8a24890d 100644
--- a/content-api/content-service/conf/routes
+++ b/content-api/content-service/conf/routes
@@ -94,3 +94,17 @@ POST /content/v4/flag/accept/:identifier controllers.v4.ContentControl
DELETE /content/v4/discard/:identifier controllers.v4.ContentController.discard(identifier:String)
DELETE /content/v4/retire/:identifier controllers.v4.ContentController.retire(identifier:String)
+# Event APIs
+POST /event/v4/create controllers.v4.EventController.create
+PATCH /event/v4/update/:identifier controllers.v4.EventController.update(identifier:String)
+GET /event/v4/read/:identifier controllers.v4.EventController.read(identifier:String, mode:Option[String], fields:Option[String])
+DELETE /private/event/v4/discard/:identifier controllers.v4.EventController.discard(identifier:String)
+DELETE /event/v4/retire/:identifier controllers.v4.EventController.retire(identifier:String)
+
+# EventSet v4 Api's
+POST /eventset/v4/create controllers.v4.EventSetController.create
+PATCH /private/eventset/v4/update/:identifier controllers.v4.EventSetController.update(identifier:String)
+GET /eventset/v4/hierarchy/:identifier controllers.v4.EventSetController.getHierarchy(identifier:String, mode:Option[String])
+GET /eventset/v4/read/:identifier controllers.v4.EventSetController.read(identifier:String, mode:Option[String], fields:Option[String])
+DELETE /private/eventset/v4/discard/:identifier controllers.v4.EventSetController.discard(identifier:String)
+DELETE /eventset/v4/retire/:identifier controllers.v4.EventSetController.retire(identifier:String)
\ No newline at end of file
diff --git a/content-api/content-service/test/controllers/v4/EventSetSpec.scala b/content-api/content-service/test/controllers/v4/EventSetSpec.scala
new file mode 100644
index 000000000..dd2193265
--- /dev/null
+++ b/content-api/content-service/test/controllers/v4/EventSetSpec.scala
@@ -0,0 +1,93 @@
+package controllers.v4
+
+import controllers.base.BaseSpec
+import org.junit.runner.RunWith
+import org.specs2.runner.JUnitRunner
+import play.api.libs.json.{JsValue, Json}
+import play.api.test.FakeRequest
+import play.api.test.Helpers.{OK, status, _}
+
+@RunWith(classOf[JUnitRunner])
+class EventSetSpec extends BaseSpec {
+
+ "EventSet Controller " should {
+ "return success response for create API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventSetController]
+ val json: JsValue = Json.parse("""{"request": {"eventSet": {"name": "EventSet","primaryCategory": "Event Set"}}}""")
+ val fakeRequest = FakeRequest("POST", "/eventset/v4/create ").withJsonBody(json)
+ val result = controller.create()(fakeRequest)
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
+ "return success response for update API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventSetController]
+ val result = controller.update("do_123")(FakeRequest("POST", "/eventset/v4/update "))
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
+ "return success response for read API" in {
+ val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val result = controller.read("do_123", None, None)(FakeRequest("POST", "/eventset/v4/read "))
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
+ "return success response for hierarchy get API" in {
+ val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val result = controller.getHierarchy("do_123", None)(FakeRequest("POST", "/eventset/v4/hierarchy "))
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
+ "return success response for discard API" in {
+ val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val result = controller.discard("0123")(FakeRequest("POST", "/eventset/v4/discard "))
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+ "return success response for retire API" in {
+ val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val result = controller.retire("0123")(FakeRequest("POST", "/eventset/v4/retire "))
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
+ "return success response for collectionLinkDialCode API" in {
+ val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val result = controller.collectionLinkDialCode("do_123")(FakeRequest("POST", "/eventset/v4/dialcode/link "))
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+ }
+
+ "return success response for hierarchy update API" in {
+ val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val json: JsValue = Json.parse("""{"request": {"data": {"mimeType": "application/vnd.ekstep.content-collection"}}}""")
+ val fakeRequest = FakeRequest("POST", "/collection/v4/hierarchy/update").withJsonBody(json)
+ val result = controller.updateHierarchy()(fakeRequest)
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
+ "Collection Controller with invalid request " should {
+ "return client error response for create API" in {
+ val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val json: JsValue = Json.parse("""{"request": {"collection": { "contentType": "TextBook"}}}""")
+ val fakeRequest = FakeRequest("POST", "/collection/v4/create ").withJsonBody(json)
+ val result = controller.create()(fakeRequest)
+ status(result) must equalTo(BAD_REQUEST)
+ }
+ }
+
+ "Collection Controller with invalid request " should {
+ "return client error response for create API" in {
+ val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val json: JsValue = Json.parse("""{"request": {"collection": { "name": "Textbook"}}}""")
+ val fakeRequest = FakeRequest("POST", "/collection/v4/create ").withJsonBody(json)
+ val result = controller.create()(fakeRequest)
+ status(result) must equalTo(BAD_REQUEST)
+ }
+ }
+}
\ No newline at end of file
diff --git a/content-api/content-service/test/modules/TestModule.scala b/content-api/content-service/test/modules/TestModule.scala
index 6b592ff9b..ebe890c3b 100644
--- a/content-api/content-service/test/modules/TestModule.scala
+++ b/content-api/content-service/test/modules/TestModule.scala
@@ -18,6 +18,7 @@ class TestModule extends AbstractModule with AkkaGuiceSupport {
bindActor(classOf[TestActor], ActorNames.CHANNEL_ACTOR)
bindActor(classOf[TestActor], ActorNames.CATEGORY_ACTOR)
bindActor(classOf[TestActor], ActorNames.ASSET_ACTOR)
+ bindActor(classOf[TestActor], ActorNames.EVENT_SET_ACTOR)
println("Test Module is initialized...")
}
}
diff --git a/content-api/hierarchy-manager/src/main/scala/org/sunbird/utils/HierarchyConstants.scala b/content-api/hierarchy-manager/src/main/scala/org/sunbird/utils/HierarchyConstants.scala
index 2f4fbca8f..9dabb3406 100644
--- a/content-api/hierarchy-manager/src/main/scala/org/sunbird/utils/HierarchyConstants.scala
+++ b/content-api/hierarchy-manager/src/main/scala/org/sunbird/utils/HierarchyConstants.scala
@@ -9,6 +9,7 @@ object HierarchyConstants {
val SET_DEFAULT_VALUE: String = "setDefaultValue"
val COLLECTION_MIME_TYPE: String = "application/vnd.ekstep.content-collection"
val COLLECTION_SCHEMA_NAME: String = "collection"
+ val EVENT_SET_SCHEMA_NAME: String = "eventSet"
val LATEST_CONTENT_VERSION: Integer = 2
val VERSION: String = "version"
val IDENTIFIER: String = "identifier"
diff --git a/content-api/orchestrator/src/test/resources/application.conf b/content-api/orchestrator/src/test/resources/application.conf
index 4825c0c5a..a07b73257 100644
--- a/content-api/orchestrator/src/test/resources/application.conf
+++ b/content-api/orchestrator/src/test/resources/application.conf
@@ -1,5 +1,5 @@
# Learning-Service Configuration
-content.metadata.visibility.parent=["textbookunit", "courseunit", "lessonplanunit"]
+content.metadata.visibility.parent=["textbookunit", "courseunit", "lessonplanunit", "event"]
# Cassandra Configuration
content.keyspace.name=content_store
diff --git a/platform-core/schema-validator/src/main/java/org/sunbird/schema/impl/CustomProblemHandler.java b/platform-core/schema-validator/src/main/java/org/sunbird/schema/impl/CustomProblemHandler.java
index aab6d7cfb..270821328 100644
--- a/platform-core/schema-validator/src/main/java/org/sunbird/schema/impl/CustomProblemHandler.java
+++ b/platform-core/schema-validator/src/main/java/org/sunbird/schema/impl/CustomProblemHandler.java
@@ -61,6 +61,13 @@ private String processMessage(Problem problem) {
+ " cannot have new property with name "
+ ((String) problem.parametersAsMap().get("name")).replace("\"", ""));
}
+ case "format": {
+ return ("Incorrect format for " + Arrays.stream(problem.getPointer().split("/"))
+ .filter(StringUtils::isNotBlank)
+ .findFirst().orElse("")
+ + " : "
+ + problem.getMessage());
+ }
default:
return "";
}
diff --git a/schemas/event/1.0/config.json b/schemas/event/1.0/config.json
new file mode 100644
index 000000000..52bdf3ba8
--- /dev/null
+++ b/schemas/event/1.0/config.json
@@ -0,0 +1,62 @@
+{
+ "restrictProps": {
+ "create": [
+ "status",
+ "dialcodes"
+ ],
+ "update": []
+ },
+ "objectType": "Event",
+ "relations": {
+ "usesContent": {
+ "type": "associatedTo",
+ "direction": "out",
+ "objects": [
+ "Content"
+ ]
+ },
+ "collections": {
+ "type": "hasSequenceMember",
+ "direction": "in",
+ "objects": [
+ "EventSet"
+ ]
+ },
+ "usedByContent": {
+ "type": "associatedTo",
+ "direction": "in",
+ "objects": [
+ "Content"
+ ]
+ }
+ },
+ "frameworkCategories": [
+ "board",
+ "medium",
+ "subject",
+ "gradeLevel",
+ "difficultyLevel",
+ "topic",
+ "subDomains",
+ "subjectCodes"
+ ],
+ "orgFrameworkTerms": [
+ "boardIds",
+ "gradeLevelIds",
+ "subjectIds",
+ "mediumIds",
+ "topicsIds"
+ ],
+ "targetFrameworkTerms": [
+ "targetFWIds",
+ "targetBoardIds",
+ "targetGradeLevelIds",
+ "targetSubjectIds",
+ "targetMediumIds",
+ "targetTopicIds"
+ ],
+ "version": "disable",
+ "versionCheckMode": "OFF",
+ "cacheEnabled": false,
+ "schema_restrict_api": false
+}
diff --git a/schemas/event/1.0/schema.json b/schemas/event/1.0/schema.json
new file mode 100644
index 000000000..4a4c3e1be
--- /dev/null
+++ b/schemas/event/1.0/schema.json
@@ -0,0 +1,244 @@
+{
+ "$id": "event-schema.json",
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Event",
+ "type": "object",
+ "required": [
+ "name",
+ "status",
+ "code",
+ "startDate",
+ "endDate",
+ "startTime",
+ "endTime",
+ "registrationEndDate",
+ "eventType"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 5
+ },
+ "code": {
+ "type": "string"
+ },
+ "primaryCategory": {
+ "type": "string"
+ },
+ "contentType": {
+ "type": "string",
+ "enum": [
+ "Event"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "Live",
+ "Retired"
+ ],
+ "default": "Live"
+ },
+ "startDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "endDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "startTime": {
+ "type": "string",
+ "format": "time"
+ },
+ "endTime": {
+ "type": "string",
+ "format": "time"
+ },
+ "registrationStartDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "registrationEndDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "eventType": {
+ "type": "string",
+ "enum": [
+ "Online",
+ "Offline",
+ "OnlineAndOffline"
+ ]
+ },
+ "onlineProvider": {"type": "string"},
+ "onlineProviderData": {"type": "object", "properties": {
+ "meetingLink" : {
+ "type": "string",
+ "format": "url"
+ }
+ }},
+ "registrationLink": {"type": "string", "format": "url"},
+ "venue": {"type": "object"},
+ "visibility": {
+ "type": "string",
+ "enum": [
+ "Default",
+ "Parent"
+ ],
+ "default": "Default"
+ },
+ "audience": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "Student",
+ "Teacher",
+ "Administrator"
+ ]
+ },
+ "default": ["Student"]
+ },
+ "posterImage": {
+ "type": "string",
+ "format": "url"
+ },
+ "appIcon": {
+ "type": "string",
+ "format": "url"
+ },
+ "createdFor": {
+ "type": "array"
+ },
+ "source": {
+ "type": "string"
+ },
+ "owner": {
+ "type": "string"
+ },
+ "collaborators": {
+ "type": "array"
+ },
+ "language": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "English",
+ "Hindi",
+ "Assamese",
+ "Bengali",
+ "Gujarati",
+ "Kannada",
+ "Malayalam",
+ "Marathi",
+ "Nepali",
+ "Odia",
+ "Punjabi",
+ "Tamil",
+ "Telugu",
+ "Urdu",
+ "Sanskrit",
+ "Maithili",
+ "Munda",
+ "Santali",
+ "Juang",
+ "Ho",
+ "Other"
+ ]
+ },
+ "default": ["English"]
+ },
+ "ageGroup": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "<5",
+ "5-6",
+ "6-7",
+ "7-8",
+ "8-10",
+ ">10",
+ "Other"
+ ]
+ }
+ },
+ "keywords": {
+ "type": "array"
+ },
+ "domain": {
+ "type": "array"
+ },
+ "dialcodes": {
+ "type": "array"
+ },
+ "description": {
+ "type": "string"
+ },
+ "trackable": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "string",
+ "enum": ["Yes","No"],
+ "default": "Yes"
+ },
+ "fixedBatch": {
+ "type": "string",
+ "enum": ["Yes","No"],
+ "default": "Yes"
+ },
+ "fixedBatchId": {
+ "type": "string",
+ "default": "event_batch_id"
+ }
+ },
+ "default": {
+ "enabled": "Yes",
+ "fixedBatch": "Yes",
+ "fixedBatchId": "event_batch_id"
+ },
+ "additionalProperties": false
+ },
+ "createdOn": {
+ "type": "string"
+ },
+ "createdBy": {
+ "type": "string"
+ },
+ "lastUpdatedBy": {
+ "type": "string"
+ },
+ "lastUpdatedOn": {
+ "type": "string"
+ },
+ "versionDate": {
+ "type": "string"
+ },
+ "origin": {
+ "type": "string"
+ },
+ "originData": {
+ "type": "object"
+ },
+ "versionCreatedBy": {
+ "type": "string"
+ },
+ "version": {
+ "type": "number",
+ "default": 2
+ },
+ "childNodes": {
+ "type": "array"
+ },
+ "leafNodesCount": {
+ "type": "number",
+ "default": 1
+ },
+ "depth": {
+ "type": "number"
+ }
+ }
+}
\ No newline at end of file
diff --git a/schemas/eventSet/1.0/config.json b/schemas/eventSet/1.0/config.json
new file mode 100644
index 000000000..6479a4937
--- /dev/null
+++ b/schemas/eventSet/1.0/config.json
@@ -0,0 +1,33 @@
+{
+ "restrictProps": {
+ "create" : [
+ "status", "dialcodes"
+ ],
+ "update": []
+ },
+ "objectType": "EventSet",
+ "relations": {
+ "usesContent": {
+ "type": "associatedTo",
+ "direction": "out",
+ "objects": ["Content"]
+ },
+ "collections": {
+ "type": "hasSequenceMember",
+ "direction": "out",
+ "objects": ["Event"]
+ },
+ "usedByContent": {
+ "type": "associatedTo",
+ "direction": "in",
+ "objects": ["Content"]
+ }
+ },
+ "frameworkCategories": ["board","medium","subject","gradeLevel","difficultyLevel","topic", "subDomains", "subjectCodes"],
+ "orgFrameworkTerms": ["boardIds", "gradeLevelIds", "subjectIds", "mediumIds", "topicsIds"],
+ "targetFrameworkTerms": ["targetFWIds", "targetBoardIds", "targetGradeLevelIds", "targetSubjectIds", "targetMediumIds", "targetTopicIds"],
+ "version": "disable",
+ "versionCheckMode": "OFF",
+ "cacheEnabled": false,
+ "schema_restrict_api": false
+}
diff --git a/schemas/eventSet/1.0/schema.json b/schemas/eventSet/1.0/schema.json
new file mode 100644
index 000000000..6530ccf22
--- /dev/null
+++ b/schemas/eventSet/1.0/schema.json
@@ -0,0 +1,252 @@
+{
+ "$id": "eventset-schema.json",
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "EventSet",
+ "type": "object",
+ "required": [
+ "name",
+ "status",
+ "code",
+ "startDate",
+ "endDate",
+ "schedule",
+ "registrationEndDate",
+ "eventType"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 5
+ },
+ "code": {
+ "type": "string"
+ },
+ "primaryCategory": {
+ "type": "string"
+ },
+ "contentType": {
+ "type": "string",
+ "enum": [
+ "Event"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "Live",
+ "Retired"
+ ],
+ "default": "Live"
+ },
+ "startDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "endDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "schedule": {
+ "type": "object",
+ "properties": {
+ "type": {"type": "string", "enum": ["NON_RECURRING"]},
+ "nonRecurringDetails": {"type": "array", "items": {
+ "type": "object",
+ "properties": {
+ "startDate": {"type": "string", "format": "date"},
+ "endDate": {"type": "string", "format": "date"},
+ "startTime": {"type": "string", "format": "time"},
+ "endTime": {"type": "string", "format": "time"},
+ "registrationStartDate": {"type": "string", "format": "date"},
+ "registrationEndDate": {"type": "string", "format": "date"}
+ }
+
+ }}
+ }
+ },
+ "registrationStartDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "registrationEndDate": {
+ "type": "string",
+ "format": "date"
+ },
+ "eventType": {
+ "type": "string",
+ "enum": [
+ "Online",
+ "Offline",
+ "OnlineAndOffline"
+ ]
+ },
+ "onlineProvider": {"type": "string"},
+ "onlineProviderData": {"type": "object", "properties": {
+ "meetingLink" : {
+ "type": "string",
+ "format": "url"
+ }
+ }},
+ "registrationLink": {"type": "string", "format": "url"},
+ "venue": {"type": "object"},
+ "visibility": {
+ "type": "string",
+ "enum": [
+ "Default",
+ "Parent"
+ ],
+ "default": "Default"
+ },
+ "audience": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "Student",
+ "Teacher",
+ "Administrator"
+ ]
+ },
+ "default": ["Student"]
+ },
+ "posterImage": {
+ "type": "string",
+ "format": "url"
+ },
+ "appIcon": {
+ "type": "string",
+ "format": "url"
+ },
+ "createdFor": {
+ "type": "array"
+ },
+ "source": {
+ "type": "string"
+ },
+ "owner": {
+ "type": "string"
+ },
+ "collaborators": {
+ "type": "array"
+ },
+ "language": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "English",
+ "Hindi",
+ "Assamese",
+ "Bengali",
+ "Gujarati",
+ "Kannada",
+ "Malayalam",
+ "Marathi",
+ "Nepali",
+ "Odia",
+ "Punjabi",
+ "Tamil",
+ "Telugu",
+ "Urdu",
+ "Sanskrit",
+ "Maithili",
+ "Munda",
+ "Santali",
+ "Juang",
+ "Ho",
+ "Other"
+ ]
+ },
+ "default": ["English"]
+ },
+ "ageGroup": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "<5",
+ "5-6",
+ "6-7",
+ "7-8",
+ "8-10",
+ ">10",
+ "Other"
+ ]
+ }
+ },
+ "keywords": {
+ "type": "array"
+ },
+ "domain": {
+ "type": "array"
+ },
+ "dialcodes": {
+ "type": "array"
+ },
+ "description": {
+ "type": "string"
+ },
+ "trackable": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "string",
+ "enum": ["Yes","No"],
+ "default": "Yes"
+ },
+ "fixedBatch": {
+ "type": "string",
+ "enum": ["Yes","No"],
+ "default": "Yes"
+ },
+ "fixedBatchId": {
+ "type": "string",
+ "default": "event_batch_id"
+ }
+ },
+ "default": {
+ "enabled": "Yes",
+ "fixedBatch": "Yes",
+ "fixedBatchId": "event_batch_id"
+ },
+ "additionalProperties": false
+ },
+ "createdOn": {
+ "type": "string"
+ },
+ "createdBy": {
+ "type": "string"
+ },
+ "lastUpdatedBy": {
+ "type": "string"
+ },
+ "lastUpdatedOn": {
+ "type": "string"
+ },
+ "versionDate": {
+ "type": "string"
+ },
+ "origin": {
+ "type": "string"
+ },
+ "originData": {
+ "type": "object"
+ },
+ "versionCreatedBy": {
+ "type": "string"
+ },
+ "version": {
+ "type": "number",
+ "default": 2
+ },
+ "childNodes": {
+ "type": "array"
+ },
+ "leafNodesCount": {
+ "type": "number"
+ },
+ "depth": {
+ "type": "number"
+ }
+ }
+}
\ No newline at end of file
From 9769bc54ab7f735ad00dd8f33a85aa557b3ee98a Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Thu, 25 Feb 2021 13:45:27 +0530
Subject: [PATCH 16/53] SC-2226 Event and EventSet APIs
---
.../app/controllers/v4/EventController.scala | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/content-api/content-service/app/controllers/v4/EventController.scala b/content-api/content-service/app/controllers/v4/EventController.scala
index 5c555e216..afea537b9 100644
--- a/content-api/content-service/app/controllers/v4/EventController.scala
+++ b/content-api/content-service/app/controllers/v4/EventController.scala
@@ -10,7 +10,7 @@ import scala.collection.JavaConverters.mapAsJavaMapConverter
import scala.concurrent.ExecutionContext
@Singleton
-class EventController @Inject()(@Named(ActorNames.EVENT_ACTOR) contentActor: ActorRef, cc: ControllerComponents, actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends ContentController(contentActor, cc, actorSystem) {
+class EventController @Inject()(@Named(ActorNames.EVENT_ACTOR) eventActor: ActorRef, cc: ControllerComponents, actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends ContentController(eventActor, cc, actorSystem) {
override val objectType = "Event"
override val schemaName: String = "event"
@@ -25,7 +25,7 @@ class EventController @Inject()(@Named(ActorNames.EVENT_ACTOR) contentActor: Act
else {
val contentRequest = getRequest(content, headers, "createContent", false)
setRequestContext(contentRequest, version, objectType, schemaName)
- getResult(ApiId.CREATE_EVENT, contentActor, contentRequest, version = apiVersion)
+ getResult(ApiId.CREATE_EVENT, eventActor, contentRequest, version = apiVersion)
}
}
@@ -37,7 +37,7 @@ class EventController @Inject()(@Named(ActorNames.EVENT_ACTOR) contentActor: Act
val readRequest = getRequest(content, headers, "readContent")
setRequestContext(readRequest, version, objectType, schemaName)
readRequest.getContext.put(Constants.RESPONSE_SCHEMA_NAME, schemaName);
- getResult(ApiId.READ_CONTENT, contentActor, readRequest, version = apiVersion)
+ getResult(ApiId.READ_CONTENT, eventActor, readRequest, version = apiVersion)
}
}
\ No newline at end of file
From de3473757904bba3a16ccb49b558ed0f9e85aa0e Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Mon, 1 Mar 2021 11:16:22 +0530
Subject: [PATCH 17/53] SC-2226 Add EventActor to TestModule
---
content-api/content-service/test/modules/TestModule.scala | 1 +
1 file changed, 1 insertion(+)
diff --git a/content-api/content-service/test/modules/TestModule.scala b/content-api/content-service/test/modules/TestModule.scala
index ebe890c3b..52ff24e8b 100644
--- a/content-api/content-service/test/modules/TestModule.scala
+++ b/content-api/content-service/test/modules/TestModule.scala
@@ -19,6 +19,7 @@ class TestModule extends AbstractModule with AkkaGuiceSupport {
bindActor(classOf[TestActor], ActorNames.CATEGORY_ACTOR)
bindActor(classOf[TestActor], ActorNames.ASSET_ACTOR)
bindActor(classOf[TestActor], ActorNames.EVENT_SET_ACTOR)
+ bindActor(classOf[TestActor], ActorNames.EVENT_ACTOR)
println("Test Module is initialized...")
}
}
From 5042e96a425eea808f7ea21df7081c80178926cd Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Tue, 2 Mar 2021 23:19:38 +0530
Subject: [PATCH 18/53] SC-2226 Added unit tests
---
.../content/actors/EventSetActor.scala | 2 +
.../content/actors/TestEventActor.scala | 172 ++++++++++
.../content/actors/TestEventSetActor.scala | 298 ++++++++++++++++++
.../test/controllers/v4/EventSpec.scala | 32 ++
.../org/sunbird/graph/nodes/DataNode.scala | 4 +-
5 files changed, 506 insertions(+), 2 deletions(-)
create mode 100644 content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala
create mode 100644 content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
create mode 100644 content-api/content-service/test/controllers/v4/EventSpec.scala
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
index 9e1541969..76c50dbc1 100644
--- a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
@@ -77,6 +77,8 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
}
def getHierarchy(request: Request): Future[Response] = {
+ val fields: util.List[String] = seqAsJavaListConverter(request.get("fields").asInstanceOf[String].split(",").filter(field => StringUtils.isNotBlank(field) && !StringUtils.equalsIgnoreCase(field, "null"))).asJava
+ request.getRequest.put("fields", fields)
DataNode.read(request).map(node => {
val outRelations = if (node.getOutRelations == null) List[Relation]() else node.getOutRelations.asScala
val childNodes = outRelations.map(relation => relation.getEndNodeId).toList
diff --git a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala
new file mode 100644
index 000000000..31c46f1a2
--- /dev/null
+++ b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala
@@ -0,0 +1,172 @@
+package org.sunbird.content.actors
+
+import akka.actor.Props
+import org.scalamock.scalatest.MockFactory
+import org.sunbird.cloudstore.StorageService
+import org.sunbird.common.dto.Request
+import org.sunbird.common.exception.ResponseCode
+import org.sunbird.graph.dac.model.Node
+import org.sunbird.graph.{GraphService, OntologyEngineContext}
+
+import java.util
+import scala.collection.JavaConversions._
+import scala.concurrent.ExecutionContext.Implicits.global
+import scala.concurrent.Future
+
+class TestEventActor extends BaseSpec with MockFactory {
+
+ it should "discard node in draft state should return success" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getValidNodeToDiscard())).anyNumberOfTimes()
+ (graphDB.deleteNode(_: String, _: String, _: Request)).expects(*, *, *).returns(Future(true))
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_12346")))
+ request.setOperation("discardContent")
+ val response = callActor(request, Props(new EventActor()))
+ assert(response.getResponseCode == ResponseCode.OK)
+ assert(response.get("identifier") == "do_12346")
+ assert(response.get("message") == "Draft version of the content with id : do_12346 is discarded")
+
+ }
+
+ it should "discard node in Live state should return client error" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getInValidNodeToDiscard())).anyNumberOfTimes()
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_12346")))
+ request.setOperation("discardContent")
+ val response = callActor(request, Props(new EventActor()))
+ assert(response.getResponseCode == ResponseCode.CLIENT_ERROR)
+ }
+
+ it should "return client error response for retireContent" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getContext.put("identifier","do_1234.img")
+ request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_1234.img")))
+ request.setOperation("retireContent")
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB)
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getInValidNodeToDiscard()))
+ val response = callActor(request, Props(new EventActor()))
+ assert(response.getResponseCode == ResponseCode.CLIENT_ERROR)
+ }
+
+ it should "return success response for retireContent" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ val node = getNode("Content", None)
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(node)).anyNumberOfTimes()
+ (graphDB.updateNodes(_: String, _: util.List[String], _: util.HashMap[String, AnyRef])).expects(*, *, *).returns(Future(new util.HashMap[String, Node]))
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getContext.put("identifier","do1234")
+ request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_1234")))
+ request.setOperation("retireContent")
+ val response = callActor(request, Props(new EventActor()))
+ assert("successful".equals(response.getParams.getStatus))
+ }
+
+ it should "return success response for 'updateContent'" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ implicit val ss = mock[StorageService]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ val node = getNode()
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(node)).anyNumberOfTimes()
+ (graphDB.upsertNode(_: String, _: Node, _: Request)).expects(*, *, *).returns(Future(node))
+ val request = getContentRequest()
+ request.getContext.put("identifier","do_1234")
+ request.putAll(mapAsJavaMap(Map("name" -> "New Content", "code" -> "1234",
+ "startDate" -> "2021-03-04", "endDate" -> "2021-03-04", "startTime" -> "11:00:00Z", "endTime" -> "11:00:00Z",
+ "registrationEndDate" -> "2021-03-04", "eventType" -> "Online", "versionKey" -> "test_123")))
+ request.setOperation("updateContent")
+ val response = callActor(request, Props(new EventActor()))
+ assert("successful".equals(response.getParams.getStatus))
+ assert("do_1234".equals(response.get("identifier")))
+ assert("test_123".equals(response.get("versionKey")))
+ }
+
+ private def getContentRequest(): Request = {
+ val request = new Request()
+ request.setContext(new util.HashMap[String, AnyRef]() {
+ {
+ put("graph_id", "domain")
+ put("version", "1.0")
+ put("objectType", "Event")
+ put("schemaName", "event")
+ put("X-Channel-Id", "in.ekstep")
+ }
+ })
+ request.setObjectType("Event")
+ request
+ }
+
+ private def getValidNodeToDiscard(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_12346")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("Content")
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_12346")
+ put("mimeType", "application/pdf")
+ put("status", "Draft")
+ put("contentType", "Resource")
+ put("name", "Node To discard")
+ put("primaryCategory", "Learning Resource")
+ }
+ })
+ node
+ }
+
+ private def getInValidNodeToDiscard(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_12346")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("Content")
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_12346")
+ put("mimeType", "application/pdf")
+ put("status", "Live")
+ put("contentType", "Resource")
+ put("name", "Node To discard")
+ put("primaryCategory", "Learning Resource")
+ }
+ })
+ node
+ }
+
+ private def getNode(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_1234")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("Event")
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_1234")
+ put("status", "Live")
+ put("name", "Resource_1")
+ put("versionKey", "test_321")
+ put("channel", "in.ekstep")
+ put("code", "Resource_1")
+ put("startDate", "2021-02-02")
+ put("endDate", "2021-02-02")
+ put("startTime", "11:00:00Z")
+ put("endTime", "12:00:00Z")
+ put("registrationEndDate", "2021-01-02")
+ put("eventType", "Online")
+ }
+ })
+ node
+ }
+}
diff --git a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
new file mode 100644
index 000000000..fb64d13b3
--- /dev/null
+++ b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
@@ -0,0 +1,298 @@
+package org.sunbird.content.actors
+
+import akka.actor.Props
+import org.scalamock.scalatest.MockFactory
+import org.sunbird.cloudstore.StorageService
+import org.sunbird.common.JsonUtils
+import org.sunbird.common.dto.{Request, Response}
+import org.sunbird.common.exception.ResponseCode
+import org.sunbird.graph.common.enums.GraphDACParams
+import org.sunbird.graph.dac.model.{Node, SearchCriteria}
+import org.sunbird.graph.{GraphService, OntologyEngineContext}
+
+import java.util
+import scala.collection.JavaConversions.mapAsJavaMap
+import scala.collection.JavaConverters.seqAsJavaListConverter
+import scala.concurrent.ExecutionContext.Implicits.global
+import scala.concurrent.Future
+
+class TestEventSetActor extends BaseSpec with MockFactory {
+
+ "EventSetActor" should "return failed response for 'unknown' operation" in {
+ implicit val ss = mock[StorageService]
+ implicit val oec: OntologyEngineContext = new OntologyEngineContext
+ testUnknownOperation(Props(new EventSetActor()), getContentRequest())
+ }
+
+ it should "validate input before creating event set" in {
+ implicit val ss = mock[StorageService]
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val request = getContentRequest()
+ val eventSet = mapAsJavaMap(Map(
+ "name" -> "New Content", "code" -> "1234",
+ "startDate"-> "2021/01/03", //wrong format
+ "endDate"-> "2021-01-03",
+ "schedule" ->
+ mapAsJavaMap(Map("type" -> "NON_RECURRING",
+ "value" -> List(mapAsJavaMap(Map("startDate" -> "2021-01-03", "endDate" -> "2021-01-03", "startTime" -> "11:00:00Z", "endTime" -> "13:00:00Z"))).asJava)),
+ "onlineProvider" -> "Zoom",
+ "registrationEndDate" -> "2021-02-25",
+ "eventType" -> "Online"))
+ request.putAll(eventSet)
+ assert(true)
+ val response = callActor(request, Props(new EventSetActor()))
+ println("Response: " + JsonUtils.serialize(response))
+ }
+
+ it should "create an eventset and store it in neo4j" in {
+ val eventNode = getEventNode()
+ val eventSetNode = getEventSetNode()
+ implicit val ss = mock[StorageService]
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ (graphDB.addNode _).expects(where { (g: String, n:Node) => {
+ n.getObjectType.equals("Event")
+ }}).returns(Future(eventNode)).once()
+ val loopResult: util.Map[String, Object] = new util.HashMap[String, Object]()
+ loopResult.put(GraphDACParams.loop.name, new java.lang.Boolean(false))
+ (graphDB.checkCyclicLoop _).expects(*, *, *, *).returns(loopResult).anyNumberOfTimes()
+ (graphDB.addNode _).expects(where { (g: String, n:Node) => n.getObjectType.equals("EventSet")}).returns(Future(eventSetNode)).once()
+ (graphDB.getNodeByUniqueIds(_: String, _: SearchCriteria)).expects(*, *).returns(Future(new util.ArrayList[Node]() {
+ {
+ add(eventNode)
+ }
+ }))
+ (graphDB.createRelation _).expects(*, *).returns(Future(new Response()))
+ val request = getContentRequest()
+ val eventSet = mapAsJavaMap(Map(
+ "name" -> "New Content", "code" -> "1234",
+ "startDate"-> "2021-01-03", //wrong format
+ "endDate"-> "2021-01-03",
+ "schedule" ->
+ mapAsJavaMap(Map("type" -> "NON_RECURRING",
+ "value" -> List(mapAsJavaMap(Map("startDate" -> "2021-01-03", "endDate" -> "2021-01-03", "startTime" -> "11:00:00Z", "endTime" -> "13:00:00Z"))).asJava)),
+ "onlineProvider" -> "Zoom",
+ "registrationEndDate" -> "2021-02-25",
+ "eventType" -> "Online"))
+ request.putAll(eventSet)
+ request.setOperation("createContent")
+ val response = callActor(request, Props(new EventSetActor()))
+ assert(response.get("identifier") != null)
+ assert(response.get("versionKey") != null)
+ }
+
+ it should "update an eventset and store it in neo4j" in {
+ val eventNode = getEventNode()
+ val eventSetNode = getEventSetNode()
+ implicit val ss = mock[StorageService]
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ (graphDB.addNode _).expects(where { (g: String, n:Node) => {
+ n.getObjectType.equals("Event")
+ }}).returns(Future(eventNode))
+ val loopResult: util.Map[String, Object] = new util.HashMap[String, Object]()
+ loopResult.put(GraphDACParams.loop.name, new java.lang.Boolean(false))
+ (graphDB.checkCyclicLoop _).expects(*, *, *, *).returns(loopResult).anyNumberOfTimes()
+ (graphDB.upsertNode _).expects(*, *, *).returns(Future(eventSetNode))
+ (graphDB.getNodeByUniqueIds(_: String, _: SearchCriteria)).expects(*, *).returns(Future(new util.ArrayList[Node]() {
+ {
+ add(eventNode)
+ }
+ }))
+ (graphDB.getNodeByUniqueId _).expects(*, *, *, *).returns(Future(eventSetNode)).anyNumberOfTimes()
+ (graphDB.createRelation _).expects(*, *).returns(Future(new Response()))
+ val request = getContentRequest()
+ val eventSet = mapAsJavaMap(Map(
+ "name" -> "New Content", "code" -> "1234",
+ "startDate"-> "2021-01-03", //wrong format
+ "endDate"-> "2021-01-03",
+ "schedule" ->
+ mapAsJavaMap(Map("type" -> "NON_RECURRING",
+ "value" -> List(mapAsJavaMap(Map("startDate" -> "2021-01-03", "endDate" -> "2021-01-03", "startTime" -> "11:00:00Z", "endTime" -> "13:00:00Z"))).asJava)),
+ "onlineProvider" -> "Zoom",
+ "registrationEndDate" -> "2021-02-25",
+ "eventType" -> "Online",
+ "versionKey" -> "test_123"))
+ request.putAll(eventSet)
+ request.setOperation("updateContent")
+ val response = callActor(request, Props(new EventSetActor()))
+ assert(response.get("identifier") != null)
+ assert(response.get("versionKey") != null)
+ }
+
+
+ it should "discard node in draft state should return success" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).repeated(2)
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getValidNodeToDiscard()))
+ (graphDB.deleteNode(_: String, _: String, _: Request)).expects(*, *, *).returns(Future(true))
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_12346")))
+ request.setOperation("discardContent")
+ val response = callActor(request, Props(new EventSetActor()))
+ assert(response.getResponseCode == ResponseCode.OK)
+ assert(response.get("identifier") == "do_12346")
+ assert(response.get("message") == "Draft version of the content with id : do_12346 is discarded")
+
+ }
+
+ it should "discard node in Live state should return client error" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).repeated(1)
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getInValidNodeToDiscard()))
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_12346")))
+ request.setOperation("discardContent")
+ val response = callActor(request, Props(new EventSetActor()))
+ assert(response.getResponseCode == ResponseCode.CLIENT_ERROR)
+ }
+
+ it should "return success response for retireContent" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).repeated(2)
+ val node = getNode("EventSet", None)
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(node)).anyNumberOfTimes()
+ (graphDB.updateNodes(_: String, _: util.List[String], _: util.HashMap[String, AnyRef])).expects(*, *, *).returns(Future(new util.HashMap[String, Node]))
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getContext.put("identifier","do1234")
+ request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_1234")))
+ request.setOperation("retireContent")
+ val response = callActor(request, Props(new EventSetActor()))
+ assert("successful".equals(response.getParams.getStatus))
+ }
+
+ it should "return success response for 'readContent'" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB)
+ val node = getNode("EventSet", None)
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(node))
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getContext.put("identifier","do1234")
+ request.putAll(mapAsJavaMap(Map("identifier" -> "do_1234", "fields" -> "")))
+ request.setOperation("readContent")
+ val response = callActor(request, Props(new EventSetActor()))
+ assert("successful".equals(response.getParams.getStatus))
+ }
+
+ it should "return success response for 'getHierarchy'" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB)
+ val node = getNode("EventSet", None)
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(node))
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getContext.put("identifier","do1234")
+ request.putAll(mapAsJavaMap(Map("identifier" -> "do_1234", "fields" -> "")))
+ request.setOperation("getHierarchy")
+ val response = callActor(request, Props(new EventSetActor()))
+ assert("successful".equals(response.getParams.getStatus))
+ }
+
+ private def getContentRequest(): Request = {
+ val request = new Request()
+ request.setContext(new util.HashMap[String, AnyRef]() {
+ {
+ put("graph_id", "domain")
+ put("version", "1.0")
+ put("objectType", "EventSet")
+ put("schemaName", "eventSet")
+ put("X-Channel-Id", "in.ekstep")
+ }
+ })
+ request.setObjectType("EventSet")
+ request
+ }
+
+ private def getValidNodeToDiscard(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_12346")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("Content")
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_12346")
+ put("mimeType", "application/pdf")
+ put("status", "Draft")
+ put("contentType", "Resource")
+ put("name", "Node To discard")
+ put("primaryCategory", "Learning Resource")
+ }
+ })
+ node
+ }
+
+ private def getInValidNodeToDiscard(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_12346")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("Content")
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_12346")
+ put("mimeType", "application/pdf")
+ put("status", "Live")
+ put("contentType", "Resource")
+ put("name", "Node To discard")
+ put("primaryCategory", "Learning Resource")
+ }
+ })
+ node
+ }
+
+ private def getEventNode(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_1234")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("Event")
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_1234")
+ put("status", "Live")
+ put("name", "Event_1")
+ put("code", "event1")
+ put("versionKey", "1878141")
+ put("startDate", "2021-02-02")
+ put("endDate", "2021-02-02")
+ put("startTime", "11:00:00Z")
+ put("endTime", "12:00:00Z")
+ put("registrationEndDate", "2021-01-02")
+ put("eventType", "Online")
+ }
+ })
+ node
+ }
+
+ private def getEventSetNode(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_12345")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("EventSet")
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_12345")
+ put("status", "Live")
+ put("name", "EventSet_1")
+ put("code", "eventset1")
+ put("versionKey", "1878141")
+ put("startDate", "2021-02-02")
+ put("endDate", "2021-02-02")
+ put("registrationEndDate", "2021-01-02")
+ put("eventType", "Online")
+ }
+ })
+ node
+ }
+
+
+}
diff --git a/content-api/content-service/test/controllers/v4/EventSpec.scala b/content-api/content-service/test/controllers/v4/EventSpec.scala
new file mode 100644
index 000000000..2a17c99b1
--- /dev/null
+++ b/content-api/content-service/test/controllers/v4/EventSpec.scala
@@ -0,0 +1,32 @@
+package controllers.v4
+
+import controllers.base.BaseSpec
+import org.junit.runner.RunWith
+import org.specs2.runner.JUnitRunner
+import play.api.libs.json.{JsValue, Json}
+import play.api.test.FakeRequest
+import play.api.test.Helpers.{OK, status, _}
+
+@RunWith(classOf[JUnitRunner])
+class EventSpec extends BaseSpec {
+
+ "Event Controller " should {
+ "return success response for create API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventController]
+ val json: JsValue = Json.parse("""{"request": {"event": {"name": "Event","primaryCategory": "Event"}}}""")
+ val fakeRequest = FakeRequest("POST", "/event/v4/create ").withJsonBody(json)
+ val result = controller.create()(fakeRequest)
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
+ "return success response for read API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventController]
+ val result = controller.read("do_123", None, None)(FakeRequest("POST", "/event/v4/read "))
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/ontology-engine/graph-engine_2.11/src/main/scala/org/sunbird/graph/nodes/DataNode.scala b/ontology-engine/graph-engine_2.11/src/main/scala/org/sunbird/graph/nodes/DataNode.scala
index fd06ee5ca..6c6cad146 100644
--- a/ontology-engine/graph-engine_2.11/src/main/scala/org/sunbird/graph/nodes/DataNode.scala
+++ b/ontology-engine/graph-engine_2.11/src/main/scala/org/sunbird/graph/nodes/DataNode.scala
@@ -127,10 +127,10 @@ object DataNode {
} else Future(new Response)
}
- private def createRelations(graphId: String, node: Node, context: util.Map[String, AnyRef])(implicit ec: ExecutionContext) : Future[Response] = {
+ private def createRelations(graphId: String, node: Node, context: util.Map[String, AnyRef])(implicit ec: ExecutionContext, oec: OntologyEngineContext) : Future[Response] = {
val relations: util.List[Relation] = node.getAddedRelations
if (CollectionUtils.isNotEmpty(relations)) {
- GraphAsyncOperations.createRelation(graphId,getRelationMap(relations))
+ oec.graphService.createRelation(graphId,getRelationMap(relations))
} else {
Future(new Response)
}
From f3d2079727261c33eb9e889c4436406db590e01e Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Wed, 3 Mar 2021 00:03:05 +0530
Subject: [PATCH 19/53] SC-2226 Added Draft mode and renamed event set schema
to lower case
---
.../main/scala/org/sunbird/content/actors/EventSetActor.scala | 2 +-
.../scala/org/sunbird/content/actors/TestEventSetActor.scala | 2 +-
.../app/controllers/v4/EventSetController.scala | 2 +-
content-api/content-service/app/utils/ApiId.scala | 4 ++--
.../content-service/test/controllers/v4/EventSetSpec.scala | 2 +-
.../src/main/scala/org/sunbird/utils/HierarchyConstants.scala | 2 +-
schemas/event/1.0/schema.json | 3 ++-
schemas/{eventSet => eventset}/1.0/config.json | 0
schemas/{eventSet => eventset}/1.0/schema.json | 3 ++-
9 files changed, 11 insertions(+), 9 deletions(-)
rename schemas/{eventSet => eventset}/1.0/config.json (100%)
rename schemas/{eventSet => eventset}/1.0/schema.json (99%)
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
index 76c50dbc1..6e536ab35 100644
--- a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
@@ -92,7 +92,7 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
metadata.put("childNodes", childNodes.asJava)
metadata.put("children", children.asJava)
val response: Response = ResponseHandler.OK
- response.put("eventSet", metadata)
+ response.put("eventset", metadata)
response
})
}
diff --git a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
index fb64d13b3..4a6178c4a 100644
--- a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
+++ b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
@@ -206,7 +206,7 @@ class TestEventSetActor extends BaseSpec with MockFactory {
put("graph_id", "domain")
put("version", "1.0")
put("objectType", "EventSet")
- put("schemaName", "eventSet")
+ put("schemaName", "eventset")
put("X-Channel-Id", "in.ekstep")
}
})
diff --git a/content-api/content-service/app/controllers/v4/EventSetController.scala b/content-api/content-service/app/controllers/v4/EventSetController.scala
index 17db13a83..1e242c0a7 100644
--- a/content-api/content-service/app/controllers/v4/EventSetController.scala
+++ b/content-api/content-service/app/controllers/v4/EventSetController.scala
@@ -12,7 +12,7 @@ import scala.concurrent.ExecutionContext
@Singleton
class EventSetController @Inject()(@Named(ActorNames.EVENT_SET_ACTOR) eventSetActor: ActorRef, cc: ControllerComponents, actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends CollectionController(eventSetActor, eventSetActor, cc, actorSystem) {
override val objectType = "EventSet"
- override val schemaName: String = "eventSet"
+ override val schemaName: String = "eventset"
override def create() = Action.async { implicit request =>
val headers = commonHeaders()
diff --git a/content-api/content-service/app/utils/ApiId.scala b/content-api/content-service/app/utils/ApiId.scala
index 0790da953..2337cd3ec 100644
--- a/content-api/content-service/app/utils/ApiId.scala
+++ b/content-api/content-service/app/utils/ApiId.scala
@@ -72,7 +72,7 @@ object ApiId {
val CREATE_EVENT = "api.event.create"
val UPDATE_EVENT = "api.event.update"
- val CREATE_EVENT_SET = "api.eventSet.create"
- val UPDATE_EVENT_SET = "api.eventSet.update"
+ val CREATE_EVENT_SET = "api.eventset.create"
+ val UPDATE_EVENT_SET = "api.eventset.update"
}
diff --git a/content-api/content-service/test/controllers/v4/EventSetSpec.scala b/content-api/content-service/test/controllers/v4/EventSetSpec.scala
index dd2193265..4e2dc4d0e 100644
--- a/content-api/content-service/test/controllers/v4/EventSetSpec.scala
+++ b/content-api/content-service/test/controllers/v4/EventSetSpec.scala
@@ -13,7 +13,7 @@ class EventSetSpec extends BaseSpec {
"EventSet Controller " should {
"return success response for create API" in {
val controller = app.injector.instanceOf[controllers.v4.EventSetController]
- val json: JsValue = Json.parse("""{"request": {"eventSet": {"name": "EventSet","primaryCategory": "Event Set"}}}""")
+ val json: JsValue = Json.parse("""{"request": {"eventset": {"name": "EventSet","primaryCategory": "Event Set"}}}""")
val fakeRequest = FakeRequest("POST", "/eventset/v4/create ").withJsonBody(json)
val result = controller.create()(fakeRequest)
isOK(result)
diff --git a/content-api/hierarchy-manager/src/main/scala/org/sunbird/utils/HierarchyConstants.scala b/content-api/hierarchy-manager/src/main/scala/org/sunbird/utils/HierarchyConstants.scala
index 9dabb3406..83c5d1da7 100644
--- a/content-api/hierarchy-manager/src/main/scala/org/sunbird/utils/HierarchyConstants.scala
+++ b/content-api/hierarchy-manager/src/main/scala/org/sunbird/utils/HierarchyConstants.scala
@@ -9,7 +9,7 @@ object HierarchyConstants {
val SET_DEFAULT_VALUE: String = "setDefaultValue"
val COLLECTION_MIME_TYPE: String = "application/vnd.ekstep.content-collection"
val COLLECTION_SCHEMA_NAME: String = "collection"
- val EVENT_SET_SCHEMA_NAME: String = "eventSet"
+ val EVENT_SET_SCHEMA_NAME: String = "eventset"
val LATEST_CONTENT_VERSION: Integer = 2
val VERSION: String = "version"
val IDENTIFIER: String = "identifier"
diff --git a/schemas/event/1.0/schema.json b/schemas/event/1.0/schema.json
index 4a4c3e1be..f6894addb 100644
--- a/schemas/event/1.0/schema.json
+++ b/schemas/event/1.0/schema.json
@@ -34,10 +34,11 @@
"status": {
"type": "string",
"enum": [
+ "Draft",
"Live",
"Retired"
],
- "default": "Live"
+ "default": "Draft"
},
"startDate": {
"type": "string",
diff --git a/schemas/eventSet/1.0/config.json b/schemas/eventset/1.0/config.json
similarity index 100%
rename from schemas/eventSet/1.0/config.json
rename to schemas/eventset/1.0/config.json
diff --git a/schemas/eventSet/1.0/schema.json b/schemas/eventset/1.0/schema.json
similarity index 99%
rename from schemas/eventSet/1.0/schema.json
rename to schemas/eventset/1.0/schema.json
index 6530ccf22..0a04c1622 100644
--- a/schemas/eventSet/1.0/schema.json
+++ b/schemas/eventset/1.0/schema.json
@@ -33,10 +33,11 @@
"status": {
"type": "string",
"enum": [
+ "Draft",
"Live",
"Retired"
],
- "default": "Live"
+ "default": "Draft"
},
"startDate": {
"type": "string",
From e242b48982a2d1a11cde6da4c84ce7acf5fd997f Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Wed, 3 Mar 2021 11:00:37 +0530
Subject: [PATCH 20/53] SC-2226 Added publis APIs
---
.../app/controllers/v4/EventController.scala | 28 +++++++++-
.../controllers/v4/EventSetController.scala | 29 +++++++++-
content-api/content-service/conf/routes | 2 +
.../test/controllers/v4/EventSetSpec.scala | 53 ++++++++-----------
.../test/controllers/v4/EventSpec.scala | 22 ++++++++
5 files changed, 101 insertions(+), 33 deletions(-)
diff --git a/content-api/content-service/app/controllers/v4/EventController.scala b/content-api/content-service/app/controllers/v4/EventController.scala
index afea537b9..c7fce266e 100644
--- a/content-api/content-service/app/controllers/v4/EventController.scala
+++ b/content-api/content-service/app/controllers/v4/EventController.scala
@@ -2,7 +2,7 @@ package controllers.v4
import akka.actor.{ActorRef, ActorSystem}
import com.google.inject.Singleton
-import play.api.mvc.ControllerComponents
+import play.api.mvc.{Action, AnyContent, ControllerComponents}
import utils.{ActorNames, ApiId, Constants}
import javax.inject.{Inject, Named}
@@ -40,4 +40,30 @@ class EventController @Inject()(@Named(ActorNames.EVENT_ACTOR) eventActor: Actor
getResult(ApiId.READ_CONTENT, eventActor, readRequest, version = apiVersion)
}
+ override def update(identifier: String) = Action.async { implicit request =>
+ val headers = commonHeaders()
+ val body = requestBody()
+ val content = body.getOrDefault(schemaName, new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]];
+ if (content.containsKey("status")) {
+ getErrorResponse(ApiId.UPDATE_EVENT, apiVersion, "VALIDATION_ERROR", "status update is restricted, use status APIs.")
+ } else {
+ content.putAll(headers)
+ val contentRequest = getRequest(content, headers, "updateContent")
+ setRequestContext(contentRequest, version, objectType, schemaName)
+ contentRequest.getContext.put("identifier", identifier);
+ getResult(ApiId.UPDATE_EVENT, eventActor, contentRequest, version = apiVersion)
+ }
+ }
+
+ def publish(identifier: String): Action[AnyContent] = Action.async { implicit request =>
+ val headers = commonHeaders()
+ val content = new java.util.HashMap[String, Object]()
+ content.put("status", "Live")
+ content.putAll(headers)
+ val contentRequest = getRequest(content, headers, "updateContent")
+ setRequestContext(contentRequest, version, objectType, schemaName)
+ contentRequest.getContext.put("identifier", identifier);
+ getResult(ApiId.UPDATE_EVENT, eventActor, contentRequest, version = apiVersion)
+ }
+
}
\ No newline at end of file
diff --git a/content-api/content-service/app/controllers/v4/EventSetController.scala b/content-api/content-service/app/controllers/v4/EventSetController.scala
index 1e242c0a7..d1f040774 100644
--- a/content-api/content-service/app/controllers/v4/EventSetController.scala
+++ b/content-api/content-service/app/controllers/v4/EventSetController.scala
@@ -2,7 +2,7 @@ package controllers.v4
import akka.actor.{ActorRef, ActorSystem}
import com.google.inject.Singleton
-import play.api.mvc.ControllerComponents
+import play.api.mvc.{Action, AnyContent, ControllerComponents}
import utils.{ActorNames, ApiId, Constants}
import javax.inject.{Inject, Named}
@@ -49,4 +49,31 @@ class EventSetController @Inject()(@Named(ActorNames.EVENT_SET_ACTOR) eventSetAc
getResult(ApiId.READ_COLLECTION, eventSetActor, readRequest, version = apiVersion)
}
+ override def update(identifier: String): Action[AnyContent] = Action.async { implicit request =>
+ val headers = commonHeaders()
+ val body = requestBody()
+ val content = body.getOrDefault(schemaName, new java.util.HashMap()).asInstanceOf[java.util.Map[String, Object]]
+ if (content.containsKey("status")) {
+ getErrorResponse(ApiId.UPDATE_EVENT_SET, apiVersion, "VALIDATION_ERROR", "status update is restricted, use status APIs.")
+ } else {
+ content.putAll(headers)
+ val contentRequest = getRequest(content, headers, "updateContent")
+ setRequestContext(contentRequest, version, objectType, schemaName)
+ contentRequest.getContext.put("identifier", identifier)
+ getResult(ApiId.UPDATE_EVENT_SET, eventSetActor, contentRequest, version = apiVersion)
+ }
+ }
+
+ def publish(identifier: String): Action[AnyContent] = Action.async { implicit request =>
+ val headers = commonHeaders()
+ val content = new java.util.HashMap[String, Object]()
+ content.put("status", "Live")
+ content.putAll(headers)
+ val contentRequest = getRequest(content, headers, "updateContent")
+ setRequestContext(contentRequest, version, objectType, schemaName)
+ contentRequest.getContext.put("identifier", identifier)
+ getResult(ApiId.UPDATE_EVENT_SET, eventSetActor, contentRequest, version = apiVersion)
+ }
+
+
}
\ No newline at end of file
diff --git a/content-api/content-service/conf/routes b/content-api/content-service/conf/routes
index a8a24890d..0d2189dd4 100644
--- a/content-api/content-service/conf/routes
+++ b/content-api/content-service/conf/routes
@@ -97,6 +97,7 @@ DELETE /content/v4/retire/:identifier controllers.v4.ContentControl
# Event APIs
POST /event/v4/create controllers.v4.EventController.create
PATCH /event/v4/update/:identifier controllers.v4.EventController.update(identifier:String)
+POST /event/v4/publish/:identifier controllers.v4.EventController.publish(identifier:String)
GET /event/v4/read/:identifier controllers.v4.EventController.read(identifier:String, mode:Option[String], fields:Option[String])
DELETE /private/event/v4/discard/:identifier controllers.v4.EventController.discard(identifier:String)
DELETE /event/v4/retire/:identifier controllers.v4.EventController.retire(identifier:String)
@@ -104,6 +105,7 @@ DELETE /event/v4/retire/:identifier controllers.v4.EventController.
# EventSet v4 Api's
POST /eventset/v4/create controllers.v4.EventSetController.create
PATCH /private/eventset/v4/update/:identifier controllers.v4.EventSetController.update(identifier:String)
+POST /eventset/v4/publish/:identifier controllers.v4.EventSetController.publish(identifier:String)
GET /eventset/v4/hierarchy/:identifier controllers.v4.EventSetController.getHierarchy(identifier:String, mode:Option[String])
GET /eventset/v4/read/:identifier controllers.v4.EventSetController.read(identifier:String, mode:Option[String], fields:Option[String])
DELETE /private/eventset/v4/discard/:identifier controllers.v4.EventSetController.discard(identifier:String)
diff --git a/content-api/content-service/test/controllers/v4/EventSetSpec.scala b/content-api/content-service/test/controllers/v4/EventSetSpec.scala
index 4e2dc4d0e..f8fae0283 100644
--- a/content-api/content-service/test/controllers/v4/EventSetSpec.scala
+++ b/content-api/content-service/test/controllers/v4/EventSetSpec.scala
@@ -28,66 +28,57 @@ class EventSetSpec extends BaseSpec {
}
"return success response for read API" in {
- val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val controller = app.injector.instanceOf[controllers.v4.EventSetController]
val result = controller.read("do_123", None, None)(FakeRequest("POST", "/eventset/v4/read "))
isOK(result)
status(result) must equalTo(OK)
}
"return success response for hierarchy get API" in {
- val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val controller = app.injector.instanceOf[controllers.v4.EventSetController]
val result = controller.getHierarchy("do_123", None)(FakeRequest("POST", "/eventset/v4/hierarchy "))
isOK(result)
status(result) must equalTo(OK)
}
"return success response for discard API" in {
- val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val controller = app.injector.instanceOf[controllers.v4.EventSetController]
val result = controller.discard("0123")(FakeRequest("POST", "/eventset/v4/discard "))
isOK(result)
status(result) must equalTo(OK)
}
"return success response for retire API" in {
- val controller = app.injector.instanceOf[controllers.v4.CollectionController]
+ val controller = app.injector.instanceOf[controllers.v4.EventSetController]
val result = controller.retire("0123")(FakeRequest("POST", "/eventset/v4/retire "))
isOK(result)
status(result) must equalTo(OK)
}
- "return success response for collectionLinkDialCode API" in {
- val controller = app.injector.instanceOf[controllers.v4.CollectionController]
- val result = controller.collectionLinkDialCode("do_123")(FakeRequest("POST", "/eventset/v4/dialcode/link "))
+ "return success response for hierarchy update API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventSetController]
+ val json: JsValue = Json.parse("""{"request": {"data": {"mimeType": "application/vnd.ekstep.content-collection"}}}""")
+ val fakeRequest = FakeRequest("POST", "/eventset/v4/hierarchy/update").withJsonBody(json)
+ val result = controller.updateHierarchy()(fakeRequest)
isOK(result)
status(result) must equalTo(OK)
}
- }
-
- "return success response for hierarchy update API" in {
- val controller = app.injector.instanceOf[controllers.v4.CollectionController]
- val json: JsValue = Json.parse("""{"request": {"data": {"mimeType": "application/vnd.ekstep.content-collection"}}}""")
- val fakeRequest = FakeRequest("POST", "/collection/v4/hierarchy/update").withJsonBody(json)
- val result = controller.updateHierarchy()(fakeRequest)
- isOK(result)
- status(result) must equalTo(OK)
- }
- "Collection Controller with invalid request " should {
- "return client error response for create API" in {
- val controller = app.injector.instanceOf[controllers.v4.CollectionController]
- val json: JsValue = Json.parse("""{"request": {"collection": { "contentType": "TextBook"}}}""")
- val fakeRequest = FakeRequest("POST", "/collection/v4/create ").withJsonBody(json)
- val result = controller.create()(fakeRequest)
+ "return error response when updating status using update API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventSetController]
+ val json: JsValue = Json.parse("""{"request": {"eventset": {"status": "Live"}}}""")
+ val fakeRequest = FakeRequest("POST", "/eventset/v4/update ").withJsonBody(json)
+ val result = controller.update("do_123")(fakeRequest)
status(result) must equalTo(BAD_REQUEST)
}
- }
- "Collection Controller with invalid request " should {
- "return client error response for create API" in {
- val controller = app.injector.instanceOf[controllers.v4.CollectionController]
- val json: JsValue = Json.parse("""{"request": {"collection": { "name": "Textbook"}}}""")
- val fakeRequest = FakeRequest("POST", "/collection/v4/create ").withJsonBody(json)
- val result = controller.create()(fakeRequest)
- status(result) must equalTo(BAD_REQUEST)
+ "return success response for publish API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventSetController]
+ val result = controller.publish("do_123")(FakeRequest())
+ isOK(result)
+ status(result) must equalTo(OK)
}
+
}
+
+
}
\ No newline at end of file
diff --git a/content-api/content-service/test/controllers/v4/EventSpec.scala b/content-api/content-service/test/controllers/v4/EventSpec.scala
index 2a17c99b1..e184fd701 100644
--- a/content-api/content-service/test/controllers/v4/EventSpec.scala
+++ b/content-api/content-service/test/controllers/v4/EventSpec.scala
@@ -27,6 +27,28 @@ class EventSpec extends BaseSpec {
status(result) must equalTo(OK)
}
+ "return success response for update API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventController]
+ val result = controller.update("do_123")(FakeRequest())
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
+ "return error response when updating status using update API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventController]
+ val json: JsValue = Json.parse("""{"request": {"event": {"status": "Live"}}}""")
+ val fakeRequest = FakeRequest("POST", "/event/v4/update ").withJsonBody(json)
+ val result = controller.update("do_123")(fakeRequest)
+ status(result) must equalTo(BAD_REQUEST)
+ }
+
+ "return success response for publish API" in {
+ val controller = app.injector.instanceOf[controllers.v4.EventController]
+ val result = controller.publish("do_123")(FakeRequest())
+ isOK(result)
+ status(result) must equalTo(OK)
+ }
+
}
}
\ No newline at end of file
From ed7e8f7b74fcff23d1e2d59fad1176d7b7e68251 Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Mon, 15 Mar 2021 14:47:43 +0530
Subject: [PATCH 21/53] SC-2226 update publish flow and validations
---
.../sunbird/content/actors/EventActor.scala | 97 ++++++++++-----
.../content/actors/EventSetActor.scala | 110 ++++++++++++++++++
.../app/controllers/v4/EventController.scala | 5 +-
.../controllers/v4/EventSetController.scala | 11 +-
.../content-service/app/utils/ApiId.scala | 2 +
content-api/content-service/conf/routes | 20 ++--
schemas/event/1.0/schema.json | 9 +-
schemas/eventset/1.0/schema.json | 9 +-
8 files changed, 199 insertions(+), 64 deletions(-)
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala
index 1c33f3b5c..cd42072d8 100644
--- a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala
@@ -1,8 +1,10 @@
package org.sunbird.content.actors
+import org.apache.commons.lang.StringUtils
import org.sunbird.cloudstore.StorageService
import org.sunbird.common.dto.{Request, Response, ResponseHandler}
-import org.sunbird.common.exception.ResponseCode
+import org.sunbird.common.exception.{ClientException, ResponseCode}
+import org.sunbird.content.util.ContentConstants
import org.sunbird.graph.OntologyEngineContext
import org.sunbird.graph.dac.model.{Node, Relation}
import org.sunbird.graph.nodes.DataNode
@@ -14,36 +16,67 @@ import scala.concurrent.Future
class EventActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageService) extends ContentActor {
- override def dataModifier(node: Node): Node = {
- if(node.getMetadata.containsKey("trackable") &&
- node.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].containsKey("enabled") &&
- "Yes".equalsIgnoreCase(node.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].getOrDefault("enabled", "").asInstanceOf[String])) {
- node.getMetadata.put("contentType", "Event")
- }
- node
- }
-
- override def update(request: Request): Future[Response] = {
- verifyStandaloneEventAndApply(super.update, request)
- }
-
- override def discard(request: Request): Future[Response] = {
- verifyStandaloneEventAndApply(super.discard, request)
- }
-
- override def retire(request: Request): Future[Response] = {
- verifyStandaloneEventAndApply(super.retire, request)
- }
-
- private def verifyStandaloneEventAndApply(f: Request => Future[Response], request: Request):Future[Response] = {
- DataNode.read(request).flatMap(node => {
- val inRelations = if (node.getInRelations == null) new util.ArrayList[Relation]() else node.getInRelations;
- val hasEventSetParent = inRelations.asScala.exists(rel => "EventSet".equalsIgnoreCase(rel.getStartNodeObjectType))
- if (hasEventSetParent)
- Future(ResponseHandler.ERROR(ResponseCode.CLIENT_ERROR, ResponseCode.CLIENT_ERROR.name(), "ERROR: Can't modify an Event which is part of an Event Set!"))
- else
- f.apply(request)
- })
- }
+ override def onReceive(request: Request): Future[Response] = {
+ request.getOperation match {
+ case "createContent" => create(request)
+ case "readContent" => read(request)
+ case "updateContent" => update(request)
+ case "retireContent" => retire(request)
+ case "discardContent" => discard(request)
+ case "publishContent" => publish(request)
+ case _ => ERROR(request.getOperation)
+ }
+ }
+
+ override def update(request: Request): Future[Response] = {
+ verifyStandaloneEventAndApply(super.update, request, Some(node => {
+ if (!"Draft".equalsIgnoreCase(node.getMetadata.getOrDefault("status", "").toString)) {
+ throw new ClientException(ContentConstants.ERR_CONTENT_NOT_DRAFT, "Update not allowed! Event status isn't draft")
+ }
+ }))
+ }
+
+ def publish(request: Request): Future[Response] = {
+ verifyStandaloneEventAndApply(super.update, request, Some(node => {
+ if (!"Draft".equalsIgnoreCase(node.getMetadata.getOrDefault("status", "").toString)) {
+ throw new ClientException(ContentConstants.ERR_CONTENT_NOT_DRAFT, "Publish not allowed! Event status isn't draft")
+ }
+ val versionKey = node.getMetadata.getOrDefault("versionKey", "").toString
+ if (StringUtils.isNotBlank(versionKey))
+ request.put("versionKey", versionKey)
+ }))
+ }
+
+ override def discard(request: Request): Future[Response] = {
+ verifyStandaloneEventAndApply(super.discard, request)
+ }
+
+ override def retire(request: Request): Future[Response] = {
+ verifyStandaloneEventAndApply(super.retire, request)
+ }
+
+ private def verifyStandaloneEventAndApply(f: Request => Future[Response], request: Request, dataUpdater: Option[Node => Unit] = None): Future[Response] = {
+ DataNode.read(request).flatMap(node => {
+ val inRelations = if (node.getInRelations == null) new util.ArrayList[Relation]() else node.getInRelations;
+ val hasEventSetParent = inRelations.asScala.exists(rel => "EventSet".equalsIgnoreCase(rel.getStartNodeObjectType))
+ if (hasEventSetParent)
+ Future(ResponseHandler.ERROR(ResponseCode.CLIENT_ERROR, ResponseCode.CLIENT_ERROR.name(), "ERROR: Can't modify an Event which is part of an Event Set!"))
+ else {
+ if (dataUpdater.isDefined) {
+ dataUpdater.get.apply(node)
+ }
+ f.apply(request)
+ }
+ })
+ }
+
+ override def dataModifier(node: Node): Node = {
+ if (node.getMetadata.containsKey("trackable") &&
+ node.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].containsKey("enabled") &&
+ "Yes".equalsIgnoreCase(node.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].getOrDefault("enabled", "").asInstanceOf[String])) {
+ node.getMetadata.put("contentType", "Event")
+ }
+ node
+ }
}
\ No newline at end of file
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
index 6e536ab35..ffe6f2187 100644
--- a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
@@ -4,6 +4,7 @@ import org.apache.commons.lang3.StringUtils
import org.sunbird.cloudstore.StorageService
import org.sunbird.common.dto.{Request, Response, ResponseHandler}
import org.sunbird.common.exception.{ClientException, ResponseCode}
+import org.sunbird.content.util.{ContentConstants, DiscardManager, RetireManager}
import org.sunbird.graph.OntologyEngineContext
import org.sunbird.graph.common.enums.SystemProperties
import org.sunbird.graph.dac.model.{Node, Relation}
@@ -24,6 +25,7 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
request.getOperation match {
case "createContent" => create(request)
case "updateContent" => update(request)
+ case "publishContent" => publish(request)
case "getHierarchy" => getHierarchy(request)
case "readContent" => read(request)
case "retireContent" => retire(request)
@@ -56,6 +58,9 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
RequestUtil.restrictProperties(request)
val originalRequestContent = request.getRequest
DataNode.read(request).flatMap(node => {
+ if (!"Draft".equalsIgnoreCase(node.getMetadata.getOrDefault("status", "").toString)) {
+ throw new ClientException(ContentConstants.ERR_CONTENT_NOT_DRAFT, "Update not allowed! EventSet status isn't draft")
+ }
deleteExistingEvents(node.getOutRelations, request).flatMap(_ => {
addChildEvents(request).map(nodes => {
updateRequestWithChildRelations(request, originalRequestContent, nodes)
@@ -76,6 +81,51 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
}
}
+ def publish(request: Request): Future[Response] = {
+ DataNode.read(request).flatMap(node => {
+ if (!"Draft".equalsIgnoreCase(node.getMetadata.getOrDefault("status", "").toString)) {
+ throw new ClientException(ContentConstants.ERR_CONTENT_NOT_DRAFT, "Publish not allowed! EventSet status isn't draft")
+ }
+ publishChildEvents(node.getOutRelations, request).flatMap(_ => {
+ val existingVersionKey = node.getMetadata.getOrDefault("versionKey", "").asInstanceOf[String]
+ request.put("versionKey", existingVersionKey)
+ request.getContext.put("identifier", node.getIdentifier)
+ request.put("status", "Live")
+ DataNode.update(request).map(updateNode => {
+ val response: Response = ResponseHandler.OK
+ val identifier: String = updateNode.getIdentifier.replace(".img", "")
+ response.put("node_id", identifier)
+ response.put("identifier", identifier)
+ response.put("versionKey", updateNode.getMetadata.get("versionKey"))
+ response
+ })
+ }
+ )
+ }).recoverWith {
+ case e: Exception =>
+ Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
+ }
+ }
+
+ override def retire(request: Request): Future[Response] = {
+ DataNode.read(request).flatMap(node => {
+ retireChildEvents(node.getOutRelations, request)
+ .flatMap(_ => RetireManager.retire(request))
+ }).recoverWith {
+ case e: Exception =>
+ Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
+ }
+ }
+
+ override def discard(request: Request): Future[Response] = {
+ DataNode.read(request).flatMap(node => discardChildEvents(node.getOutRelations, request)
+ .flatMap(_ => DiscardManager.discard(request)))
+ .recoverWith {
+ case e: Exception =>
+ Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
+ }
+ }
+
def getHierarchy(request: Request): Future[Response] = {
val fields: util.List[String] = seqAsJavaListConverter(request.get("fields").asInstanceOf[String].split(",").filter(field => StringUtils.isNotBlank(field) && !StringUtils.equalsIgnoreCase(field, "null"))).asJava
request.getRequest.put("fields", fields)
@@ -143,4 +193,64 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
else
Future(List())
}
+
+ private def publishChildEvents(relations: util.List[Relation], request: Request) = {
+ if (relations != null)
+ Future.sequence(relations.asScala.filter(rel => "Event".equalsIgnoreCase(rel.getEndNodeObjectType)).map(relation => {
+ val updateReq = new Request()
+ val context = new util.HashMap[String, Object]()
+ context.putAll(request.getContext)
+ updateReq.setContext(context)
+ updateReq.getContext.put("schemaName", "event")
+ updateReq.getContext.put("objectType", "Event")
+ updateReq.getContext.put("identifier", relation.getEndNodeId)
+ val updateMap = new util.HashMap[String, AnyRef]()
+ updateMap.put("identifier", relation.getEndNodeId)
+ updateMap.put("status", "Live")
+ updateReq.setRequest(updateMap)
+ DataNode.update(updateReq)
+ }))
+ else
+ Future(List())
+ }
+
+ private def retireChildEvents(relations: util.List[Relation], request: Request) = {
+ if (relations != null)
+ Future.sequence(relations.asScala.filter(rel => "Event".equalsIgnoreCase(rel.getEndNodeObjectType)).map(relation => {
+ val retireReq = new Request()
+ val context = new util.HashMap[String, Object]()
+ context.putAll(request.getContext)
+ retireReq.setContext(context)
+ retireReq.getContext.put("schemaName", "event")
+ retireReq.getContext.put("objectType", "Event")
+ retireReq.getContext.put("identifier", relation.getEndNodeId)
+ val updateMap = new util.HashMap[String, AnyRef]()
+ updateMap.put("identifier", relation.getEndNodeId)
+ retireReq.setRequest(updateMap)
+ RetireManager.retire(retireReq)
+
+ }))
+ else
+ Future(List())
+ }
+
+ private def discardChildEvents(relations: util.List[Relation], request: Request) = {
+ if (relations != null)
+ Future.sequence(relations.asScala.filter(rel => "Event".equalsIgnoreCase(rel.getEndNodeObjectType)).map(relation => {
+ val discardReq = new Request()
+ val context = new util.HashMap[String, Object]()
+ context.putAll(request.getContext)
+ discardReq.setContext(context)
+ discardReq.getContext.put("schemaName", "event")
+ discardReq.getContext.put("objectType", "Event")
+ discardReq.getContext.put("identifier", relation.getEndNodeId)
+ val updateMap = new util.HashMap[String, AnyRef]()
+ updateMap.put("identifier", relation.getEndNodeId)
+ discardReq.setRequest(updateMap)
+ RetireManager.retire(discardReq)
+
+ }))
+ else
+ Future(List())
+ }
}
\ No newline at end of file
diff --git a/content-api/content-service/app/controllers/v4/EventController.scala b/content-api/content-service/app/controllers/v4/EventController.scala
index c7fce266e..3b609d32b 100644
--- a/content-api/content-service/app/controllers/v4/EventController.scala
+++ b/content-api/content-service/app/controllers/v4/EventController.scala
@@ -59,11 +59,12 @@ class EventController @Inject()(@Named(ActorNames.EVENT_ACTOR) eventActor: Actor
val headers = commonHeaders()
val content = new java.util.HashMap[String, Object]()
content.put("status", "Live")
+ content.put("identifier", identifier)
content.putAll(headers)
- val contentRequest = getRequest(content, headers, "updateContent")
+ val contentRequest = getRequest(content, headers, "publishContent")
setRequestContext(contentRequest, version, objectType, schemaName)
contentRequest.getContext.put("identifier", identifier);
- getResult(ApiId.UPDATE_EVENT, eventActor, contentRequest, version = apiVersion)
+ getResult(ApiId.PUBLISH_EVENT, eventActor, contentRequest, version = apiVersion)
}
}
\ No newline at end of file
diff --git a/content-api/content-service/app/controllers/v4/EventSetController.scala b/content-api/content-service/app/controllers/v4/EventSetController.scala
index d1f040774..76f014098 100644
--- a/content-api/content-service/app/controllers/v4/EventSetController.scala
+++ b/content-api/content-service/app/controllers/v4/EventSetController.scala
@@ -39,11 +39,11 @@ class EventSetController @Inject()(@Named(ActorNames.EVENT_SET_ACTOR) eventSetAc
getResult(ApiId.READ_COLLECTION, eventSetActor, readRequest, version = apiVersion)
}
- override def getHierarchy(identifier: String, mode: Option[String]) = Action.async { implicit request =>
+ def getHierarchy(identifier: String, mode: Option[String], fields: Option[String]) = Action.async { implicit request =>
val headers = commonHeaders()
val content = new java.util.HashMap().asInstanceOf[java.util.Map[String, Object]]
content.putAll(headers)
- content.putAll(Map("identifier" -> identifier, "mode" -> mode.getOrElse("read")).asJava)
+ content.putAll(Map("identifier" -> identifier, "mode" -> mode.getOrElse("read"), "fields" -> fields.getOrElse("")).asJava)
val readRequest = getRequest(content, headers, "getHierarchy")
setRequestContext(readRequest, version, objectType, schemaName)
getResult(ApiId.READ_COLLECTION, eventSetActor, readRequest, version = apiVersion)
@@ -67,12 +67,11 @@ class EventSetController @Inject()(@Named(ActorNames.EVENT_SET_ACTOR) eventSetAc
def publish(identifier: String): Action[AnyContent] = Action.async { implicit request =>
val headers = commonHeaders()
val content = new java.util.HashMap[String, Object]()
- content.put("status", "Live")
+ content.put("identifier", identifier)
content.putAll(headers)
- val contentRequest = getRequest(content, headers, "updateContent")
+ val contentRequest = getRequest(content, headers, "publishContent")
setRequestContext(contentRequest, version, objectType, schemaName)
- contentRequest.getContext.put("identifier", identifier)
- getResult(ApiId.UPDATE_EVENT_SET, eventSetActor, contentRequest, version = apiVersion)
+ getResult(ApiId.PUBLISH_EVENT_SET, eventSetActor, contentRequest, version = apiVersion)
}
diff --git a/content-api/content-service/app/utils/ApiId.scala b/content-api/content-service/app/utils/ApiId.scala
index 2337cd3ec..f8ec07127 100644
--- a/content-api/content-service/app/utils/ApiId.scala
+++ b/content-api/content-service/app/utils/ApiId.scala
@@ -74,5 +74,7 @@ object ApiId {
val CREATE_EVENT_SET = "api.eventset.create"
val UPDATE_EVENT_SET = "api.eventset.update"
+ val PUBLISH_EVENT_SET = "api.eventset.publish"
+ val PUBLISH_EVENT = "api.event.publish"
}
diff --git a/content-api/content-service/conf/routes b/content-api/content-service/conf/routes
index 0d2189dd4..f6340ee52 100644
--- a/content-api/content-service/conf/routes
+++ b/content-api/content-service/conf/routes
@@ -95,18 +95,18 @@ DELETE /content/v4/discard/:identifier controllers.v4.ContentControl
DELETE /content/v4/retire/:identifier controllers.v4.ContentController.retire(identifier:String)
# Event APIs
-POST /event/v4/create controllers.v4.EventController.create
-PATCH /event/v4/update/:identifier controllers.v4.EventController.update(identifier:String)
-POST /event/v4/publish/:identifier controllers.v4.EventController.publish(identifier:String)
-GET /event/v4/read/:identifier controllers.v4.EventController.read(identifier:String, mode:Option[String], fields:Option[String])
-DELETE /private/event/v4/discard/:identifier controllers.v4.EventController.discard(identifier:String)
-DELETE /event/v4/retire/:identifier controllers.v4.EventController.retire(identifier:String)
+POST /event/v4/create controllers.v4.EventController.create
+PATCH /event/v4/update/:identifier controllers.v4.EventController.update(identifier:String)
+POST /event/v4/publish/:identifier controllers.v4.EventController.publish(identifier:String)
+GET /event/v4/read/:identifier controllers.v4.EventController.read(identifier:String, mode:Option[String], fields:Option[String])
+DELETE /event/v4/discard/:identifier controllers.v4.EventController.discard(identifier:String)
+DELETE /private/event/v4/retire/:identifier controllers.v4.EventController.retire(identifier:String)
# EventSet v4 Api's
POST /eventset/v4/create controllers.v4.EventSetController.create
-PATCH /private/eventset/v4/update/:identifier controllers.v4.EventSetController.update(identifier:String)
+PUT /eventset/v4/update/:identifier controllers.v4.EventSetController.update(identifier:String)
POST /eventset/v4/publish/:identifier controllers.v4.EventSetController.publish(identifier:String)
-GET /eventset/v4/hierarchy/:identifier controllers.v4.EventSetController.getHierarchy(identifier:String, mode:Option[String])
+GET /eventset/v4/hierarchy/:identifier controllers.v4.EventSetController.getHierarchy(identifier:String, mode:Option[String], fields:Option[String])
GET /eventset/v4/read/:identifier controllers.v4.EventSetController.read(identifier:String, mode:Option[String], fields:Option[String])
-DELETE /private/eventset/v4/discard/:identifier controllers.v4.EventSetController.discard(identifier:String)
-DELETE /eventset/v4/retire/:identifier controllers.v4.EventSetController.retire(identifier:String)
\ No newline at end of file
+DELETE /eventset/v4/discard/:identifier controllers.v4.EventSetController.discard(identifier:String)
+DELETE /private/eventset/v4/retire/:identifier controllers.v4.EventSetController.retire(identifier:String)
\ No newline at end of file
diff --git a/schemas/event/1.0/schema.json b/schemas/event/1.0/schema.json
index f6894addb..69556357c 100644
--- a/schemas/event/1.0/schema.json
+++ b/schemas/event/1.0/schema.json
@@ -186,20 +186,15 @@
"enum": ["Yes","No"],
"default": "Yes"
},
- "fixedBatch": {
+ "autoBatch": {
"type": "string",
"enum": ["Yes","No"],
"default": "Yes"
- },
- "fixedBatchId": {
- "type": "string",
- "default": "event_batch_id"
}
},
"default": {
"enabled": "Yes",
- "fixedBatch": "Yes",
- "fixedBatchId": "event_batch_id"
+ "autoBatch": "Yes"
},
"additionalProperties": false
},
diff --git a/schemas/eventset/1.0/schema.json b/schemas/eventset/1.0/schema.json
index 0a04c1622..4c0774664 100644
--- a/schemas/eventset/1.0/schema.json
+++ b/schemas/eventset/1.0/schema.json
@@ -195,20 +195,15 @@
"enum": ["Yes","No"],
"default": "Yes"
},
- "fixedBatch": {
+ "autoBatch": {
"type": "string",
"enum": ["Yes","No"],
"default": "Yes"
- },
- "fixedBatchId": {
- "type": "string",
- "default": "event_batch_id"
}
},
"default": {
"enabled": "Yes",
- "fixedBatch": "Yes",
- "fixedBatchId": "event_batch_id"
+ "autoBatch": "Yes"
},
"additionalProperties": false
},
From 9b62708ff0f6da24ef1d30cf4e8b7fbe599dcc55 Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Mon, 15 Mar 2021 16:44:45 +0530
Subject: [PATCH 22/53] SC-2226 update publish flow and validations
---
.../content/actors/EventSetActor.scala | 14 +++++++++--
.../content/actors/TestEventActor.scala | 25 ++++++++++++++++++-
.../content/actors/TestEventSetActor.scala | 24 ++++++++----------
3 files changed, 46 insertions(+), 17 deletions(-)
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
index ffe6f2187..2f7e51529 100644
--- a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventSetActor.scala
@@ -48,6 +48,8 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
response
})
}).recoverWith {
+ case clientException: ClientException =>
+ Future(ResponseHandler.ERROR(ResponseCode.CLIENT_ERROR, ResponseCode.CLIENT_ERROR.name(), clientException.getMessage))
case e: Exception =>
Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
}
@@ -76,6 +78,8 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
)
})
}).recoverWith {
+ case clientException: ClientException =>
+ Future(ResponseHandler.ERROR(ResponseCode.CLIENT_ERROR, ResponseCode.CLIENT_ERROR.name(), clientException.getMessage))
case e: Exception =>
Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
}
@@ -102,6 +106,8 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
}
)
}).recoverWith {
+ case clientException: ClientException =>
+ Future(ResponseHandler.ERROR(ResponseCode.CLIENT_ERROR, ResponseCode.CLIENT_ERROR.name(), clientException.getMessage))
case e: Exception =>
Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
}
@@ -112,6 +118,8 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
retireChildEvents(node.getOutRelations, request)
.flatMap(_ => RetireManager.retire(request))
}).recoverWith {
+ case clientException: ClientException =>
+ Future(ResponseHandler.ERROR(ResponseCode.CLIENT_ERROR, ResponseCode.CLIENT_ERROR.name(), clientException.getMessage))
case e: Exception =>
Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
}
@@ -121,8 +129,10 @@ class EventSetActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageSe
DataNode.read(request).flatMap(node => discardChildEvents(node.getOutRelations, request)
.flatMap(_ => DiscardManager.discard(request)))
.recoverWith {
- case e: Exception =>
- Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
+ case clientException: ClientException =>
+ Future(ResponseHandler.ERROR(ResponseCode.CLIENT_ERROR, ResponseCode.CLIENT_ERROR.name(), clientException.getMessage))
+ case e: Exception =>
+ Future(ResponseHandler.ERROR(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR.name(), e.getMessage))
}
}
diff --git a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala
index 31c46f1a2..2d30e21a9 100644
--- a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala
+++ b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala
@@ -80,7 +80,7 @@ class TestEventActor extends BaseSpec with MockFactory {
implicit val ss = mock[StorageService]
val graphDB = mock[GraphService]
(oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
- val node = getNode()
+ val node = getDraftNode()
(graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(node)).anyNumberOfTimes()
(graphDB.upsertNode(_: String, _: Node, _: Request)).expects(*, *, *).returns(Future(node))
val request = getContentRequest()
@@ -169,4 +169,27 @@ class TestEventActor extends BaseSpec with MockFactory {
})
node
}
+ private def getDraftNode(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_1234")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("Event")
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_1234")
+ put("status", "Draft")
+ put("name", "Resource_1")
+ put("versionKey", "test_321")
+ put("channel", "in.ekstep")
+ put("code", "Resource_1")
+ put("startDate", "2021-02-02")
+ put("endDate", "2021-02-02")
+ put("startTime", "11:00:00Z")
+ put("endTime", "12:00:00Z")
+ put("registrationEndDate", "2021-01-02")
+ put("eventType", "Online")
+ }
+ })
+ node
+ }
}
diff --git a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
index 4a6178c4a..53f0747ad 100644
--- a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
+++ b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
@@ -126,8 +126,8 @@ class TestEventSetActor extends BaseSpec with MockFactory {
it should "discard node in draft state should return success" in {
implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
val graphDB = mock[GraphService]
- (oec.graphService _).expects().returns(graphDB).repeated(2)
- (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getValidNodeToDiscard()))
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getValidNodeToDiscard())).twice()
(graphDB.deleteNode(_: String, _: String, _: Request)).expects(*, *, *).returns(Future(true))
implicit val ss = mock[StorageService]
val request = getContentRequest()
@@ -143,8 +143,8 @@ class TestEventSetActor extends BaseSpec with MockFactory {
it should "discard node in Live state should return client error" in {
implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
val graphDB = mock[GraphService]
- (oec.graphService _).expects().returns(graphDB).repeated(1)
- (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getInValidNodeToDiscard()))
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getInValidNodeToDiscard())).twice()
implicit val ss = mock[StorageService]
val request = getContentRequest()
request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_12346")))
@@ -156,7 +156,7 @@ class TestEventSetActor extends BaseSpec with MockFactory {
it should "return success response for retireContent" in {
implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
val graphDB = mock[GraphService]
- (oec.graphService _).expects().returns(graphDB).repeated(2)
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
val node = getNode("EventSet", None)
(graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(node)).anyNumberOfTimes()
(graphDB.updateNodes(_: String, _: util.List[String], _: util.HashMap[String, AnyRef])).expects(*, *, *).returns(Future(new util.HashMap[String, Node]))
@@ -218,15 +218,13 @@ class TestEventSetActor extends BaseSpec with MockFactory {
val node = new Node()
node.setIdentifier("do_12346")
node.setNodeType("DATA_NODE")
- node.setObjectType("Content")
+ node.setObjectType("EventSet")
node.setMetadata(new util.HashMap[String, AnyRef]() {
{
put("identifier", "do_12346")
- put("mimeType", "application/pdf")
put("status", "Draft")
- put("contentType", "Resource")
+ put("contentType", "EventSet")
put("name", "Node To discard")
- put("primaryCategory", "Learning Resource")
}
})
node
@@ -236,15 +234,13 @@ class TestEventSetActor extends BaseSpec with MockFactory {
val node = new Node()
node.setIdentifier("do_12346")
node.setNodeType("DATA_NODE")
- node.setObjectType("Content")
+ node.setObjectType("EventSet")
node.setMetadata(new util.HashMap[String, AnyRef]() {
{
put("identifier", "do_12346")
- put("mimeType", "application/pdf")
put("status", "Live")
- put("contentType", "Resource")
+ put("contentType", "EventSet")
put("name", "Node To discard")
- put("primaryCategory", "Learning Resource")
}
})
node
@@ -281,7 +277,7 @@ class TestEventSetActor extends BaseSpec with MockFactory {
node.setMetadata(new util.HashMap[String, AnyRef]() {
{
put("identifier", "do_12345")
- put("status", "Live")
+ put("status", "Draft")
put("name", "EventSet_1")
put("code", "eventset1")
put("versionKey", "1878141")
From 75b46ad7d96219949ccb25228805624c8c3282a0 Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Mon, 15 Mar 2021 20:04:45 +0530
Subject: [PATCH 23/53] SC-2226 update publish flow and validations
---
.circleci/config.yml | 11 +-
.../content/actors/TestEventActor.scala | 17 +++
.../content/actors/TestEventSetActor.scala | 112 ++++++++++++++++--
.../test/controllers/v4/EventSetSpec.scala | 11 +-
4 files changed, 133 insertions(+), 18 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index f514b7203..7e9202031 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -12,7 +12,16 @@ jobs:
- run:
name: Setup VM and Build
command: bash vmsetup.sh
-
+ - run:
+ name: Save test results
+ command: |
+ mkdir -p ~/test-results/junit/
+ find . -type f -regex ".*/target/surefire-reports/.*xml" -exec cp {} ~/test-results/junit/ \;
+ when: always
+ - store_test_results:
+ path: ~/test-results
+ - store_artifacts:
+ path: ~/test-results/junit
workflows:
version: 2.1
workflow:
diff --git a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala
index 2d30e21a9..9951be514 100644
--- a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala
+++ b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventActor.scala
@@ -32,6 +32,23 @@ class TestEventActor extends BaseSpec with MockFactory {
}
+ it should "publish node in draft state should return success" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getDraftNode())).anyNumberOfTimes()
+ (graphDB.upsertNode(_: String, _: Node, _: Request)).expects(*, *, *).returns(Future(getDraftNode()))
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getContext.put("identifier", "do_1234")
+ request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_1234")))
+ request.setOperation("publishContent")
+ val response = callActor(request, Props(new EventActor()))
+ assert(response.getResponseCode == ResponseCode.OK)
+ assert(response.get("identifier") == "do_1234")
+
+ }
+
it should "discard node in Live state should return client error" in {
implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
val graphDB = mock[GraphService]
diff --git a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
index 53f0747ad..961c4ae1a 100644
--- a/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
+++ b/content-api/content-actors/src/test/scala/org/sunbird/content/actors/TestEventSetActor.scala
@@ -7,7 +7,7 @@ import org.sunbird.common.JsonUtils
import org.sunbird.common.dto.{Request, Response}
import org.sunbird.common.exception.ResponseCode
import org.sunbird.graph.common.enums.GraphDACParams
-import org.sunbird.graph.dac.model.{Node, SearchCriteria}
+import org.sunbird.graph.dac.model.{Node, Relation, SearchCriteria}
import org.sunbird.graph.{GraphService, OntologyEngineContext}
import java.util
@@ -84,11 +84,13 @@ class TestEventSetActor extends BaseSpec with MockFactory {
it should "update an eventset and store it in neo4j" in {
val eventNode = getEventNode()
- val eventSetNode = getEventSetNode()
+ val eventSetNode = getEventSetCollectionNode()
implicit val ss = mock[StorageService]
implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
val graphDB = mock[GraphService]
(oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ (graphDB.deleteNode(_: String, _: String, _: Request)).expects(*, *, *).returns(Future(true))
+ (graphDB.removeRelation(_: String, _: util.List[util.Map[String, AnyRef]])).expects(*, *).returns(Future(new Response))
(graphDB.addNode _).expects(where { (g: String, n:Node) => {
n.getObjectType.equals("Event")
}}).returns(Future(eventNode))
@@ -127,7 +129,7 @@ class TestEventSetActor extends BaseSpec with MockFactory {
implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
val graphDB = mock[GraphService]
(oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
- (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getValidNodeToDiscard())).twice()
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getValidDraftNode())).twice()
(graphDB.deleteNode(_: String, _: String, _: Request)).expects(*, *, *).returns(Future(true))
implicit val ss = mock[StorageService]
val request = getContentRequest()
@@ -140,11 +142,28 @@ class TestEventSetActor extends BaseSpec with MockFactory {
}
+ it should "publish node in draft state should return success" in {
+ implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
+ val graphDB = mock[GraphService]
+ (oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
+ val eventSetNode = getEventSetCollectionNode()
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(eventSetNode)).anyNumberOfTimes()
+ (graphDB.upsertNode _).expects(*, *, *).returns(Future(eventSetNode)).anyNumberOfTimes()
+ implicit val ss = mock[StorageService]
+ val request = getContentRequest()
+ request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_12346")))
+ request.setOperation("publishContent")
+ val response = callActor(request, Props(new EventSetActor()))
+ assert(response.getResponseCode == ResponseCode.OK)
+ assert(response.get("identifier") == "do_12345")
+ }
+
it should "discard node in Live state should return client error" in {
implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
val graphDB = mock[GraphService]
(oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
- (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getInValidNodeToDiscard())).twice()
+ (graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(getLiveEventSetCollectionNode())).anyNumberOfTimes()
+ (graphDB.updateNodes(_: String, _: util.List[String], _: util.HashMap[String, AnyRef])).expects(*, *, *).returns(Future(new util.HashMap[String, Node])).anyNumberOfTimes()
implicit val ss = mock[StorageService]
val request = getContentRequest()
request.getRequest.putAll(mapAsJavaMap(Map("identifier" -> "do_12346")))
@@ -157,9 +176,9 @@ class TestEventSetActor extends BaseSpec with MockFactory {
implicit val oec: OntologyEngineContext = mock[OntologyEngineContext]
val graphDB = mock[GraphService]
(oec.graphService _).expects().returns(graphDB).anyNumberOfTimes()
- val node = getNode("EventSet", None)
+ val node = getEventSetCollectionNode()
(graphDB.getNodeByUniqueId(_: String, _: String, _: Boolean, _: Request)).expects(*, *, *, *).returns(Future(node)).anyNumberOfTimes()
- (graphDB.updateNodes(_: String, _: util.List[String], _: util.HashMap[String, AnyRef])).expects(*, *, *).returns(Future(new util.HashMap[String, Node]))
+ (graphDB.updateNodes(_: String, _: util.List[String], _: util.HashMap[String, AnyRef])).expects(*, *, *).returns(Future(new util.HashMap[String, Node])).anyNumberOfTimes()
implicit val ss = mock[StorageService]
val request = getContentRequest()
request.getContext.put("identifier","do1234")
@@ -214,7 +233,7 @@ class TestEventSetActor extends BaseSpec with MockFactory {
request
}
- private def getValidNodeToDiscard(): Node = {
+ private def getValidDraftNode(): Node = {
val node = new Node()
node.setIdentifier("do_12346")
node.setNodeType("DATA_NODE")
@@ -285,6 +304,85 @@ class TestEventSetActor extends BaseSpec with MockFactory {
put("endDate", "2021-02-02")
put("registrationEndDate", "2021-01-02")
put("eventType", "Online")
+ put("schedule",
+ mapAsJavaMap(Map("type" -> "NON_RECURRING",
+ "value" -> List(mapAsJavaMap(Map("startDate" -> "2021-01-03",
+ "endDate" -> "2021-01-03",
+ "startTime" -> "11:00:00Z",
+ "endTime" -> "13:00:00Z"))).asJava)))
+
+ }
+ })
+ node
+ }
+
+ private def getEventSetCollectionNode(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_12345")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("EventSet")
+ val rel: Relation = new Relation()
+ rel.setEndNodeObjectType("Event")
+ rel.setEndNodeId("do_12345.1")
+ rel.setStartNodeId("do_12345")
+ rel.setRelationType("hasSequenceMember")
+ node.setOutRelations(new util.ArrayList[Relation](){
+ add(rel)
+ })
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_12345")
+ put("status", "Draft")
+ put("name", "EventSet_1")
+ put("code", "eventset1")
+ put("versionKey", "1878141")
+ put("startDate", "2021-02-02")
+ put("endDate", "2021-02-02")
+ put("registrationEndDate", "2021-01-02")
+ put("eventType", "Online")
+ put("schedule",
+ mapAsJavaMap(Map("type" -> "NON_RECURRING",
+ "value" -> List(mapAsJavaMap(Map("startDate" -> "2021-01-03",
+ "endDate" -> "2021-01-03",
+ "startTime" -> "11:00:00Z",
+ "endTime" -> "13:00:00Z",
+ "status" -> "Draft"))).asJava)))
+
+ }
+ })
+ node
+ }
+
+ private def getLiveEventSetCollectionNode(): Node = {
+ val node = new Node()
+ node.setIdentifier("do_12345")
+ node.setNodeType("DATA_NODE")
+ node.setObjectType("EventSet")
+ val rel: Relation = new Relation()
+ rel.setEndNodeObjectType("Event")
+ rel.setEndNodeId("do_12345.1")
+ node.setOutRelations(new util.ArrayList[Relation](){
+ add(rel)
+ })
+ node.setMetadata(new util.HashMap[String, AnyRef]() {
+ {
+ put("identifier", "do_12345")
+ put("status", "Live")
+ put("name", "EventSet_1")
+ put("code", "eventset1")
+ put("versionKey", "1878141")
+ put("startDate", "2021-02-02")
+ put("endDate", "2021-02-02")
+ put("registrationEndDate", "2021-01-02")
+ put("eventType", "Online")
+ put("schedule",
+ mapAsJavaMap(Map("type" -> "NON_RECURRING",
+ "value" -> List(mapAsJavaMap(Map("startDate" -> "2021-01-03",
+ "endDate" -> "2021-01-03",
+ "startTime" -> "11:00:00Z",
+ "endTime" -> "13:00:00Z",
+ "status" -> "Live"))).asJava)))
+
}
})
node
diff --git a/content-api/content-service/test/controllers/v4/EventSetSpec.scala b/content-api/content-service/test/controllers/v4/EventSetSpec.scala
index f8fae0283..2fcbcf0ed 100644
--- a/content-api/content-service/test/controllers/v4/EventSetSpec.scala
+++ b/content-api/content-service/test/controllers/v4/EventSetSpec.scala
@@ -36,7 +36,7 @@ class EventSetSpec extends BaseSpec {
"return success response for hierarchy get API" in {
val controller = app.injector.instanceOf[controllers.v4.EventSetController]
- val result = controller.getHierarchy("do_123", None)(FakeRequest("POST", "/eventset/v4/hierarchy "))
+ val result = controller.getHierarchy("do_123", None, None)(FakeRequest("POST", "/eventset/v4/hierarchy "))
isOK(result)
status(result) must equalTo(OK)
}
@@ -54,15 +54,6 @@ class EventSetSpec extends BaseSpec {
status(result) must equalTo(OK)
}
- "return success response for hierarchy update API" in {
- val controller = app.injector.instanceOf[controllers.v4.EventSetController]
- val json: JsValue = Json.parse("""{"request": {"data": {"mimeType": "application/vnd.ekstep.content-collection"}}}""")
- val fakeRequest = FakeRequest("POST", "/eventset/v4/hierarchy/update").withJsonBody(json)
- val result = controller.updateHierarchy()(fakeRequest)
- isOK(result)
- status(result) must equalTo(OK)
- }
-
"return error response when updating status using update API" in {
val controller = app.injector.instanceOf[controllers.v4.EventSetController]
val json: JsValue = Json.parse("""{"request": {"eventset": {"status": "Live"}}}""")
From 8f88d63767eb73bbb1dfd6be0a67c75c46323cd2 Mon Sep 17 00:00:00 2001
From: Nitin Puri
Date: Mon, 15 Mar 2021 20:10:35 +0530
Subject: [PATCH 24/53] SC-2226 update publish flow and validations
---
.circleci/config.yml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 7e9202031..950389788 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -18,10 +18,10 @@ jobs:
mkdir -p ~/test-results/junit/
find . -type f -regex ".*/target/surefire-reports/.*xml" -exec cp {} ~/test-results/junit/ \;
when: always
- - store_test_results:
- path: ~/test-results
- - store_artifacts:
- path: ~/test-results/junit
+ - store_test_results:
+ path: ~/test-results
+ - store_artifacts:
+ path: ~/test-results/junit
workflows:
version: 2.1
workflow:
From 795f809e16399f78e80376bd1c5d7a50e0468166 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Thu, 29 Apr 2021 19:04:40 +0530
Subject: [PATCH 25/53] removed cloud-store-sdk dependencies
---
platform-modules/mimetype-manager/pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/platform-modules/mimetype-manager/pom.xml b/platform-modules/mimetype-manager/pom.xml
index 9f609b0e2..2473f765b 100644
--- a/platform-modules/mimetype-manager/pom.xml
+++ b/platform-modules/mimetype-manager/pom.xml
@@ -13,7 +13,7 @@
2.11
2.7.2
-
+
org.sunbird
platform-common
From c099fefeaf3417195f83ebdf6a90eeda2d36ca24 Mon Sep 17 00:00:00 2001
From: pritha-tarento <42533384+pritha-tarento@users.noreply.github.com>
Date: Fri, 30 Apr 2021 13:12:43 +0530
Subject: [PATCH 26/53] Update pom.xml
---
platform-modules/mimetype-manager/pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/platform-modules/mimetype-manager/pom.xml b/platform-modules/mimetype-manager/pom.xml
index 2473f765b..a11b081fb 100644
--- a/platform-modules/mimetype-manager/pom.xml
+++ b/platform-modules/mimetype-manager/pom.xml
@@ -22,9 +22,9 @@
false
-
+ -->
-
+