Upgrade event schema to support delete operation

Issue-ID: CPS-789
Signed-off-by: Renu Kumari <renu.kumari@bell.ca>
Change-Id: I2625f0cc068618bea820ad9503ee75c5a7ae4c5f
diff --git a/cps-events/src/main/resources/schemas/cps-data-updated-event-schema.json b/cps-events/src/main/resources/schemas/cps-data-updated-event-schema.json
index 95dc605..3c95664 100644
--- a/cps-events/src/main/resources/schemas/cps-data-updated-event-schema.json
+++ b/cps-events/src/main/resources/schemas/cps-data-updated-event-schema.json
@@ -1,7 +1,7 @@
 {
 
   "$schema": "https://json-schema.org/draft/2019-09/schema",
-  "$id": "urn:cps:org.onap.cps:data-updated-event-schema:v1",
+  "$id": "urn:cps:org.onap.cps:data-updated-event-schema:v2",
 
   "$ref": "#/definitions/CpsDataUpdatedEvent",
 
@@ -40,7 +40,7 @@
         "type",
         "content"
       ],
-      "additionalProperties": false
+      "additionalProperties": true
     },
 
     "Content": {
@@ -63,6 +63,11 @@
           "description": "The name of CPS Core anchor the data is attached to.",
           "type": "string"
         },
+        "operation": {
+          "description": "The operation on the data",
+          "type": "string",
+          "enum": ["CREATE", "UPDATE", "DELETE"]
+        },
         "data": {
           "$ref": "#/definitions/Data"
         }
@@ -71,10 +76,9 @@
         "observedTimestamp",
         "dataspaceName",
         "schemaSetName",
-        "anchorName",
-        "data"
+        "anchorName"
       ],
