Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

W-16571553: merge avro feature to develop in amf #2038

Merged
merged 39 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d010887
W-16459888: add AvroRawSchema Annotation
arielmirra Aug 19, 2024
1b882c1
W-16459888: add Avro JVM and JS plugins
arielmirra Aug 19, 2024
689f973
W-16459888: split avro/jsonschema validation logic
arielmirra Aug 19, 2024
9fd56fb
W-16459888: initial validation testing
arielmirra Aug 19, 2024
afd5321
W-16540082: trow JVM-specific validation messages
arielmirra Aug 22, 2024
0b9c12c
W-16540082: simplify avro payload validators
arielmirra Aug 22, 2024
991581f
W-16540082: improve JS avro payload validation
arielmirra Aug 26, 2024
c45e9ae
W-15633281: add JVM schema validation tests
arielmirra Aug 28, 2024
71e1790
W-15633281: add JS AVRO Schema validation dummy code
arielmirra Aug 28, 2024
4b0b616
W-15633281: fix avro plugin validation error message
arielmirra Aug 28, 2024
336182a
W-16540082: stop serializing AVRORawSchema annotation
arielmirra Aug 29, 2024
218d46c
W-16609870: make async message payload object be virtual unless expli…
arielmirra Sep 2, 2024
9a1cc38
return an empty payload when parsing invalid avro
arielmirra Sep 6, 2024
c6320ad
W-16540082: rename avro Document Emitter
arielmirra Sep 12, 2024
271fd5c
W-16540082: fix Async AVRO payload emission
arielmirra Sep 12, 2024
50ae9da
W-16540082: improve AVRO adr doc
arielmirra Sep 12, 2024
af08613
W-16540082: improve base avro parser interfaces
arielmirra Sep 16, 2024
d648060
W-16540082: improve avro validation exceptions in JVM
arielmirra Sep 16, 2024
28050a0
W-16540082: make AVRORawSchema ann. Eternal
arielmirra Sep 16, 2024
17522ef
W-16540082: add YAML to avro validator mediaTypes
arielmirra Sep 16, 2024
0c7ad8e
add definedBySpec annotation to avro schemas in async apis
arielmirra Sep 18, 2024
24628be
W-16596042: fix avro map with empty values lexical
arielmirra Sep 18, 2024
788d555
W-16596042: update avro ADR validation constraints
arielmirra Sep 18, 2024
f3ff9cf
W-16701554: test avro default values validations
arielmirra Sep 18, 2024
2895299
W-16702592 - AVRO Js lib working
looseale Sep 19, 2024
9e6ff09
generalize loadDataNodeString method in avro validators
arielmirra Sep 19, 2024
cd6365f
fix avro collection members parsing for ALS
arielmirra Sep 19, 2024
16eb6da
W-16701643: add AvroSchemaPayloadValidationPlugin
arielmirra Sep 20, 2024
40bfea4
W-16702592 - Extracted AVRO Error filter. Fixed invalid root type val…
looseale Sep 20, 2024
fe56ec1
W-16701643: remove duplicated anns. in avro record range fields
arielmirra Sep 20, 2024
cdeb1a4
W-16702592 - Fix schema parse validation. Remove excluded errors (we …
looseale Sep 20, 2024
6c381ee
W-16702592 - Uncomment some tests that was ignored for JS
looseale Sep 20, 2024
c811e8f
W-16701643: put avro record field default value inside the property r…
arielmirra Sep 20, 2024
50f159a
W-16701643: test async+avro payload validation in channel message exa…
arielmirra Sep 20, 2024
b42a569
W-16702592 - Added custom NameValidator to JVM AVRO parser in order t…
looseale Sep 20, 2024
d2e0f40
W-16701643: test async+avro payload validator creation
arielmirra Sep 20, 2024
28e11b1
update avro ADR
arielmirra Sep 22, 2024
b019d9e
W-16701643: add anns. to empty avro type
arielmirra Sep 22, 2024
09004eb
update avro ADR
arielmirra Sep 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions adrs/0014-avro-parsing.md → adrs/0014-avro-support.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 13. AWS OAS parsing
# 14. AVRO Support in AMF

Date: 2024-07-02

Expand All @@ -10,8 +10,10 @@ Accepted

## Context

Async 2.x supports AVRO Schemas and we currently don't.
We want to add support AVRO Schemas inside Async APIs and as a standalone documents.
Async 2.x supports AVRO Schemas, and we currently don't.
We want to add support of AVRO Schemas:
- inside Async APIs
- as a standalone document

We need to decide:
- how are we going to map AVRO Schemas to the AMF Model
Expand Down Expand Up @@ -50,10 +52,32 @@ We've also added 3 AVRO-specific fields to the `AnyShape` Model via the `AvroFie
- Aliases
- Size

### Where we support and DON'T support AVRO Schemas
We Support AVRO Schemas (inline or inside a `$ref`):
- as a standalone document or file
- we encourage users to use the `.avsc` file type to indicate that's an avro file, for better suggestions and so on in the platform).
- inside a message payload in an AsyncAPI
- the key `schemaFormat` MUST be declared and specify it's an AVRO payload
arielmirra marked this conversation as resolved.
Show resolved Hide resolved

For now only parsing is done
We don't support AVRO Schemas:
- inside components --> schemas in an AsyncAPI
- because we can't determine if it's an AVRO Schema or any other schema

### AVRO Validation
We'll use the Apache official plugins for JVM and JS.
arielmirra marked this conversation as resolved.
Show resolved Hide resolved

## Consequences

None so far.
## Consequences / Constraints

The validation plugins differ in interfaces and implementations, and each has some constraints:

### JVM avro validation plugin
- validation per se is not supported, we try to parse an avro schema and throw parsing results if there are any
- this means it's difficult to have location of where the error is thrown, we may give an approximate location from our end post-validation
- when a validation is thrown, the rest of the file is not being searched for more validations
- this is particularly important in large avro schemas, where many errors can be found but only one is shown


### Both JVM & JS validation plugins
- `"default"` values are not being validated when the type is `bytes`, `map`, or `array`
- the validator treats as invalid an empty array as the default value for arrays (`"default": []`) even though the [Avro Schema Specification](https://avro.apache.org/docs/1.12.0/specification) has some examples with it
arielmirra marked this conversation as resolved.
Show resolved Hide resolved
29 changes: 28 additions & 1 deletion amf-antlr-syntax/js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion amf-antlr-syntax/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"dependencies": {
"@aml-org/amf-antlr-parsers": "0.7.25",
"ajv": "6.12.6"
"ajv": "6.12.6",
"avro-js": "1.12.0"
}
}
29 changes: 28 additions & 1 deletion amf-api-contract/js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion amf-api-contract/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"dependencies": {
"@aml-org/amf-antlr-parsers": "0.7.25",
"ajv": "6.12.6"
"ajv": "6.12.6",
"avro-js": "^1.12.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import amf.apicontract.internal.spec.avro.transformation.{
AvroSchemaEditingPipeline,
AvroSchemaTransformationPipeline
}
import amf.apicontract.internal.spec.avro.validation.AvroSchemaPayloadValidationPlugin
import amf.apicontract.internal.spec.avro.{AvroParsePlugin, AvroRenderPlugin}
import amf.apicontract.internal.spec.oas._
import amf.apicontract.internal.spec.raml._
Expand Down Expand Up @@ -49,10 +50,12 @@ import amf.core.internal.validation.EffectiveValidations
import amf.core.internal.validation.core.ValidationProfile
import amf.shapes.client.scala.ShapesConfiguration
import amf.shapes.client.scala.config.JsonSchemaConfiguration
import amf.shapes.client.scala.plugin.JsonSchemaShapePayloadValidationPlugin
import amf.shapes.client.scala.plugin.{AvroSchemaShapePayloadValidationPlugin, JsonSchemaShapePayloadValidationPlugin}
import amf.shapes.internal.annotations.ShapeSerializableAnnotations
import amf.shapes.internal.entities.ShapeEntities
import amf.shapes.internal.spec.jsonschema.JsonSchemaParsePlugin
import amf.shapes.internal.validation.model.ShapeEffectiveValidations.AvroSchemaEffectiveValidations
import amf.shapes.internal.validation.model.ShapeValidationProfiles.AvroSchemaValidationProfile

import scala.concurrent.Future

Expand Down Expand Up @@ -82,7 +85,8 @@ trait APIConfigurationBuilder {
configuration.idAdopterProvider
).withPlugins(
List(
JsonSchemaShapePayloadValidationPlugin
JsonSchemaShapePayloadValidationPlugin,
AvroSchemaShapePayloadValidationPlugin
)
).withFallback(ApiContractFallbackPlugin())
result
Expand Down Expand Up @@ -166,14 +170,21 @@ object RAMLConfiguration extends APIConfigurationBuilder {
object AvroConfiguration extends APIConfigurationBuilder {
def Avro(): AMFConfiguration = {
common()
.withPlugins(List(AvroParsePlugin, AvroRenderPlugin)) // TODO: add validation profiles
.withPlugins(
List(
AvroParsePlugin,
AvroRenderPlugin,
AvroSchemaPayloadValidationPlugin()
)
)
.withTransformationPipelines(
List(
AvroSchemaTransformationPipeline(),
AvroSchemaEditingPipeline(),
AvroSchemaCachePipeline()
)
)
.withValidationProfile(AvroSchemaValidationProfile, AvroSchemaEffectiveValidations)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ package amf.apicontract.internal.spec.async.emitters.domain

import amf.apicontract.internal.spec.async.emitters.context.Async20SpecEmitterContext
import amf.apicontract.internal.spec.async.parser.domain.AsyncSchemaFormats
import amf.apicontract.internal.spec.avro.emitters.context.AvroShapeEmitterContext
import amf.apicontract.internal.spec.avro.emitters.domain.AvroShapeEmitter
import amf.apicontract.internal.spec.oas.emitter.context.{OasLikeShapeEmitterContextAdapter, OasLikeSpecEmitterContext}
import amf.apicontract.internal.spec.raml.emitter
import amf.apicontract.internal.spec.spec.toRaml
import org.mulesoft.common.client.lexical.Position
import amf.core.client.scala.model.document.BaseUnit
import amf.core.client.scala.model.domain.Shape
import amf.core.internal.render.BaseEmitters.pos
import amf.core.internal.render.BaseEmitters.{pos, traverse}
import amf.core.internal.render.SpecOrdering
import amf.core.internal.render.emitters.EntryEmitter
import amf.shapes.internal.spec.common.{AVROSchema, RAML10SchemaVersion, SchemaVersion}
import amf.shapes.internal.spec.oas.emitter.OasTypePartEmitter
import amf.shapes.internal.spec.raml.emitter.Raml10TypeEmitter
import org.mulesoft.common.client.lexical.Position
import org.yaml.model.YDocument.EntryBuilder

case class AsyncSchemaEmitter(
Expand Down Expand Up @@ -59,9 +61,9 @@ case class AsyncSchemaEmitter(
key,
b => {
val newCtx = new Async20SpecEmitterContext(spec.eh, config = spec.renderConfig, schemaVersion = schemaVersion)
// todo: call a specific AVRO Schema emitter (tbd in W-15633198)
OasTypePartEmitter(shape, ordering, references = references)(OasLikeShapeEmitterContextAdapter(newCtx))
.emit(b)
val entries =
AvroShapeEmitter(shape, ordering)(AvroShapeEmitterContext(newCtx.eh, newCtx.renderConfig)).entries()
b.obj((traverse(entries, _)))
}
)
}
Expand Down
Loading