You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by dg...@apache.org on 2022/05/02 08:53:28 UTC

[unomi] branch remove-bean-validation created (now 5f09dacbd)

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

dgriffon pushed a change to branch remove-bean-validation
in repository https://gitbox.apache.org/repos/asf/unomi.git


      at 5f09dacbd UNOMI-562 : remove bean validation

This branch includes the following new commits:

     new 5f09dacbd UNOMI-562 : remove bean validation

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-562 : remove bean validation

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

dgriffon pushed a commit to branch remove-bean-validation
in repository https://gitbox.apache.org/repos/asf/unomi.git

commit 5f09dacbd8baef32b6a5d00978f51471985bde1e
Author: David Griffon <dg...@jahia.com>
AuthorDate: Mon May 2 10:52:46 2022 +0200

    UNOMI-562 : remove bean validation
---
 .../resources/schemas/events/dummy-event-type.json | 43 +++++++++++++++----
 .../deserializers/ContextRequestDeserializer.java  |  4 +-
 ...ava => EventsCollectorRequestDeserializer.java} | 10 ++---
 .../unomi/rest/endpoints/ContextJsonEndpoint.java  | 49 ++++++++++++++--------
 .../rest/endpoints/EventsCollectorEndpoint.java    |  8 +++-
 .../InvalidRequestException.java                   |  7 +++-
 .../exception/InvalidRequestExceptionMapper.java   |  4 +-
 .../org/apache/unomi/rest/server/RestServer.java   | 22 +---------
 .../RetroCompatibilityParamConverterProvider.java  |  7 +---
 .../rest/service/impl/RestServiceUtilsImpl.java    | 19 +++++----
 .../rest/validation/BeanValidationService.java     | 32 --------------
 .../HibernateValidationProviderResolver.java       | 37 ----------------
 .../JAXRSBeanValidationInInterceptorOverride.java  | 42 -------------------
 .../validation/impl/BeanValidationServiceImpl.java | 48 ---------------------
 .../request/RequestValidatorInterceptor.java       |  1 +
 .../rest/validation/wrapper/CookieWrapper.java     | 36 ----------------
 .../META-INF/cxs/schemas/contextrequestparams.json | 16 +++++++
 .../resources/META-INF/cxs/schemas/cookie.json     | 12 ++++++
 .../cxs/schemas/eventscollectorrequest.json        |  5 ++-
 19 files changed, 136 insertions(+), 266 deletions(-)

