confluent-schema-registry 3.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +2 -0
- package/.prettierrc.js +8 -0
- package/CHANGELOG.md +166 -0
- package/Dockerfile +10 -0
- package/LICENSE +21 -0
- package/README.md +44 -0
- package/bin/avdlToAVSC.sh +9 -0
- package/dist/@types.d.ts +93 -0
- package/dist/@types.js +10 -0
- package/dist/@types.js.map +1 -0
- package/dist/AvroHelper.d.ts +12 -0
- package/dist/AvroHelper.js +67 -0
- package/dist/AvroHelper.js.map +1 -0
- package/dist/JsonHelper.d.ts +7 -0
- package/dist/JsonHelper.js +20 -0
- package/dist/JsonHelper.js.map +1 -0
- package/dist/JsonSchema.d.ts +31 -0
- package/dist/JsonSchema.js +58 -0
- package/dist/JsonSchema.js.map +1 -0
- package/dist/ProtoHelper.d.ts +7 -0
- package/dist/ProtoHelper.js +23 -0
- package/dist/ProtoHelper.js.map +1 -0
- package/dist/ProtoSchema.d.ts +14 -0
- package/dist/ProtoSchema.js +66 -0
- package/dist/ProtoSchema.js.map +1 -0
- package/dist/SchemaRegistry.d.ts +48 -0
- package/dist/SchemaRegistry.js +250 -0
- package/dist/SchemaRegistry.js.map +1 -0
- package/dist/api/index.d.ts +43 -0
- package/dist/api/index.js +90 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/middleware/confluentEncoderMiddleware.d.ts +3 -0
- package/dist/api/middleware/confluentEncoderMiddleware.js +31 -0
- package/dist/api/middleware/confluentEncoderMiddleware.js.map +1 -0
- package/dist/api/middleware/errorMiddleware.d.ts +3 -0
- package/dist/api/middleware/errorMiddleware.js +20 -0
- package/dist/api/middleware/errorMiddleware.js.map +1 -0
- package/dist/api/middleware/userAgent.d.ts +3 -0
- package/dist/api/middleware/userAgent.js +18 -0
- package/dist/api/middleware/userAgent.js.map +1 -0
- package/dist/cache.d.ts +20 -0
- package/dist/cache.js +24 -0
- package/dist/cache.js.map +1 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.js +15 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.js +26 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/schemaTypeResolver.d.ts +4 -0
- package/dist/schemaTypeResolver.js +80 -0
- package/dist/schemaTypeResolver.js.map +1 -0
- package/dist/utils/avdlToAVSC.d.ts +2 -0
- package/dist/utils/avdlToAVSC.js +85 -0
- package/dist/utils/avdlToAVSC.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/readAVSC.d.ts +3 -0
- package/dist/utils/readAVSC.js +33 -0
- package/dist/utils/readAVSC.js.map +1 -0
- package/dist/wireDecoder.d.ts +7 -0
- package/dist/wireDecoder.js +8 -0
- package/dist/wireDecoder.js.map +1 -0
- package/dist/wireEncoder.d.ts +3 -0
- package/dist/wireEncoder.js +10 -0
- package/dist/wireEncoder.js.map +1 -0
- package/dockest-error.json +11 -0
- package/dockest.ts +30 -0
- package/jest.setup.ts +60 -0
- package/package.json +56 -0
- package/release/CHANGELOG.md +166 -0
- package/release/LICENSE +21 -0
- package/release/README.md +44 -0
- package/release/dist/@types.d.ts +93 -0
- package/release/dist/@types.js +10 -0
- package/release/dist/@types.js.map +1 -0
- package/release/dist/AvroHelper.d.ts +12 -0
- package/release/dist/AvroHelper.js +67 -0
- package/release/dist/AvroHelper.js.map +1 -0
- package/release/dist/JsonHelper.d.ts +7 -0
- package/release/dist/JsonHelper.js +20 -0
- package/release/dist/JsonHelper.js.map +1 -0
- package/release/dist/JsonSchema.d.ts +31 -0
- package/release/dist/JsonSchema.js +58 -0
- package/release/dist/JsonSchema.js.map +1 -0
- package/release/dist/ProtoHelper.d.ts +7 -0
- package/release/dist/ProtoHelper.js +23 -0
- package/release/dist/ProtoHelper.js.map +1 -0
- package/release/dist/ProtoSchema.d.ts +14 -0
- package/release/dist/ProtoSchema.js +66 -0
- package/release/dist/ProtoSchema.js.map +1 -0
- package/release/dist/SchemaRegistry.d.ts +48 -0
- package/release/dist/SchemaRegistry.js +250 -0
- package/release/dist/SchemaRegistry.js.map +1 -0
- package/release/dist/api/index.d.ts +43 -0
- package/release/dist/api/index.js +90 -0
- package/release/dist/api/index.js.map +1 -0
- package/release/dist/api/middleware/confluentEncoderMiddleware.d.ts +3 -0
- package/release/dist/api/middleware/confluentEncoderMiddleware.js +31 -0
- package/release/dist/api/middleware/confluentEncoderMiddleware.js.map +1 -0
- package/release/dist/api/middleware/errorMiddleware.d.ts +3 -0
- package/release/dist/api/middleware/errorMiddleware.js +20 -0
- package/release/dist/api/middleware/errorMiddleware.js.map +1 -0
- package/release/dist/api/middleware/userAgent.d.ts +3 -0
- package/release/dist/api/middleware/userAgent.js +18 -0
- package/release/dist/api/middleware/userAgent.js.map +1 -0
- package/release/dist/cache.d.ts +20 -0
- package/release/dist/cache.js +24 -0
- package/release/dist/cache.js.map +1 -0
- package/release/dist/constants.d.ts +11 -0
- package/release/dist/constants.js +15 -0
- package/release/dist/constants.js.map +1 -0
- package/release/dist/errors.d.ts +14 -0
- package/release/dist/errors.js +26 -0
- package/release/dist/errors.js.map +1 -0
- package/release/dist/index.d.ts +4 -0
- package/release/dist/index.js +13 -0
- package/release/dist/index.js.map +1 -0
- package/release/dist/schemaTypeResolver.d.ts +4 -0
- package/release/dist/schemaTypeResolver.js +80 -0
- package/release/dist/schemaTypeResolver.js.map +1 -0
- package/release/dist/utils/avdlToAVSC.d.ts +2 -0
- package/release/dist/utils/avdlToAVSC.js +85 -0
- package/release/dist/utils/avdlToAVSC.js.map +1 -0
- package/release/dist/utils/index.d.ts +2 -0
- package/release/dist/utils/index.js +9 -0
- package/release/dist/utils/index.js.map +1 -0
- package/release/dist/utils/readAVSC.d.ts +3 -0
- package/release/dist/utils/readAVSC.js +33 -0
- package/release/dist/utils/readAVSC.js.map +1 -0
- package/release/dist/wireDecoder.d.ts +7 -0
- package/release/dist/wireDecoder.js +8 -0
- package/release/dist/wireDecoder.js.map +1 -0
- package/release/dist/wireEncoder.d.ts +3 -0
- package/release/dist/wireEncoder.js +10 -0
- package/release/dist/wireEncoder.js.map +1 -0
- package/release/package.json +56 -0
- package/src/@types.ts +105 -0
- package/src/AvroHelper.ts +91 -0
- package/src/JsonHelper.ts +35 -0
- package/src/JsonSchema.ts +80 -0
- package/src/ProtoHelper.ts +38 -0
- package/src/ProtoSchema.ts +80 -0
- package/src/SchemaRegistry.avro.spec.ts +558 -0
- package/src/SchemaRegistry.json.spec.ts +364 -0
- package/src/SchemaRegistry.newApi.spec.ts +622 -0
- package/src/SchemaRegistry.protobuf.spec.ts +372 -0
- package/src/SchemaRegistry.spec.ts +252 -0
- package/src/SchemaRegistry.ts +387 -0
- package/src/api/index.spec.ts +23 -0
- package/src/api/index.ts +121 -0
- package/src/api/middleware/confluentEncoderMiddleware.ts +36 -0
- package/src/api/middleware/errorMiddleware.spec.ts +67 -0
- package/src/api/middleware/errorMiddleware.ts +37 -0
- package/src/api/middleware/userAgent.spec.ts +53 -0
- package/src/api/middleware/userAgent.ts +19 -0
- package/src/cache.ts +34 -0
- package/src/constants.ts +13 -0
- package/src/errors.ts +26 -0
- package/src/index.ts +4 -0
- package/src/schemaTypeResolver.ts +101 -0
- package/src/utils/avdlToAVSC.spec.ts +79 -0
- package/src/utils/avdlToAVSC.ts +106 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/readAVSC.spec.ts +23 -0
- package/src/utils/readAVSC.ts +36 -0
- package/src/wireDecoder.ts +5 -0
- package/src/wireEncoder.ts +10 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
import SchemaRegistry, { RegisteredSchema } from './SchemaRegistry'
|
|
2
|
+
import API from './api'
|
|
3
|
+
import { AvroConfluentSchema, SchemaType } from './@types'
|
|
4
|
+
import avro from 'avsc'
|
|
5
|
+
|
|
6
|
+
const REGISTRY_HOST = 'http://localhost:8982'
|
|
7
|
+
const schemaRegistryAPIClientArgs = { host: REGISTRY_HOST }
|
|
8
|
+
const schemaRegistryArgs = { host: REGISTRY_HOST }
|
|
9
|
+
|
|
10
|
+
enum Color {
|
|
11
|
+
RED = 1,
|
|
12
|
+
GREEN = 2,
|
|
13
|
+
BLUE = 3,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
enum Direction {
|
|
17
|
+
UP = 1,
|
|
18
|
+
DOWN = 2,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const TestSchemas = {
|
|
22
|
+
FirstLevelSchema: {
|
|
23
|
+
type: SchemaType.AVRO,
|
|
24
|
+
schema: `
|
|
25
|
+
{
|
|
26
|
+
"type" : "record",
|
|
27
|
+
"namespace" : "test",
|
|
28
|
+
"name" : "FirstLevel",
|
|
29
|
+
"fields" : [
|
|
30
|
+
{ "name" : "id1" , "type" : "int" },
|
|
31
|
+
{ "name" : "level1a" , "type" : "test.SecondLevelA" },
|
|
32
|
+
{ "name" : "level1b" , "type" : "test.SecondLevelB" }
|
|
33
|
+
]
|
|
34
|
+
}`,
|
|
35
|
+
references: [
|
|
36
|
+
{
|
|
37
|
+
name: 'test.SecondLevelA',
|
|
38
|
+
subject: 'Avro:SecondLevelA',
|
|
39
|
+
version: undefined,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'test.SecondLevelB',
|
|
43
|
+
subject: 'Avro:SecondLevelB',
|
|
44
|
+
version: undefined,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
} as AvroConfluentSchema,
|
|
48
|
+
|
|
49
|
+
SecondLevelASchema: {
|
|
50
|
+
type: SchemaType.AVRO,
|
|
51
|
+
schema: `
|
|
52
|
+
{
|
|
53
|
+
"type" : "record",
|
|
54
|
+
"namespace" : "test",
|
|
55
|
+
"name" : "SecondLevelA",
|
|
56
|
+
"fields" : [
|
|
57
|
+
{ "name" : "id2a" , "type" : "int" },
|
|
58
|
+
{ "name" : "level2a" , "type" : "test.ThirdLevel" }
|
|
59
|
+
]
|
|
60
|
+
}`,
|
|
61
|
+
references: [
|
|
62
|
+
{
|
|
63
|
+
name: 'test.ThirdLevel',
|
|
64
|
+
subject: 'Avro:ThirdLevel',
|
|
65
|
+
version: undefined,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
} as AvroConfluentSchema,
|
|
69
|
+
|
|
70
|
+
SecondLevelBSchema: {
|
|
71
|
+
type: SchemaType.AVRO,
|
|
72
|
+
schema: `
|
|
73
|
+
{
|
|
74
|
+
"type" : "record",
|
|
75
|
+
"namespace" : "test",
|
|
76
|
+
"name" : "SecondLevelB",
|
|
77
|
+
"fields" : [
|
|
78
|
+
{ "name" : "id2b" , "type" : "int" },
|
|
79
|
+
{ "name" : "level2b" , "type" : "test.ThirdLevel" }
|
|
80
|
+
]
|
|
81
|
+
}`,
|
|
82
|
+
references: [
|
|
83
|
+
{
|
|
84
|
+
name: 'test.ThirdLevel',
|
|
85
|
+
subject: 'Avro:ThirdLevel',
|
|
86
|
+
version: undefined,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
} as AvroConfluentSchema,
|
|
90
|
+
|
|
91
|
+
ThirdLevelSchema: {
|
|
92
|
+
type: SchemaType.AVRO,
|
|
93
|
+
schema: `
|
|
94
|
+
{
|
|
95
|
+
"type" : "record",
|
|
96
|
+
"namespace" : "test",
|
|
97
|
+
"name" : "ThirdLevel",
|
|
98
|
+
"fields" : [
|
|
99
|
+
{ "name" : "id3" , "type" : "int" }
|
|
100
|
+
]
|
|
101
|
+
}`,
|
|
102
|
+
} as AvroConfluentSchema,
|
|
103
|
+
|
|
104
|
+
EnumSchema: {
|
|
105
|
+
type: SchemaType.AVRO,
|
|
106
|
+
schema: `
|
|
107
|
+
{
|
|
108
|
+
"type" : "record",
|
|
109
|
+
"namespace" : "test",
|
|
110
|
+
"name" : "EnumSchema",
|
|
111
|
+
"fields" : [
|
|
112
|
+
{
|
|
113
|
+
"name": "color",
|
|
114
|
+
"type": ["null", {
|
|
115
|
+
"type": "enum",
|
|
116
|
+
"name": "Color",
|
|
117
|
+
"symbols": ["RED", "GREEN", "BLUE"]
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}`,
|
|
123
|
+
} as AvroConfluentSchema,
|
|
124
|
+
|
|
125
|
+
EnumWithReferencesSchema: {
|
|
126
|
+
type: SchemaType.AVRO,
|
|
127
|
+
schema: `
|
|
128
|
+
{
|
|
129
|
+
"type" : "record",
|
|
130
|
+
"namespace" : "test",
|
|
131
|
+
"name" : "EnumWithReferences",
|
|
132
|
+
"fields" : [
|
|
133
|
+
{
|
|
134
|
+
"name": "direction",
|
|
135
|
+
"type": ["null", {
|
|
136
|
+
"type": "enum",
|
|
137
|
+
"name": "Direction",
|
|
138
|
+
"symbols": ["UP", "DOWN"]
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
{ "name" : "attributes" , "type" : "test.EnumSchema" }
|
|
143
|
+
]
|
|
144
|
+
}`,
|
|
145
|
+
references: [
|
|
146
|
+
{
|
|
147
|
+
name: 'test.EnumSchema',
|
|
148
|
+
subject: 'Avro:EnumSchema',
|
|
149
|
+
version: undefined,
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
} as AvroConfluentSchema,
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function apiResponse(result) {
|
|
156
|
+
return JSON.parse(result.responseData)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
describe('SchemaRegistry', () => {
|
|
160
|
+
let schemaRegistry: SchemaRegistry
|
|
161
|
+
let registeredSchema: RegisteredSchema
|
|
162
|
+
let api
|
|
163
|
+
|
|
164
|
+
beforeEach(async () => {
|
|
165
|
+
api = API(schemaRegistryAPIClientArgs)
|
|
166
|
+
schemaRegistry = new SchemaRegistry(schemaRegistryArgs)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
describe('when register', () => {
|
|
170
|
+
describe('when no reference', () => {
|
|
171
|
+
beforeEach(async () => {
|
|
172
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
|
|
173
|
+
subject: 'Avro:ThirdLevel',
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it('should return schema id', async () => {
|
|
178
|
+
expect(registeredSchema.id).toEqual(expect.any(Number))
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
it('should be able to encode/decode', async () => {
|
|
182
|
+
const obj = { id3: 3 }
|
|
183
|
+
|
|
184
|
+
const buffer = await schemaRegistry.encode(registeredSchema.id, obj)
|
|
185
|
+
const resultObj = await schemaRegistry.decode(buffer)
|
|
186
|
+
|
|
187
|
+
expect(resultObj).toEqual(obj)
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
describe('with reference', () => {
|
|
192
|
+
let schemaId
|
|
193
|
+
let referenceSchema
|
|
194
|
+
|
|
195
|
+
beforeEach(async () => {
|
|
196
|
+
await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
|
|
197
|
+
subject: 'Avro:ThirdLevel',
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
|
|
201
|
+
TestSchemas.SecondLevelASchema.references[0].version = latest.version
|
|
202
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelASchema, {
|
|
203
|
+
subject: 'Avro:SecondLevelA',
|
|
204
|
+
})
|
|
205
|
+
schemaId = registeredSchema.id
|
|
206
|
+
|
|
207
|
+
const schemaRaw = apiResponse(await api.Schema.find({ id: schemaId }))
|
|
208
|
+
referenceSchema = schemaRaw.references[0].subject
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it('should return schema id', async () => {
|
|
212
|
+
expect(schemaId).toEqual(expect.any(Number))
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
it('should create a schema with reference', async () => {
|
|
216
|
+
expect(referenceSchema).toEqual('Avro:ThirdLevel')
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
it('should be able to encode/decode', async () => {
|
|
220
|
+
const obj = { id2a: 2, level2a: { id3: 3 } }
|
|
221
|
+
|
|
222
|
+
const buffer = await schemaRegistry.encode(registeredSchema.id, obj)
|
|
223
|
+
const resultObj = await schemaRegistry.decode(buffer)
|
|
224
|
+
|
|
225
|
+
expect(resultObj).toEqual(obj)
|
|
226
|
+
})
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
describe('with multiple reference', () => {
|
|
230
|
+
beforeEach(async () => {
|
|
231
|
+
let latest
|
|
232
|
+
|
|
233
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
|
|
234
|
+
subject: 'Avro:ThirdLevel',
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
|
|
238
|
+
TestSchemas.SecondLevelASchema.references[0].version = latest.version
|
|
239
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelASchema, {
|
|
240
|
+
subject: 'Avro:SecondLevelA',
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
|
|
244
|
+
TestSchemas.SecondLevelBSchema.references[0].version = latest.version
|
|
245
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelBSchema, {
|
|
246
|
+
subject: 'Avro:SecondLevelB',
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:SecondLevelA' }))
|
|
250
|
+
TestSchemas.FirstLevelSchema.references[0].version = latest.version
|
|
251
|
+
latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:SecondLevelB' }))
|
|
252
|
+
TestSchemas.FirstLevelSchema.references[1].version = latest.version
|
|
253
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.FirstLevelSchema, {
|
|
254
|
+
subject: 'Avro:FirstLevel',
|
|
255
|
+
})
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('should be able to encode/decode', async () => {
|
|
259
|
+
const obj = {
|
|
260
|
+
id1: 1,
|
|
261
|
+
level1a: { id2a: 2, level2a: { id3: 3 } },
|
|
262
|
+
level1b: { id2b: 4, level2b: { id3: 5 } },
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const buffer = await schemaRegistry.encode(registeredSchema.id, obj)
|
|
266
|
+
const resultObj = await schemaRegistry.decode(buffer)
|
|
267
|
+
|
|
268
|
+
expect(resultObj).toEqual(obj)
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
it('should be able to encode/decode independent', async () => {
|
|
272
|
+
const obj = {
|
|
273
|
+
id1: 1,
|
|
274
|
+
level1a: { id2a: 2, level2a: { id3: 3 } },
|
|
275
|
+
level1b: { id2b: 4, level2b: { id3: 5 } },
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
schemaRegistry = new SchemaRegistry(schemaRegistryArgs)
|
|
279
|
+
const buffer = await schemaRegistry.encode(registeredSchema.id, obj)
|
|
280
|
+
|
|
281
|
+
schemaRegistry = new SchemaRegistry(schemaRegistryArgs)
|
|
282
|
+
const resultObj = await schemaRegistry.decode(buffer)
|
|
283
|
+
|
|
284
|
+
expect(resultObj).toEqual(obj)
|
|
285
|
+
})
|
|
286
|
+
})
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
describe('_getSchema', () => {
|
|
290
|
+
let schema
|
|
291
|
+
|
|
292
|
+
describe('no references', () => {
|
|
293
|
+
beforeEach(async () => {
|
|
294
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
|
|
295
|
+
subject: 'Avro:ThirdLevel',
|
|
296
|
+
})
|
|
297
|
+
;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
it('should return schema that match name', async () => {
|
|
301
|
+
expect(schema.name).toEqual('test.ThirdLevel')
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
it('should be able to encode/decode', async () => {
|
|
305
|
+
const obj = { id3: 3 }
|
|
306
|
+
|
|
307
|
+
const buffer = await schema.toBuffer(obj)
|
|
308
|
+
const resultObj = await schema.fromBuffer(buffer)
|
|
309
|
+
|
|
310
|
+
expect(resultObj).toEqual(obj)
|
|
311
|
+
})
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
describe('with references', () => {
|
|
315
|
+
beforeEach(async () => {
|
|
316
|
+
await schemaRegistry.register(TestSchemas.ThirdLevelSchema, { subject: 'Avro:ThirdLevel' })
|
|
317
|
+
|
|
318
|
+
const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
|
|
319
|
+
TestSchemas.SecondLevelASchema.references[0].version = latest.version
|
|
320
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelASchema, {
|
|
321
|
+
subject: 'Avro:SecondLevelA',
|
|
322
|
+
})
|
|
323
|
+
;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
it('should return schema that match name', async () => {
|
|
327
|
+
expect(schema.name).toEqual('test.SecondLevelA')
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
it('should be able to encode/decode', async () => {
|
|
331
|
+
const obj = { id2a: 2, level2a: { id3: 3 } }
|
|
332
|
+
|
|
333
|
+
const buffer = await schema.toBuffer(obj)
|
|
334
|
+
const resultObj = await schema.fromBuffer(buffer)
|
|
335
|
+
|
|
336
|
+
expect(resultObj).toEqual(obj)
|
|
337
|
+
})
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
describe('with multi references', () => {
|
|
341
|
+
beforeEach(async () => {
|
|
342
|
+
let latest
|
|
343
|
+
|
|
344
|
+
await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
|
|
345
|
+
subject: 'Avro:ThirdLevel',
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
|
|
349
|
+
TestSchemas.SecondLevelASchema.references[0].version = latest.version
|
|
350
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelASchema, {
|
|
351
|
+
subject: 'Avro:SecondLevelA',
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
|
|
355
|
+
TestSchemas.SecondLevelBSchema.references[0].version = latest.version
|
|
356
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelBSchema, {
|
|
357
|
+
subject: 'Avro:SecondLevelB',
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:SecondLevelA' }))
|
|
361
|
+
TestSchemas.FirstLevelSchema.references[0].version = latest.version
|
|
362
|
+
latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:SecondLevelB' }))
|
|
363
|
+
TestSchemas.FirstLevelSchema.references[1].version = latest.version
|
|
364
|
+
registeredSchema = await schemaRegistry.register(TestSchemas.FirstLevelSchema, {
|
|
365
|
+
subject: 'Avro:FirstLevel',
|
|
366
|
+
})
|
|
367
|
+
;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
it('should return schema that match name', async () => {
|
|
371
|
+
expect(schema.name).toEqual('test.FirstLevel')
|
|
372
|
+
})
|
|
373
|
+
|
|
374
|
+
it('should be able to encode/decode', async () => {
|
|
375
|
+
const obj = {
|
|
376
|
+
id1: 1,
|
|
377
|
+
level1a: { id2a: 2, level2a: { id3: 3 } },
|
|
378
|
+
level1b: { id2b: 4, level2b: { id3: 5 } },
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const buffer = await schema.toBuffer(obj)
|
|
382
|
+
const resultObj = await schema.fromBuffer(buffer)
|
|
383
|
+
|
|
384
|
+
expect(resultObj).toEqual(obj)
|
|
385
|
+
})
|
|
386
|
+
})
|
|
387
|
+
})
|
|
388
|
+
|
|
389
|
+
describe('when document example', () => {
|
|
390
|
+
it('should encode/decode', async () => {
|
|
391
|
+
const schemaA = {
|
|
392
|
+
type: 'record',
|
|
393
|
+
namespace: 'test',
|
|
394
|
+
name: 'A',
|
|
395
|
+
fields: [
|
|
396
|
+
{ name: 'id', type: 'int' },
|
|
397
|
+
{ name: 'b', type: 'test.B' },
|
|
398
|
+
],
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const schemaB = {
|
|
402
|
+
type: 'record',
|
|
403
|
+
namespace: 'test',
|
|
404
|
+
name: 'B',
|
|
405
|
+
fields: [{ name: 'id', type: 'int' }],
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
await schemaRegistry.register(
|
|
409
|
+
{ type: SchemaType.AVRO, schema: JSON.stringify(schemaB) },
|
|
410
|
+
{ subject: 'Avro:B' },
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
const response = await schemaRegistry.api.Subject.latestVersion({ subject: 'Avro:B' })
|
|
414
|
+
const { version } = JSON.parse(response.responseData)
|
|
415
|
+
|
|
416
|
+
const { id } = await schemaRegistry.register(
|
|
417
|
+
{
|
|
418
|
+
type: SchemaType.AVRO,
|
|
419
|
+
schema: JSON.stringify(schemaA),
|
|
420
|
+
references: [
|
|
421
|
+
{
|
|
422
|
+
name: 'test.B',
|
|
423
|
+
subject: 'Avro:B',
|
|
424
|
+
version,
|
|
425
|
+
},
|
|
426
|
+
],
|
|
427
|
+
},
|
|
428
|
+
{ subject: 'Avro:A' },
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
const obj = { id: 1, b: { id: 2 } }
|
|
432
|
+
|
|
433
|
+
const buffer = await schemaRegistry.encode(id, obj)
|
|
434
|
+
const decodedObj = await schemaRegistry.decode(buffer)
|
|
435
|
+
|
|
436
|
+
expect(decodedObj).toEqual(obj)
|
|
437
|
+
})
|
|
438
|
+
})
|
|
439
|
+
|
|
440
|
+
describe('with EnumType types and nested schemas', () => {
|
|
441
|
+
/**
|
|
442
|
+
* Hook which will decode/encode enums to/from integers.
|
|
443
|
+
*
|
|
444
|
+
* The default `EnumType` implementation represents enum values as strings
|
|
445
|
+
* (consistent with the JSON representation). This hook can be used to provide
|
|
446
|
+
* an alternate representation (which is for example compatible with TypeScript
|
|
447
|
+
* enums).
|
|
448
|
+
*
|
|
449
|
+
* For simplicity, we don't do any bound checking here but we could by
|
|
450
|
+
* implementing a "bounded long" logical type and returning that instead.
|
|
451
|
+
*
|
|
452
|
+
* https://gist.github.com/mtth/c0088c745de048c4e466#file-long-enum-js
|
|
453
|
+
*/
|
|
454
|
+
function typeHook(attrs, opts) {
|
|
455
|
+
if (attrs.type === 'enum') {
|
|
456
|
+
return avro.parse('long', opts)
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
let schema
|
|
461
|
+
|
|
462
|
+
describe('with no enum typeHook defined', () => {
|
|
463
|
+
beforeEach(async () => {
|
|
464
|
+
const schemaRegistry = new SchemaRegistry(schemaRegistryArgs)
|
|
465
|
+
|
|
466
|
+
await schemaRegistry.register(TestSchemas.EnumSchema, {
|
|
467
|
+
subject: 'Avro:EnumSchema',
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:EnumSchema' }))
|
|
471
|
+
TestSchemas.EnumWithReferencesSchema.references[0].version = latest.version
|
|
472
|
+
const registeredSchema = await schemaRegistry.register(
|
|
473
|
+
TestSchemas.EnumWithReferencesSchema,
|
|
474
|
+
{
|
|
475
|
+
subject: 'Avro:EnumWithReferences',
|
|
476
|
+
},
|
|
477
|
+
)
|
|
478
|
+
;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
it('should not be able to encode/decode enums schemas', async () => {
|
|
482
|
+
const obj = {
|
|
483
|
+
direction: Direction.UP,
|
|
484
|
+
attributes: { color: Color.BLUE },
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
expect(() => schema.toBuffer(obj)).toThrow(Error)
|
|
488
|
+
})
|
|
489
|
+
})
|
|
490
|
+
|
|
491
|
+
describe('with enum typeHook defined', () => {
|
|
492
|
+
beforeEach(async () => {
|
|
493
|
+
const schemaRegistry = new SchemaRegistry(schemaRegistryArgs, {
|
|
494
|
+
[SchemaType.AVRO]: { typeHook },
|
|
495
|
+
})
|
|
496
|
+
|
|
497
|
+
await schemaRegistry.register(TestSchemas.EnumSchema, {
|
|
498
|
+
subject: 'Avro:EnumSchema',
|
|
499
|
+
})
|
|
500
|
+
|
|
501
|
+
const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:EnumSchema' }))
|
|
502
|
+
TestSchemas.EnumWithReferencesSchema.references[0].version = latest.version
|
|
503
|
+
const registeredSchema = await schemaRegistry.register(
|
|
504
|
+
TestSchemas.EnumWithReferencesSchema,
|
|
505
|
+
{
|
|
506
|
+
subject: 'Avro:EnumWithReferences',
|
|
507
|
+
},
|
|
508
|
+
)
|
|
509
|
+
;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
it('should be able to encode/decode enums schemas', async () => {
|
|
513
|
+
const obj = {
|
|
514
|
+
direction: Direction.UP,
|
|
515
|
+
attributes: { color: Color.BLUE },
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const buffer = await schema.toBuffer(obj)
|
|
519
|
+
const resultObj = await schema.fromBuffer(buffer)
|
|
520
|
+
|
|
521
|
+
expect(resultObj).toEqual(obj)
|
|
522
|
+
})
|
|
523
|
+
})
|
|
524
|
+
describe('with enum typeHook defined as LegacyOptions', () => {
|
|
525
|
+
beforeEach(async () => {
|
|
526
|
+
const schemaRegistry = new SchemaRegistry(schemaRegistryArgs, {
|
|
527
|
+
forSchemaOptions: { typeHook },
|
|
528
|
+
})
|
|
529
|
+
|
|
530
|
+
await schemaRegistry.register(TestSchemas.EnumSchema, {
|
|
531
|
+
subject: 'Avro:EnumSchema',
|
|
532
|
+
})
|
|
533
|
+
|
|
534
|
+
const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:EnumSchema' }))
|
|
535
|
+
TestSchemas.EnumWithReferencesSchema.references[0].version = latest.version
|
|
536
|
+
const registeredSchema = await schemaRegistry.register(
|
|
537
|
+
TestSchemas.EnumWithReferencesSchema,
|
|
538
|
+
{
|
|
539
|
+
subject: 'Avro:EnumWithReferences',
|
|
540
|
+
},
|
|
541
|
+
)
|
|
542
|
+
;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
|
|
543
|
+
})
|
|
544
|
+
|
|
545
|
+
it('should be able to encode/decode enums schemas', async () => {
|
|
546
|
+
const obj = {
|
|
547
|
+
direction: Direction.UP,
|
|
548
|
+
attributes: { color: Color.BLUE },
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
const buffer = await schema.toBuffer(obj)
|
|
552
|
+
const resultObj = await schema.fromBuffer(buffer)
|
|
553
|
+
|
|
554
|
+
expect(resultObj).toEqual(obj)
|
|
555
|
+
})
|
|
556
|
+
})
|
|
557
|
+
})
|
|
558
|
+
})
|