You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2017/10/07 08:59:31 UTC

[03/14] camel git commit: Improved JSON schema loading making it possible for injecting custom schema loader.

Improved JSON schema loading making it possible for injecting custom schema loader.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/923f1267
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/923f1267
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/923f1267

Branch: refs/heads/master
Commit: 923f12675eab496083cd69efd424001672d631bd
Parents: 8ba38cf
Author: Pontus Ullgren <ul...@gmail.com>
Authored: Wed Oct 4 01:10:22 2017 +0200
Committer: Pontus Ullgren <po...@redpill-linpro.com>
Committed: Fri Oct 6 22:37:42 2017 +0200

----------------------------------------------------------------------
 .../src/main/docs/json-validator-component.adoc | 18 +++--
 .../jsonschema/DefaultJsonSchemaLoader.java     | 45 +++++++++++
 .../everit/jsonschema/JsonSchemaLoader.java     | 28 +++++++
 .../everit/jsonschema/JsonSchemaReader.java     | 36 +++++++++
 .../JsonSchemaValidatorComponent.java           | 13 +--
 .../jsonschema/JsonSchemaValidatorEndpoint.java | 49 ++++++------
 .../jsonschema/JsonValidatingProcessor.java     |  8 +-
 .../component/everit/jsonschema/package.html    |  2 +-
 .../CustomSchemaLoaderValidatorRouteTest.java   | 84 ++++++++++++++++++++
 .../everit/jsonschema/EvenCharNumValidator.java | 22 +++++
 .../jsonschema/TestCustomSchemaLoader.java      | 33 ++++++++
 .../everit/jsonschema/schemawithformat.json     | 35 ++++++++
 12 files changed, 325 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/main/docs/json-validator-component.adoc
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/main/docs/json-validator-component.adoc b/components/camel-everit-json-schema/src/main/docs/json-validator-component.adoc
index 2f10a7b..7097e04 100644
--- a/components/camel-everit-json-schema/src/main/docs/json-validator-component.adoc
+++ b/components/camel-everit-json-schema/src/main/docs/json-validator-component.adoc
@@ -1,9 +1,11 @@
 == JSON Schema Validator Component
 === Everit Json Schema Validator Component
+*Available as of Camel version *
+
 
 *Available as of Camel version 2.20*
 
-The Validator component performs bean validation of the message body
+The JSON Schema Validator component performs bean validation of the message body
 agains JSON Schemas using the Everit.org JSON Schema library
 (https://github.com/everit-org/json-schema). 
 
@@ -29,13 +31,12 @@ json-validator:resourceUri[?options]
 ------------------------------
 
 
-Where *label* is an arbitrary text value describing the endpoint. +
- You can append query options to the URI in the following format,
-?option=value&option=value&...
-
+Where *resourceUri* is some URL to a local resource on the classpath or a 
+full URL to a remote resource or resource on the file system which contains 
+the JSON Schema to validate against.
+ 
 === URI Options
 
-
 // component options: START
 The JSON Schema Validator component has no options.
 // component options: END
@@ -59,7 +60,7 @@ with the following path and query parameters:
 | *resourceUri* | *Required* URL to a local resource on the classpath or a reference to lookup a bean in the Registry or a full URL to a remote resource or resource on the file system which contains the JSON Schema to validate against. |  | String
 |===
 
-==== Query Parameters (5 parameters):
+==== Query Parameters (6 parameters):
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -68,6 +69,7 @@ with the following path and query parameters:
 | *failOnNullHeader* (producer) | Whether to fail if no header exists when validating against a header. | true | boolean
 | *headerName* (producer) | To validate against a header instead of the message body. |  | String
 | *errorHandler* (advanced) | To use a custom org.apache.camel.processor.validation.ValidatorErrorHandler. The default error handler captures the errors and throws an exception. |  | JsonValidatorError Handler
+| *schemaLoader* (advanced) | To use a custom schema loader allowing for adding custom format validation. See the Everit JSON Schema documentation. The default implementation will create a schema loader builder with draft v6 support. |  | JsonSchemaLoader
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used or Camel is allowed to use asynchronous processing (if supported). | false | boolean
 |===
 // endpoint options: END
@@ -117,7 +119,7 @@ Assumed we have the following JSON Schema
 }
 -----------------------------------------------------------
 