diff --git a/itests/src/test/resources/schemas/events/dummy-event-type.json b/itests/src/test/resources/schemas/events/dummy-event-type.json
index 439f2f9f2..59f439abf 100644
--- a/itests/src/test/resources/schemas/events/dummy-event-type.json
+++ b/itests/src/test/resources/schemas/events/dummy-event-type.json
@@ -1,14 +1,43 @@
 {
   "$id": "https://unomi.apache.org/schemas/json/events/dummy_event_type/1-0-0",
   "$schema": "https://json-schema.org/draft/2019-09/schema",
-  "self":{
-    "vendor":"org.apache.unomi",
-    "name":"events/dummy_event_type",
-    "format":"jsonschema",
-    "target":"events",
-    "version":"1-0-0"
+  "self": {
+    "vendor": "org.apache.unomi",
+    "name": "events/dummy_event_type",
+    "format": "jsonschema",
+    "target": "events",
+    "version": "1-0-0"
   },
   "title": "DummyEvent",
   "type": "object",
-  "allOf": [{ "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0" }]
+  "allOf": [
+    {
+      "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0"
+    }
+  ],
+  "properties": {
+    "source": {
+      "type": "object",
+      "properties": {
+        "itemType": {
+          "type": "string"
+        },
+        "scope": {
+          "type": "string"
+        },
+        "itemId": {
+          "type": "string"
+        },
+        "properties": {
+          "type": "object",
+          "properties": {
+            "myProperty": {
+              "type": "string",
+              "maxLength": 20000
+            }
+          }
+        }
+      }
+    }
+  }
 }
diff --git a/rest/src/main/java/org/apache/unomi/rest/deserializers/ContextRequestDeserializer.java b/rest/src/main/java/org/apache/unomi/rest/deserializers/ContextRequestDeserializer.java
index 5e5488f3b..1dcb653b8 100644
--- a/rest/src/main/java/org/apache/unomi/rest/deserializers/ContextRequestDeserializer.java
+++ b/rest/src/main/java/org/apache/unomi/rest/deserializers/ContextRequestDeserializer.java
@@ -27,7 +27,7 @@ import org.apache.unomi.api.Event;
 import org.apache.unomi.api.Profile;
 import org.apache.unomi.api.services.PersonalizationService;
 import org.apache.unomi.api.services.SchemaService;
-import org.apache.unomi.rest.validation.request.InvalidRequestException;
+import org.apache.unomi.rest.exception.InvalidRequestException;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -55,7 +55,7 @@ public class ContextRequestDeserializer extends StdDeserializer<ContextRequest>
         JsonNode node = jsonParser.getCodec().readTree(jsonParser);
         // Validate schema on it
         if (!schemaService.isValid(node, "https://unomi.apache.org/schemas/json/contextrequest/1-0-0")) {
-            throw new InvalidRequestException("Invalid received data", "Invalid received data");
+            throw new InvalidRequestException("Invalid Context request object", "Invalid received data");
         }
         ContextRequest cr = new ContextRequest();
         if (node.get("requireSegments") != null) {
diff --git a/rest/src/main/java/org/apache/unomi/rest/deserializers/EventCollectorRequestDeserializer.java b/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java
similarity index 86%
rename from rest/src/main/java/org/apache/unomi/rest/deserializers/EventCollectorRequestDeserializer.java
rename to rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java
index 5e78fc0a9..b544f2089 100644
--- a/rest/src/main/java/org/apache/unomi/rest/deserializers/EventCollectorRequestDeserializer.java
+++ b/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java
@@ -25,7 +25,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
 import org.apache.unomi.api.Event;
 import org.apache.unomi.api.EventsCollectorRequest;
 import org.apache.unomi.api.services.SchemaService;
-import org.apache.unomi.rest.validation.request.InvalidRequestException;
+import org.apache.unomi.rest.exception.InvalidRequestException;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -34,15 +34,15 @@ import java.util.List;
 /**
  * Custom deserializer for EventCollectorRequest that do validate the events using JSon Schema
  */
-public class EventCollectorRequestDeserializer extends StdDeserializer<EventsCollectorRequest> {
+public class EventsCollectorRequestDeserializer extends StdDeserializer<EventsCollectorRequest> {
 
     private final SchemaService schemaService;
 
-    public EventCollectorRequestDeserializer(SchemaService schemaRegistry) {
+    public EventsCollectorRequestDeserializer(SchemaService schemaRegistry) {
         this(null, schemaRegistry);
     }
 
-    public EventCollectorRequestDeserializer(Class<EventsCollectorRequest> vc, SchemaService schemaService) {
+    public EventsCollectorRequestDeserializer(Class<EventsCollectorRequest> vc, SchemaService schemaService) {
         super(vc);
         this.schemaService = schemaService;
     }
@@ -51,7 +51,7 @@ public class EventCollectorRequestDeserializer extends StdDeserializer<EventsCol
     public EventsCollectorRequest deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
         JsonNode node = jsonParser.getCodec().readTree(jsonParser);
         if (!schemaService.isValid(node, "https://unomi.apache.org/schemas/json/eventscollectorrequest/1-0-0")) {
-            throw new InvalidRequestException("Invalid received data", "Invalid received data");
+            throw new InvalidRequestException("Invalid events collector object", "Invalid received data");
         }
 
         // Validate schema on each event
diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java
index 7748b9aa9..324216586 100644
--- a/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java
+++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java
@@ -18,18 +18,17 @@
 package org.apache.unomi.rest.endpoints;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.rs.security.cors.CrossOriginResourceSharing;
 import org.apache.unomi.api.*;
 import org.apache.unomi.api.conditions.Condition;
-import org.apache.unomi.api.services.ConfigSharingService;
-import org.apache.unomi.api.services.EventService;
-import org.apache.unomi.api.services.PersonalizationService;
-import org.apache.unomi.api.services.PrivacyService;
-import org.apache.unomi.api.services.ProfileService;
-import org.apache.unomi.api.services.RulesService;
+import org.apache.unomi.api.services.*;
 import org.apache.unomi.api.utils.ValidationPattern;
 import org.apache.unomi.persistence.spi.CustomObjectMapper;
+import org.apache.unomi.rest.exception.InvalidRequestException;
 import org.apache.unomi.rest.service.RestServiceUtils;
 import org.apache.unomi.utils.Changes;
 import org.apache.unomi.utils.HttpUtils;
@@ -94,6 +93,8 @@ public class ContextJsonEndpoint {
     private ConfigSharingService configSharingService;
     @Reference
     private RestServiceUtils restServiceUtils;
+    @Reference
+    private SchemaService schemaService;
 
     @OPTIONS
     @Path("/context.js")
@@ -110,9 +111,9 @@ public class ContextJsonEndpoint {
     @POST
     @Produces(MediaType.TEXT_PLAIN)
     @Path("/context.js")
-    public Response contextJSAsPost(@Valid ContextRequest contextRequest,
-            @QueryParam("personaId") @Pattern(regexp = ValidationPattern.TEXT_VALID_CHARACTERS_PATTERN) String personaId,
-            @QueryParam("sessionId") @Pattern(regexp = ValidationPattern.TEXT_VALID_CHARACTERS_PATTERN) String sessionId,
+    public Response contextJSAsPost(ContextRequest contextRequest,
+            @QueryParam("personaId") String personaId,
+            @QueryParam("sessionId") String sessionId,
             @QueryParam("timestamp") Long timestampAsLong, @QueryParam("invalidateProfile") boolean invalidateProfile,
             @QueryParam("invalidateSession") boolean invalidateSession) throws JsonProcessingException {
         return contextJSAsGet(contextRequest, personaId, sessionId, timestampAsLong, invalidateProfile, invalidateSession);
@@ -121,9 +122,9 @@ public class ContextJsonEndpoint {
     @GET
     @Produces(MediaType.TEXT_PLAIN)
     @Path("/context.js")
-    public Response contextJSAsGet(@QueryParam("payload") @Valid ContextRequest contextRequest,
-            @QueryParam("personaId") @Pattern(regexp = ValidationPattern.TEXT_VALID_CHARACTERS_PATTERN) String personaId,
-            @QueryParam("sessionId") @Pattern(regexp = ValidationPattern.TEXT_VALID_CHARACTERS_PATTERN) String sessionId,
+    public Response contextJSAsGet(@QueryParam("payload") ContextRequest contextRequest,
+            @QueryParam("personaId") String personaId,
+            @QueryParam("sessionId") String sessionId,
             @QueryParam("timestamp") Long timestampAsLong, @QueryParam("invalidateProfile") boolean invalidateProfile,
             @QueryParam("invalidateSession") boolean invalidateSession) throws JsonProcessingException {
         ContextResponse contextResponse = contextJSONAsPost(contextRequest, personaId, sessionId, timestampAsLong, invalidateProfile,
@@ -138,9 +139,9 @@ public class ContextJsonEndpoint {
     @GET
     @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
     @Path("/context.json")
-    public ContextResponse contextJSONAsGet(@QueryParam("payload") @Valid ContextRequest contextRequest,
-            @QueryParam("personaId") @Pattern(regexp = ValidationPattern.TEXT_VALID_CHARACTERS_PATTERN) String personaId,
-            @QueryParam("sessionId") @Pattern(regexp = ValidationPattern.TEXT_VALID_CHARACTERS_PATTERN) String sessionId,
+    public ContextResponse contextJSONAsGet(@QueryParam("payload") ContextRequest contextRequest,
+            @QueryParam("personaId") String personaId,
+            @QueryParam("sessionId") String sessionId,
             @QueryParam("timestamp") Long timestampAsLong, @QueryParam("invalidateProfile") boolean invalidateProfile,
             @QueryParam("invalidateSession") boolean invalidateSession) {
         return contextJSONAsPost(contextRequest, personaId, sessionId, timestampAsLong, invalidateProfile, invalidateSession);
@@ -149,11 +150,23 @@ public class ContextJsonEndpoint {
     @POST
     @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
     @Path("/context.json")
-    public ContextResponse contextJSONAsPost(@Valid ContextRequest contextRequest,
-            @QueryParam("personaId") @Pattern(regexp = ValidationPattern.TEXT_VALID_CHARACTERS_PATTERN) String personaId,
-            @QueryParam("sessionId") @Pattern(regexp = ValidationPattern.TEXT_VALID_CHARACTERS_PATTERN) String sessionId,
+    public ContextResponse contextJSONAsPost(ContextRequest contextRequest,
+            @QueryParam("personaId") String personaId,
+            @QueryParam("sessionId") String sessionId,
             @QueryParam("timestamp") Long timestampAsLong, @QueryParam("invalidateProfile") boolean invalidateProfile,
             @QueryParam("invalidateSession") boolean invalidateSession) {
+
+        // Schema validation
+        ObjectNode paramsAsJson = JsonNodeFactory.instance.objectNode();
+        if (personaId != null) {
+            paramsAsJson.put("personaId", personaId);
+        }
+        if (sessionId != null) {
+            paramsAsJson.put("sessionId", sessionId);
+        }
+        if (!schemaService.isValid(paramsAsJson, "https://unomi.apache.org/schemas/json/contextrequestparams/1-0-0")) {
+            throw new InvalidRequestException("Invalid parameter", "Invalid received data");
+        }
         Date timestamp = new Date();
         if (timestampAsLong != null) {
             timestamp = new Date(timestampAsLong);
diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/EventsCollectorEndpoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/EventsCollectorEndpoint.java
index 28d312a8d..11b4d8c62 100644
--- a/rest/src/main/java/org/apache/unomi/rest/endpoints/EventsCollectorEndpoint.java
+++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/EventsCollectorEndpoint.java
@@ -28,6 +28,7 @@ import org.apache.unomi.api.services.ConfigSharingService;
 import org.apache.unomi.api.services.EventService;
 import org.apache.unomi.api.services.PrivacyService;
 import org.apache.unomi.api.services.ProfileService;
+import org.apache.unomi.rest.exception.InvalidRequestException;
 import org.apache.unomi.rest.models.EventCollectorResponse;
 import org.apache.unomi.rest.service.RestServiceUtils;
 import org.apache.unomi.utils.Changes;
@@ -88,19 +89,22 @@ public class EventsCollectorEndpoint {
 
     @GET
     @Path("/eventcollector")
-    public EventCollectorResponse collectAsGet(@QueryParam("payload") @NotNull @Valid EventsCollectorRequest eventsCollectorRequest,
+    public EventCollectorResponse collectAsGet(@QueryParam("payload") EventsCollectorRequest eventsCollectorRequest,
                                                @QueryParam("timestamp") Long timestampAsString) {
         return doEvent(eventsCollectorRequest, timestampAsString);
     }
 
     @POST
     @Path("/eventcollector")
-    public EventCollectorResponse collectAsPost(@NotNull @Valid EventsCollectorRequest eventsCollectorRequest,
+    public EventCollectorResponse collectAsPost(EventsCollectorRequest eventsCollectorRequest,
             @QueryParam("timestamp") Long timestampAsLong) {
         return doEvent(eventsCollectorRequest, timestampAsLong);
     }
 
     private EventCollectorResponse doEvent(EventsCollectorRequest eventsCollectorRequest, Long timestampAsLong) {
+        if (eventsCollectorRequest == null) {
+            throw new InvalidRequestException("events collector cannot be empty", "Invalid received data");
+        }
         Date timestamp = new Date();
         if (timestampAsLong != null) {
             timestamp = new Date(timestampAsLong);
diff --git a/rest/src/main/java/org/apache/unomi/rest/validation/request/InvalidRequestException.java b/rest/src/main/java/org/apache/unomi/rest/exception/InvalidRequestException.java
similarity index 83%
rename from rest/src/main/java/org/apache/unomi/rest/validation/request/InvalidRequestException.java
rename to rest/src/main/java/org/apache/unomi/rest/exception/InvalidRequestException.java
index b41a6575f..d97495e6a 100644
--- a/rest/src/main/java/org/apache/unomi/rest/validation/request/InvalidRequestException.java
+++ b/rest/src/main/java/org/apache/unomi/rest/exception/InvalidRequestException.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.unomi.rest.validation.request;
+package org.apache.unomi.rest.exception;
 
 /**
  * Exception throw when the request exceed the configured limit size
@@ -26,6 +26,11 @@ public class InvalidRequestException extends RuntimeException {
      */
     private final String responseMessage;
 
+    /**
+     * Build an invalid request
+     * @param message message in the logs. It contains detailed information
+     * @param responseMessage message in the response, sent to the browser, must be vague as possible.
+     */
     public InvalidRequestException(String message, String responseMessage) {
         super(message);
         this.responseMessage = responseMessage;
diff --git a/rest/src/main/java/org/apache/unomi/rest/exception/InvalidRequestExceptionMapper.java b/rest/src/main/java/org/apache/unomi/rest/exception/InvalidRequestExceptionMapper.java
index 9dfd29e1a..c793f602f 100644
--- a/rest/src/main/java/org/apache/unomi/rest/exception/InvalidRequestExceptionMapper.java
+++ b/rest/src/main/java/org/apache/unomi/rest/exception/InvalidRequestExceptionMapper.java
@@ -16,7 +16,6 @@
  */
 package org.apache.unomi.rest.exception;
 
-import org.apache.unomi.rest.validation.request.InvalidRequestException;
 import org.osgi.service.component.annotations.Component;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,7 +32,8 @@ public class InvalidRequestExceptionMapper implements ExceptionMapper<InvalidReq
 
     @Override
     public Response toResponse(InvalidRequestException exception) {
-        logger.error(exception.getMessage(), exception);
+        logger.error("{} - set InvalidRequestExceptionMapper to debug level to get full error", exception.getMessage());
+        logger.debug("error", exception);
 
         return Response.status(Response.Status.BAD_REQUEST).header("Content-Type", MediaType.TEXT_PLAIN)
                 .entity("Request rejected by the server because: " + exception.getResponseMessage()).build();
diff --git a/rest/src/main/java/org/apache/unomi/rest/server/RestServer.java b/rest/src/main/java/org/apache/unomi/rest/server/RestServer.java
index 2d43dcb0d..0da55b996 100644
--- a/rest/src/main/java/org/apache/unomi/rest/server/RestServer.java
+++ b/rest/src/main/java/org/apache/unomi/rest/server/RestServer.java
@@ -26,8 +26,6 @@ import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
 import org.apache.cxf.jaxrs.openapi.OpenApiCustomizer;
 import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
 import org.apache.cxf.jaxrs.security.SimpleAuthorizingFilter;
-import org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor;
-import org.apache.cxf.jaxrs.validation.JAXRSBeanValidationOutInterceptor;
 import org.apache.cxf.message.Message;
 import org.apache.unomi.api.ContextRequest;
 import org.apache.unomi.api.EventsCollectorRequest;
@@ -37,10 +35,8 @@ import org.apache.unomi.rest.authentication.AuthenticationFilter;
 import org.apache.unomi.rest.authentication.AuthorizingInterceptor;
 import org.apache.unomi.rest.authentication.RestAuthenticationConfig;
 import org.apache.unomi.rest.deserializers.ContextRequestDeserializer;
-import org.apache.unomi.rest.deserializers.EventCollectorRequestDeserializer;
+import org.apache.unomi.rest.deserializers.EventsCollectorRequestDeserializer;
 import org.apache.unomi.rest.server.provider.RetroCompatibilityParamConverterProvider;
-import org.apache.unomi.rest.validation.JAXRSBeanValidationInInterceptorOverride;
-import org.apache.unomi.rest.validation.BeanValidationService;
 import org.apache.unomi.rest.validation.request.RequestValidatorInterceptor;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
@@ -75,7 +71,6 @@ public class RestServer {
     private Bus serverBus;
     private RestAuthenticationConfig restAuthenticationConfig;
     private List<ExceptionMapper> exceptionMappers = new ArrayList<>();
-    private BeanValidationService beanValidationService;
     private ConfigSharingService configSharingService;
     private SchemaService schemaService;
 
@@ -113,11 +108,6 @@ public class RestServer {
         refreshServer();
     }
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    public void setBeanValidationService(BeanValidationService beanValidationService) {
-        this.beanValidationService = beanValidationService;
-    }
-
     public void removeExceptionMapper(ExceptionMapper exceptionMapper) {
         this.exceptionMappers.remove(exceptionMapper);
         timeOfLastUpdate = System.currentTimeMillis();
@@ -213,7 +203,7 @@ public class RestServer {
 
         Map<Class, StdDeserializer<?>> desers = new HashMap<>();
         desers.put(ContextRequest.class, new ContextRequestDeserializer(schemaService));
-        desers.put(EventsCollectorRequest.class, new EventCollectorRequestDeserializer(schemaService));
+        desers.put(EventsCollectorRequest.class, new EventsCollectorRequestDeserializer(schemaService));
 
 
         // Build the server
@@ -251,14 +241,6 @@ public class RestServer {
         openApiFeature.setCustomizer(customizer);
         jaxrsServerFactoryBean.getFeatures().add(openApiFeature);
 
-        // Hibernate validator config
-        JAXRSBeanValidationInInterceptor beanValidationInInterceptor = new JAXRSBeanValidationInInterceptorOverride();
-        JAXRSBeanValidationOutInterceptor beanValidationOutInterceptor = new JAXRSBeanValidationOutInterceptor();
-        beanValidationInInterceptor.setProvider(beanValidationService.getBeanValidationProvider());
-        beanValidationOutInterceptor.setProvider(beanValidationService.getBeanValidationProvider());
-        inInterceptors.add(beanValidationInInterceptor);
-        outInterceptors.add(beanValidationOutInterceptor);
-
         // Request validator
         inInterceptors.add(new RequestValidatorInterceptor(configSharingService));
 
diff --git a/rest/src/main/java/org/apache/unomi/rest/server/provider/RetroCompatibilityParamConverterProvider.java b/rest/src/main/java/org/apache/unomi/rest/server/provider/RetroCompatibilityParamConverterProvider.java
index d7b6f3e84..fabd37121 100644
--- a/rest/src/main/java/org/apache/unomi/rest/server/provider/RetroCompatibilityParamConverterProvider.java
+++ b/rest/src/main/java/org/apache/unomi/rest/server/provider/RetroCompatibilityParamConverterProvider.java
@@ -20,12 +20,9 @@ import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.unomi.api.ContextRequest;
 import org.apache.unomi.api.EventsCollectorRequest;
-import org.apache.unomi.rest.validation.request.InvalidRequestException;
+import org.apache.unomi.rest.exception.InvalidRequestException;
 
-import javax.ws.rs.BadRequestException;
-import javax.ws.rs.ProcessingException;
 import javax.ws.rs.ext.*;
-import java.io.IOException;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
@@ -65,7 +62,7 @@ public class RetroCompatibilityParamConverterProvider implements ParamConverterP
                     try {
                         return objectMapper.readValue(factory.createParser(value), rawType);
                     } catch (Exception e) {
-                        throw new InvalidRequestException("Invalid received data", "Invalid received data");
+                        throw new InvalidRequestException(String.format("Unable to deserialize object because %s", e.getMessage()), "Invalid received data");
                     }
                 }
 
diff --git a/rest/src/main/java/org/apache/unomi/rest/service/impl/RestServiceUtilsImpl.java b/rest/src/main/java/org/apache/unomi/rest/service/impl/RestServiceUtilsImpl.java
index 9f05bd6be..4600f0c1e 100644
--- a/rest/src/main/java/org/apache/unomi/rest/service/impl/RestServiceUtilsImpl.java
+++ b/rest/src/main/java/org/apache/unomi/rest/service/impl/RestServiceUtilsImpl.java
@@ -16,6 +16,8 @@
  */
 package org.apache.unomi.rest.service.impl;
 
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.TextNode;
 import org.apache.unomi.api.Event;
 import org.apache.unomi.api.Persona;
 import org.apache.unomi.api.Profile;
@@ -23,9 +25,9 @@ import org.apache.unomi.api.Session;
 import org.apache.unomi.api.services.ConfigSharingService;
 import org.apache.unomi.api.services.EventService;
 import org.apache.unomi.api.services.PrivacyService;
+import org.apache.unomi.api.services.SchemaService;
+import org.apache.unomi.rest.exception.InvalidRequestException;
 import org.apache.unomi.rest.service.RestServiceUtils;
-import org.apache.unomi.rest.validation.BeanValidationService;
-import org.apache.unomi.rest.validation.wrapper.CookieWrapper;
 import org.apache.unomi.utils.Changes;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
@@ -36,6 +38,7 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.BadRequestException;
 import java.util.Date;
 import java.util.List;
 
@@ -47,15 +50,14 @@ public class RestServiceUtilsImpl implements RestServiceUtils {
     @Reference
     private ConfigSharingService configSharingService;
 
-    @Reference
-    private BeanValidationService beanValidationService;
-
     @Reference
     private PrivacyService privacyService;
 
     @Reference
     private EventService eventService;
 
+    @Reference SchemaService schemaService;
+
     public String getProfileIdCookieValue(HttpServletRequest httpServletRequest) {
         String cookieProfileId = null;
 
@@ -63,8 +65,11 @@ public class RestServiceUtilsImpl implements RestServiceUtils {
 
         if (cookies != null) {
             for (Cookie cookie : cookies) {
-                if (configSharingService.getProperty("profileIdCookieName").equals(cookie.getName())) {
-                    beanValidationService.getBeanValidationProvider().validateBean(new CookieWrapper(cookie.getValue()));
+                final Object profileIdCookieName = configSharingService.getProperty("profileIdCookieName");
+                if (profileIdCookieName.equals(cookie.getName())) {
+                    if (!schemaService.isValid(JsonNodeFactory.instance.objectNode().put("profileIdCookieName", cookie.getValue()), "https://unomi.apache.org/schemas/json/cookie/1-0-0")) {
+                        throw new InvalidRequestException("Invalid profile ID format in cookie", "Invalid received data");
+                    }
                     cookieProfileId = cookie.getValue();
                 }
             }
diff --git a/rest/src/main/java/org/apache/unomi/rest/validation/BeanValidationService.java b/rest/src/main/java/org/apache/unomi/rest/validation/BeanValidationService.java
deleted file mode 100644
index b691fe7eb..000000000
--- a/rest/src/main/java/org/apache/unomi/rest/validation/BeanValidationService.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.unomi.rest.validation;
-
-import org.apache.cxf.validation.BeanValidationProvider;
-
-/**
- * This service is just here to provide the CXF BeanValidationProvider in the OSGI context as a service.
- */
-public interface BeanValidationService {
-
-    /**
-     * Get the CXF BeanValidationProvider instance
-     * @return the CXF BeanValidationProvider instance
-     */
-    BeanValidationProvider getBeanValidationProvider();
-}
diff --git a/rest/src/main/java/org/apache/unomi/rest/validation/HibernateValidationProviderResolver.java b/rest/src/main/java/org/apache/unomi/rest/validation/HibernateValidationProviderResolver.java
deleted file mode 100644
index 485733c11..000000000
--- a/rest/src/main/java/org/apache/unomi/rest/validation/HibernateValidationProviderResolver.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.unomi.rest.validation;
-
-import static java.util.Collections.singletonList;
-import org.hibernate.validator.HibernateValidator;
-
-import javax.validation.ValidationProviderResolver;
-import javax.validation.spi.ValidationProvider;
-import java.util.List;
-
-/**
- * OSGi-friendly implementation of {@code javax.validation.ValidationProviderResolver} returning
- * {@code org.hibernate.validator.HibernateValidator} instance.
- *
- */
-public class HibernateValidationProviderResolver implements ValidationProviderResolver {
-
-    @Override
-    public List<ValidationProvider<?>> getValidationProviders() {
-        return singletonList(new HibernateValidator());
-    }
-}
diff --git a/rest/src/main/java/org/apache/unomi/rest/validation/JAXRSBeanValidationInInterceptorOverride.java b/rest/src/main/java/org/apache/unomi/rest/validation/JAXRSBeanValidationInInterceptorOverride.java
deleted file mode 100644
index 44a6d1105..000000000
--- a/rest/src/main/java/org/apache/unomi/rest/validation/JAXRSBeanValidationInInterceptorOverride.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.unomi.rest.validation;
-
-import org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor;
-import org.apache.cxf.message.Message;
-
-import java.lang.reflect.Method;
-import java.util.List;
-
-/**
- * This class allows to replace the class loader use by
- * javax.el.FactoryFinder.newInstance(FactoryFinder.java:53)
- * to allow to retrieve com.sun.el.ExpressionFactoryImpl which is present in the class loader of this module
- */
-public class JAXRSBeanValidationInInterceptorOverride extends JAXRSBeanValidationInInterceptor {
-    @Override
-    protected void handleValidation(final Message message, final Object resourceInstance, final Method method,
-            final List<Object> arguments) {
-        ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
-        try {
-            Thread.currentThread().setContextClassLoader(JAXRSBeanValidationInInterceptorOverride.class.getClassLoader());
-            super.handleValidation(message, resourceInstance, method, arguments);
-        } finally {
-            Thread.currentThread().setContextClassLoader(currentContextClassLoader);
-        }
-    }
-}
diff --git a/rest/src/main/java/org/apache/unomi/rest/validation/impl/BeanValidationServiceImpl.java b/rest/src/main/java/org/apache/unomi/rest/validation/impl/BeanValidationServiceImpl.java
deleted file mode 100644
index 2bccc1811..000000000
--- a/rest/src/main/java/org/apache/unomi/rest/validation/impl/BeanValidationServiceImpl.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.unomi.rest.validation.impl;
-
-import org.apache.cxf.validation.BeanValidationProvider;
-import org.apache.unomi.rest.validation.HibernateValidationProviderResolver;
-import org.apache.unomi.rest.validation.BeanValidationService;
-import org.hibernate.validator.HibernateValidator;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-
-@Component(service = BeanValidationService.class)
-public class BeanValidationServiceImpl implements BeanValidationService {
-    private BeanValidationProvider beanValidationProvider;
-
-    @Activate
-    public void activate() {
-        // This is a TCCL (Thread context class loader) hack to for the javax.el.FactoryFinder to use Class.forName(className)
-        // instead of tccl.loadClass(className) to load the class "com.sun.el.ExpressionFactoryImpl".
-        ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
-        try {
-            Thread.currentThread().setContextClassLoader(null);
-            HibernateValidationProviderResolver validationProviderResolver = new HibernateValidationProviderResolver();
-            this.beanValidationProvider = new BeanValidationProvider(validationProviderResolver, HibernateValidator.class);
-        } finally {
-            Thread.currentThread().setContextClassLoader(currentContextClassLoader);
-        }
-    }
-
-    public BeanValidationProvider getBeanValidationProvider() {
-        return beanValidationProvider;
-    }
-}
diff --git a/rest/src/main/java/org/apache/unomi/rest/validation/request/RequestValidatorInterceptor.java b/rest/src/main/java/org/apache/unomi/rest/validation/request/RequestValidatorInterceptor.java
index 4cc23434f..ae19c1039 100644
--- a/rest/src/main/java/org/apache/unomi/rest/validation/request/RequestValidatorInterceptor.java
+++ b/rest/src/main/java/org/apache/unomi/rest/validation/request/RequestValidatorInterceptor.java
@@ -22,6 +22,7 @@ import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.AbstractPhaseInterceptor;
 import org.apache.cxf.phase.Phase;
 import org.apache.unomi.api.services.ConfigSharingService;
+import org.apache.unomi.rest.exception.InvalidRequestException;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.ArrayList;
diff --git a/rest/src/main/java/org/apache/unomi/rest/validation/wrapper/CookieWrapper.java b/rest/src/main/java/org/apache/unomi/rest/validation/wrapper/CookieWrapper.java
deleted file mode 100644
index 6a5040eba..000000000
--- a/rest/src/main/java/org/apache/unomi/rest/validation/wrapper/CookieWrapper.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.unomi.rest.validation.wrapper;
-
-import org.apache.unomi.api.utils.ValidationPattern;
-
-import javax.validation.constraints.Pattern;
-
-/**
- * This class exists to allow to wrap a cookie value into an object and validate this object trough
- * the bean validation
- */
-public class CookieWrapper {
-
-    @Pattern(regexp = ValidationPattern.TEXT_VALID_CHARACTERS_PATTERN)
-    private String cookie;
-
-    public CookieWrapper(String cookie) {
-        this.cookie = cookie;
-    }
-
-}
diff --git a/services/src/main/resources/META-INF/cxs/schemas/contextrequestparams.json b/services/src/main/resources/META-INF/cxs/schemas/contextrequestparams.json
new file mode 100644
index 000000000..6e115f3cb
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/schemas/contextrequestparams.json
@@ -0,0 +1,16 @@
+{
+  "$id": "https://unomi.apache.org/schemas/json/contextrequestparams/1-0-0",
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "title": "ContextRequestParams",
+  "type": "object",
+  "properties": {
+    "personaId" : {
+      "type" : "string",
+      "pattern" : "^(\\w|[-_@\\.]){0,60}$"
+    },
+    "sessionId" : {
+      "type" : "string",
+      "pattern" : "^(\\w|[-_@\\.]){0,60}$"
+    }
+  }
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/schemas/cookie.json b/services/src/main/resources/META-INF/cxs/schemas/cookie.json
new file mode 100644
index 000000000..1e82ada08
--- /dev/null
+++ b/services/src/main/resources/META-INF/cxs/schemas/cookie.json
@@ -0,0 +1,12 @@
+{
+  "$id": "https://unomi.apache.org/schemas/json/cookie/1-0-0",
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "title": "Cookie",
+  "type": "object",
+  "properties": {
+    "profileIdCookieName" : {
+      "type" : "string",
+      "pattern" : "^(\\w|[-_@\\.]){0,60}$"
+    }
+  }
+}
\ No newline at end of file
diff --git a/services/src/main/resources/META-INF/cxs/schemas/eventscollectorrequest.json b/services/src/main/resources/META-INF/cxs/schemas/eventscollectorrequest.json
index 39e98ff83..781ff2862 100644
--- a/services/src/main/resources/META-INF/cxs/schemas/eventscollectorrequest.json
+++ b/services/src/main/resources/META-INF/cxs/schemas/eventscollectorrequest.json
@@ -10,10 +10,11 @@
   ],
   "properties": {
     "events" : {
-      "type": ["null", "array"],
+      "type": ["array"],
       "items": {
         "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0"
-      }
+      },
+      "minItems": 1
     },
     "sessionId" : {
       "type": ["null", "string"],