1
votes

We are use Mule 3.7 CE. In our Maven POM we use apikit 1.7.3. We also use raml-for-jax-rs to generate java code based on the RAML.

What we are trying to do is code-wise use one common object and raml/jsonschema-wise refer to common schema that various other schemas can use.

The mule-flow uses apikit and links to the following RAML (just an example):

#%RAML 0.8
version: v1.0
title: Test service
mediaType: application/json
schemas:
  - addressbook: |
      {
        "$schema": "draft4 (normally the url needs to be here but can't post more then 2 links)",
        "title": "addressbook",
        "description": "addressbook object",
        "type": "object",
        "properties": {
          "address": {
            "description": "address",
            "type": "string",
            "default":""
          }
        }
      }
  - testinput1: |
      {
        "$schema": "draft4 (normally the url needs to be here but can't post more then 2 links)",
        "title": "Testinput1",
        "description": "Testinput1 object",
        "type": "object",
        "properties": {
          "name": {
            "description": "name",
            "type": "string",
            "default":""
          },
          "addressbook": {
            "$ref" : "addressbook"
          }
        }
      }
  - testinput2: |
      {
        "$schema": "draft4 (normally the url needs to be here but can't post more then 2 links)",
        "title": "Testinput2",
        "description": "Testinput2 object",
        "type": "object",
        "properties":
        {
          "name": {
            "description": "id",
            "type": "string"
          },
          "addressbook": {
            "$ref" : "addressbook"
          }
        }
      }
  - output: |
      {
        "$schema": "draft4 (normally the url needs to be here but can't post more then 2 links)",
        "title": "Output",
        "description": "Output object",
        "type": "object",
        "properties": {
          "code": {
            "description": "code",
            "type": "string",
            "default":""
          }
        }
      }
/test1:
  displayName: test1
  post:
    description: test1
    body:
      application/json:
        schema: testinput1
    responses:
      200:
        body:
          application/json:
            schema: output
/test2:
  displayName: test2
  post:
    description: test2
    body:
      application/json:
        schema: testinput2
    responses:
      200:
        body:
          application/json:
            schema: output

Now the problem is that we get the following error when doing a POST at runtime:

 ERROR 2016-02-29 15:45:52,755 [[testraml].test-httpListenerConfig.worker.01] org.mule.module.apikit.MappingExceptionListener: 
********************************************************************************
Message               : fatal: URI "addressbook#" is not absolute
    level: "fatal"
    uri: "addressbook#"
 (com.github.fge.jsonschema.core.exceptions.ProcessingException)
Type                  : org.mule.module.apikit.exception.BadRequestException
Code                  : MULE_ERROR--2
JavaDoc               : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/module/apikit/exception/BadRequestException.html
********************************************************************************
Exception stack is:
1. fatal: URI "addressbook#" is not absolute
    level: "fatal"
    uri: "addressbook#"
 (com.github.fge.jsonschema.core.exceptions.ProcessingException)
  com.github.fge.jsonschema.core.load.SchemaLoader:163 (null)
2. fatal: URI "addressbook#" is not absolute
    level: "fatal"
    uri: "addressbook#"
 (com.github.fge.jsonschema.core.exceptions.ProcessingException) (org.mule.module.apikit.exception.BadRequestException)
  org.mule.module.apikit.validation.RestJsonSchemaValidator:95 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/module/apikit/exception/BadRequestException.html)
