GithubHelp home page GithubHelp logo

json-skema's People

Contributors

big-andy-coates avatar dependabot[bot] avatar erosb avatar jakesmolka avatar rayokota avatar rechvs avatar singingbush avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

json-skema's Issues

A list of supported and unsupported (todo) features

Hi

Thanks for providing this library. I am looking to use it in my projects. The "About" section of the library says "(under development)". I am assuming there are some features of 2020-12 which are missing in it right now.

Is there a list detailing supported and unsupported features? Such a list will help in tracking progress and help contributors effectively contribute to this library.

Performance and functional comparison

Hi,

I've recently needed to compare the performance and functionality of this and other JVM based JSON validation libraries, and I thought you might like to see how this implementation compares. I've published to the code and the results here: https://github.com/creek-service/json-schema-validation-comparison.

While I've spent time trying to get the best out of each library under test, it's possible that the results for this implementation could be improved if someone with more in-depth knowledge were to look into it. If you feel I'm not showing in its best light, please feel free to raise PRs to fix issues and improve your score.

Please feel free to link to the code and results.

I hope this is of some use to you.

Thanks,

Andy

Validation returns "An operation is not implemented: something went wrong" for complex schema

Hi @erosb ,

While using this library against our test suite, I ran into a validation error on a complex schema. Below is the code that returns the error.

package io.confluent.kafka.schemaregistry.json.schema;

import com.github.erosb.jsonsKema.IJsonValue;
import com.github.erosb.jsonsKema.JsonParseException;
import com.github.erosb.jsonsKema.JsonParser;
import com.github.erosb.jsonsKema.JsonValue;
import com.github.erosb.jsonsKema.Schema;
import com.github.erosb.jsonsKema.SchemaClient;
import com.github.erosb.jsonsKema.SchemaLoader;
import com.github.erosb.jsonsKema.SchemaLoaderConfig;
import com.github.erosb.jsonsKema.SchemaLoadingException;
import com.github.erosb.jsonsKema.Validator;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import org.junit.Test;

public class ReferenceTest {

  private static final String DUMMY_BASE_URI = "dummy://input/";

  @Test
  public void testReferences() throws Exception {
    String doc = "{\n"
        + "  \"customerName\": \"acme\",\n"
        + "  \"acquireDate\": \"2020-12-12\"\n"
        + "}";
    JsonValue jsonValue = new JsonParser(doc).parse();

    String oneOfSchema = "{\n"
        + "  \"oneOf\": [\n"
        + "    { \"$ref\": \"customer.json\"},\n"
        + "    { \"$ref\": \"user.json\"}\n"
        + "  ]\n"
        + "}";
    String userSchema = "{\n"
        + "  \"type\": \"object\",\n"
        + "  \"additionalProperties\": false,\n"
        + "  \"properties\": {\n"
        + "    \"name\": {\n"
        + "      \"type\": \"string\"\n"
        + "    },\n"
        + "    \"age\": {\n"
        + "      \"type\": \"integer\",\n"
        + "      \"minimum\": 0\n"
        + "    }\n"
        + "  },\n"
        + "  \"required\": [\n"
        + "    \"age\"\n"
        + "  ]\n"
        + "}\n";
    String customerSchema = "{\n"
        + "  \"type\": \"object\",\n"
        + "  \"additionalProperties\": false,\n"
        + "  \"properties\": {\n"
        + "    \"customerName\": {\n"
        + "      \"type\": \"string\"\n"
        + "    },\n"
        + "    \"acquireDate\": {\n"
        + "      \"type\": \"string\"\n"
        + "    }\n"
        + "  }\n"
        + "}\n";

    Map<URI, String> refs = new HashMap<>();
    refs.put(new URI(DUMMY_BASE_URI + "user.json"), userSchema);
    refs.put(new URI(DUMMY_BASE_URI + "customer.json"), customerSchema);

    SchemaLoaderConfig config = new SchemaLoaderConfig(
        new ReferenceSchemaClient(refs), DUMMY_BASE_URI);

    JsonValue schemaJson = new JsonParser(oneOfSchema).parse();

    Schema loadedSchema = new SchemaLoader(schemaJson, config).load();
    Validator validator = Validator.forSchema(loadedSchema);
    validator.validate(jsonValue);
  }

  public static class ReferenceSchemaClient implements SchemaClient {

    private Map<URI, String> references;

    public ReferenceSchemaClient(Map<URI, String> references) {
      this.references = references;
    }