-we can validate incomming JSON with the following Camel route.
+we can validate incoming JSON with the following Camel route.
 
 [source,java]
 -------------------------

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/DefaultJsonSchemaLoader.java
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/DefaultJsonSchemaLoader.java b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/DefaultJsonSchemaLoader.java
new file mode 100644
index 0000000..8548f6e
--- /dev/null
+++ b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/DefaultJsonSchemaLoader.java
@@ -0,0 +1,45 @@
+/**
+ * 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.camel.component.everit.jsonschema;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.util.ResourceHelper;
+import org.everit.json.schema.Schema;
+import org.everit.json.schema.loader.SchemaLoader;
+import org.everit.json.schema.loader.SchemaLoader.SchemaLoaderBuilder;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+
+public class DefaultJsonSchemaLoader implements
+        JsonSchemaLoader {
+
+    @Override
+    public Schema createSchema(CamelContext camelContext, String resourceUri) throws IOException {
+        
+        SchemaLoaderBuilder schemaLoaderBuilder = SchemaLoader.builder().draftV6Support();
+        
+        try (InputStream inputStream = ResourceHelper.resolveMandatoryResourceAsInputStream(camelContext, resourceUri)) {
+            JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
+            return schemaLoaderBuilder.schemaJson(rawSchema).build().load().build();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaLoader.java
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaLoader.java b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaLoader.java
new file mode 100644
index 0000000..bd7998b
--- /dev/null
+++ b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaLoader.java
@@ -0,0 +1,28 @@
+/**
+ * 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.camel.component.everit.jsonschema;
+
+import java.io.IOException;
+
+import org.apache.camel.CamelContext;
+import org.everit.json.schema.Schema;
+
+public interface JsonSchemaLoader {
+    
+    Schema createSchema(CamelContext camelContext, String resourceUri) throws IOException;
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaReader.java
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaReader.java b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaReader.java
new file mode 100644
index 0000000..1f76f67
--- /dev/null
+++ b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaReader.java
@@ -0,0 +1,36 @@
+package org.apache.camel.component.everit.jsonschema;
+
+import java.io.IOException;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.util.ObjectHelper;
+import org.everit.json.schema.Schema;
+
+public class JsonSchemaReader {    
+    private Schema schema;
+    
+    private final CamelContext camelContext;
+    private final String resourceUri;
+    private final JsonSchemaLoader schemaLoader;
+    
+    public JsonSchemaReader(CamelContext camelContext, String resourceUri, JsonSchemaLoader schemaLoader) {
+        ObjectHelper.notNull(camelContext, "camelContext");
+        ObjectHelper.notNull(resourceUri, "resourceUri");
+        ObjectHelper.notNull(schemaLoader, "schemaLoader");
+
+        this.camelContext = camelContext;
+        this.resourceUri = resourceUri;
+        this.schemaLoader = schemaLoader;
+    }
+    
+    public Schema getSchema() throws IOException {
+        if ( this.schema == null ) {
+            this.schema = this.schemaLoader.createSchema(this.camelContext, this.resourceUri);
+        }
+        return schema;
+    }
+    
+    public void setSchema(Schema schema) {
+        this.schema = schema;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorComponent.java b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorComponent.java
index 61cdd05..ebf626b 100644
--- a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorComponent.java
+++ b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorComponent.java
@@ -19,23 +19,14 @@ package org.apache.camel.component.everit.jsonschema;
 import java.util.Map;
 
 import org.apache.camel.Endpoint;
-import org.apache.camel.impl.UriEndpointComponent;
+import org.apache.camel.impl.DefaultComponent;
 
 /**
  * The JSON Schema Validator Component is for validating JSON against a schema.
  *
  * @version
  */
