rimless 0.1.4 → 0.2.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 +4 -4
- data/CHANGELOG.md +19 -0
- data/Dockerfile +2 -1
- data/Envfile +6 -0
- data/Makefile +1 -1
- data/README.md +30 -2
- data/docker-compose.yml +1 -0
- data/lib/rimless/avro_helpers.rb +35 -0
- data/lib/rimless/avro_utils.rb +6 -1
- data/lib/rimless/dependencies.rb +7 -4
- data/lib/rimless/kafka_helpers.rb +2 -2
- data/lib/rimless/rspec/helpers.rb +3 -2
- data/lib/rimless/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7bb2e99346e0f71cdd800b802a9d405e3188303a7017b375442c50a66872cfb
|
4
|
+
data.tar.gz: 73f37b16200f0ac00cec1756ffd085a8fcd1a3265fc8af8b652aca130161bf95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42541dacf4cd9c0ce8c7dc837e0f0d289d4be93c0b940f3b2fd724ec08ed70f4d4a69e92b0726a81951e509c83c2c4e69a48b92884862404225754fbce4ef109
|
7
|
+
data.tar.gz: 84986a34d1f651dcb1f215d25762f1e1b6c9f18aa8068ed34090fa15f0185284be3ab1b77e8b29c2dddb9b74b3a6f655728b42d196af9650ed7b7253710ad4c9
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
### 0.2.0
|
2
|
+
|
3
|
+
* Added the `Rimless.encode` (`.avro_encode`) and `Rimless.decode`
|
4
|
+
(`.avro_decode`) helpers/shortcuts to simplify the interaction with the
|
5
|
+
Apache Avro library
|
6
|
+
* The `.encode` method automatically performs input data sanitation and
|
7
|
+
supports deep relative (to the local namespace) schema resolution. This
|
8
|
+
allows you to access deeply located schemes relative by just providing a
|
9
|
+
leading period (eg. `.deep.a.b.c` becomes
|
10
|
+
`development.your_app.deep.a.b.c`)
|
11
|
+
* The `.message`, '.sync_message', '.async_message' helpers now make use of the
|
12
|
+
new `.encode` functionality which adds transparent data sanitation and schema
|
13
|
+
name features
|
14
|
+
* At the `test` environment the compiled Avro schemas output path is not
|
15
|
+
deleted anymore, instead the compiled schemas are overwritten. This may keep
|
16
|
+
dead schemas, but it allows parallel test execution without flaws. The removal
|
17
|
+
of the compiled schema directory caused previously file read errors when a
|
18
|
+
parallel process started a recompilation.
|
19
|
+
|
1
20
|
### 0.1.4
|
2
21
|
|
3
22
|
* Reconfigure (reset) the AvroTurf instance on tests to avoid caching issues
|
data/Dockerfile
CHANGED
@@ -11,7 +11,8 @@ RUN apt-get update -yqqq && \
|
|
11
11
|
ca-certificates \
|
12
12
|
bash-completion inotify-tools && \
|
13
13
|
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && /usr/sbin/locale-gen && \
|
14
|
-
gem install bundler --no-document --no-prerelease
|
14
|
+
gem install bundler -v '~> 2.0' --no-document --no-prerelease && \
|
15
|
+
gem install bundler -v '~> 1.0' --no-document --no-prerelease
|
15
16
|
|
16
17
|
# Add new web user
|
17
18
|
RUN mkdir /app && \
|
data/Envfile
ADDED
data/Makefile
CHANGED
data/README.md
CHANGED
@@ -23,6 +23,7 @@ opinionated framework which sets up solid conventions for producing messages.
|
|
23
23
|
- [Confluent Schema Registry Subject](#confluent-schema-registry-subject)
|
24
24
|
- [Organize and write schema definitions](#organize-and-write-schema-definitions)
|
25
25
|
- [Producing messages](#producing-messages)
|
26
|
+
- [Encoding/Decoding messages](#encodingdecoding-messages)
|
26
27
|
- [Handling of schemaless deep blobs](#handling-of-schemaless-deep-blobs)
|
27
28
|
- [Writing tests for your messages](#writing-tests-for-your-messages)
|
28
29
|
- [Development](#development)
|
@@ -254,8 +255,11 @@ Rimless.message(data: user, schema: :user_v1, topic: :users)
|
|
254
255
|
Rimless.async_message(data: user, schema: :user_v1, topic: :users)
|
255
256
|
|
256
257
|
# In cases you just want the encoded Apache Avro binary blob, you can encode it
|
257
|
-
# directly
|
258
|
-
encoded = Rimless.
|
258
|
+
# directly with our simple helper like this:
|
259
|
+
encoded = Rimless.encode(user, schema: 'user_v1')
|
260
|
+
# Next to this wrapped shortcut (see Encoding/Decoding messages section for
|
261
|
+
# details), we provide access to our configured AvroTurf gem instance via
|
262
|
+
# +Rimless.avro+, so you can also use +Rimless.avro.encode(user, ..)+
|
259
263
|
|
260
264
|
# You can also send raw messages with the rimless gem, so encoding of your
|
261
265
|
# message must be done before
|
@@ -275,6 +279,30 @@ Rimless.message(data: user, schema: :user_v1,
|
|
275
279
|
Rimless.async_raw_message(data: encoded, topic: :users)
|
276
280
|
```
|
277
281
|
|
282
|
+
### Encoding/Decoding messages
|
283
|
+
|
284
|
+
By convention we focus on the [Apache Avro](https://avro.apache.org/) data
|
285
|
+
format. This is provided by the [AvroTurf](https://rubygems.org/gems/avro_turf)
|
286
|
+
gem and the rimless gem adds some neat helpers on top of it. Here are a few
|
287
|
+
examples to show how rimless can be used to encode/decode Apache Avro data:
|
288
|
+
|
289
|
+
```ruby
|
290
|
+
# Encode a data structure (no matter of symbolized, or stringified keys, or
|
291
|
+
# non-simple types) to Apache Avro format
|
292
|
+
encoded = Rimless.encode(user, schema: 'user_v1')
|
293
|
+
|
294
|
+
# Works the same for symbolized schema names
|
295
|
+
encoded = Rimless.encode(user, schema: :user_v1)
|
296
|
+
|
297
|
+
# Also supports the resolution of deep relative schemes
|
298
|
+
# (+.user.address+ becomes +<ENV>.<APP>.user.address+)
|
299
|
+
encoded = Rimless.encode(user.address, schema: '.user.address')
|
300
|
+
|
301
|
+
# Decoding Apache Avro data is even more simple. The resulting data structure
|
302
|
+
# is deeply key-symbolized.
|
303
|
+
decoded = Rimless.decode('your-avro-binary-data-here')
|
304
|
+
```
|
305
|
+
|
278
306
|
#### Handling of schemaless deep blobs
|
279
307
|
|
280
308
|
Apache Avro is by design a strict, type casted format which does not allow
|
data/docker-compose.yml
CHANGED
data/lib/rimless/avro_helpers.rb
CHANGED
@@ -8,6 +8,41 @@ module Rimless
|
|
8
8
|
class_methods do
|
9
9
|
# A top-level avro instance
|
10
10
|
mattr_accessor :avro
|
11
|
+
# A shared AvroUtils instance
|
12
|
+
mattr_accessor :avro_utils
|
13
|
+
|
14
|
+
# A shortcut to encode data using the specified schema to the Apache Avro
|
15
|
+
# format. This also applies data sanitation to avoid issues with the low
|
16
|
+
# level Apache Avro library (symbolized keys, etc) and it allows
|
17
|
+
# deep-relative schema names. When you pass +.deep.deep+ for example
|
18
|
+
# (leading period) it will prefix the schema name with the local
|
19
|
+
# namespace (so it becomes absolute).
|
20
|
+
#
|
21
|
+
# @param data [Mixed] the data structure to encode
|
22
|
+
# @param schema [String, Symbol] name of the schema that should be used
|
23
|
+
# @param opts [Hash{Symbol => Mixed}] additional options
|
24
|
+
# @return [String] the Apache Avro blob
|
25
|
+
def avro_encode(data, schema:, **opts)
|
26
|
+
data = avro_sanitize(data)
|
27
|
+
|
28
|
+
# When the deep-relative form (+.deep.deep[..]+) is present, we add our
|
29
|
+
# local namespace, so Avro can resolve it
|
30
|
+
schema = avro_utils.namespace + schema.to_s \
|
31
|
+
if schema.to_s.start_with? '.'
|
32
|
+
|
33
|
+
avro.encode(data, schema_name: schema.to_s, **opts)
|
34
|
+
end
|
35
|
+
alias_method :encode, :avro_encode
|
36
|
+
|
37
|
+
# A shortcut to parse a blob of Apache Avro data.
|
38
|
+
#
|
39
|
+
# @param data [String] the Apache Avro blob
|
40
|
+
# @param opts [Hash{Symbol => Mixed}] additional options
|
41
|
+
# @return [Mixed] the decoded data structure
|
42
|
+
def avro_decode(data, **opts)
|
43
|
+
avro.decode(data, **opts).deep_symbolize_keys!
|
44
|
+
end
|
45
|
+
alias_method :decode, :avro_decode
|
11
46
|
|
12
47
|
# The Apache Avro Ruby gem requires simple typed hashes for encoding.
|
13
48
|
# This forces us to convert eg. Grape entity representations into simple
|
data/lib/rimless/avro_utils.rb
CHANGED
@@ -61,7 +61,12 @@ module Rimless
|
|
61
61
|
|
62
62
|
# Clear previous compiled Avro schema files to provide a clean rebuild.
|
63
63
|
def clear
|
64
|
-
|
64
|
+
# In a test environment, especially with parallel test execution the
|
65
|
+
# recompiling of Avro schemas is error prone due to the deletion of the
|
66
|
+
# configuration (output) directory. This leads to random failures due to
|
67
|
+
# file read calls to temporary not existing files. So we just keep the
|
68
|
+
# files and just overwrite them in place while testing.
|
69
|
+
FileUtils.rm_rf(output_path) unless Rimless.env.test?
|
65
70
|
FileUtils.mkdir_p(output_path)
|
66
71
|
end
|
67
72
|
|
data/lib/rimless/dependencies.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Rimless
|
4
4
|
# The top-level dependencies helpers.
|
5
|
+
#
|
6
|
+
# rubocop:disable Metrics/BlockLength because its an Active Support concern
|
5
7
|
module Dependencies
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
|
@@ -53,17 +55,18 @@ module Rimless
|
|
53
55
|
|
54
56
|
# Setup a global available Apache Avro decoder/encoder with support for
|
55
57
|
# the Confluent Schema Registry, but first create a helper instance
|
56
|
-
avro_utils = Rimless::AvroUtils.new
|
58
|
+
Rimless.avro_utils = Rimless::AvroUtils.new
|
57
59
|
# Compile our Avro schema templates to ready-to-consume Avro schemas
|
58
|
-
avro_utils.recompile_schemas
|
60
|
+
Rimless.avro_utils.recompile_schemas
|
59
61
|
# Register a global Avro messaging instance
|
60
62
|
Rimless.avro = AvroTurf::Messaging.new(
|
61
63
|
logger: Rimless.logger,
|
62
|
-
namespace: avro_utils.namespace,
|
63
|
-
schemas_path: avro_utils.output_path,
|
64
|
+
namespace: Rimless.avro_utils.namespace,
|
65
|
+
schemas_path: Rimless.avro_utils.output_path,
|
64
66
|
registry_url: Rimless.configuration.schema_registry_url
|
65
67
|
)
|
66
68
|
end
|
67
69
|
end
|
68
70
|
end
|
71
|
+
# rubocop:enable Metrics/BlockLength
|
69
72
|
end
|
@@ -50,7 +50,7 @@ module Rimless
|
|
50
50
|
# @param topic [String, Symbol, Hash{Symbol => Mixed}] the destination
|
51
51
|
# Apache Kafka topic
|
52
52
|
def sync_message(data:, schema:, topic:, **args)
|
53
|
-
encoded = Rimless.
|
53
|
+
encoded = Rimless.encode(data, schema: schema)
|
54
54
|
sync_raw_message(data: encoded, topic: topic, **args)
|
55
55
|
end
|
56
56
|
alias_method :message, :sync_message
|
@@ -66,7 +66,7 @@ module Rimless
|
|
66
66
|
# @param topic [String, Symbol, Hash{Symbol => Mixed}] the destination
|
67
67
|
# Apache Kafka topic
|
68
68
|
def async_message(data:, schema:, topic:, **args)
|
69
|
-
encoded = Rimless.
|
69
|
+
encoded = Rimless.encode(data, schema: schema)
|
70
70
|
async_raw_message(data: encoded, topic: topic, **args)
|
71
71
|
end
|
72
72
|
|
@@ -8,9 +8,10 @@ module Rimless
|
|
8
8
|
# A simple helper to parse a blob of Apache Avro data.
|
9
9
|
#
|
10
10
|
# @param data [String] the Apache Avro blob
|
11
|
+
# @param opts [Hash{Symbol => Mixed}] additional options
|
11
12
|
# @return [Hash{String => Mixed}] the parsed payload
|
12
|
-
def avro_parse(data)
|
13
|
-
Rimless.
|
13
|
+
def avro_parse(data, **opts)
|
14
|
+
Rimless.avro_decode(data, **opts)
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
data/lib/rimless/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rimless
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hermann Mayer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -327,6 +327,7 @@ files:
|
|
327
327
|
- Appraisals
|
328
328
|
- CHANGELOG.md
|
329
329
|
- Dockerfile
|
330
|
+
- Envfile
|
330
331
|
- Gemfile
|
331
332
|
- LICENSE
|
332
333
|
- Makefile
|