    @Override
    public InputStream get(URI uri) {
      String reference = references.get(uri);
      if (reference == null) {
        throw new UncheckedIOException(new FileNotFoundException(uri.toString()));
      }
      return new ByteArrayInputStream(reference.getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public IJsonValue getParsed(URI uri) {
      BufferedReader reader = new BufferedReader(new InputStreamReader(get(uri)));
      String string = reader.lines().collect(Collectors.joining());
      try {
        return new JsonParser(string, uri).parse();
      } catch (JsonParseException ex) {
        throw new SchemaLoadingException("failed to parse json content returned from $uri", ex);
      }
    }
  }
}

Oddly, if I remove "required": ["age"] from userSchema, then the "something went wrong" error does not appear.

Error in README due to new version

In Readme:

// create a validator instance for each validation (one-time use object)
Validator validator = Validator.create(schema, new ValidatorConfig(FormatValidationPolicy.ALWAYS));

But in version 0.12.0:
new ValidatorConfig(FormatValidationPolicy.ALWAYS) doesn't exists.

supports tuple validation mode for items in array object

Hello, your work is very good and has solved many of my problems, especially for error reports, I haven't found a good way to handle them from other jsonschema projects。I hope you can support the tuple mode of array.items. Thank you very much。

Input some json below, it throw error.
json code:
{ "type": "array", "title": "array desc", "items": [ {"type": "object", "title": "some obj"} ] }

cause
Caused by: kotlin.NotImplementedError: An operation is not implemented. at com.github.erosb.jsonsKema.SchemaLoader.doLoadSchema(SchemaLoader.kt:428) at com.github.erosb.jsonsKema.SchemaLoader.loadChild$json_sKema(SchemaLoader.kt:515) at com.github.erosb.jsonsKema.SchemaLoader$createCompositeSchema$1$1$ctx$1.invoke(SchemaLoader.kt:452) at com.github.erosb.jsonsKema.SchemaLoader$createCompositeSchema$1$1$ctx$1.invoke(SchemaLoader.kt:450) at com.github.erosb.jsonsKema.ItemsKt$itemsSchemaLoader$1.invoke(Items.kt:10) at com.github.erosb.jsonsKema.ItemsKt$itemsSchemaLoader$1.invoke(Items.kt:8) at com.github.erosb.jsonsKema.SchemaLoader$createCompositeSchema$1.invoke(SchemaLoader.kt:475) at com.github.erosb.jsonsKema.SchemaLoader$createCompositeSchema$1.invoke(SchemaLoader.kt:447) at com.github.erosb.jsonsKema.SchemaLoader.enterScope(SchemaLoader.kt:176) at com.github.erosb.jsonsKema.SchemaLoader.createCompositeSchema(SchemaLoader.kt:447)

SubSchema internal references are not resolved

Hello,

I have a problem when working with multiple schemas which refer to the internal content.

NOTE: The test cases below are based on RefResolutionTest.kt class.

When working with a root schema referencing its internal variables, the properties are resolved successfully, for instance:

    @Test
    fun `ref definitions`() {
        val root: CompositeSchema = createSchemaLoaderForString(
                """
            {
                "$ref": "#/$defs/ddd",
                "$defs": {
                   "ddd": {
                        "title": "my title",
                        "$anchor": "myAnchor"
                   }
                }
            }
            """.trimIndent()
        )() as CompositeSchema
        val actual = root.accept(TraversingSchemaVisitor<String>("$ref", "title"))!!
        assertThat(actual).isEqualTo("my title")
    }

Here we refer to "ddd" header directly from the schema and it works well, returning the correct value.

If we want to add a simple subSchema and refer it from the root schema, it works well as well:

    @Test
    fun `ref definitions child`() {
        val actual = createSchemaLoaderForString(
                """
                {
                    "$ref": "http://subschema.json#/$defs/ddd"
                }
            """,
                mapOf(
                        Pair(
                                "http://subschema.json",
                                """
                                    {
                                        "$defs": {
                                           "ddd": {
                                                "title": "my title",
                                                "$anchor": "myAnchor"
                                           }
                                        }
                                    }
                                """
                        )
                )
        )() as CompositeSchema

        val referred = (actual.subschemas.iterator().next() as ReferenceSchema).referredSchema as CompositeSchema
        assertThat(referred.title!!.value).isEqualTo("my title")
    }

However, if the subSchema uses internal "$ref" reference, that fails as the application is looking for the referenced object in the root schema, and not within the subSchema.
For instance, if we move the schema from the first example to a be a subschema in the second example, it does not longer work:

    @Test
    fun `ref definitions child self ref`() {
        val actual = createSchemaLoaderForString(
                """
                {
                    "$ref": "http://subschema.json#/$defs/ddd"
                }
            """,
                mapOf(
                        Pair(
                                "http://subschema.json",
                                """
                                    {
                                        "$ref": "#/$defs/ddd",
                                        "$defs": {
                                           "ddd": {
                                                "title": "my title",
                                                "$anchor": "myAnchor"
                                           }
                                        }
                                    }
                                """
                        )
                )
        )() as CompositeSchema
    }

and returns the following error:

java.lang.Error: json pointer evaluation error: could not resolve property $defs in {
  "$ref": "http://subschema.json#/$defs/ddd"
}
	at com.github.erosb.jsonsKema.SchemaLoader$evaluateJsonPointer$lookupNext$1.invoke(SchemaLoader.kt:375)
	at com.github.erosb.jsonsKema.SchemaLoader$evaluateJsonPointer$lookupNext$1.invoke(SchemaLoader.kt:366)
	at com.github.erosb.jsonsKema.SchemaLoader.enterScope(SchemaLoader.kt:176)
	at com.github.erosb.jsonsKema.SchemaLoader.evaluateJsonPointer$lookupNext(SchemaLoader.kt:366)
	at com.github.erosb.jsonsKema.SchemaLoader.access$evaluateJsonPointer$lookupNext(SchemaLoader.kt:107)
	at com.github.erosb.jsonsKema.SchemaLoader$evaluateJsonPointer$1.invoke(SchemaLoader.kt:404)
	at com.github.erosb.jsonsKema.SchemaLoader$evaluateJsonPointer$1.invoke(SchemaLoader.kt:403)
	at com.github.erosb.jsonsKema.SchemaLoader.runWithChangedBaseURI(SchemaLoader.kt:412)
	at com.github.erosb.jsonsKema.SchemaLoader.evaluateJsonPointer(SchemaLoader.kt:403)
	at com.github.erosb.jsonsKema.SchemaLoader.resolve(SchemaLoader.kt:353)
	at com.github.erosb.jsonsKema.SchemaLoader.loadSchema(SchemaLoader.kt:305)
	at com.github.erosb.jsonsKema.SchemaLoader.loadRootSchema(SchemaLoader.kt:290)
	at com.github.erosb.jsonsKema.SchemaLoader.invoke(SchemaLoader.kt:184)

So it looks like it tries to resolve the "ddd" header from the root schema, when it is defined within the subSchema itself.

Would it be possible to fix the issue as it blocks our project from upgrading from everit library?

Thank you!

Best regards,
Aleksandr.

How to resolve schemas with URI

Hello , I am exploring json-sKema library for schema validation.
I have below schema , how can i resolve city and state json schema during validation.
On validating schema with below data, i expect it to fail validation. But it pass the validation
"{"firstName":"ABC","lastName":"ABC","age":20,"city":{"city1":{"name":20,"zipCode":"45676"}}}\n"

{

"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The citizen's first name."
},
"lastName": {
"type": "string",
"description": "The citizen's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
},
"city": {
"type": "object",
"properties": {
"city1": { "$ref": "city.json"},
"state": {"$ref": "state.json"}
}

  }

}
}

city.json {

"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The city's name."
},
"zipCode": {
"type": "integer",
"description": "The zip code.",
"minimum": 0
}
}
}

state.json {

"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The city's name."
},
"zipCode": {
"type": "integer",
"description": "The zip code.",
"minimum": 0
}
}
}

Override "message" as well as "toString" in JsonTypeException

Currently JsonTypingException only overrides the toString method, whereas JsonParseException only overrides the message field. Is this intentional?
I’m asking, because imho it makes processing these exceptions more difficult than necessary, because you need separate logic for retrieving the detail message: for JsonTypingException you have to call toString, while for JsonParseException you have to access the message field.

If it helps, I’d be happy to provide a PR.

Set up Dependabot to keep dependencies up to date.

Hey @erosb,

I find it generally very useful to make use of GitHub's Dependabot to keep all your project's dependencies up to date. I know this project doesn't have much in the way of release dependencies, but it can't hurt to automate it.

Happy to help if you want.

Improper error message for "unevaluatedProperties": false schema always fails

Hi,

