avro_turf 1.7.0 → 1.8.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3eea429db02f7f6eba5f13f46b2bf3e82602371ef9306e374c1102561f508675
4
- data.tar.gz: d798ef10b0e674f48ffdcc6bd3b87e59d9447c985d539f2ba01164e689fe4f8a
3
+ metadata.gz: 67ff8ee9b578227cd54a33d76a95fed8bd2c9a396aa360ad9df9f52d01e5c25a
4
+ data.tar.gz: 8bca24236ce42f19f6db457ad13d76d33e89b18703dc0eb74a8adca53b2c7b6e
5
5
  SHA512:
6
- metadata.gz: e7cacb60d4e7890a700ebaba9a0cf1d46606fb01157e0746a0d6a6c900895e9ca1268f0a04dd4d03f5d1a9cec9bf6795d9c5d70acb6884965353c72bb1de4095
7
- data.tar.gz: c4dbd604b66916355a6cba44ec4e7225eb439c2d9bb0682e62414b6ffa3018bb1d2a84b78d943983c99d7af3897a67658db9cb2205f7d92d6c13661ae44ba602
6
+ metadata.gz: 859e8fa6938679007704d35b1b4a54616da7637c83f41c58cbd10828216e0af198846e755334f465613ceb9086ec0c63a823dc2cbf3ddbdc191a97423d2e3147
7
+ data.tar.gz: 7900a85abaf9dd55ac3b89bba2d04935ddbafc850a92fb1941ff8984df864cfaa4bb5527ca4d48a74ef3715915d598044b7c486363909f2705ece83b0ffca50f
data/CHANGELOG.md CHANGED
@@ -2,9 +2,14 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## v1.8.0
6
+
7
+ - add support for `Date` via appropriate logicalType defintion. This is a backwards incompatible change (#177)
8
+ - Fixed schema file cache truncation on multiple running instances and parallel access to the cache files.
9
+
5
10
  ## v1.7.0
6
11
 
7
- - Added extra params for the validation message schem before encode (#169)
12
+ - Added extra params for the validation message schema before encode (#169)
8
13
  - Fix infinite retry when loading schema with nested primary type in separate file (#165)
9
14
 
10
15
  ## v1.6.0
@@ -60,7 +65,7 @@
60
65
  ## v0.9.0
61
66
 
62
67
  - Compatibility with Avro v1.9.0 (#94)
63
- - Disable the auto registeration of schema (#95)
68
+ - Disable the auto registration of schema (#95)
64
69
  - abstracted caching from CachedConfluentSchemaRegistry (#74)
65
70
  - Load avro-patches if installed to silence deprecation errors (#85)
66
71
  - Make schema store to be thread safe (#92)
@@ -13,7 +13,7 @@ class AvroTurf::CachedConfluentSchemaRegistry
13
13
  # cache - Optional user provided Cache object that responds to all methods in the AvroTurf::InMemoryCache interface.
14
14
  def initialize(upstream, cache: nil)
15
15
  @upstream = upstream
16
- @cache = cache || AvroTurf::InMemoryCache.new()
16
+ @cache = cache || AvroTurf::InMemoryCache.new
17
17
  end
18
18
 
19
19
  # Delegate the following methods to the upstream
@@ -34,7 +34,7 @@ class AvroTurf::CachedConfluentSchemaRegistry
34
34
 
35
35
  def subject_version(subject, version = 'latest')
36
36
  return @upstream.subject_version(subject, version) if version == 'latest'
37
-
37
+
38
38
  @cache.lookup_by_version(subject, version) ||
39
39
  @cache.store_by_version(subject, version, @upstream.subject_version(subject, version))
40
40
  end
@@ -1,5 +1,5 @@
1
1
  class Date
2
2
  def as_avro
3
- iso8601
3
+ self
4
4
  end
5
5
  end
@@ -1,20 +1,18 @@
1
1
  # A cache for the CachedConfluentSchemaRegistry.
2
2
  # Extends the InMemoryCache to provide a write-thru to disk for persistent cache.
3
- class AvroTurf::DiskCache < AvroTurf::InMemoryCache
3
+ class AvroTurf::DiskCache
4
4
 
5
5
  def initialize(disk_path, logger: Logger.new($stdout))
6
- super()
7
-
8
6
  @logger = logger
9
7
 
10
8
  # load the write-thru cache on startup, if it exists
11
9
  @schemas_by_id_path = File.join(disk_path, 'schemas_by_id.json')
12
10
  hash = read_from_disk_cache(@schemas_by_id_path)
13
- @schemas_by_id = hash if hash
11
+ @schemas_by_id = hash || {}
14
12
 
15
13
  @ids_by_schema_path = File.join(disk_path, 'ids_by_schema.json')
16
14
  hash = read_from_disk_cache(@ids_by_schema_path)
17
- @ids_by_schema = hash if hash
15
+ @ids_by_schema = hash || {}
18
16
 
19
17
  @schemas_by_subject_version_path = File.join(disk_path, 'schemas_by_subject_version.json')
20
18
  @schemas_by_subject_version = {}
@@ -24,15 +22,16 @@ class AvroTurf::DiskCache < AvroTurf::InMemoryCache
24
22
  # the write-thru cache (json) does not store keys in numeric format
25
23
  # so, convert id to a string for caching purposes
26
24
  def lookup_by_id(id)
27
- super(id.to_s)
25
+ @schemas_by_id[id.to_s]
28
26
  end
29
27
 
30
28
  # override to include write-thru cache after storing result from upstream
31
29
  def store_by_id(id, schema)
32
30
  # must return the value from storing the result (i.e. do not return result from file write)
33
- value = super(id.to_s, schema)
34
- File.write(@schemas_by_id_path, JSON.pretty_generate(@schemas_by_id))
35
- return value
31
+ @schemas_by_id[id.to_s] = schema
32
+ write_to_disk_cache(@schemas_by_id_path, @schemas_by_id)
33
+
34
+ schema
36
35
  end
37
36
 
38
37
  # override to use a json serializable cache key
@@ -45,7 +44,8 @@ class AvroTurf::DiskCache < AvroTurf::InMemoryCache
45
44
  def store_by_schema(subject, schema, id)
46
45
  key = "#{subject}#{schema}"
47
46
  @ids_by_schema[key] = id
48
- File.write(@ids_by_schema_path, JSON.pretty_generate(@ids_by_schema))
47
+
48
+ write_to_disk_cache(@ids_by_schema_path, @ids_by_schema)
49
49
  id
50
50
  end
51
51
 
@@ -78,7 +78,7 @@ class AvroTurf::DiskCache < AvroTurf::InMemoryCache
78
78
  hash[key] = schema
79
79
  hash
80
80
  else
81
- {key => schema}
81
+ { key => schema }
82
82
  end
83
83
 
84
84
  write_to_disk_cache(@schemas_by_subject_version_path, hash)
@@ -90,17 +90,27 @@ class AvroTurf::DiskCache < AvroTurf::InMemoryCache
90
90
  # Parse the file from disk, if it exists and is not zero length
91
91
  private def read_from_disk_cache(path)
92
92
  if File.exist?(path)
93
- if File.size(path)!=0
94
- return JSON.parse(File.read(path))
93
+ if File.size(path) != 0
94
+ json_data = File.open(path, 'r') do |file|
95
+ file.flock(File::LOCK_SH)
96
+ file.read
97
+ end
98
+
99
+ return JSON.parse(json_data)
95
100
  else
96
101
  # just log a message if skipping zero length file
97
102
  @logger.warn "skipping JSON.parse of zero length file at #{path}"
98
103
  end
99
104
  end
100
- return nil
105
+
106
+ nil
101
107
  end
102
108
 
103
109
  private def write_to_disk_cache(path, hash)
104
- File.write(path, JSON.pretty_generate(hash))
110
+ # don't use "w" because it truncates the file before lock
111
+ File.open(path, File::RDWR | File::CREAT, 0644) do |file|
112
+ file.flock(File::LOCK_EX)
113
+ file.write(JSON.pretty_generate(hash))
114
+ end
105
115
  end
106
116
  end
@@ -21,8 +21,20 @@ class AvroTurf
21
21
  # 1: https://github.com/confluentinc/schema-registry
22
22
  class Messaging
23
23
  MAGIC_BYTE = [0].pack("C").freeze
24
- DecodedMessage = Struct.new(:schema_id, :writer_schema, :reader_schema, :message)
25
- private_constant(:DecodedMessage)
24
+
25
+ class DecodedMessage
26
+ attr_reader :schema_id
27
+ attr_reader :writer_schema
28
+ attr_reader :reader_schema
29
+ attr_reader :message
30
+
31
+ def initialize(schema_id, writer_schema, reader_schema, message)
32
+ @schema_id = schema_id
33
+ @writer_schema = writer_schema
34
+ @reader_schema = reader_schema
35
+ @message = message
36
+ end
37
+ end
26
38
 
27
39
  # Instantiate a new Messaging instance with the given configuration.
28
40
  #
@@ -34,7 +46,7 @@ class AvroTurf
34
46
  # namespace - The String default schema namespace.
35
47
  # registry_path_prefix - The String URL path prefix used to namespace schema registry requests (optional).
36
48
  # logger - The Logger that should be used to log information (optional).
37
- # proxy - Forward the request via proxy (optional).
49
+ # proxy - Forward the request via proxy (optional).
38
50
  # user - User for basic auth (optional).
39
51
  # password - Password for basic auth (optional).
40
52
  # ssl_ca_file - Name of file containing CA certificate (optional).
@@ -130,7 +142,7 @@ class AvroTurf
130
142
  writer.write(message, encoder)
131
143
 
132
144
  stream.string
133
- rescue Excon::Errors::NotFound
145
+ rescue Excon::Error::NotFound
134
146
  if schema_id
135
147
  raise SchemaNotFoundError.new("Schema with id: #{schema_id} is not found on registry")
136
148
  else
@@ -1,3 +1,3 @@
1
1
  class AvroTurf
2
- VERSION = "1.7.0"
2
+ VERSION = "1.8.0"
3
3
  end
@@ -16,6 +16,13 @@ describe AvroTurf do
16
16
  {
17
17
  "type": "string",
18
18
  "name": "full_name"
19
+ },
20
+ {
21
+ "name": "birth_date",
22
+ "type": {
23
+ "type": "int",
24
+ "logicalType": "date"
25
+ }
19
26
  }
20
27
  ]
21
28
  }
@@ -24,7 +31,8 @@ describe AvroTurf do
24
31
 
25
32
  it "encodes data with Avro" do
26
33
  data = {
27
- "full_name" => "John Doe"
34
+ "full_name" => "John Doe",
35
+ "birth_date" => Date.new(1934, 1, 2)
28
36
  }
29
37
 
30
38
  encoded_data = avro.encode(data, schema_name: "person")
@@ -36,7 +44,8 @@ describe AvroTurf do
36
44
  compressed_avro = AvroTurf.new(schemas_path: "spec/schemas/", codec: "deflate")
37
45
 
38
46
  data = {
39
- "full_name" => "John Doe" * 100
47
+ "full_name" => "John Doe" * 100,
48
+ "birth_date" => Date.new(1934, 1, 2)
40
49
  }
41
50
 
42
51
  uncompressed_data = avro.encode(data, schema_name: "person")
@@ -329,5 +338,33 @@ describe AvroTurf do
329
338
  datum = { message: "hello" }
330
339
  expect(avro.valid?(datum, schema_name: "postcard")).to eq true
331
340
  end
341
+
342
+ it "handles logicalType of date in schema" do
343
+ define_schema "postcard.avsc", <<-AVSC
344
+ {
345
+ "name": "postcard",
346
+ "type": "record",
347
+ "fields": [
348
+ {
349
+ "name": "message",
350
+ "type": "string"
351
+ },
352
+ {
353
+ "name": "sent_date",
354
+ "type": {
355
+ "type": "int",
356
+ "logicalType": "date"
357
+ }
358
+ }
359
+ ]
360
+ }
361
+ AVSC
362
+
363
+ datum = {
364
+ message: "hello",
365
+ sent_date: Date.new(2022, 9, 11)
366
+ }
367
+ expect(avro.valid?(datum, schema_name: "postcard")).to eq true
368
+ end
332
369
  end
333
370
  end
@@ -1,6 +1,6 @@
1
1
  describe Date, "#as_avro" do
2
- it "returns an ISO8601 string describing the time" do
2
+ it "returns Date object describing the time" do
3
3
  date = Date.today
4
- expect(date.as_avro).to eq(date.iso8601)
4
+ expect(date.as_avro).to eq(date)
5
5
  end
6
6
  end
data/spec/spec_helper.rb CHANGED
@@ -22,6 +22,16 @@ module Helpers
22
22
  end
23
23
  end
24
24
 
25
+ # gem `fakefs` does not support flock for the file, and require patch
26
+ # https://github.com/fakefs/fakefs/issues/433
27
+ module FakeFS
28
+ class File < StringIO
29
+ def flock(*)
30
+ true
31
+ end
32
+ end
33
+ end
34
+
25
35
  RSpec.configure do |config|
26
36
  config.include FakeFS::SpecHelpers
27
37
  config.include Helpers
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: avro_turf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Schierbeck
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-25 00:00:00.000000000 Z
11
+ date: 2022-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: avro