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

Implement support for Protocol Buffer references (imports) -- continued #202

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
bb75685
Specify shell type
Jul 8, 2021
7c8e714
Extend schema registration with Protocol Buffer references
Jul 8, 2021
c66fc55
Support for references in getSchema
Jul 9, 2021
06b0a13
Fix outdated doc string
Jul 9, 2021
4ddb036
Remove debug log
Jul 9, 2021
68cc9eb
Extend import test with an extra layer
Jul 9, 2021
a47dd57
Remove duplicate method and use existing instead
Jul 12, 2021
6ca2f0d
test commit
Aug 31, 2021
d7cb8f6
Avoid polluting imported schema cache entry
Sep 3, 2021
74c2732
Don't include the schemaType field in API requests when type is Avro
Nevon Nov 3, 2021
2af698f
Upgrade build agents
Nevon Nov 3, 2021
1ad5992
Fix typo
Nevon Nov 3, 2021
04419aa
Document new Ajv options introduced in #133
Nevon Nov 3, 2021
f154739
v3.1.0
Nevon Nov 3, 2021
518c3b0
Update link to ajv options page in docs
Nov 3, 2021
5e4315c
Allow ajvInstance to be newer version than we use
Nevon Nov 3, 2021
a3211a1
Create custom Ajv type to allow for old and new versions
Nevon Nov 3, 2021
4ac3cbf
Specify Ajv 8.X.X
Nevon Nov 3, 2021
9bfc87c
Fix lockfile
Nevon Nov 3, 2021
82d5ab4
v3.1.1
Nevon Nov 4, 2021
0ddbed8
Support reader schema when decoding avro
ivan-klass Jul 23, 2021
b2cf528
Adjust formatting, better type annotations
ivan-klass Jul 23, 2021
3b7cea6
Add per schema type decoding options
Nevon Nov 4, 2021
42a5d4c
Fix type discrimination between schema types
Nevon Nov 4, 2021
5bd9aec
Remove outdated docs
Nevon Nov 4, 2021
2f06e2c
Update docs
Nevon Nov 4, 2021
b4efb0f
v3.2.0
Nevon Nov 22, 2021
7ac83d9
Bump lodash from 4.17.19 to 4.17.21
dependabot[bot] Nov 22, 2021
426359d
Handle client-side Mappersmith errors better
Nevon Jan 28, 2022
997785e
v3.2.1
Nevon Jan 28, 2022
96691fe
Bump ajv from 6.10.2 to 6.12.6 in /website
dependabot[bot] Feb 12, 2022
e3d721d
Bump prismjs from 1.17.1 to 1.26.0 in /website
dependabot[bot] Feb 14, 2022
7c1de7f
Bump color-string from 1.5.3 to 1.9.0 in /website
dependabot[bot] Feb 14, 2022
e6b0f07
Bump url-parse from 1.4.7 to 1.5.4 in /website
dependabot[bot] Jan 28, 2022
60894d2
Bump shelljs from 0.8.3 to 0.8.5 in /website
dependabot[bot] Feb 14, 2022
ea2bc22
Bump ws from 7.2.3 to 7.5.7
dependabot[bot] Feb 14, 2022
af8acf3
Bump postcss from 7.0.17 to 7.0.39 in /website
dependabot[bot] Feb 14, 2022
71188d0
Bump tmpl from 1.0.4 to 1.0.5
dependabot[bot] Feb 14, 2022
21d64a1
Bump tar from 4.4.10 to 4.4.19 in /website
dependabot[bot] Feb 14, 2022
2810972
Bump path-parse from 1.0.6 to 1.0.7 in /website
dependabot[bot] Feb 14, 2022
6c53ee5
Bump path-parse from 1.0.6 to 1.0.7
dependabot[bot] Feb 14, 2022
6f56e0e
Bump set-getter from 0.1.0 to 0.1.1 in /website
dependabot[bot] Feb 14, 2022
0dc8d45
Bump glob-parent from 5.1.1 to 5.1.2
dependabot[bot] Feb 14, 2022
19ddc39
Bump y18n from 4.0.0 to 4.0.3
dependabot[bot] Feb 14, 2022
f7de2cb
Bump url-parse from 1.5.4 to 1.5.7 in /website
dependabot[bot] Feb 19, 2022
dd99edd
Bump url-parse from 1.5.7 to 1.5.10 in /website
dependabot[bot] Feb 28, 2022
dc3f9c7
Bump prismjs from 1.26.0 to 1.27.0 in /website
dependabot[bot] Feb 26, 2022
a2f0bfc
Send user-agent header with API requests
Nevon Mar 10, 2022
2832956
fix apicurio register function compatibility
evanshortiss Apr 4, 2022
668b37c
only set compatibility on first time registration
evanshortiss Apr 5, 2022
b53d600
Fix merge artefact: tests passing
erwinw Apr 20, 2022
33b2dd1
Add test for duplicate dependencies, make test pass, migrate to appro…
erwinw Apr 22, 2022
6968f03
Merge branch 'master' of https://github.com/kafkajs/confluent-schema-…
erwinw Apr 22, 2022
f4adf01
Cleanup
erwinw Apr 22, 2022
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
2 changes: 2 additions & 0 deletions bin/avdlToAVSC.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/bin/sh

avdl_path=$1
avsc_name=$2

Expand Down
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ services:
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
depends_on:
- zooKeeper
image: 'confluentinc/cp-kafka:5.5.3'
image: 'confluentinc/cp-kafka:6.2.4'
ports:
- '9092:9092'

zooKeeper: # https://hub.docker.com/r/confluentinc/cp-zookeeper
environment:
ZOOKEEPER_CLIENT_PORT: '2181'
image: 'confluentinc/cp-zookeeper:5.2.2'
image: 'confluentinc/cp-zookeeper:6.2.4'
ports:
- '2181:2181'

