You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by sh...@apache.org on 2021/01/14 13:29:43 UTC

[unomi] branch unomi-404-and-375-fix-tests-with-default-eventtypes created (now 221aa1b)

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

shuber pushed a change to branch unomi-404-and-375-fix-tests-with-default-eventtypes
in repository https://gitbox.apache.org/repos/asf/unomi.git.


      at 221aa1b  UNOMI-404 & UNOMI 375 - Fix integration tests by adding default event types for all known Unomi event types - Implement more complete event validation for source and target not just properties -

This branch includes the following new commits:

     new 221aa1b  UNOMI-404 & UNOMI 375 - Fix integration tests by adding default event types for all known Unomi event types - Implement more complete event validation for source and target not just properties -

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[unomi] 01/01: UNOMI-404 & UNOMI 375 - Fix integration tests by adding default event types for all known Unomi event types - Implement more complete event validation for source and target not just properties -

Posted by sh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

shuber pushed a commit to branch unomi-404-and-375-fix-tests-with-default-eventtypes
in repository https://gitbox.apache.org/repos/asf/unomi.git

commit 221aa1b55f525b135cea19a68c6d6f00ca2d0847
Author: Serge Huber <sh...@jahia.com>
AuthorDate: Thu Jan 14 14:29:35 2021 +0100

    UNOMI-404 & UNOMI 375
    - Fix integration tests by adding default event types for all known Unomi event types
    - Implement more complete event validation for source and target not just properties
    -
