Repository: networknt/json-schema-validator (java)

Issue:
Support BinaryNode
When using a Java data model with a byte[] property, json-schema-validator fails to validate because of an unknown data type.

Example:

Java model:
```java
public class Model {

      @ApiModelProperty(name = "s", value = "BASE64 encoded signature", required = true)
    private byte[] signature;
}
````
Jackson converts byte[] automatically to BASE64 strings.

JSON schema:
````json
{
  "properties": {
      "s": {
        "$id": "#/properties/s",
        "type": "string"
      }
  }
}
````

JSON file:
````json
{
  "s": "BASE64 string"
}
````

When parsing it using jackson using the Java model (with byte[] type) and then validating it, the resulting node in the jackson tree is of type BinaryTree. Validation fails then with an unknown type is not of type string error.
IMPORTANT to reproduce: Do not use jackson to directly parse into a tree. In this case the resulting jackosn node is of type TextNode and validation works fine.

Pull request:
Map BinaryNodes to type string
..to support using Java models with type byte[].
close #650

Patch:
diff --git a/pom.xml b/pom.xml
index f10bec2..2f54a19 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.networknt</groupId>
     <artifactId>json-schema-validator</artifactId>
-    <version>1.0.76</version>
+    <version>1.0.77</version>
     <packaging>bundle</packaging>
     <description>A json schema validator that supports draft v4, v6, v7, v2019-09 and v2020-12</description>
     <url>https://github.com/networknt/json-schema-validator</url>
diff --git a/src/main/java/com/networknt/schema/TypeFactory.java b/src/main/java/com/networknt/schema/TypeFactory.java
index d44ff9c..38fa58e 100644
--- a/src/main/java/com/networknt/schema/TypeFactory.java
+++ b/src/main/java/com/networknt/schema/TypeFactory.java
@@ -69,6 +69,8 @@ public class TypeFactory {
         if (node.isValueNode()) {
             if (node.isTextual())
                 return JsonType.STRING;
+            if (node.isBinary())
+                return JsonType.STRING;
             if (node.isIntegralNumber())
                 return JsonType.INTEGER;
             if (node.isNumber())


Test patch:
diff --git a/src/test/java/com/networknt/schema/Issue650Test.java b/src/test/java/com/networknt/schema/Issue650Test.java
new file mode 100644
index 0000000..37a29f7
--- /dev/null
+++ b/src/test/java/com/networknt/schema/Issue650Test.java
@@ -0,0 +1,84 @@
+package com.networknt.schema;
+
+import static org.junit.jupiter.api.Assertions.*;
+import java.io.InputStream;
+import java.util.Set;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.node.BinaryNode;
+
+/**
+ *
+ * created at 07.02.2023
+ *
+ * @author k-oliver
+ * @since 1.0.77
+ */
+public class Issue650Test {
+
+    /**
+     * Test using a Java model with a byte[] property which jackson converts to a BASE64 encoded string automatically. Then convert into
+     * a jackson tree. The resulting node is of type {@link BinaryNode}. This test checks if validation handles the {@link BinaryNode} as string
+     * when validating.
+     *
+     * @throws Exception
+     * @since 1.0.77
+     */
+    @Test
+    public void testBinaryNode() throws Exception {
+        final ObjectMapper mapper = new ObjectMapper();
+        mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+
+        // schema with data property of type string:
+        InputStream schemaInputStream = getClass().getResourceAsStream("/draft7/issue650.json");
+        JsonSchema schema = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7).getSchema(schemaInputStream);
+
+        // create model first:
+        Issue650Test.Model model = new Issue650Test.Model();
+        model.setData("content".getBytes("UTF-8"));
+        // now convert to tree. The resulting type of the data property is BinaryNode now:
+        JsonNode node = mapper.valueToTree(model);
+
+        // validate:
+        Set<ValidationMessage> errors = schema.validate(node);
+
+        // check result:
+        Assertions.assertTrue(errors.isEmpty());
+    }
+
+    /**
+     * created at 07.02.2023
+     *
+     * @author Oliver Kelling
+     * @since 1.0.77
+     */
+    private static class Model {
+        private byte[] data;
+
+
+        /**
+         * @return the data
+         * @since 1.0.77
+         */
+        public byte[] getData() {
+            return this.data;
+        }
+
+
+        /**
+         * @param data the data to set
+         * @since 1.0.77
+         */
+        public void setData(byte[] data) {
+            this.data = data;
+        }
+
+    }
+}
diff --git a/src/test/resources/draft7/issue650.json b/src/test/resources/draft7/issue650.json
new file mode 100644
index 0000000..2eb430c
--- /dev/null
+++ b/src/test/resources/draft7/issue650.json
@@ -0,0 +1,13 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "type": "object",
+  "required": [
+    "data"
+  ],
+  "properties": {
+    "data": {
+      "$id": "#/properties/data",
+      "type": "string"
+    }
+  }
+}
\ No newline at end of file