avro-resolution_canonical_form 0.1.0.rc0
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 +7 -0
- data/.gitignore +9 -0
- data/.overcommit.yml +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +107 -0
- data/Rakefile +8 -0
- data/avro-resolution_canonical_form.gemspec +38 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/avro-resolution_canonical_form.rb +3 -0
- data/lib/avro/resolution_canonical_form.rb +31 -0
- data/lib/avro/resolution_canonical_form/version.rb +7 -0
- data/lib/avro/resolution_fingerprint.rb +10 -0
- metadata +162 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8b215d8dafd28cb843b8a64936d6293631ca83ea
|
4
|
+
data.tar.gz: 260398add04f7503f3fdb68b04b7b009db08bb92
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db330d565c3e1251ff07e976b9cd8f6199fb0ac9e54548513004edd83194d584dfeda71950583100106d27bf957f36f5712f67532676bb064ad92e9485ae19d7
|
7
|
+
data.tar.gz: aca2c3fcb923337b095adedf83ad181dae64463ea625d2e8cc18e7c01b1f62e392e70d92ce057b500d13f1cbc4a911261d76244dbdcfb94dbdc472209b4605da
|
data/.gitignore
ADDED
data/.overcommit.yml
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Salsify, Inc
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# avro-resolution_canonical_form
|
2
|
+
|
3
|
+
This gem defines a [Resolution Canonical Form](#resolution_canonical_form) for Avro schemas.
|
4
|
+
This is similar to the [Parsing Canonical Form](http://avro.apache.org/docs/1.8.1/spec.html#Parsing+Canonical+Form+for+Schemas)
|
5
|
+
from the Apache Avro spec, but extends is to also include attributes that are
|
6
|
+
relevant to schema resolution and compatibility.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'avro-resolution_canonical_form'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install avro-resolution_canonical_form
|
23
|
+
|
24
|
+
## Resolution Canonical Form
|
25
|
+
|
26
|
+
The Resolution Canonical Form extends the [Parsing Canonical Form](http://avro.apache.org/docs/1.8.1/spec.html#Parsing+Canonical+Form+for+Schemas)
|
27
|
+
to include `default` and `aliases` attributes:
|
28
|
+
|
29
|
+
* [ORDER] Order the appearance of fields in JSON objects as follows:
|
30
|
+
`name, type, fields, symbols, items, values, size, default, aliases`
|
31
|
+
* [ALIASES] [Aliases](http://avro.apache.org/docs/1.8.1/spec.html#Aliases) for
|
32
|
+
named types and fields are converted to their fullname, using applicable
|
33
|
+
namespace, and sorted.
|
34
|
+
|
35
|
+
## Ruby Support
|
36
|
+
|
37
|
+
This currently gem requires the [avro-salsify-fork](https://github.com/salsify/avro)
|
38
|
+
gem due to a bug in the Avro Ruby gem support for defaults. The fix for this issue
|
39
|
+
will be included in Avro v1.8.2.
|
40
|
+
|
41
|
+
### Aliases
|
42
|
+
|
43
|
+
The Avro Ruby gem, including the avro-salsify-fork, does not yet include support
|
44
|
+
for aliases. Aliases are included in the specification of the Resolution Canonical
|
45
|
+
Form above, but not yet supported by this gem.
|
46
|
+
|
47
|
+
## Usage
|
48
|
+
|
49
|
+
`Avro::ResolutionCanonicalForm` subclasses `Avro::SchemaNormalization`
|
50
|
+
and provides a `to_resolution_form` method that returns the resolution canonical
|
51
|
+
form for the schema:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
require 'avro-resolution_canonical_form'
|
55
|
+
|
56
|
+
schema = Avro::Schema.parse(<<-JSON)
|
57
|
+
{
|
58
|
+
"type": "record",
|
59
|
+
"name": "dimensions",
|
60
|
+
"aliases": ["dims", "eg.sizing"],
|
61
|
+
"namespace": "example",
|
62
|
+
"doc": "an example",
|
63
|
+
"fields": [
|
64
|
+
{ "name": "height", "type": "int", "default": 1, "doc": "the height" },
|
65
|
+
{ "name": "width", "aliases": ["across"], "type": "int", "doc": "the width" }
|
66
|
+
]
|
67
|
+
}
|
68
|
+
JSON
|
69
|
+
|
70
|
+
Avro::ResolutionCanonicalForm.to_resolution_form(schema)
|
71
|
+
#=> {"name":"example.dimensions","type":"record","fields":[{"name":"height","type":"int","default":1},{"name":"width","type":"int"}]}
|
72
|
+
```
|
73
|
+
|
74
|
+
A new method, `#sha256_resolution_fingerprint`, is added to `Avro::Schema` to
|
75
|
+
return the SHA256 digest based on the resolution form above. This is similar to
|
76
|
+
the existing `#sha256_fingerprint` which is based on the Parsing Canonical Form.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
schema.sha256_resolution_fingerprint
|
80
|
+
|
81
|
+
#=> 80361294467930602613800428579400567035362599364974249578710466785512094641526
|
82
|
+
```
|
83
|
+
|
84
|
+
## Development
|
85
|
+
|
86
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then,
|
87
|
+
run `rake spec` to run the tests. You can also run `bin/console` for an
|
88
|
+
interactive prompt that will allow you to experiment.
|
89
|
+
|
90
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
91
|
+
|
92
|
+
To release a new version, update the version number in `version.rb`, and then
|
93
|
+
run `bundle exec rake release`, which will create a git tag for the version,
|
94
|
+
push git commits and tags, and push the `.gem` file to
|
95
|
+
[rubygems.org](https://rubygems.org)
|
96
|
+
.
|
97
|
+
|
98
|
+
## Contributing
|
99
|
+
|
100
|
+
Bug reports and pull requests are welcome on GitHub at
|
101
|
+
https://github.com/salsify/avro-resolution_canonical_form.
|
102
|
+
|
103
|
+
## License
|
104
|
+
|
105
|
+
The gem is available as open source under the terms of the
|
106
|
+
[MIT License](http://opensource.org/licenses/MIT).
|
107
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'avro/resolution_canonical_form/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'avro-resolution_canonical_form'
|
8
|
+
spec.version = Avro::ResolutionCanonicalForm::VERSION
|
9
|
+
spec.authors = ['Salsify, Inc']
|
10
|
+
spec.email = ['engineering@salsify.com']
|
11
|
+
|
12
|
+
spec.summary = 'Unique identification of Avro schemas for schema resolution'
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = 'https://github.com/salsify/avro-resolution_canonical_form'
|
15
|
+
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
# Set 'allowed_push_post' to control where this gem can be published.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
|
+
|
22
|
+
else
|
23
|
+
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
|
24
|
+
end
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
|
+
spec.bindir = 'bin'
|
28
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ['lib']
|
30
|
+
|
31
|
+
spec.add_development_dependency 'bundler', '~> 1.12'
|
32
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
33
|
+
spec.add_development_dependency 'rspec', '~> 3.4'
|
34
|
+
spec.add_development_dependency 'salsify_rubocop', '~> 0.46.0'
|
35
|
+
spec.add_development_dependency 'overcommit'
|
36
|
+
spec.add_development_dependency 'simplecov'
|
37
|
+
spec.add_runtime_dependency 'avro-salsify-fork', '>= 1.9.0.5'
|
38
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'avro-resolution_canonical_form'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'avro'
|
2
|
+
|
3
|
+
module Avro
|
4
|
+
class ResolutionCanonicalForm < SchemaNormalization
|
5
|
+
def self.to_resolution_form(schema)
|
6
|
+
new.to_resolution_form(schema)
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_resolution_form(schema)
|
10
|
+
MultiJson.dump(normalize_schema(schema))
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# TODO: include aliases once the avro Ruby gem supports them
|
16
|
+
# Note: permitted values for defaults are not enforced here.
|
17
|
+
# That should be done at the schema level, and is not done currently
|
18
|
+
# in the Avro Ruby gem
|
19
|
+
def normalize_field(field)
|
20
|
+
default_value = if field.default?
|
21
|
+
{ default: field.default }
|
22
|
+
else
|
23
|
+
{}
|
24
|
+
end
|
25
|
+
super.merge(default_value)
|
26
|
+
end
|
27
|
+
|
28
|
+
# TODO: Override normalize_named_type once the Avro Ruby gem supports aliases
|
29
|
+
# def normalized_named_type(schema, attributes = {})
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Avro
|
2
|
+
class Schema
|
3
|
+
# Returns the SHA-256 fingerprint of the Resolution Canonical Form for the
|
4
|
+
# schema as an Integer
|
5
|
+
def sha256_resolution_fingerprint
|
6
|
+
resolution_form = ResolutionCanonicalForm.to_resolution_form(self)
|
7
|
+
Digest::SHA256.hexdigest(resolution_form).to_i(16)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: avro-resolution_canonical_form
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.rc0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Salsify, Inc
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.12'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.12'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: salsify_rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.46.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.46.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: overcommit
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: avro-salsify-fork
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.9.0.5
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.9.0.5
|
111
|
+
description: Unique identification of Avro schemas for schema resolution
|
112
|
+
email:
|
113
|
+
- engineering@salsify.com
|
114
|
+
executables:
|
115
|
+
- console
|
116
|
+
- setup
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- ".gitignore"
|
121
|
+
- ".overcommit.yml"
|
122
|
+
- ".rspec"
|
123
|
+
- ".rubocop.yml"
|
124
|
+
- ".travis.yml"
|
125
|
+
- CHANGELOG.md
|
126
|
+
- Gemfile
|
127
|
+
- LICENSE.txt
|
128
|
+
- README.md
|
129
|
+
- Rakefile
|
130
|
+
- avro-resolution_canonical_form.gemspec
|
131
|
+
- bin/console
|
132
|
+
- bin/setup
|
133
|
+
- lib/avro-resolution_canonical_form.rb
|
134
|
+
- lib/avro/resolution_canonical_form.rb
|
135
|
+
- lib/avro/resolution_canonical_form/version.rb
|
136
|
+
- lib/avro/resolution_fingerprint.rb
|
137
|
+
homepage: https://github.com/salsify/avro-resolution_canonical_form
|
138
|
+
licenses:
|
139
|
+
- MIT
|
140
|
+
metadata:
|
141
|
+
allowed_push_host: https://rubygems.org
|
142
|
+
post_install_message:
|
143
|
+
rdoc_options: []
|
144
|
+
require_paths:
|
145
|
+
- lib
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">"
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: 1.3.1
|
156
|
+
requirements: []
|
157
|
+
rubyforge_project:
|
158
|
+
rubygems_version: 2.6.10
|
159
|
+
signing_key:
|
160
|
+
specification_version: 4
|
161
|
+
summary: Unique identification of Avro schemas for schema resolution
|
162
|
+
test_files: []
|