-      "additionalProperties": false
+      "additionalProperties": true
     },
 
     "Data": {
diff --git a/cps-events/src/test/groovy/org/onap/cps/event/CpsDataUpdatedEventSpec.groovy b/cps-events/src/test/groovy/org/onap/cps/event/CpsDataUpdatedEventSpec.groovy
index 545b183..aac0b5a 100644
--- a/cps-events/src/test/groovy/org/onap/cps/event/CpsDataUpdatedEventSpec.groovy
+++ b/cps-events/src/test/groovy/org/onap/cps/event/CpsDataUpdatedEventSpec.groovy
@@ -23,6 +23,7 @@
 import org.onap.cps.event.model.Content
 import org.onap.cps.event.model.CpsDataUpdatedEvent
 import org.onap.cps.event.model.Data
+import spock.lang.Shared
 import spock.lang.Specification
 
 /**
@@ -39,8 +40,10 @@
     final EVENT_ID = '77b8f114-4562-4069-8234-6d059ff742ac'
     final EVENT_SOURCE = new URI('urn:cps:org.onap.cps')
     final EVENT_TYPE = 'org.onap.cps.data-updated-event'
-    final EVENT_SCHEMA = new URI('urn:cps:org.onap.cps:data-updated-event-schema:v1')
+    final EVENT_SCHEMA_V1 = new URI('urn:cps:org.onap.cps:data-updated-event-schema:v1')
+    final EVENT_SCHEMA_V2 = new URI('urn:cps:org.onap.cps:data-updated-event-schema:v2')
 
+    @Shared
     final DATA = [
             'test:bookstore': [
                     'bookstore-name': 'Chapters',
@@ -60,14 +63,14 @@
             ]
     ]
 
-    def 'Conversion from JSON String to CpsDataUpdatedEvent POJO.'() {
-        when: 'event JSON String is converted to CpsDataUpdatedEvent'
-            def notificationMessage = getEventAsJsonStringFromFile()
+    def 'Conversion from Event V1 JSON String to CpsDataUpdatedEvent POJO.'() {
+        when: 'event V1 JSON String is converted to CpsDataUpdatedEvent'
+            def notificationMessage = getEventAsJsonStringFromFile('/event-v1.json')
             def cpsDataUpdatedEvent = objectMapper.readValue(notificationMessage, CpsDataUpdatedEvent.class)
         then: 'CpsDataUpdatedEvent POJO has the excepted values'
             cpsDataUpdatedEvent.id == EVENT_ID
             cpsDataUpdatedEvent.source == EVENT_SOURCE
-            cpsDataUpdatedEvent.schema == EVENT_SCHEMA
+            cpsDataUpdatedEvent.schema == EVENT_SCHEMA_V1
             cpsDataUpdatedEvent.type == EVENT_TYPE
             def content = cpsDataUpdatedEvent.content
             content.observedTimestamp == EVENT_TIMESTAMP
@@ -77,8 +80,37 @@
             content.data.getAdditionalProperties() == DATA
     }
 
-    def 'Conversion CpsDataUpdatedEvent POJO to JSON String.'() {
-        given: 'Event content with the Data'
+    def 'Conversion from Event V2 JSON String to CpsDataUpdatedEvent POJO'() {
+        when: 'event V2 JSON String is converted to CpsDataUpdatedEvent'
+            def notificationMessage = getEventAsJsonStringFromFile(inputEventJson)
+            def cpsDataUpdatedEvent = objectMapper.readValue(notificationMessage, CpsDataUpdatedEvent.class)
+        then: 'CpsDataUpdatedEvent POJO has the excepted values'
+            with(cpsDataUpdatedEvent) {
+                id == EVENT_ID
+                source == EVENT_SOURCE
+                schema == EVENT_SCHEMA_V2
+                type == EVENT_TYPE
+            }
+            with(cpsDataUpdatedEvent.content) {
+                observedTimestamp == EVENT_TIMESTAMP
+                dataspaceName == DATASPACE_NAME
+                schemaSetName == BOOKSTORE_SCHEMA_SET
+                anchorName == ANCHOR_NAME
+                operation == expectedOperation
+                if (expectedData != null)
+                    data.getAdditionalProperties() == expectedData
+                else
+                    data == null
+            }
+        where:
+            scenario                        | inputEventJson                              || expectedData | expectedOperation
+            'create operation'              | '/event-v2-create-operation.json'           || DATA         | Content.Operation.CREATE
+            'delete operation'              | '/event-v2-delete-operation.json'           || null         | Content.Operation.DELETE
+            'create with additional fields' | '/event-v2-with-additional-properties.json' || DATA         | Content.Operation.CREATE
+    }
+
+    def 'Conversion from CpsDataUpdatedEvent POJO to Event V2 JSON String.'() {
+        given: 'Event V2 content with the Data'
             def data = new Data()
             data.withAdditionalProperty('test:bookstore', DATA.'test:bookstore')
             def content = new Content()
@@ -86,28 +118,28 @@
                     .withDataspaceName(DATASPACE_NAME)
                     .withSchemaSetName(BOOKSTORE_SCHEMA_SET)
                     .withObservedTimestamp(EVENT_TIMESTAMP)
+                    .withOperation(Content.Operation.CREATE)
                     .withData(data)
         and: 'CpsDataUpdatedEvent with the content'
             def cpsDataUpdateEvent = new CpsDataUpdatedEvent()
             cpsDataUpdateEvent
-                    .withSchema(EVENT_SCHEMA)
+                    .withSchema(EVENT_SCHEMA_V2)
                     .withId(EVENT_ID)
                     .withSource(EVENT_SOURCE)
                     .withType(EVENT_TYPE)
                     .withContent(content)
-        when: 'CpsDataUpdatedEvent is converted to JSON string'
+        when: 'CpsDataUpdatedEvent is converted to Event V2 JSON string'
             def actualMessage = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(cpsDataUpdateEvent)
         then: 'the created JSON String is same as the expected JSON String'
-            def expectedMessage = getEventAsJsonStringFromFile()
+            def expectedMessage = getEventAsJsonStringFromFile('/event-v2-create-operation.json')
             assert actualMessage == expectedMessage
     }
 
-    def getEventAsJsonStringFromFile() {
+    def getEventAsJsonStringFromFile(String fileName) {
         return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(
                 objectMapper.readValue(
-                        this.class.getResource('/bookstore-chapters.json').getText('UTF-8'),
+                        this.class.getResource(fileName).getText('UTF-8'),
                         ObjectNode.class)
         )
     }
-
 }
diff --git a/cps-events/src/test/resources/bookstore-chapters.json b/cps-events/src/test/resources/event-v1.json
similarity index 100%
rename from cps-events/src/test/resources/bookstore-chapters.json
rename to cps-events/src/test/resources/event-v1.json
diff --git a/cps-events/src/test/resources/event-v2-create-operation.json b/cps-events/src/test/resources/event-v2-create-operation.json
new file mode 100644
index 0000000..92ecab3
--- /dev/null
+++ b/cps-events/src/test/resources/event-v2-create-operation.json
@@ -0,0 +1,36 @@
+{
+  "schema": "urn:cps:org.onap.cps:data-updated-event-schema:v2",
+  "id": "77b8f114-4562-4069-8234-6d059ff742ac",
+  "source": "urn:cps:org.onap.cps",
+  "type": "org.onap.cps.data-updated-event",
+  "content": {
+    "observedTimestamp": "2020-12-01T00:00:00.000+0000",
+    "dataspaceName": "my-dataspace",
+    "schemaSetName": "bookstore-schemaset",
+    "anchorName": "chapters",
+    "operation" : "CREATE",
+    "data": {
+      "test:bookstore":{
+        "bookstore-name": "Chapters",
+        "categories": [
+          {
+            "code": "01",
+            "name": "SciFi",
+            "books": [
+              {
+                "authors": [
+                  "Iain M. Banks"
+                ],
+                "lang": "en",
+                "price": 895,
+                "pub_year": "1994",
+                "title": "Feersum Endjinn"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+}
+
diff --git a/cps-events/src/test/resources/event-v2-delete-operation.json b/cps-events/src/test/resources/event-v2-delete-operation.json
new file mode 100644
index 0000000..e003088
--- /dev/null
+++ b/cps-events/src/test/resources/event-v2-delete-operation.json
@@ -0,0 +1,13 @@
+{
+  "schema": "urn:cps:org.onap.cps:data-updated-event-schema:v2",
+  "id": "77b8f114-4562-4069-8234-6d059ff742ac",
+  "source": "urn:cps:org.onap.cps",
+  "type": "org.onap.cps.data-updated-event",
+  "content": {
+    "observedTimestamp": "2020-12-01T00:00:00.000+0000",
+    "dataspaceName": "my-dataspace",
+    "schemaSetName": "bookstore-schemaset",
+    "anchorName": "chapters",
+    "operation" : "DELETE"
+  }
+}
\ No newline at end of file
diff --git a/cps-events/src/test/resources/event-v2-with-additional-properties.json b/cps-events/src/test/resources/event-v2-with-additional-properties.json
new file mode 100644
index 0000000..4e2db68
--- /dev/null
+++ b/cps-events/src/test/resources/event-v2-with-additional-properties.json
@@ -0,0 +1,36 @@
+{
+  "schema": "urn:cps:org.onap.cps:data-updated-event-schema:v2",
+  "id": "77b8f114-4562-4069-8234-6d059ff742ac",
+  "source": "urn:cps:org.onap.cps",
+  "type": "org.onap.cps.data-updated-event",
+  "content": {
+    "observedTimestamp": "2020-12-01T00:00:00.000+0000",
+    "dataspaceName": "my-dataspace",
+    "schemaSetName": "bookstore-schemaset",
+    "anchorName": "chapters",
+    "operation" : "CREATE",
+    "additionalField" : "value",
+    "data": {
+      "test:bookstore":{
+        "bookstore-name": "Chapters",
+        "categories": [
+          {
+            "code": "01",
+            "name": "SciFi",
+            "books": [
+              {
+                "authors": [
+                  "Iain M. Banks"
+                ],
+                "lang": "en",
+                "price": 895,
+                "pub_year": "1994",
+                "title": "Feersum Endjinn"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+}