Checking payload with Json schema

gerhardo
gerhardo Member Posts: 6

Hi !
In the Event Portal I can associate a Json schema for checking the payload of an incoming event.
I'm wondering how to do this when using Spring cloud streams messaging with the Solace binder in a Docker environment. Is there an example available ?
BR Gerhard

Comments

  • marc
    marc Member, Administrator, Moderator, Employee Posts: 914 admin
    edited June 2020 #2

    Hi @gerhardo,
    I think what you're asking is how do I ensure that when sending/receiving events using Spring Cloud Stream that they comply with an associated JSON Schema. Is that correct?

    If yes, the Spring Cloud Stream framework does content-type negotiation to try to convert messages into POJOs that are defined in the method signature of the functions that are bound to the channels that messages are being exchanged over.

    So for example in the Function below the framework will take the message payload and try to convert it into a Person POJO.

    public Function<Person, Person> personFunction {..}

    Because of this, one way to ensure your payloads match the schema is to generate your POJOs from your schemas and that is what is being done in the AsyncAPI Code Generator template for Spring Cloud Stream which you can find here.

    Hope that helps! If you want to see how to use the generator you can check out my youtube video here

    Note that I'm hoping to upgrade our Spring Cloud Stream samples soon :)

    -Marc

  • gerhardo
    gerhardo Member Posts: 6

    Hi @marc ,
    thank you for hint regarding the Json to POJO mapping. I will test it soon.
    Until then i verify incoming Json by using a validator this way:

    import org.everit.json.schema.Schema;
    import org.everit.json.schema.ValidationException;
    import org.everit.json.schema.loader.SchemaLoader;
    import org.json.JSONObject;
    import org.json.JSONTokener;
    ...
        private Schema schema = SchemaLoader
                .load(new JSONObject(new JSONTokener(Application.class.getResourceAsStream("/schema/Item.json"))));
    ...
        @Bean
        public Consumer<String> itemCreated() {
            return s -> {
                try {
                    schema.validate(new JSONObject(new JSONTokener(s)));
                } catch (ValidationException e) {
                    logger.error("item invalid: " + e.toString());
                }
                logger.info("item created: " + s);
            };
        }
    

    I have included this dependency in my gradle build:

    implementation 'org.everit.json:org.everit.json.schema:1.3.0'
    
    

    BR Gerhard

  • gerhardo
    gerhardo Member Posts: 6

    Hi @marc
    Just tested the generator by following the description here .
    If I have some more information in my Json Schemas f.e. an attribute is required, I can not find how this influences the generation. The objects just contain the attributes but no additional settings. Also the comments have not been transfered to the source.
    The infos alle are present in the exported AsyncApi file.
    BR Gerhard

  • marc
    marc Member, Administrator, Moderator, Employee Posts: 914 admin

    Hi @gerhardo,
    I checked with the main developer of the java-spring-cloud-steam-template for asyncapi and it currently does not consider the optional/required as part of the generated POJOs. He did open an enhancement for the template in the template repo here to get it on the to do list. Feel free to contribute if you'd like of course :)
    https://github.com/asyncapi/java-spring-cloud-stream-template/issues/43

    While the AsyncAPI Code Generator does not yet support it, according to the Spring Cloud Stream Reference guide you can register a org.springframework.validation.Validator and then use the @Valid annotation as part of the method signature to ensure that your ingoing/outgoing objects are valid. To me that seems like it would be the best route to take. They don't have much info in the docs but if you use this link and search for "@Valid" it's easy to find. Let me know what you come up with as I haven't had the chance to test this out myself yet!

    -Marc