This is an automated email from the ASF dual-hosted git repository. jkevan pushed a commit to branch eventValidationEndPoint in repository https://gitbox.apache.org/repos/asf/unomi.git
commit b7dbc4afb78473cdc978772b3c96ca14bbc32583 Author: Kevan <ke...@jahia.com> AuthorDate: Wed Mar 22 21:31:11 2023 +0100 UNOMI-754: new jsonSchema endpoint to be able to validate events and get validation error messages --- .../unomi/schema/rest/JsonSchemaEndPoint.java | 20 ++++ .../org/apache/unomi/schema/api/SchemaService.java | 28 ++++- .../unomi/schema/api/ValidationException.java | 36 ++++++ .../unomi/schema/api/ValidationMessageWrapper.java | 51 +++++++++ .../unomi/schema/impl/SchemaServiceImpl.java | 127 ++++++++++++++------- .../org/apache/unomi/itests/InputValidationIT.java | 8 +- .../java/org/apache/unomi/itests/JSONSchemaIT.java | 61 ++++------ .../deserializers/ContextRequestDeserializer.java | 2 +- .../EventsCollectorRequestDeserializer.java | 2 +- 9 files changed, 246 insertions(+), 89 deletions(-) diff --git a/extensions/json-schema/rest/src/main/java/org/apache/unomi/schema/rest/JsonSchemaEndPoint.java b/extensions/json-schema/rest/src/main/java/org/apache/unomi/schema/rest/JsonSchemaEndPoint.java index bb178be0d..4bb637445 100644 --- a/extensions/json-schema/rest/src/main/java/org/apache/unomi/schema/rest/JsonSchemaEndPoint.java +++ b/extensions/json-schema/rest/src/main/java/org/apache/unomi/schema/rest/JsonSchemaEndPoint.java @@ -21,6 +21,7 @@ import org.apache.cxf.rs.security.cors.CrossOriginResourceSharing; import org.apache.unomi.rest.exception.InvalidRequestException; import org.apache.unomi.schema.api.JsonSchemaWrapper; import org.apache.unomi.schema.api.SchemaService; +import org.apache.unomi.schema.api.ValidationMessageWrapper; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; @@ -35,6 +36,7 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.util.Collection; import java.util.Set; @WebService @@ -114,4 +116,22 @@ public class JsonSchemaEndPoint { public boolean remove(String id) { return schemaService.deleteSchema(id); } + + /** + * Being able to validate a given event is useful when you want to develop custom events and associated schemas + * @param event the event to be validated + * @return Validation error messages if there is some + */ + @POST + @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8") + @Consumes({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON }) + @Path("/validateEvent") + public Collection<ValidationMessageWrapper> validateEvent(String event) { + try { + return schemaService.validateEvent(event); + } catch (Exception e) { + String errorMessage = "Unable to validate event: " + e.getMessage(); + throw new InvalidRequestException(errorMessage, errorMessage); + } + } } diff --git a/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/SchemaService.java b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/SchemaService.java index 0e6d398f6..1553dd50b 100644 --- a/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/SchemaService.java +++ b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/SchemaService.java @@ -29,21 +29,39 @@ public interface SchemaService { /** * Verify if a jsonNode is valid against a schema + * (This method is fail safe, if unexpected errors happens it will returns false) * * @param data to validate * @param schemaId id of the schema used for the validation - * @return true is the object is valid + * @return true is the object is valid, false otherwise, false also in case of unexpected errors ! */ boolean isValid(String data, String schemaId); + /** + * Deprecate (since 2.2.0). + * the eventType is now directly extracted from the event source + * You can directly use sibling function: isEventValid(String event) + */ + @Deprecated + boolean isEventValid(String event, String eventType); + /** * Verify if the event is valid + * (This method is fail safe, if unexpected errors happens it will returns false) * - * @param event to validate - * @param eventType The type of the event + * @param event the event to check validity + * @return true is the event is valid, false otherwise, false also in case of unexpected errors ! + */ + boolean isEventValid(String event); + + /** + * perform a validation on the given event + * + * @param event the event to validate * @return true is the event is valid + * @throws ValidationException in case something goes wrong and validation could not be performed. */ - boolean isEventValid(String event, String eventType); + Set<ValidationMessageWrapper> validateEvent(String event) throws ValidationException; /** * Get the list of installed Json Schema Ids @@ -74,7 +92,7 @@ public interface SchemaService { * @param eventType the eventType * @return The JSON Schema able to validate the given event type or null if not found. */ - JsonSchemaWrapper getSchemaForEventType(String eventType); + JsonSchemaWrapper getSchemaForEventType(String eventType) throws ValidationException; /** * Save a new schema or update a schema diff --git a/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationException.java b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationException.java new file mode 100644 index 000000000..d2a278907 --- /dev/null +++ b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationException.java @@ -0,0 +1,36 @@ +/* + * 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.schema.api; + +/** + * This Exception is throw only when a validation process failed due to unexpected error + * Or when we can't perform the validation due to missing data or invalid required data + */ +public class ValidationException extends Exception { + public ValidationException(String message) { + super(message); + } + + public ValidationException(Throwable throwable) { + super(throwable); + } + + public ValidationException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationMessageWrapper.java b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationMessageWrapper.java new file mode 100644 index 000000000..3b0dcc89a --- /dev/null +++ b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/api/ValidationMessageWrapper.java @@ -0,0 +1,51 @@ +/* + * 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.schema.api; + +import com.networknt.schema.ValidationMessage; + +import java.io.Serializable; + +/** + * Just a bean wrapping JSON Schema validation messages to avoid exposing the lib classes to other OSGI bundles. + * (It allows keeping control on the underlying validation system) + */ +public class ValidationMessageWrapper implements Serializable { + + private transient final ValidationMessage validationMessage; + + public ValidationMessageWrapper(ValidationMessage validationMessage) { + this.validationMessage = validationMessage; + } + + public String getError() { + return validationMessage.getMessage(); + } + + public String toString() { + return validationMessage.toString(); + } + + public boolean equals(Object o) { + return validationMessage.equals(o); + } + + public int hashCode() { + return validationMessage.hashCode(); + } +} diff --git a/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/impl/SchemaServiceImpl.java b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/impl/SchemaServiceImpl.java index 44ff90f7b..75b50e4a6 100644 --- a/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/impl/SchemaServiceImpl.java +++ b/extensions/json-schema/services/src/main/java/org/apache/unomi/schema/impl/SchemaServiceImpl.java @@ -31,6 +31,8 @@ import org.apache.unomi.api.services.ScopeService; import org.apache.unomi.persistence.spi.PersistenceService; import org.apache.unomi.schema.api.JsonSchemaWrapper; import org.apache.unomi.schema.api.SchemaService; +import org.apache.unomi.schema.api.ValidationException; +import org.apache.unomi.schema.api.ValidationMessageWrapper; import org.apache.unomi.schema.keyword.ScopeKeyword; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -76,60 +78,45 @@ public class SchemaServiceImpl implements SchemaService { private ScheduledExecutorService scheduler; //private SchedulerService schedulerService; - @Override public boolean isValid(String data, String schemaId) { - JsonSchema jsonSchema; - JsonNode jsonNode; - try { - jsonNode = objectMapper.readTree(data); - jsonSchema = jsonSchemaFactory.getSchema(new URI(schemaId)); - } catch (Exception e) { - logger.debug("Schema validation failed", e); - return false; - } - - if (jsonNode == null) { - logger.debug("Schema validation failed because: no data to validate"); + JsonNode jsonNode = parseData(data); + JsonSchema jsonSchema = getJsonSchema(schemaId); + return validate(jsonNode, jsonSchema).size() == 0; + } catch (ValidationException e) { + if (logger.isDebugEnabled()) { + logger.debug(e.getMessage(), e); + } return false; } + } - if (jsonSchema == null) { - logger.debug("Schema validation failed because: Schema not found {}", schemaId); - return false; - } + @Override + public boolean isEventValid(String event, String eventType) { + return isEventValid(event); + } - Set<ValidationMessage> validationMessages; + @Override + public boolean isEventValid(String event) { try { - validationMessages = jsonSchema.validate(jsonNode); - } catch (Exception e) { - logger.debug("Schema validation failed", e); - return false; - } - - if (validationMessages == null || validationMessages.isEmpty()) { - return true; - } else { + return validateEvent(event).size() == 0; + } catch (ValidationException e) { if (logger.isDebugEnabled()) { - logger.debug("Schema validation found {} errors while validating against schema: {}", validationMessages.size(), schemaId); - for (ValidationMessage validationMessage : validationMessages) { - logger.debug("Validation error: {}", validationMessage); - } + logger.debug(e.getMessage(), e); } - return false; } + return false; } @Override - public boolean isEventValid(String event, String eventType) { + public Set<ValidationMessageWrapper> validateEvent(String event) throws ValidationException { + JsonNode jsonEvent = parseData(event); + String eventType = extractEventType(jsonEvent); JsonSchemaWrapper eventSchema = getSchemaForEventType(eventType); - if (eventSchema != null) { - return isValid(event, eventSchema.getItemId()); - } + JsonSchema jsonSchema = getJsonSchema(eventSchema.getItemId()); - // Event schema not found - return false; + return validate(jsonEvent, jsonSchema); } @Override @@ -150,9 +137,9 @@ public class SchemaServiceImpl implements SchemaService { } @Override - public JsonSchemaWrapper getSchemaForEventType(String eventType) { + public JsonSchemaWrapper getSchemaForEventType(String eventType) throws ValidationException { if (StringUtils.isEmpty(eventType)) { - return null; + throw new ValidationException("eventType missing"); } return schemasById.values().stream() @@ -162,7 +149,7 @@ public class SchemaServiceImpl implements SchemaService { jsonSchemaWrapper.getName() != null && jsonSchemaWrapper.getName().equals(eventType)) .findFirst() - .orElse(null); + .orElseThrow(() -> new ValidationException("Schema not found for event type: " + eventType)); } @Override @@ -199,6 +186,62 @@ public class SchemaServiceImpl implements SchemaService { return predefinedUnomiJSONSchemaById.remove(schemaId) != null; } + private Set<ValidationMessageWrapper> validate(JsonNode jsonNode, JsonSchema jsonSchema) throws ValidationException { + try { + Set<ValidationMessage> validationMessages = jsonSchema.validate(jsonNode); + + if (logger.isDebugEnabled() && validationMessages.size() > 0) { + logger.debug("Schema validation found {} errors while validating against schema: {}", validationMessages.size(), jsonSchema.getCurrentUri()); + for (ValidationMessage validationMessage : validationMessages) { + logger.debug("Validation error: {}", validationMessage); + } + } + + return validationMessages != null ? + validationMessages.stream() + .map(ValidationMessageWrapper::new) + .collect(Collectors.toSet()) : + Collections.emptySet(); + } catch (Exception e) { + throw new ValidationException("Unexpected error while validating", e); + } + } + + private JsonNode parseData(String data) throws ValidationException { + if (StringUtils.isEmpty(data)) { + throw new ValidationException("Empty data, nothing to validate"); + } + + try { + return objectMapper.readTree(data); + } catch (Exception e) { + throw new ValidationException("Unexpected error while parsing the data to validate", e); + } + } + + private JsonSchema getJsonSchema(String schemaId) throws ValidationException { + try { + JsonSchema jsonSchema = jsonSchemaFactory.getSchema(new URI(schemaId)); + if (jsonSchema != null) { + return jsonSchema; + } else { + throw new ValidationException("Json schema not found: " + schemaId); + } + } catch (Exception e) { + throw new ValidationException("Unexpected error while loading json schema: " + schemaId, e); + } + } + + private String extractEventType(JsonNode jsonEvent) throws ValidationException { + if (jsonEvent.hasNonNull("eventType")) { + String eventType = jsonEvent.get("eventType").textValue(); + if (StringUtils.isNotBlank(eventType)) { + return eventType; + } + } + throw new ValidationException("eventType property is either missing/empty/invalid in event source"); + } + private JsonSchemaWrapper buildJsonSchemaWrapper(String schema) { JsonSchema jsonSchema = jsonSchemaFactory.getSchema(schema); JsonNode schemaNode = jsonSchema.getSchemaNode(); @@ -303,7 +346,7 @@ public class SchemaServiceImpl implements SchemaService { try { refreshJSONSchemas(); } catch (Exception e) { - logger.error("Error while refreshing JSON Schemas", e); + logger.error("Unexpected error while refreshing JSON Schemas", e); } } }; 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 8248ca3c7..b04890001 100644 --- a/itests/src/test/java/org/apache/unomi/itests/InputValidationIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/InputValidationIT.java @@ -97,7 +97,7 @@ public class InputValidationIT extends BaseIT { schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json")); schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json")); keepTrying("Event should be valid", - () -> schemaService.isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy"), + () -> schemaService.isEventValid(resourceAsString("schemas/event-dummy-valid.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); @@ -108,7 +108,7 @@ public class InputValidationIT extends BaseIT { schemaService.deleteSchema("https://vendor.test.com/schemas/json/events/dummy/1-0-0"); schemaService.deleteSchema("https://vendor.test.com/schemas/json/events/dummy/properties/1-0-0"); keepTrying("Event should be invalid", - () -> schemaService.isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy"), + () -> schemaService.isEventValid(resourceAsString("schemas/event-dummy-valid.json")), isValid -> !isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); } @@ -143,7 +143,7 @@ public class InputValidationIT extends BaseIT { schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json")); schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json")); keepTrying("Event should be valid", - () -> schemaService.isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy"), + () -> schemaService.isEventValid(resourceAsString("schemas/event-dummy-valid.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); @@ -154,7 +154,7 @@ public class InputValidationIT extends BaseIT { schemaService.deleteSchema("https://vendor.test.com/schemas/json/events/dummy/1-0-0"); schemaService.deleteSchema("https://vendor.test.com/schemas/json/events/dummy/properties/1-0-0"); keepTrying("Event should be invalid", - () -> schemaService.isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy"), + () -> schemaService.isEventValid(resourceAsString("schemas/event-dummy-valid.json")), isValid -> !isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); } 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 f30e3f1a6..43cb5949d 100644 --- a/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/JSONSchemaIT.java @@ -85,35 +85,30 @@ public class JSONSchemaIT extends BaseIT { @Test public void testValidation_SaveDeleteSchemas() throws InterruptedException, IOException { // check that event is not valid at first - assertFalse(schemaService - .isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-valid.json"))); // Push schemas schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json")); schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json")); keepTrying("Event should be valid", () -> schemaService - .isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy"), + .isEventValid(resourceAsString("schemas/event-dummy-valid.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); // Test multiple invalid event: // unevaluated property at root: - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-1.json"), - "dummy")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-1.json"))); // unevaluated property in properties: - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-2.json"), - "dummy")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-2.json"))); // bad type number but should be string: - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-3.json"), - "dummy")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-3.json"))); // Event with unexisting scope: - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-4.json"), - "dummy")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-4.json"))); // remove one of the schema: assertTrue(schemaService.deleteSchema("https://vendor.test.com/schemas/json/events/dummy/properties/1-0-0")); keepTrying("Event should be invalid since of the schema have been deleted", () -> schemaService - .isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy"), + .isEventValid(resourceAsString("schemas/event-dummy-valid.json")), isValid -> !isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); } @@ -121,24 +116,22 @@ public class JSONSchemaIT extends BaseIT { public void testValidation_UpdateSchema() throws InterruptedException, IOException { // check that event is not valid at first assertFalse(schemaService - .isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy")); + .isEventValid(resourceAsString("schemas/event-dummy-valid.json"))); // Push schemas schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json")); schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json")); keepTrying("Event should be valid", () -> schemaService - .isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy"), + .isEventValid(resourceAsString("schemas/event-dummy-valid.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); // Test the invalid event, that use the new prop "invalidPropName" in properties: - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-2.json"), - "dummy")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-invalid-2.json"))); // update the schema to allow "invalidPropName": schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties-updated.json")); keepTrying("Event should be valid since of the schema have been updated", () -> schemaService - .isEventValid(resourceAsString("schemas/event-dummy-invalid-2.json"), - "dummy"), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, + .isEventValid(resourceAsString("schemas/event-dummy-invalid-2.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); } @@ -148,24 +141,23 @@ public class JSONSchemaIT extends BaseIT { schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json")); schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json")); keepTrying("Event should be valid", () -> schemaService - .isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy"), + .isEventValid(resourceAsString("schemas/event-dummy-valid.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); // check that extended event is not valid at first - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-extended.json"), - "dummy")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-extended.json"))); // 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 - .isEventValid(resourceAsString("schemas/event-dummy-extended.json"), "dummy"), + .isEventValid(resourceAsString("schemas/event-dummy-extended.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); // delete one of the extension schemaService.deleteSchema("https://vendor.test.com/schemas/json/events/dummy/properties/extension/1-0-0"); keepTrying("Extended event should be invalid again, one necessary extension have been removed", () -> schemaService - .isEventValid(resourceAsString("schemas/event-dummy-extended.json"), "dummy"), + .isEventValid(resourceAsString("schemas/event-dummy-extended.json")), isValid -> !isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); } @@ -175,29 +167,26 @@ public class JSONSchemaIT extends BaseIT { schemaService.saveSchema(resourceAsString("schemas/schema-dummy.json")); schemaService.saveSchema(resourceAsString("schemas/schema-dummy-properties.json")); keepTrying("Event should be valid", () -> schemaService - .isEventValid(resourceAsString("schemas/event-dummy-valid.json"), "dummy"), + .isEventValid(resourceAsString("schemas/event-dummy-valid.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); // check that extended event is not valid at first - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-extended.json"), - "dummy")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-extended.json"))); // 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 - .isEventValid(resourceAsString("schemas/event-dummy-extended.json"), "dummy"), + .isEventValid(resourceAsString("schemas/event-dummy-extended.json")), 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.isEventValid(resourceAsString("schemas/event-dummy-extended-2.json"), - "dummy")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-dummy-extended-2.json"))); // 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 - .isEventValid(resourceAsString("schemas/event-dummy-extended-2.json"), - "dummy"), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, + .isEventValid(resourceAsString("schemas/event-dummy-extended-2.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); } @@ -260,7 +249,7 @@ public class JSONSchemaIT extends BaseIT { assertNull(schemaService.getSchema("https://vendor.test.com/schemas/json/events/flattened/properties/interests/1-0-0")); // Test that at first the flattened event is not valid. - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-flattened-valid.json"), "flattened")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-flattened-valid.json"))); // save schemas and check the event pass the validation schemaService.saveSchema(resourceAsString("schemas/schema-flattened.json")); @@ -268,7 +257,7 @@ public class JSONSchemaIT extends BaseIT { schemaService.saveSchema(resourceAsString("schemas/schema-flattened-flattenedProperties-interests.json")); schemaService.saveSchema(resourceAsString("schemas/schema-flattened-properties.json")); keepTrying("Event should be valid now", - () -> schemaService.isEventValid(resourceAsString("schemas/event-flattened-valid.json"), "flattened"), + () -> schemaService.isEventValid(resourceAsString("schemas/event-flattened-valid.json")), isValid -> isValid, DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES); // insure event is correctly indexed when send to /cxs/eventCollector @@ -295,9 +284,9 @@ public class JSONSchemaIT extends BaseIT { assertEquals(events.get(0).getItemId(), event.getItemId()); // Bonus: Check that other invalid flattened events are correctly rejected by schema service: - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-flattened-invalid-1.json"), "flattened")); - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-flattened-invalid-2.json"), "flattened")); - assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-flattened-invalid-3.json"), "flattened")); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-flattened-invalid-1.json"))); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-flattened-invalid-2.json"))); + assertFalse(schemaService.isEventValid(resourceAsString("schemas/event-flattened-invalid-3.json"))); } @Test 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 9e4b24216..12ba8347d 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 @@ -90,7 +90,7 @@ public class ContextRequestDeserializer extends StdDeserializer<ContextRequest> ArrayNode events = (ArrayNode) eventsNode; List<Event> filteredEvents = new ArrayList<>(); for (JsonNode event : events) { - if (schemaService.isEventValid(event.toString(), event.get("eventType").textValue())) { + if (schemaService.isEventValid(event.toString())) { filteredEvents.add(jsonParser.getCodec().treeToValue(event, Event.class)); } else { logger.error("An event was rejected - switch to DEBUG log level for more information"); diff --git a/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java b/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java index 2114205ca..b20d6bf07 100644 --- a/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java +++ b/rest/src/main/java/org/apache/unomi/rest/deserializers/EventsCollectorRequestDeserializer.java @@ -63,7 +63,7 @@ public class EventsCollectorRequestDeserializer extends StdDeserializer<EventsCo final JsonNode eventsNode = node.get("events"); if (eventsNode instanceof ArrayNode) { for (JsonNode event : eventsNode) { - if (schemaService.isEventValid(event.toString(), event.get("eventType").textValue())) { + if (schemaService.isEventValid(event.toString())) { filteredEvents.add(jsonParser.getCodec().treeToValue(event, Event.class)); } else { logger.error("An event was rejected - switch to DEBUG log level for more information");