Add correct handling of `discriminator` in conjunction with `oneOf`

Issue #254 duplicate
Leonard Osang created an issue

In the Notifications Platform team we started to use this validator and are very happy so far.

However recently we encountered an issue with using the discriminator keyword together with a oneOf usage as described here: https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/.

Our specific use case looks like this:

contentBody:
      title: 'ContentBody'
      oneOf:
        - $ref: '#/components/schemas/adfContentBody'
        - $ref: '#/components/schemas/adfReferenceContentBody'
        - $ref: '#/components/schemas/textContentBody'
      discriminator:
        propertyName: format
        mapping:
          ADF: '#/components/schemas/adfContentBody'
          ADF_REF: '#/components/schemas/adfReferenceContentBody'
          TEXT: '#/components/schemas/textContentBody'
    adfContentBody:
      title: 'AdfContentBody'
      type: object
      properties:
        format:
          $ref: '#/components/schemas/contentBodyFormat'
        data:
          type: string
      required:
        - format
        - data
    adfReferenceContentBody:
      title: 'AdfReferenceContentBody'
      description: |

      type: object
      properties:
        format:
          $ref: '#/components/schemas/contentBodyFormat'
        reference:
          $ref: '#/components/schemas/ari'
        version:
          type: string
      required:
        - format
        - reference
        - version
    textContentBody:
      title: 'TextContentBody'
      type: object
      properties:
        format:
          $ref: '#/components/schemas/contentBodyFormat'
        data:
          type: string
      required:
        - format
        - data
    contentBodyFormat:
      title: 'ContentBodyFormat'
      type: string
      enum:
        - ADF
        - ADF_REF
        - TEXT

This breaks in Discriminator.java with a NullPointerException:

Caused by: com.google.common.util.concurrent.UncheckedExecutionException: java.lang.NullPointerException
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2051)
    at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
    at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3976)
    at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4960)
    at com.github.fge.jsonschema.core.processing.CachingProcessor.process(CachingProcessor.java:122)
    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:141)
    at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:133)
    at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529)
    at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278)
    at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155)
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045)
    ... 110 more
Caused by: java.lang.NullPointerException
    at com.atlassian.oai.validator.schema.keyword.Discriminator$DiscriminatorSyntaxChecker.checkValue(Discriminator.java:83)
    at com.github.fge.jsonschema.core.keyword.syntax.checkers.AbstractSyntaxChecker.checkSyntax(AbstractSyntaxChecker.java:116)
    at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.validate(SyntaxProcessor.java:112)
    at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.validate(SyntaxProcessor.java:118)
    at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.validate(SyntaxProcessor.java:118)
    at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.validate(SyntaxProcessor.java:118)
    at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.rawProcess(SyntaxProcessor.java:70)
    at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.rawProcess(SyntaxProcessor.java:45)
    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:190)
    at com.github.fge.jsonschema.core.processing.ProcessingResult.of(ProcessingResult.java:79)
    at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:141)
    at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:133)
    at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529)
    at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278)
    at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155)
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045)
    ... 124 more

It looks like the Discriminator class can’t handle cases where there are no properties in the declared schema object, however it’s possible to combine that with oneOf as mentioned in the documentation.

Happy to assist to fix this 👍

CC @James Navin @Michael Truong

Comments (4)

  1. Leonard Osang Account Deactivated reporter

    Thanks heaps @{557057:f45e4a5a-dc79-4be4-b232-7ac018682f30} indeed looks like exactly the same problem, will give the solution proposal a try now 👍

  2. Log in to comment