iglu-ruby-client 0.1.0.beta

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e73421a2bfedada5669ee7482883196a824ffebc
4
+ data.tar.gz: ea2ab1d53ecb6594a8bce2f299c2efcb366fdafa
5
+ SHA512:
6
+ metadata.gz: ea6bbef26f62f7e2ad2b85527a80f64ea9751bf555dbea95ddd20fcceec79d12e2d083ef3e53ec2764dee233b02e75c5287f3c9c9127f5c89791f272c54e40aa
7
+ data.tar.gz: 4640a5303b0761eec70916f3763a9094d47c164801e4c15bddf223507a866eb8f1470c580bf147634a554d94cd6fed8007d0719958311072eaf710e11fa247c5
data/LICENSE-2.0.txt ADDED
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # Ruby client for Iglu
2
+
3
+ [![Build Status] [travis-image]] [travis]
4
+ [![Release] [release-image]] [releases]
5
+ [![License] [license-image]] [license]
6
+ [![Coverage Status] [coveralls-image]] [coveralls]
7
+
8
+ A Ruby client and resolver for **[Iglu schema repositories] [iglu-wiki]** from the team at **[Snowplow Analytics] [snowplow-website]**.
9
+
10
+ Iglu Ruby Client is used to validate self-describing JSONs. For a presentation on how we came to build Iglu, see **[this blog post] [snowplow-schema-post]**.
11
+
12
+ ![client-img] [client-img]
13
+
14
+ ## Installation
15
+
16
+ The Ruby Iglu Client is published to [RubyGems] [rubygems], the Ruby community's gem hosting service.
17
+ This makes it easy to either install the client locally, or to add it as a dependency into your own Ruby app.
18
+
19
+ To install the Iglu Ruby Client locally:
20
+
21
+ $ gem install iglu-ruby-client
22
+
23
+ To add the Iglu Client as a dependency to your own Ruby gem, edit your gemfile and add:
24
+
25
+ ```ruby
26
+ gem 'iglu-ruby-client'
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ The primary entity for working with Iglu Ruby Client is `Iglu::Client`.
32
+ Resolver static method `parse` allows you to create Resolver instance from a **[resolver configuration] [resolver-config]**.
33
+ The second working method is `lookup_schema`, receiving Schema key as String or directly `com.snowplowanalytics.iglu.SchemaKey` object,
34
+ this method traverses all configured repositories trying to find Schema by its key.
35
+
36
+ ```ruby
37
+ require 'json'
38
+ require 'iglu-client'
39
+
40
+ schema_key = Iglu::SchemaKey.parse_key("iglu:com.snowplowanalytics.snowplow/mobile_context/jsonschema/1-0-0")
41
+ resolver = Iglu::Resolver.parse(JSON.parse(resolver_config, {:symbolize_names => true}))
42
+ schema = resolver.lookup_schema(schema_key)
43
+ ```
44
+
45
+ Above snippet returns a mobile context JSON Schema if you provide the correct `resolver_config`.
46
+
47
+ ## Developer quickstart
48
+
49
+ Assuming git, **[Vagrant] [vagrant-install]** and **[VirtualBox] [virtualbox-install]** installed:
50
+
51
+ ```bash
52
+ host> git clone https://github.com/snowplow/iglu-ruby-client
53
+ host> cd iglu-ruby-client
54
+ host> vagrant up && vagrant ssh
55
+ guest> cd /vagrant
56
+ guest> rspec
57
+ ```
58
+
59
+ ## Find out more
60
+
61
+ | **[Technical Docs] [techdocs]** | **[Setup Guide] [setup]** | **[Roadmap] [roadmap]** | **[Contributing] [contributing]** |
62
+ |-------------------------------------|-------------------------------|-----------------------------------|---------------------------------------------|
63
+ | [![i1] [techdocs-image]] [techdocs] | [![i2] [setup-image]] [setup] | [![i3] [roadmap-image]] [roadmap] | [![i4] [contributing-image]] [contributing] |
64
+
65
+ ## Copyright and license
66
+
67
+ Iglu Ruby Client is copyright 2017 Snowplow Analytics Ltd.
68
+
69
+ Licensed under the **[Apache License, Version 2.0] [license]** (the "License");
70
+ you may not use this software except in compliance with the License.
71
+
72
+ Unless required by applicable law or agreed to in writing, software
73
+ distributed under the License is distributed on an "AS IS" BASIS,
74
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
75
+ See the License for the specific language governing permissions and
76
+ limitations under the License.
77
+
78
+ [client-img]: https://github.com/snowplow/iglu/wiki/technical-documentation/images/iglu-clients.png
79
+
80
+ [iglu-wiki]: https://github.com/snowplow/iglu/wiki
81
+ [snowplow-schema-post]: http://snowplowanalytics.com/blog/2014/06/06/making-snowplow-schemas-flexible-a-technical-approach/
82
+ [resolver-config]: https://github.com/snowplow/iglu/wiki/Iglu-client-configuration
83
+
84
+ [snowplow-repo]: https://github.com/snowplow/snowplow
85
+ [snowplow-website]: http://snowplowanalytics.com
86
+
87
+ [vagrant-install]: http://docs.vagrantup.com/v2/installation/index.html
88
+ [virtualbox-install]: https://www.virtualbox.org/wiki/Downloads
89
+
90
+ [techdocs-image]: https://d3i6fms1cm1j0i.cloudfront.net/github/images/techdocs.png
91
+ [setup-image]: https://d3i6fms1cm1j0i.cloudfront.net/github/images/setup.png
92
+ [roadmap-image]: https://d3i6fms1cm1j0i.cloudfront.net/github/images/roadmap.png
93
+ [contributing-image]: https://d3i6fms1cm1j0i.cloudfront.net/github/images/contributing.png
94
+
95
+ [techdocs]: https://github.com/snowplow/iglu/wiki/Ruby-client
96
+ [setup]: https://github.com/snowplow/iglu/wiki/Ruby-client-setup
97
+ [roadmap]: https://github.com/snowplow/iglu/wiki/Product-roadmap
98
+ [contributing]: https://github.com/snowplow/iglu/wiki/Contributing
99
+
100
+ [travis]: https://travis-ci.org/snowplow/iglu-ruby-client
101
+ [travis-image]: https://travis-ci.org/snowplow/iglu-ruby-client.png?branch=master
102
+
103
+ [releases]: https://github.com/snowplow/ruby-iglu-client/releases
104
+ [release-image]: http://img.shields.io/badge/release-0.1.0-blue.svg?style=flat
105
+
106
+ [license]: http://www.apache.org/licenses/LICENSE-2.0
107
+ [license-image]: http://img.shields.io/badge/license-Apache--2-blue.svg?style=flat
108
+
109
+ [coveralls]: https://coveralls.io/r/snowplow/iglu-ruby-client
110
+ [coveralls-image]: https://coveralls.io/repos/snowplow/iglu-ruby-client/badge.png
111
+
@@ -0,0 +1,89 @@
1
+ {
2
+ "$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
3
+ "description": "Schema for an Iglu resolver's configuration",
4
+ "self": {
5
+ "vendor": "com.snowplowanalytics.iglu",
6
+ "name": "resolver-config",
7
+ "format": "jsonschema",
8
+ "version": "1-0-0"
9
+ },
10
+
11
+ "type": "object",
12
+
13
+ "properties": {
14
+
15
+ "cacheSize": {
16
+ "type": "number"
17
+ },
18
+
19
+ "repositories": {
20
+ "type": "array",
21
+ "items": {
22
+ "type": "object",
23
+
24
+ "properties": {
25
+
26
+ "name": {
27
+ "type": "string"
28
+ },
29
+
30
+ "priority": {
31
+ "type": "number"
32
+ },
33
+
34
+ "vendorPrefixes": {
35
+ "type": "array",
36
+ "items": {
37
+ "type": "string"
38
+ }
39
+ },
40
+
41
+ "connection": {
42
+ "type": "object",
43
+ "oneOf": [
44
+ {
45
+ "properties": {
46
+ "embedded": {
47
+ "type": "object",
48
+ "properties": {
49
+ "path": {
50
+ "type": "string"
51
+ }
52
+ },
53
+ "required": ["path"],
54
+ "additionalProperties": false
55
+ }
56
+ },
57
+ "required": ["embedded"],
58
+ "additionalProperties": false
59
+ },
60
+ {
61
+ "properties": {
62
+ "http": {
63
+ "type": "object",
64
+ "properties": {
65
+ "uri": {
66
+ "type": "string",
67
+ "format": "uri"
68
+ }
69
+ },
70
+ "required": ["uri"],
71
+ "additionalProperties": false
72
+ }
73
+ },
74
+ "required": ["http"],
75
+ "additionalProperties": false
76
+ }
77
+ ]
78
+ }
79
+ },
80
+ "required": ["name", "priority", "vendorPrefixes", "connection"],
81
+ "additionalProperties": false
82
+ }
83
+ }
84
+
85
+ },
86
+
87
+ "required": ["cacheSize", "repositories"],
88
+ "additionalProperties": false
89
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
3
+ "description": "Schema for an Iglu resolver's configuration",
4
+ "self": {
5
+ "vendor": "com.snowplowanalytics.iglu",
6
+ "name": "resolver-config",
7
+ "format": "jsonschema",
8
+ "version": "1-0-1"
9
+ },
10
+
11
+ "type": "object",
12
+
13
+ "properties": {
14
+
15
+ "cacheSize": {
16
+ "type": "number"
17
+ },
18
+
19
+ "repositories": {
20
+ "type": "array",
21
+ "items": {
22
+ "type": "object",
23
+
24
+ "properties": {
25
+
26
+ "name": {
27
+ "type": "string"
28
+ },
29
+
30
+ "priority": {
31
+ "type": "number"
32
+ },
33
+
34
+ "vendorPrefixes": {
35
+ "type": "array",
36
+ "items": {
37
+ "type": "string"
38
+ }
39
+ },
40
+
41
+ "connection": {
42
+ "type": "object",
43
+ "oneOf": [
44
+ {
45
+ "properties": {
46
+ "embedded": {
47
+ "type": "object",
48
+ "properties": {
49
+ "path": {
50
+ "type": "string"
51
+ }
52
+ },
53
+ "required": ["path"],
54
+ "additionalProperties": false
55
+ }
56
+ },
57
+ "required": ["embedded"],
58
+ "additionalProperties": false
59
+ },
60
+ {
61
+ "properties": {
62
+ "http": {
63
+ "type": "object",
64
+ "properties": {
65
+ "uri": {
66
+ "type": "string",
67
+ "format": "uri"
68
+ },
69
+ "apikey": {
70
+ "type": ["string", "null"]
71
+ }
72
+ },
73
+ "required": ["uri"],
74
+ "additionalProperties": false
75
+ }
76
+ },
77
+ "required": ["http"],
78
+ "additionalProperties": false
79
+ }
80
+ ]
81
+ }
82
+ },
83
+ "required": ["name", "priority", "vendorPrefixes", "connection"],
84
+ "additionalProperties": false
85
+ }
86
+ }
87
+
88
+ },
89
+
90
+ "required": ["cacheSize", "repositories"],
91
+ "additionalProperties": false
92
+ }
93
+
@@ -0,0 +1,98 @@
1
+ {
2
+ "$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
3
+ "description": "Schema for an Iglu resolver's configuration",
4
+ "self": {
5
+ "vendor": "com.snowplowanalytics.iglu",
6
+ "name": "resolver-config",
7
+ "format": "jsonschema",
8
+ "version": "1-0-2"
9
+ },
10
+
11
+ "type": "object",
12
+
13
+ "properties": {
14
+
15
+ "cacheSize": {
16
+ "type": "number"
17
+ },
18
+
19
+ "cacheTtl": {
20
+ "type": ["integer", "null"],
21
+ "minimum": 1
22
+ },
23
+
24
+ "repositories": {
25
+ "type": "array",
26
+ "items": {
27
+ "type": "object",
28
+
29
+ "properties": {
30
+
31
+ "name": {
32
+ "type": "string"
33
+ },
34
+
35
+ "priority": {
36
+ "type": "number"
37
+ },
38
+
39
+ "vendorPrefixes": {
40
+ "type": "array",
41
+ "items": {
42
+ "type": "string"
43
+ }
44
+ },
45
+
46
+ "connection": {
47
+ "type": "object",
48
+ "oneOf": [
49
+ {
50
+ "properties": {
51
+ "embedded": {
52
+ "type": "object",
53
+ "properties": {
54
+ "path": {
55
+ "type": "string"
56
+ }
57
+ },
58
+ "required": ["path"],
59
+ "additionalProperties": false
60
+ }
61
+ },
62
+ "required": ["embedded"],
63
+ "additionalProperties": false
64
+ },
65
+ {
66
+ "properties": {
67
+ "http": {
68
+ "type": "object",
69
+ "properties": {
70
+ "uri": {
71
+ "type": "string",
72
+ "format": "uri"
73
+ },
74
+ "apikey": {
75
+ "type": ["string", "null"]
76
+ }
77
+ },
78
+ "required": ["uri"],
79
+ "additionalProperties": false
80
+ }
81
+ },
82
+ "required": ["http"],
83
+ "additionalProperties": false
84
+ }
85
+ ]
86
+ }
87
+ },
88
+ "required": ["name", "priority", "vendorPrefixes", "connection"],
89
+ "additionalProperties": false
90
+ }
91
+ }
92
+
93
+ },
94
+
95
+ "required": ["cacheSize", "repositories"],
96
+ "additionalProperties": false
97
+ }
98
+
@@ -0,0 +1,25 @@
1
+ {
2
+ "$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
3
+ "description": "Top-level schema for the validation process (Iglu-only)",
4
+ "self": {
5
+ "vendor": "com.snowplowanalytics.self-desc",
6
+ "name": "instance-iglu-only",
7
+ "format": "jsonschema",
8
+ "version": "1-0-0"
9
+ },
10
+
11
+ "type": "object",
12
+
13
+ "properties": {
14
+
15
+ "schema": {
16
+ "type": "string",
17
+ "pattern": "^iglu:[a-zA-Z0-9-_.]+/[a-zA-Z0-9-_]+/[a-zA-Z0-9-_]+/[0-9]+-[0-9]+-[0-9]+$"
18
+ },
19
+
20
+ "data": {}
21
+ },
22
+
23
+ "required": ["schema", "data"],
24
+ "additionalProperties": false
25
+ }
@@ -0,0 +1,11 @@
1
+ module Iglu
2
+ module Registries
3
+ config = Iglu::Registries::RegistryRefConfig.new "Iglu Client Embedded", 0, []
4
+ @@registry = Iglu::Registries::EmbeddedRegistryRef.new config, "iglu-client-embedded"
5
+
6
+ # Registry embedded straight into iglu-client gem
7
+ def self.bootstrap
8
+ @@registry
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,107 @@
1
+ # Copyright (c) 2017 Snowplow Analytics Ltd. All rights reserved.
2
+ #
3
+ # This program is licensed to you under the Apache License Version 2.0,
4
+ # and you may not use this file except in compliance with the Apache License Version 2.0.
5
+ # You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6
+ #
7
+ # Unless required by applicable law or agreed to in writing,
8
+ # software distributed under the Apache License Version 2.0 is distributed on an
9
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11
+
12
+ require "json-schema"
13
+
14
+ module Iglu
15
+
16
+ # Regular expression to extract metadata from self-describing JSON
17
+ URI_REGEX = Regexp.new "^iglu:([a-zA-Z0-9\\-_.]+)\/([a-zA-Z0-9\\-_]+)\/([a-zA-Z0-9\\-_]+)\/([1-9][0-9]*(?:-(?:0|[1-9][0-9]*)){2})$"
18
+
19
+ # Regular expression to extract all parts of SchemaVer: MODEL, REVISION, ADDITION
20
+ SCHEMAVER_REGEX = Regexp.new "^([1-9][0-9]*)-(0|[1-9][0-9]*)-(0|[1-9][0-9]*)$"
21
+
22
+ # Class holding SchemaVer data
23
+ class SchemaVer
24
+ attr_accessor :model, :revision, :addition
25
+
26
+ # Constructor. To initalize from string - use static parse_schemaver
27
+ def initialize(model, revision, addition)
28
+ @model = model
29
+ @revision = revision
30
+ @addition = addition
31
+ end
32
+
33
+ # Render as string
34
+ def as_string
35
+ "#{model}-#{revision}-#{addition}"
36
+ end
37
+
38
+ # Construct SchemaVer from string
39
+ def self.parse_schemaver(version)
40
+ model, revision, addition = version.scan(SCHEMAVER_REGEX).flatten
41
+ SchemaVer.new model.to_i, revision.to_i, addition.to_i
42
+ end
43
+
44
+ def ==(other)
45
+ other.model == @model && other.revision == @revision && other.addition == @addition
46
+ end
47
+ end
48
+
49
+
50
+ # Class holding Schema metadata
51
+ class SchemaKey
52
+ attr_accessor :vendor, :name, :format, :version
53
+
54
+ # Constructor. To initalize from string - use static parse_key
55
+ def initialize(vendor, name, format, version)
56
+ @vendor = vendor
57
+ @name = name
58
+ @format = format
59
+ @version = version
60
+ end
61
+
62
+ # Render as Iglu URI (with `iglu:`)
63
+ def as_uri
64
+ "iglu:#{as_path}"
65
+ end
66
+
67
+ # Render as plain path
68
+ def as_path
69
+ "#{vendor}/#{name}/#{format}/#{version.as_string}"
70
+ end
71
+
72
+ # Construct SchemaKey from URI
73
+ def self.parse_key(key)
74
+ vendor, name, format, version = key.scan(URI_REGEX).flatten
75
+ if vendor.nil? or name.nil? or format.nil? or version.nil?
76
+ raise IgluError.new "Schema key [#{key}] is not valid Iglu URI"
77
+ else
78
+ schema_ver = SchemaVer.parse_schemaver(version)
79
+ SchemaKey.new vendor, name, format, schema_ver
80
+ end
81
+ end
82
+
83
+ def ==(other)
84
+ other.vendor == @vendor && other.name == @name && other.format == @format && other.version == @version
85
+ end
86
+ end
87
+
88
+
89
+ # Custom validator, allowing to use self-describing JSON Schemas
90
+ class SelfDescribingSchema < JSON::Schema::Validator
91
+ def initialize
92
+ super
93
+ extend_schema_definition("http://json-schema.org/draft-04/schema#")
94
+ @uri = URI.parse("http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#")
95
+ end
96
+
97
+ JSON::Validator.register_validator(self.new)
98
+ end
99
+
100
+
101
+ # Common Iglu error
102
+ class IgluError < StandardError
103
+ def initialize(message = "Schema not found")
104
+ super(message)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,109 @@
1
+ require 'json'
2
+
3
+ module Iglu
4
+ module Registries
5
+ class RegistryRefConfig
6
+ attr_reader :name, :priority, :vendor_prefixes
7
+
8
+ def initialize(name, priority, vendor_prefixes)
9
+ @name = name
10
+ @priority = priority
11
+ @vendor_prefixes = vendor_prefixes
12
+ end
13
+
14
+ def self.parse(config)
15
+ RegistryRefConfig.new config[:name], config[:priority], config[:vendorPrefixes]
16
+ end
17
+ end
18
+
19
+ # Interface
20
+ class RegistryRef
21
+ attr_reader :config, :class_priority, :descriptor
22
+
23
+ def lookup_schema(schema_key)
24
+ end
25
+
26
+ def vendor_matched(schema_key)
27
+ matches = @config.vendor_prefixes.map { |p|
28
+ schema_key.vendor.start_with?(p)
29
+ }
30
+ matches.include? true
31
+ end
32
+ end
33
+
34
+ class HttpRegistryRef < RegistryRef
35
+
36
+ def initialize(config, uri)
37
+ @config = config
38
+ @class_priority = 100
39
+ @descriptor = "HTTP"
40
+
41
+ @uri = uri
42
+ end
43
+
44
+ def lookup_schema(schema_key)
45
+ schema_uri = "#{@uri}/schemas/#{schema_key.as_path}"
46
+ begin
47
+ response = HTTParty.get(schema_uri)
48
+ rescue SocketError => _
49
+ raise IgluError.new "Iglu registry #{config.name} is not available"
50
+ end
51
+ if response.code == 200
52
+ JSON::parse(response.body)
53
+ else
54
+ nil
55
+ end
56
+ end
57
+ end
58
+
59
+ # This is not a replacement for JVM Embedded Registry
60
+ # It is something more like FileSystemRegistry if you pass absolute path,
61
+ # But by default it's root is relative to gem
62
+ class EmbeddedRegistryRef < RegistryRef
63
+ def initialize(config, path)
64
+ @config = config
65
+ @class_priority = 1
66
+ @descriptor = "embedded"
67
+
68
+ @path = path
69
+ @root = "assets"
70
+ end
71
+
72
+ def lookup_schema(schema_key)
73
+ schema_path = File.join(@root, @path, 'schemas', schema_key.as_path)
74
+ content = File.read(schema_path)
75
+ JSON::parse(content)
76
+ rescue Errno::ENOENT => _
77
+ nil
78
+ end
79
+ end
80
+
81
+ # Lookup results
82
+
83
+ class NotFound
84
+ attr_reader :registry
85
+
86
+ def initialize(registry)
87
+ @registry = registry
88
+ end
89
+ end
90
+
91
+ class LookupFailure
92
+ attr_reader :registry, :reason
93
+
94
+ def initialize(registry, reason)
95
+ @reason = reason
96
+ @registry = registry
97
+ end
98
+ end
99
+
100
+ class ResolverError < StandardError
101
+ attr_reader :lookups
102
+
103
+ def initialize(lookups)
104
+ @lookups = lookups
105
+ end
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,127 @@
1
+ # Copyright (c) 2017 Snowplow Analytics Ltd. All rights reserved.
2
+ #
3
+ # This program is licensed to you under the Apache License Version 2.0,
4
+ # and you may not use this file except in compliance with the Apache License Version 2.0.
5
+ # You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6
+ #
7
+ # Unless required by applicable law or agreed to in writing,
8
+ # software distributed under the Apache License Version 2.0 is distributed on an
9
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11
+
12
+ require "httparty"
13
+ require "json-schema"
14
+
15
+ module Iglu
16
+
17
+ # Iglu Client. Able to fetch schemas only from Iglu Central
18
+ class Resolver
19
+ attr_reader :registries, :cache
20
+
21
+ def initialize(registries)
22
+ @registries = registries.unshift(Registries.bootstrap)
23
+ @cache = Hash.new
24
+ end
25
+
26
+ # Lookup schema in cache or try to fetch
27
+ def lookup_schema(schema_key)
28
+ if schema_key.is_a?(String)
29
+ schema_key = SchemaKey.parse_key(schema_key)
30
+ end
31
+ failures = []
32
+
33
+ cache_result = @cache[schema_key]
34
+
35
+ if cache_result.nil? # Fetch from every registry
36
+ for registry in prioritize_repos(schema_key, @registries) do
37
+ begin
38
+ lookup_result = registry.lookup_schema(schema_key)
39
+ rescue StandardError => e
40
+ failures.push(Registries::LookupFailure.new(registry.config.name, e))
41
+ else
42
+ if lookup_result.nil?
43
+ failures.push(Registries::NotFound.new(registry.config.name))
44
+ else
45
+ break
46
+ end
47
+ end
48
+ end
49
+
50
+ if lookup_result.nil?
51
+ raise Registries::ResolverError.new failures
52
+ else
53
+ @cache[schema_key] = lookup_result
54
+ lookup_result
55
+ end
56
+ else
57
+ if cache_result.is_a?(Registries::ResolverError)
58
+ raise cache_result
59
+ else
60
+ cache_result
61
+ end
62
+ end
63
+ end
64
+
65
+ def self.parse(json)
66
+ schema_key = Resolver.get_schema_key(json)
67
+ schema = Registries.bootstrap.lookup_schema(schema_key)
68
+ data = get_data(json)
69
+ if JSON::Validator.validate!(schema, data)
70
+ # cache_size = data[:cacheSize]
71
+ registries = data[:repositories].map do |registry| parse_registry(registry) end
72
+ Resolver.new(registries)
73
+ else
74
+ throw IgluError.new "Invalid resolver configuration"
75
+ end
76
+ end
77
+
78
+ def self.parse_registry(config)
79
+ ref_config = Registries::RegistryRefConfig.parse(config)
80
+ if not config[:connection][:embedded].nil?
81
+ Registries::EmbeddedRegistryRef.new(ref_config, config[:connection][:embedded][:path])
82
+ elsif not config[:connection][:http].nil?
83
+ Registries::HttpRegistryRef.new(ref_config, config[:connection][:http][:uri])
84
+ else
85
+ raise IgluError.new "Incorrect RegistryRef"
86
+ end
87
+ end
88
+
89
+ def self.get_schema_key(json)
90
+ schema_uri = json[:schema] || json["schema"]
91
+ if schema_uri.nil?
92
+ raise IgluError.new "JSON instance is not self-describing (schema property is absent):\n #{json.to_json}"
93
+ else
94
+ SchemaKey.parse_key schema_uri
95
+ end
96
+ end
97
+
98
+ def self.get_data(json)
99
+ data = json[:data] || json["data"]
100
+ if data.nil?
101
+ raise IgluError.new "JSON instance is not self-describing (data proprty is absent):\n #{json.to_json}"
102
+ else
103
+ data
104
+ end
105
+ end
106
+
107
+ # Return true or throw exception
108
+ def validate(json)
109
+ schema_key = Resolver.get_schema_key json
110
+ data = Resolver.get_data json
111
+ schema = lookup_schema schema_key
112
+ JSON::Validator.validate!(schema, data)
113
+ end
114
+
115
+
116
+ # Primary method. Validate self-describing JSON instance
117
+ def self.validate(json)
118
+ JSON::Validator.validate!(schema, data)
119
+ end
120
+
121
+ def prioritize_repos(schema_key, repository_refs)
122
+ repository_refs.sort_by do |ref|
123
+ [!ref.vendor_matched(schema_key), ref.class_priority, ref.config.priority]
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright (c) 2017 Snowplow Analytics Ltd. All rights reserved.
2
+ #
3
+ # This program is licensed to you under the Apache License Version 2.0,
4
+ # and you may not use this file except in compliance with the Apache License Version 2.0.
5
+ # You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6
+ #
7
+ # Unless required by applicable law or agreed to in writing,
8
+ # software distributed under the Apache License Version 2.0 is distributed on an
9
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11
+
12
+ require "json-schema"
13
+
14
+ module Iglu
15
+
16
+ # Class holding SchemaVer data
17
+ class SelfDescribingJson
18
+ attr_accessor :schema, :data
19
+
20
+ # Constructor. To initalize from string - use static parse_schemaver
21
+ def initialize(schema, data)
22
+ @schema = schema
23
+ @data = data
24
+ @valid = false
25
+ end
26
+
27
+ def to_json
28
+ {
29
+ :schema => @schema.as_uri,
30
+ :data => @data
31
+ }
32
+ end
33
+
34
+ # Check if JSON is valid (throw exception otherwise)
35
+ def validate(resolver)
36
+ @valid = resolver.validate(to_json)
37
+ @valid
38
+ end
39
+
40
+ def valid?(resolver)
41
+ begin
42
+ @valid or validate(resolver)
43
+ rescue JSON::Schema::ValidationError => _
44
+ false
45
+ end
46
+ end
47
+
48
+ def self.parse_json(json)
49
+ schema = json[:schema] || json['schema']
50
+ data = json[:data] || json['data']
51
+ if schema.nil? or data.nil?
52
+ raise IgluError.new "Not a self-describing JSON"
53
+ end
54
+ schema_key = SchemaKey.parse_key(schema)
55
+ SelfDescribingJson.new(schema_key, data)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,14 @@
1
+ # Copyright (c) 2017 Snowplow Analytics Ltd. All rights reserved.
2
+ #
3
+ # This program is licensed to you under the Apache License Version 2.0,
4
+ # and you may not use this file except in compliance with the Apache License Version 2.0.
5
+ # You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6
+ #
7
+ # Unless required by applicable law or agreed to in writing,
8
+ # software distributed under the Apache License Version 2.0 is distributed on an
9
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11
+
12
+ module Iglu
13
+ CLIENT_VERSION = '0.1.0.beta'
14
+ end
@@ -0,0 +1,18 @@
1
+ # Copyright (c) 2017 Snowplow Analytics Ltd. All rights reserved.
2
+ #
3
+ # This program is licensed to you under the Apache License Version 2.0,
4
+ # and you may not use this file except in compliance with the Apache License Version 2.0.
5
+ # You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6
+ #
7
+ # Unless required by applicable law or agreed to in writing,
8
+ # software distributed under the Apache License Version 2.0 is distributed on an
9
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11
+
12
+ require 'iglu-client/core.rb'
13
+ require 'iglu-client/resolver.rb'
14
+ require 'iglu-client/self_describing_json.rb'
15
+ require 'iglu-client/registries.rb'
16
+ require 'iglu-client/bootstrap.rb'
17
+ require 'iglu-client/version.rb'
18
+
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iglu-ruby-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.beta
5
+ platform: ruby
6
+ authors:
7
+ - Anton Parkhomenko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "<="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.14.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "<="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.14.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: json-schema
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.7.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.7.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: 2.14.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.14.1
55
+ description: Iglu Client is used to resolve JSON Schemas and validate self-describing
56
+ JSONs
57
+ email: support@snowplowanalytics.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - LICENSE-2.0.txt
63
+ - README.md
64
+ - assets/iglu-client-embedded/schemas/com.snowplowanalytics.iglu/resolver-config/jsonschema/1-0-0
65
+ - assets/iglu-client-embedded/schemas/com.snowplowanalytics.iglu/resolver-config/jsonschema/1-0-1
66
+ - assets/iglu-client-embedded/schemas/com.snowplowanalytics.iglu/resolver-config/jsonschema/1-0-2
67
+ - assets/iglu-client-embedded/schemas/com.snowplowanalytics.self-desc/instance-iglu-only/jsonschema/1-0-0
68
+ - lib/iglu-client.rb
69
+ - lib/iglu-client/bootstrap.rb
70
+ - lib/iglu-client/core.rb
71
+ - lib/iglu-client/registries.rb
72
+ - lib/iglu-client/resolver.rb
73
+ - lib/iglu-client/self_describing_json.rb
74
+ - lib/iglu-client/version.rb
75
+ homepage: http://github.com/snowplow/iglu-ruby-client
76
+ licenses:
77
+ - Apache License 2.0
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: 2.0.0
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">"
91
+ - !ruby/object:Gem::Version
92
+ version: 1.3.1
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.4.5
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: A Ruby client for Iglu
99
+ test_files: []