You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by jk...@apache.org on 2022/05/20 21:43:21 UTC

[unomi] branch json-schema-extensions updated: Fix tests + new tests for extensions

This is an automated email from the ASF dual-hosted git repository.

jkevan pushed a commit to branch json-schema-extensions
in repository https://gitbox.apache.org/repos/asf/unomi.git


The following commit(s) were added to refs/heads/json-schema-extensions by this push:
     new 3540ff5f5 Fix tests + new tests for extensions
3540ff5f5 is described below

commit 3540ff5f5f908826b24e52e9d7316ad219ee1784
Author: Kevan <ke...@jahia.com>
AuthorDate: Fri May 20 23:43:10 2022 +0200

    Fix tests + new tests for extensions
---
 .../test/java/org/apache/unomi/itests/BaseIT.java  | 16 ++--
 .../org/apache/unomi/itests/ContextServletIT.java  | 37 ++++-----
 .../org/apache/unomi/itests/InputValidationIT.java | 45 +++++++++--
 .../java/org/apache/unomi/itests/JSONSchemaIT.java | 87 +++++++++++++++-------
 .../resources/schemas/event-dummy-extended-2.json  | 11 +++
 .../resources/schemas/event-dummy-extended.json    | 10 +++
 .../schemas/events/float-property-type.json        | 23 ++++++
 .../resources/schemas/events/test-event-type.json  | 14 ++++
 .../resources/schemas/schema-dummy-extension.json  | 18 +++++
 ...on => schema-dummy-properties-extension-2.json} | 18 ++---
 ...json => schema-dummy-properties-extension.json} | 17 ++---
 .../resources/schemas/schema-dummy-properties.json |  3 +-
 .../eventcollector_invalidSessionId.json           | 12 +--
 .../eventcollector_request_size_invalid.json       | 12 +--
 .../eventcollector_request_size_valid.json         | 12 +--
 .../resources/validation/eventcollector_valid.json | 12 +--
 16 files changed, 233 insertions(+), 114 deletions(-)

diff --git a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
index cece1ce78..ba2558524 100644
--- a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
@@ -44,6 +44,7 @@ import org.apache.unomi.api.services.RulesService;
 import org.apache.unomi.lifecycle.BundleWatcher;
 import org.apache.unomi.persistence.spi.CustomObjectMapper;
 import org.apache.unomi.persistence.spi.PersistenceService;