********************************************************************************
Root Exception stack trace:
com.github.fge.jsonschema.core.exceptions.ProcessingException: fatal: URI "addressbook#" is not absolute
    level: "fatal"
    uri: "addressbook#"

    at com.github.fge.jsonschema.core.load.SchemaLoader.get(SchemaLoader.java:163)
    at com.github.fge.jsonschema.core.load.RefResolver.rawProcess(RefResolver.java:114)
    at com.github.fge.jsonschema.core.load.RefResolver.rawProcess(RefResolver.java:51)
    at com.github.fge.jsonschema.core.processing.RawProcessor.process(RawProcessor.java:77)
    at com.github.fge.jsonschema.core.processing.RawProcessor.process(RawProcessor.java:41)
    at com.github.fge.jsonschema.core.processing.ProcessorChain$ProcessorMerger.process(ProcessorChain.java:189)
    at com.github.fge.jsonschema.core.processing.ProcessingResult.of(ProcessingResult.java:79)
    at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:128)
    at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:120)
    at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527)
    at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2319)
    at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2282)
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2197)
    at com.google.common.cache.LocalCache.get(LocalCache.java:3937)
    at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3941)
    at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4824)
    at com.github.fge.jsonschema.core.processing.CachingProcessor.process(CachingProcessor.java:109)
    at com.github.fge.jsonschema.processors.validation.ValidationChain.process(ValidationChain.java:107)
    at com.github.fge.jsonschema.processors.validation.ValidationChain.process(ValidationChain.java:57)
    at com.github.fge.jsonschema.core.processing.ProcessorMap$Mapper.process(ProcessorMap.java:166)
    at com.github.fge.jsonschema.core.processing.ProcessingResult.of(ProcessingResult.java:79)
    at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:128)
    at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:120)
    at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527)
    at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2319)
    at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2282)
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2197)
    at com.google.common.cache.LocalCache.get(LocalCache.java:3937)
    at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3941)
    at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4824)
    at com.github.fge.jsonschema.core.processing.CachingProcessor.process(CachingProcessor.java:109)
    at com.github.fge.jsonschema.processors.validation.InstanceValidator.process(InstanceValidator.java:136)
    at com.github.fge.jsonschema.processors.validation.InstanceValidator.processObject(InstanceValidator.java:241)
    at com.github.fge.jsonschema.processors.validation.InstanceValidator.process(InstanceValidator.java:176)
    at com.github.fge.jsonschema.processors.validation.ValidationProcessor.process(ValidationProcessor.java:56)
    at com.github.fge.jsonschema.processors.validation.ValidationProcessor.process(ValidationProcessor.java:34)
    at com.github.fge.jsonschema.core.processing.ProcessingResult.of(ProcessingResult.java:79)
    at com.github.fge.jsonschema.main.JsonSchema.doValidate(JsonSchema.java:76)
    at com.github.fge.jsonschema.main.JsonSchema.validate(JsonSchema.java:109)
    at com.github.fge.jsonschema.main.JsonSchema.validate(JsonSchema.java:125)
    at org.mule.module.apikit.validation.RestJsonSchemaValidator.validate(RestJsonSchemaValidator.java:73)
    at org.mule.module.apikit.HttpRestRequest.validateSchema(HttpRestRequest.java:413)
    at org.mule.module.apikit.HttpRestRequest.valideateBody(HttpRestRequest.java:312)
    at org.mule.module.apikit.HttpRestRequest.negotiateInputRepresentation(HttpRestRequest.java:289)
    at org.mule.module.apikit.HttpRestRequest.validate(HttpRestRequest.java:114)
    at org.mule.module.apikit.AbstractRouter.processRouterRequest(AbstractRouter.java:193)
    at org.mule.module.apikit.AbstractRouter.processBlockingRequest(AbstractRouter.java:89)
    at org.mule.module.apikit.AbstractRouter.processBlocking(AbstractRouter.java:83)
    at org.mule.processor.AbstractRequestResponseMessageProcessor.process(AbstractRequestResponseMessageProcessor.java:47)
    at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
    at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:107)
    at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
    at org.mule.processor.BlockingProcessorExecutor.executeNext(Blocking...
********************************************************************************

The generated code that comes from raml-for-jax-rs looks good. We got one Addressbook object which TestInput1 and TestInput2 uses.

We did find a jira ticket that says it was fixed in 1.7.3 (which we use in our POM). To our knowledge this issue still doesn't seem resolved because RAML-wise this looks good, code-wise it looks good but using the RAML with API-kit gives errors.

So are we doing something wrong? Is this still a bug? Do we need to wait for Mule 3.8? Any work-around? Are we doing it wrong on a concept level?

Also on a side-note; viewing the APIkit console shows the reference intact instead of describing the reference. That way external developers don't know what the context is of the scheme. Any work-around for that?

1
Thanks for the link. However I have seen that post before. As you can see in the example I posted is that I use #ref. At the moment RAML 1.0 is not an option yet because raml-for-jax-rs does not support RAML 1.0 yet. Also if not mistaken, RAML 1.0's use of describing objects is not as complete as jsonschema. - Mark W

1 Answers

1
votes

I remember I used a custom JSON validator to call the json schema, but your case here is to reference the object from different schema and produce multiple schema.

Can you create a multiple schema files then use the raml !include? Say !include sampleschema.json.

Then check link: http://spacetelescope.github.io/understanding-json-schema/structuring.html

There is a section there:

"The pound symbol (#) refers to the current document, and then the slash (/) separated keys thereafter just traverse the keys in the objects in the document. Therefore, in our example "#/definitions/address" means:

go to the root of the document find the value of the key "definitions" within that object, find the value of the key "address" $ref can also be a relative or absolute URI, so if you prefer to include your definitions in separate files, you can also do that. For example:

{ "$ref": "definitions.json#/address" } "