---
 .../org/apache/unomi/itests/ContextServletIT.java  | 49 ++++++++----
 .../ElasticSearchPersistenceServiceImpl.java       |  4 +
 .../impl/events/EventTypeRegistryImpl.java         | 87 +++++++++++++++++-----
 .../META-INF/cxs/events/anonymizeProfile.json      | 23 ++++++
 .../META-INF/cxs/events/articleCompleted.json      | 69 +++++++++++++++++
 .../main/resources/META-INF/cxs/events/form.json   | 69 +++++++++++++++++
 .../main/resources/META-INF/cxs/events/goal.json   | 79 ++++++++++++++++++++
 .../resources/META-INF/cxs/events/identify.json    | 69 +++++++++++++++++
 .../META-INF/cxs/events/incrementInterest.json     | 33 ++++++++
 .../main/resources/META-INF/cxs/events/login.json  | 32 ++++----
 .../META-INF/cxs/events/modifyConsent.json         | 77 +++++++++++++++++++
 .../META-INF/cxs/events/profileDeleted.json        | 23 ++++++
 .../resources/META-INF/cxs/events/ruleFired.json   | 87 ++++++++++++++++++++++
 .../META-INF/cxs/events/sessionCreated.json        | 52 +++++++++++++
 .../META-INF/cxs/events/sessionReassigned.json     | 55 ++++++++++++++
 .../META-INF/cxs/events/updateProperties.json      | 26 +++++++
 .../main/resources/META-INF/cxs/events/view.json   | 69 +++++++++++++++++
 17 files changed, 855 insertions(+), 48 deletions(-)

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 45cc2e0..ba9392b 100644
--- a/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java
@@ -137,11 +137,33 @@ public class ContextServletIT extends BaseIT {
 
     private void registerEventType(final String type) {
         final Set<PropertyType> props = new HashSet<>();
-        registerEventType(type, props);
+        registerEventType(type, props, null, null);
     }
 
-    private void registerEventType(final String type, final Set<PropertyType> props) {
-        final EventType eventType = new EventType(type, props, 1);
+    private void registerEventType(final String type, final Set<PropertyType> properties, final Set<PropertyType> source, final Set<PropertyType> target) {
+        final Set<PropertyType> typeProps = new HashSet<>();
+        if (properties != null) {
+            PropertyType propertiesPropType = new PropertyType();
+            propertiesPropType.setItemId("properties");
+            propertiesPropType.setValueTypeId("set");
+            propertiesPropType.setChildPropertyTypes(properties);
+            typeProps.add(propertiesPropType);
+        }
+        if (source != null) {
+            PropertyType sourcePropType = new PropertyType();
+            sourcePropType.setItemId("source");
+            sourcePropType.setValueTypeId("set");
+            sourcePropType.setChildPropertyTypes(source);
+            typeProps.add(sourcePropType);
+        }
+        if (target != null) {
+            PropertyType targetPropType = new PropertyType();
+            targetPropType.setItemId("target");
+            targetPropType.setValueTypeId("set");
+            targetPropType.setChildPropertyTypes(target);
+            typeProps.add(targetPropType);
+        }
+        final EventType eventType = new EventType(type, typeProps, 1);
         eventService.registerEventType(eventType);
     }
 
@@ -393,12 +415,12 @@ public class ContextServletIT extends BaseIT {
         contextRequest.setProfileId(profileId);
         contextRequest.setEvents(Arrays.asList(event));
 
-        final Set<PropertyType> typeProps = new HashSet<>();
+        final Set<PropertyType> propertiesPropTypes = new HashSet<>();
         PropertyType floatProp = new PropertyType();
         floatProp.setItemId("floatProperty");
         floatProp.setValueTypeId("float");
-        typeProps.add(floatProp);
-        this.registerEventType(eventType, typeProps);
+        propertiesPropTypes.add(floatProp);
+        this.registerEventType(eventType, propertiesPropTypes, null, null);
 
         //Act
         HttpPost request = new HttpPost(URL + CONTEXT_URL);
@@ -431,12 +453,12 @@ public class ContextServletIT extends BaseIT {
         contextRequest.setProfileId(profileId);
         contextRequest.setEvents(Arrays.asList(event));
 
-        final Set<PropertyType> typeProps = new HashSet<>();
+        final Set<PropertyType> propertiesPropTypes = new HashSet<>();
         PropertyType floatProp = new PropertyType();
         floatProp.setItemId("floatProperty");
         floatProp.setValueTypeId("float");
-        typeProps.add(floatProp);
-        this.registerEventType(eventType, typeProps);
+        propertiesPropTypes.add(floatProp);
+        this.registerEventType(eventType, propertiesPropTypes, null, null);
 
         //Act
         HttpPost request = new HttpPost(URL + CONTEXT_URL);
@@ -461,22 +483,23 @@ public class ContextServletIT extends BaseIT {
         event.setEventType(eventType);
         event.setItemId(eventId);
         Map<String, Object> props = new HashMap<>();
-        props.put("floatProperty", 3.14159);
+        props.put("ffloatProperty", 3.14159);
         event.setProperties(props);
 
         ContextRequest contextRequest = new ContextRequest();
         contextRequest.setProfileId(profileId);
         contextRequest.setEvents(Arrays.asList(event));
 
-        final Set<PropertyType> typeProps = new HashSet<>();
+        final Set<PropertyType> propertiesPropTypes = new HashSet<>();
         PropertyType floatProp = new PropertyType();
         floatProp.setItemId("floatProperty");
         floatProp.setValueTypeId("float");
+        propertiesPropTypes.add(floatProp);
         PropertyType geopointProp = new PropertyType();
         geopointProp.setItemId("geopointProperty");
         geopointProp.setValueTypeId("geopoint");
-        typeProps.add(geopointProp);
-        this.registerEventType(eventType, typeProps);
+        propertiesPropTypes.add(geopointProp);
+        this.registerEventType(eventType, propertiesPropTypes, null, null);
 
         //Act
         HttpPost request = new HttpPost(URL + CONTEXT_URL);
diff --git a/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java b/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java
index 4f8de5f..5ddeafd 100644
--- a/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java
+++ b/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java
@@ -1191,6 +1191,10 @@ public class ElasticSearchPersistenceServiceImpl implements PersistenceService,
                                     "      }\n" +
                                     "    }\n" +
                                     "}\n", XContentType.JSON);
+                    if (mappings.get(itemName) == null) {
+                        logger.warn("Couldn't find mapping for item {}, won't create monthly index template", itemName);
+                        return false;
+                    }
                     putIndexTemplateRequest.mapping(mappings.get(itemName), XContentType.JSON);
                     AcknowledgedResponse putIndexTemplateResponse = client.indices().putTemplate(putIndexTemplateRequest, RequestOptions.DEFAULT);
                     executedSuccessfully &= putIndexTemplateResponse.isAcknowledged();
diff --git a/services/src/main/java/org/apache/unomi/services/impl/events/EventTypeRegistryImpl.java b/services/src/main/java/org/apache/unomi/services/impl/events/EventTypeRegistryImpl.java
index 02b1079..9a0f543 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/events/EventTypeRegistryImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/events/EventTypeRegistryImpl.java
@@ -17,11 +17,8 @@
 
 package org.apache.unomi.services.impl.events;
 
-import org.apache.unomi.api.Event;
-import org.apache.unomi.api.EventType;
-import org.apache.unomi.api.GeoPoint;
-import org.apache.unomi.api.PluginType;
-import org.apache.unomi.api.PropertyType;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.unomi.api.*;
 import org.apache.unomi.api.services.EventTypeRegistry;
 import org.apache.unomi.persistence.spi.CustomObjectMapper;
 import org.osgi.framework.Bundle;
@@ -31,16 +28,10 @@ import org.osgi.framework.SynchronousBundleListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 public class EventTypeRegistryImpl implements EventTypeRegistry, SynchronousBundleListener {
 
@@ -104,7 +95,13 @@ public class EventTypeRegistryImpl implements EventTypeRegistry, SynchronousBund
             return false;
         }
 
-        return areAllPropertiesValid(event.getProperties(), eventType.getPropertyTypes());
+        Set<PropertyType> propertiesPropertyTypes = findChildPropertyTypesById("properties", eventType.getPropertyTypes());
+        Set<PropertyType> sourcePropertyTypes = findChildPropertyTypesById("source", eventType.getPropertyTypes());
+        Set<PropertyType> targetPropertyTypes = findChildPropertyTypesById("target", eventType.getPropertyTypes());
+
+        return areObjectPropertiesValid(event.getProperties(), propertiesPropertyTypes) &&
+                areObjectPropertiesValid(event.getSource(), sourcePropertyTypes) &&
+                areObjectPropertiesValid(event.getTarget(), targetPropertyTypes);
     }
 
     /**
@@ -115,31 +112,81 @@ public class EventTypeRegistryImpl implements EventTypeRegistry, SynchronousBund
      * @param types set of a predefined event type properties
      * @return boolean result of validation
      */
-    private boolean areAllPropertiesValid(Map<String, Object> props, Set<PropertyType> types) {
+    private boolean areMapPropertiesValid(Map<Object, Object> props, Set<PropertyType> types) {
         if (props == null || props.isEmpty() || types == null || types.isEmpty()) {
             return true;
         }
         return props.entrySet().stream().allMatch(entry -> {
             return types.stream().anyMatch(type -> {
-                if (!type.getItemId().equals(entry.getKey())) {
+                if (!type.getItemId().equals(entry.getKey().toString())) {
+                    logger.warn("Event type validation error: map property {} is not allowed", entry.getKey().toString());
                     return false;
                 }
                 final Set<PropertyType> childTypes = type.getChildPropertyTypes();
                 if (childTypes.size() > 0 && entry.getValue() != null) {
                     try {
-                        final Map<String, Object> childProps = (Map<String, Object>) entry.getValue();
-                        return areAllPropertiesValid(childProps, childTypes);
+                        return areObjectPropertiesValid(entry.getValue(), childTypes);
                     } catch (ClassCastException e) {
                         logger.error("Event property '{}' value is invalid: {}", entry.getKey(), e.getCause());
                         return false;
                     }
                 } else {
-                    return testValueType(entry.getValue(), type.getValueTypeId());
+                    boolean valueTypeValid = testValueType(entry.getValue(), type.getValueTypeId());
+                    if (!valueTypeValid) {
+                        logger.warn("Event type validation error: value type for property {} is not valid", entry.getKey().toString());
+                    }
+                    return valueTypeValid;
                 }
             });
         });
     }
 
+    private boolean areObjectPropertiesValid(Object object, Set<PropertyType> types) {
+        if (object == null) {
+            return true;
+        }
+        if (object instanceof Map) {
+            return areMapPropertiesValid((Map<Object,Object>) object, types);
+        }
+        PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(object);
+        return Arrays.stream(propertyDescriptors).allMatch(propertyDescriptor -> {
+            PropertyType propertyType = findPropertyTypeById(propertyDescriptor.getName(), types);
+            if (propertyType == null) {
+                logger.warn("Event type validation error: couldn't find property type for property {}", propertyDescriptor.getName());
+                return false;
+            }
+            if ("set".equals(propertyType.getValueTypeId())) {
+                boolean setPropertiesValid = false;
+                try {
+                    setPropertiesValid = areObjectPropertiesValid(PropertyUtils.getProperty(object, propertyDescriptor.getName()), propertyType.getChildPropertyTypes());
+                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+                    logger.error("Error accessing property {} on object {}: {}", propertyDescriptor.getName(), object.toString(), e);
+                    return false;
+                }
+                if (!setPropertiesValid) {
+                    logger.warn("Event type validation error: set property for property {} are not valid", propertyDescriptor.getName());
+                    return false;
+                }
+            }
+            return true;
+        });
+    }
+
+    private Set<PropertyType> findChildPropertyTypesById(String id, Set<PropertyType> types) {
+        PropertyType propertyType = findPropertyTypeById(id, types);
+        if (propertyType == null) {
+            return new HashSet<>();
+        } else {
+            return propertyType.getChildPropertyTypes();
+        }
+    }
+
+    private PropertyType findPropertyTypeById(String id, Set<PropertyType> types) {
+        Optional<PropertyType> optionalPropertyType = types.stream().filter(propertyType -> propertyType.getItemId().equals(id)).findFirst();
+        return optionalPropertyType.orElse(null);
+
+    }
+
     private boolean testValueType(final Object value, final String valueTypeId) {
         switch (valueTypeId) {
             case "integer":
diff --git a/services/src/main/resources/META-INF/cxs/events/anonymizeProfile.json b/services/src/main/resources/META-INF/cxs/events/anonymizeProfile.json
new file mode 100644
index 0000000..1fa196a
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/anonymizeProfile.json
@@ -0,0 +1,23 @@
+{
+  "type" : "anonymizeProfile",
+  "propertyTypes" : [
+    {
+      "itemId": "target",
+      "type": "set",
+      "childPropertyTypes": [
+        {
+          "itemId": "itemId",
+          "type": "string"
+        },
+        {
+          "itemId": "properties",
+          "type": "set"
+        },
+        {
+          "itemId": "systemProperties",
+          "type": "set"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/articleCompleted.json b/services/src/main/resources/META-INF/cxs/events/articleCompleted.json
new file mode 100644
index 0000000..cc73736
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/articleCompleted.json
@@ -0,0 +1,69 @@
+{
+  "type" : "articleCompleted",
+  "propertyTypes" : [
+    {
+      "itemId": "properties",
+      "type": "set"
+    },
+    {
+      "itemId" : "source",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId": "version",
+          "type": "long"
+        },
+        {
+          "itemId": "systemMetadata",
+          "type": "set"
+        }
+      ]
+    },
+    {
+      "itemId" : "target",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId": "version",
+          "type": "long"
+        },
+        {
+          "itemId": "systemMetadata",
+          "type": "set"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/form.json b/services/src/main/resources/META-INF/cxs/events/form.json
new file mode 100644
index 0000000..ace03f5
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/form.json
@@ -0,0 +1,69 @@
+{
+  "type" : "form",
+  "propertyTypes" : [
+    {
+      "itemId": "properties",
+      "type": "set"
+    },
+    {
+      "itemId" : "source",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId": "version",
+          "type": "long"
+        },
+        {
+          "itemId": "systemMetadata",
+          "type": "set"
+        }
+      ]
+    },
+    {
+      "itemId" : "target",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId": "version",
+          "type": "long"
+        },
+        {
+          "itemId": "systemMetadata",
+          "type": "set"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/goal.json b/services/src/main/resources/META-INF/cxs/events/goal.json
new file mode 100644
index 0000000..57a3f9f
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/goal.json
@@ -0,0 +1,79 @@
+{
+  "type" : "goal",
+  "propertyTypes" : [
+    {
+      "itemId" : "source",
+      "type": "set"
+    },
+    {
+      "itemId" : "target",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "campaignId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "startEvent",
+          "type" : "set"
+        },
+        {
+          "itemId" : "targetEvent",
+          "type" : "set"
+        },
+        {
+          "itemId" : "metadata",
+          "type" : "set",
+          "childPropertyTypes" : [
+            {
+              "itemId": "id",
+              "type": "string"
+            },
+            {
+              "itemId": "name",
+              "type": "string"
+            },
+            {
+              "itemId": "description",
+              "type": "string"
+            },
+            {
+              "itemId": "scope",
+              "type": "string"
+            },
+            {
+              "itemId": "tags",
+              "multivalued" : true,
+              "type": "string"
+            },
+            {
+              "itemId": "enabled",
+              "type": "boolean"
+            },
+            {
+              "itemId": "missingPlugins",
+              "type": "boolean"
+            },
+            {
+              "itemId": "hidden",
+              "type": "boolean"
+            },
+            {
+              "itemId": "readOnly",
+              "type": "boolean"
+            }
+          ]
+        }
+      ]
+    }
+
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/identify.json b/services/src/main/resources/META-INF/cxs/events/identify.json
new file mode 100644
index 0000000..0842972
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/identify.json
@@ -0,0 +1,69 @@
+{
+  "type": "identify",
+  "propertyTypes": [
+    {
+      "itemId": "properties",
+      "type": "set"
+    },
+    {
+      "itemId" : "source",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId": "version",
+          "type": "long"
+        },
+        {
+          "itemId": "systemMetadata",
+          "type": "set"
+        }
+      ]
+    },
+    {
+      "itemId" : "target",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId": "version",
+          "type": "long"
+        },
+        {
+          "itemId": "systemMetadata",
+          "type": "set"
+        }
+      ]
+    }
+  ]
+}
diff --git a/services/src/main/resources/META-INF/cxs/events/incrementInterest.json b/services/src/main/resources/META-INF/cxs/events/incrementInterest.json
new file mode 100644
index 0000000..d933d51
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/incrementInterest.json
@@ -0,0 +1,33 @@
+{
+  "type" : "incrementInterest",
+  "propertyTypes" : [
+    {
+      "itemId": "properties",
+      "type": "set",
+      "childPropertyTypes": [
+        {
+          "itemId" : "interests",
+          "type" : "set"
+        }
+      ]
+    },
+    {
+      "itemId": "target",
+      "type": "set",
+      "childPropertyTypes": [
+        {
+          "itemId": "itemId",
+          "type": "string"
+        },
+        {
+          "itemId": "properties",
+          "type": "set"
+        },
+        {
+          "itemId": "systemProperties",
+          "type": "set"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/login.json b/services/src/main/resources/META-INF/cxs/events/login.json
index 48a41e6..36f5bc5 100644
--- a/services/src/main/resources/META-INF/cxs/events/login.json
+++ b/services/src/main/resources/META-INF/cxs/events/login.json
@@ -10,22 +10,24 @@
           "type": "string"
         },
         {
+          "itemId": "itemType",
+          "type": "string"
+        },
+        {
+          "itemId": "scope",
+          "type": "string"
+        },
+        {
           "itemId": "properties",
-          "type": "set",
-          "childPropertyTypes": [
-            {
-              "itemId": "preferredLanguage",
-              "type": "string"
-            },
-            {
-              "itemId": "j:gender",
-              "type": "string"
-            },
-            {
-              "itemId": "j:firstName",
-              "type": "string"
-            }
-          ]
+          "type": "set"
+        },
+        {
+          "itemId": "version",
+          "type": "long"
+        },
+        {
+          "itemId": "systemMetadata",
+          "type": "set"
         }
       ]
     }
diff --git a/services/src/main/resources/META-INF/cxs/events/modifyConsent.json b/services/src/main/resources/META-INF/cxs/events/modifyConsent.json
new file mode 100644
index 0000000..0fb7686
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/modifyConsent.json
@@ -0,0 +1,77 @@
+{
+  "type" : "modifyConsent",
+  "propertyTypes" : [
+    {
+      "itemId" : "source",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        }
+      ]
+    },
+    {
+      "itemId" : "target",
+      "type" : "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        }
+      ]
+    },
+    {
+      "itemId" : "properties",
+      "type" : "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "consent",
+          "type" : "set",
+          "childPropertyTypes" : [
+            {
+              "itemId" : "scope",
+              "type" : "string"
+            },
+            {
+              "itemId" : "typeIdentifier",
+              "type" : "string"
+            },
+            {
+              "itemId" : "status",
+              "type" : "string"
+            },
+            {
+              "itemId" : "statusDate",
+              "type" : "date"
+            },
+            {
+              "itemId" : "revokeDate",
+              "type" : "date"
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/profileDeleted.json b/services/src/main/resources/META-INF/cxs/events/profileDeleted.json
new file mode 100644
index 0000000..a7806f2
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/profileDeleted.json
@@ -0,0 +1,23 @@
+{
+  "type" : "profileDeleted",
+  "propertyTypes" : [
+    {
+      "itemId": "target",
+      "type": "set",
+      "childPropertyTypes": [
+        {
+          "itemId": "itemId",
+          "type": "string"
+        },
+        {
+          "itemId": "properties",
+          "type": "set"
+        },
+        {
+          "itemId": "systemProperties",
+          "type": "set"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/ruleFired.json b/services/src/main/resources/META-INF/cxs/events/ruleFired.json
new file mode 100644
index 0000000..601b793
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/ruleFired.json
@@ -0,0 +1,87 @@
+{
+  "type" : "ruleFired",
+  "propertyTypes" : [
+    {
+      "itemId" : "source",
+      "type": "set"
+    },
+    {
+      "itemId" : "target",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "linkedItems",
+          "type" : "string",
+          "multivalued" : true
+        },
+        {
+          "itemId" : "priority",
+          "type" : "long"
+        },
+        {
+          "itemId" : "raiseEventOnlyOnceForProfile",
+          "type" : "boolean"
+        },
+        {
+          "itemId" : "raiseEventOnlyOnceForSession",
+          "type" : "boolean"
+        },
+        {
+          "itemId" : "raiseEventOnlyOnce",
+          "type" : "boolean"
+        },
+        {
+          "itemId" : "metadata",
+          "type" : "set",
+          "childPropertyTypes" : [
+            {
+              "itemId": "id",
+              "type": "string"
+            },
+            {
+              "itemId": "name",
+              "type": "string"
+            },
+            {
+              "itemId": "description",
+              "type": "string"
+            },
+            {
+              "itemId": "scope",
+              "type": "string"
+            },
+            {
+              "itemId": "tags",
+              "multivalued" : true,
+              "type": "string"
+            },
+            {
+              "itemId": "enabled",
+              "type": "boolean"
+            },
+            {
+              "itemId": "missingPlugins",
+              "type": "boolean"
+            },
+            {
+              "itemId": "hidden",
+              "type": "boolean"
+            },
+            {
+              "itemId": "readOnly",
+              "type": "boolean"
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/sessionCreated.json b/services/src/main/resources/META-INF/cxs/events/sessionCreated.json
new file mode 100644
index 0000000..1424c28
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/sessionCreated.json
@@ -0,0 +1,52 @@
+{
+  "type" : "sessionCreated",
+  "propertyTypes" : [
+    {
+      "itemId" : "target",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "profileId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "profile",
+          "type" : "set"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId" : "systemProperties",
+          "type" : "set"
+        },
+        {
+          "itemId" : "lastEventDate",
+          "type" : "date"
+        },
+        {
+          "itemId" : "size",
+          "type" : "long"
+        },
+        {
+          "itemId" : "duration",
+          "type" : "long"
+        }
+      ]
+    }
+
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/sessionReassigned.json b/services/src/main/resources/META-INF/cxs/events/sessionReassigned.json
new file mode 100644
index 0000000..3ec72ab
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/sessionReassigned.json
@@ -0,0 +1,55 @@
+{
+  "type" : "sessionReassigned",
+  "propertyTypes" : [
+    {
+      "itemId" : "source",
+      "type": "set"
+    },
+    {
+      "itemId" : "target",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "profileId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "profile",
+          "type" : "set"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId" : "systemProperties",
+          "type" : "set"
+        },
+        {
+          "itemId" : "lastEventDate",
+          "type" : "date"
+        },
+        {
+          "itemId" : "size",
+          "type" : "long"
+        },
+        {
+          "itemId" : "duration",
+          "type" : "long"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/events/updateProperties.json b/services/src/main/resources/META-INF/cxs/events/updateProperties.json
index f0f785c..089b3b0 100644
--- a/services/src/main/resources/META-INF/cxs/events/updateProperties.json
+++ b/services/src/main/resources/META-INF/cxs/events/updateProperties.json
@@ -3,6 +3,32 @@
   "propertyTypes" : [
     {
       "itemId": "properties",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "targetId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "targetType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "add",
+          "type" : "set"
+        },
+        {
+          "itemId" : "update",
+          "type" : "set"
+        },
+        {
+          "itemId" : "delete",
+          "type" : "set"
+        }
+      ]
+    },
+    {
+      "itemId": "target",
       "type": "set"
     }
   ]
diff --git a/services/src/main/resources/META-INF/cxs/events/view.json b/services/src/main/resources/META-INF/cxs/events/view.json
new file mode 100644
index 0000000..798e24c
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/events/view.json
@@ -0,0 +1,69 @@
+{
+  "type" : "view",
+  "propertyTypes" : [
+    {
+      "itemId": "properties",
+      "type": "set"
+    },
+    {
+      "itemId" : "source",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId": "version",
+          "type": "long"
+        },
+        {
+          "itemId": "systemMetadata",
+          "type": "set"
+        }
+      ]
+    },
+    {
+      "itemId" : "target",
+      "type": "set",
+      "childPropertyTypes" : [
+        {
+          "itemId" : "itemId",
+          "type" : "string"
+        },
+        {
+          "itemId" : "itemType",
+          "type" : "string"
+        },
+        {
+          "itemId" : "scope",
+          "type" : "string"
+        },
+        {
+          "itemId" : "properties",
+          "type" : "set"
+        },
+        {
+          "itemId": "version",
+          "type": "long"
+        },
+        {
+          "itemId": "systemMetadata",
+          "type": "set"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file