schemaRegistry: # https://hub.docker.com/r/confluentinc/cp-schema-registry
environment:
SCHEMA_REGISTRY_KAFKASTORE_CONNECTION_URL: 'zooKeeper:2181'
SCHEMA_REGISTRY_HOST_NAME: localhost
image: 'confluentinc/cp-schema-registry:5.5.3'
image: 'confluentinc/cp-schema-registry:6.2.4'
ports:
- '8982:8081'

Expand Down
1 change: 1 addition & 0 deletions src/@types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export enum SchemaType {
export interface SchemaHelper {
validate(schema: Schema): void
getSubject(confluentSchema: ConfluentSchema, schema: Schema, separator: string): ConfluentSubject
referencedSchemas(schema: string): Promise<string[]>
}

export type AvroOptions = Partial<ForSchemaOptions>
Expand Down
7 changes: 7 additions & 0 deletions src/AvroHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ export default class AvroHelper implements SchemaHelper {
return subject
}

public async referencedSchemas(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_schema: string,
): Promise<string[]> {
return []
}

private isRawAvroSchema(schema: ConfluentSchema | RawAvroSchema): schema is RawAvroSchema {
const asRawAvroSchema = schema as RawAvroSchema
return asRawAvroSchema.name != null && asRawAvroSchema.type != null
Expand Down
5 changes: 5 additions & 0 deletions src/JsonHelper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
// @ts-nocheck
import { Schema, SchemaHelper, ConfluentSubject, ConfluentSchema } from './@types'
import { ConfluentSchemaRegistryError } from './errors'
Expand All @@ -14,4 +15,8 @@ export default class JsonHelper implements SchemaHelper {
): ConfluentSubject {
throw new ConfluentSchemaRegistryError('not implemented yet')
}

public async referencedSchemas(schema: string): Promise<string[]> {
return []
}
}
34 changes: 28 additions & 6 deletions src/ProtoHelper.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
// @ts-nocheck
import { Schema, SchemaHelper, ConfluentSubject, ConfluentSchema } from './@types'
import { ConfluentSchemaRegistryError } from './errors'
import { ConfluentSchemaRegistryArgumentError, ConfluentSchemaRegistryError } from './errors'
import { IParserResult, parse } from 'protobufjs'

export default class ProtoHelper implements SchemaHelper {
public validate(schema: Schema): void {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public validate(_schema: Schema): void {
return
}

public getSubject(
confluentSchema: ConfluentSchema,
schema: Schema,
separator: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_confluentSchema: ConfluentSchema,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_schema: Schema,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_separator: string,
): ConfluentSubject {
throw new ConfluentSchemaRegistryError('not implemented yet')
}

/**
* Get the schemas referenced by the provided schema.
*
* @param schema The schema to find references for
*
* @returns A list of imported/referenced schemas that is used by the given schema.
*/
public async referencedSchemas(schema: string): Promise<string[]> {
let parsed: IParserResult
try {
parsed = parse(schema)
} catch (err) {
throw new ConfluentSchemaRegistryArgumentError(err)
}
const out: string[] = []
return out.concat(parsed.imports || []).concat(parsed.weakImports || [])
}
}
52 changes: 48 additions & 4 deletions src/ProtoSchema.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,62 @@
import { Schema, ProtoOptions, ProtoConfluentSchema } from './@types'
import protobuf from 'protobufjs'
import protobuf, { AnyNestedObject } from 'protobufjs'
import { IParserResult, ReflectionObject, Namespace, Type } from 'protobufjs/light'
import {
ConfluentSchemaRegistryArgumentError,
ConfluentSchemaRegistryValidationError,
} from './errors'

interface NestedSchema {
[k: string]: AnyNestedObject
}

export default class ProtoSchema implements Schema {
private message: Type
private root: protobuf.Root

constructor(schema: ProtoConfluentSchema, opts?: ProtoOptions) {
constructor(schema: ProtoConfluentSchema, opts?: ProtoOptions, references?: Schema[]) {
const parsedMessage = protobuf.parse(schema.schema)
const root = parsedMessage.root
this.message = root.lookupType(this.getTypeName(parsedMessage, opts))
this.root = parsedMessage.root

if (references) {
const schemas = references as ProtoSchema[]
schemas.forEach(reference => {
// root.add() takes ownership over its input argument.
// add() can modify and extend the input schema, so we have to clone the reference to avoid polluting it.
const root = reference.root.toJSON().nested
if (!root) {
return
}

// make sure we add the items one-by-one to avoid adding duplicate items (which are not tolerated)
this.spreadReference(root)
.filter(item => {
const referencePath = this.referencePath(item)
return !this.root.lookup(referencePath)
})
.forEach(item => this.root.addJSON(item))
})
}

this.message = this.root.lookupType(this.getTypeName(parsedMessage, opts))
}

private referencePath(namespace: NestedSchema): string[] {
const [key, entry] = Object.entries(namespace)[0]
if ('nested' in entry && entry.nested) {
return [key, ...this.referencePath(entry.nested)]
}
return [key]
}

private spreadReference(namespace: NestedSchema): NestedSchema[] {
return Object.entries(namespace).flatMap(([key, entry]): NestedSchema[] => {
if ('nested' in entry && entry.nested) {
const nested: NestedSchema[] = this.spreadReference(entry.nested)
return nested.map((it: NestedSchema) => ({ [key]: { nested: it } }))
}
return [{ [key]: entry }]
})
}

private getNestedTypeName(parent: { [k: string]: ReflectionObject } | undefined): string {
Expand Down
Loading