-public class JsonSchemaValidatorComponent extends UriEndpointComponent {
-
-    public JsonSchemaValidatorComponent() {
-        this(JsonSchemaValidatorEndpoint.class);
-    }
-
-    public JsonSchemaValidatorComponent(Class<? extends Endpoint> endpointClass) {
-        super(endpointClass);
-    }
-
+public class JsonSchemaValidatorComponent extends DefaultComponent {
 
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
         JsonSchemaValidatorEndpoint endpoint = new JsonSchemaValidatorEndpoint(uri, this, remaining);

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorEndpoint.java b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorEndpoint.java
index ea0db62..dd05a33 100644
--- a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorEndpoint.java
+++ b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonSchemaValidatorEndpoint.java
@@ -16,9 +16,6 @@
  */
 package org.apache.camel.component.everit.jsonschema;
 
-import java.io.IOException;
-import java.io.InputStream;
-
 import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
@@ -30,12 +27,6 @@ import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
-import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.ResourceHelper;
-import org.everit.json.schema.Schema;
-import org.everit.json.schema.loader.SchemaLoader;
-import org.json.JSONObject;
-import org.json.JSONTokener;
 
 
 /**
@@ -52,46 +43,42 @@ public class JsonSchemaValidatorEndpoint extends DefaultEndpoint {
     @UriParam(label = "advanced", description = "To use a custom org.apache.camel.component.everit.jsonschema.JsonValidatorErrorHandler. " 
             + "The default error handler captures the errors and throws an exception.")
     private JsonValidatorErrorHandler errorHandler = new DefaultJsonValidationErrorHandler();
+    @UriParam(label = "advanced", description = "To use a custom schema loader allowing for adding custom format validation. See the Everit JSON Schema documentation.")
+    private JsonSchemaLoader schemaLoader = new DefaultJsonSchemaLoader();
     @UriParam(defaultValue = "true", description = "Whether to fail if no body exists.")
     private boolean failOnNullBody = true;
     @UriParam(defaultValue = "true", description = "Whether to fail if no header exists when validating against a header.")
     private boolean failOnNullHeader = true;
     @UriParam(description = "To validate against a header instead of the message body.")
     private String headerName;
+    
 
     /**
-     * We need a one-to-one relation between endpoint and a Schema 
+     * We need a one-to-one relation between endpoint and a JsonSchemaReader 
      * to be able to clear the cached schema. See method
      * {@link #clearCachedSchema}.
      */
-    private Schema schema;
+    private JsonSchemaReader schemaReader;
 
     public JsonSchemaValidatorEndpoint(String endpointUri, Component component, String resourceUri) {
         super(endpointUri, component);
         this.resourceUri = resourceUri;
     }
 
-    private Schema loadSchema() throws IOException {
-        ObjectHelper.notNull(getCamelContext(), "camelContext");
-        ObjectHelper.notNull(this.resourceUri, "resourceUri");
-        try (InputStream inputStream = ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext(), this.resourceUri)) {
-            JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
-            // LOG.debug("JSON schema: {}", rawSchema);
-            return SchemaLoader.load(rawSchema);
-        }
-    }
-
+    
     @ManagedOperation(description = "Clears the cached schema, forcing to re-load the schema on next request")
     public void clearCachedSchema() {        
-        this.schema = null; // will cause to reload the schema
+        this.schemaReader.setSchema(null); // will cause to reload the schema
     }
     
     @Override
     public Producer createProducer() throws Exception {
-        if (this.schema == null) {
-            this.schema = loadSchema();
+        if (this.schemaReader == null) {
+            this.schemaReader = new JsonSchemaReader(getCamelContext(), resourceUri, schemaLoader);
+            // Load the schema once when creating the producer to fail fast if the schema is invalid.
+            this.schemaReader.getSchema();
         }
-        JsonValidatingProcessor validator = new JsonValidatingProcessor(this.schema);
+        JsonValidatingProcessor validator = new JsonValidatingProcessor(this.schemaReader);
         configureValidator(validator);
 
         return new JsonSchemaValidatorProducer(this, validator);
@@ -140,6 +127,18 @@ public class JsonSchemaValidatorEndpoint extends DefaultEndpoint {
     public void setErrorHandler(JsonValidatorErrorHandler errorHandler) {
         this.errorHandler = errorHandler;
     }
+    
+    public JsonSchemaLoader getSchemaLoader() {
+        return schemaLoader;
+    }
+    
+    /**
+     * To use a custom schema loader allowing for adding custom format validation. See the Everit JSON Schema documentation.
+     * The default implementation will create a schema loader builder with draft v6 support.
+     */
+    public void setSchemaLoader(JsonSchemaLoader schemaLoader) {
+        this.schemaLoader = schemaLoader;
+    }
 
     public boolean isFailOnNullBody() {
         return failOnNullBody;

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonValidatingProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonValidatingProcessor.java b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonValidatingProcessor.java
index 7b5fb68..68cffaf 100644
--- a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonValidatingProcessor.java
+++ b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/JsonValidatingProcessor.java
@@ -39,7 +39,7 @@ import org.slf4j.LoggerFactory;
  */
 public class JsonValidatingProcessor implements AsyncProcessor {
     private static final Logger LOG = LoggerFactory.getLogger(JsonValidatingProcessor.class);
-    private Schema schema;
+    private JsonSchemaReader schemaReader;
     private JsonValidatorErrorHandler errorHandler = new DefaultJsonValidationErrorHandler();
     private boolean failOnNullBody = true;
     private boolean failOnNullHeader = true;
@@ -49,8 +49,8 @@ public class JsonValidatingProcessor implements AsyncProcessor {
         
     }
 
-    public JsonValidatingProcessor(Schema schema) {
-        this.schema = schema;
+    public JsonValidatingProcessor(JsonSchemaReader schemaReader) {
+        this.schemaReader = schemaReader;
     }
 
     public void process(Exchange exchange) throws Exception {
@@ -70,6 +70,7 @@ public class JsonValidatingProcessor implements AsyncProcessor {
     protected void doProcess(Exchange exchange) throws Exception {
         Object jsonPayload = null;
         InputStream is = null;
+        Schema schema = null;
         try {
             is = getContentToValidate(exchange, InputStream.class);
             if (shouldUseHeader()) {
@@ -82,6 +83,7 @@ public class JsonValidatingProcessor implements AsyncProcessor {
                 }
             }
             if (is != null) {
+                schema = this.schemaReader.getSchema();
                 if (schema instanceof ObjectSchema) {
                     jsonPayload = new JSONObject(new JSONTokener(is));
                 } else { 

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/package.html
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/package.html b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/package.html
index 64cf1d8..23a5ab3 100644
--- a/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/package.html
+++ b/components/camel-everit-json-schema/src/main/java/org/apache/camel/component/everit/jsonschema/package.html
@@ -19,7 +19,7 @@
 </head>
 <body>
 
-The <a href="http://activemq.apache.org/camel/validator.html">Validator Component</a> for validating XML against some schema
+The JSON Schema Validator Component for validating JSON against a JSON schema.
 
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/CustomSchemaLoaderValidatorRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/CustomSchemaLoaderValidatorRouteTest.java b/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/CustomSchemaLoaderValidatorRouteTest.java
new file mode 100644
index 0000000..198c1ef
--- /dev/null
+++ b/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/CustomSchemaLoaderValidatorRouteTest.java
@@ -0,0 +1,84 @@
+/**
+ * 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.camel.component.everit.jsonschema;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.ValidationException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class CustomSchemaLoaderValidatorRouteTest extends CamelTestSupport {
+    
+    @EndpointInject(uri = "mock:valid")
+    protected MockEndpoint validEndpoint;
+    
+    @EndpointInject(uri = "mock:finally")
+    protected MockEndpoint finallyEndpoint;
+    
+    @EndpointInject(uri = "mock:invalid")
+    protected MockEndpoint invalidEndpoint;
+
+    @Test
+    public void testValidMessage() throws Exception {
+        validEndpoint.expectedMessageCount(1);
+        finallyEndpoint.expectedMessageCount(1);
+
+        template.sendBody("direct:start",
+                "{ \"name\": \"Even Joe\", \"id\": 1, \"price\": 12.5 }");
+
+        MockEndpoint.assertIsSatisfied(validEndpoint, invalidEndpoint, finallyEndpoint);
+    }
+
+    @Test
+    public void testInvalidMessage() throws Exception {
+        invalidEndpoint.expectedMessageCount(1);
+        finallyEndpoint.expectedMessageCount(1);
+
+        template.sendBody("direct:start",
+                "{ \"name\": \"Odd Joe\", \"id\": 1, \"price\": 12.5 }");
+
+        MockEndpoint.assertIsSatisfied(validEndpoint, invalidEndpoint, finallyEndpoint);
+    }
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry jndiRegistry = super.createRegistry();
+        jndiRegistry.bind("customSchemaLoader", new TestCustomSchemaLoader());
+        return jndiRegistry;
+    }
+    
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .doTry()
+                        .to("json-validator:org/apache/camel/component/everit/jsonschema/schemawithformat.json?schemaLoader=#customSchemaLoader")
+                        .to("mock:valid")
+                    .doCatch(ValidationException.class)
+                        .to("mock:invalid")
+                    .doFinally()
+                        .to("mock:finally")
+                    .end();
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/EvenCharNumValidator.java
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/EvenCharNumValidator.java b/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/EvenCharNumValidator.java
new file mode 100644
index 0000000..876f55e
--- /dev/null
+++ b/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/EvenCharNumValidator.java
@@ -0,0 +1,22 @@
+package org.apache.camel.component.everit.jsonschema;
+
+import java.util.Optional;
+
+import org.everit.json.schema.FormatValidator;
+
+public class EvenCharNumValidator implements FormatValidator {
+
+    @Override
+    public Optional<String> validate(final String subject) {
+      if (subject.length() % 2 == 0) {
+        return Optional.empty();
+      } else {
+        return Optional.of(String.format("the length of string [%s] is odd", subject));
+      }
+    }
+
+    @Override
+    public String formatName() {
+        return "evenlength";
+    }
+  }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/TestCustomSchemaLoader.java
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/TestCustomSchemaLoader.java b/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/TestCustomSchemaLoader.java
new file mode 100644
index 0000000..7902fc3
--- /dev/null
+++ b/components/camel-everit-json-schema/src/test/java/org/apache/camel/component/everit/jsonschema/TestCustomSchemaLoader.java
@@ -0,0 +1,33 @@
+package org.apache.camel.component.everit.jsonschema;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.util.ResourceHelper;
+import org.everit.json.schema.Schema;
+import org.everit.json.schema.loader.SchemaLoader;
+import org.everit.json.schema.loader.SchemaLoader.SchemaLoaderBuilder;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+public class TestCustomSchemaLoader implements JsonSchemaLoader {
+
+    @Override
+    public Schema createSchema(CamelContext camelContext, String resourceUri)
+            throws IOException {
+        
+        SchemaLoaderBuilder schemaLoaderBuilder = SchemaLoader.builder().draftV6Support();
+        
+        try (InputStream inputStream = ResourceHelper.resolveMandatoryResourceAsInputStream(camelContext, resourceUri)) {
+            JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
+            return schemaLoaderBuilder
+                    .schemaJson(rawSchema)
+                    .addFormatValidator(new EvenCharNumValidator())
+                    .build()
+                    .load()
+                    .build();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/923f1267/components/camel-everit-json-schema/src/test/resources/org/apache/camel/component/everit/jsonschema/schemawithformat.json
----------------------------------------------------------------------
diff --git a/components/camel-everit-json-schema/src/test/resources/org/apache/camel/component/everit/jsonschema/schemawithformat.json b/components/camel-everit-json-schema/src/test/resources/org/apache/camel/component/everit/jsonschema/schemawithformat.json
new file mode 100644
index 0000000..17ba7ad
--- /dev/null
+++ b/components/camel-everit-json-schema/src/test/resources/org/apache/camel/component/everit/jsonschema/schemawithformat.json
@@ -0,0 +1,35 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#", 
+  "definitions": {}, 
+  "id": "http://example.com/example.json", 
+  "properties": {
+    "id": {
+      "default": 1, 
+      "description": "An explanation about the purpose of this instance.", 
+      "id": "/properties/id", 
+      "title": "The id schema", 
+      "type": "integer"
+    }, 
+    "name": {
+      "default": "A green door", 
+      "description": "An explanation about the purpose of this instance. Must have even number of characters", 
+      "id": "/properties/name", 
+      "title": "The name schema", 
+      "type": "string",
+      "format": "evenlength"
+    }, 
+    "price": {
+      "default": 12.5, 
+      "description": "An explanation about the purpose of this instance.", 
+      "id": "/properties/price", 
+      "title": "The price schema", 
+      "type": "number"
+    }
+  }, 
+  "required": [
+    "name", 
+    "id", 
+    "price"
+  ], 
+  "type": "object"
+}
\ No newline at end of file