+import org.apache.unomi.schema.api.SchemaService;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -112,7 +113,6 @@ public abstract class BaseIT {
     protected static final int REQUEST_TIMEOUT = 60000;
     protected static final int DEFAULT_TRYING_TIMEOUT = 2000;
     protected static final int DEFAULT_TRYING_TRIES = 30;
-    private final static String JSONSCHEMA_URL = "/cxs/jsonSchema";
 
     protected final static ObjectMapper objectMapper;
 
@@ -129,6 +129,10 @@ public abstract class BaseIT {
     @Filter(timeout = 600000)
     protected RulesService rulesService;
 
+    @Inject
+    @Filter(timeout = 600000)
+    protected SchemaService schemaService;
+
     @Inject
     @Filter(timeout = 600000)
     protected DefinitionsService definitionsService;
@@ -376,6 +380,7 @@ public abstract class BaseIT {
         persistenceService = getService(PersistenceService.class);
         definitionsService = getService(DefinitionsService.class);
         rulesService = getService(RulesService.class);
+        schemaService = getService(SchemaService.class);
     }
 
     public void updateConfiguration(String serviceName, String configPid, String propName, Object propValue) throws InterruptedException, IOException {
@@ -605,13 +610,4 @@ public abstract class BaseIT {
             LOGGER.error("Could not close httpClient: " + httpClient, e);
         }
     }
-
-    void registerEventType(String jsonSchemaFileName) {
-        post(JSONSCHEMA_URL, "schemas/events/" + jsonSchemaFileName, ContentType.TEXT_PLAIN);
-    }
-
-    void unRegisterEventType(String jsonSchemaId) {
-        delete(JSONSCHEMA_URL + "/" + Base64.getEncoder().encodeToString(jsonSchemaId.getBytes()));
-    }
-
 }
diff --git a/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java b/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java
index 4e1b75957..a540124e8 100644
--- a/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java
@@ -80,9 +80,9 @@ public class ContextServletIT extends BaseIT {
 
     private final static String THIRD_PARTY_HEADER_NAME = "X-Unomi-Peer";
     private final static String TEST_EVENT_TYPE = "testEventType";
-    private final static String TEST_EVENT_TYPE_SCHEMA = "test-event-type.json";
+    private final static String TEST_EVENT_TYPE_SCHEMA = "schemas/events/test-event-type.json";
     private final static String FLOAT_PROPERTY_EVENT_TYPE = "floatPropertyType";
-    private final static String FLOAT_PROPERTY_EVENT_TYPE_SCHEMA = "float-property-type.json";
+    private final static String FLOAT_PROPERTY_EVENT_TYPE_SCHEMA = "schemas/events/float-property-type.json";
     private final static String TEST_PROFILE_ID = "test-profile-id";
 
     private final static String SEGMENT_ID = "test-segment-id";
@@ -115,8 +115,6 @@ public class ContextServletIT extends BaseIT {
 
     @Before
     public void setUp() throws InterruptedException {
-        this.registerEventType(TEST_EVENT_TYPE_SCHEMA);
-        this.registerEventType(FLOAT_PROPERTY_EVENT_TYPE_SCHEMA);
 
         //Create a past-event segment
         Metadata segmentMetadata = new Metadata(SEGMENT_ID);
@@ -136,29 +134,32 @@ public class ContextServletIT extends BaseIT {
         keepTrying("Profile " + TEST_PROFILE_ID + " not found in the required time", () -> profileService.load(TEST_PROFILE_ID),
                 Objects::nonNull, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
 
-        keepTrying("Couldn't find json schema endpoint", () -> get(JSONSCHEMA_URL, List.class), Objects::nonNull, DEFAULT_TRYING_TIMEOUT,
-                DEFAULT_TRYING_TRIES);
+        // create schemas required for tests
+        schemaService.saveSchema(resourceAsString(TEST_EVENT_TYPE_SCHEMA));
+        schemaService.saveSchema(resourceAsString(FLOAT_PROPERTY_EVENT_TYPE_SCHEMA));
+        keepTrying("Couldn't find json schemas",
+                () -> schemaService.getInstalledJsonSchemaIds(),
+                (schemaIds) -> (schemaIds.contains("https://unomi.apache.org/schemas/json/events/floatPropertyType/1-0-0") &&
+                        schemaIds.contains("https://unomi.apache.org/schemas/json/events/testEventType/1-0-0")),
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
     }
 
     @After
-    public void tearDown() {
+    public void tearDown() throws InterruptedException {
         TestUtils.removeAllEvents(definitionsService, persistenceService);
         TestUtils.removeAllSessions(definitionsService, persistenceService);
         TestUtils.removeAllProfiles(definitionsService, persistenceService);
         profileService.delete(profile.getItemId(), false);
         segmentService.removeSegmentDefinition(SEGMENT_ID, false);
 
-        String encodedString = Base64.getEncoder()
-                .encodeToString("https://unomi.apache.org/schemas/json/events/testEventType/1-0-0".getBytes());
-        delete(JSONSCHEMA_URL + "/" + encodedString);
-
-        encodedString = Base64.getEncoder()
-                .encodeToString("https://unomi.apache.org/schemas/json/events/floatPropertyType/1-0-0".getBytes());
-        delete(JSONSCHEMA_URL + "/" + encodedString);
-
-        encodedString = Base64.getEncoder()
-                .encodeToString("https://unomi.apache.org/schemas/json/events/floatPropertyType/1-0-0".getBytes());
-        delete(JSONSCHEMA_URL + "/" + encodedString);
+        // cleanup schemas
+        schemaService.deleteSchema("https://unomi.apache.org/schemas/json/events/testEventType/1-0-0");
+        schemaService.deleteSchema("https://unomi.apache.org/schemas/json/events/floatPropertyType/1-0-0");
+        keepTrying("Couldn't find json schemas",
+                () -> schemaService.getInstalledJsonSchemaIds(),
+                (schemaIds) -> (!schemaIds.contains("https://unomi.apache.org/schemas/json/events/floatPropertyType/1-0-0") &&
+                        !schemaIds.contains("https://unomi.apache.org/schemas/json/events/testEventType/1-0-0")),
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
     }
 
     @Test
diff --git a/itests/src/test/java/org/apache/unomi/itests/InputValidationIT.java b/itests/src/test/java/org/apache/unomi/itests/InputValidationIT.java
index 538b8b52a..1978e8bbe 100644
--- a/itests/src/test/java/org/apache/unomi/itests/InputValidationIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/InputValidationIT.java
@@ -23,9 +23,10 @@ import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.util.EntityUtils;
+import org.apache.unomi.api.Event;
 import org.apache.unomi.itests.tools.httpclient.HttpClientThatWaitsForUnomi;
-import org.junit.Before;
-import org.junit.Test;
+import org.apache.unomi.schema.api.JsonSchemaWrapper;
+import org.junit.*;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
@@ -70,11 +71,25 @@ public class InputValidationIT extends BaseIT {
     }
 
     @Test
-    public void test_eventCollector_valid() throws IOException {
-        registerEventType(DUMMY_EVENT_TYPE_SCHEMA);
+    public void test_eventCollector_valid() throws IOException, InterruptedException {
+        // needed schema for event to be valid during tests
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json"));
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json"));
+        keepTrying("Event should be valid",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-valid.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+
         doPOSTRequestTest(EVENT_COLLECTOR_URL, null, "/validation/eventcollector_valid.json", 200, null);
         doGETRequestTest(EVENT_COLLECTOR_URL, null, "/validation/eventcollector_valid.json", 200, null);
-        unRegisterEventType("https://unomi.apache.org/schemas/json/events/dummy_event_type/1-0-0");
+
+        // remove schemas
+        schemaService.deleteSchema("https://unomi.apache.org/schemas/json/events/dummy/1-0-0");
+        schemaService.deleteSchema("https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0");
+        keepTrying("Event should be invalid",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-valid.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> !isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
     }
 
     @Test
@@ -102,11 +117,25 @@ public class InputValidationIT extends BaseIT {
     }
 
     @Test
-    public void test_eventCollector_request_size_exceed_limit() throws IOException {
-        registerEventType(DUMMY_EVENT_TYPE_SCHEMA);
+    public void test_eventCollector_request_size_exceed_limit() throws IOException, InterruptedException {
+        // needed schema for event to be valid during tests
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json"));
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json"));
+        keepTrying("Event should be valid",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-valid.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+
         doPOSTRequestTest(EVENT_COLLECTOR_URL, null, "/validation/eventcollector_request_size_invalid.json", 400, ERROR_MESSAGE_REQUEST_SIZE_LIMIT_EXCEEDED);
         doPOSTRequestTest(EVENT_COLLECTOR_URL, null, "/validation/eventcollector_request_size_valid.json", 200, null);
-        unRegisterEventType("https://unomi.apache.org/schemas/json/events/dummy_event_type/1-0-0");
+
+        // remove schemas
+        schemaService.deleteSchema("https://unomi.apache.org/schemas/json/events/dummy/1-0-0");
+        schemaService.deleteSchema("https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0");
+        keepTrying("Event should be invalid",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-valid.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> !isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
     }
 
     @Test
diff --git a/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java b/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java
index 540ee0b40..dd31f79ba 100644
--- a/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java
@@ -79,13 +79,6 @@ public class JSONSchemaIT extends BaseIT {
         // Push schemas
         schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json"));
         schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json"));
-        keepTrying("Couldn't find json schemas",
-                () -> get(JSONSCHEMA_URL, List.class),
-                (list) -> (list.contains("https://unomi.apache.org/schemas/json/events/dummy/1-0-0") &&
-                        list.contains("https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0")),
-                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
-
-        // event should be valid now
         keepTrying("Event should be valid",
                 () -> schemaService.isValid(resourceAsString("schemas/event-dummy-valid.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
                 isValid -> isValid,
@@ -101,12 +94,6 @@ public class JSONSchemaIT extends BaseIT {
 
         // remove one of the schema:
         assertTrue(schemaService.deleteSchema("https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0"));
-        keepTrying("Schema should have been deleted",
-                () -> schemaService.getInstalledJsonSchemaIds(),
-                (list) -> !list.contains("https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0"),
-                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
-
-        // event should be invalid now that one of the schema have been deleted -> this is validating cache is correctly flushed
         keepTrying("Event should be invalid since of the schema have been deleted",
                 () -> schemaService.isValid(resourceAsString("schemas/event-dummy-valid.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
                 isValid -> !isValid,
@@ -121,13 +108,6 @@ public class JSONSchemaIT extends BaseIT {
         // Push schemas
         schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json"));
         schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json"));
-        keepTrying("Couldn't find json schemas",
-                () -> get(JSONSCHEMA_URL, List.class),
-                (list) -> (list.contains("https://unomi.apache.org/schemas/json/events/dummy/1-0-0") &&
-                        list.contains("https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0")),
-                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
-
-        // event should be valid now
         keepTrying("Event should be valid",
                 () -> schemaService.isValid(resourceAsString("schemas/event-dummy-valid.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
                 isValid -> isValid,
@@ -138,18 +118,73 @@ public class JSONSchemaIT extends BaseIT {
 
         // update the schema to allow "invalidPropName":
         schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties-updated.json"));
-        keepTrying("schema should be updated by refresh 1sec",
-                () -> schemaService.getSchema("https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0"),
-                schema -> (schema != null && schema.getSchema().contains("invalidPropName")),
-                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
-
-        // "invalidPropName" should be valid and allowed now
         keepTrying("Event should be valid since of the schema have been updated",
                 () -> schemaService.isValid(resourceAsString("schemas/event-dummy-invalid-2.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
                 isValid -> isValid,
                 DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
     }
 
+    @Test
+    public void testExtension_SaveDelete() throws InterruptedException, IOException {
+        // Push base schemas
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json"));
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json"));
+        keepTrying("Event should be valid",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-valid.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+
+        // check that extended event is not valid at first
+        assertFalse(schemaService.isValid(resourceAsString("schemas/event-dummy-extended.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"));
+
+        // register both extensions (for root event and the properties level)
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy-extension.json"));
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties-extension.json"));
+        keepTrying("Extended event should be valid since of the extensions have been deployed",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-extended.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+
+        // delete one of the extension
+        schemaService.deleteSchema("https://unomi.apache.org/schemas/json/events/dummy/properties/extension/1-0-0");
+        keepTrying("Extended event should be invalid again, one necessary extension have been removed",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-extended.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> !isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+    }
+
+    @Test
+    public void testExtension_Update() throws InterruptedException, IOException {
+        // Push base schemas
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json"));
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json"));
+        keepTrying("Event should be valid",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-valid.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+
+        // check that extended event is not valid at first
+        assertFalse(schemaService.isValid(resourceAsString("schemas/event-dummy-extended.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"));
+
+        // register both extensions (for root event and the properties level)
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy-extension.json"));
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties-extension.json"));
+        keepTrying("Extended event should be valid since of the extensions have been deployed",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-extended.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+
+        // check that extended event 2 is not valid due to usage of unevaluatedProperty not bring by schemas or extensions
+        assertFalse(schemaService.isValid(resourceAsString("schemas/event-dummy-extended-2.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"));
+
+        // Update extensions to allow the extended event 2
+        schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties-extension-2.json"));
+        keepTrying("Extended event 2 should be valid since of the extensions have been updated",
+                () -> schemaService.isValid(resourceAsString("schemas/event-dummy-extended-2.json"), "https://unomi.apache.org/schemas/json/events/dummy/1-0-0"),
+                isValid -> isValid,
+                DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+    }
+
     @Test
     public void testEndPoint_GetInstalledJsonSchemas() throws InterruptedException {
         List<String> jsonSchemas = get(JSONSCHEMA_URL, List.class);
diff --git a/itests/src/test/resources/schemas/event-dummy-extended-2.json b/itests/src/test/resources/schemas/event-dummy-extended-2.json
new file mode 100644
index 000000000..4014a1f6d
--- /dev/null
+++ b/itests/src/test/resources/schemas/event-dummy-extended-2.json
@@ -0,0 +1,11 @@
+{
+  "eventType":"dummy",
+  "scope":"dummy_scope",
+  "newRootProp": "extended Root Prop !",
+  "properties": {
+    "workspace": "dummy_workspace",
+    "path": "dummy/path",
+    "newProp": "extended Prop !",
+    "newProp2": 42
+  }
+}
\ No newline at end of file
diff --git a/itests/src/test/resources/schemas/event-dummy-extended.json b/itests/src/test/resources/schemas/event-dummy-extended.json
new file mode 100644
index 000000000..6c6b9b60f
--- /dev/null
+++ b/itests/src/test/resources/schemas/event-dummy-extended.json
@@ -0,0 +1,10 @@
+{
+  "eventType":"dummy",
+  "scope":"dummy_scope",
+  "newRootProp": "extended Root Prop !",
+  "properties": {
+    "workspace": "dummy_workspace",
+    "path": "dummy/path",
+    "newProp": "extended Prop !"
+  }
+}
\ No newline at end of file
diff --git a/itests/src/test/resources/schemas/events/float-property-type.json b/itests/src/test/resources/schemas/events/float-property-type.json
new file mode 100644
index 000000000..93bb3f8ea
--- /dev/null
+++ b/itests/src/test/resources/schemas/events/float-property-type.json
@@ -0,0 +1,23 @@
+{
+  "$id": "https://unomi.apache.org/schemas/json/events/floatPropertyType/1-0-0",
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "self":{
+    "vendor":"org.apache.unomi",
+    "target" : "events",
+    "name":"floatPropertyType",
+    "format":"jsonschema",
+    "version":"1-0-0"
+  },
+  "title": "FloatPropertyEvent",
+  "type": "object",
+  "allOf": [{ "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0" }],
+  "properties" : {
+    "properties" : {
+      "type" : "object",
+      "properties" : {
+        "floatProperty" : { "type" : "number" }
+      },
+      "additionalProperties": false
+    }
+  }
+}
diff --git a/itests/src/test/resources/schemas/events/test-event-type.json b/itests/src/test/resources/schemas/events/test-event-type.json
new file mode 100644
index 000000000..8d5a928a2
--- /dev/null
+++ b/itests/src/test/resources/schemas/events/test-event-type.json
@@ -0,0 +1,14 @@
+{
+  "$id": "https://unomi.apache.org/schemas/json/events/testEventType/1-0-0",
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "self":{
+    "vendor":"org.apache.unomi",
+    "name":"testEventType",
+    "format":"jsonschema",
+    "target":"events",
+    "version":"1-0-0"
+  },
+  "title": "TestEvent",
+  "type": "object",
+  "allOf": [{ "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0" }]
+}
diff --git a/itests/src/test/resources/schemas/schema-dummy-extension.json b/itests/src/test/resources/schemas/schema-dummy-extension.json
new file mode 100644
index 000000000..3c6f06d86
--- /dev/null
+++ b/itests/src/test/resources/schemas/schema-dummy-extension.json
@@ -0,0 +1,18 @@
+{
+  "$id": "https://unomi.apache.org/schemas/json/events/dummy/extension/1-0-0",
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "self":{
+    "vendor":"org.apache.unomi",
+    "name":"dummyExtension",
+    "format":"jsonschema",
+    "extends": "https://unomi.apache.org/schemas/json/events/dummy/1-0-0",
+    "version":"1-0-0"
+  },
+  "title": "DummyEventExtension",
+  "type": "object",
+  "properties": {
+    "newRootProp": {
+      "type": "string"
+    }
+  }
+}
diff --git a/itests/src/test/resources/schemas/schema-dummy-properties.json b/itests/src/test/resources/schemas/schema-dummy-properties-extension-2.json
similarity index 50%
copy from itests/src/test/resources/schemas/schema-dummy-properties.json
copy to itests/src/test/resources/schemas/schema-dummy-properties-extension-2.json
index 498dd58aa..427a7f633 100644
--- a/itests/src/test/resources/schemas/schema-dummy-properties.json
+++ b/itests/src/test/resources/schemas/schema-dummy-properties-extension-2.json
@@ -1,21 +1,21 @@
 {
-  "$id": "https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0",
+  "$id": "https://unomi.apache.org/schemas/json/events/dummy/properties/extension/1-0-0",
   "$schema": "https://json-schema.org/draft/2019-09/schema",
   "self": {
     "vendor": "org.modules.jahia",
-    "name": "dummyProperties",
+    "name": "dummyPropertiesExtension",
     "format": "jsonschema",
-    "version": "1-0-0"
+    "version": "1-0-0",
+    "extends": "https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0"
   },
-  "title": "dummyProperties",
+  "title": "dummyPropertiesExtension",
   "type": "object",
   "properties": {
-    "workspace": {
+    "newProp": {
       "type": "string"
     },
-    "path": {
-      "type": "string"
+    "newProp2": {
+      "type": "number"
     }
-  },
-  "unevaluatedProperties": false
+  }
 }
diff --git a/itests/src/test/resources/schemas/schema-dummy-properties.json b/itests/src/test/resources/schemas/schema-dummy-properties-extension.json
similarity index 54%
copy from itests/src/test/resources/schemas/schema-dummy-properties.json
copy to itests/src/test/resources/schemas/schema-dummy-properties-extension.json
index 498dd58aa..469cc7d29 100644
--- a/itests/src/test/resources/schemas/schema-dummy-properties.json
+++ b/itests/src/test/resources/schemas/schema-dummy-properties-extension.json
@@ -1,21 +1,18 @@
 {
-  "$id": "https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0",
+  "$id": "https://unomi.apache.org/schemas/json/events/dummy/properties/extension/1-0-0",
   "$schema": "https://json-schema.org/draft/2019-09/schema",
   "self": {
     "vendor": "org.modules.jahia",
-    "name": "dummyProperties",
+    "name": "dummyPropertiesExtension",
     "format": "jsonschema",
-    "version": "1-0-0"
+    "version": "1-0-0",
+    "extends": "https://unomi.apache.org/schemas/json/events/dummy/properties/1-0-0"
   },
-  "title": "dummyProperties",
+  "title": "dummyPropertiesExtension",
   "type": "object",
   "properties": {
-    "workspace": {
-      "type": "string"
-    },
-    "path": {
+    "newProp": {
       "type": "string"
     }
-  },
-  "unevaluatedProperties": false
+  }
 }
diff --git a/itests/src/test/resources/schemas/schema-dummy-properties.json b/itests/src/test/resources/schemas/schema-dummy-properties.json
index 498dd58aa..f5cd6121d 100644
--- a/itests/src/test/resources/schemas/schema-dummy-properties.json
+++ b/itests/src/test/resources/schemas/schema-dummy-properties.json
@@ -14,7 +14,8 @@
       "type": "string"
     },
     "path": {
-      "type": "string"
+      "type": "string",
+      "maxLength": 20000
     }
   },
   "unevaluatedProperties": false
diff --git a/itests/src/test/resources/validation/eventcollector_invalidSessionId.json b/itests/src/test/resources/validation/eventcollector_invalidSessionId.json
index bdea1634b..4a35cdc78 100644
--- a/itests/src/test/resources/validation/eventcollector_invalidSessionId.json
+++ b/itests/src/test/resources/validation/eventcollector_invalidSessionId.json
@@ -2,15 +2,11 @@
   "sessionId": "<script>alert();</script>",
   "events":[
     {
-      "eventType":"dummy_event_type",
+      "eventType":"dummy",
       "scope":"dummy_scope",
-      "source":{
-        "itemType":"pageView",
-        "scope":"dummy_scope",
-        "itemId":"pageView",
-        "properties":{
-          "myProperty":"myValue"
-        }
+      "properties": {
+        "workspace": "dummy_workspace",
+        "path": "dummy/path"
       }
     }
   ]
diff --git a/itests/src/test/resources/validation/eventcollector_request_size_invalid.json b/itests/src/test/resources/validation/eventcollector_request_size_invalid.json
index 9813ba3bc..a6b269fbe 100644
--- a/itests/src/test/resources/validation/eventcollector_request_size_invalid.json
+++ b/itests/src/test/resources/validation/eventcollector_request_size_invalid.json
@@ -2,15 +2,11 @@
   "sessionId": "dummy-session-id",
   "events":[
     {
-      "eventType":"dummy_event_type",
+      "eventType":"dummy",
       "scope":"dummy_scope",
-      "source":{
-        "itemType":"pageView",
-        "scope":"dummy_scope",
-        "itemId":"pageView",
-        "properties":{
-          "myProperty":"Where doesWhere does it come from?\nContrary to popular belief, Lorem Ipsum is not simply random text. Ithere does it come from?\nContrary to popular belief, Lorem Ipsum is not simply random text. It here does it come from?\nContrary to popular belief, Lorem Ipsum is not simply random text. It here does it come from?\nContrary to popular belief, Lorem Ipsum is not simply random text. It here does it come from?\nContrary to popular belief, Lorem Ipsum is not simply [...]
-        }
+      "properties": {
+        "workspace": "dummy_workspace",
+        "path": "Where doesWhere does it come from?\nContrary to popular belief, Lorem Ipsum is not simply random text. Ithere does it come from?\nContrary to popular belief, Lorem Ipsum is not simply random text. It here does it come from?\nContrary to popular belief, Lorem Ipsum is not simply random text. It here does it come from?\nContrary to popular belief, Lorem Ipsum is not simply random text. It here does it come from?\nContrary to popular belief, Lorem Ipsum is not simply random [...]
       }
     }
   ]
diff --git a/itests/src/test/resources/validation/eventcollector_request_size_valid.json b/itests/src/test/resources/validation/eventcollector_request_size_valid.json
index 6fc32fa1d..329a3c4b1 100644
--- a/itests/src/test/resources/validation/eventcollector_request_size_valid.json
+++ b/itests/src/test/resources/validation/eventcollector_request_size_valid.json
@@ -2,15 +2,11 @@
   "sessionId": "dummy-session-id",
   "events":[
     {
-      "eventType":"dummy_event_type",
+      "eventType":"dummy",
       "scope":"dummy_scope",
-      "source":{
-        "itemType":"pageView",
-        "scope":"dummy_scope",
-        "itemId":"pageView",
-        "properties":{
-          "myProperty": "Well sized property"
-        }
+      "properties": {
+        "workspace": "dummy_workspace",
+        "path": "dummy/path/well/sized"
       }
     }
   ]
diff --git a/itests/src/test/resources/validation/eventcollector_valid.json b/itests/src/test/resources/validation/eventcollector_valid.json
index 29a39cf96..edc63fe78 100644
--- a/itests/src/test/resources/validation/eventcollector_valid.json
+++ b/itests/src/test/resources/validation/eventcollector_valid.json
@@ -2,15 +2,11 @@
   "sessionId": "dummy-session-id",
   "events":[
     {
-      "eventType":"dummy_event_type",
+      "eventType":"dummy",
       "scope":"dummy_scope",
-      "source":{
-        "itemType":"pageView",
-        "scope":"dummy_scope",
-        "itemId":"pageView",
-        "properties":{
-          "myProperty":"myValue"
-        }
+      "properties": {
+        "workspace": "dummy_workspace",
+        "path": "dummy/path"
       }
     }
   ]