I am trying to validate against a schema that does not allow unevaluated properties and I'm getting the following error every single time: false schema always fails. I managed to reproduce the behavior on a smaller schema:

  • Schema: { "$schema": "http://json-schema.org/draft/2020-12/schema#", "type": "object", "properties": { "key2": { "type": "string" } }, "unevaluatedProperties": false }

  • Document to validate: { "key": "val" }

Any thoughts on this?

Thanks in advance,
Florin

Don't use java.net.URLDecoder.decode(String, Charset) to lower minimum Android API level from 33

When using this library, calls to the static method java.net.URLDecoder.decode(String, Charset) force a minimum Android API level 33[1].

In order to allow using this library on earlier android api versions, code like the following should be replaced throughout the library:

-URLDecoder.decode(s, StandardCharsets.UTF_8)
+URLDecoder.decode(s, StandardCharsets.UTF_8.name())

[1]: https://developer.android.com/reference/java/net/URLDecoder#decode(java.lang.String,%20java.nio.charset.Charset)

Format "date-time" requiring

Create a schema:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "Timestamp Test",
    "type": "object",
    
    "properties": {
	"@timestamp": {
	    "description": "The UTC date and time the event was created",
	    "type": "string",
	    "format": "date-time"
	}
    }
}

Create three test JSON files:

{
    "@timestamp": "2023-07-06T20:20:10.388-02:00"
}
{
    "@timestamp": "2023-07-06T20:20:10.388Z"
}
{
    "@timestamp": "2023-07-06T20:20:10.388"
}

The first two will validate against the schema, the third one does not.

The standard ISO 8601 date/time specification makes the timezone specification optional. Other JSON Schema libraries handle this correctly (e.g., "check-jsonschema").

Extending schemas?

Is it possible to write our own schemas to extend the current definitions? For an example, there is a https://json-schema-faker.js.org/ project that allows users to define "faker" value for their properties. An example of such schema is:

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "faker": "name.findName"
    },
    "email": {
      "type": "string",
      "faker": "internet.email"
    }
  },
  "required": [
    "name",
    "email"
  ]
}

json-sKema will parse all properties except "faker" since it is not a registered keyword. I would like to write my own FakerSchema and extend the SchemaVisitor to allow visiting the new schemas.

Is something like this possible with the library?

kotlin.NotImplementedError

Hello,

I am receiving for one event validation following error

kotlin.NotImplementedError: An operation is not implemented: something went wrong: com.github.erosb.jsonsKema.MarkableJsonObject@13b61e54 vs {
"feature": "some-val",
"element": "some-val",
"action": "some-val"
}

at com.github.erosb.jsonsKema.AggregatingValidationFailure.join$json_sKema(ValidationFailure.kt:67) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.DefaultValidator.accumulate(Validator.kt:711) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.DefaultValidator.accumulate(Validator.kt:156) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.SchemaVisitor.visitCompositeSchema(SchemaVisitor.kt:71) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.DefaultValidator.access$visitCompositeSchema$s680550253(Validator.kt:156) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.DefaultValidator$visitCompositeSchema$2.invoke(Validator.kt:259) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.DefaultValidator$visitCompositeSchema$2.invoke(Validator.kt:258) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.DefaultValidator.withOtherInstance(Validator.kt:352) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.DefaultValidator.visitCompositeSchema(Validator.kt:258) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.DefaultValidator.visitCompositeSchema(Validator.kt:156) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.SchemaVisitor.internallyVisitCompositeSchema$json_sKema(SchemaVisitor.kt:55) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.CompositeSchema.accept(Schema.kt:26) ~[json-sKema-0.13.0.jar:na]
at com.github.erosb.jsonsKema.DefaultValidator.validate(Validator.kt:249) ~[json-sKema-0.13.0.jar:na]
at com.bonial.tracking.trackingpolicing.service.SchemaValidator.validate(SchemaValidator.java:79) ~[classes/:na]
--> rest i cutted 

Tried to debug through the code and I relly cant find the issue.
Using Java 11, json sKema 0.13.0 and also set the kotlin version to 1.9 in my pom.

Is there anything I can do?

Throw SchemaException when loading fails

Hello,

It would be very useful if a SchemaException (or similar) would be thrown when loading a Schema with errors (such as invalid references, or wrongly used keywords). At the moment, an Error is thrown, which is too generic and also does not provide a JSON pointer (like the previous library).

Thank you for your great work!

Regards,
Florin

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.